From 6d7e88a84a125a7e52d0fcc1d80493fe5252697e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 23 Jan 2019 15:06:49 +0000 Subject: [PATCH 01/64] Fix desktop captcha check Change gnarly hardcoded protocol to detect running in the electron app Fixes https://github.com/vector-im/riot-web/issues/8236 --- src/components/views/auth/CaptchaForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/auth/CaptchaForm.js b/src/components/views/auth/CaptchaForm.js index ab1bfbd393..eba1682b03 100644 --- a/src/components/views/auth/CaptchaForm.js +++ b/src/components/views/auth/CaptchaForm.js @@ -62,7 +62,7 @@ module.exports = React.createClass({ console.log("Loading recaptcha script..."); window.mx_on_recaptcha_loaded = () => {this._onCaptchaLoaded();}; const protocol = global.location.protocol; - if (protocol === "file:") { + if (protocol === "vector:") { const warning = document.createElement('div'); // XXX: fix hardcoded app URL. Better solutions include: // * jumping straight to a hosted captcha page (but we don't support that yet) From 36ebd91f07352f7e533cbdfad73c256e9e1dfb58 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 23 Jan 2019 09:10:49 -0600 Subject: [PATCH 02/64] Move language selector to auth header --- src/components/structures/auth/ForgotPassword.js | 3 --- src/components/structures/auth/Login.js | 3 --- src/components/structures/auth/Registration.js | 3 --- src/components/views/auth/AuthHeader.js | 2 ++ 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/components/structures/auth/ForgotPassword.js b/src/components/structures/auth/ForgotPassword.js index 87e8c7d131..b2dc2a47eb 100644 --- a/src/components/structures/auth/ForgotPassword.js +++ b/src/components/structures/auth/ForgotPassword.js @@ -234,8 +234,6 @@ module.exports = React.createClass({ errorText =
{ err }
; } - const LanguageSelector = sdk.getComponent('structures.auth.LanguageSelector'); - resetPasswordJsx = (
@@ -271,7 +269,6 @@ module.exports = React.createClass({ { _t('Create an account') } -
); diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index 28bed9af05..28c4a3e960 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -555,8 +555,6 @@ module.exports = React.createClass({ ); } - const LanguageSelector = sdk.getComponent('structures.auth.LanguageSelector'); - return ( @@ -569,7 +567,6 @@ module.exports = React.createClass({ { _t('Create an account') } { loginAsGuestJsx } - ); diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index fe6fb078e3..fb913b22e1 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -471,8 +471,6 @@ module.exports = React.createClass({ ); } - const LanguageSelector = sdk.getComponent('structures.auth.LanguageSelector'); - return ( ); diff --git a/src/components/views/auth/AuthHeader.js b/src/components/views/auth/AuthHeader.js index c1d831a70a..cc70d126e8 100644 --- a/src/components/views/auth/AuthHeader.js +++ b/src/components/views/auth/AuthHeader.js @@ -25,10 +25,12 @@ module.exports = React.createClass({ render: function() { const AuthHeaderLogo = sdk.getComponent('auth.AuthHeaderLogo'); + const LanguageSelector = sdk.getComponent('structures.auth.LanguageSelector'); return (
+
); }, From f9793fa5676001a6dea37a6f605df12f9581bc2e Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 23 Jan 2019 09:11:37 -0600 Subject: [PATCH 03/64] Extract language selector styles --- .../structures/auth/_LanguageSelector.scss | 27 +++++++++++++++++++ res/css/structures/auth/_Login.scss | 13 --------- .../structures/auth/LanguageSelector.js | 4 +-- 3 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 res/css/structures/auth/_LanguageSelector.scss diff --git a/res/css/structures/auth/_LanguageSelector.scss b/res/css/structures/auth/_LanguageSelector.scss new file mode 100644 index 0000000000..26a8207b20 --- /dev/null +++ b/res/css/structures/auth/_LanguageSelector.scss @@ -0,0 +1,27 @@ +/* +Copyright 2019 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. +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. +*/ + +.mx_Auth_language { + margin-left: auto; + margin-right: auto; + min-width: 60%; +} + +.mx_Auth_language_div { + display: flex; + margin-top: 12px; + margin-bottom: 12px; +} diff --git a/res/css/structures/auth/_Login.scss b/res/css/structures/auth/_Login.scss index c4eebc48a1..09af69183b 100644 --- a/res/css/structures/auth/_Login.scss +++ b/res/css/structures/auth/_Login.scss @@ -233,16 +233,3 @@ limitations under the License. margin: 3px; vertical-align: top; } - -.mx_Login_language { - margin-left: auto; - margin-right: auto; - min-width: 60%; -} - -.mx_Login_language_div { - display: flex; - margin-top: 12px; - margin-bottom: 12px; -} - diff --git a/src/components/structures/auth/LanguageSelector.js b/src/components/structures/auth/LanguageSelector.js index 965d8334d9..60b369c303 100644 --- a/src/components/structures/auth/LanguageSelector.js +++ b/src/components/structures/auth/LanguageSelector.js @@ -32,7 +32,7 @@ export default function LanguageSelector() { if (SdkConfig.get()['disable_login_language_selector']) return
; const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown'); - return
- + return
+
; } From 05254f0e8284bfed770c8422c3f2e317ee88029e Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 23 Jan 2019 09:57:31 -0600 Subject: [PATCH 04/64] Tweak language selector to match design --- res/css/_components.scss | 1 + res/css/structures/auth/_LanguageSelector.scss | 13 ++++++------- res/css/views/auth/_AuthHeader.scss | 2 ++ res/css/views/auth/_AuthHeaderLogo.scss | 1 + res/themes/dharma/css/_dharma.scss | 1 + res/themes/light/css/_base.scss | 1 + src/components/structures/auth/LanguageSelector.js | 7 ++++--- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/res/css/_components.scss b/res/css/_components.scss index 2617cd7c4c..133324529b 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -23,6 +23,7 @@ @import "./structures/_UploadBar.scss"; @import "./structures/_UserSettings.scss"; @import "./structures/_ViewSource.scss"; +@import "./structures/auth/_LanguageSelector.scss"; @import "./structures/auth/_Login.scss"; @import "./views/auth/_AuthBody.scss"; @import "./views/auth/_AuthButtons.scss"; diff --git a/res/css/structures/auth/_LanguageSelector.scss b/res/css/structures/auth/_LanguageSelector.scss index 26a8207b20..5193fa98ed 100644 --- a/res/css/structures/auth/_LanguageSelector.scss +++ b/res/css/structures/auth/_LanguageSelector.scss @@ -15,13 +15,12 @@ limitations under the License. */ .mx_Auth_language { - margin-left: auto; - margin-right: auto; - min-width: 60%; + width: 100%; } -.mx_Auth_language_div { - display: flex; - margin-top: 12px; - margin-bottom: 12px; +.mx_Auth_language .mx_Dropdown_input { + border: none; + font-size: 14px; + font-weight: 600; + color: $authpage-lang-color; } diff --git a/res/css/views/auth/_AuthHeader.scss b/res/css/views/auth/_AuthHeader.scss index 376864d268..e1e8802437 100644 --- a/res/css/views/auth/_AuthHeader.scss +++ b/res/css/views/auth/_AuthHeader.scss @@ -15,6 +15,8 @@ limitations under the License. */ .mx_AuthHeader { + display: flex; + flex-direction: column; width: 206px; padding: 25px 50px; box-sizing: border-box; diff --git a/res/css/views/auth/_AuthHeaderLogo.scss b/res/css/views/auth/_AuthHeaderLogo.scss index 3d8ab29325..b6f107d9c4 100644 --- a/res/css/views/auth/_AuthHeaderLogo.scss +++ b/res/css/views/auth/_AuthHeaderLogo.scss @@ -16,6 +16,7 @@ limitations under the License. .mx_AuthHeaderLogo { margin-top: 15px; + flex: 1; } .mx_AuthHeaderLogo img { diff --git a/res/themes/dharma/css/_dharma.scss b/res/themes/dharma/css/_dharma.scss index 235eb02e3c..22aa018b5e 100644 --- a/res/themes/dharma/css/_dharma.scss +++ b/res/themes/dharma/css/_dharma.scss @@ -216,6 +216,7 @@ $memberstatus-placeholder-color: $roomtile-name-color; $authpage-bg-color: #2e3649; $authpage-modal-bg-color: rgba(255, 255, 255, 0.59); $authpage-body-bg-color: #ffffff; +$authpage-lang-color: #4e5054; /*** form elements ***/ diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index 1522ee82a0..438ab69856 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -212,6 +212,7 @@ $memberstatus-placeholder-color: $roomtile-name-color; $authpage-bg-color: #2e3649; $authpage-modal-bg-color: rgba(255, 255, 255, 0.59); $authpage-body-bg-color: #ffffff; +$authpage-lang-color: #4e5054; // ***** Mixins! ***** diff --git a/src/components/structures/auth/LanguageSelector.js b/src/components/structures/auth/LanguageSelector.js index 60b369c303..d964af184c 100644 --- a/src/components/structures/auth/LanguageSelector.js +++ b/src/components/structures/auth/LanguageSelector.js @@ -32,7 +32,8 @@ export default function LanguageSelector() { if (SdkConfig.get()['disable_login_language_selector']) return
; const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown'); - return
- -
; + return ; } From 523d910c6618ff4225260217732cd0422efb6838 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 23 Jan 2019 10:14:45 -0600 Subject: [PATCH 05/64] Use new dropdown arrow for language selector --- .../structures/auth/_LanguageSelector.scss | 20 +++++++++++++++++++ res/img/feather-icons/dropdown-arrow.svg | 6 ++++++ 2 files changed, 26 insertions(+) create mode 100644 res/img/feather-icons/dropdown-arrow.svg diff --git a/res/css/structures/auth/_LanguageSelector.scss b/res/css/structures/auth/_LanguageSelector.scss index 5193fa98ed..e73dd4ac64 100644 --- a/res/css/structures/auth/_LanguageSelector.scss +++ b/res/css/structures/auth/_LanguageSelector.scss @@ -24,3 +24,23 @@ limitations under the License. font-weight: 600; color: $authpage-lang-color; } + +/* TODO: Consider using this new arrow for all dropdowns */ +.mx_Auth_language .mx_Dropdown_arrow { + width: 10px; + height: 6px; + border: none; + right: 6px; +} + +.mx_Auth_language .mx_Dropdown_arrow::before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + mask: url('$(res)/img/feather-icons/dropdown-arrow.svg'); + mask-repeat: no-repeat; + background: $authpage-lang-color; +} diff --git a/res/img/feather-icons/dropdown-arrow.svg b/res/img/feather-icons/dropdown-arrow.svg new file mode 100644 index 0000000000..a1d46fa61a --- /dev/null +++ b/res/img/feather-icons/dropdown-arrow.svg @@ -0,0 +1,6 @@ + + + + + + From de81c8d768b9d5e8cdd0e68190a502b0b5e84ce1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 22 Jan 2019 10:36:47 -0700 Subject: [PATCH 06/64] Template out remaining sections --- .../views/settings/tabs/GeneralSettingsTab.js | 41 +++++++++++++++++++ src/i18n/strings/en_EN.json | 13 +++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/components/views/settings/tabs/GeneralSettingsTab.js b/src/components/views/settings/tabs/GeneralSettingsTab.js index c8816325c0..c248ba23dd 100644 --- a/src/components/views/settings/tabs/GeneralSettingsTab.js +++ b/src/components/views/settings/tabs/GeneralSettingsTab.js @@ -73,6 +73,7 @@ export default class GeneralSettingsTab extends React.Component { disabled={!this.state.enableProfileSave}> {_t("Save")} +
FLAIR
); @@ -84,11 +85,51 @@ export default class GeneralSettingsTab extends React.Component { ); } + _renderAccountSection() { + return ( +
+ {_t("Account")} +

ACCOUNT SECTION

+
+ ); + } + + _renderLanguageSection() { + return ( +
+ {_t("Language and region")} +

LANGUAGE SECTION

+
+ ); + } + + _renderThemeSection() { + return ( +
+ {_t("Theme")} +

THEME SECTION

+
+ ); + } + + _renderManagementSection() { + return ( +
+ {_t("Account management")} +

MANAGEMENT SECTION

+
+ ); + } + render() { return (
{_t("General")}
{this._renderProfileSection()} + {this._renderAccountSection()} + {this._renderLanguageSection()} + {this._renderThemeSection()} + {this._renderManagementSection()}
); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6bf857be07..5a85f8c4f3 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -405,6 +405,10 @@ "Display Name": "Display Name", "Save": "Save", "Profile": "Profile", + "Account": "Account", + "Language and region": "Language and region", + "Theme": "Theme", + "Account management": "Account management", "General": "General", "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", @@ -431,6 +435,7 @@ "Encrypted by an unverified device": "Encrypted by an unverified device", "Unencrypted message": "Unencrypted message", "Please select the destination room for this message": "Please select the destination room for this message", + "Scroll to bottom of page": "Scroll to bottom of page", "Blacklisted": "Blacklisted", "Verified": "Verified", "Unverified": "Unverified", @@ -1065,6 +1070,8 @@ "Set status": "Set status", "Set a new status...": "Set a new status...", "View Community": "View Community", + "Login": "Login", + "powered by Matrix": "powered by Matrix", "Robot check is currently unavailable on desktop - please use a web browser": "Robot check is currently unavailable on desktop - please use a web browser", "This Home Server would like to make sure you are not a robot": "This Home Server would like to make sure you are not a robot", "Custom Server Options": "Custom Server Options", @@ -1082,7 +1089,6 @@ "Please enter the code it contains:": "Please enter the code it contains:", "Code": "Code", "Start authentication": "Start authentication", - "powered by Matrix": "powered by Matrix", "The email field must not be blank.": "The email field must not be blank.", "The user name field must not be blank.": "The user name field must not be blank.", "The phone number field must not be blank.": "The phone number field must not be blank.", @@ -1155,7 +1161,6 @@ "Couldn't load home page": "Couldn't load home page", "You are currently using Riot anonymously as a guest.": "You are currently using Riot anonymously as a guest.", "If you would like to create a Matrix account you can register now.": "If you would like to create a Matrix account you can register now.", - "Login": "Login", "Invalid configuration: Cannot supply a default homeserver URL and a default server name": "Invalid configuration: Cannot supply a default homeserver URL and a default server name", "Failed to reject invitation": "Failed to reject invitation", "This room is not public. You will not be able to rejoin without an invite.": "This room is not public. You will not be able to rejoin without an invite.", @@ -1197,7 +1202,6 @@ "Directory": "Directory", "Search for a room": "Search for a room", "#example": "#example", - "Scroll to bottom of page": "Scroll to bottom of page", "Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present", "Show devices, send anyway or cancel.": "Show devices, send anyway or cancel.", "You can't send any messages until you review and agree to our terms and conditions.": "You can't send any messages until you review and agree to our terms and conditions.", @@ -1209,8 +1213,6 @@ "%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|one": "Resend message or cancel message now.", "Connectivity to the server has been lost.": "Connectivity to the server has been lost.", "Sent messages will be stored until your connection has returned.": "Sent messages will be stored until your connection has returned.", - "%(count)s new messages|other": "%(count)s new messages", - "%(count)s new messages|one": "%(count)s new message", "Active call": "Active call", "There's no one else here! Would you like to invite others or stop warning about the empty room?": "There's no one else here! Would you like to invite others or stop warning about the empty room?", "You seem to be uploading files, are you sure you want to quit?": "You seem to be uploading files, are you sure you want to quit?", @@ -1294,7 +1296,6 @@ "Email": "Email", "Add email address": "Add email address", "Display name": "Display name", - "Account": "Account", "To return to your account in future you need to set a password": "To return to your account in future you need to set a password", "Logged in as:": "Logged in as:", "Access Token:": "Access Token:", From f643d7a143ce1ba5e1a26c4666b3fe2b23fad9dc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 21 Jan 2019 22:39:49 -0700 Subject: [PATCH 07/64] Finish the box for displayname/avatar changes --- .../settings/tabs/_GeneralSettingsTab.scss | 70 +++++++++++++- res/img/feather-icons/upload.svg | 5 + res/themes/dharma/css/_dharma.scss | 5 + res/themes/light/css/_base.scss | 5 + .../views/settings/tabs/GeneralSettingsTab.js | 92 +++++++++++++++++-- src/i18n/strings/en_EN.json | 3 + 6 files changed, 170 insertions(+), 10 deletions(-) create mode 100644 res/img/feather-icons/upload.svg diff --git a/res/css/views/settings/tabs/_GeneralSettingsTab.scss b/res/css/views/settings/tabs/_GeneralSettingsTab.scss index 8bc3de8689..caacd0d3c7 100644 --- a/res/css/views/settings/tabs/_GeneralSettingsTab.scss +++ b/res/css/views/settings/tabs/_GeneralSettingsTab.scss @@ -14,12 +14,78 @@ width: 88px; height: 88px; margin-left: 13px; + position: relative; + cursor: pointer; } -.mx_GeneralSettingsTab_profileAvatar div { +.mx_GeneralSettingsTab_profileAvatar > * { display: block; width: 88px; height: 88px; border-radius: 4px; - background-color: #ccc; +} + +.mx_GeneralSettingsTab_profileAvatar .mx_GeneralSettingsTab_profileAvatarPlaceholder { + background-color: $settings-profile-placeholder-bg-color; +} + +.mx_GeneralSettingsTab_profileAvatarOverlay { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: none; + text-align: center; + vertical-align: middle; + font-size: 10px; +} + +.mx_GeneralSettingsTab_profileAvatar:hover .mx_GeneralSettingsTab_profileAvatarOverlay { + display: inline-block; + opacity: 0.5 !important; + color: $settings-profile-overlay-fg-color !important; + background-color: $settings-profile-overlay-bg-color !important; +} + +.mx_GeneralSettingsTab_profileAvatarOverlay_show { + display: inline-block; + opacity: 1; + color: $settings-profile-overlay-placeholder-fg-color; + background-color: $settings-profile-overlay-placeholder-bg-color; +} + +.mx_GeneralSettingsTab_profileAvatarOverlayText { + display: block; + margin-top: 17px; + margin-bottom: 8px; +} + +.mx_GeneralSettingsTab_profileAvatarOverlayImgContainer { + position: relative; + width: 14px; + height: 14px; + margin: auto; +} + +.mx_GeneralSettingsTab_profileAvatarOverlayImg:before { + background-color: $settings-profile-overlay-placeholder-fg-color; + mask: url("$(res)/img/feather-icons/upload.svg"); + mask-repeat: no-repeat; + mask-size: 14px; + mask-position: center; + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.mx_GeneralSettingsTab_profileAvatar:hover .mx_GeneralSettingsTab_profileAvatarOverlayImg:before { + background-color: $settings-profile-overlay-fg-color !important; +} + +.mx_GeneralSettingsTab_profileAvatarUpload { + display: none; } \ No newline at end of file diff --git a/res/img/feather-icons/upload.svg b/res/img/feather-icons/upload.svg new file mode 100644 index 0000000000..8ec5d95c2c --- /dev/null +++ b/res/img/feather-icons/upload.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/res/themes/dharma/css/_dharma.scss b/res/themes/dharma/css/_dharma.scss index 235eb02e3c..ed5620d30f 100644 --- a/res/themes/dharma/css/_dharma.scss +++ b/res/themes/dharma/css/_dharma.scss @@ -120,6 +120,11 @@ $blockquote-bar-color: #ddd; $blockquote-fg-color: #777; $settings-grey-fg-color: #a2a2a2; +$settings-profile-placeholder-bg-color: #e7e7e7; +$settings-profile-overlay-bg-color: #000; +$settings-profile-overlay-placeholder-bg-color: transparent; +$settings-profile-overlay-fg-color: #fff; +$settings-profile-overlay-placeholder-fg-color: #454545; $voip-decline-color: #f48080; $voip-accept-color: #80f480; diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index 1522ee82a0..d7b135a74e 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -113,6 +113,11 @@ $blockquote-bar-color: #ddd; $blockquote-fg-color: #777; $settings-grey-fg-color: #a2a2a2; +$settings-profile-placeholder-bg-color: #e7e7e7; +$settings-profile-overlay-bg-color: #000; +$settings-profile-overlay-placeholder-bg-color: transparent; +$settings-profile-overlay-fg-color: #fff; +$settings-profile-overlay-placeholder-fg-color: #454545; $voip-decline-color: #f48080; $voip-accept-color: #80f480; diff --git a/src/components/views/settings/tabs/GeneralSettingsTab.js b/src/components/views/settings/tabs/GeneralSettingsTab.js index c248ba23dd..993061eaa0 100644 --- a/src/components/views/settings/tabs/GeneralSettingsTab.js +++ b/src/components/views/settings/tabs/GeneralSettingsTab.js @@ -19,19 +19,34 @@ import {_t} from "../../../../languageHandler"; import MatrixClientPeg from "../../../../MatrixClientPeg"; import Field from "../../elements/Field"; import AccessibleButton from "../../elements/AccessibleButton"; +import classNames from 'classnames'; export default class GeneralSettingsTab extends React.Component { constructor() { super(); const client = MatrixClientPeg.get(); + const user = client.getUser(client.getUserId()); + let avatarUrl = user.avatarUrl; + if (avatarUrl) avatarUrl = client.mxcUrlToHttp(avatarUrl, 96, 96, 'crop', false); this.state = { - userId: client.getUserId(), - displayName: client.getUser(client.getUserId()).displayName, + userId: user.userId, + originalDisplayName: user.displayName, + displayName: user.displayName, + originalAvatarUrl: avatarUrl, + avatarUrl: avatarUrl, + avatarFile: null, enableProfileSave: false, }; } + _uploadAvatar = (e) => { + e.stopPropagation(); + e.preventDefault(); + + this.refs.avatarUpload.click(); + }; + _saveProfile = async (e) => { e.stopPropagation(); e.preventDefault(); @@ -39,12 +54,26 @@ export default class GeneralSettingsTab extends React.Component { if (!this.state.enableProfileSave) return; this.setState({enableProfileSave: false}); + const client = MatrixClientPeg.get(); + const newState = {}; + // TODO: What do we do about errors? - await MatrixClientPeg.get().setDisplayName(this.state.displayName); - // TODO: Support avatars + if (this.state.originalDisplayName !== this.state.displayName) { + await client.setDisplayName(this.state.displayName); + newState.originalDisplayName = this.state.displayName; + } - this.setState({enableProfileSave: true}); + if (this.state.avatarFile) { + const uri = await client.uploadContent(this.state.avatarFile); + await client.setAvatarUrl(uri); + newState.avatarUrl = client.mxcUrlToHttp(uri, 96, 96, 'crop', false); + newState.originalAvatarUrl = newState.avatarUrl; + newState.avatarFile = null; + } + + newState.enableProfileSave = true; + this.setState(newState); }; _onDisplayNameChanged = (e) => { @@ -54,19 +83,66 @@ export default class GeneralSettingsTab extends React.Component { }); }; + _onAvatarChanged = (e) => { + if (!e.target.files || !e.target.files.length) { + this.setState({ + avatarUrl: this.state.originalAvatarUrl, + avatarFile: null, + enableProfileSave: false, + }); + return; + } + + const file = e.target.files[0]; + const reader = new FileReader(); + reader.onload = (ev) => { + this.setState({ + avatarUrl: ev.target.result, + avatarFile: file, + enableProfileSave: true, + }); + }; + reader.readAsDataURL(file); + }; + _renderProfileSection() { - // TODO: Ditch avatar placeholder and use the real thing + // TODO: Why is rendering a box with an overlay so complicated? Can the DOM be reduced? + + let showOverlayAnyways = true; + let avatarElement =
; + if (this.state.avatarUrl) { + showOverlayAnyways = false; + avatarElement = {_t("Profile + } + + const avatarOverlayClasses = classNames({ + "mx_GeneralSettingsTab_profileAvatarOverlay": true, + "mx_GeneralSettingsTab_profileAvatarOverlay_show": showOverlayAnyways, + }); + let avatarHoverElement = ( +
+ {_t("Upload profile picture")} +
+
+
+
+ ); + const form = (
+

{this.state.userId}

-
+ {avatarElement} + {avatarHoverElement}
Date: Mon, 21 Jan 2019 23:08:01 -0700 Subject: [PATCH 08/64] Bring flair into the new settings Makes the flair options in old settings look broken (cosmetic issues), but it's fine because we're ripping that out in due time. --- res/css/views/groups/_GroupUserSettings.scss | 1 - res/css/views/settings/tabs/_SettingsTab.scss | 11 +++++++--- res/themes/dharma/css/_dharma.scss | 1 + res/themes/light/css/_base.scss | 1 + .../views/groups/GroupUserSettings.js | 11 ++++------ .../views/settings/tabs/GeneralSettingsTab.js | 21 ++++++++++++++++++- src/i18n/strings/en_EN.json | 3 +-- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/res/css/views/groups/_GroupUserSettings.scss b/res/css/views/groups/_GroupUserSettings.scss index 0c909b7cf7..b207aa2958 100644 --- a/res/css/views/groups/_GroupUserSettings.scss +++ b/res/css/views/groups/_GroupUserSettings.scss @@ -18,6 +18,5 @@ limitations under the License. height: 200px; border: 1px solid $primary-hairline-color; border-radius: 3px; - margin-right: 32px; overflow: hidden; } diff --git a/res/css/views/settings/tabs/_SettingsTab.scss b/res/css/views/settings/tabs/_SettingsTab.scss index 0753df56af..c86fb1f41e 100644 --- a/res/css/views/settings/tabs/_SettingsTab.scss +++ b/res/css/views/settings/tabs/_SettingsTab.scss @@ -10,8 +10,13 @@ font-family: $font-family-semibold; color: $primary-fg-color; margin-bottom: 10px; -} - -.mx_SettingsTab_section { margin-top: 10px; } + +.mx_SettingsTab_subsectionText { + color: $settings-subsection-fg-color; + font-size: 12px; + padding-bottom: 12px; + margin: 0; + display: block; +} diff --git a/res/themes/dharma/css/_dharma.scss b/res/themes/dharma/css/_dharma.scss index ed5620d30f..f54c058220 100644 --- a/res/themes/dharma/css/_dharma.scss +++ b/res/themes/dharma/css/_dharma.scss @@ -125,6 +125,7 @@ $settings-profile-overlay-bg-color: #000; $settings-profile-overlay-placeholder-bg-color: transparent; $settings-profile-overlay-fg-color: #fff; $settings-profile-overlay-placeholder-fg-color: #454545; +$settings-subsection-fg-color: #61708b; $voip-decline-color: #f48080; $voip-accept-color: #80f480; diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index d7b135a74e..fce4e93112 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -118,6 +118,7 @@ $settings-profile-overlay-bg-color: #000; $settings-profile-overlay-placeholder-bg-color: transparent; $settings-profile-overlay-fg-color: #fff; $settings-profile-overlay-placeholder-fg-color: #454545; +$settings-subsection-fg-color: #61708b; $voip-decline-color: #f48080; $voip-accept-color: #80f480; diff --git a/src/components/views/groups/GroupUserSettings.js b/src/components/views/groups/GroupUserSettings.js index 0405d411d2..a349a34caf 100644 --- a/src/components/views/groups/GroupUserSettings.js +++ b/src/components/views/groups/GroupUserSettings.js @@ -68,15 +68,12 @@ export default React.createClass({ text = _t("You're not currently a member of any communities."); } - return
-

{ _t('Flair') }

-
-

- { text } -

+ return ( +
+

{ text }

{ scrollbox }
-
; + ); }, render() { diff --git a/src/components/views/settings/tabs/GeneralSettingsTab.js b/src/components/views/settings/tabs/GeneralSettingsTab.js index 993061eaa0..f57609625f 100644 --- a/src/components/views/settings/tabs/GeneralSettingsTab.js +++ b/src/components/views/settings/tabs/GeneralSettingsTab.js @@ -20,8 +20,16 @@ import MatrixClientPeg from "../../../../MatrixClientPeg"; import Field from "../../elements/Field"; import AccessibleButton from "../../elements/AccessibleButton"; import classNames from 'classnames'; +import GroupUserSettings from "../../groups/GroupUserSettings"; +import PropTypes from "prop-types"; +import {MatrixClient} from "matrix-js-sdk"; +import { DragDropContext } from 'react-beautiful-dnd'; export default class GeneralSettingsTab extends React.Component { + static childContextTypes = { + matrixClient: PropTypes.instanceOf(MatrixClient), + }; + constructor() { super(); @@ -40,6 +48,12 @@ export default class GeneralSettingsTab extends React.Component { }; } + getChildContext() { + return { + matrixClient: MatrixClientPeg.get(), + }; + } + _uploadAvatar = (e) => { e.stopPropagation(); e.preventDefault(); @@ -149,14 +163,19 @@ export default class GeneralSettingsTab extends React.Component { disabled={!this.state.enableProfileSave}> {_t("Save")} -
FLAIR
); + // HACK/TODO: Using DragDropContext feels wrong, but we need it. return (
{_t("Profile")} {form} + + {_t("Flair")} + + +
); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index c61c806830..42046cba19 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -404,10 +404,10 @@ "Noisy": "Noisy", "Profile picture": "Profile picture", "Upload profile picture": "Upload profile picture", - "Upload": "Upload", "Display Name": "Display Name", "Save": "Save", "Profile": "Profile", + "Flair": "Flair", "Account": "Account", "Language and region": "Language and region", "Theme": "Theme", @@ -680,7 +680,6 @@ "New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)", "Invalid community ID": "Invalid community ID", "'%(groupId)s' is not a valid community ID": "'%(groupId)s' is not a valid community ID", - "Flair": "Flair", "Showing flair for these communities:": "Showing flair for these communities:", "This room is not showing flair for any communities": "This room is not showing flair for any communities", "New community ID (e.g. +foo:%(localDomain)s)": "New community ID (e.g. +foo:%(localDomain)s)", From 19de6694ca642f6d066c077ca5df3744585619bd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 22 Jan 2019 13:09:40 -0700 Subject: [PATCH 09/64] Bring in the change password section This also changes the layout slightly in the user settings, but nothing detrimental. --- .../settings/tabs/_GeneralSettingsTab.scss | 18 +++++++ src/components/structures/UserSettings.js | 4 +- .../views/dialogs/SetPasswordDialog.js | 5 +- src/components/views/elements/Field.js | 5 ++ .../views/settings/ChangePassword.js | 39 +++++--------- .../views/settings/tabs/GeneralSettingsTab.js | 52 ++++++++++++++++++- src/i18n/strings/en_EN.json | 7 +-- 7 files changed, 94 insertions(+), 36 deletions(-) diff --git a/res/css/views/settings/tabs/_GeneralSettingsTab.scss b/res/css/views/settings/tabs/_GeneralSettingsTab.scss index caacd0d3c7..097d81dab4 100644 --- a/res/css/views/settings/tabs/_GeneralSettingsTab.scss +++ b/res/css/views/settings/tabs/_GeneralSettingsTab.scss @@ -88,4 +88,22 @@ .mx_GeneralSettingsTab_profileAvatarUpload { display: none; +} + +.mx_GeneralSettingsTab_changePassword { + display: block; +} + +.mx_GeneralSettingsTab_changePassword .mx_Field { + display: block; + margin-right: 100px; // Align with the other fields on the page +} + +.mx_GeneralSettingsTab_changePassword .mx_Field input { + display: block; + width: calc(100% - 20px); // subtract 10px padding on left and right +} + +.mx_GeneralSettingsTab_changePassword .mx_Field:first-child { + margin-top: 0; } \ No newline at end of file diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 65e1897137..f8d9e2dd84 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -1268,9 +1268,7 @@ module.exports = React.createClass({ ); diff --git a/src/components/views/dialogs/SetPasswordDialog.js b/src/components/views/dialogs/SetPasswordDialog.js index 42c35ad187..fe3a2216f4 100644 --- a/src/components/views/dialogs/SetPasswordDialog.js +++ b/src/components/views/dialogs/SetPasswordDialog.js @@ -116,9 +116,8 @@ export default React.createClass({