From 37fd19290f0cdbe07052cee2b31e9696d69a6a47 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 20 Oct 2017 18:42:29 +0100 Subject: [PATCH 01/32] concept of default theme --- src/components/structures/MatrixChat.js | 2 +- src/components/structures/UserSettings.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 3fa628b8a3..9e476714ec 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -888,7 +888,7 @@ module.exports = React.createClass({ */ _onSetTheme: function(theme) { if (!theme) { - theme = 'light'; + theme = this.props.config.default_theme || 'light'; } // look for the stylesheet elements. diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index b69bea9282..e98bb844cc 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -179,6 +179,11 @@ const THEMES = [ label: _td('Dark theme'), value: 'dark', }, + { + id: 'theme', + label: _td('Status.im theme'), + value: 'status', + }, ]; const IgnoredUser = React.createClass({ @@ -279,7 +284,7 @@ module.exports = React.createClass({ const syncedSettings = UserSettingsStore.getSyncedSettings(); if (!syncedSettings.theme) { - syncedSettings.theme = 'light'; + syncedSettings.theme = SdkConfig.get().default_theme || 'light'; } this._syncedSettings = syncedSettings; From f09fbccc1917ff6d9da5d5169c795a9826c84381 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 23 Oct 2017 00:56:15 +0100 Subject: [PATCH 02/32] WIP --- src/UserSettingsStore.js | 15 ++++++ src/components/structures/login/Login.js | 37 ++++++++++----- src/components/views/login/LoginPageFooter.js | 30 ++++++++++++ src/components/views/login/LoginPageHeader.js | 47 +++++++++++++++++++ src/i18n/strings/en_EN.json | 1 + 5 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 src/components/views/login/LoginPageFooter.js create mode 100644 src/components/views/login/LoginPageHeader.js diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index 68f463c373..ede5a157a8 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -180,6 +180,21 @@ export default { }); }, + getTheme: function() { + let syncedSettings; + let theme; + if (MatrixClientPeg.get()) { + syncedSettings = this.getSyncedSettings(); + } + if (!syncedSettings || !syncedSettings.theme) { + theme = SdkConfig.get().default_theme || 'light'; + } + else { + theme = syncedSettings.theme; + } + return theme; + }, + getSyncedSettings: function() { const event = MatrixClientPeg.get().getAccountData('im.vector.web.settings'); return event ? event.getContent() : {}; diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 8ee6eafad4..eb131989a8 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -329,13 +329,17 @@ module.exports = React.createClass({ render: function() { const Loader = sdk.getComponent("elements.Spinner"); + const LoginPageHeader = sdk.getComponent("login.LoginPageHeader"); + const LoginPageFooter = sdk.getComponent("login.LoginPageFooter"); const LoginHeader = sdk.getComponent("login.LoginHeader"); const LoginFooter = sdk.getComponent("login.LoginFooter"); const ServerConfig = sdk.getComponent("login.ServerConfig"); const loader = this.state.busy ?
: null; + const theme = UserSettingsStore.getTheme(); + let loginAsGuestJsx; - if (this.props.enableGuest) { + if (this.props.enableGuest && theme !== 'status') { loginAsGuestJsx = { _t('Login as guest') } @@ -343,42 +347,49 @@ module.exports = React.createClass({ } let returnToAppJsx; - if (this.props.onCancelClick) { + if (this.props.onCancelClick && theme !== 'status') { returnToAppJsx = { _t('Return to app') } ; } + let serverConfig; + if (theme !== 'status') { + serverConfig = ; + } + return (
+
-

{ _t('Sign in') } +

{ theme !== 'status' ? _t('Sign in') : _t('Sign in to get started') } { loader }

- { this.componentForStep(this.state.currentFlow) } -
{ this.state.errorText }
+ { this.componentForStep(this.state.currentFlow) } + { serverConfig } { _t('Create an account') } { loginAsGuestJsx } { returnToAppJsx } - { this._renderLanguageSetting() } + { theme !== 'status' ? this._renderLanguageSetting() : '' }
+
); }, diff --git a/src/components/views/login/LoginPageFooter.js b/src/components/views/login/LoginPageFooter.js new file mode 100644 index 0000000000..e4eca9b8b3 --- /dev/null +++ b/src/components/views/login/LoginPageFooter.js @@ -0,0 +1,30 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +import { _t } from '../../../languageHandler'; +import React from 'react'; + +module.exports = React.createClass({ + displayName: 'LoginPageFooter', + + render: function() { + return ( +
+ ); + }, +}); diff --git a/src/components/views/login/LoginPageHeader.js b/src/components/views/login/LoginPageHeader.js new file mode 100644 index 0000000000..bef7fa5e0b --- /dev/null +++ b/src/components/views/login/LoginPageHeader.js @@ -0,0 +1,47 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +import UserSettingsStore from '../../../UserSettingsStore'; + +const React = require('react'); + +module.exports = React.createClass({ + displayName: 'LoginPageHeader', + + render: function() { + let themeBranding; + if (UserSettingsStore.getTheme() === 'status') { + themeBranding =
+
+ Status +
+
+

Status Community Chat

+
+ A safer, decentralised communication platform powered by Riot +
+
+
; + } + else { + themeBranding =
; + } + + return themeBranding; + }, +}); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index f071d42f56..db13972c9f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -475,6 +475,7 @@ "Sign in with": "Sign in with", "Email address": "Email address", "Sign in": "Sign in", + "Sign in to get started": "Sign in to get started", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?", "Email address (optional)": "Email address (optional)", "You are registering with %(SelectedTeamName)s": "You are registering with %(SelectedTeamName)s", From 26e8b2c1b3af8d6a2b8559ec3b4644d18746b7c2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 24 Oct 2017 23:37:26 +0100 Subject: [PATCH 03/32] switch to a LoginPage wrapper component as it's much nicer in the CSS to wrap the LoginBox as needed rather than have separate header & footer divs floating above and below it which need to be correctly vertically centered --- .../structures/login/ForgotPassword.js | 5 +- src/components/structures/login/Login.js | 9 +-- .../structures/login/PostRegistration.js | 5 +- .../structures/login/Registration.js | 5 +- src/components/views/login/LoginPage.js | 58 +++++++++++++++++++ src/components/views/login/LoginPageFooter.js | 30 ---------- src/components/views/login/LoginPageHeader.js | 47 --------------- 7 files changed, 70 insertions(+), 89 deletions(-) create mode 100644 src/components/views/login/LoginPage.js delete mode 100644 src/components/views/login/LoginPageFooter.js delete mode 100644 src/components/views/login/LoginPageHeader.js diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index 3e76291d20..f14d64528f 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -154,6 +154,7 @@ module.exports = React.createClass({ }, render: function() { + const LoginPage = sdk.getComponent("login.LoginPage"); const LoginHeader = sdk.getComponent("login.LoginHeader"); const LoginFooter = sdk.getComponent("login.LoginFooter"); const ServerConfig = sdk.getComponent("login.ServerConfig"); @@ -233,12 +234,12 @@ module.exports = React.createClass({ return ( -
+
{ resetPasswordJsx }
-
+ ); }, }); diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index eb131989a8..f5f4f8cd69 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -329,8 +329,7 @@ module.exports = React.createClass({ render: function() { const Loader = sdk.getComponent("elements.Spinner"); - const LoginPageHeader = sdk.getComponent("login.LoginPageHeader"); - const LoginPageFooter = sdk.getComponent("login.LoginPageFooter"); + const LoginPage = sdk.getComponent("login.LoginPage"); const LoginHeader = sdk.getComponent("login.LoginHeader"); const LoginFooter = sdk.getComponent("login.LoginFooter"); const ServerConfig = sdk.getComponent("login.ServerConfig"); @@ -367,8 +366,7 @@ module.exports = React.createClass({ } return ( -
- +
@@ -389,8 +387,7 @@ module.exports = React.createClass({
- -
+ ); }, }); diff --git a/src/components/structures/login/PostRegistration.js b/src/components/structures/login/PostRegistration.js index 194995150c..184356e852 100644 --- a/src/components/structures/login/PostRegistration.js +++ b/src/components/structures/login/PostRegistration.js @@ -59,9 +59,10 @@ module.exports = React.createClass({ render: function() { const ChangeDisplayName = sdk.getComponent('settings.ChangeDisplayName'); const ChangeAvatar = sdk.getComponent('settings.ChangeAvatar'); + const LoginPage = sdk.getComponent('login.LoginPage'); const LoginHeader = sdk.getComponent('login.LoginHeader'); return ( -
+
@@ -74,7 +75,7 @@ module.exports = React.createClass({ { this.state.errorString }
-
+ ); }, }); diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index db488ea237..8151c1e65c 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -322,6 +322,7 @@ module.exports = React.createClass({ render: function() { const LoginHeader = sdk.getComponent('login.LoginHeader'); const LoginFooter = sdk.getComponent('login.LoginFooter'); + const LoginPage = sdk.getComponent('login.LoginPage'); const InteractiveAuth = sdk.getComponent('structures.InteractiveAuth'); const Spinner = sdk.getComponent("elements.Spinner"); const ServerConfig = sdk.getComponent('views.login.ServerConfig'); @@ -385,7 +386,7 @@ module.exports = React.createClass({ ); } return ( -
+
-
+ ); }, }); diff --git a/src/components/views/login/LoginPage.js b/src/components/views/login/LoginPage.js new file mode 100644 index 0000000000..a07997727b --- /dev/null +++ b/src/components/views/login/LoginPage.js @@ -0,0 +1,58 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +import UserSettingsStore from '../../../UserSettingsStore'; + +const React = require('react'); + +module.exports = React.createClass({ + displayName: 'LoginPage', + + render: function() { + if (UserSettingsStore.getTheme() === 'status') { + return ( +
+
+ Status +
+
+
+

Status Community Chat

+
+ A safer, decentralised communication platform powered by Riot +
+
+ { this.props.children } +
+

This channel is for our development community.

+

Interested in SNT and discussions on the cryptocurrency market?

+

Join Telegram Chat

+
+
+
+ ); + } + else { + return ( +
+ { this.props.children } +
+ ); + } + }, +}); diff --git a/src/components/views/login/LoginPageFooter.js b/src/components/views/login/LoginPageFooter.js deleted file mode 100644 index e4eca9b8b3..0000000000 --- a/src/components/views/login/LoginPageFooter.js +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -'use strict'; - -import { _t } from '../../../languageHandler'; -import React from 'react'; - -module.exports = React.createClass({ - displayName: 'LoginPageFooter', - - render: function() { - return ( -
- ); - }, -}); diff --git a/src/components/views/login/LoginPageHeader.js b/src/components/views/login/LoginPageHeader.js deleted file mode 100644 index bef7fa5e0b..0000000000 --- a/src/components/views/login/LoginPageHeader.js +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -'use strict'; - -import UserSettingsStore from '../../../UserSettingsStore'; - -const React = require('react'); - -module.exports = React.createClass({ - displayName: 'LoginPageHeader', - - render: function() { - let themeBranding; - if (UserSettingsStore.getTheme() === 'status') { - themeBranding =
-
- Status -
-
-

Status Community Chat

-
- A safer, decentralised communication platform powered by Riot -
-
-
; - } - else { - themeBranding =
; - } - - return themeBranding; - }, -}); From 59b2189909ba9ff074c613987e18b5ca01d3c591 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 24 Oct 2017 23:58:54 +0100 Subject: [PATCH 04/32] unbreak tests --- src/UserSettingsStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index ede5a157a8..eca6d916a9 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -187,7 +187,7 @@ export default { syncedSettings = this.getSyncedSettings(); } if (!syncedSettings || !syncedSettings.theme) { - theme = SdkConfig.get().default_theme || 'light'; + theme = (SdkConfig.get() ? SdkConfig.get().default_theme : undefined) || 'light'; } else { theme = syncedSettings.theme; From adbea44d70826dad20ffbcdf50098ff807248173 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 25 Oct 2017 01:30:09 +0100 Subject: [PATCH 05/32] hide login options for status --- src/components/views/login/PasswordLogin.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js index 484ee01f4e..eb89bc00f1 100644 --- a/src/components/views/login/PasswordLogin.js +++ b/src/components/views/login/PasswordLogin.js @@ -20,7 +20,7 @@ import classNames from 'classnames'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import {field_input_incorrect} from '../../../UiEffects'; - +import UserSettingsStore from '../../../UserSettingsStore'; /** * A pure UI component which displays a username/password form. @@ -210,9 +210,10 @@ class PasswordLogin extends React.Component { const loginField = this.renderLoginField(this.state.loginType, matrixIdText === ''); - return ( -
-
+ const theme = UserSettingsStore.getTheme(); + let loginType; + if (theme !== 'status') { + loginType = (
{ _t('Phone') }
+ ); + } + + return ( +
+ + { loginType } { loginField } {this._passwordField = e;}} type="password" name="password" From 67cc02df3b3a938972fcf33969fa9bdb00b8e841 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 25 Oct 2017 01:37:06 +0100 Subject: [PATCH 06/32] hide header when error is up --- src/components/structures/login/Login.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index f5f4f8cd69..c31bdb1cca 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -354,6 +354,7 @@ module.exports = React.createClass({ } let serverConfig; + let header; if (theme !== 'status') { serverConfig = ; + + header =

{ _t('Sign in') }

; + } + else { + if (!this.state.errorText) { + header =

{ _t('Sign in to get started') }

; + } } return ( @@ -370,11 +378,9 @@ module.exports = React.createClass({
-

{ theme !== 'status' ? _t('Sign in') : _t('Sign in to get started') } - { loader } -

+ { header }
- { this.state.errorText } + { this.state.errorText }
{ this.componentForStep(this.state.currentFlow) } { serverConfig } From eb4b7c78a048b5ad2494e48ec6ab34c4d170bf52 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 25 Oct 2017 02:04:02 +0100 Subject: [PATCH 07/32] skin register screen --- .../structures/login/Registration.js | 46 +++++++++++------ .../views/login/RegistrationForm.js | 50 +++++++++++-------- 2 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 8151c1e65c..15e6b536c4 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -26,6 +26,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import RegistrationForm from '../../views/login/RegistrationForm'; import RtsClient from '../../../RtsClient'; import { _t } from '../../../languageHandler'; +import UserSettingsStore from '../../../UserSettingsStore'; const MIN_PASSWORD_LENGTH = 6; @@ -327,6 +328,8 @@ module.exports = React.createClass({ const Spinner = sdk.getComponent("elements.Spinner"); const ServerConfig = sdk.getComponent('views.login.ServerConfig'); + const theme = UserSettingsStore.getTheme(); + let registerBody; if (this.state.doingUIAuth) { registerBody = ( @@ -345,9 +348,19 @@ module.exports = React.createClass({ } else if (this.state.busy || this.state.teamServerBusy) { registerBody = ; } else { - let errorSection; - if (this.state.errorText) { - errorSection =
{ this.state.errorText }
; + let serverConfigSection; + if (theme !== 'status') { + serverConfigSection = ( + + ); } registerBody = (
@@ -363,16 +376,7 @@ module.exports = React.createClass({ onRegisterClick={this.onFormSubmit} onTeamSelected={this.onTeamSelected} /> - { errorSection } - + { serverConfigSection }
); } @@ -385,6 +389,17 @@ module.exports = React.createClass({ ); } + + let header; + let errorText; + if (theme === 'status' && this.state.errorText) { + header =
{ this.state.errorText }
; + } + else { + header =

{ _t('Create an account') }

; + errorText =
{ this.state.errorText }
; + } + return (
@@ -394,11 +409,12 @@ module.exports = React.createClass({ this.state.teamSelected.domain + "/icon.png" : null} /> -

{ _t('Create an account') }

+ { header } { registerBody } - { _t('I already have an account') } + { theme === 'status' ? _t('Sign in') : _t('I already have an account') } + { errorText } { returnToAppJsx }
diff --git a/src/components/views/login/RegistrationForm.js b/src/components/views/login/RegistrationForm.js index 9c7c75b125..7574b68418 100644 --- a/src/components/views/login/RegistrationForm.js +++ b/src/components/views/login/RegistrationForm.js @@ -22,6 +22,7 @@ import Email from '../../../email'; import { looksValid as phoneNumberLooksValid } from '../../../phonenumber'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; +import UserSettingsStore from '../../../UserSettingsStore'; const FIELD_EMAIL = 'field_email'; const FIELD_PHONE_COUNTRY = 'field_phone_country'; @@ -305,29 +306,34 @@ module.exports = React.createClass({ } } + const theme = UserSettingsStore.getTheme(); + const CountryDropdown = sdk.getComponent('views.login.CountryDropdown'); - const phoneSection = ( -
- - -
- ); + let phoneSection; + if (theme !== "status") { + phoneSection = ( +
+ + +
+ ); + } const registerButton = ( From ae40ef44606a34e362229a2b1746cd71456ee548 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 25 Oct 2017 02:18:14 +0100 Subject: [PATCH 08/32] fix error layouts --- src/components/structures/login/Login.js | 13 ++++++++++--- src/components/structures/login/Registration.js | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index c31bdb1cca..44363d83ad 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -373,15 +373,22 @@ module.exports = React.createClass({ } } + let errorTextSection; + if (this.state.errorText) { + errorTextSection = ( +
+ { this.state.errorText } +
+ ); + } + return (
{ header } -
- { this.state.errorText } -
+ { errorTextSection } { this.componentForStep(this.state.currentFlow) } { serverConfig } diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 15e6b536c4..4e95b62be3 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -397,7 +397,9 @@ module.exports = React.createClass({ } else { header =

{ _t('Create an account') }

; - errorText =
{ this.state.errorText }
; + if (this.state.errorText) { + errorText =
{ this.state.errorText }
; + } } return ( From 6beb604cd0dd14172ab7655c4027597cb84d305f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 25 Oct 2017 02:31:30 +0100 Subject: [PATCH 09/32] fascist linting >:( --- src/UserSettingsStore.js | 3 ++- src/components/views/login/LoginPage.js | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index eca6d916a9..ec6184f61a 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -189,7 +189,8 @@ export default { if (!syncedSettings || !syncedSettings.theme) { theme = (SdkConfig.get() ? SdkConfig.get().default_theme : undefined) || 'light'; } - else { + else + { theme = syncedSettings.theme; } return theme; diff --git a/src/components/views/login/LoginPage.js b/src/components/views/login/LoginPage.js index a07997727b..fa51426059 100644 --- a/src/components/views/login/LoginPage.js +++ b/src/components/views/login/LoginPage.js @@ -28,13 +28,14 @@ module.exports = React.createClass({ return (
- Status + Status
{ this.props.children } @@ -47,7 +48,8 @@ module.exports = React.createClass({
); } - else { + else + { return (
{ this.props.children } From b3a85934682b54e56734d6a26c909c25bffc355e Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 25 Oct 2017 22:48:27 +0100 Subject: [PATCH 10/32] make tinter coarsely theme aware --- src/Tinter.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Tinter.js b/src/Tinter.js index 6b23df8c9b..81cc48c7c0 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -1,5 +1,6 @@ /* Copyright 2015 OpenMarket Ltd +Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,6 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +import UserSettingsStore from './UserSettingsStore'; + // FIXME: these vars should be bundled up and attached to // module.exports otherwise this will break when included by both // react-sdk and apps layered on top. @@ -178,8 +181,11 @@ module.exports = { } if (!primaryColor) { - primaryColor = "#76CFA6"; // Vector green - secondaryColor = "#EAF5F0"; // Vector light green + const theme = UserSettingsStore.getTheme(); + // FIXME: get this out of the theme CSS itself somehow? + // we could store it in a string CSS attrib somewhere we could sniff... + primaryColor = theme === 'status' ? "#6CC1F6" : "#76CFA6"; // Vector green + secondaryColor = theme === 'status' ? "#586C7B" : "#EAF5F0"; // Vector light green } if (!secondaryColor) { From ac7a94afb22a77f61973c2d5e5c3fe82fc4ecd29 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 26 Oct 2017 01:43:42 +0100 Subject: [PATCH 11/32] apply theme tint at launch --- src/components/structures/MatrixChat.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 9e476714ec..d4759a0e23 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -276,6 +276,9 @@ module.exports = React.createClass({ this._windowWidth = 10000; this.handleResize(); window.addEventListener('resize', this.handleResize); + + // check we have the right tint applied for this theme + Tinter.tint(); }, componentDidMount: function() { From 5a9dae5ff1f1e990e05c132a404502eb58ee82a5 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 26 Oct 2017 01:44:05 +0100 Subject: [PATCH 12/32] use generic 'text button' for delete buttons in UserSettings --- src/components/structures/UserSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index e98bb844cc..beaf1b04b5 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -205,7 +205,7 @@ const IgnoredUser = React.createClass({ render: function() { return (
  • - + { _t("Unignore") } { this.props.userId } From deb0f902e31541f83eeaa84b482a053c7e2006c1 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 26 Oct 2017 01:59:18 +0100 Subject: [PATCH 13/32] linting --- src/UserSettingsStore.js | 4 +--- src/components/structures/UserSettings.js | 2 +- src/components/views/login/LoginPage.js | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index 65973c0763..c1d77b120b 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -188,9 +188,7 @@ export default { } if (!syncedSettings || !syncedSettings.theme) { theme = (SdkConfig.get() ? SdkConfig.get().default_theme : undefined) || 'light'; - } - else - { + } else { theme = syncedSettings.theme; } return theme; diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index beaf1b04b5..30828bdc85 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -181,7 +181,7 @@ const THEMES = [ }, { id: 'theme', - label: _td('Status.im theme'), + label: 'Status.im theme', value: 'status', }, ]; diff --git a/src/components/views/login/LoginPage.js b/src/components/views/login/LoginPage.js index fa51426059..a1a5000227 100644 --- a/src/components/views/login/LoginPage.js +++ b/src/components/views/login/LoginPage.js @@ -47,9 +47,7 @@ module.exports = React.createClass({
  • ); - } - else - { + } else { return (
    { this.props.children } From 5c32b5b11a94cef53b7bf31f64eeef9f00446b7a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 26 Oct 2017 02:10:03 +0100 Subject: [PATCH 14/32] fix i18n --- src/components/structures/UserSettings.js | 2 +- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 30828bdc85..beaf1b04b5 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -181,7 +181,7 @@ const THEMES = [ }, { id: 'theme', - label: 'Status.im theme', + label: _td('Status.im theme'), value: 'status', }, ]; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index d69374acd1..cf6ee70ddf 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -904,5 +904,6 @@ "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.", "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", - "Import": "Import" + "Import": "Import", + "Status.im theme": "Status.im theme" } From e6c3483c8b37df93f239aa1735d4858ac43a7d73 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Oct 2017 09:58:05 +0100 Subject: [PATCH 15/32] Add correct telegram link --- src/components/views/login/LoginPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/login/LoginPage.js b/src/components/views/login/LoginPage.js index a1a5000227..32f090d361 100644 --- a/src/components/views/login/LoginPage.js +++ b/src/components/views/login/LoginPage.js @@ -42,7 +42,7 @@ module.exports = React.createClass({

    This channel is for our development community.

    Interested in SNT and discussions on the cryptocurrency market?

    -

    Join Telegram Chat

    +

    Join Telegram Chat

    From 14d9743e303097f26182f80d45d0e956a15cebbe Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 26 Oct 2017 17:22:17 +0100 Subject: [PATCH 16/32] unbreak reg --- src/components/views/login/RegistrationForm.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/login/RegistrationForm.js b/src/components/views/login/RegistrationForm.js index 7574b68418..07418c4843 100644 --- a/src/components/views/login/RegistrationForm.js +++ b/src/components/views/login/RegistrationForm.js @@ -123,7 +123,7 @@ module.exports = React.createClass({ password: this.refs.password.value.trim(), email: email, phoneCountry: this.state.phoneCountry, - phoneNumber: this.refs.phoneNumber.value.trim(), + phoneNumber: this.refs.phoneNumber ? this.refs.phoneNumber.value.trim() : '', }); if (promise) { @@ -181,7 +181,7 @@ module.exports = React.createClass({ this.markFieldValid(field_id, emailValid, "RegistrationForm.ERR_EMAIL_INVALID"); break; case FIELD_PHONE_NUMBER: - const phoneNumber = this.refs.phoneNumber.value; + const phoneNumber = this.refs.phoneNumber ? this.refs.phoneNumber.value : ''; const phoneNumberValid = phoneNumber === '' || phoneNumberLooksValid(phoneNumber); this.markFieldValid(field_id, phoneNumberValid, "RegistrationForm.ERR_PHONE_NUMBER_INVALID"); break; From 655d0c615a6bfb627440971cc337de307c22a024 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 26 Oct 2017 17:57:49 +0100 Subject: [PATCH 17/32] remove spurious Sign In button and legacy Return to App buttons --- src/components/structures/login/Login.js | 5 ++++- src/components/structures/login/Registration.js | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 44363d83ad..789b066074 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -346,12 +346,15 @@ module.exports = React.createClass({ } let returnToAppJsx; - if (this.props.onCancelClick && theme !== 'status') { + /* + // with the advent of ILAG I don't think we need this any more + if (this.props.onCancelClick) { returnToAppJsx = { _t('Return to app') } ; } + */ let serverConfig; let header; diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 4e95b62be3..5634c28197 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -382,6 +382,8 @@ module.exports = React.createClass({ } let returnToAppJsx; + /* + // with the advent of ILAG I don't think we need this any more if (this.props.onCancelClick) { returnToAppJsx = ( @@ -389,6 +391,7 @@ module.exports = React.createClass({ ); } + */ let header; let errorText; @@ -402,6 +405,15 @@ module.exports = React.createClass({ } } + let signIn; + if (!this.state.doingUIAuth) { + signIn = ( + + { theme === 'status' ? _t('Sign in') : _t('I already have an account') } + + ); + } + return (
    @@ -413,9 +425,7 @@ module.exports = React.createClass({ /> { header } { registerBody } - - { theme === 'status' ? _t('Sign in') : _t('I already have an account') } - + { signIn } { errorText } { returnToAppJsx } From 015aed05973e28c7b3f75ed415af0479f72277e2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 27 Oct 2017 01:03:04 +0100 Subject: [PATCH 18/32] hide optionality of email for status --- src/components/views/login/RegistrationForm.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/views/login/RegistrationForm.js b/src/components/views/login/RegistrationForm.js index 07418c4843..426cc41dea 100644 --- a/src/components/views/login/RegistrationForm.js +++ b/src/components/views/login/RegistrationForm.js @@ -274,10 +274,13 @@ module.exports = React.createClass({ render: function() { const self = this; + const theme = UserSettingsStore.getTheme(); + const emailPlaceholder = theme === 'status' ? _t("Email address") : _t("Email address (optional)"); + const emailSection = (
    Date: Fri, 27 Oct 2017 01:09:37 +0100 Subject: [PATCH 19/32] target blank for tg --- src/components/views/login/LoginPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/login/LoginPage.js b/src/components/views/login/LoginPage.js index 32f090d361..b5e2faedec 100644 --- a/src/components/views/login/LoginPage.js +++ b/src/components/views/login/LoginPage.js @@ -42,7 +42,7 @@ module.exports = React.createClass({

    This channel is for our development community.

    Interested in SNT and discussions on the cryptocurrency market?

    -

    Join Telegram Chat

    +

    Join Telegram Chat

    From 1bf3ef6de4128a1bf2211c5f6d11db6aed05869b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 27 Oct 2017 01:23:50 +0100 Subject: [PATCH 20/32] fix password reset --- .../structures/login/ForgotPassword.js | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index f14d64528f..0e49a59936 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -17,13 +17,14 @@ limitations under the License. 'use strict'; -const React = require('react'); +import React from 'react'; import { _t } from '../../../languageHandler'; -const sdk = require('../../../index'); -const Modal = require("../../../Modal"); -const MatrixClientPeg = require('../../../MatrixClientPeg'); +import sdk from '../../../index'; +import Modal from "../../../Modal"; +import MatrixClientPeg from "../../../MatrixClientPeg"; -const PasswordReset = require("../../../PasswordReset"); +import PasswordReset from "../../../PasswordReset"; +import UserSettingsStore from "../../../UserSettingsStore"; module.exports = React.createClass({ displayName: 'ForgotPassword', @@ -183,6 +184,22 @@ module.exports = React.createClass({
    ); } else { + let theme = UserSettingsStore.getTheme(); + + let serverConfigSection; + if (theme !== 'status') { + serverConfigSection = ( + + ); + } + resetPasswordJsx = (
    @@ -210,16 +227,7 @@ module.exports = React.createClass({
    - -
    -
    + { serverConfigSection } { _t('Return to login screen') } From e3f896c5e091cb0199afe9d9766c844afea7f3ba Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 27 Oct 2017 01:35:21 +0100 Subject: [PATCH 21/32] don't forget login prompt class --- src/components/structures/login/ForgotPassword.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index 0e49a59936..851d13b23e 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -167,7 +167,7 @@ module.exports = React.createClass({ resetPasswordJsx = ; } else if (this.state.progress === "sent_email") { resetPasswordJsx = ( -
    +
    { _t('An email has been sent to') } { this.state.email }. { _t("Once you've followed the link it contains, click below") }.
    +

    { _t('Your password has been reset') }.

    { _t('You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device') }.

    Date: Fri, 27 Oct 2017 14:23:16 +0100 Subject: [PATCH 22/32] resolve matrix.status.im v. matrix.org confusion --- src/components/structures/login/Login.js | 12 +++++++++++- src/components/views/login/PasswordLogin.js | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 789b066074..fa1bd2e6b5 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -105,7 +105,17 @@ module.exports = React.createClass({ if (error.httpStatus == 400 && usingEmail) { errorText = _t('This Home Server does not support login using email address.'); } else if (error.httpStatus === 401 || error.httpStatus === 403) { - errorText = _t('Incorrect username and/or password.'); + const theme = UserSettingsStore.getTheme(); + if (theme === "status") { + errorText = ( +
    +
    Incorrect username and/or password.
    +
    Please note you are logging into the matrix.status.im server, not matrix.org.
    +
    + ); + } else { + errorText = _t('Incorrect username and/or password.'); + } } else { // other errors, not specific to doing a password login errorText = this._errorTextFromError(error); diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js index eb89bc00f1..8af148dc6c 100644 --- a/src/components/views/login/PasswordLogin.js +++ b/src/components/views/login/PasswordLogin.js @@ -122,6 +122,8 @@ class PasswordLogin extends React.Component { mx_Login_field_disabled: disabled, }; + const theme = UserSettingsStore.getTheme(); + switch(loginType) { case PasswordLogin.LOGIN_FIELD_EMAIL: classes.mx_Login_email = true; @@ -144,7 +146,7 @@ class PasswordLogin extends React.Component { type="text" name="username" // make it a little easier for browser's remember-password onChange={this.onUsernameChanged} - placeholder={_t('User name')} + placeholder={theme === 'status' ? "Username on matrix.status.im" : _t("User name")} value={this.state.username} autoFocus disabled={disabled} From 672fbb287316641bdcccf0b6314a40bd165f23a9 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 28 Oct 2017 18:33:38 +0100 Subject: [PATCH 23/32] hopefully fix NPE on toLowerCase --- src/components/structures/login/Registration.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 17204ee4e8..2403610416 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -303,7 +303,9 @@ module.exports = React.createClass({ } : {}; return this._matrixClient.register( - this.state.formVals.username.toLowerCase(), + (this.state.formVals.username ? + this.state.formVals.username.toLowerCase() : + this.state.formVals.username), this.state.formVals.password, undefined, // session id: included in the auth dict already auth, From 1ae9103d78bf6f6d878972fb585a34bfbf93955d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 1 Nov 2017 15:24:02 +0000 Subject: [PATCH 24/32] evil evil hack to temporarily hide avatar changes in status autojoin rooms --- src/shouldHideEvent.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/shouldHideEvent.js b/src/shouldHideEvent.js index 1501e28875..fbb0ee884e 100644 --- a/src/shouldHideEvent.js +++ b/src/shouldHideEvent.js @@ -41,6 +41,24 @@ export default function shouldHideEvent(ev, syncedSettings) { const eventDiff = memberEventDiff(ev); if (eventDiff.isMemberEvent) { + // XXX: horrific hack for Status until granular settings lands, where these + // can then be added into room state + if (['!YkNaCvrOXIQKPMhUHC:status.im', // #announcements:status.im + '!TSECabqXwnmkYVTfdX:status.im', // #general:status.im + '!FhCoxZbSjazJYFlCOY:status.im', // #dev-status:status.im + '!hHZWxpKcmFSjXcFHZC:status.im', // #news-articles:status.im + '!gIfSnanKtRcKDpUcmR:status.im', // #introductions:status.im + '!eGsKellGrAmpROBwXT:status.im', // #book-club:status.im + '!AqnfKJOcxeeuMOcqRL:status.im', // #music:status.im + ].includes(ev.getRoomId()) + && (/* eventDiff.isJoin || + eventDiff.isPart || + eventDiff.isDisplaynameChange || */ + eventDiff.isAvatarChange)) + { + return true; + } + if (syncedSettings['hideJoinLeaves'] && (eventDiff.isJoin || eventDiff.isPart)) return true; const isMemberAvatarDisplaynameChange = eventDiff.isAvatarChange || eventDiff.isDisplaynameChange; if (syncedSettings['hideAvatarDisplaynameChanges'] && isMemberAvatarDisplaynameChange) return true; From b3a7d25ef8c36242804750180b0c906a971b4a2d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 1 Nov 2017 15:31:44 +0000 Subject: [PATCH 25/32] lint hell --- src/shouldHideEvent.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/shouldHideEvent.js b/src/shouldHideEvent.js index fbb0ee884e..7c156dd7a5 100644 --- a/src/shouldHideEvent.js +++ b/src/shouldHideEvent.js @@ -54,8 +54,7 @@ export default function shouldHideEvent(ev, syncedSettings) { && (/* eventDiff.isJoin || eventDiff.isPart || eventDiff.isDisplaynameChange || */ - eventDiff.isAvatarChange)) - { + eventDiff.isAvatarChange)) { return true; } From b2ddcb8027b95cb6bea0306561fb8d651aa32f0f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 4 Nov 2017 23:43:20 +0000 Subject: [PATCH 26/32] tint the colours in the theme rather than hardcode vector green --- src/Tinter.js | 45 ++++++++++++++----- .../views/room_settings/ColorSettings.js | 2 +- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/Tinter.js b/src/Tinter.js index 81cc48c7c0..cc3e424f2e 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -23,11 +23,12 @@ import UserSettingsStore from './UserSettingsStore'; const DEBUG = 0; -// The colour keys to be replaced as referred to in CSS +// The default colour keys to be replaced as referred to in CSS +// (should be overridden by .mx_theme_accentColor and .mx_theme_secondaryAccentColor) const keyRgb = [ "rgb(118, 207, 166)", // Vector Green "rgb(234, 245, 240)", // Vector Light Green - "rgb(211, 239, 225)", // BottomLeftMenu overlay (20% Vector Green) + "rgb(211, 239, 225)", // Unused: BottomLeftMenu (20% Green overlaid on Light Green) ]; // Some algebra workings for calculating the tint % of Vector Green & Light Green @@ -41,7 +42,7 @@ const keyRgb = [ const keyHex = [ "#76CFA6", // Vector Green "#EAF5F0", // Vector Light Green - "#D3EFE1", // BottomLeftMenu overlay (20% Vector Green overlaid on Vector Light Green) + "#D3EFE1", // Unused: BottomLeftMenu (20% Green overlaid on Light Green) "#FFFFFF", // white highlights of the SVGs (for switching to dark theme) ]; @@ -80,7 +81,20 @@ const svgAttrs = [ let cached = false; function calcCssFixups() { - if (DEBUG) console.log("calcSvgFixups start"); + if (DEBUG) console.log("calcCssFixups start"); + + // update keyRgb from the current theme CSS itself, if it defines it + if (document.getElementById('mx_theme_accentColor')) { + keyRgb[0] = window.getComputedStyle( + document.getElementById('mx_theme_accentColor') + ).color; + } + if (document.getElementById('mx_theme_secondaryAccentColor')) { + keyRgb[1] = window.getComputedStyle( + document.getElementById('mx_theme_secondaryAccentColor') + ).color; + } + for (let i = 0; i < document.styleSheets.length; i++) { const ss = document.styleSheets[i]; if (!ss) continue; // well done safari >:( @@ -103,13 +117,22 @@ function calcCssFixups() { // Iterating through the CSS looking for matches to hack on feels // pretty horrible anyway. And what if the application skin doesn't use // Vector Green as its primary color? + // --richvdh + + // Yes, tinting assumes that you are using the Riot skin for now. + // The right solution will be to move the CSS over to react-sdk. + // And yes, the default assets for the base skin might as well use + // Vector Green as any other colour. + // --matthew if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue; - + if (ss.disabled) continue; if (!ss.cssRules) continue; + for (let j = 0; j < ss.cssRules.length; j++) { const rule = ss.cssRules[j]; if (!rule.style) continue; + if (rule.selectorText && rule.selectorText.match(/#mx_theme/)) continue; for (let k = 0; k < cssAttrs.length; k++) { const attr = cssAttrs[k]; for (let l = 0; l < keyRgb.length; l++) { @@ -124,7 +147,7 @@ function calcCssFixups() { } } } - if (DEBUG) console.log("calcSvgFixups end"); + if (DEBUG) console.log("calcCssFixups end"); } function applyCssFixups() { @@ -174,6 +197,10 @@ module.exports = { tintables.push(tintable); }, + getKeyRgb: function() { + return keyRgb; + }, + tint: function(primaryColor, secondaryColor, tertiaryColor) { if (!cached) { calcCssFixups(); @@ -182,10 +209,8 @@ module.exports = { if (!primaryColor) { const theme = UserSettingsStore.getTheme(); - // FIXME: get this out of the theme CSS itself somehow? - // we could store it in a string CSS attrib somewhere we could sniff... - primaryColor = theme === 'status' ? "#6CC1F6" : "#76CFA6"; // Vector green - secondaryColor = theme === 'status' ? "#586C7B" : "#EAF5F0"; // Vector light green + primaryColor = keyRgb[0]; + secondaryColor = keyRgb[1]; } if (!secondaryColor) { diff --git a/src/components/views/room_settings/ColorSettings.js b/src/components/views/room_settings/ColorSettings.js index bfdaa49f65..c2bfa6ea73 100644 --- a/src/components/views/room_settings/ColorSettings.js +++ b/src/components/views/room_settings/ColorSettings.js @@ -25,7 +25,7 @@ import dis from '../../../dispatcher'; const ROOM_COLORS = [ // magic room default values courtesy of Ribot - ["#76cfa6", "#eaf5f0"], + [Tinter.getKeyRgb()[0], Tinter.getKeyRgb()[1]], ["#81bddb", "#eaf1f4"], ["#bd79cb", "#f3eaf5"], ["#c65d94", "#f5eaef"], From e72e30197a23693faae45b1d3bc2190e5d30a26d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 4 Nov 2017 23:50:57 +0000 Subject: [PATCH 27/32] calculate new CSS tinting when we change theme --- src/Tinter.js | 166 ++++++++++++------------ src/components/structures/MatrixChat.js | 2 + 2 files changed, 86 insertions(+), 82 deletions(-) diff --git a/src/Tinter.js b/src/Tinter.js index cc3e424f2e..c35e65a21e 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -80,85 +80,6 @@ const svgAttrs = [ let cached = false; -function calcCssFixups() { - if (DEBUG) console.log("calcCssFixups start"); - - // update keyRgb from the current theme CSS itself, if it defines it - if (document.getElementById('mx_theme_accentColor')) { - keyRgb[0] = window.getComputedStyle( - document.getElementById('mx_theme_accentColor') - ).color; - } - if (document.getElementById('mx_theme_secondaryAccentColor')) { - keyRgb[1] = window.getComputedStyle( - document.getElementById('mx_theme_secondaryAccentColor') - ).color; - } - - for (let i = 0; i < document.styleSheets.length; i++) { - const ss = document.styleSheets[i]; - if (!ss) continue; // well done safari >:( - // Chromium apparently sometimes returns null here; unsure why. - // see $14534907369972FRXBx:matrix.org in HQ - // ...ah, it's because there's a third party extension like - // privacybadger inserting its own stylesheet in there with a - // resource:// URI or something which results in a XSS error. - // See also #vector:matrix.org/$145357669685386ebCfr:matrix.org - // ...except some browsers apparently return stylesheets without - // hrefs, which we have no choice but ignore right now - - // XXX seriously? we are hardcoding the name of vector's CSS file in - // here? - // - // Why do we need to limit it to vector's CSS file anyway - if there - // are other CSS files affecting the doc don't we want to apply the - // same transformations to them? - // - // Iterating through the CSS looking for matches to hack on feels - // pretty horrible anyway. And what if the application skin doesn't use - // Vector Green as its primary color? - // --richvdh - - // Yes, tinting assumes that you are using the Riot skin for now. - // The right solution will be to move the CSS over to react-sdk. - // And yes, the default assets for the base skin might as well use - // Vector Green as any other colour. - // --matthew - - if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue; - if (ss.disabled) continue; - if (!ss.cssRules) continue; - - for (let j = 0; j < ss.cssRules.length; j++) { - const rule = ss.cssRules[j]; - if (!rule.style) continue; - if (rule.selectorText && rule.selectorText.match(/#mx_theme/)) continue; - for (let k = 0; k < cssAttrs.length; k++) { - const attr = cssAttrs[k]; - for (let l = 0; l < keyRgb.length; l++) { - if (rule.style[attr] === keyRgb[l]) { - cssFixups.push({ - style: rule.style, - attr: attr, - index: l, - }); - } - } - } - } - } - if (DEBUG) console.log("calcCssFixups end"); -} - -function applyCssFixups() { - if (DEBUG) console.log("applyCssFixups start"); - for (let i = 0; i < cssFixups.length; i++) { - const cssFixup = cssFixups[i]; - cssFixup.style[cssFixup.attr] = colors[cssFixup.index]; - } - if (DEBUG) console.log("applyCssFixups end"); -} - function hexToRgb(color) { if (color[0] === '#') color = color.slice(1); if (color.length === 3) { @@ -203,7 +124,7 @@ module.exports = { tint: function(primaryColor, secondaryColor, tertiaryColor) { if (!cached) { - calcCssFixups(); + this.calcCssFixups(); cached = true; } @@ -245,7 +166,7 @@ module.exports = { if (DEBUG) console.log("Tinter.tint"); // go through manually fixing up the stylesheets. - applyCssFixups(); + this.applyCssFixups(); // tell all the SVGs to go fix themselves up // we don't do this as a dispatch otherwise it will visually lag @@ -267,6 +188,85 @@ module.exports = { }); }, + calcCssFixups: function() { + if (DEBUG) console.log("calcCssFixups start"); + + // update keyRgb from the current theme CSS itself, if it defines it + if (document.getElementById('mx_theme_accentColor')) { + keyRgb[0] = window.getComputedStyle( + document.getElementById('mx_theme_accentColor') + ).color; + } + if (document.getElementById('mx_theme_secondaryAccentColor')) { + keyRgb[1] = window.getComputedStyle( + document.getElementById('mx_theme_secondaryAccentColor') + ).color; + } + + for (let i = 0; i < document.styleSheets.length; i++) { + const ss = document.styleSheets[i]; + if (!ss) continue; // well done safari >:( + // Chromium apparently sometimes returns null here; unsure why. + // see $14534907369972FRXBx:matrix.org in HQ + // ...ah, it's because there's a third party extension like + // privacybadger inserting its own stylesheet in there with a + // resource:// URI or something which results in a XSS error. + // See also #vector:matrix.org/$145357669685386ebCfr:matrix.org + // ...except some browsers apparently return stylesheets without + // hrefs, which we have no choice but ignore right now + + // XXX seriously? we are hardcoding the name of vector's CSS file in + // here? + // + // Why do we need to limit it to vector's CSS file anyway - if there + // are other CSS files affecting the doc don't we want to apply the + // same transformations to them? + // + // Iterating through the CSS looking for matches to hack on feels + // pretty horrible anyway. And what if the application skin doesn't use + // Vector Green as its primary color? + // --richvdh + + // Yes, tinting assumes that you are using the Riot skin for now. + // The right solution will be to move the CSS over to react-sdk. + // And yes, the default assets for the base skin might as well use + // Vector Green as any other colour. + // --matthew + + if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue; + if (ss.disabled) continue; + if (!ss.cssRules) continue; + + for (let j = 0; j < ss.cssRules.length; j++) { + const rule = ss.cssRules[j]; + if (!rule.style) continue; + if (rule.selectorText && rule.selectorText.match(/#mx_theme/)) continue; + for (let k = 0; k < cssAttrs.length; k++) { + const attr = cssAttrs[k]; + for (let l = 0; l < keyRgb.length; l++) { + if (rule.style[attr] === keyRgb[l]) { + cssFixups.push({ + style: rule.style, + attr: attr, + index: l, + }); + } + } + } + } + } + if (DEBUG) console.log("calcCssFixups end"); + }, + + applyCssFixups: function() { + if (DEBUG) console.log("applyCssFixups start"); + for (let i = 0; i < cssFixups.length; i++) { + const cssFixup = cssFixups[i]; + cssFixup.style[cssFixup.attr] = colors[cssFixup.index]; + } + if (DEBUG) console.log("applyCssFixups end"); + }, + // XXX: we could just move this all into TintableSvg, but as it's so similar // to the CSS fixup stuff in Tinter (just that the fixups are stored in TintableSvg) // keeping it here for now. @@ -299,7 +299,9 @@ module.exports = { for (let k = 0; k < svgAttrs.length; k++) { const attr = svgAttrs[k]; for (let l = 0; l < keyHex.length; l++) { - if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) { + if (tag.getAttribute(attr) && + tag.getAttribute(attr).toUpperCase() === keyHex[l]) + { fixups.push({ node: tag, attr: attr, diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index acc1119105..15a8d2f31a 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -919,6 +919,8 @@ module.exports = React.createClass({ }); styleElements[theme].disabled = false; + Tinter.calcCssFixups(); + if (theme === 'dark') { // abuse the tinter to change all the SVG's #fff to #2d2d2d // XXX: obviously this shouldn't be hardcoded here. From 68115f5b9c9987e579e083062e47dc281e2e6bbd Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 5 Nov 2017 00:40:38 +0000 Subject: [PATCH 28/32] tint when theming correctly --- src/Tinter.js | 9 ++++++--- src/components/structures/MatrixChat.js | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Tinter.js b/src/Tinter.js index c35e65a21e..77af0859da 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -15,8 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -import UserSettingsStore from './UserSettingsStore'; - // FIXME: these vars should be bundled up and attached to // module.exports otherwise this will break when included by both // react-sdk and apps layered on top. @@ -122,6 +120,10 @@ module.exports = { return keyRgb; }, + getCurrentColors: function() { + return colors; + }, + tint: function(primaryColor, secondaryColor, tertiaryColor) { if (!cached) { this.calcCssFixups(); @@ -129,7 +131,6 @@ module.exports = { } if (!primaryColor) { - const theme = UserSettingsStore.getTheme(); primaryColor = keyRgb[0]; secondaryColor = keyRgb[1]; } @@ -191,6 +192,8 @@ module.exports = { calcCssFixups: function() { if (DEBUG) console.log("calcCssFixups start"); + cssFixups.length = 0; + // update keyRgb from the current theme CSS itself, if it defines it if (document.getElementById('mx_theme_accentColor')) { keyRgb[0] = window.getComputedStyle( diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 15a8d2f31a..6429ea1ce1 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -920,6 +920,8 @@ module.exports = React.createClass({ styleElements[theme].disabled = false; Tinter.calcCssFixups(); + const colors = Tinter.getCurrentColors(); + Tinter.tint(colors[0], colors[1]); if (theme === 'dark') { // abuse the tinter to change all the SVG's #fff to #2d2d2d From 58ee4d0a76a1ae65e38dbcbd8e013e1a066dd373 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 8 Nov 2017 06:55:07 -0800 Subject: [PATCH 29/32] rewrite the tinter to be ES6, and correctly cache fixups per theme --- src/Tinter.js | 267 +++++++++++++----------- src/components/structures/MatrixChat.js | 2 +- 2 files changed, 144 insertions(+), 125 deletions(-) diff --git a/src/Tinter.js b/src/Tinter.js index 77af0859da..fe4cafe744 100644 --- a/src/Tinter.js +++ b/src/Tinter.js @@ -15,69 +15,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -// FIXME: these vars should be bundled up and attached to -// module.exports otherwise this will break when included by both -// react-sdk and apps layered on top. - const DEBUG = 0; -// The default colour keys to be replaced as referred to in CSS -// (should be overridden by .mx_theme_accentColor and .mx_theme_secondaryAccentColor) -const keyRgb = [ - "rgb(118, 207, 166)", // Vector Green - "rgb(234, 245, 240)", // Vector Light Green - "rgb(211, 239, 225)", // Unused: BottomLeftMenu (20% Green overlaid on Light Green) -]; - -// Some algebra workings for calculating the tint % of Vector Green & Light Green -// x * 118 + (1 - x) * 255 = 234 -// x * 118 + 255 - 255 * x = 234 -// x * 118 - x * 255 = 234 - 255 -// (255 - 118) x = 255 - 234 -// x = (255 - 234) / (255 - 118) = 0.16 - -// The colour keys to be replaced as referred to in SVGs -const keyHex = [ - "#76CFA6", // Vector Green - "#EAF5F0", // Vector Light Green - "#D3EFE1", // Unused: BottomLeftMenu (20% Green overlaid on Light Green) - "#FFFFFF", // white highlights of the SVGs (for switching to dark theme) -]; - -// cache of our replacement colours -// defaults to our keys. -const colors = [ - keyHex[0], - keyHex[1], - keyHex[2], - keyHex[3], -]; - -const cssFixups = [ - // { - // style: a style object that should be fixed up taken from a stylesheet - // attr: name of the attribute to be clobbered, e.g. 'color' - // index: ordinal of primary, secondary or tertiary - // } -]; - -// CSS attributes to be fixed up -const cssAttrs = [ - "color", - "backgroundColor", - "borderColor", - "borderTopColor", - "borderBottomColor", - "borderLeftColor", -]; - -const svgAttrs = [ - "fill", - "stroke", -]; - -let cached = false; - +// utility to turn #rrggbb into [red,green,blue] function hexToRgb(color) { if (color[0] === '#') color = color.slice(1); if (color.length === 3) { @@ -92,15 +32,77 @@ function hexToRgb(color) { return [r, g, b]; } +// utility to turn [red,green,blue] into #rrggbb function rgbToHex(rgb) { const val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; return '#' + (0x1000000 + val).toString(16).slice(1); } -// List of functions to call when the tint changes. -const tintables = []; +class Tinter { + constructor() { + // The default colour keys to be replaced as referred to in CSS + // (should be overridden by .mx_theme_accentColor and .mx_theme_secondaryAccentColor) + this.keyRgb = [ + "rgb(118, 207, 166)", // Vector Green + "rgb(234, 245, 240)", // Vector Light Green + "rgb(211, 239, 225)", // Unused: BottomLeftMenu (20% Green overlaid on Light Green) + ]; + + // Some algebra workings for calculating the tint % of Vector Green & Light Green + // x * 118 + (1 - x) * 255 = 234 + // x * 118 + 255 - 255 * x = 234 + // x * 118 - x * 255 = 234 - 255 + // (255 - 118) x = 255 - 234 + // x = (255 - 234) / (255 - 118) = 0.16 + + // The colour keys to be replaced as referred to in SVGs + this.keyHex = [ + "#76CFA6", // Vector Green + "#EAF5F0", // Vector Light Green + "#D3EFE1", // Unused: BottomLeftMenu (20% Green overlaid on Light Green) + "#FFFFFF", // white highlights of the SVGs (for switching to dark theme) + ]; + + // cache of our replacement colours + // defaults to our keys. + this.colors = [ + this.keyHex[0], + this.keyHex[1], + this.keyHex[2], + this.keyHex[3], + ]; + + this.cssFixups = [ + // { theme: { + // style: a style object that should be fixed up taken from a stylesheet + // attr: name of the attribute to be clobbered, e.g. 'color' + // index: ordinal of primary, secondary or tertiary + // }, + // } + ]; + + // CSS attributes to be fixed up + this.cssAttrs = [ + "color", + "backgroundColor", + "borderColor", + "borderTopColor", + "borderBottomColor", + "borderLeftColor", + ]; + + this.svgAttrs = [ + "fill", + "stroke", + ]; + + // List of functions to call when the tint changes. + this.tintables = []; + + // the currently loaded theme (if any) + this.theme = undefined; + } -module.exports = { /** * Register a callback to fire when the tint changes. * This is used to rewrite the tintable SVGs with the new tint. @@ -112,27 +114,24 @@ module.exports = { * * @param {Function} tintable Function to call when the tint changes. */ - registerTintable: function(tintable) { - tintables.push(tintable); - }, + registerTintable(tintable) { + this.tintables.push(tintable); + } - getKeyRgb: function() { - return keyRgb; - }, + getKeyRgb() { + return this.keyRgb; + } - getCurrentColors: function() { - return colors; - }, + getCurrentColors() { + return this.colors; + } - tint: function(primaryColor, secondaryColor, tertiaryColor) { - if (!cached) { - this.calcCssFixups(); - cached = true; - } + tint(primaryColor, secondaryColor, tertiaryColor) { + this.calcCssFixups(); if (!primaryColor) { - primaryColor = keyRgb[0]; - secondaryColor = keyRgb[1]; + primaryColor = this.keyRgb[0]; + secondaryColor = this.keyRgb[1]; } if (!secondaryColor) { @@ -154,15 +153,15 @@ module.exports = { tertiaryColor = rgbToHex(rgb1); } - if (colors[0] === primaryColor && - colors[1] === secondaryColor && - colors[2] === tertiaryColor) { + if (this.colors[0] === primaryColor && + this.colors[1] === secondaryColor && + this.colors[2] === tertiaryColor) { return; } - colors[0] = primaryColor; - colors[1] = secondaryColor; - colors[2] = tertiaryColor; + this.colors[0] = primaryColor; + this.colors[1] = secondaryColor; + this.colors[2] = tertiaryColor; if (DEBUG) console.log("Tinter.tint"); @@ -171,41 +170,52 @@ module.exports = { // tell all the SVGs to go fix themselves up // we don't do this as a dispatch otherwise it will visually lag - tintables.forEach(function(tintable) { + this.tintables.forEach(function(tintable) { tintable(); }); - }, + } - tintSvgWhite: function(whiteColor) { + tintSvgWhite(whiteColor) { if (!whiteColor) { - whiteColor = colors[3]; + whiteColor = this.colors[3]; } - if (colors[3] === whiteColor) { + if (this.colors[3] === whiteColor) { return; } - colors[3] = whiteColor; - tintables.forEach(function(tintable) { + this.colors[3] = whiteColor; + this.tintables.forEach(function(tintable) { tintable(); }); - }, + } - calcCssFixups: function() { - if (DEBUG) console.log("calcCssFixups start"); - - cssFixups.length = 0; + setTheme(theme) { + this.theme = theme; // update keyRgb from the current theme CSS itself, if it defines it if (document.getElementById('mx_theme_accentColor')) { - keyRgb[0] = window.getComputedStyle( + this.keyRgb[0] = window.getComputedStyle( document.getElementById('mx_theme_accentColor') ).color; } if (document.getElementById('mx_theme_secondaryAccentColor')) { - keyRgb[1] = window.getComputedStyle( + this.keyRgb[1] = window.getComputedStyle( document.getElementById('mx_theme_secondaryAccentColor') ).color; } + this.calcCssFixups(); + } + + calcCssFixups() { + // cache our fixups + if (this.cssFixups[this.theme]) return; + + if (DEBUG) console.trace("calcCssFixups start for " + this.theme + " (checking " + + document.styleSheets.length + + " stylesheets)"); + + this.cssFixups[this.theme] = []; + for (let i = 0; i < document.styleSheets.length; i++) { const ss = document.styleSheets[i]; if (!ss) continue; // well done safari >:( @@ -236,7 +246,7 @@ module.exports = { // Vector Green as any other colour. // --matthew - if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue; + if (ss.href && !ss.href.match(new RegExp('/theme-' + this.theme + '.css$'))) continue; if (ss.disabled) continue; if (!ss.cssRules) continue; @@ -244,11 +254,11 @@ module.exports = { const rule = ss.cssRules[j]; if (!rule.style) continue; if (rule.selectorText && rule.selectorText.match(/#mx_theme/)) continue; - for (let k = 0; k < cssAttrs.length; k++) { - const attr = cssAttrs[k]; - for (let l = 0; l < keyRgb.length; l++) { - if (rule.style[attr] === keyRgb[l]) { - cssFixups.push({ + for (let k = 0; k < this.cssAttrs.length; k++) { + const attr = this.cssAttrs[k]; + for (let l = 0; l < this.keyRgb.length; l++) { + if (rule.style[attr] === this.keyRgb[l]) { + this.cssFixups[this.theme].push({ style: rule.style, attr: attr, index: l, @@ -258,22 +268,26 @@ module.exports = { } } } - if (DEBUG) console.log("calcCssFixups end"); - }, + if (DEBUG) console.log("calcCssFixups end (" + + this.cssFixups[this.theme].length + + " fixups)"); + } - applyCssFixups: function() { - if (DEBUG) console.log("applyCssFixups start"); - for (let i = 0; i < cssFixups.length; i++) { - const cssFixup = cssFixups[i]; - cssFixup.style[cssFixup.attr] = colors[cssFixup.index]; + applyCssFixups() { + if (DEBUG) console.log("applyCssFixups start (" + + this.cssFixups[this.theme].length + + " fixups)"); + for (let i = 0; i < this.cssFixups[this.theme].length; i++) { + const cssFixup = this.cssFixups[this.theme][i]; + cssFixup.style[cssFixup.attr] = this.colors[cssFixup.index]; } if (DEBUG) console.log("applyCssFixups end"); - }, + } // XXX: we could just move this all into TintableSvg, but as it's so similar // to the CSS fixup stuff in Tinter (just that the fixups are stored in TintableSvg) // keeping it here for now. - calcSvgFixups: function(svgs) { + calcSvgFixups(svgs) { // go through manually fixing up SVG colours. // we could do this by stylesheets, but keeping the stylesheets // updated would be a PITA, so just brute-force search for the @@ -299,11 +313,11 @@ module.exports = { const tags = svgDoc.getElementsByTagName("*"); for (let j = 0; j < tags.length; j++) { const tag = tags[j]; - for (let k = 0; k < svgAttrs.length; k++) { - const attr = svgAttrs[k]; - for (let l = 0; l < keyHex.length; l++) { + for (let k = 0; k < this.svgAttrs.length; k++) { + const attr = this.svgAttrs[k]; + for (let l = 0; l < this.keyHex.length; l++) { if (tag.getAttribute(attr) && - tag.getAttribute(attr).toUpperCase() === keyHex[l]) + tag.getAttribute(attr).toUpperCase() === this.keyHex[l]) { fixups.push({ node: tag, @@ -318,14 +332,19 @@ module.exports = { if (DEBUG) console.log("calcSvgFixups end"); return fixups; - }, + } - applySvgFixups: function(fixups) { + applySvgFixups(fixups) { if (DEBUG) console.log("applySvgFixups start for " + fixups); for (let i = 0; i < fixups.length; i++) { const svgFixup = fixups[i]; - svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]); + svgFixup.node.setAttribute(svgFixup.attr, this.colors[svgFixup.index]); } if (DEBUG) console.log("applySvgFixups end"); - }, -}; + } +} + +if (global.singletonTinter === undefined) { + global.singletonTinter = new Tinter(); +} +export default global.singletonTinter; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index ec3844a99e..5972611af8 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -922,7 +922,7 @@ module.exports = React.createClass({ }); styleElements[theme].disabled = false; - Tinter.calcCssFixups(); + Tinter.setTheme(theme); const colors = Tinter.getCurrentColors(); Tinter.tint(colors[0], colors[1]); From 2827bc071833a80594ff5433491e049a94eb817c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 11 Nov 2017 23:46:43 +0000 Subject: [PATCH 30/32] replace some of the status.im theme with general config options --- .../structures/login/ForgotPassword.js | 5 +-- src/components/structures/login/Login.js | 31 ++++++++++++------- .../structures/login/Registration.js | 4 ++- src/components/views/login/LoginPage.js | 1 + src/components/views/login/PasswordLogin.js | 12 +++---- .../views/login/RegistrationForm.js | 4 ++- src/i18n/strings/en_EN.json | 4 ++- 7 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index bdcc641391..8a2714d96a 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -24,7 +24,6 @@ import Modal from "../../../Modal"; import MatrixClientPeg from "../../../MatrixClientPeg"; import PasswordReset from "../../../PasswordReset"; -import UserSettingsStore from "../../../UserSettingsStore"; module.exports = React.createClass({ displayName: 'ForgotPassword', @@ -184,10 +183,8 @@ module.exports = React.createClass({
    ); } else { - let theme = UserSettingsStore.getTheme(); - let serverConfigSection; - if (theme !== 'status') { + if (!config.disable_custom_urls) { serverConfigSection = ( -
    Incorrect username and/or password.
    -
    Please note you are logging into the matrix.status.im server, not matrix.org.
    +
    { _t('Incorrect username and/or password.') }
    +
    + { _t('Please note you are logging into the %(hs)s server, not matrix.org.', + { + hs: this.props.defaultHsUrl.replace(/^https?:\/\//, '') + }) + } +
    ); } else { @@ -345,10 +351,8 @@ module.exports = React.createClass({ const ServerConfig = sdk.getComponent("login.ServerConfig"); const loader = this.state.busy ?
    : null; - const theme = UserSettingsStore.getTheme(); - let loginAsGuestJsx; - if (this.props.enableGuest && theme !== 'status') { + if (this.props.enableGuest) { loginAsGuestJsx = { _t('Login as guest') } @@ -366,9 +370,7 @@ module.exports = React.createClass({ } */ - let serverConfig; - let header; - if (theme !== 'status') { + if (!SdkConfig.get().disable_custom_urls) { serverConfig = ; + } + let serverConfig; + let header; + + // FIXME: remove status.im theme tweaks + const theme = UserSettingsStore.getTheme(); + if (theme !== "status") { header =

    { _t('Sign in') }

    ; } else { @@ -409,7 +418,7 @@ module.exports = React.createClass({
    { loginAsGuestJsx } { returnToAppJsx } - { theme !== 'status' ? this._renderLanguageSetting() : '' } + { !SdkConfig.get().disable_login_language_selector ? this._renderLanguageSetting() : '' }
    diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 2403610416..910d81ec33 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -27,6 +27,7 @@ import RegistrationForm from '../../views/login/RegistrationForm'; import RtsClient from '../../../RtsClient'; import { _t } from '../../../languageHandler'; import UserSettingsStore from '../../../UserSettingsStore'; +import SdkConfig from '../../../SdkConfig'; const MIN_PASSWORD_LENGTH = 6; @@ -351,7 +352,7 @@ module.exports = React.createClass({ registerBody = ; } else { let serverConfigSection; - if (theme !== 'status') { + if (!SdkConfig.get().disable_custom_urls) { serverConfigSection = ( { this.state.errorText }
    ; } diff --git a/src/components/views/login/LoginPage.js b/src/components/views/login/LoginPage.js index b5e2faedec..b971ecd1df 100644 --- a/src/components/views/login/LoginPage.js +++ b/src/components/views/login/LoginPage.js @@ -24,6 +24,7 @@ module.exports = React.createClass({ displayName: 'LoginPage', render: function() { + // FIXME: this should be turned into a proper skin with a StatusLoginPage component if (UserSettingsStore.getTheme() === 'status') { return (
    diff --git a/src/components/views/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js index 8af148dc6c..77b695ef12 100644 --- a/src/components/views/login/PasswordLogin.js +++ b/src/components/views/login/PasswordLogin.js @@ -20,7 +20,7 @@ import classNames from 'classnames'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import {field_input_incorrect} from '../../../UiEffects'; -import UserSettingsStore from '../../../UserSettingsStore'; +import SdkConfig from '../../../SdkConfig'; /** * A pure UI component which displays a username/password form. @@ -122,8 +122,6 @@ class PasswordLogin extends React.Component { mx_Login_field_disabled: disabled, }; - const theme = UserSettingsStore.getTheme(); - switch(loginType) { case PasswordLogin.LOGIN_FIELD_EMAIL: classes.mx_Login_email = true; @@ -146,7 +144,10 @@ class PasswordLogin extends React.Component { type="text" name="username" // make it a little easier for browser's remember-password onChange={this.onUsernameChanged} - placeholder={theme === 'status' ? "Username on matrix.status.im" : _t("User name")} + placeholder={ SdkConfig.get().disable_custom_urls ? + _t("Username on %(hs)s", { + hs: this.props.hsUrl.replace(/^https?:\/\//, '') + }) : _t("User name")} value={this.state.username} autoFocus disabled={disabled} @@ -212,9 +213,8 @@ class PasswordLogin extends React.Component { const loginField = this.renderLoginField(this.state.loginType, matrixIdText === ''); - const theme = UserSettingsStore.getTheme(); let loginType; - if (theme !== 'status') { + if (!SdkConfig.get().disable_3pid_login) { loginType = (
    diff --git a/src/components/views/login/RegistrationForm.js b/src/components/views/login/RegistrationForm.js index 426cc41dea..5ba93ec272 100644 --- a/src/components/views/login/RegistrationForm.js +++ b/src/components/views/login/RegistrationForm.js @@ -23,6 +23,7 @@ import { looksValid as phoneNumberLooksValid } from '../../../phonenumber'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; import UserSettingsStore from '../../../UserSettingsStore'; +import SdkConfig from '../../../SdkConfig'; const FIELD_EMAIL = 'field_email'; const FIELD_PHONE_COUNTRY = 'field_phone_country'; @@ -275,6 +276,7 @@ module.exports = React.createClass({ const self = this; const theme = UserSettingsStore.getTheme(); + // FIXME: remove hardcoded Status team tweaks at some point const emailPlaceholder = theme === 'status' ? _t("Email address") : _t("Email address (optional)"); const emailSection = ( @@ -311,7 +313,7 @@ module.exports = React.createClass({ const CountryDropdown = sdk.getComponent('views.login.CountryDropdown'); let phoneSection; - if (theme !== "status") { + if (!SdkConfig.get().disable_3pid_login) { phoneSection = (
    Date: Sat, 11 Nov 2017 23:57:50 +0000 Subject: [PATCH 31/32] unbreak tests --- src/SdkConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SdkConfig.js b/src/SdkConfig.js index 48ebf011f2..8df725a913 100644 --- a/src/SdkConfig.js +++ b/src/SdkConfig.js @@ -26,7 +26,7 @@ const DEFAULTS = { class SdkConfig { static get() { - return global.mxReactSdkConfig; + return global.mxReactSdkConfig || {}; } static put(cfg) { From ca531f83d2d0264db04ecc6b855d4b249a2a4148 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 13 Nov 2017 10:34:38 +0000 Subject: [PATCH 32/32] remove needless case-squash on login, castrating https://github.com/matrix-org/matrix-react-sdk/pull/1550 --- src/Login.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Login.js b/src/Login.js index 55e996ce80..61a14959d8 100644 --- a/src/Login.js +++ b/src/Login.js @@ -204,6 +204,12 @@ export default class Login { } throw originalLoginError; }).catch((error) => { + // We apparently squash case at login serverside these days: + // https://github.com/matrix-org/synapse/blob/1189be43a2479f5adf034613e8d10e3f4f452eb9/synapse/handlers/auth.py#L475 + // so this wasn't needed after all. Keeping the code around in case the + // the situation changes... + + /* if ( error.httpStatus === 403 && loginParams.identifier.type === 'm.id.user' && @@ -211,6 +217,7 @@ export default class Login { ) { return tryLowercaseUsername(originalLoginError); } + */ throw originalLoginError; }).catch((error) => { console.log("Login failed", error);