From 118e752a1fd8f3b900709db205976feb84b95304 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 12 May 2019 23:24:12 +0100 Subject: [PATCH 01/88] Add button to clear all notification counts, sometimes stuck in historical Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/settings/Notifications.js | 22 +++++++++++++++++++ src/i18n/strings/en_EN.json | 1 + 2 files changed, 23 insertions(+) diff --git a/src/components/views/settings/Notifications.js b/src/components/views/settings/Notifications.js index 9b5688aa6a..9e01d44fb6 100644 --- a/src/components/views/settings/Notifications.js +++ b/src/components/views/settings/Notifications.js @@ -29,6 +29,7 @@ import { } from '../../../notifications'; import SdkConfig from "../../../SdkConfig"; import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; +import AccessibleButton from "../elements/AccessibleButton"; // TODO: this "view" component still has far too much application logic in it, // which should be factored out to other files. @@ -654,6 +655,17 @@ module.exports = React.createClass({ MatrixClientPeg.get().getThreePids().then((r) => this.setState({threepids: r.threepids})); }, + _onClearNotifications: function() { + const cli = MatrixClientPeg.get(); + + cli.getRooms().forEach(r => { + if (r.getUnreadNotificationCount() > 0) { + const events = r.getLiveTimeline().getEvents(); + if (events.length) cli.sendReadReceipt(events.pop()); + } + }); + }, + _updatePushRuleActions: function(rule, actions, enabled) { const cli = MatrixClientPeg.get(); @@ -746,6 +758,13 @@ module.exports = React.createClass({ label={_t('Enable notifications for this account')}/>; } + let clearNotificationsButton; + if (MatrixClientPeg.get().getRooms().some(r => r.getUnreadNotificationCount() > 0)) { + clearNotificationsButton = + {_t("Clear notifications")} + ; + } + // When enabled, the master rule inhibits all existing rules // So do not show all notification settings if (this.state.masterPushRule && this.state.masterPushRule.enabled) { @@ -756,6 +775,8 @@ module.exports = React.createClass({
{ _t('All notifications are currently disabled for all targets.') }
+ + {clearNotificationsButton} ); } @@ -877,6 +898,7 @@ module.exports = React.createClass({ { devicesSection } + { clearNotificationsButton } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8534091176..c6a12d8d56 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -501,6 +501,7 @@ "Notify for all other messages/rooms": "Notify for all other messages/rooms", "Notify me for anything else": "Notify me for anything else", "Enable notifications for this account": "Enable notifications for this account", + "Clear notifications": "Clear notifications", "All notifications are currently disabled for all targets.": "All notifications are currently disabled for all targets.", "Add an email address to configure email notifications": "Add an email address to configure email notifications", "Enable email notifications": "Enable email notifications", From 966f84115dc16415269e5285d104f90e3596a988 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 20 Nov 2019 18:26:29 +0000 Subject: [PATCH 02/88] js-sdk rc.1 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index eb234e0573..57e8dd77e3 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "2.4.3", + "matrix-js-sdk": "2.4.4-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 3e43c29ef6..eb72b11793 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5197,10 +5197,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.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.3.tgz#23b78cc707a02eb0ce7eecb3aa50129e46dd5b6e" - integrity sha512-8qTqILd/NmTWF24tpaxmDIzkTk/bZhPD5N8h69PlvJ5Y6kMFctpRj+Tud5zZjl5/yhO07+g+JCyDzg+AagiM/A== +matrix-js-sdk@2.4.4-rc.1: + version "2.4.4-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.4-rc.1.tgz#5fd33fd11be9eea23cd0d0b8eb79da7a4b6253bf" + integrity sha512-Kn94zZMXh2EmihYL3lWNp2lpT7RtqcaUxjkP7H9Mr113swSOXtKr8RWMrvopAIguC1pcLzL+lCk+N8rrML2A4Q== dependencies: another-json "^0.2.0" babel-runtime "^6.26.0" From 318a720e75e9e70831aa7f9cd775cb902274b657 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 20 Nov 2019 18:29:16 +0000 Subject: [PATCH 03/88] Prepare changelog for v1.7.3-rc.1 --- CHANGELOG.md | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c46530fad..2dad0accd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,97 @@ +Changes in [1.7.3-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.3-rc.1) (2019-11-20) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.2...v1.7.3-rc.1) + + * Fix positioning, size, and colour of the composer e2e icon + [\#3641](https://github.com/matrix-org/matrix-react-sdk/pull/3641) + * upgrade nunito from 3.500 to 3.504 + [\#3639](https://github.com/matrix-org/matrix-react-sdk/pull/3639) + * Wire up the widget permission prompt to the cross-platform setting + [\#3630](https://github.com/matrix-org/matrix-react-sdk/pull/3630) + * Get theme automatically from system setting + [\#3637](https://github.com/matrix-org/matrix-react-sdk/pull/3637) + * Update code style for our 90 char life + [\#3636](https://github.com/matrix-org/matrix-react-sdk/pull/3636) + * use general warning icon instead of e2e one for room status + [\#3633](https://github.com/matrix-org/matrix-react-sdk/pull/3633) + * Add support for platform specific event indexing and search + [\#3550](https://github.com/matrix-org/matrix-react-sdk/pull/3550) + * Update from Weblate + [\#3635](https://github.com/matrix-org/matrix-react-sdk/pull/3635) + * Use a settings watcher to set the theme + [\#3634](https://github.com/matrix-org/matrix-react-sdk/pull/3634) + * Merge the `feature_user_info_panel` flag into `feature_dm_verification` + [\#3632](https://github.com/matrix-org/matrix-react-sdk/pull/3632) + * Fix some styling regressions in member panel + [\#3631](https://github.com/matrix-org/matrix-react-sdk/pull/3631) + * Add a bit more safety around breadcrumbs + [\#3629](https://github.com/matrix-org/matrix-react-sdk/pull/3629) + * Ensure widgets always have a sender associated with them + [\#3628](https://github.com/matrix-org/matrix-react-sdk/pull/3628) + * re-add missing case of codepath + [\#3627](https://github.com/matrix-org/matrix-react-sdk/pull/3627) + * Implement the bulk of the new widget permission prompt design + [\#3622](https://github.com/matrix-org/matrix-react-sdk/pull/3622) + * Relax identity server discovery error handling + [\#3588](https://github.com/matrix-org/matrix-react-sdk/pull/3588) + * Add cross-signing feature flag + [\#3626](https://github.com/matrix-org/matrix-react-sdk/pull/3626) + * Attempt number two at ripping out Bluebird from rageshake.js + [\#3624](https://github.com/matrix-org/matrix-react-sdk/pull/3624) + * Update from Weblate + [\#3625](https://github.com/matrix-org/matrix-react-sdk/pull/3625) + * Remove Bluebird: phase 2.1 + [\#3618](https://github.com/matrix-org/matrix-react-sdk/pull/3618) + * Add better error handling to Synapse user deactivation + [\#3619](https://github.com/matrix-org/matrix-react-sdk/pull/3619) + * New design for member panel + [\#3620](https://github.com/matrix-org/matrix-react-sdk/pull/3620) + * Show server details on login for unreachable homeserver + [\#3617](https://github.com/matrix-org/matrix-react-sdk/pull/3617) + * Add a function to get the "base" theme for a theme + [\#3615](https://github.com/matrix-org/matrix-react-sdk/pull/3615) + * Remove Bluebird: phase 2 + [\#3616](https://github.com/matrix-org/matrix-react-sdk/pull/3616) + * Remove Bluebird: phase 1 + [\#3612](https://github.com/matrix-org/matrix-react-sdk/pull/3612) + * Move notification count to in front of the room name in the page title + [\#3613](https://github.com/matrix-org/matrix-react-sdk/pull/3613) + * Add some logging/recovery for lost rooms + [\#3614](https://github.com/matrix-org/matrix-react-sdk/pull/3614) + * Add Mjolnir ban list support + [\#3585](https://github.com/matrix-org/matrix-react-sdk/pull/3585) + * Improve room switching performance with alias cache + [\#3610](https://github.com/matrix-org/matrix-react-sdk/pull/3610) + * Fix draw order when hovering composer format buttons + [\#3609](https://github.com/matrix-org/matrix-react-sdk/pull/3609) + * Use a ternary operator instead of relying on AND semantics in + EditHistoryDialog + [\#3606](https://github.com/matrix-org/matrix-react-sdk/pull/3606) + * Update from Weblate + [\#3608](https://github.com/matrix-org/matrix-react-sdk/pull/3608) + * Fix HTML fallback in replies + [\#3607](https://github.com/matrix-org/matrix-react-sdk/pull/3607) + * Fix rounded corners for the formatting toolbar + [\#3605](https://github.com/matrix-org/matrix-react-sdk/pull/3605) + * Check for a message type before assuming it is a room message + [\#3604](https://github.com/matrix-org/matrix-react-sdk/pull/3604) + * Remove lint comments about no-descending-specificity + [\#3603](https://github.com/matrix-org/matrix-react-sdk/pull/3603) + * Show verification requests in the timeline + [\#3601](https://github.com/matrix-org/matrix-react-sdk/pull/3601) + * Match identity server registration to the IS r0.3.0 spec + [\#3602](https://github.com/matrix-org/matrix-react-sdk/pull/3602) + * Restore thumbs after variation selector removal + [\#3600](https://github.com/matrix-org/matrix-react-sdk/pull/3600) + * Fix breadcrumbs so the bar is a toolbar and the buttons are buttons. + [\#3599](https://github.com/matrix-org/matrix-react-sdk/pull/3599) + * Now that part of spacing is padding, make it smaller when collapsed + [\#3597](https://github.com/matrix-org/matrix-react-sdk/pull/3597) + * Remove variation selectors from quick reactions + [\#3598](https://github.com/matrix-org/matrix-react-sdk/pull/3598) + * Fix linkify imports + [\#3595](https://github.com/matrix-org/matrix-react-sdk/pull/3595) + Changes in [1.7.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.2) (2019-11-06) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.1...v1.7.2) From ef475bbdadd9c4ae1ab9057b6b18602cf39af137 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 20 Nov 2019 18:29:16 +0000 Subject: [PATCH 04/88] v1.7.3-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 57e8dd77e3..e5d2d7635c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.2", + "version": "1.7.3-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 5670a524693c3cc267065dd782967078a27a74d6 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 21 Nov 2019 02:52:36 +0000 Subject: [PATCH 05/88] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1919 of 1919 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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 1dfdc34f1a..2d6d3f55bc 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2344,5 +2344,7 @@ "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "使用這個小工具可能會與 %(widgetDomain)s 以及您的整合管理員分享資料 。", "Using this widget may share data with %(widgetDomain)s.": "使用這個小工具可能會與 %(widgetDomain)s 分享資料 。", "Widget added by": "小工具新增由", - "This widget may use cookies.": "這個小工具可能會使用 cookies。" + "This widget may use cookies.": "這個小工具可能會使用 cookies。", + "Enable local event indexing and E2EE search (requires restart)": "啟用本機事件索引與端到端加密搜尋(需要重新啟動)", + "Match system dark mode setting": "與系統深色模式設定相符" } From 670d44ecd8bfdf41026cfbed45ca5d7f120f5137 Mon Sep 17 00:00:00 2001 From: Tuomas Hietala Date: Thu, 21 Nov 2019 11:36:43 +0000 Subject: [PATCH 06/88] Translated using Weblate (Finnish) Currently translated at 96.1% (1845 of 1919 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fi/ --- src/i18n/strings/fi.json | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json index 80fbb9b138..81a8563e5b 100644 --- a/src/i18n/strings/fi.json +++ b/src/i18n/strings/fi.json @@ -2137,5 +2137,25 @@ "%(count)s unread messages including mentions.|one": "Yksi lukematon maininta.", "%(count)s unread messages.|one": "Yksi lukematon viesti.", "Unread messages.": "Lukemattomat viestit.", - "Message Actions": "Viestitoiminnot" + "Message Actions": "Viestitoiminnot", + "Custom (%(level)s)": "Mukautettu (%(level)s)", + "Match system dark mode setting": "Sovita järjestelmän tumman tilan asetukseen", + "None": "Ei mitään", + "Unsubscribe": "Lopeta tilaus", + "View rules": "Näytä säännöt", + "Subscribe": "Tilaa", + "Direct message": "Yksityisviesti", + "%(role)s in %(roomName)s": "%(role)s huoneessa %(roomName)s", + "Security": "Tietoturva", + "Any of the following data may be shared:": "Seuraavat tiedot saatetaan jakaa:", + "Your display name": "Näyttönimesi", + "Your avatar URL": "Kuvasi URL-osoite", + "Your user ID": "Käyttäjätunnuksesi", + "Your theme": "Teemasi", + "Riot URL": "Riotin URL-osoite", + "Room ID": "Huoneen tunnus", + "Widget ID": "Sovelman tunnus", + "Using this widget may share data with %(widgetDomain)s.": "Tämän sovelman käyttäminen voi jakaa tietoja verkkotunnukselle %(widgetDomain)s.", + "Widget added by": "Sovelman lisäsi", + "This widget may use cookies.": "Tämä sovelma saattaa käyttää evästeitä." } From ad941b96e09c863dd5c2a8add15c455ea9ce9218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 21 Nov 2019 11:17:02 +0000 Subject: [PATCH 07/88] Translated using Weblate (French) Currently translated at 100.0% (1919 of 1919 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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 64272bb839..e58cb187e8 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2351,5 +2351,7 @@ "Using this widget may share data with %(widgetDomain)s.": "L’utilisation de ce widget pourrait partager des données avec %(widgetDomain)s.", "Widget added by": "Widget ajouté par", "This widget may use cookies.": "Ce widget pourrait utiliser des cookies.", - "Send verification requests in direct message, including a new verification UX in the member panel.": "Envoyer les demandes de vérification en message direct, en incluant une nouvelle expérience de vérification dans le tableau des membres." + "Send verification requests in direct message, including a new verification UX in the member panel.": "Envoyer les demandes de vérification en message direct, en incluant une nouvelle expérience de vérification dans le tableau des membres.", + "Enable local event indexing and E2EE search (requires restart)": "Activer l’indexation des événements locaux et la recherche des données chiffrées de bout en bout (nécessite un redémarrage)", + "Match system dark mode setting": "S’adapter aux paramètres de mode sombre du système" } From d786017d08deef229710db2c2cf7a65a0400efd3 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 20 Nov 2019 19:02:23 +0000 Subject: [PATCH 08/88] Translated using Weblate (Hungarian) Currently translated at 100.0% (1919 of 1919 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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 892f21dbb1..e48161d798 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2338,5 +2338,7 @@ "Using this widget may share data with %(widgetDomain)s.": "Ennek a kisalkalmazásnak a használata adatot oszthat meg %(widgetDomain)s domain-nel.", "Widget added by": "A kisalkalmazást hozzáadta", "This widget may use cookies.": "Ez a kisalkalmazás sütiket használhat.", - "Send verification requests in direct message, including a new verification UX in the member panel.": "Ellenőrzés küldése közvetlen üzenetben, beleértve az új ellenőrzési felhasználói élményt a résztvevői panelen." + "Send verification requests in direct message, including a new verification UX in the member panel.": "Ellenőrzés küldése közvetlen üzenetben, beleértve az új ellenőrzési felhasználói élményt a résztvevői panelen.", + "Enable local event indexing and E2EE search (requires restart)": "Helyi esemény indexálás és végponttól végpontig titkosított események keresésének engedélyezése (újraindítás szükséges)", + "Match system dark mode setting": "Rendszer sötét témájához alkalmazkodás" } From 87167f42f89cd8c2f3e87f8d18ad95d717ad678e Mon Sep 17 00:00:00 2001 From: random Date: Thu, 21 Nov 2019 09:34:39 +0000 Subject: [PATCH 09/88] Translated using Weblate (Italian) Currently translated at 99.9% (1917 of 1919 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 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index efab4595f6..9faa48328c 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2295,5 +2295,8 @@ "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "Usando questo widget i dati possono essere condivisi con %(widgetDomain)s e il tuo Gestore di Integrazione.", "Using this widget may share data with %(widgetDomain)s.": "Usando questo widget i dati possono essere condivisi con %(widgetDomain)s.", "Widget added by": "Widget aggiunto da", - "This widget may use cookies.": "Questo widget può usare cookie." + "This widget may use cookies.": "Questo widget può usare cookie.", + "Send verification requests in direct message, including a new verification UX in the member panel.": "Invia le richieste di verifica via messaggio diretto, inclusa una nuova esperienza utente per la verifica nel pannello membri.", + "Enable local event indexing and E2EE search (requires restart)": "Attiva l'indicizzazione di eventi locali e la ricerca E2EE (richiede riavvio)", + "Match system dark mode setting": "Combacia la modalità scura di sistema" } From 598901b48339e5547b1396db16e81d8b2ab5e932 Mon Sep 17 00:00:00 2001 From: Edgars Voroboks Date: Wed, 20 Nov 2019 18:58:42 +0000 Subject: [PATCH 10/88] Translated using Weblate (Latvian) Currently translated at 47.8% (918 of 1919 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lv/ --- src/i18n/strings/lv.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 80e173dc3f..1c7d2b0311 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -1144,5 +1144,8 @@ "You do not have permission to start a conference call in this room": "Šajā istabā nav atļaujas sākt konferences zvanu", "Replying With Files": "Atbildot ar failiem", "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Šobrīd nav iespējams atbildēt ar failu. Vai vēlaties augšupielādēt šo failu, neatbildot?", - "Your Riot is misconfigured": "Jūsu Riot ir nepareizi konfigurēts" + "Your Riot is misconfigured": "Jūsu Riot ir nepareizi konfigurēts", + "Add Email Address": "Pievienot e-pasta adresi", + "Add Phone Number": "Pievienot tālruņa numuru", + "Call failed due to misconfigured server": "Zvans neizdevās nekorekti nokonfigurēta servera dēļ" } From 08e08376a204e34926a525b34454427589878b25 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 21 Nov 2019 15:19:59 +0000 Subject: [PATCH 11/88] Translated using Weblate (Hungarian) Currently translated at 100.0% (1922 of 1922 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 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index e48161d798..70a966ce3d 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2340,5 +2340,11 @@ "This widget may use cookies.": "Ez a kisalkalmazás sütiket használhat.", "Send verification requests in direct message, including a new verification UX in the member panel.": "Ellenőrzés küldése közvetlen üzenetben, beleértve az új ellenőrzési felhasználói élményt a résztvevői panelen.", "Enable local event indexing and E2EE search (requires restart)": "Helyi esemény indexálás és végponttól végpontig titkosított események keresésének engedélyezése (újraindítás szükséges)", - "Match system dark mode setting": "Rendszer sötét témájához alkalmazkodás" + "Match system dark mode setting": "Rendszer sötét témájához alkalmazkodás", + "Widgets are not encrypted.": "A kisalkalmazások nem titkosítottak.", + "More options": "További beállítások", + "Reload": "Újratölt", + "Take picture": "Fénykép készítés", + "Remove for everyone": "Visszavonás mindenkitől", + "Remove for me": "Visszavonás magamtól" } From 5d8476185f83e73ff06a59e89a71a4f53bf0a419 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 21 Nov 2019 17:00:35 +0000 Subject: [PATCH 12/88] Catch exceptions when we can't play audio ...or try to: the chrome debugger still breakpoints, even when we catch the exception. Related to, but probably does not fix https://github.com/vector-im/riot-web/issues/7657 --- src/CallHandler.js | 17 +++++++++++++++-- src/Notifier.js | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/CallHandler.js b/src/CallHandler.js index 625ca8c551..c15fda1ef9 100644 --- a/src/CallHandler.js +++ b/src/CallHandler.js @@ -80,13 +80,26 @@ function play(audioId) { // which listens? const audio = document.getElementById(audioId); if (audio) { + const playAudio = async () => { + try { + // This still causes the chrome debugger to break on promise rejection if + // the promise is rejected, even though we're catching the exception. + await audio.play(); + } catch (e) { + // This is usually because the user hasn't interacted with the document, + // or chrome doesn't think so and is denying the request. Not sure what + // we can really do here... + // https://github.com/vector-im/riot-web/issues/7657 + console.log("Unable to play audio clip", e); + } + }; if (audioPromises[audioId]) { audioPromises[audioId] = audioPromises[audioId].then(()=>{ audio.load(); - return audio.play(); + return playAudio(); }); } else { - audioPromises[audioId] = audio.play(); + audioPromises[audioId] = playAudio(); } } } diff --git a/src/Notifier.js b/src/Notifier.js index edb9850dfe..dd691d8ca7 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -146,7 +146,7 @@ const Notifier = { } document.body.appendChild(audioElement); } - audioElement.play(); + await audioElement.play(); } catch (ex) { console.warn("Caught error when trying to fetch room notification sound:", ex); } From 3cddcad5de18f926dcd2b44e0b4dfe36968018d3 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:12:32 +0100 Subject: [PATCH 13/88] use correct icons with borders --- res/img/e2e/verified.svg | 14 +++----------- res/img/e2e/warning.svg | 15 ++++----------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/res/img/e2e/verified.svg b/res/img/e2e/verified.svg index af6bb92297..464b443dcf 100644 --- a/res/img/e2e/verified.svg +++ b/res/img/e2e/verified.svg @@ -1,12 +1,4 @@ - - - + + + diff --git a/res/img/e2e/warning.svg b/res/img/e2e/warning.svg index 2501da6ab3..209ae0f71f 100644 --- a/res/img/e2e/warning.svg +++ b/res/img/e2e/warning.svg @@ -1,12 +1,5 @@ - - - + + + + From cb0e6ca5d280d16b951e843748936f337f05d802 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:13:01 +0100 Subject: [PATCH 14/88] dont make e2e icons themable, as they have multiple colors --- res/css/views/rooms/_E2EIcon.scss | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/res/css/views/rooms/_E2EIcon.scss b/res/css/views/rooms/_E2EIcon.scss index 1ee5008888..cb99aa63f1 100644 --- a/res/css/views/rooms/_E2EIcon.scss +++ b/res/css/views/rooms/_E2EIcon.scss @@ -15,8 +15,8 @@ limitations under the License. */ .mx_E2EIcon { - width: 25px; - height: 25px; + width: 16px; + height: 16px; margin: 0 9px; position: relative; display: block; @@ -30,16 +30,14 @@ limitations under the License. bottom: 0; left: 0; right: 0; - mask-repeat: no-repeat; - mask-size: contain; + background-repeat: no-repeat; + background-size: contain; } .mx_E2EIcon_verified::after { - mask-image: url('$(res)/img/e2e/verified.svg'); - background-color: $accent-color; + background-image: url('$(res)/img/e2e/verified.svg'); } .mx_E2EIcon_warning::after { - mask-image: url('$(res)/img/e2e/warning.svg'); - background-color: $warning-color; + background-image: url('$(res)/img/e2e/warning.svg'); } From 854f27df3fbd0b8d65790a06c33d0ed301756a7f Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:14:25 +0100 Subject: [PATCH 15/88] remove obsolete style from message composer for e2e icon as it's now the default size for the e2e iconn --- res/css/views/rooms/_MessageComposer.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 036756e2eb..12e45a07c9 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -74,8 +74,6 @@ limitations under the License. .mx_MessageComposer_e2eIcon.mx_E2EIcon { position: absolute; left: 60px; - width: 16px; - height: 16px; margin-right: 0; // Counteract the E2EIcon class margin-left: 3px; // Counteract the E2EIcon class } From f75e45a715db4314ffa23684412d24fbd86f02a4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:17:55 +0100 Subject: [PATCH 16/88] reduce margin on e2e icon in room header --- res/css/views/rooms/_RoomHeader.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/res/css/views/rooms/_RoomHeader.scss b/res/css/views/rooms/_RoomHeader.scss index 5da8ff76b9..f1e4456cc1 100644 --- a/res/css/views/rooms/_RoomHeader.scss +++ b/res/css/views/rooms/_RoomHeader.scss @@ -17,6 +17,10 @@ limitations under the License. .mx_RoomHeader { flex: 0 0 52px; border-bottom: 1px solid $primary-hairline-color; + + .mx_E2EIcon { + margin: 0 5px; + } } .mx_RoomHeader_wrapper { From b239fde32dec454b29f9b11611e02862a79cd979 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 21 Nov 2019 17:31:57 +0000 Subject: [PATCH 17/88] Workaround for soft-crash with calls on startup Fixes https://github.com/vector-im/riot-web/issues/11458 --- src/components/views/voip/CallView.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/views/voip/CallView.js b/src/components/views/voip/CallView.js index a4d7927ac3..cf1f505197 100644 --- a/src/components/views/voip/CallView.js +++ b/src/components/views/voip/CallView.js @@ -90,6 +90,13 @@ module.exports = createReactClass({ } } else { call = CallHandler.getAnyActiveCall(); + // Ignore calls if we can't get the room associated with them. + // I think the underlying problem is that the js-sdk sends events + // for calls before it has made the rooms available in the store, + // although this isn't confirmed. + if (MatrixClientPeg.get().getRoom(call.roomId) === null) { + call = null; + } this.setState({ call: call }); } From a02a285058fdc38bebcc198aaefe06d1f28cd586 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 Nov 2019 10:24:51 +0000 Subject: [PATCH 18/88] Show m.room.create event before the ELS on room upgrade Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/MessagePanel.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index cf2a5b1738..39504666bf 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -411,6 +411,11 @@ module.exports = createReactClass({ readMarkerInSummary = true; } + // If this m.room.create event should be shown (room upgrade) then show it before the summary + if (this._shouldShowEvent(mxEv)) { + ret.push(...this._getTilesForEvent(prevEvent, mxEv, false)); + } + const summarisedEvents = []; // Don't add m.room.create here as we don't want it inside the summary for (;i + 1 < this.props.events.length; i++) { const collapsedMxEv = this.props.events[i + 1]; From 6d4abeef4515bab769d04359a2ded0ca70219d57 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 22 Nov 2019 12:07:25 +0000 Subject: [PATCH 19/88] Convert MessagePanel to React class I was about to add the getDerivedStateFromProps function to change how read markers worked, but doing that in an old style class means the statics object, so let;s just convert the thing. --- src/components/structures/MessagePanel.js | 132 +++++++++++----------- 1 file changed, 65 insertions(+), 67 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index cf2a5b1738..3781dd0ce7 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -1,6 +1,7 @@ /* Copyright 2016 OpenMarket Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ limitations under the License. /* global Velocity */ import React from 'react'; -import createReactClass from 'create-react-class'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import classNames from 'classnames'; @@ -37,10 +37,8 @@ const isMembershipChange = (e) => e.getType() === 'm.room.member' || e.getType() /* (almost) stateless UI component which builds the event tiles in the room timeline. */ -module.exports = createReactClass({ - displayName: 'MessagePanel', - - propTypes: { +export default class MessagePanel extends React.Component { + propTypes = { // true to give the component a 'display: none' style. hidden: PropTypes.bool, @@ -109,9 +107,9 @@ module.exports = createReactClass({ // whether to show reactions for an event showReactions: PropTypes.bool, - }, + }; - componentWillMount: function() { + componentDidMount() { // the event after which we put a visible unread marker on the last // render cycle; null if readMarkerVisible was false or the RM was // suppressed (eg because it was at the end of the timeline) @@ -168,37 +166,37 @@ module.exports = createReactClass({ SettingsStore.getValue("showHiddenEventsInTimeline"); this._isMounted = true; - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this._isMounted = false; - }, + } /* get the DOM node representing the given event */ - getNodeForEventId: function(eventId) { + getNodeForEventId(eventId) { if (!this.eventNodes) { return undefined; } return this.eventNodes[eventId]; - }, + } /* return true if the content is fully scrolled down right now; else false. */ - isAtBottom: function() { + isAtBottom() { return this.refs.scrollPanel && this.refs.scrollPanel.isAtBottom(); - }, + } /* get the current scroll state. See ScrollPanel.getScrollState for * details. * * returns null if we are not mounted. */ - getScrollState: function() { + getScrollState() { if (!this.refs.scrollPanel) { return null; } return this.refs.scrollPanel.getScrollState(); - }, + } // returns one of: // @@ -206,7 +204,7 @@ module.exports = createReactClass({ // -1: read marker is above the window // 0: read marker is within the window // +1: read marker is below the window - getReadMarkerPosition: function() { + getReadMarkerPosition() { const readMarker = this.refs.readMarkerNode; const messageWrapper = this.refs.scrollPanel; @@ -226,45 +224,45 @@ module.exports = createReactClass({ } else { return 1; } - }, + } /* jump to the top of the content. */ - scrollToTop: function() { + scrollToTop() { if (this.refs.scrollPanel) { this.refs.scrollPanel.scrollToTop(); } - }, + } /* jump to the bottom of the content. */ - scrollToBottom: function() { + scrollToBottom() { if (this.refs.scrollPanel) { this.refs.scrollPanel.scrollToBottom(); } - }, + } /** * Page up/down. * * @param {number} mult: -1 to page up, +1 to page down */ - scrollRelative: function(mult) { + scrollRelative(mult) { if (this.refs.scrollPanel) { this.refs.scrollPanel.scrollRelative(mult); } - }, + } /** * Scroll up/down in response to a scroll key * * @param {KeyboardEvent} ev: the keyboard event to handle */ - handleScrollKey: function(ev) { + handleScrollKey(ev) { if (this.refs.scrollPanel) { this.refs.scrollPanel.handleScrollKey(ev); } - }, + } /* jump to the given event id. * @@ -276,33 +274,33 @@ module.exports = createReactClass({ * node (specifically, the bottom of it) will be positioned. If omitted, it * defaults to 0. */ - scrollToEvent: function(eventId, pixelOffset, offsetBase) { + scrollToEvent(eventId, pixelOffset, offsetBase) { if (this.refs.scrollPanel) { this.refs.scrollPanel.scrollToToken(eventId, pixelOffset, offsetBase); } - }, + } - scrollToEventIfNeeded: function(eventId) { + scrollToEventIfNeeded(eventId) { const node = this.eventNodes[eventId]; if (node) { node.scrollIntoView({block: "nearest", behavior: "instant"}); } - }, + } /* check the scroll state and send out pagination requests if necessary. */ - checkFillState: function() { + checkFillState() { if (this.refs.scrollPanel) { this.refs.scrollPanel.checkFillState(); } - }, + } - _isUnmounting: function() { + _isUnmounting() { return !this._isMounted; - }, + } // TODO: Implement granular (per-room) hide options - _shouldShowEvent: function(mxEv) { + _shouldShowEvent(mxEv) { if (mxEv.sender && MatrixClientPeg.get().isUserIgnored(mxEv.sender.userId)) { return false; // ignored = no show (only happens if the ignore happens after an event was received) } @@ -320,9 +318,9 @@ module.exports = createReactClass({ if (this.props.highlightedEventId === mxEv.getId()) return true; return !shouldHideEvent(mxEv); - }, + } - _getEventTiles: function() { + _getEventTiles() { const DateSeparator = sdk.getComponent('messages.DateSeparator'); const EventListSummary = sdk.getComponent('views.elements.EventListSummary'); const MemberEventListSummary = sdk.getComponent('views.elements.MemberEventListSummary'); @@ -596,9 +594,9 @@ module.exports = createReactClass({ this.currentReadMarkerEventId = readMarkerVisible ? this.props.readMarkerEventId : null; return ret; - }, + } - _getTilesForEvent: function(prevEvent, mxEv, last) { + _getTilesForEvent(prevEvent, mxEv, last) { const EventTile = sdk.getComponent('rooms.EventTile'); const DateSeparator = sdk.getComponent('messages.DateSeparator'); const ret = []; @@ -691,20 +689,20 @@ module.exports = createReactClass({ ); return ret; - }, + } - _wantsDateSeparator: function(prevEvent, nextEventDate) { + _wantsDateSeparator(prevEvent, nextEventDate) { if (prevEvent == null) { // first event in the panel: depends if we could back-paginate from // here. return !this.props.suppressFirstDateSeparator; } return wantsDateSeparator(prevEvent.getDate(), nextEventDate); - }, + } // Get a list of read receipts that should be shown next to this event // Receipts are objects which have a 'userId', 'roomMember' and 'ts'. - _getReadReceiptsForEvent: function(event) { + _getReadReceiptsForEvent(event) { const myUserId = MatrixClientPeg.get().credentials.userId; // get list of read receipts, sorted most recent first @@ -728,12 +726,12 @@ module.exports = createReactClass({ }); }); return receipts; - }, + } // Get an object that maps from event ID to a list of read receipts that // should be shown next to that event. If a hidden event has read receipts, // they are folded into the receipts of the last shown event. - _getReadReceiptsByShownEvent: function() { + _getReadReceiptsByShownEvent() { const receiptsByEvent = {}; const receiptsByUserId = {}; @@ -786,9 +784,9 @@ module.exports = createReactClass({ } return receiptsByEvent; - }, + } - _getReadMarkerTile: function(visible) { + _getReadMarkerTile(visible) { let hr; if (visible) { hr =
); - }, + } - _startAnimation: function(ghostNode) { + _startAnimation = (ghostNode) => { if (this._readMarkerGhostNode) { Velocity.Utilities.removeData(this._readMarkerGhostNode); } @@ -816,9 +814,9 @@ module.exports = createReactClass({ {duration: 400, easing: 'easeInSine', delay: 1000}); } - }, + }; - _getReadMarkerGhostTile: function() { + _getReadMarkerGhostTile() { const hr =
); - }, + } - _collectEventNode: function(eventId, node) { + _collectEventNode = (eventId, node) => { this.eventNodes[eventId] = node; - }, + } // once dynamic content in the events load, make the scrollPanel check the // scroll offsets. - _onHeightChanged: function() { + _onHeightChanged = () => { const scrollPanel = this.refs.scrollPanel; if (scrollPanel) { scrollPanel.checkScroll(); } - }, + }; - _onTypingShown: function() { + _onTypingShown = () => { const scrollPanel = this.refs.scrollPanel; // this will make the timeline grow, so checkScroll scrollPanel.checkScroll(); if (scrollPanel && scrollPanel.getScrollState().stuckAtBottom) { scrollPanel.preventShrinking(); } - }, + }; - _onTypingHidden: function() { + _onTypingHidden = () => { const scrollPanel = this.refs.scrollPanel; if (scrollPanel) { // as hiding the typing notifications doesn't @@ -868,9 +866,9 @@ module.exports = createReactClass({ // reveal added padding to balance the notifs disappearing. scrollPanel.checkScroll(); } - }, + }; - updateTimelineMinHeight: function() { + updateTimelineMinHeight() { const scrollPanel = this.refs.scrollPanel; if (scrollPanel) { @@ -885,16 +883,16 @@ module.exports = createReactClass({ scrollPanel.preventShrinking(); } } - }, + } - onTimelineReset: function() { + onTimelineReset() { const scrollPanel = this.refs.scrollPanel; if (scrollPanel) { scrollPanel.clearPreventShrinking(); } - }, + } - render: function() { + render() { const ScrollPanel = sdk.getComponent("structures.ScrollPanel"); const WhoIsTypingTile = sdk.getComponent("rooms.WhoIsTypingTile"); const Spinner = sdk.getComponent("elements.Spinner"); @@ -941,5 +939,5 @@ module.exports = createReactClass({ { bottomSpinner } ); - }, -}); + } +} From fd5a5e13ee0c485716e7d758e2da63c9b434ee12 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 22 Nov 2019 12:59:51 +0000 Subject: [PATCH 20/88] Make addEventListener conditional Safari doesn't support addEventListener --- src/theme.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/theme.js b/src/theme.js index 92bf03ef0a..9208ff2045 100644 --- a/src/theme.js +++ b/src/theme.js @@ -41,14 +41,18 @@ export class ThemeWatcher { start() { this._themeWatchRef = SettingsStore.watchSetting("theme", null, this._onChange); this._systemThemeWatchRef = SettingsStore.watchSetting("use_system_theme", null, this._onChange); - this._preferDark.addEventListener('change', this._onChange); - this._preferLight.addEventListener('change', this._onChange); + if (this._preferDark.addEventListener) { + this._preferDark.addEventListener('change', this._onChange); + this._preferLight.addEventListener('change', this._onChange); + } this._dispatcherRef = dis.register(this._onAction); } stop() { - this._preferDark.removeEventListener('change', this._onChange); - this._preferLight.removeEventListener('change', this._onChange); + if (this._preferDark.addEventListener) { + this._preferDark.removeEventListener('change', this._onChange); + this._preferLight.removeEventListener('change', this._onChange); + } SettingsStore.unwatchSetting(this._systemThemeWatchRef); SettingsStore.unwatchSetting(this._themeWatchRef); dis.unregister(this._dispatcherRef); From 3f5a8faf376b33499258f071b1eefe69e8c2c5ee Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 22 Nov 2019 13:01:56 +0000 Subject: [PATCH 21/88] PropTypes should be static --- res/css/structures/_RoomView.scss | 1 + src/components/structures/MessagePanel.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 50d412ad58..8e47fe7509 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -221,6 +221,7 @@ hr.mx_RoomView_myReadMarker { position: relative; top: -1px; z-index: 1; + transition: width 1s easeInSine; } .mx_RoomView_callStatusBar .mx_UploadBar_uploadProgressInner { diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 3781dd0ce7..bd5630ab12 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -38,7 +38,7 @@ const isMembershipChange = (e) => e.getType() === 'm.room.member' || e.getType() /* (almost) stateless UI component which builds the event tiles in the room timeline. */ export default class MessagePanel extends React.Component { - propTypes = { + static propTypes = { // true to give the component a 'display: none' style. hidden: PropTypes.bool, From 0dbb639aea1ef008bcdede36899112f3b7bca1fa Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 22 Nov 2019 13:06:35 +0000 Subject: [PATCH 22/88] Accidentally committed --- res/css/structures/_RoomView.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 8e47fe7509..50d412ad58 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -221,7 +221,6 @@ hr.mx_RoomView_myReadMarker { position: relative; top: -1px; z-index: 1; - transition: width 1s easeInSine; } .mx_RoomView_callStatusBar .mx_UploadBar_uploadProgressInner { From 936c36dd586ebaacfe203f00759f7d01f1abe0dd Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 22 Nov 2019 03:23:27 +0000 Subject: [PATCH 23/88] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1918 of 1918 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 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 2d6d3f55bc..2fd014554e 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2346,5 +2346,22 @@ "Widget added by": "小工具新增由", "This widget may use cookies.": "這個小工具可能會使用 cookies。", "Enable local event indexing and E2EE search (requires restart)": "啟用本機事件索引與端到端加密搜尋(需要重新啟動)", - "Match system dark mode setting": "與系統深色模式設定相符" + "Match system dark mode setting": "與系統深色模式設定相符", + "Connecting to integration manager...": "正在連線到整合管理員……", + "Cannot connect to integration manager": "無法連線到整合管理員", + "The integration manager is offline or it cannot reach your homeserver.": "整合管理員已離線或無法存取您的家伺服器。", + "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "使用整合管理員 (%(serverName)s) 以管理機器人、小工具與貼紙包。", + "Use an Integration Manager to manage bots, widgets, and sticker packs.": "使用整合管理員以管理機器人、小工具與貼紙包。", + "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "整合管理員接收設定資料,並可以修改小工具、傳送聊天室邀請並設定權限等級。", + "Failed to connect to integration manager": "連線到整合管理員失敗", + "Widgets do not use message encryption.": "小工具不使用訊息加密。", + "More options": "更多選項", + "Integrations are disabled": "整合已停用", + "Enable 'Manage Integrations' in Settings to do this.": "在設定中啟用「管理整合」以執行此動作。", + "Integrations not allowed": "不允許整合", + "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "您的 Riot 不允許您使用整合管理員來執行此動作。請聯絡管理員。", + "Reload": "重新載入", + "Take picture": "拍照", + "Remove for everyone": "對所有人移除", + "Remove for me": "對我移除" } From 27c64db613281d6d44c35fca40402c53df8e39c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Fri, 22 Nov 2019 08:35:43 +0000 Subject: [PATCH 24/88] Translated using Weblate (French) Currently translated at 100.0% (1918 of 1918 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 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index e58cb187e8..0c13b3c722 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2353,5 +2353,22 @@ "This widget may use cookies.": "Ce widget pourrait utiliser des cookies.", "Send verification requests in direct message, including a new verification UX in the member panel.": "Envoyer les demandes de vérification en message direct, en incluant une nouvelle expérience de vérification dans le tableau des membres.", "Enable local event indexing and E2EE search (requires restart)": "Activer l’indexation des événements locaux et la recherche des données chiffrées de bout en bout (nécessite un redémarrage)", - "Match system dark mode setting": "S’adapter aux paramètres de mode sombre du système" + "Match system dark mode setting": "S’adapter aux paramètres de mode sombre du système", + "Connecting to integration manager...": "Connexion au gestionnaire d’intégrations…", + "Cannot connect to integration manager": "Impossible de se connecter au gestionnaire d’intégrations", + "The integration manager is offline or it cannot reach your homeserver.": "Le gestionnaire d’intégrations est hors ligne ou il ne peut pas joindre votre serveur d’accueil.", + "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Utilisez un gestionnaire d’intégrations (%(serverName)s) pour gérer les bots, les widgets et les packs de stickers.", + "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Utilisez un gestionnaire d’intégrations pour gérer les bots, les widgets et les packs de stickers.", + "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Les gestionnaires d’intégrations reçoivent les données de configuration et peuvent modifier les widgets, envoyer des invitations aux salons et définir les rangs à votre place.", + "Failed to connect to integration manager": "Échec de la connexion au gestionnaire d’intégrations", + "Widgets do not use message encryption.": "Les widgets n’utilisent pas le chiffrement des messages.", + "More options": "Plus d’options", + "Integrations are disabled": "Les intégrations sont désactivées", + "Enable 'Manage Integrations' in Settings to do this.": "Activez « Gérer les intégrations » dans les paramètres pour faire ça.", + "Integrations not allowed": "Les intégrations ne sont pas autorisées", + "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Votre Riot ne vous autorise pas à utiliser un gestionnaire d’intégrations pour faire ça. Contactez un administrateur.", + "Reload": "Recharger", + "Take picture": "Prendre une photo", + "Remove for everyone": "Supprimer pour tout le monde", + "Remove for me": "Supprimer pour moi" } From fed1ed3b500d5e98bc04ab9ab52dd9f63949db06 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 21 Nov 2019 20:00:59 +0000 Subject: [PATCH 25/88] Translated using Weblate (Hungarian) Currently translated at 100.0% (1918 of 1918 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 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 70a966ce3d..7ed4eb253c 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2346,5 +2346,17 @@ "Reload": "Újratölt", "Take picture": "Fénykép készítés", "Remove for everyone": "Visszavonás mindenkitől", - "Remove for me": "Visszavonás magamtól" + "Remove for me": "Visszavonás magamtól", + "Connecting to integration manager...": "Kapcsolódás az integrációs menedzserhez...", + "Cannot connect to integration manager": "A kapcsolódás az integrációs menedzserhez sikertelen", + "The integration manager is offline or it cannot reach your homeserver.": "Az integrációs menedzser nem működik vagy nem éri el a matrix szerveredet.", + "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Használj Integrációs Menedzsert (%(serverName)s) a botok, kisalkalmazások és matrica csomagok kezeléséhez.", + "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Használj Integrációs Menedzsert a botok, kisalkalmazások és matrica csomagok kezeléséhez.", + "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integrációs Menedzser megkapja a konfigurációt, módosíthat kisalkalmazásokat, szobához meghívót küldhet és a hozzáférési szintet beállíthatja helyetted.", + "Failed to connect to integration manager": "Az integrációs menedzserhez nem sikerült csatlakozni", + "Widgets do not use message encryption.": "A kisalkalmazások nem használnak üzenet titkosítást.", + "Integrations are disabled": "Az integrációk le vannak tiltva", + "Enable 'Manage Integrations' in Settings to do this.": "Ehhez engedélyezd az „Integrációk Kezelésé”-t a Beállításokban.", + "Integrations not allowed": "Az integrációk nem engedélyezettek", + "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "A Riotod nem használhat ehhez Integrációs Menedzsert. Kérlek vedd fel a kapcsolatot az adminisztrátorral." } From 25ba4c5f7124d40fd5d83cddba30b1479f64dc0c Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 22 Nov 2019 13:11:36 +0000 Subject: [PATCH 26/88] Fix read markers init code needs to be a constructor or its run too late --- src/components/structures/MessagePanel.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index bd5630ab12..22be35db60 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -109,7 +109,8 @@ export default class MessagePanel extends React.Component { showReactions: PropTypes.bool, }; - componentDidMount() { + constructor() { + super(); // the event after which we put a visible unread marker on the last // render cycle; null if readMarkerVisible was false or the RM was // suppressed (eg because it was at the end of the timeline) @@ -165,6 +166,10 @@ export default class MessagePanel extends React.Component { this._showHiddenEventsInTimeline = SettingsStore.getValue("showHiddenEventsInTimeline"); + this._isMounted = false; + } + + componentDidMount() { this._isMounted = true; } From d1501a16515c003a949cd819be4a1f34c567f8ea Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:17:55 +0100 Subject: [PATCH 27/88] reduce margin on e2e icon in room header --- res/css/views/rooms/_RoomHeader.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/res/css/views/rooms/_RoomHeader.scss b/res/css/views/rooms/_RoomHeader.scss index 5da8ff76b9..f1e4456cc1 100644 --- a/res/css/views/rooms/_RoomHeader.scss +++ b/res/css/views/rooms/_RoomHeader.scss @@ -17,6 +17,10 @@ limitations under the License. .mx_RoomHeader { flex: 0 0 52px; border-bottom: 1px solid $primary-hairline-color; + + .mx_E2EIcon { + margin: 0 5px; + } } .mx_RoomHeader_wrapper { From de645a32a8d3024956270094bc01e4b6277d7bf9 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:14:25 +0100 Subject: [PATCH 28/88] remove obsolete style from message composer for e2e icon as it's now the default size for the e2e iconn --- res/css/views/rooms/_MessageComposer.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 036756e2eb..12e45a07c9 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -74,8 +74,6 @@ limitations under the License. .mx_MessageComposer_e2eIcon.mx_E2EIcon { position: absolute; left: 60px; - width: 16px; - height: 16px; margin-right: 0; // Counteract the E2EIcon class margin-left: 3px; // Counteract the E2EIcon class } From 9c234d93172c77b532b696ce18f71fb77e70db66 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:13:01 +0100 Subject: [PATCH 29/88] dont make e2e icons themable, as they have multiple colors --- res/css/views/rooms/_E2EIcon.scss | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/res/css/views/rooms/_E2EIcon.scss b/res/css/views/rooms/_E2EIcon.scss index 1ee5008888..cb99aa63f1 100644 --- a/res/css/views/rooms/_E2EIcon.scss +++ b/res/css/views/rooms/_E2EIcon.scss @@ -15,8 +15,8 @@ limitations under the License. */ .mx_E2EIcon { - width: 25px; - height: 25px; + width: 16px; + height: 16px; margin: 0 9px; position: relative; display: block; @@ -30,16 +30,14 @@ limitations under the License. bottom: 0; left: 0; right: 0; - mask-repeat: no-repeat; - mask-size: contain; + background-repeat: no-repeat; + background-size: contain; } .mx_E2EIcon_verified::after { - mask-image: url('$(res)/img/e2e/verified.svg'); - background-color: $accent-color; + background-image: url('$(res)/img/e2e/verified.svg'); } .mx_E2EIcon_warning::after { - mask-image: url('$(res)/img/e2e/warning.svg'); - background-color: $warning-color; + background-image: url('$(res)/img/e2e/warning.svg'); } From 35877a06a387e5148cdcb1aa2158283dbdeb5371 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 21 Nov 2019 18:12:32 +0100 Subject: [PATCH 30/88] use correct icons with borders --- res/img/e2e/verified.svg | 14 +++----------- res/img/e2e/warning.svg | 15 ++++----------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/res/img/e2e/verified.svg b/res/img/e2e/verified.svg index af6bb92297..464b443dcf 100644 --- a/res/img/e2e/verified.svg +++ b/res/img/e2e/verified.svg @@ -1,12 +1,4 @@ - - - + + + diff --git a/res/img/e2e/warning.svg b/res/img/e2e/warning.svg index 2501da6ab3..209ae0f71f 100644 --- a/res/img/e2e/warning.svg +++ b/res/img/e2e/warning.svg @@ -1,12 +1,5 @@ - - - + + + + From 521cbbac74b392d61b1b85c31d6e0d06808929d3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 22 Nov 2019 12:59:51 +0000 Subject: [PATCH 31/88] Make addEventListener conditional Safari doesn't support addEventListener --- src/theme.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/theme.js b/src/theme.js index fa7e3f783b..e89af55924 100644 --- a/src/theme.js +++ b/src/theme.js @@ -41,14 +41,18 @@ export class ThemeWatcher { start() { this._themeWatchRef = SettingsStore.watchSetting("theme", null, this._onChange); this._systemThemeWatchRef = SettingsStore.watchSetting("use_system_theme", null, this._onChange); - this._preferDark.addEventListener('change', this._onChange); - this._preferLight.addEventListener('change', this._onChange); + if (this._preferDark.addEventListener) { + this._preferDark.addEventListener('change', this._onChange); + this._preferLight.addEventListener('change', this._onChange); + } this._dispatcherRef = dis.register(this._onAction); } stop() { - this._preferDark.removeEventListener('change', this._onChange); - this._preferLight.removeEventListener('change', this._onChange); + if (this._preferDark.addEventListener) { + this._preferDark.removeEventListener('change', this._onChange); + this._preferLight.removeEventListener('change', this._onChange); + } SettingsStore.unwatchSetting(this._systemThemeWatchRef); SettingsStore.unwatchSetting(this._themeWatchRef); dis.unregister(this._dispatcherRef); From 5ec4b6efcdf74197b8efd60e1014aa0d83d50d6b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 Nov 2019 10:24:51 +0000 Subject: [PATCH 32/88] Show m.room.create event before the ELS on room upgrade Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/MessagePanel.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index cf2a5b1738..39504666bf 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -411,6 +411,11 @@ module.exports = createReactClass({ readMarkerInSummary = true; } + // If this m.room.create event should be shown (room upgrade) then show it before the summary + if (this._shouldShowEvent(mxEv)) { + ret.push(...this._getTilesForEvent(prevEvent, mxEv, false)); + } + const summarisedEvents = []; // Don't add m.room.create here as we don't want it inside the summary for (;i + 1 < this.props.events.length; i++) { const collapsedMxEv = this.props.events[i + 1]; From e86d2b616e647f85bbfa56cb79bc952ca932ad40 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 20 Nov 2019 16:18:28 +0100 Subject: [PATCH 33/88] add ToastContainer --- res/css/_components.scss | 1 + res/css/structures/_ToastContainer.scss | 105 ++++++++++++++++++++ src/components/structures/LoggedInView.js | 2 + src/components/structures/ToastContainer.js | 85 ++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 res/css/structures/_ToastContainer.scss create mode 100644 src/components/structures/ToastContainer.js diff --git a/res/css/_components.scss b/res/css/_components.scss index 40a2c576d0..f7147b3b9f 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -25,6 +25,7 @@ @import "./structures/_TabbedView.scss"; @import "./structures/_TagPanel.scss"; @import "./structures/_TagPanelButtons.scss"; +@import "./structures/_ToastContainer.scss"; @import "./structures/_TopLeftMenuButton.scss"; @import "./structures/_UploadBar.scss"; @import "./structures/_ViewSource.scss"; diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss new file mode 100644 index 0000000000..54132d19bf --- /dev/null +++ b/res/css/structures/_ToastContainer.scss @@ -0,0 +1,105 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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_ToastContainer { + position: absolute; + top: 0; + left: 70px; + z-index: 101; + padding: 4px; + display: grid; + grid-template-rows: 1fr 14px 6px; + + &.mx_ToastContainer_stacked::before { + content: ""; + margin: 0 4px; + grid-row: 2 / 4; + grid-column: 1; + background-color: white; + box-shadow: 0px 4px 12px $menu-box-shadow-color; + border-radius: 8px; + } + + .mx_Toast_toast { + grid-row: 1 / 3; + grid-column: 1; + color: $primary-fg-color; + background-color: $primary-bg-color; + box-shadow: 0px 4px 12px $menu-box-shadow-color; + border-radius: 8px; + overflow: hidden; + } + + .mx_Toast_toast { + display: grid; + grid-template-columns: 20px 1fr; + column-gap: 10px; + row-gap: 4px; + padding: 8px; + padding-right: 16px; + + &.mx_Toast_hasIcon { + &::after { + content: ""; + width: 20px; + height: 20px; + grid-column: 1; + grid-row: 1; + mask-size: 100%; + mask-repeat: no-repeat; + } + + &.mx_Toast_icon_verification::after { + mask-image: url("$(res)/img/e2e/normal.svg"); + background-color: $primary-fg-color; + } + + h2, .mx_Toast_body { + grid-column: 2; + } + } + + h2 { + grid-column: 1 / 3; + grid-row: 1; + margin: 0; + font-size: 15px; + font-weight: 600; + } + + .mx_Toast_body { + grid-column: 1 / 3; + grid-row: 2; + } + + .mx_Toast_buttons { + display: flex; + + > :not(:last-child) { + margin-right: 8px; + } + } + + .mx_Toast_description { + max-width: 400px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + margin: 4px 0 11px 0; + font-size: 12px; + } + } +} diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 889b0cdc8b..d071ba1d79 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -525,6 +525,7 @@ const LoggedInView = createReactClass({ const EmbeddedPage = sdk.getComponent('structures.EmbeddedPage'); const GroupView = sdk.getComponent('structures.GroupView'); const MyGroups = sdk.getComponent('structures.MyGroups'); + const ToastContainer = sdk.getComponent('structures.ToastContainer'); const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar'); const CookieBar = sdk.getComponent('globals.CookieBar'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); @@ -628,6 +629,7 @@ const LoggedInView = createReactClass({ return (
{ topBar } +
{ + if (payload.action === "show_toast") { + this._addToast(payload.toast); + } + }; + + _addToast(toast) { + this.setState({toasts: this.state.toasts.concat(toast)}); + } + + dismissTopToast = () => { + const [, ...remaining] = this.state.toasts; + this.setState({toasts: remaining}); + }; + + render() { + const totalCount = this.state.toasts.length; + if (totalCount === 0) { + return null; + } + const isStacked = totalCount > 1; + const topToast = this.state.toasts[0]; + const {title, icon, key, component, props} = topToast; + + const containerClasses = classNames("mx_ToastContainer", { + "mx_ToastContainer_stacked": isStacked, + }); + + const toastClasses = classNames("mx_Toast_toast", { + "mx_Toast_hasIcon": icon, + [`mx_Toast_icon_${icon}`]: icon, + }); + + const countIndicator = isStacked ? _t(" (1/%(totalCount)s)", {totalCount}) : null; + + const toastProps = Object.assign({}, props, { + dismiss: this.dismissTopToast, + key, + }); + + return ( +
+
+

{title}{countIndicator}

+
{React.createElement(component, toastProps)}
+
+
+ ); + } +} From 66cc68bae4dcee465946089df4a5d973a8e02497 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 20 Nov 2019 16:18:59 +0100 Subject: [PATCH 34/88] add new-styled button might merge it later on with accessible button --- res/css/_components.scss | 1 + res/css/views/elements/_FormButton.scss | 31 +++++++++++++++++++++ src/components/views/elements/FormButton.js | 27 ++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 res/css/views/elements/_FormButton.scss create mode 100644 src/components/views/elements/FormButton.js diff --git a/res/css/_components.scss b/res/css/_components.scss index f7147b3b9f..8d2b1cc91a 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -91,6 +91,7 @@ @import "./views/elements/_ErrorBoundary.scss"; @import "./views/elements/_EventListSummary.scss"; @import "./views/elements/_Field.scss"; +@import "./views/elements/_FormButton.scss"; @import "./views/elements/_IconButton.scss"; @import "./views/elements/_ImageView.scss"; @import "./views/elements/_InlineSpinner.scss"; diff --git a/res/css/views/elements/_FormButton.scss b/res/css/views/elements/_FormButton.scss new file mode 100644 index 0000000000..191dee5566 --- /dev/null +++ b/res/css/views/elements/_FormButton.scss @@ -0,0 +1,31 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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_FormButton { + line-height: 16px; + padding: 5px 15px; + font-size: 12px; + + &.mx_AccessibleButton_kind_primary { + color: $accent-color; + background-color: $accent-bg-color; + } + + &.mx_AccessibleButton_kind_danger { + color: $notice-primary-color; + background-color: $notice-primary-bg-color; + } +} diff --git a/src/components/views/elements/FormButton.js b/src/components/views/elements/FormButton.js new file mode 100644 index 0000000000..d667132c38 --- /dev/null +++ b/src/components/views/elements/FormButton.js @@ -0,0 +1,27 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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. +*/ + +import React from 'react'; +import AccessibleButton from "./AccessibleButton"; + +export default function FormButton(props) { + const {className, label, kind, ...restProps} = props; + const newClassName = (className || "") + " mx_FormButton"; + const allProps = Object.assign({}, restProps, {className: newClassName, kind: kind || "primary", children: [label]}); + return React.createElement(AccessibleButton, allProps); +} + +FormButton.propTypes = AccessibleButton.propTypes; From f1c62e7dab0ef27bb3a5fd9fa8a63833a8779148 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 20 Nov 2019 16:19:51 +0100 Subject: [PATCH 35/88] make colors slightly more opaque than in design as it is very light otherwise --- res/themes/light/css/_light.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index dcd7ce166e..0a3ef812b8 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -12,9 +12,9 @@ $monospace-font-family: Inconsolata, Twemoji, 'Apple Color Emoji', 'Segoe UI Emo // unified palette // try to use these colors when possible $accent-color: #03b381; -$accent-bg-color: rgba(115, 247, 91, 0.08); +$accent-bg-color: rgba(3, 179, 129, 0.16); $notice-primary-color: #ff4b55; -$notice-primary-bg-color: rgba(255, 75, 85, 0.08); +$notice-primary-bg-color: rgba(255, 75, 85, 0.16); $notice-secondary-color: #61708b; $header-panel-bg-color: #f3f8fd; From c705752317769c7bcd0ed00cef8beca7c15d82a9 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Nov 2019 16:00:39 +0100 Subject: [PATCH 36/88] add toast for verification requests this uses a verification requests as emitted by the js-sdk with the `crypto.verification.request` rather than a verifier as emitted by `crypto.verification.start` as this works for both to_device and timeline events with the changes made in the js-sdk pr. --- .../views/toasts/VerificationRequestToast.js | 123 ++++++++++++++++++ src/i18n/strings/en_EN.json | 3 + src/utils/KeyVerificationStateObserver.js | 14 +- 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/components/views/toasts/VerificationRequestToast.js diff --git a/src/components/views/toasts/VerificationRequestToast.js b/src/components/views/toasts/VerificationRequestToast.js new file mode 100644 index 0000000000..c6f7f3a363 --- /dev/null +++ b/src/components/views/toasts/VerificationRequestToast.js @@ -0,0 +1,123 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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. +*/ + +import React from 'react'; +import PropTypes from 'prop-types'; +import sdk from "../../../index"; +import { _t } from '../../../languageHandler'; +import Modal from "../../../Modal"; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import {verificationMethods} from 'matrix-js-sdk/lib/crypto'; +import KeyVerificationStateObserver, {userLabelForEventRoom} from "../../../utils/KeyVerificationStateObserver"; +import dis from "../../../dispatcher"; + +export default class VerificationRequestToast extends React.PureComponent { + constructor(props) { + super(props); + const {event, timeout} = props.request; + // to_device requests don't have a timestamp, so consider them age=0 + const age = event.getTs() ? event.getLocalAge() : 0; + const remaining = Math.max(0, timeout - age); + const counter = Math.ceil(remaining / 1000); + this.state = {counter}; + if (this.props.requestObserver) { + this.props.requestObserver.setCallback(this._checkRequestIsPending); + } + } + + componentDidMount() { + if (this.props.requestObserver) { + this.props.requestObserver.attach(); + this._checkRequestIsPending(); + } + this._intervalHandle = setInterval(() => { + let {counter} = this.state; + counter -= 1; + if (counter <= 0) { + this.cancel(); + } else { + this.setState({counter}); + } + }, 1000); + } + + componentWillUnmount() { + clearInterval(this._intervalHandle); + if (this.props.requestObserver) { + this.props.requestObserver.detach(); + } + } + + _checkRequestIsPending = () => { + if (!this.props.requestObserver.pending) { + this.props.dismiss(); + } + } + + cancel = () => { + this.props.dismiss(); + try { + this.props.request.cancel(); + } catch (err) { + console.error("Error while cancelling verification request", err); + } + } + + accept = () => { + this.props.dismiss(); + const {event} = this.props.request; + // no room id for to_device requests + if (event.getRoomId()) { + dis.dispatch({ + action: 'view_room', + room_id: event.getRoomId(), + should_peek: false, + }); + } + + const verifier = this.props.request.beginKeyVerification(verificationMethods.SAS); + const IncomingSasDialog = sdk.getComponent('views.dialogs.IncomingSasDialog'); + Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, {verifier}); + }; + + render() { + const FormButton = sdk.getComponent("elements.FormButton"); + const {event} = this.props.request; + const userId = event.getSender(); + let nameLabel = event.getRoomId() ? userLabelForEventRoom(userId, event) : userId; + // for legacy to_device verification requests + if (nameLabel === userId) { + const client = MatrixClientPeg.get(); + const user = client.getUser(event.getSender()); + if (user && user.displayName) { + nameLabel = _t("%(name)s (%(userId)s)", {name: user.displayName, userId}); + } + } + return (
+
{nameLabel}
+
+ + +
+
); + } +} + +VerificationRequestToast.propTypes = { + dismiss: PropTypes.func.isRequired, + request: PropTypes.object.isRequired, + requestObserver: PropTypes.instanceOf(KeyVerificationStateObserver), +}; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7709a4a398..177d999148 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -481,6 +481,7 @@ "Headphones": "Headphones", "Folder": "Folder", "Pin": "Pin", + "Decline (%(counter)s)": "Decline (%(counter)s)", "Accept to continue:": "Accept to continue:", "Failed to upload profile picture!": "Failed to upload profile picture!", "Upload new:": "Upload new:", @@ -1694,6 +1695,7 @@ "Review terms and conditions": "Review terms and conditions", "Old cryptography data detected": "Old cryptography data detected", "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.", + "Verification Request": "Verification Request", "Logout": "Logout", "%(creator)s created and configured the room.": "%(creator)s created and configured the room.", "Your Communities": "Your Communities", @@ -1759,6 +1761,7 @@ "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", "Failed to load timeline position": "Failed to load timeline position", + " (1/%(totalCount)s)": " (1/%(totalCount)s)", "Guest": "Guest", "Your profile": "Your profile", "Uploading %(filename)s and %(count)s others|other": "Uploading %(filename)s and %(count)s others", diff --git a/src/utils/KeyVerificationStateObserver.js b/src/utils/KeyVerificationStateObserver.js index 7de50ec4bf..2f7c0367ad 100644 --- a/src/utils/KeyVerificationStateObserver.js +++ b/src/utils/KeyVerificationStateObserver.js @@ -30,6 +30,18 @@ export default class KeyVerificationStateObserver { this._updateVerificationState(); } + get concluded() { + return this.accepted || this.done || this.cancelled; + } + + get pending() { + return !this.concluded; + } + + setCallback(callback) { + this._updateCallback = callback; + } + attach() { this._requestEvent.on("Event.relationsCreated", this._onRelationsCreated); for (const phaseName of SUB_EVENT_TYPES_OF_INTEREST) { @@ -83,7 +95,7 @@ export default class KeyVerificationStateObserver { _onRelationsUpdated = (event) => { this._updateVerificationState(); - this._updateCallback(); + this._updateCallback && this._updateCallback(); }; _updateVerificationState() { From 8cb362002bf00062b8a106cdc2a2cd14b001f93b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Nov 2019 16:02:11 +0100 Subject: [PATCH 37/88] show a toast instead of dialog when feature flag is enabled --- src/components/structures/MatrixChat.js | 35 ++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 661a0c7077..9d0dd7da8f 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -62,6 +62,7 @@ import { countRoomsWithNotif } from '../../RoomNotifs'; import { ThemeWatcher } from "../../theme"; import { storeRoomAliasInCache } from '../../RoomAliasCache'; import { defer } from "../../utils/promise"; +import KeyVerificationStateObserver from '../../utils/KeyVerificationStateObserver'; // Disable warnings for now: we use deprecated bluebird functions // and need to migrate, but they spam the console with warnings. @@ -1270,7 +1271,6 @@ export default createReactClass({ this.firstSyncComplete = false; this.firstSyncPromise = defer(); const cli = MatrixClientPeg.get(); - const IncomingSasDialog = sdk.getComponent('views.dialogs.IncomingSasDialog'); // Allow the JS SDK to reap timeline events. This reduces the amount of // memory consumed as the JS SDK stores multiple distinct copies of room @@ -1469,12 +1469,35 @@ export default createReactClass({ } }); - cli.on("crypto.verification.start", (verifier) => { - Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, { - verifier, - }); - }); + if (SettingsStore.isFeatureEnabled("feature_dm_verification")) { + cli.on("crypto.verification.request", request => { + let requestObserver; + if (request.event.getRoomId()) { + requestObserver = new KeyVerificationStateObserver( + request.event, MatrixClientPeg.get()); + } + if (!requestObserver || requestObserver.pending) { + dis.dispatch({ + action: "show_toast", + toast: { + key: request.event.getId(), + title: _t("Verification Request"), + icon: "verification", + props: {request, requestObserver}, + component: sdk.getComponent("toasts.VerificationRequestToast"), + }, + }); + } + }); + } else { + cli.on("crypto.verification.start", (verifier) => { + const IncomingSasDialog = sdk.getComponent("views.dialogs.IncomingSasDialog"); + Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, { + verifier, + }); + }); + } // Fire the tinter right on startup to ensure the default theme is applied // A later sync can/will correct the tint to be the right value for the user const colorScheme = SettingsStore.getValue("roomColor"); From 0dfb0f54688e2bff8427dd38d7ce108666fc871a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Nov 2019 16:25:30 +0100 Subject: [PATCH 38/88] fix lint --- src/components/views/elements/FormButton.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/FormButton.js b/src/components/views/elements/FormButton.js index d667132c38..f6b4c986f5 100644 --- a/src/components/views/elements/FormButton.js +++ b/src/components/views/elements/FormButton.js @@ -20,7 +20,8 @@ import AccessibleButton from "./AccessibleButton"; export default function FormButton(props) { const {className, label, kind, ...restProps} = props; const newClassName = (className || "") + " mx_FormButton"; - const allProps = Object.assign({}, restProps, {className: newClassName, kind: kind || "primary", children: [label]}); + const allProps = Object.assign({}, restProps, + {className: newClassName, kind: kind || "primary", children: [label]}); return React.createElement(AccessibleButton, allProps); } From 309633181d60b0732966e7c8fe4acd4255341af4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Nov 2019 16:32:50 +0100 Subject: [PATCH 39/88] use FormButton in verification request tile too and dedupe styles --- res/css/structures/_ToastContainer.scss | 4 ---- res/css/views/elements/_FormButton.scss | 5 +++++ .../messages/_MKeyVerificationRequest.scss | 17 ----------------- .../views/messages/MKeyVerificationRequest.js | 6 +++--- 4 files changed, 8 insertions(+), 24 deletions(-) diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss index 54132d19bf..ca8477dcc5 100644 --- a/res/css/structures/_ToastContainer.scss +++ b/res/css/structures/_ToastContainer.scss @@ -87,10 +87,6 @@ limitations under the License. .mx_Toast_buttons { display: flex; - - > :not(:last-child) { - margin-right: 8px; - } } .mx_Toast_description { diff --git a/res/css/views/elements/_FormButton.scss b/res/css/views/elements/_FormButton.scss index 191dee5566..1483fe2091 100644 --- a/res/css/views/elements/_FormButton.scss +++ b/res/css/views/elements/_FormButton.scss @@ -18,6 +18,11 @@ limitations under the License. line-height: 16px; padding: 5px 15px; font-size: 12px; + height: min-content; + + &:not(:last-child) { + margin-right: 8px; + } &.mx_AccessibleButton_kind_primary { color: $accent-color; diff --git a/res/css/views/messages/_MKeyVerificationRequest.scss b/res/css/views/messages/_MKeyVerificationRequest.scss index 87a75dee82..ee20751083 100644 --- a/res/css/views/messages/_MKeyVerificationRequest.scss +++ b/res/css/views/messages/_MKeyVerificationRequest.scss @@ -65,23 +65,6 @@ limitations under the License. .mx_KeyVerification_buttons { align-items: center; display: flex; - - .mx_AccessibleButton_kind_decline { - color: $notice-primary-color; - background-color: $notice-primary-bg-color; - } - - .mx_AccessibleButton_kind_accept { - color: $accent-color; - background-color: $accent-bg-color; - } - - [role=button] { - margin: 10px; - padding: 7px 15px; - border-radius: 5px; - height: min-content; - } } .mx_KeyVerification_state { diff --git a/src/components/views/messages/MKeyVerificationRequest.js b/src/components/views/messages/MKeyVerificationRequest.js index 21d82309ed..b2a1724fc6 100644 --- a/src/components/views/messages/MKeyVerificationRequest.js +++ b/src/components/views/messages/MKeyVerificationRequest.js @@ -111,10 +111,10 @@ export default class MKeyVerificationRequest extends React.Component { userLabelForEventRoom(fromUserId, mxEvent)}
); const isResolved = !(this.state.accepted || this.state.cancelled || this.state.done); if (isResolved) { - const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); + const FormButton = sdk.getComponent("elements.FormButton"); stateNode = (
- {_t("Decline")} - {_t("Accept")} + +
); } } else if (isOwn) { // request sent by us From 8ce1ed472654297091d8fc4b76c89ffe772572e7 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Nov 2019 16:36:22 +0100 Subject: [PATCH 40/88] moar lint --- res/css/structures/_ToastContainer.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss index ca8477dcc5..4c5e746e66 100644 --- a/res/css/structures/_ToastContainer.scss +++ b/res/css/structures/_ToastContainer.scss @@ -41,9 +41,6 @@ limitations under the License. box-shadow: 0px 4px 12px $menu-box-shadow-color; border-radius: 8px; overflow: hidden; - } - - .mx_Toast_toast { display: grid; grid-template-columns: 20px 1fr; column-gap: 10px; From 32b6fccbfcfe9f8197354e69634d48d2da557ce5 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Nov 2019 17:26:14 +0100 Subject: [PATCH 41/88] fix double date separator --- src/components/structures/MessagePanel.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 7eae3ff7a3..912b865b9f 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -416,7 +416,8 @@ export default class MessagePanel extends React.Component { // If this m.room.create event should be shown (room upgrade) then show it before the summary if (this._shouldShowEvent(mxEv)) { - ret.push(...this._getTilesForEvent(prevEvent, mxEv, false)); + // pass in the mxEv as prevEvent as well so no extra DateSeparator is rendered + ret.push(...this._getTilesForEvent(mxEv, mxEv, false)); } const summarisedEvents = []; // Don't add m.room.create here as we don't want it inside the summary From f1d096e7aa860bb673513f3d6fead7880343574c Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Fri, 22 Nov 2019 15:16:53 +0000 Subject: [PATCH 42/88] Translated using Weblate (Bulgarian) Currently translated at 95.9% (1840 of 1918 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/bg/ --- src/i18n/strings/bg.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 3697cc635c..0ec1d91b9b 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -2260,5 +2260,7 @@ "You cancelled": "Отказахте потвърждаването", "%(name)s cancelled": "%(name)s отказа", "%(name)s wants to verify": "%(name)s иска да извърши потвърждение", - "You sent a verification request": "Изпратихте заявка за потвърждение" + "You sent a verification request": "Изпратихте заявка за потвърждение", + "Custom (%(level)s)": "Собствен (%(level)s)", + "Try out new ways to ignore people (experimental)": "Опитайте нови начини да игнорирате хора (експериментално)" } From 9bb98e2b9c64bf7127ffcd7143cc387a8d1ae965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanislav=20Luke=C5=A1?= Date: Fri, 22 Nov 2019 13:42:28 +0000 Subject: [PATCH 43/88] Translated using Weblate (Czech) Currently translated at 95.8% (1837 of 1918 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index e4e01b0116..62e6147506 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -1269,7 +1269,7 @@ "Security & Privacy": "Bezpečnost & Soukromí", "Encryption": "Šifrování", "Once enabled, encryption cannot be disabled.": "Když se šifrování zapne, už nepůjde vypnout.", - "Encrypted": "Šifrování je zapnuté", + "Encrypted": "Šifrování", "General": "Obecné", "General failure": "Nějaká chyba", "This homeserver does not support login using email address.": "Tento homeserver neumožňuje přihlášní pomocí emailu.", From fab7dfd8e81f709d05e012284200d59a5c1369e5 Mon Sep 17 00:00:00 2001 From: random Date: Fri, 22 Nov 2019 14:01:15 +0000 Subject: [PATCH 44/88] Translated using Weblate (Italian) Currently translated at 99.9% (1916 of 1918 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 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index 9faa48328c..eb5f5f76f2 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2298,5 +2298,22 @@ "This widget may use cookies.": "Questo widget può usare cookie.", "Send verification requests in direct message, including a new verification UX in the member panel.": "Invia le richieste di verifica via messaggio diretto, inclusa una nuova esperienza utente per la verifica nel pannello membri.", "Enable local event indexing and E2EE search (requires restart)": "Attiva l'indicizzazione di eventi locali e la ricerca E2EE (richiede riavvio)", - "Match system dark mode setting": "Combacia la modalità scura di sistema" + "Match system dark mode setting": "Combacia la modalità scura di sistema", + "Connecting to integration manager...": "Connessione al gestore di integrazioni...", + "Cannot connect to integration manager": "Impossibile connettere al gestore di integrazioni", + "The integration manager is offline or it cannot reach your homeserver.": "Il gestore di integrazioni è offline o non riesce a raggiungere il tuo homeserver.", + "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Usa un gestore di integrazioni (%(serverName)s) per gestire bot, widget e pacchetti di adesivi.", + "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Usa un gestore di integrazioni per gestire bot, widget e pacchetti di adesivi.", + "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "I gestori di integrazione ricevono dati di configurazione e possono modificare widget, inviare inviti alla stanza, assegnare permessi a tuo nome.", + "Failed to connect to integration manager": "Connessione al gestore di integrazioni fallita", + "Widgets do not use message encryption.": "I widget non usano la cifratura dei messaggi.", + "More options": "Altre opzioni", + "Integrations are disabled": "Le integrazioni sono disattivate", + "Enable 'Manage Integrations' in Settings to do this.": "Attiva 'Gestisci integrazioni' nelle impostazioni per continuare.", + "Integrations not allowed": "Integrazioni non permesse", + "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Il tuo Riot non ti permette di usare il gestore di integrazioni per questa azione. Contatta un amministratore.", + "Reload": "Ricarica", + "Take picture": "Scatta foto", + "Remove for everyone": "Rimuovi per tutti", + "Remove for me": "Rimuovi per me" } From 2b7a7f88b8dd2dba96b58e18d81c53939707b781 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Nov 2019 17:26:14 +0100 Subject: [PATCH 45/88] fix double date separator --- src/components/structures/MessagePanel.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 39504666bf..aad01a2bff 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -413,7 +413,8 @@ module.exports = createReactClass({ // If this m.room.create event should be shown (room upgrade) then show it before the summary if (this._shouldShowEvent(mxEv)) { - ret.push(...this._getTilesForEvent(prevEvent, mxEv, false)); + // pass in the mxEv as prevEvent as well so no extra DateSeparator is rendered + ret.push(...this._getTilesForEvent(mxEv, mxEv, false)); } const summarisedEvents = []; // Don't add m.room.create here as we don't want it inside the summary From aae315038309df0533986e3f7a186c236a6a7998 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 22 Nov 2019 16:50:32 +0000 Subject: [PATCH 46/88] Null check on thumbnail_file --- src/components/views/messages/MVideoBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index 43e4f2dd75..44954344ff 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -88,7 +88,7 @@ module.exports = createReactClass({ const content = this.props.mxEvent.getContent(); if (content.file !== undefined && this.state.decryptedUrl === null) { let thumbnailPromise = Promise.resolve(null); - if (content.info.thumbnail_file) { + if (content.info && content.info.thumbnail_file) { thumbnailPromise = decryptFile( content.info.thumbnail_file, ).then(function(blob) { From f23e5942e6e80465a8031aacd15878fc0360563d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 22 Nov 2019 17:18:26 +0000 Subject: [PATCH 47/88] Prepare changelog for v1.7.3-rc.2 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dad0accd2..a3f72685db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +Changes in [1.7.3-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.3-rc.2) (2019-11-22) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.3-rc.1...v1.7.3-rc.2) + + * Fix double date separator for room upgrade tiles + [\#3663](https://github.com/matrix-org/matrix-react-sdk/pull/3663) + * Show m.room.create event before the ELS on room upgrade + [\#3660](https://github.com/matrix-org/matrix-react-sdk/pull/3660) + * Make addEventListener conditional + [\#3659](https://github.com/matrix-org/matrix-react-sdk/pull/3659) + * Fix e2e icons + [\#3658](https://github.com/matrix-org/matrix-react-sdk/pull/3658) + Changes in [1.7.3-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.3-rc.1) (2019-11-20) ============================================================================================================= [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.2...v1.7.3-rc.1) From 730967fd3f381ed26db5f09a3cbaf9824fe14191 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 22 Nov 2019 17:18:27 +0000 Subject: [PATCH 48/88] v1.7.3-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5d2d7635c..099fc30b33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.3-rc.1", + "version": "1.7.3-rc.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 8254261f261006740cc53ff6ea0602f14aac4562 Mon Sep 17 00:00:00 2001 From: Keunes Date: Fri, 22 Nov 2019 18:48:44 +0000 Subject: [PATCH 49/88] Translated using Weblate (Dutch) Currently translated at 93.4% (1794 of 1921 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 825f3c6a48..7ec8197eaf 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -1193,7 +1193,7 @@ "Encrypted, not sent": "Versleuteld, niet verstuurd", "Demote yourself?": "Uzelf degraderen?", "Demote": "Degraderen", - "Share Link to User": "Koppeling met gebruiker delen", + "Share Link to User": "Link naar gebruiker delen", "deleted": "verwijderd", "underlined": "onderstreept", "inline-code": "code", From d867f41f569e01db0fbeba732ff97ba354fc3f64 Mon Sep 17 00:00:00 2001 From: Nathan Follens Date: Fri, 22 Nov 2019 18:48:50 +0000 Subject: [PATCH 50/88] Translated using Weblate (Dutch) Currently translated at 93.4% (1794 of 1921 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index 7ec8197eaf..347afc3583 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -1193,7 +1193,7 @@ "Encrypted, not sent": "Versleuteld, niet verstuurd", "Demote yourself?": "Uzelf degraderen?", "Demote": "Degraderen", - "Share Link to User": "Link naar gebruiker delen", + "Share Link to User": "Koppeling naar gebruiker delen", "deleted": "verwijderd", "underlined": "onderstreept", "inline-code": "code", From 95e02899b45735da73f299043e341f08287fc30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Sat, 23 Nov 2019 10:08:24 +0000 Subject: [PATCH 51/88] Translated using Weblate (French) Currently translated at 100.0% (1921 of 1921 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 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 0c13b3c722..097dd0824f 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2370,5 +2370,9 @@ "Reload": "Recharger", "Take picture": "Prendre une photo", "Remove for everyone": "Supprimer pour tout le monde", - "Remove for me": "Supprimer pour moi" + "Remove for me": "Supprimer pour moi", + "Decline (%(counter)s)": "Refuser (%(counter)s)", + "Manage integrations": "Gérer les intégrations", + "Verification Request": "Demande de vérification", + " (1/%(totalCount)s)": " (1/%(totalCount)s)" } From 1c02fa573f315ba5dbb479b440c7506f606d7b92 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 22 Nov 2019 18:52:54 +0000 Subject: [PATCH 52/88] Translated using Weblate (Hungarian) Currently translated at 100.0% (1921 of 1921 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 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 7ed4eb253c..9e41b7381e 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2358,5 +2358,9 @@ "Integrations are disabled": "Az integrációk le vannak tiltva", "Enable 'Manage Integrations' in Settings to do this.": "Ehhez engedélyezd az „Integrációk Kezelésé”-t a Beállításokban.", "Integrations not allowed": "Az integrációk nem engedélyezettek", - "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "A Riotod nem használhat ehhez Integrációs Menedzsert. Kérlek vedd fel a kapcsolatot az adminisztrátorral." + "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "A Riotod nem használhat ehhez Integrációs Menedzsert. Kérlek vedd fel a kapcsolatot az adminisztrátorral.", + "Decline (%(counter)s)": "Elutasítás (%(counter)s)", + "Manage integrations": "Integrációk kezelése", + "Verification Request": "Ellenőrzési kérés", + " (1/%(totalCount)s)": " (1/%(totalCount)s)" } From 00fd329bfeeb3dab87e2ccbc2d08a64ebed35c85 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sat, 23 Nov 2019 18:56:46 +0000 Subject: [PATCH 53/88] Translated using Weblate (Italian) Currently translated at 100.0% (1921 of 1921 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 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index eb5f5f76f2..21c03a7802 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2315,5 +2315,11 @@ "Reload": "Ricarica", "Take picture": "Scatta foto", "Remove for everyone": "Rimuovi per tutti", - "Remove for me": "Rimuovi per me" + "Remove for me": "Rimuovi per me", + "Trust": "Fidati", + "Decline (%(counter)s)": "Rifiuta (%(counter)s)", + "Manage integrations": "Gestisci integrazioni", + "Ignored/Blocked": "Ignorati/Bloccati", + "Verification Request": "Richiesta verifica", + " (1/%(totalCount)s)": " (1/%(totalCount)s)" } From 1607bc329bc819866e22f1d68814f897d3d7a336 Mon Sep 17 00:00:00 2001 From: dreboy30 Date: Sat, 23 Nov 2019 15:16:23 +0000 Subject: [PATCH 54/88] Translated using Weblate (Portuguese) Currently translated at 34.5% (663 of 1921 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt/ --- src/i18n/strings/pt.json | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index 5a56e807e4..7aa8851daa 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -350,7 +350,7 @@ "No devices with registered encryption keys": "Não há dispositivos com chaves de criptografia registradas", "No more results": "Não há mais resultados", "No results": "Sem resultados", - "OK": "Ok", + "OK": "OK", "Revoke Moderator": "Retirar status de moderador", "Search": "Pesquisar", "Search failed": "Busca falhou", @@ -847,6 +847,29 @@ "Add Phone Number": "Adicione número de telefone", "The platform you're on": "A plataforma em que se encontra", "The version of Riot.im": "A versão do RIOT.im", - "Whether or not you're logged in (we don't record your username)": "Tenha ou não, iniciado sessão (não iremos guardar o seu username)", - "Your language of choice": "O seu idioma de escolha" + "Whether or not you're logged in (we don't record your username)": "Tenha ou não, iniciado sessão (não iremos guardar o seu nome de utilizador)", + "Your language of choice": "O seu idioma que escolheu", + "Which officially provided instance you are using, if any": "Qual instância oficial está utilizando, se for o caso", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Se está a usar o modo de texto enriquecido do editor de texto enriquecido", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Se usa a funcionalidade 'breadcrumbs' (avatares em cima da lista de salas", + "Your homeserver's URL": "O URL do seu servidor de início", + "Your identity server's URL": "O URL do seu servidor de identidade", + "e.g. %(exampleValue)s": "ex. %(exampleValue)s", + "Every page you use in the app": "Todas as páginas que usa na aplicação", + "e.g. ": "ex. ", + "Your User Agent": "O seu Agente de Utilizador", + "Your device resolution": "A resolução do seu dispositivo", + "The information being sent to us to help make Riot.im better includes:": "As informações que estão sendo enviadas para ajudar a melhorar o Riot.im incluem:", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Quando esta página contém informação de que permitam a sua identificação, como uma sala, ID de utilizador ou de grupo, estes dados são removidos antes de serem enviados ao servidor.", + "Call Failed": "A chamada falhou", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Há dispositivos desconhecidos nesta sala: se continuar sem os verificar, será possível que alguém espie a sua chamada.", + "Review Devices": "Rever dispositivos", + "Call Anyway": "Ligar na mesma", + "Answer Anyway": "Responder na mesma", + "Call": "Ligar", + "Answer": "Responder", + "Call failed due to misconfigured server": "Chamada falhada devido a um erro de configuração do servidor", + "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Peça ao administrador do seu servidor inicial (%(homeserverDomain)s) de configurar um servidor TURN para que as chamadas funcionem fiavelmente.", + "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Alternativamente, pode tentar usar o servidor público em turn.matrix.org, mas não será tão fiável e partilhará o seu IP com esse servidor. Também pode gerir isso nas definições.", + "Try using turn.matrix.org": "Tente utilizar turn.matrix.org" } From 4fb6e4b9833e4cbb69dd773515ff41d17eb13f89 Mon Sep 17 00:00:00 2001 From: dreboy30 Date: Sat, 23 Nov 2019 15:31:58 +0000 Subject: [PATCH 55/88] Translated using Weblate (Portuguese (Brazil)) Currently translated at 68.8% (1321 of 1921 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pt_BR/ --- src/i18n/strings/pt_BR.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index 072215663d..415d2fdd4b 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -652,7 +652,7 @@ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Se você está usando o editor de texto visual", "Your homeserver's URL": "A URL do seu Servidor de Base (homeserver)", "Your identity server's URL": "A URL do seu servidor de identidade", - "The information being sent to us to help make Riot.im better includes:": "As informações que estão sendo usadas para ajudar a melhorar o Riot.im incluem:", + "The information being sent to us to help make Riot.im better includes:": "As informações que estão sendo enviadas para ajudar a melhorar o Riot.im incluem:", "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Quando esta página tem informação de identificação, como uma sala, ID de usuária/o ou de grupo, estes dados são removidos antes de serem enviados ao servidor.", "Call Failed": "A chamada falhou", "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Há dispositivos desconhecidos nesta sala: se você continuar sem verificá-los, será possível alguém espiar sua chamada.", From 11fec80370fa7cd8e081acbd19e631a88cfff131 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 24 Nov 2019 20:52:22 -0700 Subject: [PATCH 56/88] Hide tooltips with CSS when they aren't visible Fixes https://github.com/vector-im/riot-web/issues/11456 --- src/components/views/elements/Tooltip.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/Tooltip.js b/src/components/views/elements/Tooltip.js index bb5f9f0604..8ff3ce9bdb 100644 --- a/src/components/views/elements/Tooltip.js +++ b/src/components/views/elements/Tooltip.js @@ -100,7 +100,9 @@ module.exports = createReactClass({ const parent = ReactDOM.findDOMNode(this).parentNode; let style = {}; style = this._updatePosition(style); - style.display = "block"; + // Hide the entire container when not visible. This prevents flashing of the tooltip + // if it is not meant to be visible on first mount. + style.display = this.props.visible ? "block" : "none"; const tooltipClasses = classNames("mx_Tooltip", this.props.tooltipClassName, { "mx_Tooltip_visible": this.props.visible, From 56a7de5157dd70d281b80cdf59523844971bb7c8 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 25 Nov 2019 08:31:58 +0000 Subject: [PATCH 57/88] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1921 of 1921 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 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 2fd014554e..a5f8e5e04b 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2363,5 +2363,9 @@ "Reload": "重新載入", "Take picture": "拍照", "Remove for everyone": "對所有人移除", - "Remove for me": "對我移除" + "Remove for me": "對我移除", + "Decline (%(counter)s)": "拒絕 (%(counter)s)", + "Manage integrations": "管理整合", + "Verification Request": "驗證請求", + " (1/%(totalCount)s)": " (1/%(totalCount)s)" } From 422ab81185433c3d61cd261760dfcaee192b72e2 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 25 Nov 2019 12:31:57 +0100 Subject: [PATCH 58/88] a11y adjustments for toasts --- src/components/structures/ToastContainer.js | 2 +- src/components/views/toasts/VerificationRequestToast.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.js index b8ced1e9de..83bbdac1a1 100644 --- a/src/components/structures/ToastContainer.js +++ b/src/components/structures/ToastContainer.js @@ -74,7 +74,7 @@ export default class ToastContainer extends React.Component { }); return ( -
+

{title}{countIndicator}

{React.createElement(component, toastProps)}
diff --git a/src/components/views/toasts/VerificationRequestToast.js b/src/components/views/toasts/VerificationRequestToast.js index c6f7f3a363..89af91c41f 100644 --- a/src/components/views/toasts/VerificationRequestToast.js +++ b/src/components/views/toasts/VerificationRequestToast.js @@ -108,7 +108,7 @@ export default class VerificationRequestToast extends React.PureComponent { } return (
{nameLabel}
-
+
From 694f2cb1dc676c06fd2961e566eeaf144c5cf603 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 25 Nov 2019 13:20:20 +0100 Subject: [PATCH 59/88] make sure the toast container is always in the document --- src/components/structures/ToastContainer.js | 43 ++++++++++----------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/components/structures/ToastContainer.js b/src/components/structures/ToastContainer.js index 83bbdac1a1..a8dca35747 100644 --- a/src/components/structures/ToastContainer.js +++ b/src/components/structures/ToastContainer.js @@ -50,35 +50,34 @@ export default class ToastContainer extends React.Component { render() { const totalCount = this.state.toasts.length; - if (totalCount === 0) { - return null; - } const isStacked = totalCount > 1; - const topToast = this.state.toasts[0]; - const {title, icon, key, component, props} = topToast; + let toast; + if (totalCount !== 0) { + const topToast = this.state.toasts[0]; + const {title, icon, key, component, props} = topToast; + const toastClasses = classNames("mx_Toast_toast", { + "mx_Toast_hasIcon": icon, + [`mx_Toast_icon_${icon}`]: icon, + }); + const countIndicator = isStacked ? _t(" (1/%(totalCount)s)", {totalCount}) : null; + + const toastProps = Object.assign({}, props, { + dismiss: this.dismissTopToast, + key, + }); + toast = (
+

{title}{countIndicator}

+
{React.createElement(component, toastProps)}
+
); + } const containerClasses = classNames("mx_ToastContainer", { "mx_ToastContainer_stacked": isStacked, }); - const toastClasses = classNames("mx_Toast_toast", { - "mx_Toast_hasIcon": icon, - [`mx_Toast_icon_${icon}`]: icon, - }); - - const countIndicator = isStacked ? _t(" (1/%(totalCount)s)", {totalCount}) : null; - - const toastProps = Object.assign({}, props, { - dismiss: this.dismissTopToast, - key, - }); - return ( -
-
-

{title}{countIndicator}

-
{React.createElement(component, toastProps)}
-
+
+ {toast}
); } From 942db34e9263c6e9b6f7236cfdb704f223a169a7 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 25 Nov 2019 13:27:15 +0000 Subject: [PATCH 60/88] released js-sdk --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 099fc30b33..a92222579c 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "2.4.4-rc.1", + "matrix-js-sdk": "2.4.4", "optimist": "^0.6.1", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index eb72b11793..44d9548b54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5197,10 +5197,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.4-rc.1: - version "2.4.4-rc.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.4-rc.1.tgz#5fd33fd11be9eea23cd0d0b8eb79da7a4b6253bf" - integrity sha512-Kn94zZMXh2EmihYL3lWNp2lpT7RtqcaUxjkP7H9Mr113swSOXtKr8RWMrvopAIguC1pcLzL+lCk+N8rrML2A4Q== +matrix-js-sdk@2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.4.tgz#d5e2d6fbe938c4275a1423a5f09330d33517ce3f" + integrity sha512-wSaRFvhWvwEzVaEkyBGo5ReumvaM5OrC1MJ6SVlyoLwH/WRPEXcUlu+rUNw5TFVEAH4TAVHXf/SVRBiR0j5nSQ== dependencies: another-json "^0.2.0" babel-runtime "^6.26.0" From 92a50c73274160cc3476dfcfba1a2fb3c0421f43 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 25 Nov 2019 13:30:40 +0000 Subject: [PATCH 61/88] Prepare changelog for v1.7.3 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3f72685db..bc2341863a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [1.7.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.3) (2019-11-25) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.3-rc.2...v1.7.3) + + * No changes since rc.2 + Changes in [1.7.3-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.3-rc.2) (2019-11-22) ============================================================================================================= [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.3-rc.1...v1.7.3-rc.2) From f62cd367450ce47329828ca44b50550c774c61c6 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 25 Nov 2019 13:30:40 +0000 Subject: [PATCH 62/88] v1.7.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a92222579c..1ecfe63c23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.3-rc.2", + "version": "1.7.3", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 54294e4927b0392d6eb6a14a9282128405955eb1 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 25 Nov 2019 14:03:40 +0000 Subject: [PATCH 63/88] Clarify that cross-signing is in development In an attempt to clarify the state of this highly anticipated feature, this updates the labs flag name to match. Part of https://github.com/vector-im/riot-web/issues/11492 --- src/i18n/strings/en_EN.json | 2 +- src/settings/Settings.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ddc7c016cc..0a83237f45 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -342,7 +342,7 @@ "Multiple integration managers": "Multiple integration managers", "Try out new ways to ignore people (experimental)": "Try out new ways to ignore people (experimental)", "Send verification requests in direct message, including a new verification UX in the member panel.": "Send verification requests in direct message, including a new verification UX in the member panel.", - "Enable cross-signing to verify per-user instead of per-device": "Enable cross-signing to verify per-user instead of per-device", + "Enable cross-signing to verify per-user instead of per-device (in development)": "Enable cross-signing to verify per-user instead of per-device (in development)", "Enable local event indexing and E2EE search (requires restart)": "Enable local event indexing and E2EE search (requires restart)", "Use the new, faster, composer for writing messages": "Use the new, faster, composer for writing messages", "Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 89693f7c50..5a3283c5f0 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -143,7 +143,7 @@ export const SETTINGS = { }, "feature_cross_signing": { isFeature: true, - displayName: _td("Enable cross-signing to verify per-user instead of per-device"), + displayName: _td("Enable cross-signing to verify per-user instead of per-device (in development)"), supportedLevels: LEVELS_FEATURE, default: false, controller: new ReloadOnChangeController(), From 21a15fdcb4ec1098df2a62ea3fabea5812c7dbd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 21 Nov 2019 10:38:21 +0100 Subject: [PATCH 64/88] EventIndex: Move the checkpoint loading logic into the init method. The checkpoints don't seem to be loaded anymore in the onSync method, the reason why this has stopped working is left unexplored since loading the checkpoints makes most sense during the initialization step anyways. --- src/indexing/EventIndex.js | 13 +++++-------- src/indexing/EventIndexPeg.js | 2 -- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/indexing/EventIndex.js b/src/indexing/EventIndex.js index 6bad992017..cf7e2d8da2 100644 --- a/src/indexing/EventIndex.js +++ b/src/indexing/EventIndex.js @@ -35,7 +35,12 @@ export default class EventIndex { async init() { const indexManager = PlatformPeg.get().getEventIndexingManager(); + await indexManager.initEventIndex(); + console.log("EventIndex: Successfully initialized the event index"); + + this.crawlerCheckpoints = await indexManager.loadCheckpoints(); + console.log("EventIndex: Loaded checkpoints", this.crawlerCheckpoints); this.registerListeners(); } @@ -62,14 +67,6 @@ export default class EventIndex { onSync = async (state, prevState, data) => { const indexManager = PlatformPeg.get().getEventIndexingManager(); - if (prevState === null && state === "PREPARED") { - // Load our stored checkpoints, if any. - this.crawlerCheckpoints = await indexManager.loadCheckpoints(); - console.log("EventIndex: Loaded checkpoints", - this.crawlerCheckpoints); - return; - } - if (prevState === "PREPARED" && state === "SYNCING") { const addInitialCheckpoints = async () => { const client = MatrixClientPeg.get(); diff --git a/src/indexing/EventIndexPeg.js b/src/indexing/EventIndexPeg.js index c0bdd74ff4..75f0fa66ba 100644 --- a/src/indexing/EventIndexPeg.js +++ b/src/indexing/EventIndexPeg.js @@ -55,8 +55,6 @@ class EventIndexPeg { return false; } - console.log("EventIndex: Successfully initialized the event index"); - this.index = index; return true; From 9df227dbd08b130e93ed636ba2421022bc7cdd27 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Nov 2019 16:21:09 -0700 Subject: [PATCH 65/88] Update breadcrumbs when we do eventually see upgraded rooms Fixes https://github.com/vector-im/riot-web/issues/11469 --- src/components/views/rooms/RoomBreadcrumbs.js | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomBreadcrumbs.js b/src/components/views/rooms/RoomBreadcrumbs.js index 6529b5b1da..a80602368f 100644 --- a/src/components/views/rooms/RoomBreadcrumbs.js +++ b/src/components/views/rooms/RoomBreadcrumbs.js @@ -31,6 +31,9 @@ import {_t} from "../../../languageHandler"; const MAX_ROOMS = 20; const MIN_ROOMS_BEFORE_ENABLED = 10; +// The threshold time in milliseconds to wait for an autojoined room to show up. +const AUTOJOIN_WAIT_THRESHOLD_MS = 90000; // 90 seconds + export default class RoomBreadcrumbs extends React.Component { constructor(props) { super(props); @@ -38,6 +41,10 @@ export default class RoomBreadcrumbs extends React.Component { this.onAction = this.onAction.bind(this); this._dispatcherRef = null; + + // The room IDs we're waiting to come down the Room handler and when we + // started waiting for them. Used to track a room over an upgrade/autojoin. + this._waitingRoomQueue = [/* { roomId, addedTs } */]; } componentWillMount() { @@ -54,7 +61,7 @@ export default class RoomBreadcrumbs extends React.Component { MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt); MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline); MatrixClientPeg.get().on("Event.decrypted", this.onEventDecrypted); - MatrixClientPeg.get().on("Room", this.onRoomMembershipChanged); + MatrixClientPeg.get().on("Room", this.onRoom); } componentWillUnmount() { @@ -68,7 +75,7 @@ export default class RoomBreadcrumbs extends React.Component { client.removeListener("Room.receipt", this.onRoomReceipt); client.removeListener("Room.timeline", this.onRoomTimeline); client.removeListener("Event.decrypted", this.onEventDecrypted); - client.removeListener("Room", this.onRoomMembershipChanged); + client.removeListener("Room", this.onRoom); } } @@ -87,6 +94,12 @@ export default class RoomBreadcrumbs extends React.Component { onAction(payload) { switch (payload.action) { case 'view_room': + if (payload.auto_join && !MatrixClientPeg.get().getRoom(payload.room_id)) { + // Queue the room instead of pushing it immediately - we're probably just waiting + // for a join to complete (ie: joining the upgraded room). + this._waitingRoomQueue.push({roomId: payload.room_id, addedTs: (new Date).getTime()}); + break; + } this._appendRoomId(payload.room_id); break; @@ -153,7 +166,20 @@ export default class RoomBreadcrumbs extends React.Component { if (!this.state.enabled && this._shouldEnable()) { this.setState({enabled: true}); } - } + }; + + onRoom = (room) => { + // Always check for membership changes when we see new rooms + this.onRoomMembershipChanged(); + + const waitingRoom = this._waitingRoomQueue.find(r => r.roomId === room.roomId); + if (!waitingRoom) return; + this._waitingRoomQueue.splice(this._waitingRoomQueue.indexOf(waitingRoom), 1); + + const now = (new Date()).getTime(); + if ((now - waitingRoom.addedTs) > AUTOJOIN_WAIT_THRESHOLD_MS) return; // Too long ago. + this._appendRoomId(room.roomId); // add the room we've been waiting for + }; _shouldEnable() { const client = MatrixClientPeg.get(); From 1ff39f252406a531a6e3f918e1a03c9001cb52be Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 Nov 2019 16:51:48 -0700 Subject: [PATCH 66/88] Make the communities button behave more like a toggle Fixes https://github.com/vector-im/riot-web/issues/10771 Clicking the button should toggle between your last page (room in our case) and the communities stuff. --- src/components/structures/MatrixChat.js | 16 ++++++++++++++++ src/components/views/elements/GroupsButton.js | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index f5b64fe2ed..eb0481e1cd 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -627,6 +627,22 @@ export default createReactClass({ case 'view_invite': showRoomInviteDialog(payload.roomId); break; + case 'view_last_screen': + // This function does what we want, despite the name. The idea is that it shows + // the last room we were looking at or some reasonable default/guess. We don't + // have to worry about email invites or similar being re-triggered because the + // function will have cleared that state and not execute that path. + this._showScreenAfterLogin(); + break; + case 'toggle_my_groups': + // We just dispatch the page change rather than have to worry about + // what the logic is for each of these branches. + if (this.state.page_type === PageTypes.MyGroups) { + dis.dispatch({action: 'view_last_screen'}); + } else { + dis.dispatch({action: 'view_my_groups'}); + } + break; case 'notifier_enabled': { this.setState({showNotifierToolbar: Notifier.shouldShowToolbar()}); } diff --git a/src/components/views/elements/GroupsButton.js b/src/components/views/elements/GroupsButton.js index 3932c827c5..7b15e96424 100644 --- a/src/components/views/elements/GroupsButton.js +++ b/src/components/views/elements/GroupsButton.js @@ -22,7 +22,7 @@ import { _t } from '../../../languageHandler'; const GroupsButton = function(props) { const ActionButton = sdk.getComponent('elements.ActionButton'); return ( - Date: Tue, 26 Nov 2019 01:14:03 +0000 Subject: [PATCH 67/88] console.log doesn't take %s substitutions --- src/CallHandler.js | 4 ++-- src/Presence.js | 2 +- src/components/structures/MatrixChat.js | 2 +- src/components/structures/RoomView.js | 4 ++-- src/components/views/auth/CaptchaForm.js | 2 +- src/components/views/elements/AppTile.js | 2 +- src/components/views/messages/TextualBody.js | 4 ++-- src/components/views/rooms/EventTile.js | 2 +- src/components/views/rooms/MemberInfo.js | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/CallHandler.js b/src/CallHandler.js index bcdf7853fd..427be14097 100644 --- a/src/CallHandler.js +++ b/src/CallHandler.js @@ -322,7 +322,7 @@ function _onAction(payload) { }); return; } else if (members.length === 2) { - console.log("Place %s call in %s", payload.type, payload.room_id); + console.info("Place %s call in %s", payload.type, payload.room_id); const call = Matrix.createNewMatrixCall(MatrixClientPeg.get(), payload.room_id); placeCall(call); } else { // > 2 @@ -337,7 +337,7 @@ function _onAction(payload) { } break; case 'place_conference_call': - console.log("Place conference call in %s", payload.room_id); + console.info("Place conference call in %s", payload.room_id); _startCallApp(payload.room_id, payload.type); break; case 'incoming_call': diff --git a/src/Presence.js b/src/Presence.js index ca3db9b762..8ef988f171 100644 --- a/src/Presence.js +++ b/src/Presence.js @@ -96,7 +96,7 @@ class Presence { try { await MatrixClientPeg.get().setPresence(this.state); - console.log("Presence: %s", newState); + console.info("Presence: %s", newState); } catch (err) { console.error("Failed to set presence: %s", err); this.state = oldState; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 661a0c7077..81098df319 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1315,7 +1315,7 @@ export default createReactClass({ if (state === "SYNCING" && prevState === "SYNCING") { return; } - console.log("MatrixClient sync state => %s", state); + console.info("MatrixClient sync state => %s", state); if (state !== "PREPARED") { return; } self.firstSyncComplete = true; diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 6dee60bec7..db7ae33c8a 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -358,7 +358,7 @@ module.exports = createReactClass({ if (this.props.autoJoin) { this.onJoinButtonClicked(); } else if (!room && shouldPeek) { - console.log("Attempting to peek into room %s", roomId); + console.info("Attempting to peek into room %s", roomId); this.setState({ peekLoading: true, isPeeking: true, // this will change to false if peeking fails @@ -1897,7 +1897,7 @@ module.exports = createReactClass({ highlightedEventId = this.state.initialEventId; } - // console.log("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview); + // console.info("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview); const messagePanel = ( = %s", them.powerLevel, me.powerLevel); + //console.info("Cannot affect user: %s >= %s", them.powerLevel, me.powerLevel); return can; } const editPowerLevel = ( From 4cec7c41b109714eae3f5b44535b0130ad2f0fd4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 Nov 2019 09:52:03 -0700 Subject: [PATCH 68/88] Fix override behaviour of system vs defined themes Fixes https://github.com/vector-im/riot-web/issues/11509 --- src/i18n/strings/en_EN.json | 2 +- src/settings/Settings.js | 2 +- src/theme.js | 23 ++++++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0a83237f45..9136f432dd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -364,7 +364,7 @@ "Automatically replace plain text Emoji": "Automatically replace plain text Emoji", "Mirror local video feed": "Mirror local video feed", "Enable Community Filter Panel": "Enable Community Filter Panel", - "Match system dark mode setting": "Match system dark mode setting", + "Match system theme": "Match system theme", "Allow Peer-to-Peer for 1:1 calls": "Allow Peer-to-Peer for 1:1 calls", "Send analytics data": "Send analytics data", "Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 5a3283c5f0..b02ab82400 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -284,7 +284,7 @@ export const SETTINGS = { "use_system_theme": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, default: true, - displayName: _td("Match system dark mode setting"), + displayName: _td("Match system theme"), }, "webRtcAllowPeerToPeer": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, diff --git a/src/theme.js b/src/theme.js index 9208ff2045..045e573361 100644 --- a/src/theme.js +++ b/src/theme.js @@ -20,7 +20,7 @@ import {_t} from "./languageHandler"; export const DEFAULT_THEME = "light"; import Tinter from "./Tinter"; import dis from "./dispatcher"; -import SettingsStore from "./settings/SettingsStore"; +import SettingsStore, {SettingLevel} from "./settings/SettingsStore"; export class ThemeWatcher { static _instance = null; @@ -60,14 +60,14 @@ export class ThemeWatcher { _onChange = () => { this.recheck(); - } + }; _onAction = (payload) => { if (payload.action === 'recheck_theme') { // XXX forceTheme this.recheck(payload.forceTheme); } - } + }; // XXX: forceTheme param aded here as local echo appears to be unreliable // https://github.com/vector-im/riot-web/issues/11443 @@ -80,6 +80,23 @@ export class ThemeWatcher { } getEffectiveTheme() { + // If the user has specifically enabled the system matching option (excluding default), + // then use that over anything else. We pick the lowest possible level for the setting + // to ensure the ordering otherwise works. + const systemThemeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "use_system_theme", null, false, true); + if (systemThemeExplicit) { + if (this._preferDark.matches) return 'dark'; + if (this._preferLight.matches) return 'light'; + } + + // If the user has specifically enabled the theme (without the system matching option being + // enabled specifically and excluding the default), use that theme. We pick the lowest possible + // level for the setting to ensure the ordering otherwise works. + const themeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "theme", null, false, true); + if (themeExplicit) return themeExplicit; + + // If the user hasn't really made a preference in either direction, assume the defaults of the + // settings and use those. if (SettingsStore.getValue('use_system_theme')) { if (this._preferDark.matches) return 'dark'; if (this._preferLight.matches) return 'light'; From d50d8877e0d92a843ef0b2d54318438259b86f44 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 Nov 2019 09:56:04 -0700 Subject: [PATCH 69/88] Appease the linter --- src/theme.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/theme.js b/src/theme.js index 045e573361..3f50f8ba88 100644 --- a/src/theme.js +++ b/src/theme.js @@ -83,7 +83,8 @@ export class ThemeWatcher { // If the user has specifically enabled the system matching option (excluding default), // then use that over anything else. We pick the lowest possible level for the setting // to ensure the ordering otherwise works. - const systemThemeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "use_system_theme", null, false, true); + const systemThemeExplicit = SettingsStore.getValueAt( + SettingLevel.DEVICE, "use_system_theme", null, false, true); if (systemThemeExplicit) { if (this._preferDark.matches) return 'dark'; if (this._preferLight.matches) return 'light'; @@ -92,7 +93,8 @@ export class ThemeWatcher { // If the user has specifically enabled the theme (without the system matching option being // enabled specifically and excluding the default), use that theme. We pick the lowest possible // level for the setting to ensure the ordering otherwise works. - const themeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "theme", null, false, true); + const themeExplicit = SettingsStore.getValueAt( + SettingLevel.DEVICE, "theme", null, false, true); if (themeExplicit) return themeExplicit; // If the user hasn't really made a preference in either direction, assume the defaults of the From ff2ac63530646ca1d3c22b322153589fff9fb59a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 Nov 2019 09:52:03 -0700 Subject: [PATCH 70/88] Fix override behaviour of system vs defined themes Fixes https://github.com/vector-im/riot-web/issues/11509 --- src/i18n/strings/en_EN.json | 2 +- src/settings/Settings.js | 2 +- src/theme.js | 23 ++++++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7709a4a398..f31f086d26 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -364,7 +364,7 @@ "Automatically replace plain text Emoji": "Automatically replace plain text Emoji", "Mirror local video feed": "Mirror local video feed", "Enable Community Filter Panel": "Enable Community Filter Panel", - "Match system dark mode setting": "Match system dark mode setting", + "Match system theme": "Match system theme", "Allow Peer-to-Peer for 1:1 calls": "Allow Peer-to-Peer for 1:1 calls", "Send analytics data": "Send analytics data", "Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 89693f7c50..54b8715b6e 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -284,7 +284,7 @@ export const SETTINGS = { "use_system_theme": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, default: true, - displayName: _td("Match system dark mode setting"), + displayName: _td("Match system theme"), }, "webRtcAllowPeerToPeer": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, diff --git a/src/theme.js b/src/theme.js index e89af55924..2973d2d3fd 100644 --- a/src/theme.js +++ b/src/theme.js @@ -20,7 +20,7 @@ import {_t} from "./languageHandler"; export const DEFAULT_THEME = "light"; import Tinter from "./Tinter"; import dis from "./dispatcher"; -import SettingsStore from "./settings/SettingsStore"; +import SettingsStore, {SettingLevel} from "./settings/SettingsStore"; export class ThemeWatcher { static _instance = null; @@ -60,14 +60,14 @@ export class ThemeWatcher { _onChange = () => { this.recheck(); - } + }; _onAction = (payload) => { if (payload.action === 'recheck_theme') { // XXX forceTheme this.recheck(payload.forceTheme); } - } + }; // XXX: forceTheme param aded here as local echo appears to be unreliable // https://github.com/vector-im/riot-web/issues/11443 @@ -80,6 +80,23 @@ export class ThemeWatcher { } getEffectiveTheme() { + // If the user has specifically enabled the system matching option (excluding default), + // then use that over anything else. We pick the lowest possible level for the setting + // to ensure the ordering otherwise works. + const systemThemeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "use_system_theme", null, false, true); + if (systemThemeExplicit) { + if (this._preferDark.matches) return 'dark'; + if (this._preferLight.matches) return 'light'; + } + + // If the user has specifically enabled the theme (without the system matching option being + // enabled specifically and excluding the default), use that theme. We pick the lowest possible + // level for the setting to ensure the ordering otherwise works. + const themeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "theme", null, false, true); + if (themeExplicit) return themeExplicit; + + // If the user hasn't really made a preference in either direction, assume the defaults of the + // settings and use those. if (SettingsStore.getValue('use_system_theme')) { if (this._preferDark.matches) return 'dark'; if (this._preferLight.matches) return 'light'; From 810fff64bc65ecfe146442c050f7c514bd20d563 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 Nov 2019 09:56:04 -0700 Subject: [PATCH 71/88] Appease the linter --- src/theme.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/theme.js b/src/theme.js index 2973d2d3fd..77cf6e9593 100644 --- a/src/theme.js +++ b/src/theme.js @@ -83,7 +83,8 @@ export class ThemeWatcher { // If the user has specifically enabled the system matching option (excluding default), // then use that over anything else. We pick the lowest possible level for the setting // to ensure the ordering otherwise works. - const systemThemeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "use_system_theme", null, false, true); + const systemThemeExplicit = SettingsStore.getValueAt( + SettingLevel.DEVICE, "use_system_theme", null, false, true); if (systemThemeExplicit) { if (this._preferDark.matches) return 'dark'; if (this._preferLight.matches) return 'light'; @@ -92,7 +93,8 @@ export class ThemeWatcher { // If the user has specifically enabled the theme (without the system matching option being // enabled specifically and excluding the default), use that theme. We pick the lowest possible // level for the setting to ensure the ordering otherwise works. - const themeExplicit = SettingsStore.getValueAt(SettingLevel.DEVICE, "theme", null, false, true); + const themeExplicit = SettingsStore.getValueAt( + SettingLevel.DEVICE, "theme", null, false, true); if (themeExplicit) return themeExplicit; // If the user hasn't really made a preference in either direction, assume the defaults of the From a2e3f6496312d9def35d529e7ede9b5bfcc7622f Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 26 Nov 2019 19:06:02 +0000 Subject: [PATCH 72/88] Change read markers to use CSS transitions Removes one of the two places we use Velocity, so we're one step closer to getting rid of it for good. Should therefore fix the fact that Velocity is leaking data entries and therefore
elements. Hopefully also makes the logic in getEventTiles incrementally simpler, if still somwewhat byzantine. --- res/css/structures/_RoomView.scss | 3 + src/components/structures/MessagePanel.js | 228 ++++++++---------- .../structures/MessagePanel-test.js | 118 +++++---- 3 files changed, 176 insertions(+), 173 deletions(-) diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 50d412ad58..5e826306c6 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -221,6 +221,9 @@ hr.mx_RoomView_myReadMarker { position: relative; top: -1px; z-index: 1; + transition: width 400ms easeInSine 1s, opacity 400ms easeInSine 1s; + width: 99%; + opacity: 1; } .mx_RoomView_callStatusBar .mx_UploadBar_uploadProgressInner { diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 912b865b9f..d1cc1b7caf 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -16,8 +16,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -/* global Velocity */ - import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; @@ -111,14 +109,12 @@ export default class MessagePanel extends React.Component { constructor() { super(); - // the event after which we put a visible unread marker on the last - // render cycle; null if readMarkerVisible was false or the RM was - // suppressed (eg because it was at the end of the timeline) - this.currentReadMarkerEventId = null; - // the event after which we are showing a disappearing read marker - // animation - this.currentGhostEventId = null; + this.state = { + // previous positions the read marker has been in, so we can + // display 'ghost' read markers that are animating away + ghostReadMarkers: [], + }; // opaque readreceipt info for each userId; used by ReadReceiptMarker // to manage its animations @@ -157,10 +153,6 @@ export default class MessagePanel extends React.Component { // displayed event in the current render cycle. this._readReceiptsByUserId = {}; - // Remember the read marker ghost node so we can do the cleanup that - // Velocity requires - this._readMarkerGhostNode = null; - // Cache hidden events setting on mount since Settings is expensive to // query, and we check this in a hot code path. this._showHiddenEventsInTimeline = @@ -177,6 +169,16 @@ export default class MessagePanel extends React.Component { this._isMounted = false; } + componentDidUpdate(prevProps, prevState) { + if (prevProps.readMarkerVisible && this.props.readMarkerEventId !== prevProps.readMarkerEventId) { + const ghostReadMarkers = this.state.ghostReadMarkers; + ghostReadMarkers.push(prevProps.readMarkerEventId); + this.setState({ + ghostReadMarkers, + }); + } + } + /* get the DOM node representing the given event */ getNodeForEventId(eventId) { if (!this.eventNodes) { @@ -325,6 +327,78 @@ export default class MessagePanel extends React.Component { return !shouldHideEvent(mxEv); } + _readMarkerForEvent(eventId, isLastEvent) { + const visible = !isLastEvent && this.props.readMarkerVisible; + + if (this.props.readMarkerEventId === eventId) { + let hr; + // if the read marker comes at the end of the timeline (except + // for local echoes, which are excluded from RMs, because they + // don't have useful event ids), we don't want to show it, but + // we still want to create the
  • for it so that the + // algorithms which depend on its position on the screen aren't + // confused. + if (visible) { + hr =
    ; + } + + return ( +
  • + { hr } +
  • + ); + } else if (this.state.ghostReadMarkers.includes(eventId)) { + // We render 'ghost' read markers in the DOM while they + // transition away. This allows the actual read marker + // to be in the right place straight away without having + // to wait for the transition to finish. + // There are probably much simpler ways to do this transition, + // possibly using react-transition-group which handles keeping + // elements in the DOM whilst they transition out, although our + // case is a little more complex because only some of the items + // transition (ie. the read markers do but the event tiles do not) + // and TransitionGroup requires that all its children are Transitions. + const hr =
    ; + + // give it a key which depends on the event id. That will ensure that + // we get a new DOM node (restarting the animation) when the ghost + // moves to a different event. + return ( +
  • + { hr } +
  • + ); + } + + return null; + } + + _collectGhostReadMarker = (node) => { + if (node) { + // now the element has appeared, change the style which will trigger the CSS transition + requestAnimationFrame(() => { + node.style.width = '10%'; + node.style.opacity = '0'; + }); + } + }; + + _onGhostTransitionEnd = (ev) => { + // we can now clean up the ghost element + const finishedEventId = ev.target.dataset.eventid; + this.setState({ + ghostReadMarkers: this.state.ghostReadMarkers.filter(eid => eid !== finishedEventId), + }); + }; + _getEventTiles() { const DateSeparator = sdk.getComponent('messages.DateSeparator'); const EventListSummary = sdk.getComponent('views.elements.EventListSummary'); @@ -332,7 +406,6 @@ export default class MessagePanel extends React.Component { this.eventNodes = {}; - let visible = false; let i; // first figure out which is the last event in the list which we're @@ -367,16 +440,6 @@ export default class MessagePanel extends React.Component { let prevEvent = null; // the last event we showed - // assume there is no read marker until proven otherwise - let readMarkerVisible = false; - - // if the readmarker has moved, cancel any active ghost. - if (this.currentReadMarkerEventId && this.props.readMarkerEventId && - this.props.readMarkerVisible && - this.currentReadMarkerEventId !== this.props.readMarkerEventId) { - this.currentGhostEventId = null; - } - this._readReceiptsByEvent = {}; if (this.props.showReadReceipts) { this._readReceiptsByEvent = this._getReadReceiptsByShownEvent(); @@ -401,7 +464,7 @@ export default class MessagePanel extends React.Component { return false; }; if (mxEv.getType() === "m.room.create") { - let readMarkerInSummary = false; + let summaryReadMarker = null; const ts1 = mxEv.getTs(); if (this._wantsDateSeparator(prevEvent, mxEv.getDate())) { @@ -410,9 +473,7 @@ export default class MessagePanel extends React.Component { } // If RM event is the first in the summary, append the RM after the summary - if (mxEv.getId() === this.props.readMarkerEventId) { - readMarkerInSummary = true; - } + summaryReadMarker = summaryReadMarker || this._readMarkerForEvent(mxEv.getId()); // If this m.room.create event should be shown (room upgrade) then show it before the summary if (this._shouldShowEvent(mxEv)) { @@ -427,9 +488,7 @@ export default class MessagePanel extends React.Component { // Ignore redacted/hidden member events if (!this._shouldShowEvent(collapsedMxEv)) { // If this hidden event is the RM and in or at end of a summary put RM after the summary. - if (collapsedMxEv.getId() === this.props.readMarkerEventId) { - readMarkerInSummary = true; - } + summaryReadMarker = summaryReadMarker || this._readMarkerForEvent(collapsedMxEv.getId()); continue; } @@ -438,9 +497,7 @@ export default class MessagePanel extends React.Component { } // If RM event is in the summary, mark it as such and the RM will be appended after the summary. - if (collapsedMxEv.getId() === this.props.readMarkerEventId) { - readMarkerInSummary = true; - } + summaryReadMarker = summaryReadMarker || this._readMarkerForEvent(collapsedMxEv.getId()); summarisedEvents.push(collapsedMxEv); } @@ -468,8 +525,8 @@ export default class MessagePanel extends React.Component { { eventTiles } ); - if (readMarkerInSummary) { - ret.push(this._getReadMarkerTile(visible)); + if (summaryReadMarker) { + ret.push(summaryReadMarker); } prevEvent = mxEv; @@ -480,7 +537,7 @@ export default class MessagePanel extends React.Component { // Wrap consecutive member events in a ListSummary, ignore if redacted if (isMembershipChange(mxEv) && wantTile) { - let readMarkerInMels = false; + let summaryReadMarker = null; const ts1 = mxEv.getTs(); // Ensure that the key of the MemberEventListSummary does not change with new // member events. This will prevent it from being re-created unnecessarily, and @@ -498,9 +555,7 @@ export default class MessagePanel extends React.Component { } // If RM event is the first in the MELS, append the RM after MELS - if (mxEv.getId() === this.props.readMarkerEventId) { - readMarkerInMels = true; - } + summaryReadMarker = summaryReadMarker || this._readMarkerForEvent(mxEv.getId()); const summarisedEvents = [mxEv]; for (;i + 1 < this.props.events.length; i++) { @@ -509,9 +564,7 @@ export default class MessagePanel extends React.Component { // Ignore redacted/hidden member events if (!this._shouldShowEvent(collapsedMxEv)) { // If this hidden event is the RM and in or at end of a MELS put RM after MELS. - if (collapsedMxEv.getId() === this.props.readMarkerEventId) { - readMarkerInMels = true; - } + summaryReadMarker = summaryReadMarker || this._readMarkerForEvent(collapsedMxEv.getId()); continue; } @@ -521,9 +574,7 @@ export default class MessagePanel extends React.Component { } // If RM event is in MELS mark it as such and the RM will be appended after MELS. - if (collapsedMxEv.getId() === this.props.readMarkerEventId) { - readMarkerInMels = true; - } + summaryReadMarker = summaryReadMarker || this._readMarkerForEvent(collapsedMxEv.getId()); summarisedEvents.push(collapsedMxEv); } @@ -554,8 +605,8 @@ export default class MessagePanel extends React.Component { { eventTiles } ); - if (readMarkerInMels) { - ret.push(this._getReadMarkerTile(visible)); + if (summaryReadMarker) { + ret.push(summaryReadMarker); } prevEvent = mxEv; @@ -570,40 +621,10 @@ export default class MessagePanel extends React.Component { prevEvent = mxEv; } - let isVisibleReadMarker = false; - - if (eventId === this.props.readMarkerEventId) { - visible = this.props.readMarkerVisible; - - // if the read marker comes at the end of the timeline (except - // for local echoes, which are excluded from RMs, because they - // don't have useful event ids), we don't want to show it, but - // we still want to create the
  • for it so that the - // algorithms which depend on its position on the screen aren't - // confused. - if (i >= lastShownNonLocalEchoIndex) { - visible = false; - } - ret.push(this._getReadMarkerTile(visible)); - readMarkerVisible = visible; - isVisibleReadMarker = visible; - } - - // XXX: there should be no need for a ghost tile - we should just use a - // a dispatch (user_activity_end) to start the RM animation. - if (eventId === this.currentGhostEventId) { - // if we're showing an animation, continue to show it. - ret.push(this._getReadMarkerGhostTile()); - } else if (!isVisibleReadMarker && - eventId === this.currentReadMarkerEventId) { - // there is currently a read-up-to marker at this point, but no - // more. Show an animation of it disappearing. - ret.push(this._getReadMarkerGhostTile()); - this.currentGhostEventId = eventId; - } + const readMarker = this._readMarkerForEvent(eventId, i >= lastShownNonLocalEchoIndex); + if (readMarker) ret.push(readMarker); } - this.currentReadMarkerEventId = readMarkerVisible ? this.props.readMarkerEventId : null; return ret; } @@ -797,53 +818,6 @@ export default class MessagePanel extends React.Component { return receiptsByEvent; } - _getReadMarkerTile(visible) { - let hr; - if (visible) { - hr =
    ; - } - - return ( -
  • - { hr } -
  • - ); - } - - _startAnimation = (ghostNode) => { - if (this._readMarkerGhostNode) { - Velocity.Utilities.removeData(this._readMarkerGhostNode); - } - this._readMarkerGhostNode = ghostNode; - - if (ghostNode) { - // eslint-disable-next-line new-cap - Velocity(ghostNode, {opacity: '0', width: '10%'}, - {duration: 400, easing: 'easeInSine', - delay: 1000}); - } - }; - - _getReadMarkerGhostTile() { - const hr =
    ; - - // give it a key which depends on the event id. That will ensure that - // we get a new DOM node (restarting the animation) when the ghost - // moves to a different event. - return ( -
  • - { hr } -
  • - ); - } - _collectEventNode = (eventId, node) => { this.eventNodes[eventId] = node; } diff --git a/test/components/structures/MessagePanel-test.js b/test/components/structures/MessagePanel-test.js index f58f1b925c..7c52512bc2 100644 --- a/test/components/structures/MessagePanel-test.js +++ b/test/components/structures/MessagePanel-test.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -81,6 +82,7 @@ describe('MessagePanel', function() { // HACK: We assume all settings want to be disabled SettingsStore.getValue = sinon.stub().returns(false); + SettingsStore.getValue.withArgs('showDisplaynameChanges').returns(true); // This option clobbers the duration of all animations to be 1ms // which makes unit testing a lot simpler (the animation doesn't @@ -109,6 +111,44 @@ describe('MessagePanel', function() { return events; } + + // make a collection of events with some member events that should be collapsed + // with a MemberEventListSummary + function mkMelsEvents() { + const events = []; + const ts0 = Date.now(); + + let i = 0; + events.push(test_utils.mkMessage({ + event: true, room: "!room:id", user: "@user:id", + ts: ts0 + ++i*1000, + })); + + for (i = 0; i < 10; i++) { + events.push(test_utils.mkMembership({ + event: true, room: "!room:id", user: "@user:id", + target: { + userId: "@user:id", + name: "Bob", + getAvatarUrl: () => { + return "avatar.jpeg"; + }, + }, + ts: ts0 + i*1000, + mship: 'join', + prevMship: 'join', + name: 'A user', + })); + } + + events.push(test_utils.mkMessage({ + event: true, room: "!room:id", user: "@user:id", + ts: ts0 + ++i*1000, + })); + + return events; + } + it('should show the events', function() { const res = TestUtils.renderIntoDocument( , @@ -120,6 +160,23 @@ describe('MessagePanel', function() { expect(tiles.length).toEqual(10); }); + it('should collapse adjacent member events', function() { + const res = TestUtils.renderIntoDocument( + , + ); + + // just check we have the right number of tiles for now + const tiles = TestUtils.scryRenderedComponentsWithType( + res, sdk.getComponent('rooms.EventTile'), + ); + expect(tiles.length).toEqual(2); + + const summaryTiles = TestUtils.scryRenderedComponentsWithType( + res, sdk.getComponent('elements.MemberEventListSummary'), + ); + expect(summaryTiles.length).toEqual(1); + }); + it('should show the read-marker in the right place', function() { const res = TestUtils.renderIntoDocument( , + ); + + const summary = TestUtils.findRenderedDOMComponentWithClass(res, 'mx_EventListSummary'); + + // find the
  • which wraps the read marker + const rm = TestUtils.findRenderedDOMComponentWithClass(res, 'mx_RoomView_myReadMarker_container'); + + expect(rm.previousSibling).toEqual(summary); + }); + it('shows a ghost read-marker when the read-marker moves', function(done) { // fake the clock so that we can test the velocity animation. clock.install(); @@ -191,50 +263,4 @@ describe('MessagePanel', function() { }, 100); }, 100); }); - - it('shows only one ghost when the RM moves twice', function() { - const parentDiv = document.createElement('div'); - - // first render with the RM in one place - let mp = ReactDOM.render( - , parentDiv); - - const tiles = TestUtils.scryRenderedComponentsWithType( - mp, sdk.getComponent('rooms.EventTile')); - const tileContainers = tiles.map(function(t) { - return ReactDOM.findDOMNode(t).parentNode; - }); - - // now move the RM - mp = ReactDOM.render( - , parentDiv); - - // now there should be two RM containers - let found = TestUtils.scryRenderedDOMComponentsWithClass(mp, 'mx_RoomView_myReadMarker_container'); - expect(found.length).toEqual(2); - - // the first should be the ghost - expect(tileContainers.indexOf(found[0].previousSibling)).toEqual(4); - - // the second should be the real RM - expect(tileContainers.indexOf(found[1].previousSibling)).toEqual(6); - - // and move the RM again - mp = ReactDOM.render( - , parentDiv); - - // still two RM containers - found = TestUtils.scryRenderedDOMComponentsWithClass(mp, 'mx_RoomView_myReadMarker_container'); - expect(found.length).toEqual(2); - - // they should have moved - expect(tileContainers.indexOf(found[0].previousSibling)).toEqual(6); - expect(tileContainers.indexOf(found[1].previousSibling)).toEqual(8); - }); }); From c2c8b1b6e0d8f0e07e502e8a58f877427603c89b Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 25 Nov 2019 14:03:40 +0000 Subject: [PATCH 73/88] Clarify that cross-signing is in development In an attempt to clarify the state of this highly anticipated feature, this updates the labs flag name to match. Part of https://github.com/vector-im/riot-web/issues/11492 --- src/i18n/strings/en_EN.json | 2 +- src/settings/Settings.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index f31f086d26..ad877f11e7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -342,7 +342,7 @@ "Multiple integration managers": "Multiple integration managers", "Try out new ways to ignore people (experimental)": "Try out new ways to ignore people (experimental)", "Send verification requests in direct message, including a new verification UX in the member panel.": "Send verification requests in direct message, including a new verification UX in the member panel.", - "Enable cross-signing to verify per-user instead of per-device": "Enable cross-signing to verify per-user instead of per-device", + "Enable cross-signing to verify per-user instead of per-device (in development)": "Enable cross-signing to verify per-user instead of per-device (in development)", "Enable local event indexing and E2EE search (requires restart)": "Enable local event indexing and E2EE search (requires restart)", "Use the new, faster, composer for writing messages": "Use the new, faster, composer for writing messages", "Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 54b8715b6e..b02ab82400 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -143,7 +143,7 @@ export const SETTINGS = { }, "feature_cross_signing": { isFeature: true, - displayName: _td("Enable cross-signing to verify per-user instead of per-device"), + displayName: _td("Enable cross-signing to verify per-user instead of per-device (in development)"), supportedLevels: LEVELS_FEATURE, default: false, controller: new ReloadOnChangeController(), From 7905e6cc3b9933153e5dc73c2d1b9d24c51308a3 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Tue, 26 Nov 2019 14:31:11 -0600 Subject: [PATCH 74/88] Add a link to the labs feature documentation Signed-off-by: Aaron Raimist --- .../views/settings/tabs/user/LabsUserSettingsTab.js | 9 +++++++++ src/i18n/strings/en_EN.json | 1 + 2 files changed, 10 insertions(+) diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js index 07a2bf722a..71a3e5f1d2 100644 --- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js @@ -49,6 +49,15 @@ export default class LabsUserSettingsTab extends React.Component { return (
    {_t("Labs")}
    +
    + { + _t('These are experimental features. For more information on what ' + + 'these options do see the documentation.', {}, { + 'a': (sub) => {sub}, + }) + } +
    {flags} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9136f432dd..9522655698 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -641,6 +641,7 @@ "Access Token:": "Access Token:", "click to reveal": "click to reveal", "Labs": "Labs", + "These are experimental features. For more information on what these options do see the documentation.": "These are experimental features. For more information on what these options do see the documentation.", "Ignored/Blocked": "Ignored/Blocked", "Error adding ignored user/server": "Error adding ignored user/server", "Something went wrong. Please try again or view your console for hints.": "Something went wrong. Please try again or view your console for hints.", From 98c47265c9d7c9f16a27946fee8dab946158fce4 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Tue, 26 Nov 2019 15:00:56 -0600 Subject: [PATCH 75/88] Fix indentation Signed-off-by: Aaron Raimist --- .../views/settings/tabs/user/LabsUserSettingsTab.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js index 71a3e5f1d2..4232cc90fb 100644 --- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js @@ -53,8 +53,10 @@ export default class LabsUserSettingsTab extends React.Component { { _t('These are experimental features. For more information on what ' + 'these options do see the documentation.', {}, { - 'a': (sub) => {sub}, + 'a': (sub) => { + return {sub}; + }, }) }
    From bb7cc20b1a6cf181ea209fd382dd5a62a506a89c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 27 Nov 2019 00:45:46 +0000 Subject: [PATCH 76/88] fix font smoothing to match figma as per https://github.com/vector-im/riot-web/issues/11425 with apologies to https://usabilitypost.com/2012/11/05/stop-fixing-font-smoothing/ :/ --- res/css/_common.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/res/css/_common.scss b/res/css/_common.scss index 5987275f7f..51d985efb7 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -30,6 +30,11 @@ body { color: $primary-fg-color; border: 0px; margin: 0px; + + // needed to match the designs correctly on macOS + // see https://github.com/vector-im/riot-web/issues/11425 + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } pre, code { From d9e322bbcaf2f4bf78b608266c35c6c5292bb4ef Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 27 Nov 2019 10:32:21 +0000 Subject: [PATCH 77/88] Upgrade to JS SDK 2.4.5 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ecfe63c23..6cdd42c9da 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "2.4.4", + "matrix-js-sdk": "2.4.5", "optimist": "^0.6.1", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 44d9548b54..e43f12760b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5197,10 +5197,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.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.4.tgz#d5e2d6fbe938c4275a1423a5f09330d33517ce3f" - integrity sha512-wSaRFvhWvwEzVaEkyBGo5ReumvaM5OrC1MJ6SVlyoLwH/WRPEXcUlu+rUNw5TFVEAH4TAVHXf/SVRBiR0j5nSQ== +matrix-js-sdk@2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.5.tgz#0a02f0a3e18c59a393b34b8d6ebc54226cce6465" + integrity sha512-Mh0fPoiqyXRksFNYS4/2s20xAklmYVIgSms3qFvLhno32LN43NizUoAMBYYGtyjt8BQi+U77lbNL0s5f2V7gPQ== dependencies: another-json "^0.2.0" babel-runtime "^6.26.0" From 25b5921ddfeeb4dbbfd4387b8f8482fcbdda82fe Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 27 Nov 2019 10:38:35 +0000 Subject: [PATCH 78/88] Prepare changelog for v1.7.4 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc2341863a..8fe6f80e43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +Changes in [1.7.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.4) (2019-11-27) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.3...v1.7.4) + +* Upgrade to JS SDK 2.5.4 to relax identity server discovery and E2EE debugging +* Fix override behaviour of system vs defined theme +* Clarify that cross-signing is in development + Changes in [1.7.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.3) (2019-11-25) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.3-rc.2...v1.7.3) From 1a98c0d04e74684dc47ee1c7d917ae56a5a9ba91 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 27 Nov 2019 10:38:35 +0000 Subject: [PATCH 79/88] v1.7.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6cdd42c9da..7b75390293 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.3", + "version": "1.7.4", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 54d6b6aa73656d9c00cc047ace964bc73ce011e7 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 27 Nov 2019 13:31:44 +0000 Subject: [PATCH 80/88] Flip JS SDK back to develop --- package.json | 4 ++-- yarn.lock | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 92bf2e452d..5b82d9b111 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "2.4.5", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", "optimist": "^0.6.1", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", @@ -133,8 +133,8 @@ "eslint": "^5.12.0", "eslint-config-google": "^0.7.1", "eslint-plugin-babel": "^5.2.1", - "eslint-plugin-jest": "^23.0.4", "eslint-plugin-flowtype": "^2.30.0", + "eslint-plugin-jest": "^23.0.4", "eslint-plugin-react": "^7.7.0", "eslint-plugin-react-hooks": "^2.0.1", "estree-walker": "^0.5.0", diff --git a/yarn.lock b/yarn.lock index 62b45fd715..073fc95b37 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5246,10 +5246,9 @@ 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.5: +"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": version "2.4.5" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.5.tgz#0a02f0a3e18c59a393b34b8d6ebc54226cce6465" - integrity sha512-Mh0fPoiqyXRksFNYS4/2s20xAklmYVIgSms3qFvLhno32LN43NizUoAMBYYGtyjt8BQi+U77lbNL0s5f2V7gPQ== + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/6ea8003df23d55e2b84911c3204005c42a9ffa9c" dependencies: another-json "^0.2.0" babel-runtime "^6.26.0" From d6821ecb990c7667e96fab58661fbc3cb89e76bd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 27 Nov 2019 10:44:36 -0700 Subject: [PATCH 81/88] Fix multi-invite error dialog messaging Fixes https://github.com/vector-im/riot-web/issues/11515 --- src/RoomInvite.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 64aab36128..babed0e6b8 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -202,11 +202,14 @@ function _showAnyInviteErrors(addrs, room, inviter) { } } + // React 16 doesn't let us use `errorList.join(
    )` anymore, so this is our solution + let description =
    {errorList.map(e =>
    {e}
    )}
    ; + if (errorList.length > 0) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Failed to invite the following users to the room', '', ErrorDialog, { title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}), - description: errorList.join(
    ), + description, }); } } From 275bd33a6c59f25106063e3967c93b942c111872 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 27 Nov 2019 10:48:05 -0700 Subject: [PATCH 82/88] Move the description into the relevant branch --- src/RoomInvite.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/RoomInvite.js b/src/RoomInvite.js index babed0e6b8..c72ca4d662 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -202,10 +202,10 @@ function _showAnyInviteErrors(addrs, room, inviter) { } } - // React 16 doesn't let us use `errorList.join(
    )` anymore, so this is our solution - let description =
    {errorList.map(e =>
    {e}
    )}
    ; - if (errorList.length > 0) { + // React 16 doesn't let us use `errorList.join(
    )` anymore, so this is our solution + let description =
    {errorList.map(e =>
    {e}
    )}
    ; + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Failed to invite the following users to the room', '', ErrorDialog, { title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}), From 673e6c31625ded3f9215ec4cfbdefa09b1c97295 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 27 Nov 2019 12:26:43 -0700 Subject: [PATCH 83/88] Don't assume that diffs will have an appropriate child node Fixes https://github.com/vector-im/riot-web/issues/11497 This is a regression from react-sdk v1.5.0 where the diff feature was added in the first place. It only affects lists. --- src/utils/MessageDiffUtils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/utils/MessageDiffUtils.js b/src/utils/MessageDiffUtils.js index 78f3faa0c5..de0d8fdc89 100644 --- a/src/utils/MessageDiffUtils.js +++ b/src/utils/MessageDiffUtils.js @@ -77,6 +77,8 @@ function findRefNodes(root, route, isAddition) { const end = isAddition ? route.length - 1 : route.length; for (let i = 0; i < end; ++i) { refParentNode = refNode; + // Lists don't have appropriate child nodes we can use. + if (!refNode.childNodes[route[i]]) continue; refNode = refNode.childNodes[route[i]]; } return {refNode, refParentNode}; From 7b013ecc697ca8fe6aebfd96bab3ff583e2357d0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 27 Nov 2019 12:54:31 -0700 Subject: [PATCH 84/88] Fix persisted widgets getting stuck at loading screens The widget itself is rendered underneath the loading screen, so we just have to disable the loading state. This commit also removes the "is" attribute because React 16 includes unknown attributes: https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html Fixes https://github.com/vector-im/riot-web/issues/11536 --- src/components/views/elements/AppTile.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 4cfce0c5dd..9a29843d3b 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -36,6 +36,7 @@ import classNames from 'classnames'; import {IntegrationManagers} from "../../../integrations/IntegrationManagers"; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; import {createMenu} from "../../structures/ContextualMenu"; +import PersistedElement from "./PersistedElement"; const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:']; const ENABLE_REACT_PERF = false; @@ -247,7 +248,8 @@ export default class AppTile extends React.Component { this.setScalarToken(); } } else if (nextProps.show && !this.props.show) { - if (this.props.waitForIframeLoad) { + // We assume that persisted widgets are loaded and don't need a spinner. + if (this.props.waitForIframeLoad && !PersistedElement.isMounted(this._persistKey)) { this.setState({ loading: true, }); @@ -652,12 +654,7 @@ export default class AppTile extends React.Component { appTileBody = (
    { this.state.loading && loadingElement } - { /* - The "is" attribute in the following iframe tag is needed in order to enable rendering of the - "allow" attribute, which is unknown to react 15. - */ }