From 93c44390458f00bcdff090df2c1d4950870cd705 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 6 Jan 2020 13:30:56 +0000 Subject: [PATCH 01/80] js-sdk rc.1 --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index ad446e26cc..61e12eceda 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", + "matrix-js-sdk": "2.4.7", "optimist": "^0.6.1", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index a491ba3941..1646ac5a59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5271,9 +5271,10 @@ mathml-tag-names@^2.0.1: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" integrity sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw== -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": - version "2.4.6" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/01f0dd4498fb689cb66091aff7aa0ae49f9b8ebf" +matrix-js-sdk@2.4.7: + version "2.4.7" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.7.tgz#998949120cb6cfb6362af6ff7b6bce326f7dca6f" + integrity sha512-3BVlZrHJYt7j5N83BLEeqroe4Gi2J/ycZKvKIe6s6SEygP8TpUP+trVSd+bSLm7c2JpPpMCoEsJ22aaPcbWVDQ== dependencies: another-json "^0.2.0" browser-request "^0.3.3" From 6b8f6239c5f29ef3d969c8f7700f097d35ff139b Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 6 Jan 2020 13:58:43 +0000 Subject: [PATCH 02/80] js-sdk 3.0.0-rc.1 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 61e12eceda..1b97d84abb 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "2.4.7", + "matrix-js-sdk": "3.0.0-rc.1", "optimist": "^0.6.1", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 1646ac5a59..982760c49a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5271,10 +5271,10 @@ mathml-tag-names@^2.0.1: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" integrity sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw== -matrix-js-sdk@2.4.7: - version "2.4.7" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.7.tgz#998949120cb6cfb6362af6ff7b6bce326f7dca6f" - integrity sha512-3BVlZrHJYt7j5N83BLEeqroe4Gi2J/ycZKvKIe6s6SEygP8TpUP+trVSd+bSLm7c2JpPpMCoEsJ22aaPcbWVDQ== +matrix-js-sdk@3.0.0-rc.1: + version "3.0.0-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-3.0.0-rc.1.tgz#6ecdedab752933f6a0ccf6aa7d2786bd32f6d7f7" + integrity sha512-1eaECVqG64tj1pE0UBFTIGc1whryXLNaRpkrXrZ5+ZMDtuK2ZDlTOLYoK3t4z/hjn+4C6a294ytoEVe0UnIA8w== dependencies: another-json "^0.2.0" browser-request "^0.3.3" From 623799ebdcededefc5c34c3dd5a93fc08fc79f1e Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 6 Jan 2020 14:01:54 +0000 Subject: [PATCH 03/80] Prepare changelog for v1.7.6-rc.1 --- CHANGELOG.md | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5390cad319..3ad057dc7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,177 @@ +Changes in [1.7.6-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.6-rc.1) (2020-01-06) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.5...v1.7.6-rc.1) + + * Deduplicate recent emoji + [\#3806](https://github.com/matrix-org/matrix-react-sdk/pull/3806) + * Fix ability to remove avatars + [\#3803](https://github.com/matrix-org/matrix-react-sdk/pull/3803) + * Update from Weblate + [\#3810](https://github.com/matrix-org/matrix-react-sdk/pull/3810) + * User Info fetch latest RoomMember instead of showing historical data + [\#3788](https://github.com/matrix-org/matrix-react-sdk/pull/3788) + * Remove all usages of slate in favour of CIDER + [\#3808](https://github.com/matrix-org/matrix-react-sdk/pull/3808) + * Use display name when pinned messages are changed + [\#3809](https://github.com/matrix-org/matrix-react-sdk/pull/3809) + * Fix inverted diff line highlighting in dark theme + [\#3790](https://github.com/matrix-org/matrix-react-sdk/pull/3790) + * Bridge info settings tab + [\#3693](https://github.com/matrix-org/matrix-react-sdk/pull/3693) + * Send the labs flags the client is running with in rageshake + [\#3805](https://github.com/matrix-org/matrix-react-sdk/pull/3805) + * Initial implementation of FTUE user lists design + [\#3792](https://github.com/matrix-org/matrix-react-sdk/pull/3792) + * Update key backup creation and recovery paths for SSSS + [\#3800](https://github.com/matrix-org/matrix-react-sdk/pull/3800) + * Don't fail if logs exists and is an empty dir + [\#3798](https://github.com/matrix-org/matrix-react-sdk/pull/3798) + * Comment remaining non-cross-signing-compliant components + [\#3799](https://github.com/matrix-org/matrix-react-sdk/pull/3799) + * Remove 'unverify' from UserInfoPanel + [\#3797](https://github.com/matrix-org/matrix-react-sdk/pull/3797) + * Use deviceTrust when displaying key backup trust status + [\#3795](https://github.com/matrix-org/matrix-react-sdk/pull/3795) + * Don't crash if a keyshare request is removed + [\#3793](https://github.com/matrix-org/matrix-react-sdk/pull/3793) + * Convert /verify to checkDeviceTrust + [\#3794](https://github.com/matrix-org/matrix-react-sdk/pull/3794) + * Remove E2eIcon onClick + [\#3791](https://github.com/matrix-org/matrix-react-sdk/pull/3791) + * support channel names with slash in name/alias + [\#3778](https://github.com/matrix-org/matrix-react-sdk/pull/3778) + * Fix NPE when filtering the room list + [\#3787](https://github.com/matrix-org/matrix-react-sdk/pull/3787) + * Turn RoomAliasField into properly controlled and use in RoomSettings + [\#3782](https://github.com/matrix-org/matrix-react-sdk/pull/3782) + * fuzzy-sort MemberList + [\#3783](https://github.com/matrix-org/matrix-react-sdk/pull/3783) + * Serialize file uploads into room to match confirmation dialog order + [\#3786](https://github.com/matrix-org/matrix-react-sdk/pull/3786) + * Do not show Top Unread Messages Bar and Jump to bottom button if searching + [\#3785](https://github.com/matrix-org/matrix-react-sdk/pull/3785) + * Fix sticker picker chevron offset calculation + [\#3784](https://github.com/matrix-org/matrix-react-sdk/pull/3784) + * Fix not being able to promote others to the same power level as your own + [\#3781](https://github.com/matrix-org/matrix-react-sdk/pull/3781) + * Room Tile DMs online/active green dot + [\#3751](https://github.com/matrix-org/matrix-react-sdk/pull/3751) + * Fix spelling and grammar in README + [\#3780](https://github.com/matrix-org/matrix-react-sdk/pull/3780) + * Reintroduce working resizer code for right panel + [\#3776](https://github.com/matrix-org/matrix-react-sdk/pull/3776) + * Fix wrong scope binding on openHelp for TopLeftMenu + [\#3775](https://github.com/matrix-org/matrix-react-sdk/pull/3775) + * UserInfo hide kick/mute buttons if they make no sense + [\#3774](https://github.com/matrix-org/matrix-react-sdk/pull/3774) + * Fix duplicate Incoming Call prompt on Community Invite sublist + [\#3773](https://github.com/matrix-org/matrix-react-sdk/pull/3773) + * Apply new design to highlighted tags and add toggle mechanic + [\#3755](https://github.com/matrix-org/matrix-react-sdk/pull/3755) + * stop using ReactDOM.findDOMNode in componentWillUnmount, use refs + [\#3771](https://github.com/matrix-org/matrix-react-sdk/pull/3771) + * Add alt="" to presentational images + [\#3772](https://github.com/matrix-org/matrix-react-sdk/pull/3772) + * Fix room list filtering weird case sensitivity + [\#3759](https://github.com/matrix-org/matrix-react-sdk/pull/3759) + * Don't show the 'verify' button if the user is verified + [\#3758](https://github.com/matrix-org/matrix-react-sdk/pull/3758) + * Switch to using checkDeviceTrust + [\#3757](https://github.com/matrix-org/matrix-react-sdk/pull/3757) + * Migrate away from React Legacy contexts API + [\#3743](https://github.com/matrix-org/matrix-react-sdk/pull/3743) + * Migrate key backups to SSSS + [\#3749](https://github.com/matrix-org/matrix-react-sdk/pull/3749) + * Get rid of stripped-emoji.json in favour of an in-memory single source of + truth + [\#3745](https://github.com/matrix-org/matrix-react-sdk/pull/3745) + * Combine cross signing and verification over DM feature flags + [\#3753](https://github.com/matrix-org/matrix-react-sdk/pull/3753) + * apply unhomoglyph when filtering room list to fuzzify it + [\#3754](https://github.com/matrix-org/matrix-react-sdk/pull/3754) + * Make EmojiPicker an unmanaged Context Menu as it is too complex to be + managed + [\#3746](https://github.com/matrix-org/matrix-react-sdk/pull/3746) + * Internationalise M_TOO_LARGE error from Synapse + [\#3750](https://github.com/matrix-org/matrix-react-sdk/pull/3750) + * Replace UserInfo avatar with for fallback logic + [\#3748](https://github.com/matrix-org/matrix-react-sdk/pull/3748) + * Dropdown stop keyboard propagation if key handled + [\#3741](https://github.com/matrix-org/matrix-react-sdk/pull/3741) + * Fix right panel for multiple member info viewings + [\#3742](https://github.com/matrix-org/matrix-react-sdk/pull/3742) + * Fix Field validation tooltip sticking if blurred before async validation + resolved + [\#3740](https://github.com/matrix-org/matrix-react-sdk/pull/3740) + * Fix UserInfo exploding without a room being passed to it + [\#3738](https://github.com/matrix-org/matrix-react-sdk/pull/3738) + * Fix room directory maintaining and error state + [\#3737](https://github.com/matrix-org/matrix-react-sdk/pull/3737) + * Stop trapping tab in AddressPickerDialog + [\#3735](https://github.com/matrix-org/matrix-react-sdk/pull/3735) + * Stop using KeyboardEvent.keyCode as it is deprecated + [\#3736](https://github.com/matrix-org/matrix-react-sdk/pull/3736) + * Implement new design for uploading/removing avatars + [\#3733](https://github.com/matrix-org/matrix-react-sdk/pull/3733) + * Fix aspect ratio on room/profile avatar preview + [\#3731](https://github.com/matrix-org/matrix-react-sdk/pull/3731) + * Switch to react-focus-lock for it to comprehend Portals + [\#3732](https://github.com/matrix-org/matrix-react-sdk/pull/3732) + * Make combobox dropdown keyboard and screen reader accessible + [\#3729](https://github.com/matrix-org/matrix-react-sdk/pull/3729) + * Verify users when cross-signing enabled + [\#3728](https://github.com/matrix-org/matrix-react-sdk/pull/3728) + * Update from Weblate + [\#3730](https://github.com/matrix-org/matrix-react-sdk/pull/3730) + * Improve a11y of the unignore button in Settings + [\#3727](https://github.com/matrix-org/matrix-react-sdk/pull/3727) + * Fix ToggleSwitch A11Y (trapping tab and switch v. checkbox) + [\#3726](https://github.com/matrix-org/matrix-react-sdk/pull/3726) + * Make URL previews dismissable via keyboard and accessible to screen readers + [\#3725](https://github.com/matrix-org/matrix-react-sdk/pull/3725) + * Create new key backups using secret storage + [\#3720](https://github.com/matrix-org/matrix-react-sdk/pull/3720) + * Replace sign-ins with sessions + [\#3721](https://github.com/matrix-org/matrix-react-sdk/pull/3721) + * Refactor RightPanel to match expected behaviour + [\#3703](https://github.com/matrix-org/matrix-react-sdk/pull/3703) + * Render policy room event updates in the timeline + [\#3716](https://github.com/matrix-org/matrix-react-sdk/pull/3716) + * Wrap the await call for unknown device lookups + [\#3718](https://github.com/matrix-org/matrix-react-sdk/pull/3718) + * Add testing flow to bootstrap secret storage + [\#3640](https://github.com/matrix-org/matrix-react-sdk/pull/3640) + * Fix remaining context menu regressions + [\#3715](https://github.com/matrix-org/matrix-react-sdk/pull/3715) + * Migrate away from React Legacy string refs + [\#3712](https://github.com/matrix-org/matrix-react-sdk/pull/3712) + * Update copy for DM invites + [\#3706](https://github.com/matrix-org/matrix-react-sdk/pull/3706) + * Fix message action bar reaction picker regression + [\#3714](https://github.com/matrix-org/matrix-react-sdk/pull/3714) + * Add what-input to allow different scoping to focus-visible for MAB a11y + [\#3709](https://github.com/matrix-org/matrix-react-sdk/pull/3709) + * Mark the This/All Rooms scope buttons as radios for a11y + [\#3708](https://github.com/matrix-org/matrix-react-sdk/pull/3708) + * Switch ReactionsRowButton to an AccessibleButton for space/enter handling + [\#3707](https://github.com/matrix-org/matrix-react-sdk/pull/3707) + * Change the (edited) link to an AccessibleButton for a11y + [\#3710](https://github.com/matrix-org/matrix-react-sdk/pull/3710) + * Update from Weblate + [\#3713](https://github.com/matrix-org/matrix-react-sdk/pull/3713) + * Fix ?via= args in SpecPermalinkConstructor.js + [\#3694](https://github.com/matrix-org/matrix-react-sdk/pull/3694) + * Don't mark a room as unread when server ACLs are set + [\#3705](https://github.com/matrix-org/matrix-react-sdk/pull/3705) + * Make reaction buttons more accessible + [\#3704](https://github.com/matrix-org/matrix-react-sdk/pull/3704) + * yarn upgrade + [\#3701](https://github.com/matrix-org/matrix-react-sdk/pull/3701) + * Make CI scripts executable + [\#3698](https://github.com/matrix-org/matrix-react-sdk/pull/3698) + * ARIA compliant context menus + [\#3611](https://github.com/matrix-org/matrix-react-sdk/pull/3611) + Changes in [1.7.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.5) (2019-12-09) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.5-rc.1...v1.7.5) From 0df16631c24824c4cca5902a83e8c574d12fed9f Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 6 Jan 2020 14:01:54 +0000 Subject: [PATCH 04/80] v1.7.6-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1b97d84abb..f155738fbd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.5", + "version": "1.7.6-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From dac31dbe00176d28ec93c0ef579e05f00e808cc1 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 6 Jan 2020 21:08:18 +0000 Subject: [PATCH 05/80] Translated using Weblate (Hungarian) Currently translated at 100.0% (2000 of 2000 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 92113c3238..10da7537a9 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2034,5 +2034,6 @@ "Connected to on ": "Ide csatlakozva: itt: ", "Connected via %(protocolName)s": "Ezzel a protokollal csatlakozva: %(protocolName)s", "Bridge Info": "Híd információ", - "Below is a list of bridges connected to this room.": "Alább látható a lista a szobához kapcsolódó hidakról." + "Below is a list of bridges connected to this room.": "Alább látható a lista a szobához kapcsolódó hidakról.", + "Suggestions": "Javaslatok" } From 69dde64a7a6670f9954bfd94d3b64c3afa4af99f Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 7 Jan 2020 02:52:43 +0000 Subject: [PATCH 06/80] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1998 of 1998 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index db75121f07..d58f37b37a 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2033,5 +2033,6 @@ "Connected to on ": "連線到 ", "Connected via %(protocolName)s": "透過 %(protocolName)s 連線", "Bridge Info": "橋接資訊", - "Below is a list of bridges connected to this room.": "以下是連線到此聊天室的橋接列表。" + "Below is a list of bridges connected to this room.": "以下是連線到此聊天室的橋接列表。", + "Suggestions": "建議" } From 0381334f45de10054797c170fd89ef221a4db55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Tue, 7 Jan 2020 11:02:59 +0000 Subject: [PATCH 07/80] Translated using Weblate (French) Currently translated at 100.0% (1998 of 1998 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index c2ee7c575b..7261f62f3a 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2033,5 +2033,6 @@ "Connected to on ": "Connecté à sur ", "Connected via %(protocolName)s": "Connecté via %(protocolName)s", "Bridge Info": "Informations de la passerelle", - "Below is a list of bridges connected to this room.": "Vous trouverez ci-dessous la liste des passerelles connectées à ce salon." + "Below is a list of bridges connected to this room.": "Vous trouverez ci-dessous la liste des passerelles connectées à ce salon.", + "Suggestions": "Suggestions" } From 8606bb9fba98a39444158e3408d121197465c9ba Mon Sep 17 00:00:00 2001 From: random Date: Tue, 7 Jan 2020 13:50:05 +0000 Subject: [PATCH 08/80] Translated using Weblate (Italian) Currently translated at 99.9% (1997 of 1998 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 390729950b..22fc083d08 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2017,5 +2017,20 @@ "The message you are trying to send is too large.": "Il messaggio che stai tentando di inviare è troppo grande.", "Secret Storage will be set up using your existing key backup details.Your secret storage passphrase and recovery key will be the same as they were for your key backup": "L'archivio segreto verrà impostato usando i dettagli del tuo backup chiavi. La password dell'archivio segreto e la chiave di ripristino saranno le stesse del tuo backup chiavi", "Migrate from Key Backup": "Migra dal backup chiavi", - "Help": "Aiuto" + "Help": "Aiuto", + "New DM invite dialog (under development)": "Nuovo invito via messaggio diretto (in sviluppo)", + "Show info about bridges in room settings": "Mostra info sui bridge nelle impostazioni stanza", + "This bridge was provisioned by ": "Questo bridge è stato fornito da ", + "This bridge is managed by .": "Questo bridge è gestito da .", + "Bridged into , on ": "Bridge in , su ", + "Connected to on ": "Connesso a su ", + "Connected via %(protocolName)s": "Connesso via %(protocolName)s", + "Bridge Info": "Info bridge", + "Below is a list of bridges connected to this room.": "Sotto vedi una lista di brdige connessi a questa stanza.", + "Recent Conversations": "Conversazioni recenti", + "Suggestions": "Suggerimenti", + "Show more": "Mostra altro", + "Direct Messages": "Messaggi diretti", + "If you can't find someone, ask them for their username, or share your username (%(userId)s) or profile link.": "Se non riesci a trovare qualcuno, chiedigli il nome utente o condividi il tuo (%(userId)s) o il link al profilo.", + "Go": "Vai" } From ffd40c2c4081ce7bd2a6fb09a39e230f6d07b991 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 6 Jan 2020 20:51:23 -0700 Subject: [PATCH 09/80] Initial editor for user list selection For https://github.com/vector-im/riot-web/issues/11199 --- res/css/views/dialogs/_DMInviteDialog.scss | 77 ++++++- res/img/icon-email-pill-avatar.svg | 37 +++ res/img/icon-pill-remove.svg | 36 +++ .../views/dialogs/DMInviteDialog.js | 214 ++++++++++++++---- 4 files changed, 323 insertions(+), 41 deletions(-) create mode 100644 res/img/icon-email-pill-avatar.svg create mode 100644 res/img/icon-pill-remove.svg diff --git a/res/css/views/dialogs/_DMInviteDialog.scss b/res/css/views/dialogs/_DMInviteDialog.scss index 364c796f16..e581f9dc7a 100644 --- a/res/css/views/dialogs/_DMInviteDialog.scss +++ b/res/css/views/dialogs/_DMInviteDialog.scss @@ -21,15 +21,51 @@ limitations under the License. .mx_DMInviteDialog_editor { flex: 1; width: 100%; // Needed to make the Field inside grow - } + background-color: $user-tile-hover-bg-color; + border-radius: 4px; + min-height: 25px; + padding-left: 8px; + overflow-x: hidden; + overflow-y: auto; - .mx_Field { - margin: 0; + .mx_DMInviteDialog_userTile { + display: inline-block; + float: left; + position: relative; + top: 7px; + } + + // Using a textarea for this element, to circumvent autofill + // Mostly copied from AddressPickerDialog + textarea, + textarea:focus { + height: 34px; + line-height: 34px; + font-size: 14px; + padding-left: 12px; + margin: 0 !important; + border: 0 !important; + outline: 0 !important; + resize: none; + overflow: hidden; + box-sizing: border-box; + word-wrap: nowrap; + + // Roughly fill about 2/5ths of the available space. This is to try and 'fill' the + // remaining space after a bunch of pills, but is a bit hacky. Ideally we'd have + // support for "fill remaining width", but traditional tricks don't work with what + // we're pushing into this "field". Flexbox just makes things worse. The theory is + // that users won't need more than about 2/5ths of the input to find the person + // they're looking for. + width: 40%; + } } .mx_DMInviteDialog_goButton { width: 48px; margin-left: 10px; + height: 25px; + line-height: 25px; } } @@ -83,3 +119,38 @@ limitations under the License. } } +// Many of these styles are stolen from mx_UserPill, but adjusted for the invite dialog. +.mx_DMInviteDialog_userTile { + margin-right: 8px; + + .mx_DMInviteDialog_userTile_pill { + background-color: $username-variant1-color; + border-radius: 12px; + display: inline-block; + height: 24px; + line-height: 24px; + padding-left: 8px; + padding-right: 8px; + color: #ffffff; // this is fine without a var because it's for both themes + + .mx_DMInviteDialog_userTile_avatar { + border-radius: 20px; + position: relative; + left: -5px; + top: 2px; + } + + img.mx_DMInviteDialog_userTile_avatar { + vertical-align: top; + } + + .mx_DMInviteDialog_userTile_name { + vertical-align: top; + } + } + + .mx_DMInviteDialog_userTile_remove { + display: inline-block; + margin-left: 4px; + } +} diff --git a/res/img/icon-email-pill-avatar.svg b/res/img/icon-email-pill-avatar.svg new file mode 100644 index 0000000000..c107ccc480 --- /dev/null +++ b/res/img/icon-email-pill-avatar.svg @@ -0,0 +1,37 @@ + + + + at-sign + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/img/icon-pill-remove.svg b/res/img/icon-pill-remove.svg new file mode 100644 index 0000000000..5b31cca42f --- /dev/null +++ b/res/img/icon-pill-remove.svg @@ -0,0 +1,36 @@ + + + + x + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/views/dialogs/DMInviteDialog.js b/src/components/views/dialogs/DMInviteDialog.js index c5e9c92131..6eb6d0c78b 100644 --- a/src/components/views/dialogs/DMInviteDialog.js +++ b/src/components/views/dialogs/DMInviteDialog.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React from 'react'; +import React, {createRef} from 'react'; import PropTypes from 'prop-types'; import {_t} from "../../../languageHandler"; import sdk from "../../../index"; @@ -31,18 +31,46 @@ import {getHttpUriForMxc} from "matrix-js-sdk/lib/content-repo"; const INITIAL_ROOMS_SHOWN = 3; // Number of rooms to show at first const INCREMENT_ROOMS_SHOWN = 5; // Number of rooms to add when 'show more' is clicked -class DirectoryMember { +// This is the interface that is expected by various components in this file. It is a bit +// awkward because it also matches the RoomMember class from the js-sdk with some extra support +// for 3PIDs/email addresses. +// +// Dev note: In order to allow us to compile the app correctly, this needs to be a class +// even though FlowJS supports interfaces. It just means that we "extend" rather than "implement" +// in the classes, at least until TypeScript saves us. +class Member { + /** + * The display name of this Member. For users this should be their profile's display + * name or user ID if none set. For 3PIDs this should be the 3PID address (email). + */ + get name(): string { throw new Error("Member class not implemented"); } + + /** + * The ID of this Member. For users this should be their user ID. For 3PIDs this should + * be the 3PID address (email). + */ + get userId(): string { throw new Error("Member class not implemented"); } + + /** + * Gets the MXC URL of this Member's avatar. For users this should be their profile's + * avatar MXC URL or null if none set. For 3PIDs this should always be null. + */ + getMxcAvatarUrl(): string { throw new Error("Member class not implemented"); } +} + +class DirectoryMember extends Member { _userId: string; _displayName: string; _avatarUrl: string; constructor(userDirResult: {user_id: string, display_name: string, avatar_url: string}) { + super(); this._userId = userDirResult.user_id; this._displayName = userDirResult.display_name; this._avatarUrl = userDirResult.avatar_url; } - // These next members are to implement the contract expected by DMRoomTile + // These next class members are for the Member interface get name(): string { return this._displayName || this._userId; } @@ -56,12 +84,91 @@ class DirectoryMember { } } +class ThreepidMember extends Member { + _id: string; + + constructor(id: string) { + super(); + this._id = id; + } + + // This is a getter that would be falsey on all other implementations. Until we have + // better type support in the react-sdk we can use this trick to determine the kind + // of 3PID we're dealing with, if any. + get isEmail(): boolean { + return this._id.includes('@'); + } + + // These next class members are for the Member interface + get name(): string { + return this._id; + } + + get userId(): string { + return this._id; + } + + getMxcAvatarUrl(): string { + return null; + } +} + +class DMUserTile extends React.PureComponent { + static propTypes = { + member: PropTypes.object.isRequired, // Should be a Member (see interface above) + onRemove: PropTypes.func.isRequired, // takes 1 argument, the member being removed + }; + + _onRemove = (e) => { + // Stop the browser from highlighting text + e.preventDefault(); + e.stopPropagation(); + + this.props.onRemove(this.props.member); + }; + + render() { + const BaseAvatar = sdk.getComponent("views.avatars.BaseAvatar"); + const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); + + const avatarSize = 20; + const avatar = this.props.member.isEmail + ? + : ; + + return ( + + + {avatar} + {this.props.member.name} + + + {_t('Remove')} + + + ); + } +} + class DMRoomTile extends React.PureComponent { static propTypes = { - // Has properties to match RoomMember: userId (str), name (str), getMxcAvatarUrl(): string - member: PropTypes.object.isRequired, + member: PropTypes.object.isRequired, // Should be a Member (see interface above) lastActiveTs: PropTypes.number, - onToggle: PropTypes.func.isRequired, + onToggle: PropTypes.func.isRequired, // takes 1 argument, the member being toggled highlightWord: PropTypes.string, }; @@ -70,7 +177,7 @@ class DMRoomTile extends React.PureComponent { e.preventDefault(); e.stopPropagation(); - this.props.onToggle(this.props.member.userId); + this.props.onToggle(this.props.member); }; _highlightName(str: string) { @@ -121,19 +228,22 @@ class DMRoomTile extends React.PureComponent { } const avatarSize = 36; - const avatarUrl = getHttpUriForMxc( - MatrixClientPeg.get().getHomeserverUrl(), this.props.member.getMxcAvatarUrl(), - avatarSize, avatarSize, "crop"); + const avatar = this.props.member.isEmail + ? + : ; return (
- + {avatar} {this._highlightName(this.props.member.name)} {this._highlightName(this.props.member.userId)} {timestamp} @@ -149,12 +259,13 @@ export default class DMInviteDialog extends React.PureComponent { }; _debounceTimer: number = null; + _editorRef: any = null; constructor() { super(); this.state = { - targets: [], // string[] of mxids/email addresses + targets: [], // array of Member objects (see interface above) filterText: "", recents: this._buildRecents(), numRecentsShown: INITIAL_ROOMS_SHOWN, @@ -162,6 +273,8 @@ export default class DMInviteDialog extends React.PureComponent { numSuggestionsShown: INITIAL_ROOMS_SHOWN, serverResultsMixin: [], // { user: DirectoryMember, userId: string }[], like recents and suggestions }; + + this._editorRef = createRef(); } _buildRecents(): {userId: string, user: RoomMember, lastActive: number} { @@ -245,7 +358,7 @@ export default class DMInviteDialog extends React.PureComponent { } _startDm = () => { - this.props.onFinished(this.state.targets); + this.props.onFinished(this.state.targets.map(t => t.userId)); }; _cancel = () => { @@ -292,14 +405,33 @@ export default class DMInviteDialog extends React.PureComponent { this.setState({numSuggestionsShown: this.state.numSuggestionsShown + INCREMENT_ROOMS_SHOWN}); }; - _toggleMember = (userId) => { + _toggleMember = (member: Member) => { const targets = this.state.targets.map(t => t); // cheap clone for mutation - const idx = targets.indexOf(userId); + const idx = targets.indexOf(member); if (idx >= 0) targets.splice(idx, 1); - else targets.push(userId); + else targets.push(member); this.setState({targets}); }; + _removeMember = (member: Member) => { + const targets = this.state.targets.map(t => t); // cheap clone for mutation + const idx = targets.indexOf(member); + if (idx >= 0) { + targets.splice(idx, 1); + this.setState({targets}); + } + }; + + _onClickInputArea = (e) => { + // Stop the browser from highlighting text + e.preventDefault(); + e.stopPropagation(); + + if (this._editorRef && this._editorRef.current) { + this._editorRef.current.focus(); + } + }; + _renderSection(kind: "recents"|"suggestions") { let sourceMembers = kind === 'recents' ? this.state.recents : this.state.suggestions; let showNum = kind === 'recents' ? this.state.numRecentsShown : this.state.numSuggestionsShown; @@ -371,24 +503,31 @@ export default class DMInviteDialog extends React.PureComponent { ); } + _renderEditor() { + const targets = this.state.targets.map(t => ( + + )); + const input = ( +