From 8dec435e50ace23f7fcc947817fd28f93c2cf66a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Oct 2019 14:12:05 -0600 Subject: [PATCH 001/103] Bring breadcrumbs into new Riot config standard --- .../handlers/AccountSettingsHandler.js | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/settings/handlers/AccountSettingsHandler.js b/src/settings/handlers/AccountSettingsHandler.js index 71cef52c4e..1450bed494 100644 --- a/src/settings/handlers/AccountSettingsHandler.js +++ b/src/settings/handlers/AccountSettingsHandler.js @@ -19,7 +19,9 @@ import MatrixClientPeg from '../../MatrixClientPeg'; import MatrixClientBackedSettingsHandler from "./MatrixClientBackedSettingsHandler"; import {SettingLevel} from "../SettingsStore"; -const BREADCRUMBS_EVENT_TYPE = "im.vector.riot.breadcrumb_rooms"; +const BREADCRUMBS_LEGACY_EVENT_TYPE = "im.vector.riot.breadcrumb_rooms"; +const BREADCRUMBS_EVENT_TYPE = "im.vector.setting.breadcrumbs"; +const BREADCRUMBS_EVENT_TYPES = [BREADCRUMBS_LEGACY_EVENT_TYPE, BREADCRUMBS_EVENT_TYPE]; /** * Gets and sets settings at the "account" level for the current user. @@ -57,9 +59,8 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa const val = event.getContent()[settingName]; this._watchers.notifyUpdate(settingName, null, SettingLevel.ACCOUNT, val); } - } else if (event.getType() === BREADCRUMBS_EVENT_TYPE) { - const val = event.getContent()['rooms'] || []; - this._watchers.notifyUpdate("breadcrumb_rooms", null, SettingLevel.ACCOUNT, val); + } else if (BREADCRUMBS_EVENT_TYPES.includes(event.getType())) { + this._notifyBreadcrumbsUpdate(event); } } @@ -75,8 +76,15 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa // Special case for breadcrumbs if (settingName === "breadcrumb_rooms") { - const content = this._getSettings(BREADCRUMBS_EVENT_TYPE) || {}; - return content['rooms'] || []; + let content = this._getSettings(BREADCRUMBS_EVENT_TYPE); + if (!content || !content['recent_rooms']) { + content = this._getSettings(BREADCRUMBS_LEGACY_EVENT_TYPE); + + // This is a bit of a hack, but it makes things slightly easier + if (content) content['recent_rooms'] = content['rooms']; + } + + return content && content['recent_rooms'] ? content['recent_rooms'] : []; } const settings = this._getSettings() || {}; @@ -102,8 +110,13 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa // Special case for breadcrumbs if (settingName === "breadcrumb_rooms") { - const content = this._getSettings(BREADCRUMBS_EVENT_TYPE) || {}; - content['rooms'] = newValue; + // We read the value first just to make sure we preserve whatever random keys might be present. + let content = this._getSettings(BREADCRUMBS_EVENT_TYPE); + if (!content || !content['recent_rooms']) { + content = this._getSettings(BREADCRUMBS_LEGACY_EVENT_TYPE); + } + + content['recent_rooms'] = newValue; return MatrixClientPeg.get().setAccountData(BREADCRUMBS_EVENT_TYPE, content); } @@ -129,4 +142,19 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa if (!event || !event.getContent()) return null; return event.getContent(); } + + _notifyBreadcrumbsUpdate(event) { + let val = []; + if (event.getType() === BREADCRUMBS_LEGACY_EVENT_TYPE) { + // This seems fishy - try and get the event for the new rooms + const newType = this._getSettings(BREADCRUMBS_EVENT_TYPE); + if (newType) val = newType['recent_rooms']; + else val = event.getContent()['rooms']; + } else if (event.getType() === BREADCRUMBS_EVENT_TYPE) { + val = event.getContent()['recent_rooms']; + } else { + return; // for sanity, not because we expect to be here. + } + this._watchers.notifyUpdate("breadcrumb_rooms", null, SettingLevel.ACCOUNT, val || []); + } } From dd8f26a3f68e4ba4a6ae3d7861d3335ad2463c39 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Oct 2019 14:20:53 -0600 Subject: [PATCH 002/103] Add integration manager provisioning setting To be used later by a future implementation --- src/settings/Settings.js | 4 ++++ .../handlers/AccountSettingsHandler.js | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 7470641359..586ec7d1cf 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -279,6 +279,10 @@ export const SETTINGS = { supportedLevels: ['account'], default: [], }, + "integration_provisioning": { + supportedLevels: ['account'], + default: true, + }, "analyticsOptIn": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, displayName: _td('Send analytics data'), diff --git a/src/settings/handlers/AccountSettingsHandler.js b/src/settings/handlers/AccountSettingsHandler.js index 1450bed494..435c8f3388 100644 --- a/src/settings/handlers/AccountSettingsHandler.js +++ b/src/settings/handlers/AccountSettingsHandler.js @@ -23,6 +23,8 @@ const BREADCRUMBS_LEGACY_EVENT_TYPE = "im.vector.riot.breadcrumb_rooms"; const BREADCRUMBS_EVENT_TYPE = "im.vector.setting.breadcrumbs"; const BREADCRUMBS_EVENT_TYPES = [BREADCRUMBS_LEGACY_EVENT_TYPE, BREADCRUMBS_EVENT_TYPE]; +const INTEG_PROVISIONING_EVENT_TYPE = "im.vector.setting.integration_provisioning"; + /** * Gets and sets settings at the "account" level for the current user. * This handler does not make use of the roomId parameter. @@ -61,6 +63,9 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa } } else if (BREADCRUMBS_EVENT_TYPES.includes(event.getType())) { this._notifyBreadcrumbsUpdate(event); + } else if (event.getType() === INTEG_PROVISIONING_EVENT_TYPE) { + let val = event.getContent()['enabled']; + this._watchers.notifyUpdate("integration_provisioning", null, SettingLevel.ACCOUNT, val); } } @@ -87,6 +92,12 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa return content && content['recent_rooms'] ? content['recent_rooms'] : []; } + // Special case integration manager provisioning + if (settingName === "integration_provisioning") { + const content = this._getSettings(INTEG_PROVISIONING_EVENT_TYPE); + return content ? content['enabled'] : null; + } + const settings = this._getSettings() || {}; let preferredValue = settings[settingName]; @@ -120,6 +131,13 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa return MatrixClientPeg.get().setAccountData(BREADCRUMBS_EVENT_TYPE, content); } + // Special case integration manager provisioning + if (settingName === "integration_provisioning") { + const content = this._getSettings(INTEG_PROVISIONING_EVENT_TYPE) || {}; + content['enabled'] = newValue; + return MatrixClientPeg.get().setAccountData(INTEG_PROVISIONING_EVENT_TYPE, content); + } + const content = this._getSettings() || {}; content[settingName] = newValue; return MatrixClientPeg.get().setAccountData("im.vector.web.settings", content); From 3b771f682d1b5dd44358dfbd629b50b936e3d639 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Oct 2019 14:23:59 -0600 Subject: [PATCH 003/103] let -> const --- src/settings/handlers/AccountSettingsHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/handlers/AccountSettingsHandler.js b/src/settings/handlers/AccountSettingsHandler.js index 435c8f3388..7f05dc22c6 100644 --- a/src/settings/handlers/AccountSettingsHandler.js +++ b/src/settings/handlers/AccountSettingsHandler.js @@ -64,7 +64,7 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa } else if (BREADCRUMBS_EVENT_TYPES.includes(event.getType())) { this._notifyBreadcrumbsUpdate(event); } else if (event.getType() === INTEG_PROVISIONING_EVENT_TYPE) { - let val = event.getContent()['enabled']; + const val = event.getContent()['enabled']; this._watchers.notifyUpdate("integration_provisioning", null, SettingLevel.ACCOUNT, val); } } From 28e098832578f291e17bfd9d884880c7373e0fc0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Oct 2019 14:26:35 -0600 Subject: [PATCH 004/103] Fix naming of integrationProvisioning --- src/settings/Settings.js | 2 +- src/settings/handlers/AccountSettingsHandler.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 586ec7d1cf..54446a467b 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -279,7 +279,7 @@ export const SETTINGS = { supportedLevels: ['account'], default: [], }, - "integration_provisioning": { + "integrationProvisioning": { supportedLevels: ['account'], default: true, }, diff --git a/src/settings/handlers/AccountSettingsHandler.js b/src/settings/handlers/AccountSettingsHandler.js index 7f05dc22c6..f738bf7971 100644 --- a/src/settings/handlers/AccountSettingsHandler.js +++ b/src/settings/handlers/AccountSettingsHandler.js @@ -65,7 +65,7 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa this._notifyBreadcrumbsUpdate(event); } else if (event.getType() === INTEG_PROVISIONING_EVENT_TYPE) { const val = event.getContent()['enabled']; - this._watchers.notifyUpdate("integration_provisioning", null, SettingLevel.ACCOUNT, val); + this._watchers.notifyUpdate("integrationProvisioning", null, SettingLevel.ACCOUNT, val); } } @@ -93,7 +93,7 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa } // Special case integration manager provisioning - if (settingName === "integration_provisioning") { + if (settingName === "integrationProvisioning") { const content = this._getSettings(INTEG_PROVISIONING_EVENT_TYPE); return content ? content['enabled'] : null; } @@ -132,7 +132,7 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa } // Special case integration manager provisioning - if (settingName === "integration_provisioning") { + if (settingName === "integrationProvisioning") { const content = this._getSettings(INTEG_PROVISIONING_EVENT_TYPE) || {}; content['enabled'] = newValue; return MatrixClientPeg.get().setAccountData(INTEG_PROVISIONING_EVENT_TYPE, content); From 5af6d979c2f3ae13633ea1183a633d7ce0ec033d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Oct 2019 14:35:35 -0600 Subject: [PATCH 005/103] Support a setting for allowed widgets Hooking this setting up is left as a problem for a different issue. --- src/settings/Settings.js | 4 ++++ .../handlers/RoomAccountSettingsHandler.js | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 54446a467b..2220435cb9 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -283,6 +283,10 @@ export const SETTINGS = { supportedLevels: ['account'], default: true, }, + "allowedWidgets": { + supportedLevels: ['room-account'], + default: {}, // none allowed + }, "analyticsOptIn": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, displayName: _td('Send analytics data'), diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js index 3c8a1f9941..f3a3cb643d 100644 --- a/src/settings/handlers/RoomAccountSettingsHandler.js +++ b/src/settings/handlers/RoomAccountSettingsHandler.js @@ -19,6 +19,8 @@ import MatrixClientPeg from '../../MatrixClientPeg'; import MatrixClientBackedSettingsHandler from "./MatrixClientBackedSettingsHandler"; import {SettingLevel} from "../SettingsStore"; +const ALLOWED_WIDGETS_EVENT_TYPE = "im.vector.setting.allowed_widgets"; + /** * Gets and sets settings at the "room-account" level for the current user. */ @@ -58,6 +60,8 @@ export default class RoomAccountSettingsHandler extends MatrixClientBackedSettin const val = event.getContent()[settingName]; this._watchers.notifyUpdate(settingName, roomId, SettingLevel.ROOM_ACCOUNT, val); } + } else if (event.getType() === ALLOWED_WIDGETS_EVENT_TYPE) { + this._watchers.notifyUpdate("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, event.getContent()); } } @@ -79,6 +83,11 @@ export default class RoomAccountSettingsHandler extends MatrixClientBackedSettin return this._getSettings(roomId, "org.matrix.room.color_scheme"); } + // Special case allowed widgets + if (settingName === "allowedWidgets") { + return this._getSettings(roomId, ALLOWED_WIDGETS_EVENT_TYPE); + } + const settings = this._getSettings(roomId) || {}; return settings[settingName]; } @@ -97,6 +106,11 @@ export default class RoomAccountSettingsHandler extends MatrixClientBackedSettin return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.color_scheme", newValue); } + // Special case allowed widgets + if (settingName === "allowedWidgets") { + return return MatrixClientPeg.get().setRoomAccountData(roomId, ALLOWED_WIDGETS_EVENT_TYPE, newValue); + } + const content = this._getSettings(roomId) || {}; content[settingName] = newValue; return MatrixClientPeg.get().setRoomAccountData(roomId, "im.vector.web.settings", content); From 9d0d1d3b36bac8448660e37ea105bc85a1b6c278 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Oct 2019 14:38:39 -0600 Subject: [PATCH 006/103] Our code should probably compile... --- src/settings/handlers/RoomAccountSettingsHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js index f3a3cb643d..0206711db2 100644 --- a/src/settings/handlers/RoomAccountSettingsHandler.js +++ b/src/settings/handlers/RoomAccountSettingsHandler.js @@ -108,7 +108,7 @@ export default class RoomAccountSettingsHandler extends MatrixClientBackedSettin // Special case allowed widgets if (settingName === "allowedWidgets") { - return return MatrixClientPeg.get().setRoomAccountData(roomId, ALLOWED_WIDGETS_EVENT_TYPE, newValue); + return MatrixClientPeg.get().setRoomAccountData(roomId, ALLOWED_WIDGETS_EVENT_TYPE, newValue); } const content = this._getSettings(roomId) || {}; From 35b81c8e735bfc6666f296c1c978c1c038f13757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Wed, 30 Oct 2019 14:11:46 +0000 Subject: [PATCH 007/103] Translated using Weblate (French) Currently translated at 100.0% (1850 of 1850 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 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index af6634992f..0e8f00e9c4 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2273,5 +2273,8 @@ "Jump to first invite.": "Sauter à la première invitation.", "Room %(name)s": "Salon %(name)s", "Recent rooms": "Salons récents", - "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Aucun serveur d’identité n’est configuré donc vous ne pouvez pas ajouter une adresse e-mail afin de réinitialiser votre mot de passe dans l’avenir." + "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Aucun serveur d’identité n’est configuré donc vous ne pouvez pas ajouter une adresse e-mail afin de réinitialiser votre mot de passe dans l’avenir.", + "%(count)s unread messages including mentions.|one": "1 mention non lue.", + "%(count)s unread messages.|one": "1 message non lu.", + "Unread messages.": "Messages non lus." } From 8dfa4642028e12b57cfd54cfcc29673d54962f2e Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 30 Oct 2019 16:44:18 +0000 Subject: [PATCH 008/103] js-sdk rc.1 --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e709662020..f8aa8db588 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", + "matrix-js-sdk": "2.4.3-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 aa0a06e588..bc3ee0282f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5192,9 +5192,10 @@ mathml-tag-names@^2.0.1: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" integrity sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw== -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": - version "2.4.2" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/46d7e4c7075386f1330d6a49941e9979fc26be0a" +matrix-js-sdk@2.4.3-rc.1: + version "2.4.3-rc.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.3-rc.1.tgz#c06452b89c74976ac0bae0732325c0b359e6f2fa" + integrity sha512-aV70H10lSpjAOmnWDXIWc2CP5D1OylwSSfyc61QzjvGhECEYaiQi4rxH4ZFhX9AL3ezPHse7SY6AmKOCfqBQiw== dependencies: another-json "^0.2.0" babel-runtime "^6.26.0" From 5797b654db17e80bcf11e69ca3a36d0f4d653013 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 30 Oct 2019 16:47:26 +0000 Subject: [PATCH 009/103] Prepare changelog for v1.7.1-rc.1 --- CHANGELOG.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b95cc03595..1d8998ecbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,82 @@ +Changes in [1.7.1-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.1-rc.1) (2019-10-30) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.0...v1.7.1-rc.1) + + * Add ability to hide tray icon on non-Mac + [\#3573](https://github.com/matrix-org/matrix-react-sdk/pull/3573) + * Update from Weblate + [\#3579](https://github.com/matrix-org/matrix-react-sdk/pull/3579) + * Fix call state logging + [\#3578](https://github.com/matrix-org/matrix-react-sdk/pull/3578) + * Match widgets up with their integration manager + [\#3576](https://github.com/matrix-org/matrix-react-sdk/pull/3576) + * Add diagnostic log to catch events without an ID + [\#3575](https://github.com/matrix-org/matrix-react-sdk/pull/3575) + * Fix missing i18n for RoomTile ARIA labels and add a case for notif-off bold + [\#3574](https://github.com/matrix-org/matrix-react-sdk/pull/3574) + * LifeCycle onLoggedOut unmount before stopping client + [\#3566](https://github.com/matrix-org/matrix-react-sdk/pull/3566) + * Remove unneeded help about identity servers + [\#3572](https://github.com/matrix-org/matrix-react-sdk/pull/3572) + * Remove messages implying you need an identity server for email recovery + [\#3571](https://github.com/matrix-org/matrix-react-sdk/pull/3571) + * Fix quick reactions to be aligned with other emoji + [\#3570](https://github.com/matrix-org/matrix-react-sdk/pull/3570) + * If ToS gets rejected/any Scalar error then don't make Jitsi widget + [\#3569](https://github.com/matrix-org/matrix-react-sdk/pull/3569) + * Update from Weblate + [\#3568](https://github.com/matrix-org/matrix-react-sdk/pull/3568) + * Fix Room Create ELS using MXID instead of newly set Displayname/Avatar + [\#3567](https://github.com/matrix-org/matrix-react-sdk/pull/3567) + * Improve opening emoji picker performance + [\#3565](https://github.com/matrix-org/matrix-react-sdk/pull/3565) + * Update ServerTypeSelector for new matrix.org CS API URL + [\#3564](https://github.com/matrix-org/matrix-react-sdk/pull/3564) + * Accessibility Improvements + [\#3563](https://github.com/matrix-org/matrix-react-sdk/pull/3563) + * A11Y fixes in the Left Panel + [\#3562](https://github.com/matrix-org/matrix-react-sdk/pull/3562) + * Fix lint and i18n test failures + [\#3560](https://github.com/matrix-org/matrix-react-sdk/pull/3560) + * Fix: editor tests + [\#3561](https://github.com/matrix-org/matrix-react-sdk/pull/3561) + * Use Navigation Treeview pattern for RoomList Accessibility + [\#3556](https://github.com/matrix-org/matrix-react-sdk/pull/3556) + * Abort scroll updates when already unmounted + [\#3557](https://github.com/matrix-org/matrix-react-sdk/pull/3557) + * UserInfo consolidation of GroupMemberInfo and MemberInfo panels + [\#3465](https://github.com/matrix-org/matrix-react-sdk/pull/3465) + * Fix some things in the edit HTML parser + [\#3552](https://github.com/matrix-org/matrix-react-sdk/pull/3552) + * Update from Weblate + [\#3559](https://github.com/matrix-org/matrix-react-sdk/pull/3559) + * Merge end-to-end tests + [\#3537](https://github.com/matrix-org/matrix-react-sdk/pull/3537) + * Add full emoji picker for reactions + [\#3554](https://github.com/matrix-org/matrix-react-sdk/pull/3554) + * Accessibility fixes to autocomplete and tabpanels + [\#3555](https://github.com/matrix-org/matrix-react-sdk/pull/3555) + * Show warning dialog when changing unreachable IS + [\#3549](https://github.com/matrix-org/matrix-react-sdk/pull/3549) + * Fix reply fallback being included in edit m.new_content + [\#3551](https://github.com/matrix-org/matrix-react-sdk/pull/3551) + * Document composer features + [\#3548](https://github.com/matrix-org/matrix-react-sdk/pull/3548) + * Correctly update the banned users list when a user is unbanned + [\#3547](https://github.com/matrix-org/matrix-react-sdk/pull/3547) + * Summarise state events after room creation + [\#3433](https://github.com/matrix-org/matrix-react-sdk/pull/3433) + * Don't intercept TAB on the app outside of the composer, fix tabIndex > 0 + [\#3543](https://github.com/matrix-org/matrix-react-sdk/pull/3543) + * Add some type checking on event body + [\#3546](https://github.com/matrix-org/matrix-react-sdk/pull/3546) + * Fix: crash while canceling editing an event when no selection + [\#3544](https://github.com/matrix-org/matrix-react-sdk/pull/3544) + * SettingsFlag always run ToggleSwitch fully-controlled + [\#3541](https://github.com/matrix-org/matrix-react-sdk/pull/3541) + * Use Keyboard Key consts instead of hardcoded strings + [\#3540](https://github.com/matrix-org/matrix-react-sdk/pull/3540) + Changes in [1.7.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.0) (2019-10-18) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.0-rc.1...v1.7.0) From 60731dabf4203f834792a02a606b9e89dc958362 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 30 Oct 2019 16:47:27 +0000 Subject: [PATCH 010/103] v1.7.1-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f8aa8db588..865efab2c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.0", + "version": "1.7.1-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 425ecc2fbb3c5c012a9143de1f27fa3027b31d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 31 Oct 2019 11:25:44 +0000 Subject: [PATCH 011/103] Translated using Weblate (French) Currently translated at 100.0% (1850 of 1850 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 0e8f00e9c4..20f88e4d08 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2276,5 +2276,6 @@ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Aucun serveur d’identité n’est configuré donc vous ne pouvez pas ajouter une adresse e-mail afin de réinitialiser votre mot de passe dans l’avenir.", "%(count)s unread messages including mentions.|one": "1 mention non lue.", "%(count)s unread messages.|one": "1 message non lu.", - "Unread messages.": "Messages non lus." + "Unread messages.": "Messages non lus.", + "Show tray icon and minimize window to it on close": "Afficher l’icône dans la barre d’état et minimiser la fenêtre lors de la fermeture" } From 4ed253b33d2de52e31c061eb2d8d4cb59fbd892d Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 30 Oct 2019 22:08:00 +0000 Subject: [PATCH 012/103] Translated using Weblate (Hungarian) Currently translated at 100.0% (1850 of 1850 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index dc8c42b109..d901ff4d85 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2263,5 +2263,6 @@ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Azonosítási szerver nincs beállítva, így nem tudsz hozzáadni e-mail címet amivel vissza lehetne állítani a jelszót a későbbiekben.", "%(count)s unread messages including mentions.|one": "1 olvasatlan megemlítés.", "%(count)s unread messages.|one": "1 olvasatlan üzenet.", - "Unread messages.": "Olvasatlan üzenetek." + "Unread messages.": "Olvasatlan üzenetek.", + "Show tray icon and minimize window to it on close": "Tálcaikon mutatása és az ablak összecsukása bezáráskor" } From 3a1b065da2e0786e3904dd6e1bc6b6fe563ff071 Mon Sep 17 00:00:00 2001 From: Tim Stahel Date: Thu, 31 Oct 2019 09:49:30 +0000 Subject: [PATCH 013/103] Translated using Weblate (Swedish) Currently translated at 77.7% (1437 of 1850 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index f322affd1b..5c98ea50ba 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -1812,5 +1812,7 @@ "Connect this device to Key Backup": "Anslut den här enheten till nyckelsäkerhetskopiering", "Backing up %(sessionsRemaining)s keys...": "Säkerhetskopierar %(sessionsRemaining)s nycklar...", "All keys backed up": "Alla nycklar säkerhetskopierade", - "Backup has a signature from unknown device with ID %(deviceId)s.": "Säkerhetskopian har en signatur från okänd enhet med ID %(deviceId)s." + "Backup has a signature from unknown device with ID %(deviceId)s.": "Säkerhetskopian har en signatur från okänd enhet med ID %(deviceId)s.", + "Add Email Address": "Lägg till e-postadress", + "Add Phone Number": "Lägg till telefonnummer" } From 0fc51088175db7092e948d69c0c2f0e88eb5df0f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Oct 2019 11:58:31 +0000 Subject: [PATCH 014/103] Add a prompt when interacting with an identity server without terms This adds a prompt whenever we are about to perform some action on a default identity server (from homeserver .well-known or Riot app config) without terms. This allows the user to abort or trust the server (storing it in account data). Fixes https://github.com/vector-im/riot-web/issues/10557 --- src/IdentityAuthClient.js | 54 +++++++++++++++++++- src/components/views/settings/SetIdServer.js | 18 ++----- src/i18n/strings/en_EN.json | 6 ++- src/utils/IdentityServerUtils.js | 22 ++++++++ 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js index 7cbad074bf..563e5e0441 100644 --- a/src/IdentityAuthClient.js +++ b/src/IdentityAuthClient.js @@ -17,7 +17,18 @@ limitations under the License. import { createClient, SERVICE_TYPES } from 'matrix-js-sdk'; import MatrixClientPeg from './MatrixClientPeg'; +import Modal from './Modal'; +import sdk from './index'; +import { _t } from './languageHandler'; import { Service, startTermsFlow, TermsNotSignedError } from './Terms'; +import { + doesAccountDataHaveIdentityServer, + doesIdentityServerHaveTerms, + useDefaultIdentityServer, +} from './utils/IdentityServerUtils'; +import { abbreviateUrl } from './utils/UrlUtils'; + +export class AbortedIdentityActionError extends Error {} export default class IdentityAuthClient { /** @@ -89,7 +100,10 @@ export default class IdentityAuthClient { try { await this._checkToken(token); } catch (e) { - if (e instanceof TermsNotSignedError) { + if ( + e instanceof TermsNotSignedError || + e instanceof AbortedIdentityActionError + ) { // Retrying won't help this throw e; } @@ -106,6 +120,8 @@ export default class IdentityAuthClient { } async _checkToken(token) { + const identityServerUrl = this._matrixClient.getIdentityServerUrl(); + try { await this._matrixClient.getIdentityAccount(token); } catch (e) { @@ -113,7 +129,7 @@ export default class IdentityAuthClient { console.log("Identity Server requires new terms to be agreed to"); await startTermsFlow([new Service( SERVICE_TYPES.IS, - this._matrixClient.getIdentityServerUrl(), + identityServerUrl, token, )]); return; @@ -121,6 +137,40 @@ export default class IdentityAuthClient { throw e; } + if ( + !this.tempClient && + !doesAccountDataHaveIdentityServer() && + !await doesIdentityServerHaveTerms(identityServerUrl) + ) { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const { finished } = Modal.createTrackedDialog('Default identity server terms warning', '', + QuestionDialog, { + title: _t("Identity server has no terms of service"), + description:
+

{_t( + "This action requires accessing the default identity server " + + " to validate an email address or phone number, but the server " + + "does not have any terms of service.", {}, + { + server: () => {abbreviateUrl(identityServerUrl)}, + }, + )}

+

{_t( + "Only continue if you trust the owner of the server.", + )}

+
, + button: _t("Trust"), + }); + const [confirmed] = await finished; + if (confirmed) { + useDefaultIdentityServer(); + } else { + throw new AbortedIdentityActionError( + "User aborted identity server action without terms", + ); + } + } + // We should ensure the token in `localStorage` is cleared // appropriately. We already clear storage on sign out, but we'll need // additional clearing when changing ISes in settings as part of future diff --git a/src/components/views/settings/SetIdServer.js b/src/components/views/settings/SetIdServer.js index 7f4a50d391..126cdc9557 100644 --- a/src/components/views/settings/SetIdServer.js +++ b/src/components/views/settings/SetIdServer.js @@ -24,9 +24,8 @@ import Modal from '../../../Modal'; import dis from "../../../dispatcher"; import { getThreepidsWithBindStatus } from '../../../boundThreepids'; import IdentityAuthClient from "../../../IdentityAuthClient"; -import {SERVICE_TYPES} from "matrix-js-sdk"; import {abbreviateUrl, unabbreviateUrl} from "../../../utils/UrlUtils"; -import { getDefaultIdentityServerUrl } from '../../../utils/IdentityServerUtils'; +import { getDefaultIdentityServerUrl, doesIdentityServerHaveTerms } from '../../../utils/IdentityServerUtils'; // We'll wait up to this long when checking for 3PID bindings on the IS. const REACHABILITY_TIMEOUT = 10000; // ms @@ -162,19 +161,8 @@ export default class SetIdServer extends React.Component { let save = true; // Double check that the identity server even has terms of service. - let terms; - try { - terms = await MatrixClientPeg.get().getTerms(SERVICE_TYPES.IS, fullUrl); - } catch (e) { - console.error(e); - if (e.cors === "rejected" || e.httpStatus === 404) { - terms = null; - } else { - throw e; - } - } - - if (!terms || !terms["policies"] || Object.keys(terms["policies"]).length <= 0) { + const hasTerms = await doesIdentityServerHaveTerms(fullUrl); + if (!hasTerms) { const [confirmed] = await this._showNoTermsWarning(fullUrl); save = confirmed; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 31602d2dab..69f68b2497 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -99,6 +99,10 @@ "Failed to invite users to %(groupId)s": "Failed to invite users to %(groupId)s", "Failed to add the following rooms to %(groupId)s:": "Failed to add the following rooms to %(groupId)s:", "Unnamed Room": "Unnamed Room", + "Identity server has no terms of service": "Identity server has no terms of service", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.", + "Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.", + "Trust": "Trust", "Error": "Error", "Unable to load! Check your network connectivity and try again.": "Unable to load! Check your network connectivity and try again.", "Dismiss": "Dismiss", @@ -563,9 +567,7 @@ "Change identity server": "Change identity server", "Disconnect from the identity server and connect to instead?": "Disconnect from the identity server and connect to instead?", "Terms of service not accepted or the identity server is invalid.": "Terms of service not accepted or the identity server is invalid.", - "Identity server has no terms of service": "Identity server has no terms of service", "The identity server you have chosen does not have any terms of service.": "The identity server you have chosen does not have any terms of service.", - "Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.", "Disconnect identity server": "Disconnect identity server", "Disconnect from the identity server ?": "Disconnect from the identity server ?", "Disconnect": "Disconnect", diff --git a/src/utils/IdentityServerUtils.js b/src/utils/IdentityServerUtils.js index 883bd52149..cf180e3026 100644 --- a/src/utils/IdentityServerUtils.js +++ b/src/utils/IdentityServerUtils.js @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { SERVICE_TYPES } from 'matrix-js-sdk'; import SdkConfig from '../SdkConfig'; import MatrixClientPeg from '../MatrixClientPeg'; @@ -28,3 +29,24 @@ export function useDefaultIdentityServer() { base_url: url, }); } + +export async function doesIdentityServerHaveTerms(fullUrl) { + let terms; + try { + terms = await MatrixClientPeg.get().getTerms(SERVICE_TYPES.IS, fullUrl); + } catch (e) { + console.error(e); + if (e.cors === "rejected" || e.httpStatus === 404) { + terms = null; + } else { + throw e; + } + } + + return terms && terms["policies"] && (Object.keys(terms["policies"]).length > 0); +} + +export function doesAccountDataHaveIdentityServer() { + const event = MatrixClientPeg.get().getAccountData("m.identity_server"); + return event && event.getContent() && event.getContent()['base_url']; +} From 3f5b7b3b92e8a2e5bac4f9bfd9e9863bb8bba01a Mon Sep 17 00:00:00 2001 From: random Date: Thu, 31 Oct 2019 14:26:14 +0000 Subject: [PATCH 015/103] Translated using Weblate (Italian) Currently translated at 100.0% (1850 of 1850 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 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index f1f66b44d2..6262315012 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2223,5 +2223,6 @@ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Nessun server di identità configurato, perciò non puoi aggiungere un indirizzo email per ripristinare la tua password in futuro.", "%(count)s unread messages including mentions.|one": "1 citazione non letta.", "%(count)s unread messages.|one": "1 messaggio non letto.", - "Unread messages.": "Messaggi non letti." + "Unread messages.": "Messaggi non letti.", + "Show tray icon and minimize window to it on close": "Mostra icona in tray e usala alla chiusura della finestra" } From 7d6643664e334e4ff3c8576ccc273bc95b1890d0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 31 Oct 2019 19:42:41 +0000 Subject: [PATCH 016/103] Fix bug where rooms would not appear when filtering We need to reset the scroll offset otherwise the component may be scrolled past the only content it has (Chrome just corrected the scroll offset but Firefox scrolled it anyway). NB. Introducing the new deriveStateFromProps method seems to means that react no longer calls componentWillMount so I've had to change it to componentDidMount (which it should have been anyway). Fixes https://github.com/vector-im/riot-web/issues/11263 --- src/components/structures/RoomSubList.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js index 0bb5c9e9be..921680b678 100644 --- a/src/components/structures/RoomSubList.js +++ b/src/components/structures/RoomSubList.js @@ -67,6 +67,9 @@ const RoomSubList = createReactClass({ // some values to get LazyRenderList starting scrollerHeight: 800, scrollTop: 0, + // React 16's getDerivedStateFromProps(props, state) doesn't give the previous props so + // we have to store the length of the list here so we can see if it's changed or not... + listLength: null, }; }, @@ -79,11 +82,20 @@ const RoomSubList = createReactClass({ }; }, - componentWillMount: function() { + componentDidMount: function() { this._headerButton = createRef(); this.dispatcherRef = dis.register(this.onAction); }, + statics: { + getDerivedStateFromProps: function(props, state) { + return { + listLength: props.list.length, + scrollTop: props.list.length === state.listLength ? state.scrollTop : 0, + }; + }, + }, + componentWillUnmount: function() { dis.unregister(this.dispatcherRef); }, From 28d72840ec771d2abd48a1d31850c9c842c31bb5 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Fri, 1 Nov 2019 04:19:08 +0000 Subject: [PATCH 017/103] Translated using Weblate (Lithuanian) Currently translated at 44.0% (814 of 1850 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index d7f5e2bf74..6a8076ac96 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -181,7 +181,7 @@ "%(count)s Members|one": "%(count)s narys", "Developer Tools": "Programuotojo įrankiai", "Unhide Preview": "Rodyti paržiūrą", - "Custom Server Options": "Tinkinto serverio parametrai", + "Custom Server Options": "Pasirinktiniai Serverio Nustatymai", "Event Content": "Įvykio turinys", "Thank you!": "Ačiū!", "Collapse panel": "Suskleisti skydelį", @@ -997,5 +997,8 @@ "Whether or not you're logged in (we don't record your username)": "Nepriklausomai nuo to ar jūs prisijungę (mes neįrašome jūsų vartotojo vardo)", "Chat with Riot Bot": "Kalbėtis su Riot botu", "Sign In": "Prisijungti", - "Explore rooms": "Peržiūrėti kambarius" + "Explore rooms": "Peržiūrėti kambarius", + "Your Riot is misconfigured": "Jūsų Riot yra neteisingai sukonfigūruotas", + "Sign in to your Matrix account on %(serverName)s": "Prisijunkite prie savo paskyros %(serverName)s serveryje", + "Sign in to your Matrix account on ": "Prisijunkite prie savo paskyros serveryje" } From 6aa96ef82f6fbe28321afa6cb64fe3cc12592ae6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 31 Oct 2019 19:42:41 +0000 Subject: [PATCH 018/103] Fix bug where rooms would not appear when filtering We need to reset the scroll offset otherwise the component may be scrolled past the only content it has (Chrome just corrected the scroll offset but Firefox scrolled it anyway). NB. Introducing the new deriveStateFromProps method seems to means that react no longer calls componentWillMount so I've had to change it to componentDidMount (which it should have been anyway). Fixes https://github.com/vector-im/riot-web/issues/11263 --- src/components/structures/RoomSubList.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js index 0bb5c9e9be..921680b678 100644 --- a/src/components/structures/RoomSubList.js +++ b/src/components/structures/RoomSubList.js @@ -67,6 +67,9 @@ const RoomSubList = createReactClass({ // some values to get LazyRenderList starting scrollerHeight: 800, scrollTop: 0, + // React 16's getDerivedStateFromProps(props, state) doesn't give the previous props so + // we have to store the length of the list here so we can see if it's changed or not... + listLength: null, }; }, @@ -79,11 +82,20 @@ const RoomSubList = createReactClass({ }; }, - componentWillMount: function() { + componentDidMount: function() { this._headerButton = createRef(); this.dispatcherRef = dis.register(this.onAction); }, + statics: { + getDerivedStateFromProps: function(props, state) { + return { + listLength: props.list.length, + scrollTop: props.list.length === state.listLength ? state.scrollTop : 0, + }; + }, + }, + componentWillUnmount: function() { dis.unregister(this.dispatcherRef); }, From bc7da4f6c8fab44ac6e90a5f6a1a629026bbb719 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 1 Nov 2019 10:17:53 +0000 Subject: [PATCH 019/103] Prepare changelog for v1.7.1-rc.2 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d8998ecbe..b4e97b737c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [1.7.1-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.1-rc.2) (2019-11-01) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.1-rc.1...v1.7.1-rc.2) + + * Fix bug where rooms would not appear when filtering + [\#3586](https://github.com/matrix-org/matrix-react-sdk/pull/3586) + Changes in [1.7.1-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.1-rc.1) (2019-10-30) ============================================================================================================= [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.0...v1.7.1-rc.1) From 050ef95cd6676bdd90e558ed79b2c454fb0e6bc7 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 1 Nov 2019 10:17:54 +0000 Subject: [PATCH 020/103] v1.7.1-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 865efab2c2..0bd712df7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.1-rc.1", + "version": "1.7.1-rc.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From fd4cdd0dec78d2ea3085ab8b752a394c3f08bea9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 1 Nov 2019 10:50:58 +0000 Subject: [PATCH 021/103] Improve A11Y of timeline. Show TS & Actions on focus-within --- res/css/views/rooms/_EventTile.scss | 7 ++++++- src/components/views/messages/DateSeparator.js | 2 +- src/components/views/messages/MessageActionBar.js | 3 ++- src/components/views/messages/MessageTimestamp.js | 2 +- src/components/views/rooms/EventTile.js | 9 +++++++-- src/i18n/strings/en_EN.json | 1 + 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index fafd34f8ca..a30b219016 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -138,11 +138,13 @@ limitations under the License. // Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile_last > div > a > .mx_MessageTimestamp, .mx_EventTile:hover > div > a > .mx_MessageTimestamp, +.mx_EventTile:focus-within > div > a > .mx_MessageTimestamp, .mx_EventTile.mx_EventTile_actionBarFocused > div > a > .mx_MessageTimestamp { visibility: visible; } .mx_EventTile:hover .mx_MessageActionBar, +.mx_EventTile:focus-within .mx_MessageActionBar, .mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar { visibility: visible; } @@ -166,6 +168,7 @@ limitations under the License. } .mx_EventTile:hover .mx_EventTile_line, +.mx_EventTile:focus-within .mx_EventTile_line, .mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line { background-color: $event-selected-color; } @@ -465,7 +468,8 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { } } -.mx_EventTile:hover .mx_EventTile_body pre { +.mx_EventTile:hover .mx_EventTile_body pre, +.mx_EventTile:focus-within .mx_EventTile_body pre { border: 1px solid #e5e5e5; // deliberate constant as we're behind an invert filter } @@ -487,6 +491,7 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { background-image: url($copy-button-url); } +.mx_EventTile_body .mx_EventTile_pre_container:focus-within .mx_EventTile_copyButton, .mx_EventTile_body .mx_EventTile_pre_container:hover .mx_EventTile_copyButton { visibility: visible; } diff --git a/src/components/views/messages/DateSeparator.js b/src/components/views/messages/DateSeparator.js index 900fd61914..88b59d0c26 100644 --- a/src/components/views/messages/DateSeparator.js +++ b/src/components/views/messages/DateSeparator.js @@ -57,7 +57,7 @@ export default class DateSeparator extends React.Component { render() { // ARIA treats
s as separators, here we abuse them slightly so manually treat this entire thing as one - return

+ return


{ this.getLabel() }

diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index 565c66410e..acd8263410 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -180,7 +180,8 @@ export default class MessageActionBar extends React.PureComponent { />; } - return
+ // aria-live=off to not have this read out automatically as navigating around timeline, gets repetitive. + return
{reactButton} {replyButton} {editButton} diff --git a/src/components/views/messages/MessageTimestamp.js b/src/components/views/messages/MessageTimestamp.js index 0bbb3f631e..199a6f47ce 100644 --- a/src/components/views/messages/MessageTimestamp.js +++ b/src/components/views/messages/MessageTimestamp.js @@ -28,7 +28,7 @@ export default class MessageTimestamp extends React.Component { render() { const date = new Date(this.props.ts); return ( - + { formatTime(date, this.props.showTwelveHour) } ); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index ca83dd1814..bc502d0674 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -32,6 +32,7 @@ const TextForEvent = require('../../../TextForEvent'); import dis from '../../../dispatcher'; import SettingsStore from "../../../settings/SettingsStore"; import {EventStatus, MatrixClient} from 'matrix-js-sdk'; +import {formatTime} from "../../../DateUtils"; const ObjectUtils = require('../../../ObjectUtils'); @@ -787,13 +788,17 @@ module.exports = createReactClass({ 'replyThread', ); return ( -
+
{ readAvatars }
{ sender }
- + { timestamp } { this._renderE2EPadlock() } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 524a8a1abf..86521f2594 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1053,6 +1053,7 @@ "React": "React", "Reply": "Reply", "Edit": "Edit", + "Message Actions": "Message Actions", "Options": "Options", "Attachment": "Attachment", "Error decrypting attachment": "Error decrypting attachment", From 10a63ada48ec5dc9b7cfeeb324a97f5404a80611 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 1 Nov 2019 14:46:30 +0000 Subject: [PATCH 022/103] Fix SVG mask-image usage in a bunch of places for correct outlining --- res/css/structures/_GroupView.scss | 18 +++++++++++---- res/css/structures/_RightPanel.scss | 22 +++++++++--------- res/css/views/rooms/_MessageComposer.scss | 28 +++++++++++++++-------- res/css/views/rooms/_RoomHeader.scss | 27 ++++++++++++++-------- 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/res/css/structures/_GroupView.scss b/res/css/structures/_GroupView.scss index ae86f68fd0..4ec53a3c9a 100644 --- a/res/css/structures/_GroupView.scss +++ b/res/css/structures/_GroupView.scss @@ -44,21 +44,29 @@ limitations under the License. } .mx_GroupHeader_button { + position: relative; margin-left: 5px; margin-right: 5px; cursor: pointer; height: 20px; width: 20px; - background-color: $groupheader-button-color; - mask-repeat: no-repeat; - mask-size: contain; + + &::before { + content: ''; + position: absolute; + height: 20px; + width: 20px; + background-color: $groupheader-button-color; + mask-repeat: no-repeat; + mask-size: contain; + } } -.mx_GroupHeader_editButton { +.mx_GroupHeader_editButton::before { mask-image: url('$(res)/img/icons-settings-room.svg'); } -.mx_GroupHeader_shareButton { +.mx_GroupHeader_shareButton::before { mask-image: url('$(res)/img/icons-share.svg'); } diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss index c63db5d274..973f6fe9b3 100644 --- a/res/css/structures/_RightPanel.scss +++ b/res/css/structures/_RightPanel.scss @@ -50,18 +50,18 @@ limitations under the License. height: 20px; width: 20px; position: relative; -} -.mx_RightPanel_headerButton::before { - content: ''; - position: absolute; - top: 0; - left: 0; - height: 20px; - width: 20px; - background-color: $rightpanel-button-color; - mask-repeat: no-repeat; - mask-size: contain; + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + height: 20px; + width: 20px; + background-color: $rightpanel-button-color; + mask-repeat: no-repeat; + mask-size: contain; + } } .mx_RightPanel_membersButton::before { diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 5b4a9b764b..e9f33183f5 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -180,34 +180,42 @@ limitations under the License. } .mx_MessageComposer_button { + position: relative; margin-right: 12px; cursor: pointer; - padding-top: 4px; height: 20px; width: 20px; - background-color: $composer-button-color; - mask-repeat: no-repeat; - mask-size: contain; - mask-position: center; + + &::before { + content: ''; + position: absolute; + + height: 20px; + width: 20px; + background-color: $composer-button-color; + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + } } -.mx_MessageComposer_upload { +.mx_MessageComposer_upload::before { mask-image: url('$(res)/img/feather-customised/paperclip.svg'); } -.mx_MessageComposer_hangup { +.mx_MessageComposer_hangup::before { mask-image: url('$(res)/img/hangup.svg'); } -.mx_MessageComposer_voicecall { +.mx_MessageComposer_voicecall::before { mask-image: url('$(res)/img/feather-customised/phone.svg'); } -.mx_MessageComposer_videocall { +.mx_MessageComposer_videocall::before { mask-image: url('$(res)/img/feather-customised/video.svg'); } -.mx_MessageComposer_stickers { +.mx_MessageComposer_stickers::before { mask-image: url('$(res)/img/feather-customised/face.svg'); } diff --git a/res/css/views/rooms/_RoomHeader.scss b/res/css/views/rooms/_RoomHeader.scss index 2ee991cac7..5da8ff76b9 100644 --- a/res/css/views/rooms/_RoomHeader.scss +++ b/res/css/views/rooms/_RoomHeader.scss @@ -192,33 +192,41 @@ limitations under the License. } .mx_RoomHeader_button { + position: relative; margin-left: 10px; cursor: pointer; height: 20px; width: 20px; - background-color: $roomheader-button-color; - mask-repeat: no-repeat; - mask-size: contain; + + &::before { + content: ''; + position: absolute; + height: 20px; + width: 20px; + background-color: $roomheader-button-color; + mask-repeat: no-repeat; + mask-size: contain; + } } -.mx_RoomHeader_settingsButton { +.mx_RoomHeader_settingsButton::before { mask-image: url('$(res)/img/feather-customised/settings.svg'); } -.mx_RoomHeader_forgetButton { +.mx_RoomHeader_forgetButton::before { mask-image: url('$(res)/img/leave.svg'); width: 26px; } -.mx_RoomHeader_searchButton { +.mx_RoomHeader_searchButton::before { mask-image: url('$(res)/img/feather-customised/search.svg'); } -.mx_RoomHeader_shareButton { +.mx_RoomHeader_shareButton::before { mask-image: url('$(res)/img/feather-customised/share.svg'); } -.mx_RoomHeader_manageIntegsButton { +.mx_RoomHeader_manageIntegsButton::before { mask-image: url('$(res)/img/feather-customised/grid.svg'); } @@ -234,8 +242,7 @@ limitations under the License. margin-top: 18px; } -.mx_RoomHeader_pinnedButton { - position: relative; +.mx_RoomHeader_pinnedButton::before { mask-image: url('$(res)/img/icons-pin.svg'); } From 0c82d9e7e0c85db359c7917bc50c83e689078dc7 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 1 Nov 2019 16:35:16 +0000 Subject: [PATCH 023/103] Align start and end tags --- src/IdentityAuthClient.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js index 563e5e0441..f21db12c51 100644 --- a/src/IdentityAuthClient.js +++ b/src/IdentityAuthClient.js @@ -146,19 +146,21 @@ export default class IdentityAuthClient { const { finished } = Modal.createTrackedDialog('Default identity server terms warning', '', QuestionDialog, { title: _t("Identity server has no terms of service"), - description:
-

{_t( - "This action requires accessing the default identity server " + - " to validate an email address or phone number, but the server " + - "does not have any terms of service.", {}, - { - server: () => {abbreviateUrl(identityServerUrl)}, - }, - )}

-

{_t( - "Only continue if you trust the owner of the server.", - )}

-
, + description: ( +
+

{_t( + "This action requires accessing the default identity server " + + " to validate an email address or phone number, " + + "but the server does not have any terms of service.", {}, + { + server: () => {abbreviateUrl(identityServerUrl)}, + }, + )}

+

{_t( + "Only continue if you trust the owner of the server.", + )}

+
+ ), button: _t("Trust"), }); const [confirmed] = await finished; From a8b89840a34bc0f1754bc013db1fe8933884dd30 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 1 Nov 2019 09:21:09 +0000 Subject: [PATCH 024/103] Translated using Weblate (Basque) Currently translated at 100.0% (1850 of 1850 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index ef2dd9fe8b..72b6fff50d 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -2188,5 +2188,39 @@ "Emoji Autocomplete": "Emoji osatze automatikoa", "Notification Autocomplete": "Jakinarazpen osatze automatikoa", "Room Autocomplete": "Gela osatze automatikoa", - "User Autocomplete": "Erabiltzaile osatze automatikoa" + "User Autocomplete": "Erabiltzaile osatze automatikoa", + "Use the new, consistent UserInfo panel for Room Members and Group Members": "Erabili erabiltzaile-informazio panel berria gelako eta taldeko kideentzat", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Zure datu pribatuak kendu beharko zenituzke identitate-zerbitzaritik deskonektatu aurretik. Zoritxarrez identitate-zerbitzaria lineaz kanpo dago eta ezin da atzitu.", + "You should:": "Hau egin beharko zenuke:", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "egiaztatu zure nabigatzailearen gehigarriren batek ez duela identitate-zerbitzaria blokeatzen (esaterako Privacy Badger)", + "contact the administrators of identity server ": " identitate-zerbitzariko administratzaileekin kontaktuak jarri", + "wait and try again later": "itxaron eta berriro saiatu", + "Show tray icon and minimize window to it on close": "Erakutsi egoera-barrako ikonoa eta minimizatu leihoa itxi ordez", + "Room %(name)s": "%(name)s gela", + "Recent rooms": "Azken gelak", + "%(count)s unread messages including mentions.|one": "Irakurri gabeko aipamen 1.", + "%(count)s unread messages.|one": "Irakurri gabeko mezu 1.", + "Unread messages.": "Irakurri gabeko mezuak.", + "Trust & Devices": "Fidagarritasuna eta gailuak", + "Direct messages": "Mezu zuzenak", + "Failed to deactivate user": "Huts egin du erabiltzailea desaktibatzeak", + "This client does not support end-to-end encryption.": "Bezero honek ez du muturretik muturrerako zifratzea onartzen.", + "Messages in this room are not end-to-end encrypted.": "Gela honetako mezuak ez daude muturretik muturrera zifratuta.", + "React": "Erreakzioa", + "Frequently Used": "Maiz erabilia", + "Smileys & People": "Irribartxoak eta jendea", + "Animals & Nature": "Animaliak eta natura", + "Food & Drink": "Jana eta edana", + "Activities": "Jarduerak", + "Travel & Places": "Bidaiak eta tokiak", + "Objects": "Objektuak", + "Symbols": "Ikurrak", + "Flags": "Banderak", + "Quick Reactions": "Erreakzio azkarrak", + "Cancel search": "Ezeztatu bilaketa", + "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Ez da identitate-zerbitzaririk konfiguratu, beraz ezin duzu e-mail helbide bat gehitu etorkizunean pasahitza berrezartzeko.", + "Jump to first unread room.": "Jauzi irakurri gabeko lehen gelara.", + "Jump to first invite.": "Jauzi lehen gonbidapenera.", + "Command Autocomplete": "Aginduak auto-osatzea", + "DuckDuckGo Results": "DuckDuckGo emaitzak" } From aaf86b198513a3cf11ae6a337af643b0de3ddf39 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 1 Nov 2019 01:28:18 +0000 Subject: [PATCH 025/103] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1850 of 1850 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index bb383c7f5a..3c580f22ff 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2269,5 +2269,6 @@ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "未設定身份識別伺服器,所以您無法新增電子郵件以在未來重設您的密碼。", "%(count)s unread messages including mentions.|one": "1 則未讀的提及。", "%(count)s unread messages.|one": "1 則未讀的訊息。", - "Unread messages.": "未讀的訊息。" + "Unread messages.": "未讀的訊息。", + "Show tray icon and minimize window to it on close": "顯示系統匣圖示並在關閉視窗時將其最小化至其中" } From b877b81041e1ebde1fe7e955ba20b2176c4149ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=83=9C=EC=84=AD?= Date: Fri, 1 Nov 2019 14:11:54 +0000 Subject: [PATCH 026/103] Translated using Weblate (Korean) Currently translated at 100.0% (1850 of 1850 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ko/ --- src/i18n/strings/ko.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 4e94a06dc3..f06d72d01e 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -2120,5 +2120,6 @@ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "설정된 ID 서버가 없어서 이후 비밀번호를 초기화하기 위한 이메일 주소를 추가할 수 없습니다.", "%(count)s unread messages including mentions.|one": "1개의 읽지 않은 언급.", "%(count)s unread messages.|one": "1개의 읽지 않은 메시지.", - "Unread messages.": "읽지 않은 메시지." + "Unread messages.": "읽지 않은 메시지.", + "Show tray icon and minimize window to it on close": "닫을 때 창을 최소화하고 트레이 아이콘으로 표시하기" } From 661c77cfd9bbaf6e652b8533bb254f4007e10277 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 1 Nov 2019 17:15:53 +0000 Subject: [PATCH 027/103] Translated using Weblate (Hungarian) Currently translated at 100.0% (1852 of 1852 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 d901ff4d85..4946c7b14f 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2264,5 +2264,7 @@ "%(count)s unread messages including mentions.|one": "1 olvasatlan megemlítés.", "%(count)s unread messages.|one": "1 olvasatlan üzenet.", "Unread messages.": "Olvasatlan üzenetek.", - "Show tray icon and minimize window to it on close": "Tálcaikon mutatása és az ablak összecsukása bezáráskor" + "Show tray icon and minimize window to it on close": "Tálcaikon mutatása és az ablak összecsukása bezáráskor", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Ez a művelet az e-mail cím vagy telefonszám ellenőrzése miatt hozzáférést igényel az alapértelmezett azonosítási szerverhez (), de a szervernek nincsen semmilyen felhasználási feltétele.", + "Trust": "Megbízom benne" } From d3dd0cb91afde4e0bee0d3e323c2bf267807364c Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sun, 3 Nov 2019 07:47:15 +0000 Subject: [PATCH 028/103] Translated using Weblate (Bulgarian) Currently translated at 97.6% (1808 of 1852 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 | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 29771f6f2b..cf08dba77f 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -2189,5 +2189,20 @@ "Hide advanced": "Скрий разширени настройки", "Show advanced": "Покажи разширени настройки", "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Блокирай присъединяването на потребители от други Matrix сървъри в тази стая (Тази настройка не може да се промени по-късно!)", - "Close dialog": "Затвори прозореца" + "Close dialog": "Затвори прозореца", + "Add Email Address": "Добави имейл адрес", + "Add Phone Number": "Добави телефонен номер", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Това действие изисква връзка със сървъра за самоличност за валидиране на имейл адреса или телефонния номер, но сървърът не предоставя условия за ползване.", + "Trust": "Довери се", + "Use the new, consistent UserInfo panel for Room Members and Group Members": "Използвай новия UserInfo панел за членове на стаи и групи", + "Use the new, faster, composer for writing messages": "Използвай новия, по-бърз редактор за писане на съобщения", + "Show previews/thumbnails for images": "Показвай преглед (умален размер) на снимки", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Би било добре да премахнете личните си данни от сървъра за самоличност преди прекъсване на връзката. За съжаление, сървърът за самоличност в момента не е достъпен.", + "You should:": "Ще е добре да:", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "проверите браузър добавките за всичко, което може да блокира връзката със сървъра за самоличност (например Privacy Badge)", + "contact the administrators of identity server ": "се свържете с администратора на сървъра за самоличност ", + "wait and try again later": "изчакате и опитате пак", + "Clear cache and reload": "Изчисти кеша и презареди", + "Show tray icon and minimize window to it on close": "Показвай икона в лентата и минимизирай прозореца там при затваряне", + "Your email address hasn't been verified yet": "Имейл адресът ви все още не е потвърден" } From 97831277246855749990b42df178b69c89f1122d Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 2 Nov 2019 13:40:15 +0000 Subject: [PATCH 029/103] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1852 of 1852 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 3c580f22ff..94183ef83f 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2270,5 +2270,7 @@ "%(count)s unread messages including mentions.|one": "1 則未讀的提及。", "%(count)s unread messages.|one": "1 則未讀的訊息。", "Unread messages.": "未讀的訊息。", - "Show tray icon and minimize window to it on close": "顯示系統匣圖示並在關閉視窗時將其最小化至其中" + "Show tray icon and minimize window to it on close": "顯示系統匣圖示並在關閉視窗時將其最小化至其中", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "此動作需要存取預設的身份識別伺服器 以驗證電子郵件或電話號碼,但伺服器沒有任何服務條款。", + "Trust": "信任" } From d6d2505346f3513bb294855d3e5324ee647c60b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Sat, 2 Nov 2019 11:03:53 +0000 Subject: [PATCH 030/103] Translated using Weblate (French) Currently translated at 100.0% (1852 of 1852 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 20f88e4d08..7807facb1c 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2277,5 +2277,7 @@ "%(count)s unread messages including mentions.|one": "1 mention non lue.", "%(count)s unread messages.|one": "1 message non lu.", "Unread messages.": "Messages non lus.", - "Show tray icon and minimize window to it on close": "Afficher l’icône dans la barre d’état et minimiser la fenêtre lors de la fermeture" + "Show tray icon and minimize window to it on close": "Afficher l’icône dans la barre d’état et minimiser la fenêtre lors de la fermeture", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Cette action nécessite l’accès au serveur d’identité par défaut afin de valider une adresse e-mail ou un numéro de téléphone, mais le serveur n’a aucune condition de service.", + "Trust": "Confiance" } From 3a44cf2191f4dccd1bfb79cd618865e5ba873fe1 Mon Sep 17 00:00:00 2001 From: shuji narazaki Date: Sun, 3 Nov 2019 04:55:28 +0000 Subject: [PATCH 031/103] Translated using Weblate (Japanese) Currently translated at 58.8% (1089 of 1852 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 42 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 47e53e2ffe..23199094e8 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -1303,5 +1303,45 @@ "Upgrade": "アップグレード", "Sets the room name": "部屋名を設定する", "Change room name": "部屋名を変える", - "Room Name": "部屋名" + "Room Name": "部屋名", + "Add Email Address": "メールアドレスの追加", + "Add Phone Number": "電話番号の追加", + "Call failed due to misconfigured server": "サーバの誤設定により呼び出し失敗", + "Try using turn.matrix.org": "turn.matrix.orgで試してみる", + "A conference call could not be started because the integrations server is not available": "統合サーバーが利用できないので電話会議を開始できませんでした", + "Replying With Files": "ファイルを添付して返信", + "The file '%(fileName)s' failed to upload.": "ファイル '%(fileName)s' のアップロードに失敗しました。", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "ファイル '%(fileName)s' はこのホームサーバのアップロードのサイズ上限を超えています", + "The server does not support the room version specified.": "このサーバは指定された部屋バージョンに対応していません。", + "Name or Matrix ID": "名前またはMatrix ID", + "Identity server has no terms of service": "IDサーバーは利用規約を持っていません", + "Email, name or Matrix ID": "メールアドレス、名前、またはMatrix ID", + "Failed to start chat": "対話開始に失敗しました", + "Messages": "メッセージ", + "Actions": "アクション", + "Other": "その他", + "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "¯\\_(ツ)_/¯ を平文メッセージの前に挿入する", + "Sends a message as plain text, without interpreting it as markdown": "メッセージをマークダウンと解釈せずプレーンテキストとして送信する", + "Upgrades a room to a new version": "部屋を新しいバージョンへアップグレードする", + "You do not have the required permissions to use this command.": "このコマンドを実行するのに必要な権限がありません。", + "Room upgrade confirmation": "部屋のアップグレードの確認", + "Changes your display nickname in the current room only": "表示されるニックネームをこの部屋に関してのみ変更する", + "Changes the avatar of the current room": "現在の部屋のアバターを変更する", + "Changes your avatar in this current room only": "アバターをこの部屋に関してのみ変更する", + "Changes your avatar in all rooms": "全ての部屋に対するアバターを変更する", + "Gets or sets the room topic": "部屋のトピック情報を取得または設定する", + "This room has no topic.": "この部屋はトピックを持ちません。", + "Use an identity server": "IDサーバーを使用する", + "Unbans user with given ID": "与えられたIDを持つユーザーの追放を解除する", + "Adds a custom widget by URL to the room": "部屋にURLで指定したカスタムウィジェットを追加する", + "Please supply a https:// or http:// widget URL": "https:// または http:// で始まるウィジェット URLを指定してください", + "You cannot modify widgets in this room.": "あなたはこの部屋のウィジェットを変更できません。", + "Sends the given message coloured as a rainbow": "与えられたメッセージを虹色にして送信する", + "Sends the given emote coloured as a rainbow": "与えられたエモートを虹色で送信する", + "Displays list of commands with usages and descriptions": "使い方と説明付きのコマンド一覧を表示する", + "%(senderName)s made no change.": "%(senderName)s は変更されませんでした。", + "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s はこの部屋をアップグレードしました。", + "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s はこの部屋をリンクを知っている人全てに公開しました。", + "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s はこの部屋を招待者のみに変更しました。", + "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s はゲストがこの部屋に参加できるようにしました。" } From 8b63a37cdd9622e5f98efd327a19e3b7e52e0624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=83=9C=EC=84=AD?= Date: Sat, 2 Nov 2019 10:06:34 +0000 Subject: [PATCH 032/103] Translated using Weblate (Korean) Currently translated at 100.0% (1852 of 1852 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ko/ --- src/i18n/strings/ko.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index f06d72d01e..1aebd0ce17 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -2121,5 +2121,7 @@ "%(count)s unread messages including mentions.|one": "1개의 읽지 않은 언급.", "%(count)s unread messages.|one": "1개의 읽지 않은 메시지.", "Unread messages.": "읽지 않은 메시지.", - "Show tray icon and minimize window to it on close": "닫을 때 창을 최소화하고 트레이 아이콘으로 표시하기" + "Show tray icon and minimize window to it on close": "닫을 때 창을 최소화하고 트레이 아이콘으로 표시하기", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "이 작업에는 이메일 주소 또는 전화번호를 확인하기 위해 기본 ID 서버 에 접근해야 합니다. 하지만 서버가 서비스 약관을 갖고 있지 않습니다.", + "Trust": "신뢰함" } From 2fc1c3235bfdf6f127dc051a8c17970e7602bdb7 Mon Sep 17 00:00:00 2001 From: Philip Johansson Date: Sat, 2 Nov 2019 10:23:46 +0000 Subject: [PATCH 033/103] Translated using Weblate (Swedish) Currently translated at 77.8% (1441 of 1852 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sv/ --- src/i18n/strings/sv.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json index 5c98ea50ba..6d611be464 100644 --- a/src/i18n/strings/sv.json +++ b/src/i18n/strings/sv.json @@ -946,7 +946,7 @@ "Verified key": "Verifierad nyckel", "Unrecognised command:": "Oigenkänt kommando:", "Unbans user with given id": "Avbannar användare med givet id", - "Verifies a user, device, and pubkey tuple": "Verifierar en användare, enhet och nycklar", + "Verifies a user, device, and pubkey tuple": "Verifierar en användare, enhet och offentlig nyckel-tupel", "VoIP conference started.": "VoIP-konferens startad.", "VoIP conference finished.": "VoIP-konferens avslutad.", "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s gjorde framtida rumshistorik synligt för okänd (%(visibility)s).", @@ -1814,5 +1814,8 @@ "All keys backed up": "Alla nycklar säkerhetskopierade", "Backup has a signature from unknown device with ID %(deviceId)s.": "Säkerhetskopian har en signatur från okänd enhet med ID %(deviceId)s.", "Add Email Address": "Lägg till e-postadress", - "Add Phone Number": "Lägg till telefonnummer" + "Add Phone Number": "Lägg till telefonnummer", + "Identity server has no terms of service": "Identitetsserver har inga användarvillkor", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Den här åtgärden kräver åtkomst till standardidentitetsservern för att validera en e-postadress eller telefonnummer, men servern har inga användarvillkor.", + "Trust": "Förtroende" } From 6d3b5631199154d83432f292d95f6dd2ae824f6e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 4 Nov 2019 10:16:16 +0000 Subject: [PATCH 034/103] Add comments regarding tab-index=-1 --- src/components/views/messages/DateSeparator.js | 1 + src/components/views/rooms/EventTile.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/views/messages/DateSeparator.js b/src/components/views/messages/DateSeparator.js index 88b59d0c26..56faa670b2 100644 --- a/src/components/views/messages/DateSeparator.js +++ b/src/components/views/messages/DateSeparator.js @@ -57,6 +57,7 @@ export default class DateSeparator extends React.Component { render() { // ARIA treats
s as separators, here we abuse them slightly so manually treat this entire thing as one + // tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers return


{ this.getLabel() }
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index bc502d0674..9497324f5a 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -787,6 +787,7 @@ module.exports = createReactClass({ this.props.permalinkCreator, 'replyThread', ); + // tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers return (
From 2a1f26a44ff4003204ba05bc7f7c9d52a9eedc7a Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 4 Nov 2019 11:50:49 +0000 Subject: [PATCH 035/103] Translated using Weblate (Bulgarian) Currently translated at 97.6% (1808 of 1853 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index cf08dba77f..2287c5b295 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -2199,7 +2199,7 @@ "Show previews/thumbnails for images": "Показвай преглед (умален размер) на снимки", "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Би било добре да премахнете личните си данни от сървъра за самоличност преди прекъсване на връзката. За съжаление, сървърът за самоличност в момента не е достъпен.", "You should:": "Ще е добре да:", - "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "проверите браузър добавките за всичко, което може да блокира връзката със сървъра за самоличност (например Privacy Badge)", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "проверите браузър добавките за всичко, което може да блокира връзката със сървъра за самоличност (например Privacy Badger)", "contact the administrators of identity server ": "се свържете с администратора на сървъра за самоличност ", "wait and try again later": "изчакате и опитате пак", "Clear cache and reload": "Изчисти кеша и презареди", From aba557f02352e04a2276a69fe4d51e15ac351881 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 4 Nov 2019 15:09:19 +0000 Subject: [PATCH 036/103] Released react-sdk --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0bd712df7f..a27279645f 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "linkifyjs": "^2.1.6", "lodash": "^4.17.14", "lolex": "4.2", - "matrix-js-sdk": "2.4.3-rc.1", + "matrix-js-sdk": "2.4.3", "optimist": "^0.6.1", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index bc3ee0282f..fa7868d270 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5192,10 +5192,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-rc.1: - version "2.4.3-rc.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-2.4.3-rc.1.tgz#c06452b89c74976ac0bae0732325c0b359e6f2fa" - integrity sha512-aV70H10lSpjAOmnWDXIWc2CP5D1OylwSSfyc61QzjvGhECEYaiQi4rxH4ZFhX9AL3ezPHse7SY6AmKOCfqBQiw== +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== dependencies: another-json "^0.2.0" babel-runtime "^6.26.0" From 4454be909218de4050028cd4a85a56f4025f300c Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 4 Nov 2019 15:12:54 +0000 Subject: [PATCH 037/103] Prepare changelog for v1.7.1 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e97b737c..ee71ea7f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [1.7.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.1) (2019-11-04) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.1-rc.2...v1.7.1) + + * No changes since rc.2 + Changes in [1.7.1-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.1-rc.2) (2019-11-01) ============================================================================================================= [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.1-rc.1...v1.7.1-rc.2) From 2f4f15d26ccc084aebac223a1d33a7cc8f03c14a Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 4 Nov 2019 15:12:54 +0000 Subject: [PATCH 038/103] v1.7.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a27279645f..5cc23a9fe3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.1-rc.2", + "version": "1.7.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 99c8a909b31f50e33b4c1c9a43e80208936377c9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 4 Nov 2019 16:47:20 +0000 Subject: [PATCH 039/103] Fix focus-within on EventTile and more showing onClick --- res/css/structures/_RoomSubList.scss | 2 +- res/css/views/rooms/_EventTile.scss | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/res/css/structures/_RoomSubList.scss b/res/css/structures/_RoomSubList.scss index b39504593a..cd3a822d4d 100644 --- a/res/css/structures/_RoomSubList.scss +++ b/res/css/structures/_RoomSubList.scss @@ -51,7 +51,7 @@ limitations under the License. height: 36px; } -.mx_RoomSubList_labelContainer:focus-within { +.mx_RoomSubList_labelContainer.focus-visible:focus-within { background-color: $roomtile-focused-bg-color; } diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index a30b219016..ac3eeb7b81 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -138,13 +138,13 @@ limitations under the License. // Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile_last > div > a > .mx_MessageTimestamp, .mx_EventTile:hover > div > a > .mx_MessageTimestamp, -.mx_EventTile:focus-within > div > a > .mx_MessageTimestamp, +.mx_EventTile.focus-visible:focus-within > div > a > .mx_MessageTimestamp, .mx_EventTile.mx_EventTile_actionBarFocused > div > a > .mx_MessageTimestamp { visibility: visible; } .mx_EventTile:hover .mx_MessageActionBar, -.mx_EventTile:focus-within .mx_MessageActionBar, +.mx_EventTile.focus-visible:focus-within .mx_MessageActionBar, .mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar { visibility: visible; } @@ -168,7 +168,7 @@ limitations under the License. } .mx_EventTile:hover .mx_EventTile_line, -.mx_EventTile:focus-within .mx_EventTile_line, +.mx_EventTile.focus-visible:focus-within .mx_EventTile_line, .mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line { background-color: $event-selected-color; } @@ -469,7 +469,7 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { } .mx_EventTile:hover .mx_EventTile_body pre, -.mx_EventTile:focus-within .mx_EventTile_body pre { +.mx_EventTile.focus-visible:focus-within .mx_EventTile_body pre { border: 1px solid #e5e5e5; // deliberate constant as we're behind an invert filter } From bc924bbd82e2274fb6a663935201da88f2064fff Mon Sep 17 00:00:00 2001 From: sha-265 <4103710+sha-265@users.noreply.github.com> Date: Mon, 4 Nov 2019 17:37:36 +0000 Subject: [PATCH 040/103] Support RTL language in message composer --- src/components/views/rooms/BasicMessageComposer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/rooms/BasicMessageComposer.js b/src/components/views/rooms/BasicMessageComposer.js index 0cd08cce5a..c7659e89fb 100644 --- a/src/components/views/rooms/BasicMessageComposer.js +++ b/src/components/views/rooms/BasicMessageComposer.js @@ -566,6 +566,7 @@ export default class BasicMessageEditor extends React.Component { aria-haspopup="listbox" aria-expanded={Boolean(this.state.autoComplete)} aria-activedescendant={completionIndex >= 0 ? generateCompletionDomId(completionIndex) : undefined} + dir="auto" />
); } From 888da3ad84c260ed4c33f2bdd53df33dac163fb8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 5 Nov 2019 12:01:30 +0000 Subject: [PATCH 041/103] delint stylesheet --- res/css/views/rooms/_EventTile.scss | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index ac3eeb7b81..36db29d47e 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -138,14 +138,14 @@ limitations under the License. // Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) .mx_EventTile_last > div > a > .mx_MessageTimestamp, .mx_EventTile:hover > div > a > .mx_MessageTimestamp, -.mx_EventTile.focus-visible:focus-within > div > a > .mx_MessageTimestamp, -.mx_EventTile.mx_EventTile_actionBarFocused > div > a > .mx_MessageTimestamp { +.mx_EventTile.mx_EventTile_actionBarFocused > div > a > .mx_MessageTimestamp, +.mx_EventTile.focus-visible:focus-within > div > a > .mx_MessageTimestamp { visibility: visible; } .mx_EventTile:hover .mx_MessageActionBar, -.mx_EventTile.focus-visible:focus-within .mx_MessageActionBar, -.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar { +.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar, +.mx_EventTile.focus-visible:focus-within .mx_MessageActionBar { visibility: visible; } @@ -168,8 +168,8 @@ limitations under the License. } .mx_EventTile:hover .mx_EventTile_line, -.mx_EventTile.focus-visible:focus-within .mx_EventTile_line, -.mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line { +.mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line, +.mx_EventTile.focus-visible:focus-within .mx_EventTile_line { background-color: $event-selected-color; } From eb4220a836972ca470b3bffd5916921631410e55 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 6 Nov 2019 10:31:05 +0100 Subject: [PATCH 042/103] scroll panels should be in flex container so they don't grow w/ content --- res/css/structures/_FilePanel.scss | 1 + res/css/structures/_NotificationPanel.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/res/css/structures/_FilePanel.scss b/res/css/structures/_FilePanel.scss index 703e90f402..87e885e668 100644 --- a/res/css/structures/_FilePanel.scss +++ b/res/css/structures/_FilePanel.scss @@ -18,6 +18,7 @@ limitations under the License. order: 2; flex: 1 1 0; overflow-y: auto; + display: flex; } .mx_FilePanel .mx_RoomView_messageListWrapper { diff --git a/res/css/structures/_NotificationPanel.scss b/res/css/structures/_NotificationPanel.scss index 78b3522d4e..c9e0261ec9 100644 --- a/res/css/structures/_NotificationPanel.scss +++ b/res/css/structures/_NotificationPanel.scss @@ -18,6 +18,7 @@ limitations under the License. order: 2; flex: 1 1 0; overflow-y: auto; + display: flex; } .mx_NotificationPanel .mx_RoomView_messageListWrapper { From 9fa7990996ec89f2301f6cc4f3d4ab3860a7b7cd Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 6 Nov 2019 10:31:56 +0100 Subject: [PATCH 043/103] prevent error for empty list --- src/components/structures/ScrollPanel.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index 32efad1e05..1d5c520285 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -759,8 +759,10 @@ module.exports = createReactClass({ _getMessagesHeight() { const itemlist = this.refs.itemlist; const lastNode = itemlist.lastElementChild; + const lastNodeBottom = lastNode ? lastNode.offsetTop + lastNode.clientHeight : 0; + const firstNodeTop = itemlist.firstElementChild ? itemlist.firstElementChild.offsetTop : 0; // 18 is itemlist padding - return (lastNode.offsetTop + lastNode.clientHeight) - itemlist.firstElementChild.offsetTop + (18 * 2); + return lastNodeBottom - firstNodeTop + (18 * 2); }, _topFromBottom(node) { From 842bf77409184a028e721cb50abb5a50c7b655fb Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 6 Nov 2019 10:32:20 +0100 Subject: [PATCH 044/103] prevent error when nextProps is null, cleanup As the FilePanel is now rendered as part of the RoomView, we don't need to respond to room changes, as RoomView has a key of the roomId, so the whole subtree would be recreated. --- src/components/structures/FilePanel.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index c7e8295f80..f5a5912dd5 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -39,23 +39,10 @@ const FilePanel = createReactClass({ }; }, - componentWillMount: function() { + componentDidMount: function() { this.updateTimelineSet(this.props.roomId); }, - componentWillReceiveProps: function(nextProps) { - if (nextProps.roomId !== this.props.roomId) { - // otherwise we race between re-rendering the TimelinePanel and setting the new timelineSet. - // - // FIXME: this race only happens because of the promise returned by getOrCreateFilter(). - // We should only need to create the containsUrl filter once per login session, so in practice - // it shouldn't be being done here at all. Then we could just update the timelineSet directly - // without resetting it first, and speed up room-change. - this.setState({ timelineSet: null }); - this.updateTimelineSet(nextProps.roomId); - } - }, - updateTimelineSet: function(roomId) { const client = MatrixClientPeg.get(); const room = client.getRoom(roomId); From d403ed751389ee2bc8d4f26a75f6a727bf49f596 Mon Sep 17 00:00:00 2001 From: N-Pex Date: Wed, 6 Nov 2019 10:41:14 +0100 Subject: [PATCH 045/103] Fix linkify imports VECTOR_URL_PATTERN was 'undefined' inside Permalinks.tryTransformPermalinkToLocalHref() --- src/linkify-matrix.js | 2 +- src/utils/permalinks/Permalinks.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js index fabd9d15ad..889bad682c 100644 --- a/src/linkify-matrix.js +++ b/src/linkify-matrix.js @@ -243,4 +243,4 @@ matrixLinkify.options = { }, }; -module.exports = matrixLinkify; +export default matrixLinkify; diff --git a/src/utils/permalinks/Permalinks.js b/src/utils/permalinks/Permalinks.js index 19dcbd062a..aec7243236 100644 --- a/src/utils/permalinks/Permalinks.js +++ b/src/utils/permalinks/Permalinks.js @@ -20,7 +20,7 @@ import utils from 'matrix-js-sdk/lib/utils'; import SpecPermalinkConstructor, {baseUrl as matrixtoBaseUrl} from "./SpecPermalinkConstructor"; import PermalinkConstructor, {PermalinkParts} from "./PermalinkConstructor"; import RiotPermalinkConstructor from "./RiotPermalinkConstructor"; -import * as matrixLinkify from "../../linkify-matrix"; +import matrixLinkify from "../../linkify-matrix"; const SdkConfig = require("../../SdkConfig"); From 328fc5a02dd5013a42825ee2e1c3bb99d67b8eb1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 6 Nov 2019 10:41:10 +0000 Subject: [PATCH 046/103] fix style lint --- res/css/views/rooms/_EventTile.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 36db29d47e..db34200b16 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -167,6 +167,10 @@ limitations under the License. } } +.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line { + padding-left: 78px; +} + .mx_EventTile:hover .mx_EventTile_line, .mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line, .mx_EventTile.focus-visible:focus-within .mx_EventTile_line { @@ -384,10 +388,6 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { padding-left: 5px; } -.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line { - padding-left: 78px; -} - .mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line, .mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line { padding-left: 60px; From 0464b094a6fa911204891a15a6b8af4cef0fa09b Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 6 Nov 2019 11:44:32 +0000 Subject: [PATCH 047/103] Fix softcrash if editing silly events If you sent an event with a body of the empty json object, riot would then softcrash when you pressed the up arrow because it would try to treat a json object as a string and run split on it. --- src/utils/EventUtils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/EventUtils.js b/src/utils/EventUtils.js index ffc47e2277..29af5ca9b5 100644 --- a/src/utils/EventUtils.js +++ b/src/utils/EventUtils.js @@ -52,6 +52,7 @@ export function canEditContent(mxEvent) { const content = mxEvent.getOriginalContent(); const {msgtype} = content; return (msgtype === "m.text" || msgtype === "m.emote") && + content.body && typeof content.body === 'string' && mxEvent.getSender() === MatrixClientPeg.get().getUserId(); } From c73b553831a6a3976a4aeaa69183483ff1cef9ca Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 6 Nov 2019 14:17:09 +0000 Subject: [PATCH 048/103] Prepare changelog for v1.7.2 --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee71ea7f68..7c46530fad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,35 @@ +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) + + * Fix softcrash if editing silly events + [\#3596](https://github.com/matrix-org/matrix-react-sdk/pull/3596) + * Fix: file and notifications panel back-paginating forever. + [\#3594](https://github.com/matrix-org/matrix-react-sdk/pull/3594) + * Fix focus-within on EventTile and more showing onClick + [\#3591](https://github.com/matrix-org/matrix-react-sdk/pull/3591) + * Support RTL language in message composer + [\#3592](https://github.com/matrix-org/matrix-react-sdk/pull/3592) + * Update from Weblate + [\#3590](https://github.com/matrix-org/matrix-react-sdk/pull/3590) + * Improve A11Y of timeline. Show timestamp & Actions on focus-within + [\#3587](https://github.com/matrix-org/matrix-react-sdk/pull/3587) + * Fix SVG mask-image usage in a bunch of places for correct outlining + [\#3589](https://github.com/matrix-org/matrix-react-sdk/pull/3589) + * Handle breadcrumbs, integration manager provisioning, and allowed widgets + Riot settings + [\#3577](https://github.com/matrix-org/matrix-react-sdk/pull/3577) + * Add a prompt when interacting with an identity server without terms + [\#3582](https://github.com/matrix-org/matrix-react-sdk/pull/3582) + * Fix bug where rooms would not appear when filtering + [\#3584](https://github.com/matrix-org/matrix-react-sdk/pull/3584) + * Guard against misconfigured homeservers when adding / binding phone numbers + [\#3583](https://github.com/matrix-org/matrix-react-sdk/pull/3583) + * Fix error message which is shown when unknown slash command attempted + [\#3580](https://github.com/matrix-org/matrix-react-sdk/pull/3580) + * Attempt to fix soft crash on some pinned events by null guarding member + [\#3581](https://github.com/matrix-org/matrix-react-sdk/pull/3581) + Changes in [1.7.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v1.7.1) (2019-11-04) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v1.7.1-rc.2...v1.7.1) From a0909df26923249291b2addfa815ad3728b9db4b Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 6 Nov 2019 14:17:09 +0000 Subject: [PATCH 049/103] v1.7.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5cc23a9fe3..0caff285e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "1.7.1", + "version": "1.7.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From c00974d22d9e8b5b934b84980a30ea58a21e9590 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 7 Nov 2019 10:16:57 +0000 Subject: [PATCH 050/103] Now that part of spacing is padding, make it smaller when collapsed Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/structures/_RoomSubList.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/structures/_RoomSubList.scss b/res/css/structures/_RoomSubList.scss index cd3a822d4d..be44563cfb 100644 --- a/res/css/structures/_RoomSubList.scss +++ b/res/css/structures/_RoomSubList.scss @@ -151,6 +151,7 @@ limitations under the License. .mx_RoomSubList_labelContainer { margin-right: 8px; margin-left: 2px; + padding: 0; } .mx_RoomSubList_addRoom { From 91f3b75d41d9f3fc2f88818ec5afb545e15c2850 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 7 Nov 2019 10:19:17 +0000 Subject: [PATCH 051/103] Remove variation selectors from quick reactions This fixes a regression introduced by the full emoji picker which inserted empty variation selectors in the thumbs up / down quick reactions. Since this makes them different characters, it would cause us to not aggregate thumbs from web vs. mobile together. Regressed by https://github.com/matrix-org/matrix-react-sdk/pull/3554 Fixes https://github.com/vector-im/riot-web/issues/11335 --- src/components/views/emojipicker/QuickReactions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/emojipicker/QuickReactions.js b/src/components/views/emojipicker/QuickReactions.js index 66248730f9..71a53984cc 100644 --- a/src/components/views/emojipicker/QuickReactions.js +++ b/src/components/views/emojipicker/QuickReactions.js @@ -21,7 +21,7 @@ import EMOJIBASE from 'emojibase-data/en/compact.json'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; -const QUICK_REACTIONS = ["👍️", "👎️", "😄", "🎉", "😕", "❤️", "🚀", "👀"]; +const QUICK_REACTIONS = ["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"]; EMOJIBASE.forEach(emoji => { const index = QUICK_REACTIONS.indexOf(emoji.unicode); if (index !== -1) { From ec2f3d36ea2d705bc330a949a0a665873ab66a03 Mon Sep 17 00:00:00 2001 From: Marco Zehe Date: Thu, 7 Nov 2019 14:41:01 +0100 Subject: [PATCH 052/103] Fix breadcrumbs so the bar is a toolbar and the buttons are buttons. Signed-off-by: Marco Zehe --- src/components/views/rooms/RoomBreadcrumbs.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomBreadcrumbs.js b/src/components/views/rooms/RoomBreadcrumbs.js index 8bee87728b..6529b5b1da 100644 --- a/src/components/views/rooms/RoomBreadcrumbs.js +++ b/src/components/views/rooms/RoomBreadcrumbs.js @@ -353,7 +353,6 @@ export default class RoomBreadcrumbs extends React.Component { onMouseEnter={() => this._onMouseEnter(r.room)} onMouseLeave={() => this._onMouseLeave(r.room)} aria-label={_t("Room %(name)s", {name: r.room.name})} - role="listitem" > {badge} @@ -363,7 +362,7 @@ export default class RoomBreadcrumbs extends React.Component { ); }); return ( -
+
Date: Thu, 7 Nov 2019 17:49:25 +0000 Subject: [PATCH 053/103] Restore thumbs after variation selector removal This more thorough change adjusts emoji processing to deal with variation selectors appropriately and revives the missing thumbs. Regressed by https://github.com/matrix-org/matrix-react-sdk/pull/3598 Fixes https://github.com/vector-im/riot-web/issues/11344 --- src/HtmlUtils.js | 21 ++++++++++++++----- .../views/emojipicker/EmojiPicker.js | 12 ++++++++++- .../views/emojipicker/QuickReactions.js | 14 +++++++------ 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 2266522bfe..2b7384a5aa 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -53,7 +53,6 @@ const ZWJ_REGEX = new RegExp("\u200D|\u2003", "g"); const WHITESPACE_REGEX = new RegExp("\\s", "g"); const BIGEMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})+$`, 'i'); -const SINGLE_EMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})$`, 'i'); const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/; @@ -72,6 +71,21 @@ function mightContainEmoji(str) { return SURROGATE_PAIR_PATTERN.test(str) || SYMBOL_PATTERN.test(str); } +/** + * Find emoji data in emojibase by character. + * + * @param {String} char The emoji character + * @return {Object} The emoji data + */ +export function findEmojiData(char) { + // Check against both the char and the char with an empty variation selector + // appended because that's how emojibase stores its base emojis which have + // variations. + // See also https://github.com/vector-im/riot-web/issues/9785. + const emptyVariation = char + VARIATION_SELECTOR; + return EMOJIBASE.find(e => e.unicode === char || e.unicode === emptyVariation); +} + /** * Returns the shortcode for an emoji character. * @@ -79,10 +93,7 @@ function mightContainEmoji(str) { * @return {String} The shortcode (such as :thumbup:) */ export function unicodeToShortcode(char) { - // Check against both the char and the char with an empty variation selector appended because that's how - // emoji-base stores its base emojis which have variations. https://github.com/vector-im/riot-web/issues/9785 - const emptyVariation = char + VARIATION_SELECTOR; - const data = EMOJIBASE.find(e => e.unicode === char || e.unicode === emptyVariation); + const data = findEmojiData(char); return (data && data.shortcodes ? `:${data.shortcodes[0]}:` : ''); } diff --git a/src/components/views/emojipicker/EmojiPicker.js b/src/components/views/emojipicker/EmojiPicker.js index 48713b90d8..9fe8b4c81e 100644 --- a/src/components/views/emojipicker/EmojiPicker.js +++ b/src/components/views/emojipicker/EmojiPicker.js @@ -48,7 +48,14 @@ const DATA_BY_CATEGORY = { }; const DATA_BY_EMOJI = {}; +const VARIATION_SELECTOR = String.fromCharCode(0xFE0F); EMOJIBASE.forEach(emoji => { + if (emoji.unicode.includes(VARIATION_SELECTOR)) { + // Clone data into variation-less version + emoji = Object.assign({}, emoji, { + unicode: emoji.unicode.replace(VARIATION_SELECTOR, ""), + }); + } DATA_BY_EMOJI[emoji.unicode] = emoji; const categoryId = EMOJIBASE_CATEGORY_IDS[emoji.group]; if (DATA_BY_CATEGORY.hasOwnProperty(categoryId)) { @@ -82,7 +89,10 @@ class EmojiPicker extends React.Component { viewportHeight: 280, }; - this.recentlyUsed = recent.get().map(unicode => DATA_BY_EMOJI[unicode]); + // Convert recent emoji characters to emoji data, removing unknowns. + this.recentlyUsed = recent.get() + .map(unicode => DATA_BY_EMOJI[unicode]) + .filter(data => !!data); this.memoizedDataByCategory = { recent: this.recentlyUsed, ...DATA_BY_CATEGORY, diff --git a/src/components/views/emojipicker/QuickReactions.js b/src/components/views/emojipicker/QuickReactions.js index 71a53984cc..8444fb2d9c 100644 --- a/src/components/views/emojipicker/QuickReactions.js +++ b/src/components/views/emojipicker/QuickReactions.js @@ -16,17 +16,19 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import EMOJIBASE from 'emojibase-data/en/compact.json'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import { findEmojiData } from '../../../HtmlUtils'; -const QUICK_REACTIONS = ["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"]; -EMOJIBASE.forEach(emoji => { - const index = QUICK_REACTIONS.indexOf(emoji.unicode); - if (index !== -1) { - QUICK_REACTIONS[index] = emoji; +const QUICK_REACTIONS = ["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"].map(emoji => { + const data = findEmojiData(emoji); + if (!data) { + throw new Error(`Emoji ${emoji} doesn't exist in emojibase`); } + // Prefer our unicode value for quick reactions (which does not have + // variation selectors). + return Object.assign({}, data, { unicode: emoji }); }); class QuickReactions extends React.Component { From 9c4470e599006e15214d45267c1e551026dbc6ed Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:36:16 +0100 Subject: [PATCH 054/103] helper class to track the state of the verification as we will have 2 tiles, and both need to track the status of the verification request, I've put the logic for tracking the state in this helper class to use from both tiles. --- src/utils/KeyVerificationStateObserver.js | 153 ++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/utils/KeyVerificationStateObserver.js diff --git a/src/utils/KeyVerificationStateObserver.js b/src/utils/KeyVerificationStateObserver.js new file mode 100644 index 0000000000..b049b5d426 --- /dev/null +++ b/src/utils/KeyVerificationStateObserver.js @@ -0,0 +1,153 @@ +/* +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 MatrixClientPeg from '../MatrixClientPeg'; +import { _t } from '../languageHandler'; + +const SUB_EVENT_TYPES_OF_INTEREST = ["start", "cancel", "done"]; + +export default class KeyVerificationStateObserver { + constructor(requestEvent, client, updateCallback) { + this._requestEvent = requestEvent; + this._client = client; + this._updateCallback = updateCallback; + this.accepted = false; + this.done = false; + this.cancelled = false; + this._updateVerificationState(); + } + + attach() { + this._requestEvent.on("Event.relationsCreated", this._onRelationsCreated); + for (const phaseName of SUB_EVENT_TYPES_OF_INTEREST) { + this._tryListenOnRelationsForType(`m.key.verification.${phaseName}`); + } + } + + detach() { + const roomId = this._requestEvent.getRoomId(); + const room = this._client.getRoom(roomId); + + for (const phaseName of SUB_EVENT_TYPES_OF_INTEREST) { + const relations = room.getUnfilteredTimelineSet() + .getRelationsForEvent(this._requestEvent.getId(), "m.reference", `m.key.verification.${phaseName}`); + if (relations) { + relations.removeListener("Relations.add", this._onRelationsUpdated); + relations.removeListener("Relations.remove", this._onRelationsUpdated); + relations.removeListener("Relations.redaction", this._onRelationsUpdated); + } + } + this._requestEvent.removeListener("Event.relationsCreated", this._onRelationsCreated); + } + + _onRelationsCreated = (relationType, eventType) => { + if (relationType !== "m.reference") { + return; + } + if ( + eventType !== "m.key.verification.start" && + eventType !== "m.key.verification.cancel" && + eventType !== "m.key.verification.done" + ) { + return; + } + this._tryListenOnRelationsForType(eventType); + this._updateVerificationState(); + this._updateCallback(); + }; + + _tryListenOnRelationsForType(eventType) { + const roomId = this._requestEvent.getRoomId(); + const room = this._client.getRoom(roomId); + const relations = room.getUnfilteredTimelineSet() + .getRelationsForEvent(this._requestEvent.getId(), "m.reference", eventType); + if (relations) { + relations.on("Relations.add", this._onRelationsUpdated); + relations.on("Relations.remove", this._onRelationsUpdated); + relations.on("Relations.redaction", this._onRelationsUpdated); + } + } + + _onRelationsUpdated = (event) => { + this._updateVerificationState(); + this._updateCallback(); + }; + + _updateVerificationState() { + const roomId = this._requestEvent.getRoomId(); + const room = this._client.getRoom(roomId); + const timelineSet = room.getUnfilteredTimelineSet(); + const fromUserId = this._requestEvent.getSender(); + const content = this._requestEvent.getContent(); + const toUserId = content.to; + + this.cancelled = false; + this.done = false; + this.accepted = false; + this.otherPartyUserId = null; + this.cancelPartyUserId = null; + + const startRelations = timelineSet.getRelationsForEvent( + this._requestEvent.getId(), "m.reference", "m.key.verification.start"); + if (startRelations) { + for (const startEvent of startRelations.getRelations()) { + if (startEvent.getSender() === toUserId) { + this.accepted = true; + } + } + } + + const doneRelations = timelineSet.getRelationsForEvent( + this._requestEvent.getId(), "m.reference", "m.key.verification.done"); + if (doneRelations) { + let senderDone = false; + let receiverDone = false; + for (const doneEvent of doneRelations.getRelations()) { + if (doneEvent.getSender() === toUserId) { + receiverDone = true; + } else if (doneEvent.getSender() === fromUserId) { + senderDone = true; + } + } + if (senderDone && receiverDone) { + this.done = true; + } + } + + if (!this.done) { + const cancelRelations = timelineSet.getRelationsForEvent( + this._requestEvent.getId(), "m.reference", "m.key.verification.cancel"); + + if (cancelRelations) { + let earliestCancelEvent; + for (const cancelEvent of cancelRelations.getRelations()) { + // only accept cancellation from the users involved + if (cancelEvent.getSender() === toUserId || cancelEvent.getSender() === fromUserId) { + this.cancelled = true; + if (!earliestCancelEvent || cancelEvent.getTs() < earliestCancelEvent.getTs()) { + earliestCancelEvent = cancelEvent; + } + } + } + if (earliestCancelEvent) { + this.cancelPartyUserId = earliestCancelEvent.getSender(); + } + } + } + + this.otherPartyUserId = fromUserId === this._client.getUserId() ? toUserId : fromUserId; + } +} From 5c9e80a0ba12478e6358487538dc2ced2d2b2f8a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:38:52 +0100 Subject: [PATCH 055/103] add feature flag and send verification using DM from dialog if enabled --- .../views/dialogs/DeviceVerifyDialog.js | 59 ++++++++++++++++--- src/i18n/strings/en_EN.json | 1 + src/settings/Settings.js | 6 ++ 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/components/views/dialogs/DeviceVerifyDialog.js b/src/components/views/dialogs/DeviceVerifyDialog.js index 710a92aa39..0e191cc192 100644 --- a/src/components/views/dialogs/DeviceVerifyDialog.js +++ b/src/components/views/dialogs/DeviceVerifyDialog.js @@ -24,6 +24,10 @@ import sdk from '../../../index'; import * as FormattingUtils from '../../../utils/FormattingUtils'; import { _t } from '../../../languageHandler'; import {verificationMethods} from 'matrix-js-sdk/lib/crypto'; +import DMRoomMap from '../../../utils/DMRoomMap'; +import createRoom from "../../../createRoom"; +import dis from "../../../dispatcher"; +import SettingsStore from '../../../settings/SettingsStore'; const MODE_LEGACY = 'legacy'; const MODE_SAS = 'sas'; @@ -86,25 +90,37 @@ export default class DeviceVerifyDialog extends React.Component { this.props.onFinished(confirm); } - _onSasRequestClick = () => { + _onSasRequestClick = async () => { this.setState({ phase: PHASE_WAIT_FOR_PARTNER_TO_ACCEPT, }); - this._verifier = MatrixClientPeg.get().beginKeyVerification( - verificationMethods.SAS, this.props.userId, this.props.device.deviceId, - ); - this._verifier.on('show_sas', this._onVerifierShowSas); - this._verifier.verify().then(() => { + const client = MatrixClientPeg.get(); + const verifyingOwnDevice = this.props.userId === client.getUserId(); + try { + if (!verifyingOwnDevice && SettingsStore.getValue("feature_dm_verification")) { + const roomId = await ensureDMExistsAndOpen(this.props.userId); + // throws upon cancellation before having started + this._verifier = await client.requestVerificationDM( + this.props.userId, roomId, [verificationMethods.SAS], + ); + } else { + this._verifier = client.beginKeyVerification( + verificationMethods.SAS, this.props.userId, this.props.device.deviceId, + ); + } + this._verifier.on('show_sas', this._onVerifierShowSas); + // throws upon cancellation + await this._verifier.verify(); this.setState({phase: PHASE_VERIFIED}); this._verifier.removeListener('show_sas', this._onVerifierShowSas); this._verifier = null; - }).catch((e) => { + } catch (e) { console.log("Verification failed", e); this.setState({ phase: PHASE_CANCELLED, }); this._verifier = null; - }); + } } _onSasMatchesClick = () => { @@ -299,3 +315,30 @@ export default class DeviceVerifyDialog extends React.Component { } } +async function ensureDMExistsAndOpen(userId) { + const client = MatrixClientPeg.get(); + const roomIds = DMRoomMap.shared().getDMRoomsForUserId(userId); + const rooms = roomIds.map(id => client.getRoom(id)); + const suitableDMRooms = rooms.filter(r => { + if (r && r.getMyMembership() === "join") { + const member = r.getMember(userId); + return member && (member.membership === "invite" || member.membership === "join"); + } + return false; + }); + let roomId; + if (suitableDMRooms.length) { + const room = suitableDMRooms[0]; + roomId = room.roomId; + } else { + roomId = await createRoom({dmUserId: userId, spinner: false, andView: false}); + } + // don't use andView and spinner in createRoom, together, they cause this dialog to close and reopen, + // we causes us to loose the verifier and restart, and we end up having two verification requests + dis.dispatch({ + action: 'view_room', + room_id: roomId, + should_peek: false, + }); + return roomId; +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5af7e26b79..bcf68f8e4b 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -339,6 +339,7 @@ "Render simple counters in room header": "Render simple counters in room header", "Multiple integration managers": "Multiple integration managers", "Use the new, consistent UserInfo panel for Room Members and Group Members": "Use the new, consistent UserInfo panel for Room Members and Group Members", + "Send verification requests in direct message": "Send verification requests in direct message", "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", "Use compact timeline layout": "Use compact timeline layout", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 2220435cb9..b169a0f29c 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -126,6 +126,12 @@ export const SETTINGS = { supportedLevels: LEVELS_FEATURE, default: false, }, + "feature_dm_verification": { + isFeature: true, + displayName: _td("Send verification requests in direct message"), + supportedLevels: LEVELS_FEATURE, + default: false, + }, "useCiderComposer": { displayName: _td("Use the new, faster, composer for writing messages"), supportedLevels: LEVELS_ACCOUNT_SETTINGS, From 0d2f9c42152c870d93f2259fc587c22d5822dc45 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:39:50 +0100 Subject: [PATCH 056/103] add verification request tile + styling --- res/css/_components.scss | 1 + .../messages/_MKeyVerificationRequest.scss | 93 ++++++++++++ res/css/views/rooms/_EventTile.scss | 25 ++++ res/themes/light/css/_light.scss | 2 + .../views/messages/MKeyVerificationRequest.js | 141 ++++++++++++++++++ src/utils/KeyVerificationStateObserver.js | 17 +++ 6 files changed, 279 insertions(+) create mode 100644 res/css/views/messages/_MKeyVerificationRequest.scss create mode 100644 src/components/views/messages/MKeyVerificationRequest.js diff --git a/res/css/_components.scss b/res/css/_components.scss index 29c4d2c84c..5d26185393 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -118,6 +118,7 @@ @import "./views/messages/_MEmoteBody.scss"; @import "./views/messages/_MFileBody.scss"; @import "./views/messages/_MImageBody.scss"; +@import "./views/messages/_MKeyVerificationRequest.scss"; @import "./views/messages/_MNoticeBody.scss"; @import "./views/messages/_MStickerBody.scss"; @import "./views/messages/_MTextBody.scss"; diff --git a/res/css/views/messages/_MKeyVerificationRequest.scss b/res/css/views/messages/_MKeyVerificationRequest.scss new file mode 100644 index 0000000000..aff44e4109 --- /dev/null +++ b/res/css/views/messages/_MKeyVerificationRequest.scss @@ -0,0 +1,93 @@ +/* +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_KeyVerification { + + display: grid; + grid-template-columns: 24px minmax(0, 1fr) min-content; + + &.mx_KeyVerification_icon::after { + grid-column: 1; + grid-row: 1 / 3; + width: 12px; + height: 16px; + content: ""; + mask: url("$(res)/img/e2e/verified.svg"); + mask-repeat: no-repeat; + mask-size: 100%; + margin-top: 4px; + background-color: $primary-fg-color; + } + + &.mx_KeyVerification_icon_verified::after { + background-color: $accent-color; + } + + .mx_KeyVerification_title, .mx_KeyVerification_subtitle, .mx_KeyVerification_state { + overflow-wrap: break-word; + } + + .mx_KeyVerification_title { + font-weight: 600; + font-size: 15px; + grid-column: 2; + grid-row: 1; + } + + .mx_KeyVerification_subtitle { + grid-column: 2; + grid-row: 2; + } + + .mx_KeyVerification_state, .mx_KeyVerification_subtitle { + font-size: 12px; + } + + .mx_KeyVerification_state, .mx_KeyVerification_buttons { + grid-column: 3; + grid-row: 1 / 3; + } + + .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 { + width: 130px; + padding: 10px 20px; + margin: auto 0; + text-align: center; + color: $notice-secondary-color; + } +} diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index db34200b16..04c1065092 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -22,6 +22,15 @@ limitations under the License. position: relative; } +.mx_EventTile_bubble { + background-color: $dark-panel-bg-color; + padding: 10px; + border-radius: 5px; + margin: 10px auto; + max-width: 75%; + box-sizing: border-box; +} + .mx_EventTile.mx_EventTile_info { padding-top: 0px; } @@ -112,6 +121,21 @@ limitations under the License. line-height: 22px; } +.mx_EventTile_bubbleContainer.mx_EventTile_bubbleContainer { + display: grid; + grid-template-columns: 1fr 100px; + + .mx_EventTile_line { + margin-right: 0px; + grid-column: 1 / 3; + padding: 0; + } + + .mx_EventTile_msgOption { + grid-column: 2; + } +} + .mx_EventTile_reply { margin-right: 10px; } @@ -617,4 +641,5 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { } } } + /* stylelint-enable no-descending-specificity */ diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index b412261d10..dcd7ce166e 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -12,7 +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); $notice-primary-color: #ff4b55; +$notice-primary-bg-color: rgba(255, 75, 85, 0.08); $notice-secondary-color: #61708b; $header-panel-bg-color: #f3f8fd; diff --git a/src/components/views/messages/MKeyVerificationRequest.js b/src/components/views/messages/MKeyVerificationRequest.js new file mode 100644 index 0000000000..21d82309ed --- /dev/null +++ b/src/components/views/messages/MKeyVerificationRequest.js @@ -0,0 +1,141 @@ +/* +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 MatrixClientPeg from '../../../MatrixClientPeg'; +import {verificationMethods} from 'matrix-js-sdk/lib/crypto'; +import sdk from '../../../index'; +import Modal from "../../../Modal"; +import { _t } from '../../../languageHandler'; +import KeyVerificationStateObserver, {getNameForEventRoom, userLabelForEventRoom} + from '../../../utils/KeyVerificationStateObserver'; + +export default class MKeyVerificationRequest extends React.Component { + constructor(props) { + super(props); + this.keyVerificationState = new KeyVerificationStateObserver(this.props.mxEvent, MatrixClientPeg.get(), () => { + this.setState(this._copyState()); + }); + this.state = this._copyState(); + } + + _copyState() { + const {accepted, done, cancelled, cancelPartyUserId, otherPartyUserId} = this.keyVerificationState; + return {accepted, done, cancelled, cancelPartyUserId, otherPartyUserId}; + } + + componentDidMount() { + this.keyVerificationState.attach(); + } + + componentWillUnmount() { + this.keyVerificationState.detach(); + } + + _onAcceptClicked = () => { + const IncomingSasDialog = sdk.getComponent('views.dialogs.IncomingSasDialog'); + // todo: validate event, for example if it has sas in the methods. + const verifier = MatrixClientPeg.get().acceptVerificationDM(this.props.mxEvent, verificationMethods.SAS); + Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, { + verifier, + }); + }; + + _onRejectClicked = () => { + // todo: validate event, for example if it has sas in the methods. + const verifier = MatrixClientPeg.get().acceptVerificationDM(this.props.mxEvent, verificationMethods.SAS); + verifier.cancel("User declined"); + }; + + _acceptedLabel(userId) { + const client = MatrixClientPeg.get(); + const myUserId = client.getUserId(); + if (userId === myUserId) { + return _t("You accepted"); + } else { + return _t("%(name)s accepted", {name: getNameForEventRoom(userId, this.props.mxEvent)}); + } + } + + _cancelledLabel(userId) { + const client = MatrixClientPeg.get(); + const myUserId = client.getUserId(); + if (userId === myUserId) { + return _t("You cancelled"); + } else { + return _t("%(name)s cancelled", {name: getNameForEventRoom(userId, this.props.mxEvent)}); + } + } + + render() { + const {mxEvent} = this.props; + const fromUserId = mxEvent.getSender(); + const content = mxEvent.getContent(); + const toUserId = content.to; + const client = MatrixClientPeg.get(); + const myUserId = client.getUserId(); + const isOwn = fromUserId === myUserId; + + let title; + let subtitle; + let stateNode; + + if (this.state.accepted || this.state.cancelled) { + let stateLabel; + if (this.state.accepted) { + stateLabel = this._acceptedLabel(toUserId); + } else if (this.state.cancelled) { + stateLabel = this._cancelledLabel(this.state.cancelPartyUserId); + } + stateNode = (
{stateLabel}
); + } + + if (toUserId === myUserId) { // request sent to us + title = (
{ + _t("%(name)s wants to verify", {name: getNameForEventRoom(fromUserId, mxEvent)})}
); + subtitle = (
{ + userLabelForEventRoom(fromUserId, mxEvent)}
); + const isResolved = !(this.state.accepted || this.state.cancelled || this.state.done); + if (isResolved) { + const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); + stateNode = (
+ {_t("Decline")} + {_t("Accept")} +
); + } + } else if (isOwn) { // request sent by us + title = (
{ + _t("You sent a verification request")}
); + subtitle = (
{ + userLabelForEventRoom(this.state.otherPartyUserId, mxEvent)}
); + } + + if (title) { + return (
+ {title} + {subtitle} + {stateNode} +
); + } + return null; + } +} + +MKeyVerificationRequest.propTypes = { + /* the MatrixEvent to show */ + mxEvent: PropTypes.object.isRequired, +}; diff --git a/src/utils/KeyVerificationStateObserver.js b/src/utils/KeyVerificationStateObserver.js index b049b5d426..7de50ec4bf 100644 --- a/src/utils/KeyVerificationStateObserver.js +++ b/src/utils/KeyVerificationStateObserver.js @@ -151,3 +151,20 @@ export default class KeyVerificationStateObserver { this.otherPartyUserId = fromUserId === this._client.getUserId() ? toUserId : fromUserId; } } + +export function getNameForEventRoom(userId, mxEvent) { + const roomId = mxEvent.getRoomId(); + const client = MatrixClientPeg.get(); + const room = client.getRoom(roomId); + const member = room.getMember(userId); + return member ? member.name : userId; +} + +export function userLabelForEventRoom(userId, mxEvent) { + const name = getNameForEventRoom(userId, mxEvent); + if (name !== userId) { + return _t("%(name)s (%(userId)s)", {name, userId}); + } else { + return userId; + } +} From e8c21a341cf8dc96f3f57b8824bf5d78663ad660 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:40:22 +0100 Subject: [PATCH 057/103] add key verification conclusion tile --- .../messages/MKeyVerificationConclusion.js | 130 ++++++++++++++++++ src/i18n/strings/en_EN.json | 10 ++ 2 files changed, 140 insertions(+) create mode 100644 src/components/views/messages/MKeyVerificationConclusion.js diff --git a/src/components/views/messages/MKeyVerificationConclusion.js b/src/components/views/messages/MKeyVerificationConclusion.js new file mode 100644 index 0000000000..e955d6159d --- /dev/null +++ b/src/components/views/messages/MKeyVerificationConclusion.js @@ -0,0 +1,130 @@ +/* +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 classNames from 'classnames'; +import PropTypes from 'prop-types'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import { _t } from '../../../languageHandler'; +import KeyVerificationStateObserver, {getNameForEventRoom, userLabelForEventRoom} + from '../../../utils/KeyVerificationStateObserver'; + +export default class MKeyVerificationConclusion extends React.Component { + constructor(props) { + super(props); + this.keyVerificationState = null; + this.state = { + done: false, + cancelled: false, + otherPartyUserId: null, + cancelPartyUserId: null, + }; + const rel = this.props.mxEvent.getRelation(); + if (rel) { + const client = MatrixClientPeg.get(); + const room = client.getRoom(this.props.mxEvent.getRoomId()); + const requestEvent = room.findEventById(rel.event_id); + if (requestEvent) { + this._createStateObserver(requestEvent, client); + this.state = this._copyState(); + } else { + const findEvent = event => { + if (event.getId() === rel.event_id) { + this._createStateObserver(event, client); + this.setState(this._copyState()); + room.removeListener("Room.timeline", findEvent); + } + }; + room.on("Room.timeline", findEvent); + } + } + } + + _createStateObserver(requestEvent, client) { + this.keyVerificationState = new KeyVerificationStateObserver(requestEvent, client, () => { + this.setState(this._copyState()); + }); + } + + _copyState() { + const {done, cancelled, otherPartyUserId, cancelPartyUserId} = this.keyVerificationState; + return {done, cancelled, otherPartyUserId, cancelPartyUserId}; + } + + componentDidMount() { + if (this.keyVerificationState) { + this.keyVerificationState.attach(); + } + } + + componentWillUnmount() { + if (this.keyVerificationState) { + this.keyVerificationState.detach(); + } + } + + _getName(userId) { + const roomId = this.props.mxEvent.getRoomId(); + const client = MatrixClientPeg.get(); + const room = client.getRoom(roomId); + const member = room.getMember(userId); + return member ? member.name : userId; + } + + _userLabel(userId) { + const name = this._getName(userId); + if (name !== userId) { + return _t("%(name)s (%(userId)s)", {name, userId}); + } else { + return userId; + } + } + + render() { + const {mxEvent} = this.props; + const client = MatrixClientPeg.get(); + const myUserId = client.getUserId(); + let title; + + if (this.state.done) { + title = _t("You verified %(name)s", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + } else if (this.state.cancelled) { + if (mxEvent.getSender() === myUserId) { + title = _t("You cancelled verifying %(name)s", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + } else if (mxEvent.getSender() === this.state.otherPartyUserId) { + title = _t("%(name)s cancelled verifying", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + } + } + + if (title) { + const subtitle = userLabelForEventRoom(this.state.otherPartyUserId, mxEvent); + const classes = classNames("mx_EventTile_bubble", "mx_KeyVerification", "mx_KeyVerification_icon", { + mx_KeyVerification_icon_verified: this.state.done, + }); + return (
+
{title}
+
{subtitle}
+
); + } + + return null; + } +} + +MKeyVerificationConclusion.propTypes = { + /* the MatrixEvent to show */ + mxEvent: PropTypes.object.isRequired, +}; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index bcf68f8e4b..1dcd2a5129 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1065,6 +1065,16 @@ "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", "Show image": "Show image", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "You verified %(name)s": "You verified %(name)s", + "You cancelled verifying %(name)s": "You cancelled verifying %(name)s", + "%(name)s cancelled verifying": "%(name)s cancelled verifying", + "You accepted": "You accepted", + "%(name)s accepted": "%(name)s accepted", + "You cancelled": "You cancelled", + "%(name)s cancelled": "%(name)s cancelled", + "%(name)s wants to verify": "%(name)s wants to verify", + "You sent a verification request": "You sent a verification request", "Error decrypting video": "Error decrypting video", "Show all": "Show all", "reacted with %(shortName)s": "reacted with %(shortName)s", From 9d67fa9fa185ded789cedb0abbdf7943d7c58f63 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:42:06 +0100 Subject: [PATCH 058/103] render verification request with correct tile only if the request was send by or to us, otherwise ignore. --- src/components/views/rooms/EventTile.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 9497324f5a..fca77fcaf6 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -33,6 +33,7 @@ import dis from '../../../dispatcher'; import SettingsStore from "../../../settings/SettingsStore"; import {EventStatus, MatrixClient} from 'matrix-js-sdk'; import {formatTime} from "../../../DateUtils"; +import MatrixClientPeg from '../../../MatrixClientPeg'; const ObjectUtils = require('../../../ObjectUtils'); @@ -68,6 +69,21 @@ const stateEventTileTypes = { function getHandlerTile(ev) { const type = ev.getType(); + + // don't show verification requests we're not involved in, + // not even when showing hidden events + if (type === "m.room.message") { + const content = ev.getContent(); + if (content && content.msgtype === "m.key.verification.request") { + const client = MatrixClientPeg.get(); + const me = client && client.getUserId(); + if (ev.getSender() !== me && content.to !== me) { + return undefined; + } else { + return "messages.MKeyVerificationRequest"; + } + } + } return ev.isState() ? stateEventTileTypes[type] : eventTileTypes[type]; } From d7f5252f9afa237841f9c78baac9ae33c91230b8 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:43:50 +0100 Subject: [PATCH 059/103] render done and cancel event as conclusion tile don't render any done events not sent by us, as done events are sent by both parties and we don't want to render two conclusion tiles. cancel events should be only sent by one party. --- src/components/views/rooms/EventTile.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index fca77fcaf6..de13fa30e2 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -40,6 +40,8 @@ const ObjectUtils = require('../../../ObjectUtils'); const eventTileTypes = { 'm.room.message': 'messages.MessageEvent', 'm.sticker': 'messages.MessageEvent', + 'm.key.verification.cancel': 'messages.MKeyVerificationConclusion', + 'm.key.verification.done': 'messages.MKeyVerificationConclusion', 'm.call.invite': 'messages.TextualEvent', 'm.call.answer': 'messages.TextualEvent', 'm.call.hangup': 'messages.TextualEvent', @@ -84,6 +86,16 @@ function getHandlerTile(ev) { } } } + // these events are sent by both parties during verification, but we only want to render one + // tile once the verification concludes, so filter out the one from the other party. + if (type === "m.key.verification.done") { + const client = MatrixClientPeg.get(); + const me = client && client.getUserId(); + if (ev.getSender() !== me) { + return undefined; + } + } + return ev.isState() ? stateEventTileTypes[type] : eventTileTypes[type]; } From 805c83779a2bf1420fb40118041a197b6f26e828 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:44:53 +0100 Subject: [PATCH 060/103] support bubble tile style for verification tiles --- src/components/views/rooms/EventTile.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index de13fa30e2..7105ee2635 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -555,8 +555,10 @@ module.exports = createReactClass({ const eventType = this.props.mxEvent.getType(); // Info messages are basically information about commands processed on a room + const isBubbleMessage = eventType.startsWith("m.key.verification") || + (eventType === "m.room.message" && msgtype.startsWith("m.key.verification")); let isInfoMessage = ( - eventType !== 'm.room.message' && eventType !== 'm.sticker' && eventType != 'm.room.create' + !isBubbleMessage && eventType !== 'm.room.message' && eventType !== 'm.sticker' && eventType != 'm.room.create' ); let tileHandler = getHandlerTile(this.props.mxEvent); @@ -589,6 +591,7 @@ module.exports = createReactClass({ const isEditing = !!this.props.editState; const classes = classNames({ + mx_EventTile_bubbleContainer: isBubbleMessage, mx_EventTile: true, mx_EventTile_isEditing: isEditing, mx_EventTile_info: isInfoMessage, @@ -624,7 +627,7 @@ module.exports = createReactClass({ if (this.props.tileShape === "notif") { avatarSize = 24; needsSenderProfile = true; - } else if (tileHandler === 'messages.RoomCreate') { + } else if (tileHandler === 'messages.RoomCreate' || isBubbleMessage) { avatarSize = 0; needsSenderProfile = false; } else if (isInfoMessage) { @@ -822,7 +825,7 @@ module.exports = createReactClass({ { readAvatars }
{ sender } -
+
Date: Thu, 7 Nov 2019 20:01:33 +0100 Subject: [PATCH 061/103] string has moved in i18n apparently --- src/i18n/strings/en_EN.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 1dcd2a5129..5f6e327944 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -291,6 +291,7 @@ "%(items)s and %(count)s others|other": "%(items)s and %(count)s others", "%(items)s and %(count)s others|one": "%(items)s and one other", "%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", "Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions", "Not a valid Riot keyfile": "Not a valid Riot keyfile", "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", @@ -1065,7 +1066,6 @@ "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", "Show image": "Show image", - "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", "You verified %(name)s": "You verified %(name)s", "You cancelled verifying %(name)s": "You cancelled verifying %(name)s", "%(name)s cancelled verifying": "%(name)s cancelled verifying", From d83f3632f6f39f7f6d017dc2d54a3e514aea3434 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 20:04:36 +0100 Subject: [PATCH 062/103] make the linter happy --- src/components/views/messages/MKeyVerificationConclusion.js | 6 ++++-- src/components/views/rooms/EventTile.js | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/views/messages/MKeyVerificationConclusion.js b/src/components/views/messages/MKeyVerificationConclusion.js index e955d6159d..0bd8e2d3d8 100644 --- a/src/components/views/messages/MKeyVerificationConclusion.js +++ b/src/components/views/messages/MKeyVerificationConclusion.js @@ -103,9 +103,11 @@ export default class MKeyVerificationConclusion extends React.Component { title = _t("You verified %(name)s", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); } else if (this.state.cancelled) { if (mxEvent.getSender() === myUserId) { - title = _t("You cancelled verifying %(name)s", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + title = _t("You cancelled verifying %(name)s", + {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); } else if (mxEvent.getSender() === this.state.otherPartyUserId) { - title = _t("%(name)s cancelled verifying", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + title = _t("%(name)s cancelled verifying", + {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); } } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 7105ee2635..786a72f5b3 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -558,7 +558,8 @@ module.exports = createReactClass({ const isBubbleMessage = eventType.startsWith("m.key.verification") || (eventType === "m.room.message" && msgtype.startsWith("m.key.verification")); let isInfoMessage = ( - !isBubbleMessage && eventType !== 'm.room.message' && eventType !== 'm.sticker' && eventType != 'm.room.create' + !isBubbleMessage && eventType !== 'm.room.message' && + eventType !== 'm.sticker' && eventType != 'm.room.create' ); let tileHandler = getHandlerTile(this.props.mxEvent); From 2516d8ee61de0a9f76ee4c44fc8084de2b7befa4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 20:11:31 +0100 Subject: [PATCH 063/103] fix repeated css class --- res/css/views/rooms/_EventTile.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 04c1065092..98bfa248ff 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -121,7 +121,7 @@ limitations under the License. line-height: 22px; } -.mx_EventTile_bubbleContainer.mx_EventTile_bubbleContainer { +.mx_EventTile_bubbleContainer { display: grid; grid-template-columns: 1fr 100px; From cf80cb559e35b5c35694664921c98dd143fc4863 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 7 Nov 2019 15:09:23 -0700 Subject: [PATCH 064/103] Match identity server registration to the IS r0.3.0 spec The returned field is `token` for the spec, but we somehow got through with `access_token` on Sydent. --- src/IdentityAuthClient.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js index f21db12c51..24f11be474 100644 --- a/src/IdentityAuthClient.js +++ b/src/IdentityAuthClient.js @@ -183,8 +183,10 @@ export default class IdentityAuthClient { async registerForToken(check=true) { try { const hsOpenIdToken = await MatrixClientPeg.get().getOpenIdToken(); - const { access_token: identityAccessToken } = + // XXX: The spec is `token`, but we used `access_token` for a Sydent release. + const { access_token, token } = await this._matrixClient.registerWithIdentityServer(hsOpenIdToken); + let identityAccessToken = token ? token : access_token; if (check) await this._checkToken(identityAccessToken); return identityAccessToken; } catch (e) { From f0e02f59b46b04f01a3ea1ea09e9aa4f30129874 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 7 Nov 2019 15:12:55 -0700 Subject: [PATCH 065/103] Appease the linter --- src/IdentityAuthClient.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js index 24f11be474..c82c93e7a6 100644 --- a/src/IdentityAuthClient.js +++ b/src/IdentityAuthClient.js @@ -184,9 +184,9 @@ export default class IdentityAuthClient { try { const hsOpenIdToken = await MatrixClientPeg.get().getOpenIdToken(); // XXX: The spec is `token`, but we used `access_token` for a Sydent release. - const { access_token, token } = + const { access_token: accessToken, token } = await this._matrixClient.registerWithIdentityServer(hsOpenIdToken); - let identityAccessToken = token ? token : access_token; + const identityAccessToken = token ? token : accessToken; if (check) await this._checkToken(identityAccessToken); return identityAccessToken; } catch (e) { From 4283f9ec74b50748ebcc18360c68dab5e0c86eae Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 8 Nov 2019 16:01:53 +0000 Subject: [PATCH 066/103] Split CSS rule to fix descending specificity lint error --- res/css/views/rooms/_EventTile.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 98bfa248ff..81924d2be3 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -130,10 +130,6 @@ limitations under the License. grid-column: 1 / 3; padding: 0; } - - .mx_EventTile_msgOption { - grid-column: 2; - } } .mx_EventTile_reply { @@ -278,6 +274,10 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { margin-right: 10px; } +.mx_EventTile_bubbleContainer.mx_EventTile_msgOption { + grid-column: 2; +} + .mx_EventTile_msgOption a { text-decoration: none; } From 3070ee6d7b370ae13f9d0d2b6e7f759daf83bb0a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 8 Nov 2019 16:10:51 +0000 Subject: [PATCH 067/103] Put back the grouped rule & disable the linting rule instead --- .stylelintrc.js | 1 + res/css/views/rooms/_EventTile.scss | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.stylelintrc.js b/.stylelintrc.js index f028c76cc0..1690f2186f 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -15,6 +15,7 @@ module.exports = { "number-leading-zero": null, "selector-list-comma-newline-after": null, "at-rule-no-unknown": null, + "no-descending-specificity": null, "scss/at-rule-no-unknown": [true, { // https://github.com/vector-im/riot-web/issues/10544 "ignoreAtRules": ["define-mixin"], diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 81924d2be3..98bfa248ff 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -130,6 +130,10 @@ limitations under the License. grid-column: 1 / 3; padding: 0; } + + .mx_EventTile_msgOption { + grid-column: 2; + } } .mx_EventTile_reply { @@ -274,10 +278,6 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { margin-right: 10px; } -.mx_EventTile_bubbleContainer.mx_EventTile_msgOption { - grid-column: 2; -} - .mx_EventTile_msgOption a { text-decoration: none; } From 06ab9efed639c8944c6181290c6683122151540a Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Tue, 5 Nov 2019 07:16:59 +0000 Subject: [PATCH 068/103] Translated using Weblate (Bulgarian) Currently translated at 100.0% (1853 of 1853 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 | 47 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 2287c5b295..6f198b2e5a 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -2204,5 +2204,50 @@ "wait and try again later": "изчакате и опитате пак", "Clear cache and reload": "Изчисти кеша и презареди", "Show tray icon and minimize window to it on close": "Показвай икона в лентата и минимизирай прозореца там при затваряне", - "Your email address hasn't been verified yet": "Имейл адресът ви все още не е потвърден" + "Your email address hasn't been verified yet": "Имейл адресът ви все още не е потвърден", + "Click the link in the email you received to verify and then click continue again.": "Кликнете на връзката получена по имейл за да потвърдите, а след това натиснете продължи отново.", + "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "На път сте да премахнете 1 съобщение от %(user)s. Това е необратимо. Искате ли да продължите?", + "Remove %(count)s messages|one": "Премахни 1 съобщение", + "Room %(name)s": "Стая %(name)s", + "Recent rooms": "Скорошни стаи", + "%(count)s unread messages including mentions.|other": "%(count)s непрочетени съобщения, включително споменавания.", + "%(count)s unread messages including mentions.|one": "1 непрочетено споменаване.", + "%(count)s unread messages.|other": "%(count)s непрочетени съобщения.", + "%(count)s unread messages.|one": "1 непрочетено съобщение.", + "Unread mentions.": "Непрочетени споменавания.", + "Unread messages.": "Непрочетени съобщения.", + "Trust & Devices": "Доверие и устройства", + "Direct messages": "Директни съобщения", + "Failed to deactivate user": "Неуспешно деактивиране на потребител", + "This client does not support end-to-end encryption.": "Този клиент не поддържа шифроване от край до край.", + "Messages in this room are not end-to-end encrypted.": "Съобщенията в тази стая не са шифровани от край до край.", + "React": "Реагирай", + "Message Actions": "Действия със съобщението", + "Show image": "Покажи снимката", + "Frequently Used": "Често използвани", + "Smileys & People": "Усмивки и хора", + "Animals & Nature": "Животни и природа", + "Food & Drink": "Храна и напитки", + "Activities": "Действия", + "Travel & Places": "Пътуване и места", + "Objects": "Обекти", + "Symbols": "Символи", + "Flags": "Знамена", + "Quick Reactions": "Бързи реакции", + "Cancel search": "Отмени търсенето", + "Please create a new issue on GitHub so that we can investigate this bug.": "Моля, отворете нов проблем в GitHub за да проучим проблема.", + "To continue you need to accept the terms of this service.": "За да продължите, трябва да приемете условията за ползване.", + "Document": "Документ", + "Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "Липсва публичния ключ за catcha в конфигурацията на сървъра. Съобщете това на администратора на сървъра.", + "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Не е конфигуриран сървър за самоличност, така че не можете да добавите имейл адрес за възстановяване на паролата в бъдеще.", + "%(creator)s created and configured the room.": "%(creator)s създаде и настрой стаята.", + "Jump to first unread room.": "Отиди до първата непрочетена стая.", + "Jump to first invite.": "Отиди до първата покана.", + "Command Autocomplete": "Подсказка за команди", + "Community Autocomplete": "Подсказка за общности", + "DuckDuckGo Results": "DuckDuckGo резултати", + "Emoji Autocomplete": "Подсказка за емоджита", + "Notification Autocomplete": "Подсказка за уведомления", + "Room Autocomplete": "Подсказка за стаи", + "User Autocomplete": "Подсказка за потребители" } From dc5abbe3809831e00a8d2d1f2ed85d8c77bf364a Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 5 Nov 2019 03:58:00 +0000 Subject: [PATCH 069/103] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1853 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 94183ef83f..58dca89415 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2272,5 +2272,6 @@ "Unread messages.": "未讀的訊息。", "Show tray icon and minimize window to it on close": "顯示系統匣圖示並在關閉視窗時將其最小化至其中", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "此動作需要存取預設的身份識別伺服器 以驗證電子郵件或電話號碼,但伺服器沒有任何服務條款。", - "Trust": "信任" + "Trust": "信任", + "Message Actions": "訊息動作" } From 6d4971c29eb2b760f15dae41085d5b164d5dc8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Mon, 4 Nov 2019 12:28:24 +0000 Subject: [PATCH 070/103] Translated using Weblate (French) Currently translated at 100.0% (1853 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 7807facb1c..328c3b7f9e 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2279,5 +2279,6 @@ "Unread messages.": "Messages non lus.", "Show tray icon and minimize window to it on close": "Afficher l’icône dans la barre d’état et minimiser la fenêtre lors de la fermeture", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Cette action nécessite l’accès au serveur d’identité par défaut afin de valider une adresse e-mail ou un numéro de téléphone, mais le serveur n’a aucune condition de service.", - "Trust": "Confiance" + "Trust": "Confiance", + "Message Actions": "Actions de message" } From 4eb39190b493159f863debf7987b86980f8cd5b7 Mon Sep 17 00:00:00 2001 From: dreamerchris Date: Tue, 5 Nov 2019 12:12:12 +0000 Subject: [PATCH 071/103] Translated using Weblate (Greek) Currently translated at 39.7% (735 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/el/ --- src/i18n/strings/el.json | 91 +++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index c5d6468881..a2438cc22c 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -57,7 +57,7 @@ "%(senderDisplayName)s removed the room name.": "Ο %(senderDisplayName)s διέγραψε το όνομα του δωματίου.", "Changes your display nickname": "Αλλάζει το ψευδώνυμο χρήστη", "Conference call failed.": "Η κλήση συνδιάσκεψης απέτυχε.", - "powered by Matrix": "με τη βοήθεια του Matrix", + "powered by Matrix": "λειτουργεί με το Matrix", "Confirm password": "Επιβεβαίωση κωδικού πρόσβασης", "Confirm your new password": "Επιβεβαίωση του νέου κωδικού πρόσβασης", "Continue": "Συνέχεια", @@ -567,7 +567,7 @@ "numbullet": "απαρίθμηση", "You must join the room to see its files": "Πρέπει να συνδεθείτε στο δωμάτιο για να δείτε τα αρχεία του", "Reject all %(invitedRooms)s invites": "Απόρριψη όλων των προσκλήσεων %(invitedRooms)s", - "Failed to invite the following users to the %(roomName)s room:": "Δεν ήταν δυνατή η πρόσκληση των χρηστών στο δωμάτιο %(roomName)s:", + "Failed to invite the following users to the %(roomName)s room:": "Δεν ήταν δυνατή η πρόσκληση των παρακάτω χρηστών στο δωμάτιο %(roomName)s:", "Deops user with given id": "Deop χρήστη με το συγκεκριμένο αναγνωριστικό", "Drop here to tag %(section)s": "Απόθεση εδώ για ορισμό ετικέτας στο %(section)s", "Join as voice or video.": "Συμμετάσχετε με φωνή ή βίντεο.", @@ -575,7 +575,7 @@ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Εμφάνιση χρονικών σημάνσεων σε 12ωρη μορφή ώρας (π.χ. 2:30 μ.μ.)", "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Το κλειδί υπογραφής που δώσατε αντιστοιχεί στο κλειδί υπογραφής που λάβατε από τη συσκευή %(userId)s %(deviceId)s. Η συσκευή έχει επισημανθεί ως επιβεβαιωμένη.", "To link to a room it must have an address.": "Για να συνδεθείτε σε ένα δωμάτιο πρέπει να έχετε μια διεύθυνση.", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Η διεύθυνση ηλεκτρονικής αλληλογραφίας σας δεν φαίνεται να συσχετίζεται με Matrix ID σε αυτόν τον διακομιστή.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Η διεύθυνση της ηλ. αλληλογραφίας σας δεν φαίνεται να συσχετίζεται με μια ταυτότητα Matrix σε αυτόν τον Διακομιστή Φιλοξενίας.", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Ο κωδικός πρόσβασής σας άλλαξε επιτυχώς. Δεν θα λάβετε ειδοποιήσεις push σε άλλες συσκευές μέχρι να συνδεθείτε ξανά σε αυτές", "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Δεν θα μπορέσετε να αναιρέσετε αυτήν την αλλαγή καθώς προωθείτε τον χρήστη να έχει το ίδιο επίπεδο δύναμης με τον εαυτό σας.", "Sent messages will be stored until your connection has returned.": "Τα απεσταλμένα μηνύματα θα αποθηκευτούν μέχρι να αακτηθεί η σύνδεσή σας.", @@ -765,7 +765,7 @@ "The platform you're on": "Η πλατφόρμα στην οποία βρίσκεστε", "The version of Riot.im": "Η έκδοση του Riot.im", "Your language of choice": "Η γλώσσα επιλογής σας", - "Your homeserver's URL": "Το URL του διακομιστή σας", + "Your homeserver's URL": "Το URL του διακομιστή φιλοξενίας σας", "Every page you use in the app": "Κάθε σελίδα που χρησιμοποιείτε στην εφαρμογή", "e.g. ": "π.χ. ", "Your device resolution": "Η ανάλυση της συσκευής σας", @@ -774,7 +774,7 @@ "Whether or not you're logged in (we don't record your user name)": "Εάν είστε συνδεδεμένος/η ή όχι (δεν καταγράφουμε το όνομα χρήστη σας)", "e.g. %(exampleValue)s": "π.χ. %(exampleValue)s", "Review Devices": "Ανασκόπηση συσκευών", - "Call Anyway": "Κλήση όπως και να 'χει", + "Call Anyway": "Πραγματοποίηση Κλήσης όπως και να 'χει", "Answer Anyway": "Απάντηση όπως και να 'χει", "Call": "Κλήση", "Answer": "Απάντηση", @@ -785,20 +785,20 @@ "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Προσοχή: κάθε άτομο που προσθέτετε στην κοινότητα θε είναι δημοσίως ορατό σε οποιονδήποτε γνωρίζει το αναγνωριστικό της κοινότητας", "Invite new community members": "Προσκαλέστε νέα μέλη στην κοινότητα", "Name or matrix ID": "Όνομα ή αναγνωριστικό του matrix", - "Invite to Community": "Πρόσκληση στην κοινότητα", + "Invite to Community": "Προσκαλέστε στην κοινότητα", "Which rooms would you like to add to this community?": "Ποια δωμάτια θα θέλατε να προσθέσετε σε αυτή την κοινότητα;", "Add rooms to the community": "Προσθήκη δωματίων στην κοινότητα", "Add to community": "Προσθήκη στην κοινότητα", - "Failed to invite the following users to %(groupId)s:": "Αποτυχία πρόσκλησης των ακόλουθων χρηστών στο %(groupId)s :", + "Failed to invite the following users to %(groupId)s:": "Αποτυχία πρόσκλησης στο %(groupId)s των χρηστών:", "Failed to invite users to community": "Αποτυχία πρόσκλησης χρηστών στην κοινότητα", "Failed to invite users to %(groupId)s": "Αποτυχία πρόσκλησης χρηστών στο %(groupId)s", - "Failed to add the following rooms to %(groupId)s:": "Αποτυχία προσθήκης των ακόλουθων δωματίων στο %(groupId)s:", + "Failed to add the following rooms to %(groupId)s:": "Αποτυχία προσθήκης στο %(groupId)s των δωματίων:", "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Υπάρχουν άγνωστες συσκευές στο δωμάτιο: εάν συνεχίσετε χωρίς να τις επιβεβαιώσετε, θα μπορούσε κάποιος να κρυφακούει την κλήση σας.", "Show these rooms to non-members on the community page and room list?": "Εμφάνιση αυτών των δωματίων σε μη-μέλη στην σελίδα της κοινότητας και στη λίστα δωματίων;", "Room name or alias": "Όνομα η ψευδώνυμο δωματίου", - "Restricted": "Περιορισμένο", - "Unable to create widget.": "Αδυναμία δημιουργίας widget.", - "Reload widget": "Ανανέωση widget", + "Restricted": "Περιορισμένο/η", + "Unable to create widget.": "Αδυναμία δημιουργίας γραφικού στοιχείου.", + "Reload widget": "Επαναφόρτωση γραφικού στοιχείου", "You are not in this room.": "Δεν είστε μέλος αυτού του δωματίου.", "You do not have permission to do that in this room.": "Δεν έχετε την άδεια να το κάνετε αυτό σε αυτό το δωμάτιο.", "You are now ignoring %(userId)s": "Τώρα αγνοείτε τον/την %(userId)s", @@ -818,14 +818,14 @@ "Delete %(count)s devices|other": "Διαγραφή %(count)s συσκευών", "Delete %(count)s devices|one": "Διαγραφή συσκευής", "Select devices": "Επιλογή συσκευών", - "Cannot add any more widgets": "Δεν είναι δυνατή η προσθήκη άλλων widget", - "The maximum permitted number of widgets have already been added to this room.": "Ο μέγιστος επιτρεπτός αριθμός widget έχει ήδη προστεθεί σε αυτό το δωμάτιο.", - "Add a widget": "Προσθήκη widget", + "Cannot add any more widgets": "Δεν είναι δυνατή η προσθήκη άλλων γραφικών στοιχείων", + "The maximum permitted number of widgets have already been added to this room.": "Ο μέγιστος επιτρεπτός αριθμός γραφικών στοιχείων έχει ήδη προστεθεί σε αυτό το δωμάτιο.", + "Add a widget": "Προσθέστε ένα γραφικό στοιχείο", "%(senderName)s sent an image": "Ο/Η %(senderName)s έστειλε μία εικόνα", "%(senderName)s sent a video": "Ο/Η %(senderName)s έστειλε ένα βίντεο", "%(senderName)s uploaded a file": "Ο/Η %(senderName)s αναφόρτωσε ένα αρχείο", "If your other devices do not have the key for this message you will not be able to decrypt them.": "Εάν οι άλλες συσκευές σας δεν έχουν το κλειδί για αυτό το μήνυμα, τότε δεν θα μπορείτε να το αποκρυπτογραφήσετε.", - "Disinvite this user?": "Ακύρωση πρόσκλησης αυτού του χρήστη;", + "Disinvite this user?": "Απόσυρση της πρόσκλησης αυτού του χρήστη;", "Mention": "Αναφορά", "Invite": "Πρόσκληση", "User Options": "Επιλογές Χρήστη", @@ -849,5 +849,64 @@ "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Διαβάστηκε από τον/την %(displayName)s (%(userName)s) στις %(dateTime)s", "Room Notification": "Ειδοποίηση Δωματίου", "Notify the whole room": "Ειδοποιήστε όλο το δωμάτιο", - "Sets the room topic": "Ορίζει το θέμα του δωματίου" + "Sets the room topic": "Ορίζει το θέμα του δωματίου", + "Add Email Address": "Προσθήκη Διεύθυνσης Ηλ. Ταχυδρομείου", + "Add Phone Number": "Προσθήκη Τηλεφωνικού Αριθμού", + "Whether or not you're logged in (we don't record your username)": "Χωρίς να έχει σημασία εάν είστε συνδεδεμένοι (δεν καταγράφουμε το όνομα χρήστη σας)", + "Which officially provided instance you are using, if any": "Ποιά επίσημα παρεχόμενη έκδοση χρησιμοποιείτε, εάν χρησιμοποιείτε κάποια", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Χωρίς να έχει σημασία εάν χρησιμοποιείτε την λειτουργία \"Πλούσιο Κείμενο\" του Επεξεργαστή Πλουσίου Κειμένου", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Χωρίς να έχει σημασία εάν χρησιμοποιείτε το χαρακτηριστικό 'ψίχουλα' (τα άβαταρ πάνω από την λίστα δωματίων)", + "Your User Agent": "Ο Πράκτορας Χρήστη σας", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Όπου αυτή η σελίδα περιέχει αναγνωρίσιμες πληροφορίες, όπως ταυτότητα δωματίου, χρήστη ή ομάδας, αυτά τα δεδομένα αφαιρούνται πριν πραγματοποιηθεί αποστολή στον διακομιστή.", + "Call failed due to misconfigured server": "Η κλήση απέτυχε λόγω της λανθασμένης διάρθρωσης του διακομιστή", + "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Παρακαλείστε να ρωτήσετε τον διαχειριστή του διακομιστή φιλοξενίας σας (%(homeserverDomain)s) να ρυθμίσουν έναν διακομιστή πρωτοκόλλου TURN ώστε οι κλήσεις να λειτουργούν απρόσκοπτα.", + "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.": "Εναλλακτικά, δοκιμάστε να χρησιμοποιήσετε τον δημόσιο διακομιστή στο turn.matrix.org, αλλά δεν θα είναι το ίδιο απρόσκοπτο, και θα κοινοποιεί την διεύθυνση IP σας με τον διακομιστή. Μπορείτε επίσης να το διαχειριστείτε στις Ρυθμίσεις.", + "Try using turn.matrix.org": "Δοκιμάστε το turn.matrix.org", + "A conference call could not be started because the integrations server is not available": "Μια κλήση συνδιάσκεψης δεν μπορούσε να ξεκινήσει διότι ο διακομιστής ενσωμάτωσης είναι μη διαθέσιμος", + "Call in Progress": "Κλήση σε Εξέλιξη", + "A call is currently being placed!": "Μια κλήση πραγματοποιείτε τώρα!", + "A call is already in progress!": "Μια κλήση είναι σε εξέλιξη ήδη!", + "Permission Required": "Απαιτείται Άδεια", + "You do not have permission to start a conference call in this room": "Δεν έχετε άδεια για να ξεκινήσετε μια κλήση συνδιάσκεψης σε αυτό το δωμάτιο", + "Replying With Files": "Απαντώντας Με Αρχεία", + "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Αυτήν την στιγμή δεν είναι δυνατό να απαντήσετε με αρχείο. Θα θέλατε να ανεβάσετε το αρχείο χωρίς να απαντήσετε;", + "The file '%(fileName)s' failed to upload.": "Απέτυχε το ανέβασμα του αρχείου '%(fileName)s'.", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Το αρχείο '%(fileName)s' ξεπερνάει το όριο μεγέθους ανεβάσματος αυτού του διακομιστή φιλοξενίας", + "The server does not support the room version specified.": "Ο διακομιστής δεν υποστηρίζει την έκδοση του δωματίου που ορίστηκε.", + "Name or Matrix ID": "Όνομα ή ταυτότητα Matrix", + "Identity server has no terms of service": "Ο διακομιστής ταυτοποίησης δεν έχει όρους χρήσης", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Αυτή η δράση απαιτεί την πρόσβαση στο προκαθορισμένο διακομιστή ταυτοποίησης για να επιβεβαιώσει μια διεύθυνση ηλ. ταχυδρομείου ή αριθμό τηλεφώνου, αλλά ο διακομιστής δεν έχει όρους χρήσης.", + "Only continue if you trust the owner of the server.": "Συνεχίστε μόνο εάν εμπιστεύεστε τον ιδιοκτήτη του διακομιστή.", + "Trust": "Εμπιστοσύνη", + "Unable to load! Check your network connectivity and try again.": "Αδυναμία φόρτωσης! Ελέγξτε την σύνδεση του δικτύου και προσπαθήστε ξανά.", + "Registration Required": "Απαιτείτε Εγγραφή", + "You need to register to do this. Would you like to register now?": "Χρειάζεται να γίνει εγγραφή για αυτό. Θα θέλατε να κάνετε εγγραφή τώρα;", + "Email, name or Matrix ID": "Ηλ. ταχυδρομείο, όνομα ή ταυτότητα Matrix", + "Failed to start chat": "Αποτυχία αρχικοποίησης συνομιλίας", + "Failed to invite users to the room:": "Αποτυχία πρόσκλησης χρηστών στο δωμάτιο:", + "Missing roomId.": "Λείπει η ταυτότητα δωματίου.", + "Messages": "Μηνύματα", + "Actions": "Δράσεις", + "Other": "Άλλα", + "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Προ-εισάγει ¯\\_(ツ)_/¯ σε ένα μήνυμα απλού κειμένου", + "Sends a message as plain text, without interpreting it as markdown": "Αποστέλλει ένα μήνυμα ως απλό κείμενο, χωρίς να το ερμηνεύει ως \"markdown\"", + "Upgrades a room to a new version": "Αναβαθμίζει το δωμάτιο σε μια καινούργια έκδοση", + "You do not have the required permissions to use this command.": "Δεν διαθέτετε τις απαιτούμενες άδειες για να χρησιμοποιήσετε αυτήν την εντολή.", + "Room upgrade confirmation": "Επιβεβαίωση αναβάθμισης δωματίου", + "Upgrading a room can be destructive and isn't always necessary.": "Η αναβάθμιση ενός δωματίου μπορεί να είναι καταστροφική και δεν είναι πάντα απαραίτητη.", + "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Οι αναβαθμίσεις δωματίου είναι συνήθως προτεινόμενες όταν μια έκδοση δωματίου θεωρείτε ασταθής. Ασταθείς εκδόσεις δωματίων μπορεί να έχουν σφάλματα, ελλειπή χαρακτηριστικά, ή αδυναμίες ασφαλείας.", + "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .": "Οι αναβαθμίσεις δωματίων συνήθως επηρεάζουν μόνο την επεξεργασία του δωματίου από την πλευρά του διακομιστή. Εάν έχετε προβλήματα με το πρόγραμμα-πελάτη Riot, παρακαλώ αρχειοθετήστε ένα πρόβλημα μέσω .", + "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Προσοχή: Αναβαθμίζοντας ένα δωμάτιο δεν θα μεταφέρει αυτόματα τα μέλη του δωματίου στη νέα έκδοση του δωματίου. Θα αναρτήσουμε ένα σύνδεσμο προς το νέο δωμάτιο στη παλιά έκδοση του δωματίου - τα μέλη του δωματίου θα πρέπει να πατήσουν στον σύνδεσμο για να μπουν στο νέο δωμάτιο.", + "Please confirm that you'd like to go forward with upgrading this room from to .": "Παρακαλώ επιβεβαιώστε ότι θα θέλατε να προχωρήσετε με την αναβάθμιση του δωματίου από σε .", + "Upgrade": "Αναβάθμιση", + "Changes your display nickname in the current room only": "Αλλάζει το εμφανιζόμενο ψευδώνυμο μόνο στο παρόν δωμάτιο", + "Changes the avatar of the current room": "Αλλάζει το άβαταρ αυτού του δωματίου", + "Changes your avatar in this current room only": "Αλλάζει το άβαταρ σας μόνο στο παρόν δωμάτιο", + "Changes your avatar in all rooms": "Αλλάζει το άβαταρ σας σε όλα τα δωμάτια", + "Gets or sets the room topic": "Λαμβάνει ή θέτει το θέμα του δωματίου", + "This room has no topic.": "Το δωμάτιο αυτό δεν έχει κανένα θέμα.", + "Sets the room name": "Θέτει το θέμα του δωματίου", + "Use an identity server": "Χρησιμοποιήστε ένα διακομιστή ταυτοτήτων", + "Your Riot is misconfigured": "Οι παράμετροι του Riot σας είναι λανθασμένα ρυθμισμένοι", + "Explore rooms": "Εξερευνήστε δωμάτια" } From 84d23676d6002005c7ff5b906e383eeef1300647 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 4 Nov 2019 21:14:13 +0000 Subject: [PATCH 072/103] Translated using Weblate (Hungarian) Currently translated at 100.0% (1853 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 4946c7b14f..5d21a17e37 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2266,5 +2266,6 @@ "Unread messages.": "Olvasatlan üzenetek.", "Show tray icon and minimize window to it on close": "Tálcaikon mutatása és az ablak összecsukása bezáráskor", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Ez a művelet az e-mail cím vagy telefonszám ellenőrzése miatt hozzáférést igényel az alapértelmezett azonosítási szerverhez (), de a szervernek nincsen semmilyen felhasználási feltétele.", - "Trust": "Megbízom benne" + "Trust": "Megbízom benne", + "Message Actions": "Üzenet Műveletek" } From 8b3844f83b6d47053d01ffa391c51b35255c9118 Mon Sep 17 00:00:00 2001 From: shuji narazaki Date: Thu, 7 Nov 2019 23:12:55 +0000 Subject: [PATCH 073/103] Translated using Weblate (Japanese) Currently translated at 60.8% (1126 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ja/ --- src/i18n/strings/ja.json | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json index 23199094e8..5e3fecaed9 100644 --- a/src/i18n/strings/ja.json +++ b/src/i18n/strings/ja.json @@ -1343,5 +1343,42 @@ "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s はこの部屋をアップグレードしました。", "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s はこの部屋をリンクを知っている人全てに公開しました。", "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s はこの部屋を招待者のみに変更しました。", - "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s はゲストがこの部屋に参加できるようにしました。" + "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s はゲストがこの部屋に参加できるようにしました。", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "「パンくずリスト」機能(部屋リストの上のアバター)を使っているかどうか", + "Only continue if you trust the owner of the server.": "そのサーバーの所有者を信頼する場合のみ続ける。", + "Trust": "信頼", + "Use an identity server to invite by email. Manage in Settings.": "メールによる招待のためにIDサーバーを用いる。設定画面で管理する。", + "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s は参加ルールを %(rule)s に変更しました", + "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s はゲストの部屋への参加を差し止めています。", + "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s はゲストのアクセスを %(rule)s に変更しました", + "%(displayName)s is typing …": "%(displayName)s が入力中 …", + "%(names)s and %(count)s others are typing …|other": "%(names)s と他 %(count)s 名が入力中 …", + "%(names)s and %(count)s others are typing …|one": "%(names)s ともう一人が入力中 …", + "%(names)s and %(lastPerson)s are typing …": "%(names)s と %(lastPerson)s が入力中 …", + "Cannot reach homeserver": "ホームサーバーに接続できません", + "Your Riot is misconfigured": "あなたのRiotは設定が間違っています", + "Cannot reach identity server": "IDサーバーに接続できません", + "No homeserver URL provided": "ホームサーバーのURLが与えられていません", + "User %(userId)s is already in the room": "ユーザー %(userId)s はすでにその部屋にいます", + "User %(user_id)s does not exist": "ユーザー %(user_id)s は存在しません", + "The user's homeserver does not support the version of the room.": "そのユーザーのホームサーバーはその部屋のバージョンに対応していません。", + "Use a few words, avoid common phrases": "ありふれた語句を避けて、いくつかの単語を使ってください", + "This is a top-10 common password": "これがよく使われるパスワードの上位10個です", + "This is a top-100 common password": "これがよく使われるパスワードの上位100個です", + "This is a very common password": "これはとてもよく使われるパスワードです", + "This is similar to a commonly used password": "これはよく使われるパスワードに似ています", + "A word by itself is easy to guess": "単語一つだけだと簡単に特定されます", + "Custom user status messages": "ユーザーステータスのメッセージをカスタマイズする", + "Render simple counters in room header": "部屋のヘッダーに簡単なカウンターを表示する", + "Use the new, faster, composer for writing messages": "メッセージの編集に新しい高速なコンポーザーを使う", + "Enable Emoji suggestions while typing": "入力中の絵文字提案機能を有効にする", + "Show avatar changes": "アバターの変更を表示する", + "Show display name changes": "表示名の変更を表示する", + "Show read receipts sent by other users": "他の人の既読情報を表示する", + "Enable big emoji in chat": "チャットで大きな絵文字を有効にする", + "Send typing notifications": "入力中であることを通知する", + "Enable Community Filter Panel": "コミュニティーフィルターパネルを有効にする", + "Show recently visited rooms above the room list": "最近訪問した部屋をリストの上位に表示する", + "Low bandwidth mode": "低帯域通信モード", + "Trust & Devices": "信頼と端末" } From defe3fb5f81e2d34d4c91fcd43e820e30c2b2f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=83=9C=EC=84=AD?= Date: Mon, 4 Nov 2019 15:39:35 +0000 Subject: [PATCH 074/103] Translated using Weblate (Korean) Currently translated at 100.0% (1853 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ko/ --- src/i18n/strings/ko.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 1aebd0ce17..54425657cf 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -2123,5 +2123,6 @@ "Unread messages.": "읽지 않은 메시지.", "Show tray icon and minimize window to it on close": "닫을 때 창을 최소화하고 트레이 아이콘으로 표시하기", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "이 작업에는 이메일 주소 또는 전화번호를 확인하기 위해 기본 ID 서버 에 접근해야 합니다. 하지만 서버가 서비스 약관을 갖고 있지 않습니다.", - "Trust": "신뢰함" + "Trust": "신뢰함", + "Message Actions": "메시지 동작" } From 824a26549644de047d6dd75d46b9bde0babd47a6 Mon Sep 17 00:00:00 2001 From: MamasLT Date: Mon, 4 Nov 2019 22:55:04 +0000 Subject: [PATCH 075/103] Translated using Weblate (Lithuanian) Currently translated at 50.4% (933 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/lt/ --- src/i18n/strings/lt.json | 271 ++++++++++++++++++++++++++++----------- 1 file changed, 194 insertions(+), 77 deletions(-) diff --git a/src/i18n/strings/lt.json b/src/i18n/strings/lt.json index 6a8076ac96..2aeb207387 100644 --- a/src/i18n/strings/lt.json +++ b/src/i18n/strings/lt.json @@ -1,17 +1,17 @@ { "This email address is already in use": "Šis el. pašto adresas jau naudojamas", "This phone number is already in use": "Šis telefono numeris jau naudojamas", - "Failed to verify email address: make sure you clicked the link in the email": "Nepavyko patvirtinti el. pašto adreso: įsitikinkite, kad gautame el. laiške spustelėjote nuorodą", + "Failed to verify email address: make sure you clicked the link in the email": "Nepavyko patvirtinti el. pašto adreso: įsitikinkite, kad paspaudėte nuorodą el. laiške", "The platform you're on": "Jūsų naudojama platforma", "The version of Riot.im": "Riot.im versija", "Whether or not you're logged in (we don't record your user name)": "Nesvarbu ar esate prisijungę ar ne (mes neįrašome jūsų naudotojo vardo)", "Your language of choice": "Jūsų pasirinkta kalba", - "Which officially provided instance you are using, if any": "Kurį oficialiai pateiktą egzempliorių naudojate", - "Whether or not you're using the Richtext mode of the Rich Text Editor": "Ar jūs naudojate Raiškiojo Teksto Redaktoriaus Raiškiojo Teksto režimą ar ne", - "Your homeserver's URL": "Jūsų serverio URL adresas", - "Your identity server's URL": "Jūsų identifikavimo serverio URL adresas", + "Which officially provided instance you are using, if any": "Kurią oficialiai teikiamą instanciją naudojate, jei tokių yra", + "Whether or not you're using the Richtext mode of the Rich Text Editor": "Nepriklausomai nuo to ar jūs naudojate Raiškiojo Teksto Redaktoriaus Raiškiojo Teksto režimą", + "Your homeserver's URL": "Jūsų serverio URL", + "Your identity server's URL": "Jūsų tapatybės serverio URL", "Analytics": "Statistika", - "The information being sent to us to help make Riot.im better includes:": "Informacijoje, kuri yra siunčiama Riot.im tobulinimui yra:", + "The information being sent to us to help make Riot.im better includes:": "Informacija, siunčiama mums, kad padėtų tobulinti Riot.im, apima:", "Fetching third party location failed": "Nepavyko gauti trečios šalies vietos", "A new version of Riot is available.": "Yra prieinama nauja Riot versija.", "I understand the risks and wish to continue": "Aš suprantu riziką ir noriu tęsti", @@ -196,7 +196,7 @@ "Answer Anyway": "Vis tiek atsiliepti", "Call": "Skambinti", "Answer": "Atsiliepti", - "Unable to capture screen": "Nepavyko nufotografuoti ekraną", + "Unable to capture screen": "Nepavyko nufotografuoti ekrano", "You are already in a call.": "Jūs jau dalyvaujate skambutyje.", "VoIP is unsupported": "VoIP yra nepalaikoma", "Could not connect to the integration server": "Nepavyko prisijungti prie integracijos serverio", @@ -210,18 +210,18 @@ "Thu": "Ket", "Fri": "Pen", "Sat": "Šeš", - "Jan": "Sau", + "Jan": "Sausis", "Feb": "Vas", - "Mar": "Kov", + "Mar": "Kovas", "Apr": "Bal", "May": "Geg", - "Jun": "Bir", - "Jul": "Lie", - "Aug": "Rgp", - "Sep": "Rgs", - "Oct": "Spa", - "Nov": "Lap", - "Dec": "Gru", + "Jun": "Birž", + "Jul": "Liepa", + "Aug": "Rugpj", + "Sep": "Rugs", + "Oct": "Spalis", + "Nov": "Lapkr", + "Dec": "Gruodis", "PM": "PM", "AM": "AM", "%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s", @@ -229,16 +229,16 @@ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(fullYear)s %(monthName)s %(day)s", "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(fullYear)s %(monthName)s %(day)s %(time)s", "Who would you like to add to this community?": "Ką norėtumėte pridėti į šią bendruomenę?", - "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Įspėjimas: bet kuris pridėtas asmuo bus matomas visiems, žinantiems bendruomenės ID", + "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Įspėjimas: bet kuris jūsų pridėtas asmuo bus viešai matomas visiems, žinantiems bendruomenės ID", "Name or matrix ID": "Vardas ar matrix ID", "Invite to Community": "Pakviesti į bendruomenę", "Which rooms would you like to add to this community?": "Kuriuos kambarius norėtumėte pridėti į šią bendruomenę?", "Add rooms to the community": "Pridėti kambarius į bendruomenę", "Add to community": "Pridėti į bendruomenę", - "Failed to invite the following users to %(groupId)s:": "Nepavyko pakviesti šių naudotojų į %(groupId)s:", - "Failed to invite users to community": "Nepavyko pakviesti naudotojus į bendruomenę", - "Failed to invite users to %(groupId)s": "Nepavyko pakviesti naudotojų į %(groupId)s", - "Failed to add the following rooms to %(groupId)s:": "Nepavyko pridėti šiuos kambarius į %(groupId)s:", + "Failed to invite the following users to %(groupId)s:": "Nepavyko pakviesti šių vartotojų į %(groupId)s:", + "Failed to invite users to community": "Nepavyko pakviesti vartotojų į bendruomenę", + "Failed to invite users to %(groupId)s": "Nepavyko pakviesti vartotojų į %(groupId)s", + "Failed to add the following rooms to %(groupId)s:": "Nepavyko pridėti šių kambarių į %(groupId)s:", "Riot does not have permission to send you notifications - please check your browser settings": "Riot neturi leidimo siųsti jums pranešimus - patikrinkite savo naršyklės nustatymus", "Riot was not given permission to send notifications - please try again": "Riot nebuvo suteiktas leidimas siųsti pranešimus - bandykite dar kartą", "Unable to enable Notifications": "Nepavyko įjungti Pranešimus", @@ -251,7 +251,7 @@ "Send Invites": "Siųsti pakvietimus", "Failed to invite user": "Nepavyko pakviesti naudotojo", "Failed to invite": "Nepavyko pakviesti", - "Failed to invite the following users to the %(roomName)s room:": "Nepavyko pakviesti šių naudotojų į kambarį %(roomName)s :", + "Failed to invite the following users to the %(roomName)s room:": "Nepavyko pakviesti šių vartotojų į kambarį %(roomName)s:", "You need to be logged in.": "Turite būti prisijungę.", "Unable to create widget.": "Nepavyko sukurti valdiklio.", "Failed to send request.": "Nepavyko išsiųsti užklausos.", @@ -263,8 +263,8 @@ "Changes your display nickname": "Pakeičia jūsų rodomą slapyvardį", "Sets the room topic": "Nustato kambario temą", "Invites user with given id to current room": "Pakviečia naudotoją su nurodytu id į esamą kambarį", - "You are now ignoring %(userId)s": "Dabar nepaisote %(userId)s", - "Opens the Developer Tools dialog": "Atveria kūrėjo įrankių dialogą", + "You are now ignoring %(userId)s": "Dabar ignoruojate %(userId)s", + "Opens the Developer Tools dialog": "Atveria programuotojo įrankių dialogą", "Unknown (user, device) pair:": "Nežinoma pora (naudotojas, įrenginys):", "Device already verified!": "Įrenginys jau patvirtintas!", "WARNING: Device already verified, but keys do NOT MATCH!": "ĮSPĖJIMAS: Įrenginys jau patvirtintas, tačiau raktai NESUTAMPA!", @@ -273,26 +273,26 @@ "Unrecognised command:": "Neatpažinta komanda:", "Reason": "Priežastis", "%(targetName)s accepted an invitation.": "%(targetName)s priėmė pakvietimą.", - "%(senderName)s invited %(targetName)s.": "%(senderName)s pakvietė naudotoją %(targetName)s.", - "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s pasikeitė savo rodomą vardą į %(displayName)s.", - "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s nusistatė savo rodomą vardą į %(displayName)s.", - "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s pašalino savo rodomą vardą (%(oldDisplayName)s).", + "%(senderName)s invited %(targetName)s.": "%(senderName)s pakvietė %(targetName)s.", + "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s pakeitė savo vardą į %(displayName)s.", + "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s nustatė savo vardą į %(displayName)s.", + "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s pašalino savo vardą (%(oldDisplayName)s).", "%(senderName)s removed their profile picture.": "%(senderName)s pašalino savo profilio paveikslą.", - "%(senderName)s changed their profile picture.": "%(senderName)s pasikeitė savo profilio paveikslą.", - "%(senderName)s set a profile picture.": "%(senderName)s nusistatė profilio paveikslą.", + "%(senderName)s changed their profile picture.": "%(senderName)s pakeitė savo profilio paveikslą.", + "%(senderName)s set a profile picture.": "%(senderName)s nustatė profilio paveikslą.", "%(targetName)s rejected the invitation.": "%(targetName)s atmetė pakvietimą.", "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s pakeitė temą į \"%(topic)s\".", "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s pakeitė kambario pavadinimą į %(roomName)s.", "%(senderDisplayName)s sent an image.": "%(senderDisplayName)s išsiuntė paveikslą.", "Someone": "Kažkas", "%(senderName)s answered the call.": "%(senderName)s atsiliepė į skambutį.", - "(unknown failure: %(reason)s)": "(nežinoma lemtingoji klaida: %(reason)s)", + "(unknown failure: %(reason)s)": "(nežinoma klaida: %(reason)s)", "%(senderName)s ended the call.": "%(senderName)s užbaigė skambutį.", "%(displayName)s is typing": "%(displayName)s rašo", "%(names)s and %(count)s others are typing|other": "%(names)s ir dar kiti %(count)s rašo", "%(names)s and %(lastPerson)s are typing": "%(names)s ir %(lastPerson)s rašo", "Send anyway": "Vis tiek siųsti", - "Unnamed Room": "Kambarys be pavadinimo", + "Unnamed Room": "Bevardis kambarys", "Hide removed messages": "Slėpti pašalintas žinutes", "Hide display name changes": "Slėpti rodomo vardo pakeitimus", "Show timestamps in 12 hour format (e.g. 2:30pm)": "Rodyti laiko žymas 12 valandų formatu (pvz., 2:30pm)", @@ -372,7 +372,7 @@ "Settings": "Nustatymai", "Show panel": "Rodyti skydelį", "Press to start a chat with someone": "Norėdami pradėti su kuo nors pokalbį, paspauskite ", - "Community Invites": "", + "Community Invites": "Bendruomenės pakvietimai", "People": "Žmonės", "Reason: %(reasonText)s": "Priežastis: %(reasonText)s", "%(roomName)s does not exist.": "%(roomName)s nėra.", @@ -576,27 +576,27 @@ "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Eksportavimo failas bus apsaugotas slaptafraze. Norėdami iššifruoti failą, čia turėtumėte įvesti slaptafrazę.", "File to import": "Failas, kurį importuoti", "Import": "Importuoti", - "Your User Agent": "Jūsų naudotojo agentas", + "Your User Agent": "Jūsų vartotojo agentas", "Review Devices": "Peržiūrėti įrenginius", "You do not have permission to start a conference call in this room": "Jūs neturite leidimo šiame kambaryje pradėti konferencinį pokalbį", "The file '%(fileName)s' exceeds this home server's size limit for uploads": "Failas \"%(fileName)s\" viršija šio namų serverio įkeliamų failų dydžio apribojimą", "Room name or alias": "Kambario pavadinimas ar slapyvardis", - "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Neatrodo, kad jūsų el. pašto adresas šiame namų serveryje būtų susietas su Matrix ID.", + "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Neatrodo, kad jūsų el. pašto adresas šiame serveryje būtų susietas su Matrix ID.", "Who would you like to communicate with?": "Su kuo norėtumėte susisiekti?", "Missing room_id in request": "Užklausoje trūksta room_id", "Missing user_id in request": "Užklausoje trūksta user_id", "Unrecognised room alias:": "Neatpažintas kambario slapyvardis:", - "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ĮSPĖJIMAS: RAKTO PATVIRTINIMAS NEPAVYKO! Pasirašymo raktas, skirtas %(userId)s ir įrenginiui %(deviceId)s yra \"%(fprint)s\", o tai nesutampa su pateiktu raktu \"%(fingerprint)s\". Tai gali reikšti, kad kažkas perima jūsų komunikavimą!", - "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Jūsų pateiktas pasirašymo raktas sutampa su pasirašymo raktus, kuris gautas iš naudotojo %(userId)s įrenginio %(deviceId)s. Įrenginys pažymėtas kaip patvirtintas.", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ĮSPĖJIMAS: RAKTO PATVIRTINIMAS NEPAVYKO! Pasirašymo raktas, skirtas %(userId)s ir įrenginiui %(deviceId)s yra \"%(fprint)s\", o tai nesutampa su pateiktu raktu \"%(fingerprint)s\". Tai gali reikšti, kad jūsų komunikacijos yra perimamos!", + "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Jūsų pateiktas pasirašymo raktas sutampa su pasirašymo raktu, kurį gavote iš vartotojo %(userId)s įrenginio %(deviceId)s. Įrenginys pažymėtas kaip patvirtintas.", "VoIP conference started.": "VoIP konferencija pradėta.", "VoIP conference finished.": "VoIP konferencija užbaigta.", "%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s pašalino kambario pavadinimą.", - "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s įjungė ištisinį šifravimą (%(algorithm)s algoritmas).", + "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s įjungė end-to-end šifravimą (%(algorithm)s algoritmas).", "%(widgetName)s widget modified by %(senderName)s": "%(senderName)s modifikavo %(widgetName)s valdiklį", "%(widgetName)s widget added by %(senderName)s": "%(senderName)s pridėjo %(widgetName)s valdiklį", "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s pašalino %(widgetName)s valdiklį", "Failure to create room": "Nepavyko sukurti kambarį", - "Server may be unavailable, overloaded, or you hit a bug.": "Gali būti, kad serveris neprieinamas, perkrautas arba susidūrėte su klaida.", + "Server may be unavailable, overloaded, or you hit a bug.": "Serveris gali būti neprieinamas, per daug apkrautas, arba susidūrėte su klaida.", "Use compact timeline layout": "Naudoti kompaktišką laiko juostos išdėstymą", "Autoplay GIFs and videos": "Automatiškai atkurti GIF ir vaizdo įrašus", "Never send encrypted messages to unverified devices from this device": "Niekada nesiųsti iš šio įrenginio šifruotų žinučių į nepatvirtintus įrenginius", @@ -624,30 +624,30 @@ "Invited": "Pakviestas", "Filter room members": "Filtruoti kambario dalyvius", "Server unavailable, overloaded, or something else went wrong.": "Serveris neprieinamas, perkrautas arba nutiko kažkas kito.", - "%(duration)ss": "%(duration)s sek.", - "%(duration)sm": "%(duration)s min.", - "%(duration)sh": "%(duration)s val.", - "%(duration)sd": "%(duration)s d.", + "%(duration)ss": "%(duration)s sek", + "%(duration)sm": "%(duration)s min", + "%(duration)sh": "%(duration)s val", + "%(duration)sd": "%(duration)s d", "Seen by %(userName)s at %(dateTime)s": "%(userName)s matė ties %(dateTime)s", "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "%(displayName)s (%(userName)s) matė ties %(dateTime)s", - "Show these rooms to non-members on the community page and room list?": "Ar rodyti šiuos kambarius ne dalyviams bendruomenės puslapyje ir kambarių sąraše?", + "Show these rooms to non-members on the community page and room list?": "Rodyti šiuos kambarius ne nariams bendruomenės puslapyje ir kambarių sąraše?", "Invite new room members": "Pakviesti naujus kambario dalyvius", "Changes colour scheme of current room": "Pakeičia esamo kambario spalvų rinkinį", - "Kicks user with given id": "Išmeta naudotoją su nurodytu id", - "Bans user with given id": "Užblokuoja naudotoja su nurodytu id", + "Kicks user with given id": "Išmeta vartotoją su nurodytu id", + "Bans user with given id": "Užblokuoja vartotoją su nurodytu id", "Unbans user with given id": "Atblokuoja naudotoją su nurodytu id", - "%(senderName)s banned %(targetName)s.": "%(senderName)s užblokavo naudotoją %(targetName)s.", - "%(senderName)s unbanned %(targetName)s.": "%(senderName)s atblokavo naudotoją %(targetName)s.", - "%(senderName)s kicked %(targetName)s.": "%(senderName)s išmetė naudotoją %(targetName)s.", + "%(senderName)s banned %(targetName)s.": "%(senderName)s užblokavo %(targetName)s.", + "%(senderName)s unbanned %(targetName)s.": "%(senderName)s atblokavo %(targetName)s.", + "%(senderName)s kicked %(targetName)s.": "%(senderName)s išmetė %(targetName)s.", "(not supported by this browser)": "(nėra palaikoma šios naršyklės)", "(no answer)": "(nėra atsakymo)", - "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s padarė kambario ateities istoriją matomą visiems kambario dalyviams nuo to laiko, kai jie buvo pakviesti.", - "%(senderName)s made future room history visible to all room members.": "%(senderName)s padarė kambario ateities istoriją matomą visiems kambario dalyviams.", - "%(senderName)s made future room history visible to anyone.": "%(senderName)s padarė kambario ateities istoriją matomą bet kam.", + "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s padarė būsimą kambario istoriją matomą visiems kambario dalyviams, nuo pat jų pakvietimo.", + "%(senderName)s made future room history visible to all room members.": "%(senderName)s padarė būsimą kambario istoriją matomą visiems kambario dalyviams.", + "%(senderName)s made future room history visible to anyone.": "%(senderName)s padarė būsimą kambario istoriją matomą bet kam.", "%(names)s and %(count)s others are typing|one": "%(names)s ir dar vienas naudotojas rašo", "Your browser does not support the required cryptography extensions": "Jūsų naršyklė nepalaiko reikalingų kriptografijos plėtinių", "Not a valid Riot keyfile": "Negaliojantis Riot rakto failas", - "Authentication check failed: incorrect password?": "Tapatybės nustatymo patikrinimas patyrė nesėkmę: neteisingas slaptažodis?", + "Authentication check failed: incorrect password?": "Autentifikavimo patikra nepavyko: neteisingas slaptažodis?", "Send analytics data": "Siųsti analitinius duomenis", "Incoming voice call from %(name)s": "Gaunamasis balso skambutis nuo %(name)s", "Incoming video call from %(name)s": "Gaunamasis vaizdo skambutis nuo %(name)s", @@ -672,14 +672,14 @@ "Failed to set avatar.": "Nepavyko nustatyti avataro.", "Forget room": "Pamiršti kambarį", "Share room": "Bendrinti kambarį", - "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Šiame kambaryje yra nepatvirtintų įrenginių: jeigu tęsite jų nepatvirtinę, tuomet kas nors galės slapta klausytis jūsų skambučio.", + "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Šiame kambaryje yra nežinomų įrenginių: jei tęsite jų nepatvirtinę, kam nors bus įmanoma slapta klausytis jūsų skambučio.", "Usage": "Naudojimas", "Searches DuckDuckGo for results": "Atlieka rezultatų paiešką sistemoje DuckDuckGo", - "To use it, just wait for autocomplete results to load and tab through them.": "Norėdami tai naudoti, tiesiog, palaukite, kol bus įkelti automatiškai užbaigti rezultatai, o tuomet, pereikite per juos naudodami Tab klavišą.", + "To use it, just wait for autocomplete results to load and tab through them.": "Norėdami tai naudoti, tiesiog palaukite, kol bus įkelti automatiškai užbaigti rezultatai, tuomet pereikite per juos naudodami Tab klavišą.", "%(targetName)s left the room.": "%(targetName)s išėjo iš kambario.", "%(senderName)s changed the pinned messages for the room.": "%(senderName)s pakeitė prisegtas kambario žinutes.", - "Sorry, your homeserver is too old to participate in this room.": "Atleiskite, jūsų namų serveris yra per senas dalyvauti šiame kambaryje.", - "Please contact your homeserver administrator.": "Prašome susisiekti su savo namų serverio administratoriumi.", + "Sorry, your homeserver is too old to participate in this room.": "Atleiskite, jūsų serverio versija yra per sena dalyvauti šiame kambaryje.", + "Please contact your homeserver administrator.": "Prašome susisiekti su savo serverio administratoriumi.", "Enable inline URL previews by default": "Įjungti tiesiogines URL nuorodų peržiūras pagal numatymą", "Enable URL previews for this room (only affects you)": "Įjungti URL nuorodų peržiūras šiame kambaryje (įtakoja tik jus)", "Enable URL previews by default for participants in this room": "Įjungti URL nuorodų peržiūras pagal numatymą dalyviams šiame kambaryje", @@ -731,7 +731,7 @@ "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Jeigu nenurodysite savo el. pašto adreso, negalėsite atstatyti savo slaptažodį. Ar esate tikri?", "Home server URL": "Namų serverio URL", "Identity server URL": "Tapatybės serverio URL", - "Please contact your service administrator to continue using the service.": "Norėdami tęsti naudotis paslauga, susisiekite su savo paslaugos administratoriumi.", + "Please contact your service administrator to continue using the service.": "Norėdami toliau naudotis šia paslauga, susisiekite su savo paslaugos administratoriumi.", "Reload widget": "Įkelti valdiklį iš naujo", "Picture": "Paveikslas", "Create new room": "Sukurti naują kambarį", @@ -787,12 +787,12 @@ "You cannot place a call with yourself.": "Negalite skambinti patys sau.", "Registration Required": "Reikalinga registracija", "You need to register to do this. Would you like to register now?": "Norėdami tai atlikti, turite užsiregistruoti. Ar norėtumėte užsiregistruoti dabar?", - "Missing roomId.": "Trūksta kambario ID (roomId).", + "Missing roomId.": "Trūksta kambario ID.", "Leave room": "Išeiti iš kambario", "(could not connect media)": "(nepavyko prijungti medijos)", - "This homeserver has hit its Monthly Active User limit.": "Šis namų serveris pasiekė savo mėnesinį aktyvių naudotojų limitą.", - "This homeserver has exceeded one of its resource limits.": "Šis namų serveris viršijo vieno iš savo išteklių limitą.", - "Unable to connect to Homeserver. Retrying...": "Nepavyksta prisijungti prie namų serverio. Bandoma iš naujo...", + "This homeserver has hit its Monthly Active User limit.": "Šis serveris pasiekė savo mėnesinį aktyvių naudotojų limitą.", + "This homeserver has exceeded one of its resource limits.": "Šis serveris viršijo vieno iš savo išteklių limitą.", + "Unable to connect to Homeserver. Retrying...": "Nepavyksta prisijungti prie serverio. Bandoma iš naujo...", "Hide avatar changes": "Slėpti avatarų pasikeitimus", "Disable Community Filter Panel": "Išjungti bendruomenės filtro skydelį", "Enable widget screenshots on supported widgets": "Palaikomuose valdikliuose įjungti valdiklių ekrano kopijas", @@ -854,12 +854,12 @@ "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s pasikeitė avatarą %(count)s kartų(-us)", "And %(count)s more...|other": "Ir dar %(count)s...", "Existing Call": "Esamas skambutis", - "A call is already in progress!": "Skambutis jau yra inicijuojamas!", + "A call is already in progress!": "Skambutis jau vyksta!", "Default": "Numatytasis", "Restricted": "Apribotas", "Moderator": "Moderatorius", - "Ignores a user, hiding their messages from you": "Nepaiso naudotojo, paslepiant nuo jūsų jo žinutes", - "Stops ignoring a user, showing their messages going forward": "Sustabdo naudotojo nepaisymą, rodant jo tolimesnes žinutes", + "Ignores a user, hiding their messages from you": "Ignoruoja vartotoją, slepiant nuo jūsų jo žinutes", + "Stops ignoring a user, showing their messages going forward": "Sustabdo vartotojo ignoravimą, rodant jums jo tolimesnes žinutes", "Hide avatars in user and room mentions": "Slėpti avatarus naudotojų ir kambarių paminėjimuose", "Revoke Moderator": "Panaikinti moderatorių", "deleted": "perbrauktas", @@ -871,13 +871,13 @@ "Invites": "Pakvietimai", "You have no historical rooms": "Jūs neturite istorinių kambarių", "Historical": "Istoriniai", - "Every page you use in the app": "Kiekvienas puslapis, kurį naudoji programoje", + "Every page you use in the app": "Kiekvienas puslapis, kurį jūs naudojate programoje", "Call Timeout": "Skambučio laikas baigėsi", - "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s kaip šio kambario adresus pridėjo %(addedAddresses)s.", - "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s kaip šio kambario adresą pridėjo %(addedAddresses)s.", - "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s kaip šio kambario adresus pašalino %(removedAddresses)s.", - "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s kaip šio kambario adresą pašalino %(removedAddresses)s.", - "%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.": "%(senderName)s kaip šio kambario adresus pridėjo %(addedAddresses)s ir pašalino %(removedAddresses)s.", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s pridėjo %(addedAddresses)s, kaip šio kambario adresus.", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s pridėjo %(addedAddresses)s, kaip šio kambario adresą.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s pašalino %(removedAddresses)s, kaip šio kambario adresus.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s pašalino %(removedAddresses)s, kaip šio kambario adresą.", + "%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.": "%(senderName)s pridėjo %(addedAddresses)s ir pašalino %(removedAddresses)s, kaip šio kambario adresus.", "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s nustatė pagrindinį šio kambario adresą į %(address)s.", "%(senderName)s removed the main address for this room.": "%(senderName)s pašalino pagrindinį šio kambario adresą.", "Disinvite": "Atšaukti pakvietimą", @@ -885,8 +885,8 @@ "Unknown for %(duration)s": "Nežinoma jau %(duration)s", "(warning: cannot be disabled again!)": "(įspėjimas: nebeįmanoma bus išjungti!)", "Unable to load! Check your network connectivity and try again.": "Nepavyko įkelti! Patikrinkite savo tinklo ryšį ir bandykite dar kartą.", - "%(targetName)s joined the room.": "%(targetName)s atėjo į kambarį.", - "User %(user_id)s does not exist": "Naudotojo %(user_id)s nėra", + "%(targetName)s joined the room.": "%(targetName)s prisijungė prie kambario.", + "User %(user_id)s does not exist": "Vartotojas %(user_id)s neegzistuoja", "Unknown server error": "Nežinoma serverio klaida", "Avoid sequences": "Venkite sekų", "Avoid recent years": "Venkite paskiausių metų", @@ -896,7 +896,7 @@ "All-uppercase is almost as easy to guess as all-lowercase": "Visas didžiąsias raides taip pat lengva atspėti kaip ir visas mažąsias", "Reversed words aren't much harder to guess": "Žodžius atvirkštine tvarka nėra sunkiau atspėti", "Predictable substitutions like '@' instead of 'a' don't help very much": "Nuspėjami pakaitalai, tokie kaip \"@\" vietoj \"a\", nelabai padeda", - "Add another word or two. Uncommon words are better.": "Pridėkite dar vieną žodį ar du. Geriau nedažnai vartojamus žodžius.", + "Add another word or two. Uncommon words are better.": "Pridėkite dar vieną ar du žodžius. Geriau nedažnai vartojamus žodžius.", "Repeats like \"aaa\" are easy to guess": "Tokius pasikartojimus kaip \"aaa\" yra lengva atspėti", "Repeats like \"abcabcabc\" are only slightly harder to guess than \"abc\"": "Tokius pasikartojimus kaip \"abcabcabc\" yra tik truputėlį sunkiau atspėti nei \"abc\"", "Sequences like abc or 6543 are easy to guess": "Tokias sekas kaip \"abc\" ar \"6543\" yra lengva atspėti", @@ -906,13 +906,13 @@ "This is a top-100 common password": "Tai yra vienas iš 100 dažniausiai naudojamų slaptažodžių", "This is a very common password": "Tai yra labai dažnai naudojamas slaptažodis", "This is similar to a commonly used password": "Šis yra panašus į dažnai naudojamą slaptažodį", - "A word by itself is easy to guess": "Patį žodį savaime yra lengva atspėti", + "A word by itself is easy to guess": "Pats žodis yra lengvai atspėjamas", "Names and surnames by themselves are easy to guess": "Pačius vardus ar pavardes yra lengva atspėti", "Common names and surnames are easy to guess": "Dažnai naudojamus vardus ar pavardes yra lengva atspėti", "Straight rows of keys are easy to guess": "Klavišų eilę yra lengva atspėti", "Short keyboard patterns are easy to guess": "Trumpus klaviatūros šablonus yra lengva atspėti", "Avoid repeated words and characters": "Venkite pasikartojančių žodžių ir simbolių", - "Use a few words, avoid common phrases": "Naudokite kelis žodžius, venkite dažnai naudojamų frazių", + "Use a few words, avoid common phrases": "Naudokite keletą žodžių, venkite dažnai naudojamų frazių", "No need for symbols, digits, or uppercase letters": "Nereikia simbolių, skaitmenų ar didžiųjų raidžių", "Encrypted messages in group chats": "Šifruotos žinutės grupės pokalbiuose", "Delete Backup": "Ištrinti atsarginę kopiją", @@ -1000,5 +1000,122 @@ "Explore rooms": "Peržiūrėti kambarius", "Your Riot is misconfigured": "Jūsų Riot yra neteisingai sukonfigūruotas", "Sign in to your Matrix account on %(serverName)s": "Prisijunkite prie savo paskyros %(serverName)s serveryje", - "Sign in to your Matrix account on ": "Prisijunkite prie savo paskyros serveryje" + "Sign in to your Matrix account on ": "Prisijunkite prie savo paskyros serveryje", + "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Nepriklausomai nuo to ar jūs naudojate 'duonos trupinių' funkciją (avatarai virš kambarių sąrašo)", + "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Kur šis puslapis įtraukia identifikuojamą informaciją, kaip kambarys, vartotojas ar grupės ID, tie duomenys yra pašalinami prieš siunčiant į serverį.", + "The remote side failed to pick up": "Nuotolinėi pusėi nepavyko atsiliepti", + "Call failed due to misconfigured server": "Skambutis nepavyko dėl neteisingai sukonfigūruoto serverio", + "Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Paprašykite savo serverio administratoriaus (%(homeserverDomain)s) sukonfiguruoti TURN serverį, kad skambučiai veiktų patikimai.", + "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.": "Alternatyviai, jūs galite bandyti naudoti viešą serverį turn.matrix.org, bet tai nebus taip patikima, ir tai atskleis jūsų IP adresą šiam serveriui. Jūs taip pat galite tvarkyti tai Nustatymuose.", + "Try using turn.matrix.org": "Bandykite naudoti turn.matrix.org", + "A conference call could not be started because the integrations server is not available": "Konferencinio skambučio nebuvo galima pradėti, nes nėra integracijų serverio", + "Call in Progress": "Vykstantis skambutis", + "A call is currently being placed!": "Šiuo metu skambinama!", + "Replying With Files": "Atsakyti su failais", + "At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Šiuo metu neįmanoma atsakyti su failu. Ar norite įkelti šį failą neatsakydami?", + "The file '%(fileName)s' failed to upload.": "Failo '%(fileName)s' nepavyko įkelti.", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Failas '%(fileName)s' viršyja šio serverio įkeliamų failų dydžio limitą", + "The server does not support the room version specified.": "Serveris nepalaiko nurodytos kambario versijos.", + "Invite new community members": "Pakviesti naujus bendruomenės narius", + "Name or Matrix ID": "Vardas arba Matrix ID", + "Identity server has no terms of service": "Tapatybės serveris neturi paslaugų teikimo sąlygų", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Šiam veiksmui reikalinga prieiti numatytąjį tapatybės serverį , kad patvirtinti el. pašto adresą arba telefono numerį, bet serveris neturi jokių paslaugos teikimo sąlygų.", + "Only continue if you trust the owner of the server.": "Tęskite tik tada, jei pasitikite serverio savininku.", + "Trust": "Pasitikėti", + "Email, name or Matrix ID": "El. paštas, vardas arba Matrix ID", + "Failed to start chat": "Nepavyko pradėti pokalbio", + "Failed to invite users to the room:": "Nepavyko pakviesti vartotojų į kambarį:", + "You need to be able to invite users to do that.": "Norėdami tai atlikti jūs turite turėti galimybę pakviesti vartotojus.", + "Power level must be positive integer.": "Galios lygis privalo būti teigiamas sveikasis skaičius.", + "Messages": "Žinutės", + "Actions": "Veiksmai", + "Other": "Kitas", + "Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Prideda ¯\\_(ツ)_/¯ prie paprasto teksto pranešimo", + "Sends a message as plain text, without interpreting it as markdown": "SIunčia žinutę, kaip paprastą tekstą, jo neinterpretuodamas kaip pažymėto", + "Upgrades a room to a new version": "Atnaujina kambarį į naują versiją", + "You do not have the required permissions to use this command.": "Jūs neturite reikalingų leidimų naudoti šią komandą.", + "Room upgrade confirmation": "Kambario atnaujinimo patvirtinimas", + "Upgrading a room can be destructive and isn't always necessary.": "Kambario atnaujinimas gali būti destruktyvus ir nėra visada reikalingas.", + "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Kambario atnaujinimai paprastai rekomenduojami, kada kambario versija yra laikoma nestabili. Nestabilios kambario versijos gali turėti klaidų, trūkstamų funkcijų, arba saugumo spragų.", + "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .": "Kambario atnaujinimai paprastai paveikia tik serverio pusės kambario apdorojimą. Jei jūs turite problemų su jūsų Riot klientu, prašome užregistruoti problemą .", + "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Įspėjimas: Kambario atnaujinimas automatiškai nemigruos kambario dalyvių į naują kambario versiją. Mes paskelbsime nuorodą į naują kambarį senojoje kambario versijoje - kambario dalyviai turės ją paspausti, norėdami prisijungti prie naujo kambario.", + "Please confirm that you'd like to go forward with upgrading this room from to .": "Prašome patvirtinti, kad jūs norite tęsti šio kambario atnaujinimą iš į .", + "Upgrade": "Atnaujinti", + "Changes your display nickname in the current room only": "Pakeičia jūsų rodomą slapyvardį tik esamame kambaryje", + "Changes the avatar of the current room": "Pakeičia esamo kambario avatarą", + "Changes your avatar in this current room only": "Pakeičia jūsų avatarą tik esamame kambaryje", + "Changes your avatar in all rooms": "Pakeičia jūsų avatarą visuose kambariuose", + "Gets or sets the room topic": "Gauna arba nustato kambario temą", + "This room has no topic.": "Šis kambarys neturi temos.", + "Sets the room name": "Nustato kambario pavadinimą", + "Use an identity server": "Naudoti tapatybės serverį", + "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Norėdami pakviesti nurodydami el. paštą, naudokite tapatybės serverį. Tam, kad būtų naudojamas numatytasis tapatybės serveris %(defaultIdentityServerName)s, spauskite tęsti, arba tvarkykite nustatymuose.", + "Use an identity server to invite by email. Manage in Settings.": "Norėdami pakviesti nurodydami el. paštą, naudokite tapatybės serverį. Tvarkykite nustatymuose.", + "Joins room with given alias": "Prisijungia prie kambario su nurodytu slapyvardžiu", + "Unbans user with given ID": "Atblokuoja vartotoją su nurodytu id", + "Ignored user": "Ignoruojamas vartotojas", + "Unignored user": "Nebeignoruojamas vartotojas", + "You are no longer ignoring %(userId)s": "Dabar nebeignoruojate %(userId)s", + "Define the power level of a user": "Nustatykite vartotojo galios lygį", + "Deops user with given id": "Deop'ina vartotoją su nurodytu id", + "Adds a custom widget by URL to the room": "Į kambarį prideda pasirinktinį valdiklį pagal URL", + "Please supply a https:// or http:// widget URL": "Prašome pateikti https:// arba http:// valdiklio URL", + "You cannot modify widgets in this room.": "Jūs negalite keisti valdiklių šiame kambaryje.", + "Verifies a user, device, and pubkey tuple": "Patikrina vartotoją, įrenginį ir pubkey seką", + "Forces the current outbound group session in an encrypted room to be discarded": "Priverčia išmesti esamą užsibaigiančią grupės sesiją šifruotame kambaryje", + "Sends the given message coloured as a rainbow": "Išsiunčia nurodytą žinutę nuspalvintą kaip vaivorykštė", + "Sends the given emote coloured as a rainbow": "Išsiunčia nurodytą emociją nuspalvintą kaip vaivorykštė", + "Displays list of commands with usages and descriptions": "Parodo komandų sąrašą su naudojimo būdais ir aprašymais", + "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s priėmė pakvietimą %(displayName)s.", + "%(senderName)s requested a VoIP conference.": "%(senderName)s pageidauja VoIP konferencijos.", + "%(senderName)s made no change.": "%(senderName)s neatliko pakeitimo.", + "%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s atšaukė %(targetName)s pakvietimą.", + "%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s atnaujino šį kambarį.", + "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s padarė kambarį viešą visiems žinantiems nuorodą.", + "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s padarė kambarį tik pakviestiems.", + "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s pakeitė prisijungimo normą į %(rule)s", + "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s leido svečiams prisijungti prie kambario.", + "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s uždraudė svečiams prisijungti prie kambario.", + "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s pakeitė svečių prieigą prie %(rule)s", + "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s įjungė ženkliukus bendruomenėi %(groups)s šiame kambaryje.", + "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s išjungė ženkliukus bendruomenėi %(groups)s šiame kambaryje.", + "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s įjungė ženkliukus bendruomenėi %(newGroups)s ir išjungė ženkliukus bendruomenėi %(oldGroups)s šiame kambaryje.", + "%(senderName)s placed a %(callType)s call.": "%(senderName)s pradėjo %(callType)s skambutį.", + "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s atšaukė pakvietimą %(targetDisplayName)s prisijungti prie kambario.", + "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s išsiuntė pakvietimą %(targetDisplayName)s prisijungti prie kambario.", + "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s padarė būsimą kambario istoriją matomą visiems kambario dalyviams, nuo pat jų prisijungimo.", + "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s padarė būsimą kambario istoriją matomą nežinomam (%(visibility)s).", + "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s iš %(fromPowerLevel)s į %(toPowerLevel)s", + "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s pakeitė %(powerLevelDiffText)s galios lygį.", + "%(displayName)s is typing …": "%(displayName)s rašo …", + "%(names)s and %(count)s others are typing …|other": "%(names)s ir %(count)s kiti rašo …", + "%(names)s and %(count)s others are typing …|one": "%(names)s ir vienas kitas rašo …", + "%(names)s and %(lastPerson)s are typing …": "%(names)s ir %(lastPerson)s rašo …", + "Cannot reach homeserver": "Serveris nepasiekiamas", + "Ensure you have a stable internet connection, or get in touch with the server admin": "Įsitikinkite, kad jūsų interneto ryšys yra stabilus, arba susisiekite su serverio administratoriumi", + "Ask your Riot admin to check your config for incorrect or duplicate entries.": "Paprašykite savo Riot administratoriaus patikrinti ar jūsų konfigūracijoje nėra neteisingų arba pasikartojančių įrašų.", + "Cannot reach identity server": "Tapatybės serveris nepasiekiamas", + "You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Jūs galite registruotis, tačiau kai kurios funkcijos bus nepasiekiamos, kol tapatybės serveris prisijungs. Jei ir toliau matote šį įspėjimą, patikrinkite savo konfigūraciją arba susisiekite su serverio administratoriumi.", + "You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Jūs galite iš naujo nustatyti savo slaptažodį, tačiau kai kurios funkcijos bus nepasiekiamos, kol tapatybės serveris prisijungs. Jei ir toliau matote šį įspėjimą, patikrinkite savo konfigūraciją arba susisiekite su serverio administratoriumi.", + "You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Jūs galite prisijungti, tačiau kai kurios funkcijos bus nepasiekiamos, kol tapatybės serveris prisijungs. Jei ir toliau matote šį įspėjimą, patikrinkite savo konfigūraciją arba susisiekite su serverio administratoriumi.", + "No homeserver URL provided": "Nepateiktas serverio URL", + "Unexpected error resolving homeserver configuration": "Netikėta klaida nustatant serverio konfigūraciją", + "Unexpected error resolving identity server configuration": "Netikėta klaida nustatant tapatybės serverio konfigūraciją", + "%(items)s and %(count)s others|other": "%(items)s ir %(count)s kiti", + "%(items)s and %(count)s others|one": "%(items)s ir vienas kitas", + "%(items)s and %(lastItem)s": "%(items)s ir %(lastItem)s", + "Unrecognised address": "Neatpažintas adresas", + "You do not have permission to invite people to this room.": "Jūs neturite leidimo pakviesti žmones į šį kambarį.", + "User %(userId)s is already in the room": "Vartotojas %(userId)s jau yra kambaryje", + "User %(user_id)s may or may not exist": "Vartotojas %(user_id)s gali ir neegzistuoti", + "The user must be unbanned before they can be invited.": "Norint pakviesti vartotoją, pirmiausia turi būti pašalintas draudimas.", + "The user's homeserver does not support the version of the room.": "Vartotojo serveris nepalaiko kambario versijos.", + "Use a longer keyboard pattern with more turns": "Naudokite ilgesnį klaviatūros modelį su daugiau vijų", + "There was an error joining the room": "Prisijungiant prie kambario įvyko klaida", + "Failed to join room": "Prisijungti prie kambario nepavyko", + "Message Pinning": "Žinutės prisegimas", + "Custom user status messages": "Pasirinktinės vartotojo būsenos žinutės", + "Group & filter rooms by custom tags (refresh to apply changes)": "Grupuoti ir filtruoti kambarius pagal pasirinktines žymas (atnaujinkite, kad pritaikytumėte pakeitimus)", + "Render simple counters in room header": "Užkrauti paprastus skaitiklius kambario antraštėje", + "Multiple integration managers": "Daugialypiai integracijų valdikliai" } From bb5f532eeb5d074c16439f50af7d2a62996e6249 Mon Sep 17 00:00:00 2001 From: fenuks Date: Wed, 6 Nov 2019 00:32:52 +0000 Subject: [PATCH 076/103] Translated using Weblate (Polish) Currently translated at 74.6% (1382 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/pl/ --- src/i18n/strings/pl.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index dd09059da8..31f82bc2dd 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -1645,5 +1645,13 @@ "Chat with Riot Bot": "Rozmowa z Botem Riota", "FAQ": "Najczęściej zadawane pytania", "Always show the window menu bar": "Zawsze pokazuj pasek menu okna", - "Close button should minimize window to tray": "Przycisk zamknięcia minimalizuje okno do zasobnika" + "Close button should minimize window to tray": "Przycisk zamknięcia minimalizuje okno do zasobnika", + "Add Email Address": "Dodaj adres e-mail", + "Add Phone Number": "Dodaj numer telefonu", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Ta czynność wymaga dostępu do domyślnego serwera tożsamości do walidacji adresu e-mail, czy numeru telefonu, ale serwer nie określa warunków korzystania z usługi.", + "Sends a message as plain text, without interpreting it as markdown": "Wysyła wiadomość jako zwykły tekst, bez jego interpretacji jako markdown", + "You do not have the required permissions to use this command.": "Nie posiadasz wymaganych uprawnień do użycia tego polecenia.", + "Changes the avatar of the current room": "Zmienia awatar dla obecnego pokoju", + "Use an identity server": "Użyj serwera tożsamości", + "Show previews/thumbnails for images": "Pokaż podgląd/miniatury obrazów" } From 4fe95b0075832725f9e11a64cd3d44be29ee1ceb Mon Sep 17 00:00:00 2001 From: Walter Date: Thu, 7 Nov 2019 18:22:05 +0000 Subject: [PATCH 077/103] Translated using Weblate (Russian) Currently translated at 99.8% (1849 of 1853 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/ru/ --- src/i18n/strings/ru.json | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index b22c627213..01065a9e96 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -1299,7 +1299,7 @@ "Two-way device verification using short text": "Двусторонняя проверка устройства используя короткий текст", "Enable Emoji suggestions while typing": "Включить предложения эмоджи при наборе", "Show a placeholder for removed messages": "Показывать плашки вместо удалённых сообщений", - "Show join/leave messages (invites/kicks/bans unaffected)": "Показывать сообщения о вступлении/выходе (не влияет на приглашения, исключения и запреты)", + "Show join/leave messages (invites/kicks/bans unaffected)": "Показывать сообщения о вступлении | выходе (не влияет на приглашения, исключения и запреты)", "Show avatar changes": "Показывать изменения аватара", "Show display name changes": "Показывать изменения отображаемого имени", "Show read receipts": "Показывать уведомления о прочтении", @@ -1347,7 +1347,7 @@ "Account management": "Управление аккаунтом", "Deactivating your account is a permanent action - be careful!": "Деактивация вашей учётной записи — это необратимое действие. Будьте осторожны!", "Chat with Riot Bot": "Чат с ботом Riot", - "Help & About": "Помощь & о программе", + "Help & About": "Помощь & О программе", "FAQ": "Часто задаваемые вопросы", "Versions": "Версии", "Lazy loading is not supported by your current homeserver.": "Ленивая подгрузка не поддерживается вашим сервером.", @@ -1391,7 +1391,7 @@ "Backing up %(sessionsRemaining)s keys...": "Резервное копирование %(sessionsRemaining)s ключей...", "All keys backed up": "Все ключи сохранены", "Developer options": "Параметры разработчика", - "General": "Общий", + "General": "Общие", "Set a new account password...": "Установить новый пароль учётной записи...", "Legal": "Законный", "At this time it is not possible to reply with an emote.": "В настоящее время невозможно ответить с помощью эмоции.", @@ -2018,7 +2018,7 @@ "Create a private room": "Создать приватную комнату", "Topic (optional)": "Тема (опционально)", "Make this room public": "Сделать комнату публичной", - "Use the new, faster, composer for writing messages": "Используйте новый, более быстрый, composer для написания сообщений.", + "Use the new, faster, composer for writing messages": "Используйте новый, более быстрый, редактор для написания сообщений.", "Send read receipts for messages (requires compatible homeserver to disable)": "Отправлять подтверждения о прочтении сообщений (требуется отключение совместимого домашнего сервера)", "Show previews/thumbnails for images": "Показать превью / миниатюры для изображений", "Disconnect from the identity server and connect to instead?": "Отключиться от сервера идентификации и вместо этого подключиться к ?", @@ -2160,5 +2160,10 @@ "Recent rooms": "Недавние комнаты", "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Сервер идентификации не настроен, поэтому вы не можете добавить адрес электронной почты, чтобы в будущем сбросить пароль.", "Jump to first unread room.": "Перейти в первую непрочитанную комнату.", - "Jump to first invite.": "Перейти к первому приглашению." + "Jump to first invite.": "Перейти к первому приглашению.", + "Trust": "Доверие", + "%(count)s unread messages including mentions.|one": "1 непрочитанное упоминание.", + "%(count)s unread messages.|one": "1 непрочитанное сообщение.", + "Unread messages.": "Непрочитанные сообщения.", + "Message Actions": "Сообщение действий" } From 2a5dc9bfac61ec792efed970c71be470588e2f3f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 8 Nov 2019 16:35:40 +0000 Subject: [PATCH 078/103] Remove lint comments about no-descending-specificity We have disabled the `no-descending-specificity` stylelint rule, so we no longer need these block comments. --- res/css/structures/_AutoHideScrollbar.scss | 9 ++++----- res/css/views/dialogs/_DevtoolsDialog.scss | 4 ---- res/css/views/elements/_Field.scss | 4 ---- res/css/views/rooms/_EventTile.scss | 5 ----- 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/res/css/structures/_AutoHideScrollbar.scss b/res/css/structures/_AutoHideScrollbar.scss index db86a6fbd6..6e4484157c 100644 --- a/res/css/structures/_AutoHideScrollbar.scss +++ b/res/css/structures/_AutoHideScrollbar.scss @@ -14,12 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -/* This file has CSS for both native and non-native scrollbars in an - * order that's fairly logic to read but violates stylelints descending - * specificity rule, so turn it off for this file. It also duplicates - * a selector to separate the hiding/showing from the sizing. +/* This file has CSS for both native and non-native scrollbars in an order + * that's fairly logical to read but duplicates a selector to separate the + * hiding/showing from the sizing. */ -/* stylelint-disable no-descending-specificity, no-duplicate-selectors */ +/* stylelint-disable no-duplicate-selectors */ /* 1. for browsers that support native overlay auto-hiding scrollbars diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss index 417d0d6744..9d58c999c3 100644 --- a/res/css/views/dialogs/_DevtoolsDialog.scss +++ b/res/css/views/dialogs/_DevtoolsDialog.scss @@ -135,9 +135,6 @@ limitations under the License. } } -/* Ordering this block by specificity would require breaking it up into several - chunks, which seems like it would be more confusing to read. */ -/* stylelint-disable no-descending-specificity */ .mx_DevTools_tgl-flip { + .mx_DevTools_tgl-btn { padding: 2px; @@ -192,4 +189,3 @@ limitations under the License. } } } -/* stylelint-enable no-descending-specificity */ diff --git a/res/css/views/elements/_Field.scss b/res/css/views/elements/_Field.scss index da896f947d..4d012a136e 100644 --- a/res/css/views/elements/_Field.scss +++ b/res/css/views/elements/_Field.scss @@ -148,9 +148,6 @@ limitations under the License. color: $greyed-fg-color; } -/* Ordering this block by specificity would require breaking it up into several - chunks, which seems like it would be more confusing to read. */ -/* stylelint-disable no-descending-specificity */ .mx_Field_valid { &.mx_Field, &.mx_Field:focus-within { @@ -174,7 +171,6 @@ limitations under the License. color: $input-invalid-border-color; } } -/* stylelint-enable no-descending-specificity */ .mx_Field_tooltip { margin-top: -12px; diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 98bfa248ff..fb85b9cf88 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -561,9 +561,6 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { /* end of overrides */ -/* Ordering this block by specificity would require breaking it up into several - chunks, which seems like it would be more confusing to read. */ -/* stylelint-disable no-descending-specificity */ .mx_MatrixChat_useCompactLayout { .mx_EventTile { padding-top: 4px; @@ -641,5 +638,3 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { } } } - -/* stylelint-enable no-descending-specificity */ From 5a5ebee9189e7fb9fbc333797b99cca5d4ebd44b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 8 Nov 2019 10:39:38 -0700 Subject: [PATCH 079/103] Check for a message type before assuming it is a room message Redacted messages do not have message types, despite being room messages. Fixes https://github.com/vector-im/riot-web/issues/11352 Regressed in https://github.com/matrix-org/matrix-react-sdk/pull/3601 Click-to-ping being broken (as mentioned by https://github.com/vector-im/riot-web/issues/11353) is a side effect of the react stack falling over. Once one room crashes, click-to-ping is broken everywhere. --- src/components/views/rooms/EventTile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 786a72f5b3..22f1f914b6 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -556,10 +556,10 @@ module.exports = createReactClass({ // Info messages are basically information about commands processed on a room const isBubbleMessage = eventType.startsWith("m.key.verification") || - (eventType === "m.room.message" && msgtype.startsWith("m.key.verification")); + (eventType === "m.room.message" && msgtype && msgtype.startsWith("m.key.verification")); let isInfoMessage = ( !isBubbleMessage && eventType !== 'm.room.message' && - eventType !== 'm.sticker' && eventType != 'm.room.create' + eventType !== 'm.sticker' && eventType !== 'm.room.create' ); let tileHandler = getHandlerTile(this.props.mxEvent); From e161e99b63c5ea18fcebc7c244c72ba20fd4cceb Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 8 Nov 2019 17:46:08 +0000 Subject: [PATCH 080/103] Fix rounded corners for the formatting toolbar The formatting toolbar is meant to have rounded corners like the message action bar. Fixes https://github.com/vector-im/riot-web/issues/11203 --- res/css/views/rooms/_MessageComposerFormatBar.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/res/css/views/rooms/_MessageComposerFormatBar.scss b/res/css/views/rooms/_MessageComposerFormatBar.scss index 43a2fb257e..80909529ee 100644 --- a/res/css/views/rooms/_MessageComposerFormatBar.scss +++ b/res/css/views/rooms/_MessageComposerFormatBar.scss @@ -41,6 +41,18 @@ limitations under the License. &:hover { border-color: $message-action-bar-hover-border-color; } + + &:first-child { + border-radius: 3px 0 0 3px; + } + + &:last-child { + border-radius: 0 3px 3px 0; + } + + &:only-child { + border-radius: 3px; + } } .mx_MessageComposerFormatBar_button { From c4d45e87ea251f62f3ffc8c33c916613d256a9b3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 8 Nov 2019 15:54:48 -0700 Subject: [PATCH 081/103] Use a ternary operator instead of relying on AND semantics in EditHIstoryDialog Fixes https://github.com/vector-im/riot-web/issues/11334 (probably). `allEvents` should never have a boolean in it, so given the stack trace and the code this is my best estimate for what the problem could be. I can't reproduce the problem. --- src/components/views/dialogs/MessageEditHistoryDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/MessageEditHistoryDialog.js b/src/components/views/dialogs/MessageEditHistoryDialog.js index 6014cb941c..b5e4daa1c1 100644 --- a/src/components/views/dialogs/MessageEditHistoryDialog.js +++ b/src/components/views/dialogs/MessageEditHistoryDialog.js @@ -116,7 +116,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent { nodes.push(( Date: Fri, 8 Nov 2019 16:07:11 -0700 Subject: [PATCH 082/103] Fix HTML fallback in replies Correctly encode the `body` to avoid problems down the line. We also convert newlines to `
` to better represent the message as a fallback. Fixes https://github.com/vector-im/riot-web/issues/9413 --- package.json | 1 + src/components/views/elements/ReplyThread.js | 15 +++++++++++++-- yarn.lock | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 0caff285e8..95b294c8a5 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "diff-match-patch": "^1.0.4", "emojibase-data": "^4.0.2", "emojibase-regex": "^3.0.0", + "escape-html": "^1.0.3", "file-saver": "^1.3.3", "filesize": "3.5.6", "flux": "2.1.1", diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index fac0a71617..55fd028980 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -1,6 +1,7 @@ /* Copyright 2017 New Vector Ltd Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> +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. @@ -23,6 +24,7 @@ import {wantsDateSeparator} from '../../../DateUtils'; import {MatrixEvent, MatrixClient} from 'matrix-js-sdk'; import {makeUserPermalink, RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks"; import SettingsStore from "../../../settings/SettingsStore"; +import escapeHtml from "escape-html"; // This component does no cycle detection, simply because the only way to make such a cycle would be to // craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would @@ -101,6 +103,15 @@ export default class ReplyThread extends React.Component { if (html) html = this.stripHTMLReply(html); } + if (!body) body = ""; // Always ensure we have a body, for reasons. + + // Escape the body to use as HTML below. + // We also run a nl2br over the result to fix the fallback representation. We do this + // after converting the text to safe HTML to avoid user-provided BR's from being converted. + if (!html) html = escapeHtml(body).replace(/\n/g, '
'); + + // dev note: do not rely on `body` being safe for HTML usage below. + const evLink = permalinkCreator.forEvent(ev.getId()); const userLink = makeUserPermalink(ev.getSender()); const mxid = ev.getSender(); @@ -110,7 +121,7 @@ export default class ReplyThread extends React.Component { case 'm.text': case 'm.notice': { html = `
In reply to ${mxid}` - + `
${html || body}
`; + + `
${html}`; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `<${mxid}> ${lines[0]}`; @@ -140,7 +151,7 @@ export default class ReplyThread extends React.Component { break; case 'm.emote': { html = `
In reply to * ` - + `${mxid}
${html || body}
`; + + `${mxid}
${html}`; const lines = body.trim().split('\n'); if (lines.length > 0) { lines[0] = `* <${mxid}> ${lines[0]}`; diff --git a/yarn.lock b/yarn.lock index fa7868d270..60fef54c16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2862,7 +2862,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -escape-html@~1.0.3: +escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= From c46a3764c3dc8db7ec8ba8b928ad620abb8400d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Fri, 8 Nov 2019 18:40:35 +0000 Subject: [PATCH 083/103] Translated using Weblate (French) Currently translated at 100.0% (1864 of 1864 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 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 328c3b7f9e..40840c8d58 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2280,5 +2280,16 @@ "Show tray icon and minimize window to it on close": "Afficher l’icône dans la barre d’état et minimiser la fenêtre lors de la fermeture", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Cette action nécessite l’accès au serveur d’identité par défaut afin de valider une adresse e-mail ou un numéro de téléphone, mais le serveur n’a aucune condition de service.", "Trust": "Confiance", - "Message Actions": "Actions de message" + "Message Actions": "Actions de message", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Send verification requests in direct message": "Envoyer les demandes de vérification en message direct", + "You verified %(name)s": "Vous avez vérifié %(name)s", + "You cancelled verifying %(name)s": "Vous avez annulé la vérification de %(name)s", + "%(name)s cancelled verifying": "%(name)s a annulé la vérification", + "You accepted": "Vous avez accepté", + "%(name)s accepted": "%(name)s a accepté", + "You cancelled": "Vous avez annulé", + "%(name)s cancelled": "%(name)s a annulé", + "%(name)s wants to verify": "%(name)s veut vérifier", + "You sent a verification request": "Vous avez envoyé une demande de vérification" } From 949ba89b4a5cc657d953ca3566badb5b24779c4e Mon Sep 17 00:00:00 2001 From: Elwyn Malethan Date: Sat, 9 Nov 2019 19:00:33 +0000 Subject: [PATCH 084/103] Added translation using Weblate (Welsh) --- src/i18n/strings/cy.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/i18n/strings/cy.json diff --git a/src/i18n/strings/cy.json b/src/i18n/strings/cy.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/src/i18n/strings/cy.json @@ -0,0 +1 @@ +{} From def4f90257bd486b41305b6e34c3087b29e72a46 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Sun, 10 Nov 2019 18:11:53 +0000 Subject: [PATCH 085/103] Translated using Weblate (Albanian) Currently translated at 99.8% (1860 of 1864 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/sq/ --- src/i18n/strings/sq.json | 43 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json index 4f25162491..1d80a90a2b 100644 --- a/src/i18n/strings/sq.json +++ b/src/i18n/strings/sq.json @@ -2205,5 +2205,46 @@ "Emoji Autocomplete": "Vetëplotësim Emoji-sh", "Notification Autocomplete": "Vetëplotësim NJoftimesh", "Room Autocomplete": "Vetëplotësim Dhomash", - "User Autocomplete": "Vetëplotësim Përdoruesish" + "User Autocomplete": "Vetëplotësim Përdoruesish", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Ky veprim lyp hyrje te shërbyesi parazgjedhje i identiteteve për të vlerësuar një adresë email ose një numër telefoni, por shërbyesi nuk ka ndonjë kusht shërbimesh.", + "Trust": "Besim", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Use the new, consistent UserInfo panel for Room Members and Group Members": "Përdorni panelin e ri UserInfo për Anëtarë Dhome dhe Anëtarë Grupi", + "Send verification requests in direct message": "Dërgo kërkesa verifikimi në mesazh të drejtpërdrejt", + "Show tray icon and minimize window to it on close": "Me mbylljen, shfaq ikonë paneli dhe minimizo dritaren", + "Room %(name)s": "Dhoma %(name)s", + "Recent rooms": "Dhoma së fundi", + "%(count)s unread messages including mentions.|one": "1 përmendje e palexuar.", + "%(count)s unread messages.|one": "1 mesazh i palexuar.", + "Unread messages.": "Mesazhe të palexuar.", + "Trust & Devices": "Besim & Pajisje", + "Direct messages": "Mesazhe të drejtpërdrejtë", + "Failed to deactivate user": "S’u arrit të çaktivizohet përdorues", + "This client does not support end-to-end encryption.": "Ky klient nuk mbulon fshehtëzim skaj-më-skaj.", + "Messages in this room are not end-to-end encrypted.": "Mesazhet në këtë dhomë nuk janë të fshehtëzuara skaj-më-skaj.", + "React": "Reagoni", + "Message Actions": "Veprime Mesazhesh", + "You verified %(name)s": "Verifikuat %(name)s", + "You cancelled verifying %(name)s": "Anuluat verifikimin e %(name)s", + "%(name)s cancelled verifying": "%(name)s anuloi verifikimin", + "You accepted": "Pranuat", + "%(name)s accepted": "%(name)s pranoi", + "You cancelled": "Anuluat", + "%(name)s cancelled": "%(name)s anuloi", + "%(name)s wants to verify": "%(name)s dëshiron të verifikojë", + "You sent a verification request": "Dërguat një kërkesë verifikimi", + "Frequently Used": "Përdorur Shpesh", + "Smileys & People": "Emotikone & Persona", + "Animals & Nature": "Kafshë & Natyrë", + "Food & Drink": "Ushqim & Pije", + "Activities": "Veprimtari", + "Travel & Places": "Udhëtim & Vende", + "Objects": "Objekte", + "Symbols": "Simbole", + "Flags": "Flamuj", + "Quick Reactions": "Reagime të Shpejta", + "Cancel search": "Anulo kërkimin", + "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "S’ka shërbyes identitetesh të formësuar, ndaj s’mund të shtoni një adresë email që të mund të ricaktoni fjalëkalimin tuaj në të ardhmen.", + "Jump to first unread room.": "Hidhu te dhoma e parë e palexuar.", + "Jump to first invite.": "Hidhu te ftesa e parë." } From eaac3fe3b8000423f195edcc865fa32cb3ff2deb Mon Sep 17 00:00:00 2001 From: Osoitz Date: Sat, 9 Nov 2019 11:12:46 +0000 Subject: [PATCH 086/103] Translated using Weblate (Basque) Currently translated at 100.0% (1864 of 1864 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eu/ --- src/i18n/strings/eu.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 72b6fff50d..888f6984e7 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -2222,5 +2222,19 @@ "Jump to first unread room.": "Jauzi irakurri gabeko lehen gelara.", "Jump to first invite.": "Jauzi lehen gonbidapenera.", "Command Autocomplete": "Aginduak auto-osatzea", - "DuckDuckGo Results": "DuckDuckGo emaitzak" + "DuckDuckGo Results": "DuckDuckGo emaitzak", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Ekintza honek lehenetsitako identitate-zerbitzaria atzitzea eskatzen du, e-mail helbidea edo telefono zenbakia balioztatzeko, baina zerbitzariak ez du erabilera baldintzarik.", + "Trust": "Jo fidagarritzat", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Send verification requests in direct message": "Bidali egiaztaketa eskariak mezu zuzen bidez", + "Message Actions": "Mezu-ekintzak", + "You verified %(name)s": "%(name)s egiaztatu duzu", + "You cancelled verifying %(name)s": "%(name)s egiaztatzeari utzi diozu", + "%(name)s cancelled verifying": "%(name)s(e)k egiaztaketa utzi du", + "You accepted": "Onartu duzu", + "%(name)s accepted": "%(name)s onartuta", + "You cancelled": "Utzi duzu", + "%(name)s cancelled": "%(name)s utzita", + "%(name)s wants to verify": "%(name)s(e)k egiaztatu nahi du", + "You sent a verification request": "Egiaztaketa eskari bat bidali duzu" } From a4a0dc9c2d7e14c32c1d3cba6e3663f277e443a4 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Mon, 11 Nov 2019 06:47:26 +0000 Subject: [PATCH 087/103] Translated using Weblate (Bulgarian) Currently translated at 100.0% (1864 of 1864 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 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/bg.json b/src/i18n/strings/bg.json index 6f198b2e5a..3697cc635c 100644 --- a/src/i18n/strings/bg.json +++ b/src/i18n/strings/bg.json @@ -2249,5 +2249,16 @@ "Emoji Autocomplete": "Подсказка за емоджита", "Notification Autocomplete": "Подсказка за уведомления", "Room Autocomplete": "Подсказка за стаи", - "User Autocomplete": "Подсказка за потребители" + "User Autocomplete": "Подсказка за потребители", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Send verification requests in direct message": "Изпращай заявки за потвърждение чрез директни съобщения", + "You verified %(name)s": "Потвърдихте %(name)s", + "You cancelled verifying %(name)s": "Отказахте потвърждаването за %(name)s", + "%(name)s cancelled verifying": "%(name)s отказа потвърждаването", + "You accepted": "Приехте", + "%(name)s accepted": "%(name)s прие", + "You cancelled": "Отказахте потвърждаването", + "%(name)s cancelled": "%(name)s отказа", + "%(name)s wants to verify": "%(name)s иска да извърши потвърждение", + "You sent a verification request": "Изпратихте заявка за потвърждение" } From d8ea25403acb33a166f7f62ab668146c51cf306a Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 11 Nov 2019 03:26:55 +0000 Subject: [PATCH 088/103] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1864 of 1864 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 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 58dca89415..185026aad5 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2273,5 +2273,16 @@ "Show tray icon and minimize window to it on close": "顯示系統匣圖示並在關閉視窗時將其最小化至其中", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "此動作需要存取預設的身份識別伺服器 以驗證電子郵件或電話號碼,但伺服器沒有任何服務條款。", "Trust": "信任", - "Message Actions": "訊息動作" + "Message Actions": "訊息動作", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Send verification requests in direct message": "在直接訊息中傳送驗證請求", + "You verified %(name)s": "您驗證了 %(name)s", + "You cancelled verifying %(name)s": "您已取消驗證 %(name)s", + "%(name)s cancelled verifying": "%(name)s 已取消驗證", + "You accepted": "您已接受", + "%(name)s accepted": "%(name)s 已接受", + "You cancelled": "您已取消", + "%(name)s cancelled": "%(name)s 已取消", + "%(name)s wants to verify": "%(name)s 想要驗證", + "You sent a verification request": "您已傳送了驗證請求" } From 163f9f057fd39db2beb45ecd060a34bdb49e5f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanislav=20Luke=C5=A1?= Date: Sun, 10 Nov 2019 22:20:21 +0000 Subject: [PATCH 089/103] Translated using Weblate (Czech) Currently translated at 99.9% (1863 of 1864 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 | 179 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 2d3088c279..e4e01b0116 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -1716,7 +1716,7 @@ "Remove messages": "Odstranit zprávy", "Notify everyone": "Upozornění pro celou místnost", "Enable encryption?": "Povolit šifrování?", - "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Po zapnutí už nelze šifrování v této místnosti zakázat. Zprávy v šifrovaných místostech můžou číst jenom členové místnosti, server se k obsahu nedostane. Šifrování místností nepodporuje většina botů a bridgů. Více informací o šifrování.", + "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Po zapnutí už nelze šifrování v této místnosti zakázat. Zprávy v šifrovaných místostech můžou číst jenom členové místnosti, server se k obsahu nedostane. Šifrování místností nepodporuje většina botů a propojení. Více informací o šifrování.", "Error updating main address": "Nepovedlo se změnit hlavní adresu", "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "Nastala chyba při pokusu o nastavení hlavní adresy místnosti. Mohl to zakázat server, nebo to může být dočasná chyba.", "Error creating alias": "Nepovedlo se vyrobit alias", @@ -1957,8 +1957,8 @@ "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Pokud nechcete na hledání existujících kontaktů používat server , zvolte si jiný server.", "Identity Server": "Server identit", "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "Aktuálně nepoužíváte žádný server identit. Na hledání existujících kontaktů a přidání se do registru kontatů přidejte server identit níže.", - "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Odpojení ze serveru identit znamená, že vás nepůjde najít podle emailové adresy a telefonního čísla and vy taky nebudete moct hledat ostatní.", - "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Použití serveru identit je volitelné. Nemusíte server identit používat, ale nepůjde vás pak najít podle emailové adresy a telefonního čísla a vy také nebudete moct hledat ostatní.", + "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Odpojení ze serveru identit znamená, že vás nepůjde najít podle emailové adresy ani telefonního čísla and vy také nebudete moct hledat ostatní.", + "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Použití serveru identit je volitelné. Nemusíte server identit používat, ale nepůjde vás pak najít podle emailové adresy ani telefonního čísla a vy také nebudete moct hledat ostatní.", "Do not use an identity server": "Nepoužívat server identit", "Enter a new identity server": "Zadejte nový server identit", "Failed to update integration manager": "Nepovedlo se aktualizovat správce integrací", @@ -1969,7 +1969,7 @@ "You are currently using %(serverName)s to manage your bots, widgets, and sticker packs.": "Aktálně používáte %(serverName)s na správu robotů, widgetů, and balíků samolepek.", "Add which integration manager you want to manage your bots, widgets, and sticker packs.": "Zadejte kterého správce integrací chcete používat na správu robotů, widgetů a balíků samolepek.", "Integration Manager": "Správce integrací", - "Enter a new integration manager": "Přidat nový správce integrací", + "Enter a new integration manager": "Přidat nového správce integrací", "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Musíte odsouhlasit podmínky použití serveru (%(serverName)s) abyste se mohli zapsat do registru emailových adres a telefonních čísel.", "Deactivate account": "Deaktivovat účet", "Always show the window menu bar": "Vždy zobrazovat horní lištu okna", @@ -2002,5 +2002,174 @@ "Command Help": "Nápověda příkazu", "Integrations Manager": "Správce integrací", "Find others by phone or email": "Hledat ostatní pomocí emailu nebo telefonu", - "Be found by phone or email": "Umožnit ostatním mě nalézt pomocí emailu nebo telefonu" + "Be found by phone or email": "Umožnit ostatním mě nalézt pomocí emailu nebo telefonu", + "Add Email Address": "Přidat emailovou adresu", + "Add Phone Number": "Přidat telefonní číslo", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Tato akce vyžaduje přístup k výchozímu serveru identity aby šlo ověřit email a telefon, ale server nemá podmínky použití.", + "Trust": "Důvěra", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Multiple integration managers": "Více správců integrací", + "Use the new, consistent UserInfo panel for Room Members and Group Members": "Používat nový, konzistentní panel s informaci o uživalelích pro členy místností and skupin", + "Send verification requests in direct message": "Poslat žádost o verifikaci jako přímou zprávu", + "Use the new, faster, composer for writing messages": "Použít nový, rychlejší editor zpráv", + "Show previews/thumbnails for images": "Zobrazovat náhledy obrázků", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Před odpojením byste měli smazat osobní údaje ze serveru identit . Bohužel, server je offline nebo neodpovídá.", + "You should:": "Měli byste:", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "zkontrolujte, jestli nemáte v prohlížeči nějaký doplněk blokující server identit (například Privacy Badger)", + "contact the administrators of identity server ": "konaktujte administrátora serveru identit ", + "wait and try again later": "počkejte z zkuste to znovu později", + "Discovery": "Nalezitelnost", + "Clear cache and reload": "Smazat mezipaměť a načíst znovu", + "Show tray icon and minimize window to it on close": "Zobrazovat systémovou ikonu a minimalizovat při zavření", + "Read Marker lifetime (ms)": "životnost značky přečteno (ms)", + "Read Marker off-screen lifetime (ms)": "životnost značky přečteno mimo obrazovku (ms)", + "A device's public name is visible to people you communicate with": "Veřejné jméno zařízení je viditelné pro lidi se kterými komunikujete", + "Upgrade the room": "Upgradovat místnost", + "Enable room encryption": "Povolit v místnosti šifrování", + "Error changing power level requirement": "Chyba změny požadavku na úroveň oprávnění", + "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Došlo k chybě při změně požadované úrovně oprávnění v místnosti. Ubezpečte se, že na to máte dostatečná práva a zkuste to znovu.", + "Error changing power level": "Chyba při změně úrovně oprávnění", + "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "Došlo k chybě při změně úrovně oprávnění uživatele. Ubezpečte se, že na to máte dostatečná práva a zkuste to znovu.", + "Unable to revoke sharing for email address": "Nepovedlo se zrušit sdílení emailové adresy", + "Unable to share email address": "Nepovedlo se nasdílet emailovou adresu", + "Your email address hasn't been verified yet": "Vaše emailová adresa nebyla zatím verifikována", + "Click the link in the email you received to verify and then click continue again.": "Pro verifikaci a pokračování klikněte na odkaz v emailu, který vím přišel.", + "Verify the link in your inbox": "Ověřte odkaz v emailové schánce", + "Complete": "Dokončit", + "Revoke": "Zneplatnit", + "Share": "Sdílet", + "Discovery options will appear once you have added an email above.": "Možnosti nalezitelnosti se objeví až výše přidáte svou emailovou adresu.", + "Unable to revoke sharing for phone number": "Nepovedlo se zrušit sdílení telefonního čísla", + "Unable to share phone number": "Nepovedlo se nasdílet telefonní číslo", + "Please enter verification code sent via text.": "Zadejte prosím ověřovací SMS kód.", + "Discovery options will appear once you have added a phone number above.": "Možnosti nalezitelnosti se objeví až zadáte telefonní číslo výše.", + "Remove %(email)s?": "Odstranit %(email)s?", + "Remove %(phone)s?": "Odstranit %(phone)s?", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "SMS zpráva byla odeslána na +%(msisdn)s. Zadejte prosím ověřovací kód, který obsahuje.", + "No recent messages by %(user)s found": "Nebyly nalezeny žádné nedávné zprávy od uživatele %(user)s", + "Try scrolling up in the timeline to see if there are any earlier ones.": "Zkuste zascrollovat nahoru, jestli tam nejsou nějaké dřívější.", + "Remove recent messages by %(user)s": "Odstranit nedávné zprávy od uživatele %(user)s", + "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "Odstraňujeme %(count)s zpráv od %(user)s. Nelze to vzít zpět. Chcete pokračovat?", + "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "Odstraňujeme jednu zprávu od %(user)s. Nelze to vzít zpět. Chcete pokračovat?", + "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Pro větší množství zpráv to může nějakou dobu trvat. V průběhu prosím neobnovujte klienta.", + "Remove %(count)s messages|other": "Odstranit %(count)s zpráv", + "Remove %(count)s messages|one": "Odstranit zprávu", + "Deactivate user?": "Deaktivovat uživatele?", + "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Deaktivování uživatele ho odhlásí a zabrání mu v opětovném přihlášení. Navíc bude ostraněn ze všech místností. Akci nelze vzít zpět. Jste si jistí, že chcete uživatele deaktivovat?", + "Deactivate user": "Deaktivovat uživatele", + "Remove recent messages": "Odstranit nedávné zprávy", + "Bold": "Tučně", + "Italics": "Kurzívou", + "Strikethrough": "Přešktnutě", + "Code block": "Blok kódu", + "Room %(name)s": "Místnost %(name)s", + "Recent rooms": "Nedávné místnosti", + "Loading room preview": "Načítání náhdledu místnosti", + "An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "Při ověřování pozvánky jsme dostali chybu (%(errcode)s). Můžete zkusit tuto informaci předat administrátorovi místnosti.", + "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Pozvánka do místnosti %(roomName)s byla poslána na %(email)s, který není přidaný k tomuto účtu", + "Link this email with your account in Settings to receive invites directly in Riot.": "Přidejte si tento email k účtu v Nastavení, abyste dostávali pozvání přímo v Riotu.", + "This invite to %(roomName)s was sent to %(email)s": "Pozvánka do %(roomName)s byla odeslána na %(email)s", + "Use an identity server in Settings to receive invites directly in Riot.": "Používat server identit z nastavení k přijímání pozvánek přímo v Riotu.", + "Share this email in Settings to receive invites directly in Riot.": "Sdílet tento email v nastavení, abyste mohli dostávat pozvánky přímo v Riotu.", + "%(count)s unread messages including mentions.|other": "%(count)s nepřečtených zpráv a zmínek.", + "%(count)s unread messages including mentions.|one": "Nepřečtená zmínka.", + "%(count)s unread messages.|other": "%(count)s nepřečtených zpráv.", + "%(count)s unread messages.|one": "Nepřečtená zpráva.", + "Unread mentions.": "Nepřečtená zmínka.", + "Unread messages.": "Nepřečtené zprávy.", + "Failed to connect to integrations server": "Nepovedlo se připojit k serveru integrací", + "No integrations server is configured to manage stickers with": "Žádný server integrací není nakonfigurován aby spravoval samolepky", + "Trust & Devices": "Důvěra & Zařízení", + "Direct messages": "Přímé zprávy", + "Failed to deactivate user": "Deaktivace uživatele se nezdařila", + "This client does not support end-to-end encryption.": "Tento klient nepodporuje end-to-end šifrování.", + "Messages in this room are not end-to-end encrypted.": "Zprávy nejsou end-to-end šifrované.", + "React": "Reagovat", + "Message Actions": "Akce zprávy", + "Show image": "Zobrazit obrázek", + "You verified %(name)s": "Ověřili jste %(name)s", + "You cancelled verifying %(name)s": "Zrušili jste ověření %(name)s", + "%(name)s cancelled verifying": "%(name)s zrušil/a ověření", + "You accepted": "Přijali jste", + "%(name)s accepted": "%(name)s přijal/a", + "You cancelled": "Zrušili jste", + "%(name)s cancelled": "%(name)s zrušil/a", + "%(name)s wants to verify": "%(name)s chce ověřit", + "You sent a verification request": "Poslali jste požadavek na ověření", + "Show all": "Zobrazit vše", + "Edited at %(date)s. Click to view edits.": "Pozměněno v %(date)s. Klinutím zobrazíte změny.", + "Frequently Used": "Často používané", + "Smileys & People": "Obličeje & Lidé", + "Animals & Nature": "Zvířata & Příroda", + "Food & Drink": "Jídlo & Nápoje", + "Activities": "Aktivity", + "Travel & Places": "Cestování & Místa", + "Objects": "Objekty", + "Symbols": "Symboly", + "Flags": "Vlajky", + "Quick Reactions": "Rychlé reakce", + "Cancel search": "Zrušit hledání", + "Please create a new issue on GitHub so that we can investigate this bug.": "Vyrobte prosím nové issue na GitHubu abychom mohli chybu opravit.", + "%(severalUsers)smade no changes %(count)s times|other": "%(severalUsers)s neudělali %(count)s krát žádnou změnu", + "%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)sneudělali žádnou změnu", + "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)sneudělal %(count)s krát žádnou změnu", + "%(oneUser)smade no changes %(count)s times|one": "%(oneUser)sneudělal žádnou změnu", + "Room alias": "Alias místnosti", + "e.g. my-room": "například moje-mistost", + "Please provide a room alias": "Zadejte prosím alias místnosti", + "This alias is available to use": "Tento alias je volný", + "This alias is already in use": "Tento alias už je používán", + "Use bots, bridges, widgets and sticker packs": "Použít roboty, propojení, widgety a balíky samolepek", + "Terms of Service": "Podmínky použití", + "To continue you need to accept the terms of this service.": "Musíte souhlasit s podmínkami použití, abychom mohli pokračovat.", + "Service": "Služba", + "Summary": "Shrnutí", + "Document": "Dokument", + "Upload all": "Nahrát vše", + "Resend edit": "Odeslat změnu znovu", + "Resend %(unsentCount)s reaction(s)": "Poslat %(unsentCount)s reakcí znovu", + "Resend removal": "Odeslat smazání znovu", + "Report Content": "Nahlásit obsah", + "Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "Na domovském serveru chybí veřejný klíč pro captcha. Nahlaste to prosím administrátorovi serveru.", + "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Žádný server identit není nakonfigurován, takže nemůžete přidat emailovou adresu pro obnovení hesla.", + "Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Nastavit emailovou adresu pro obnovení hesla. Také můžete použít email nebo telefon, aby vás vaši přátelé snadno nalezli.", + "Set an email for account recovery. Use email to optionally be discoverable by existing contacts.": "Nastavit emailovou adresu pro obnovení hesla. Také můžete použít email, aby vás vaši přátelé snadno nalezli.", + "Enter your custom homeserver URL What does this mean?": "Zadejte adresu domovského serveru Co to znamená?", + "Enter your custom identity server URL What does this mean?": "Zadejte adresu serveru identit Co to znamená?", + "Explore": "Prohlížet", + "Filter": "Filtrovat", + "Filter rooms…": "Filtrovat místnosti…", + "%(creator)s created and configured the room.": "%(creator)s vytvořil a nakonfiguroval místnost.", + "Preview": "Náhled", + "View": "Zobrazit", + "Find a room…": "Najít místnost…", + "Find a room… (e.g. %(exampleRoom)s)": "Najít místnost… (například %(exampleRoom)s)", + "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Pokud nemůžete nelézt místnost, kterou hledáte, napište o pozvánku nebo si jí Vytvořte.", + "Explore rooms": "Prohlížet místnosti", + "Jump to first unread room.": "Skočit na první nepřečtenou místnost.", + "Jump to first invite.": "Skočit na první pozvánku.", + "No identity server is configured: add one in server settings to reset your password.": "Žádný server identit není nakonfigurován: přidejte si ho v nastavení, abyste mohli obnovit heslo.", + "This account has been deactivated.": "Tento účet byl deaktivován.", + "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "nový účet (%(newAccountId)s) je registrován, ale už jste přihlášeni pod jiným účtem (%(loggedInUserId)s).", + "Continue with previous account": "Pokračovat s předchozím účtem", + "Log in to your new account.": "Přihlaste se svým novým účtem.", + "You can now close this window or log in to your new account.": "Teď můžete okno zavřít, nebo se přihlásit svým novým účtem.", + "Registration Successful": "Úspěšná registrace", + "Failed to re-authenticate due to a homeserver problem": "Kvůli problémům s domovským server se nepovedlo autentifikovat znovu", + "Failed to re-authenticate": "Nepovedlo se autentifikovat", + "Regain access to your account and recover encryption keys stored on this device. Without them, you won’t be able to read all of your secure messages on any device.": "Získejte znovu přístup k účtu a obnovte si šifrovací klíče uložené na tomto zařízení. Bez nich nebudete schopni číst zabezpečené zprávy na některých zařízeních.", + "Enter your password to sign in and regain access to your account.": "Zadejte heslo pro přihlášení a obnovte si přístup k účtu.", + "Forgotten your password?": "Zapomněli jste heslo?", + "Sign in and regain access to your account.": "Přihlaste se a získejte přístup ke svému účtu.", + "You cannot sign in to your account. Please contact your homeserver admin for more information.": "Nemůžete se přihlásit do svého účtu. Kontaktujte administrátora domovského serveru pro více informací.", + "You're signed out": "Jste odhlášeni", + "Clear personal data": "Smazat osobní data", + "Warning: Your personal data (including encryption keys) is still stored on this device. Clear it if you're finished using this device, or want to sign in to another account.": "Varování: Vaše osobní data (včetně šifrovacích klíčů) jsou pořád uložena na tomto zařízení. Smažte je, pokud už toto zařízení nehodláte používat nebo se přihlašte pod jiný účet.", + "Command Autocomplete": "Automatické doplňování příkazů", + "Community Autocomplete": "Automatické doplňování komunit", + "DuckDuckGo Results": "Výsledky hledání DuckDuckGo", + "Emoji Autocomplete": "Automatické doplňování Emodži", + "Notification Autocomplete": "Automatické doplňování upozornění", + "Room Autocomplete": "Automatické doplňování místností", + "User Autocomplete": "Automatické doplňování uživatelů" } From 0bfbf34c3956c8364134739a78a3c983597af814 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sun, 10 Nov 2019 21:24:20 +0000 Subject: [PATCH 090/103] Translated using Weblate (Esperanto) Currently translated at 99.9% (1862 of 1864 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/eo/ --- src/i18n/strings/eo.json | 155 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 12 deletions(-) diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json index 7e4599aaea..bbed6773b5 100644 --- a/src/i18n/strings/eo.json +++ b/src/i18n/strings/eo.json @@ -182,7 +182,7 @@ "Answer": "Respondi", "Send anyway": "Tamen sendi", "Send": "Sendi", - "Enable automatic language detection for syntax highlighting": "Ŝalti memfaran rekonon de lingvo por sintaksa markado", + "Enable automatic language detection for syntax highlighting": "Ŝalti memagan rekonon de lingvo por sintaksa markado", "Hide avatars in user and room mentions": "Kaŝi profilbildojn en mencioj de uzantoj kaj babilejoj", "Disable big emoji in chat": "Malŝalti grandajn mienetojn en babilo", "Don't send typing notifications": "Ne elsendi sciigojn pri tajpado", @@ -1270,7 +1270,7 @@ "Ignored users": "Malatentaj uzantoj", "Key backup": "Sekurkopio de ŝlosilo", "Security & Privacy": "Sekureco & Privateco", - "Voice & Video": "Voĉo k Vido", + "Voice & Video": "Voĉo kaj vido", "Upgrade room to version %(ver)s": "Ĝisdatigi ĉambron al versio %(ver)s", "Room information": "Ĉambraj informoj", "Internal room ID:": "Ena ĉambra identigilo:", @@ -1507,7 +1507,7 @@ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Ŝanĝoj al viaj komunumaj nomo kaj profilbildo eble ne montriĝos al aliaj uzantoj ĝis 30 minutoj.", "Who can join this community?": "Kiu povas aliĝi al tiu ĉi komunumo?", "This room is not public. You will not be able to rejoin without an invite.": "Ĉi tiu ĉambro ne estas publika. Vi ne povos realiĝi sen invito.", - "Can't leave Server Notices room": "Ne eblas eliri el ĉambro «  Server Notices  »", + "Can't leave Server Notices room": "Ne eblas eliri el ĉambro « Server Notices »", "Revoke invite": "Nuligi inviton", "Invited by %(sender)s": "Invitita de %(sender)s", "Error updating main address": "Ĝisdatigo de la ĉefa adreso eraris", @@ -1710,7 +1710,7 @@ "Connect this device to Key Backup": "Konekti ĉi tiun aparaton al Savkopiado de ŝlosiloj", "Start using Key Backup": "Ekuzi Savkopiadon de ŝlosiloj", "Timeline": "Historio", - "Autocomplete delay (ms)": "Prokrasto de memfara kompletigo", + "Autocomplete delay (ms)": "Prokrasto de memaga kompletigo", "Upgrade this room to the recommended room version": "Gradaltigi ĉi tiun ĉambron al rekomendata ĉambra versio", "Open Devtools": "Malfermi programistajn ilojn", "Uploaded sound": "Alŝutita sono", @@ -1747,7 +1747,7 @@ "Go to Settings": "Iri al agordoj", "Flair": "Etikedo", "No Audio Outputs detected": "Neniu soneligo troviĝis", - "Send %(eventType)s events": "Sendi okazojn de tipo «%(eventType)s»", + "Send %(eventType)s events": "Sendi okazojn de tipo « %(eventType)s »", "Select the roles required to change various parts of the room": "Elektu la rolojn postulatajn por ŝanĝado de diversaj partoj de la ĉambro", "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Post ŝalto, ĉifrado de ĉambro ne povas esti malŝaltita. Mesaĝoj senditaj al ĉifrata ĉambro ne estas videblaj por la servilo, nur por la partoprenantoj de la ĉambro. Ŝalto de ĉifrado eble malfunkciigos iujn robotojn kaj pontojn. Eksciu plion pri ĉifrado.", "To link to this room, please add an alias.": "Por ligili al la ĉambro, bonvolu aldoni kromnomon.", @@ -1756,7 +1756,7 @@ "Once enabled, encryption cannot be disabled.": "Post ŝalto, ne plu eblas malŝalti ĉifradon.", "Encrypted": "Ĉifrata", "Some devices in this encrypted room are not trusted": "Iuj aparatoj en ĉi tiu ĉifrata ĉambro ne estas fidataj", - "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Petoj pri kunhavigo de ŝlosiloj sendiĝas al viaj aliaj aparatoj memfare. Se vi rifuzis aŭ forlasis la peton en viaj aliaj aparatoj, klaku ĉi tien por repeti la ŝlosilojn por tiu ĉi kunsido.", + "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Petoj pri kunhavigo de ŝlosiloj sendiĝas al viaj aliaj aparatoj memage. Se vi rifuzis aŭ forlasis la peton en viaj aliaj aparatoj, klaku ĉi tien por repeti la ŝlosilojn por tiu ĉi kunsido.", "The conversation continues here.": "La interparolo pluas ĉi tie.", "This room has been replaced and is no longer active.": "Ĉi tiu ĉambro estas anstataŭita, kaj ne plu aktivas.", "Loading room preview": "Preparas antaŭrigardon al la ĉambro", @@ -1790,7 +1790,7 @@ "Message edits": "Redaktoj de mesaĝoj", "If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Se vi renkontas problemojn aŭ havas prikomentojn, bonvolu sciigi nin per GitHub.", "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "Por eviti duoblajn raportojn, bonvolu unue rigardi jamajn raportojn (kaj meti +1) aŭ raporti novan problemon se vi neniun trovos.", - "Report bugs & give feedback": "Raporti erarojn ϗ sendi prikomentojn", + "Report bugs & give feedback": "Raporti erarojn kaj sendi prikomentojn", "Clear Storage and Sign Out": "Vakigi memoron kaj adiaŭi", "We encountered an error trying to restore your previous session.": "Ni renkontis eraron provante rehavi vian antaŭan kunsidon.", "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Vakigo de la memoro de via foliumilo eble korektos la problemon, sed adiaŭigos vin, kaj malebligos legadon de historio de ĉifritaj babiloj.", @@ -1865,7 +1865,7 @@ "Upgrading this room requires closing down the current instance of the room and creating a new room in its place. To give room members the best possible experience, we will:": "Gradaltigo de ĉi tiu ĉambro bezonas fermi ĝin, kaj krei novan por anstataŭi ĝin. Por plejbonigi sperton de la ĉambranoj, ni:", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Vi adiaŭis ĉiujn aparatojn kaj ne plu ricevados sciigojn. Por reŝalti ilin, resalutu per ĉiu el la aparatoj.", "Invalid homeserver discovery response": "Nevalida eltrova respondo de hejmservilo", - "Failed to get autodiscovery configuration from server": "Malsukcesis akiri agordojn de memfara eltrovado de la servilo", + "Failed to get autodiscovery configuration from server": "Malsukcesis akiri agordojn de memaga eltrovado de la servilo", "Homeserver URL does not appear to be a valid Matrix homeserver": "URL por hejmservilo ŝajne ne ligas al valida hejmservilo de Matrix", "Invalid identity server discovery response": "Nevalida eltrova respondo de identiga servilo", "Identity server URL does not appear to be a valid identity server": "URL por identiga servilo ŝajne ne ligas al valida identiga servilo", @@ -1932,7 +1932,7 @@ "Failed to start chat": "Malsukcesis komenci babilon", "Messages": "Mesaĝoj", "Actions": "Agoj", - "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Uzu identigan servilon por inviti retpoŝte. Klaku al »[…]« por uzi la implicitan identigan servilon (%(defaultIdentityServerName)s) aŭ administru tion en Agordoj.", + "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Uzu identigan servilon por inviti retpoŝte. Klaku al « daŭrigi » por uzi la norman identigan servilon (%(defaultIdentityServerName)s) aŭ administru tion en Agordoj.", "Displays list of commands with usages and descriptions": "Montras liston de komandoj kun priskribo de uzo", "Use the new, faster, but still experimental composer for writing messages (requires refresh)": "Uzi la novan, pli rapidan, sed ankoraŭ eksperimentan komponilon de mesaĝoj (bezonas aktualigon)", "Send read receipts for messages (requires compatible homeserver to disable)": "Sendi legokonfirmojn de mesaĝoj (bezonas akordan hejmservilon por malŝalto)", @@ -1957,8 +1957,8 @@ "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Vi nun uzas servilon por trovi kontaktojn, kaj troviĝi de ili. Vi povas ŝanĝi vian identigan servilon sube.", "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Se vi ne volas uzi servilon por trovi kontaktojn kaj troviĝi mem, enigu alian identigan servilon sube.", "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "Vi nun ne uzas identigan servilon. Por trovi kontaktojn kaj troviĝi de ili mem, aldonu iun sube.", - "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Malkonektiĝo de via identiga servilo signifas, ke vi ne povos troviĝi de aliaj uzantoj, kaj vi ne povos memfare inviti aliajn per retpoŝto aŭ telefono.", - "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Vi ne devas uzi identigan servilon. Se vi tion elektos, vi ne povos troviĝi de aliaj uzantoj, kaj vi ne povos memfare inviti ilin per retpoŝto aŭ telefono.", + "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Malkonektiĝo de via identiga servilo signifas, ke vi ne povos troviĝi de aliaj uzantoj, kaj vi ne povos memage inviti aliajn per retpoŝto aŭ telefono.", + "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Vi ne devas uzi identigan servilon. Se vi tion elektos, vi ne povos troviĝi de aliaj uzantoj, kaj vi ne povos memage inviti ilin per retpoŝto aŭ telefono.", "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Konsentu al uzkondiĉoj de la identiga servilo (%(serverName)s) por esti trovita per retpoŝtadreso aŭ telefonnumero.", "Discovery": "Trovado", "Deactivate account": "Malaktivigi konton", @@ -1996,5 +1996,136 @@ "View": "Rigardo", "Find a room…": "Trovi ĉambron…", "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Se vi ne povas travi la serĉatan ĉambron, petu inviton aŭ kreu novan ĉambron.", - "Explore rooms": "Esplori ĉambrojn" + "Explore rooms": "Esplori ĉambrojn", + "Add Email Address": "Aldoni retpoŝtadreson", + "Add Phone Number": "Aldoni telefonnumeron", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Ĉi tiu ago bezonas atingi la norman identigan servilon por kontroli retpoŝtadreson aŭ telefonnumeron, sed la servilo ne havas uzokondiĉojn.", + "Trust": "Fido", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Multiple integration managers": "Pluraj kunigiloj", + "Use the new, consistent UserInfo panel for Room Members and Group Members": "Uzi la novan, koheran informan panelon por ĉambranoj kaj grupanoj", + "Send verification requests in direct message": "Sendi kontrolajn petojn per rekta mesaĝo", + "Use the new, faster, composer for writing messages": "Uzi la novan, pli rapidan verkilon de mesaĝoj", + "Show previews/thumbnails for images": "Montri antaŭrigardojn/bildetojn je bildoj", + "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Vi forigu viajn personajn datumojn de identiga servilo antaŭ ol vi malkonektiĝos. Bedaŭrinde, identiga servilo estas nuntempe eksterreta kaj ne eblas ĝin atingi.", + "You should:": "Vi:", + "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "kontrolu kromprogramojn de via foliumilo je ĉio, kio povus malhelpi konekton al la identiga servilo (ekzemple « Privacy Badger »)", + "contact the administrators of identity server ": "kontaktu la administrantojn de la identiga servilo ", + "wait and try again later": "atendu kaj reprovu pli poste", + "Failed to update integration manager": "Malsukcesis ĝisdatigi kunigilon", + "Integration manager offline or not accessible.": "Kunigilo estas eksterreta aŭ alie neatingebla", + "Terms of service not accepted or the integration manager is invalid.": "Aŭ zokondiĉoj ne akceptiĝis, aŭ la kunigilo estas nevalida.", + "Integration manager has no terms of service": "Kunigilo havas neniujn uzokondiĉojn", + "The integration manager you have chosen does not have any terms of service.": "La elektita kunigilo havas neniujn uzokondiĉojn.", + "You are currently using %(serverName)s to manage your bots, widgets, and sticker packs.": "Vi nun mastrumas viajn robotojn, fenestaĵojn, kaj glumarkarojn per %(serverName)s.", + "Add which integration manager you want to manage your bots, widgets, and sticker packs.": "Aldonu kiun kunigilon vi volas por mastrumi viajn robotojn, fenestraĵojn, kaj glumarkarojn.", + "Integration Manager": "Kunigilo", + "Enter a new integration manager": "Metu novan kunigilon", + "Clear cache and reload": "Vakigi kaŝmemoron kaj relegi", + "Show tray icon and minimize window to it on close": "Montri pletan bildsimbolon kaj tien plejetigi la fenestron je fermo", + "Read Marker lifetime (ms)": "Vivodaŭro de legomarko (ms)", + "Read Marker off-screen lifetime (ms)": "Vivodaŭro de eksterekrana legomarko (ms)", + "Unable to revoke sharing for email address": "Ne povas senvalidigi havigadon je retpoŝtadreso", + "Unable to share email address": "Ne povas havigi vian retpoŝtadreson", + "Your email address hasn't been verified yet": "Via retpoŝtadreso ankoraŭ ne kontroliĝis", + "Click the link in the email you received to verify and then click continue again.": "Klaku la ligilon en la ricevita retletero por kontroli, kaj poste reklaku al « daŭrigi ».", + "Verify the link in your inbox": "Kontrolu la ligilon en via ricevujo.", + "Complete": "Fini", + "Revoke": "Senvalidigi", + "Share": "Havigi", + "Discovery options will appear once you have added an email above.": "Eltrovaj agordoj aperos kiam vi aldonos supre retpoŝtadreson.", + "Unable to revoke sharing for phone number": "Ne povas senvalidigi havigadon je telefonnumero", + "Unable to share phone number": "Ne povas havigi telefonnumeron", + "Please enter verification code sent via text.": "Bonvolu enigi kontrolan kodon senditan per tekstmesaĝo.", + "Discovery options will appear once you have added a phone number above.": "Eltrovaj agordoj aperos kiam vi aldonos telefonnumeron supre.", + "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Tekstmesaĝo sendiĝis al +%(msisdn)s. Bonvolu enigi la kontrolan kodon enhavitan.", + "Try scrolling up in the timeline to see if there are any earlier ones.": "Provu rulumi supren tra la historio por kontroli, ĉu ne estas iuj pli fruaj.", + "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "Vi estas forigonta 1 mesaĝon de %(user)s. Ne eblas tion malfari. Ĉu vi volas pluigi?", + "Remove %(count)s messages|one": "Forigi 1 mesaĝon", + "Room %(name)s": "Ĉambro %(name)s", + "Recent rooms": "Freŝaj vizititaj ĉambroj", + "An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "Eraris (%(errcode)s) validigo de via invito. Vi povas transdoni ĉi tiun informon al ĉambra administranto.", + "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Ĉi tiu invito al %(roomName)s sendiĝis al %(email)s, kiu ne estas ligita al via konto", + "Link this email with your account in Settings to receive invites directly in Riot.": "Ligu ĉi tiun retpoŝtadreson al via konto en Agordoj por ricevadi invitojn rekte per Riot.", + "This invite to %(roomName)s was sent to %(email)s": "La invito al %(roomName)s sendiĝis al %(email)s", + "Use an identity server in Settings to receive invites directly in Riot.": "Uzu identigan servilon en Agordoj por ricevadi invitojn rekte per Riot.", + "Share this email in Settings to receive invites directly in Riot.": "Havigu ĉi tiun retpoŝtadreson per Agordoj por ricevadi invitojn rekte per Riot.", + "%(count)s unread messages including mentions.|other": "%(count)s nelegitaj mesaĝoj, inkluzive menciojn.", + "%(count)s unread messages including mentions.|one": "1 nelegita mencio.", + "%(count)s unread messages.|other": "%(count)s nelegitaj mesaĝoj.", + "%(count)s unread messages.|one": "1 nelegita mesaĝo.", + "Unread mentions.": "Nelegitaj mencioj.", + "Unread messages.": "Nelegitaj mesaĝoj.", + "Trust & Devices": "Fido kaj Aparatoj", + "Direct messages": "Rektaj mesaĝoj", + "Failed to deactivate user": "Malsukcesis malaktivigi uzanton", + "This client does not support end-to-end encryption.": "Ĉi tiu kliento ne subtenas tutvojan ĉifradon.", + "Messages in this room are not end-to-end encrypted.": "Mesaĝoj en ĉi tiu ĉambro ne estas tutvoje ĉifrataj.", + "React": "Reagi", + "Message Actions": "Mesaĝaj agoj", + "Show image": "Montri bildon", + "You verified %(name)s": "Vi kontrolis %(name)s", + "You cancelled verifying %(name)s": "Vi nuligis kontrolon de %(name)s", + "%(name)s cancelled verifying": "%(name)s nuligis kontrolon", + "You accepted": "Vi akceptis", + "%(name)s accepted": "%(name)s akceptis", + "You cancelled": "Vi nuligis", + "%(name)s cancelled": "%(name)s nuligis", + "%(name)s wants to verify": "%(name)s volas kontroli", + "You sent a verification request": "Vi sendis peton de kontrolo", + "Frequently Used": "Ofte uzataj", + "Smileys & People": "Mienoj kaj homoj", + "Animals & Nature": "Bestoj kaj naturo", + "Food & Drink": "Manĝaĵoj kaj trinkaĵoj", + "Activities": "Agadoj", + "Travel & Places": "Lokoj kaj vojaĝado", + "Objects": "Aĵoj", + "Symbols": "Simboloj", + "Flags": "Flagoj", + "Quick Reactions": "Rapidaj reagoj", + "Cancel search": "Nuligi serĉon", + "Please create a new issue on GitHub so that we can investigate this bug.": "Bonvolu raporti novan problemon je GitHub, por ke ni povu ĝin esplori.", + "Room alias": "Kromnomo de ĉambro", + "e.g. my-room": "ekzemple mia-chambro", + "Please provide a room alias": "Bonvolu doni kromnomon de ĉambro", + "This alias is available to use": "Ĉi tiu kromnomo estas disponebla", + "This alias is already in use": "Ĉi tiu kromnomo jam estas uzata", + "Use an identity server to invite by email. Use the default (%(defaultIdentityServerName)s) or manage in Settings.": "Uzu identigan servilon por inviti per retpoŝto. Uzu la norman (%(defaultIdentityServerName)s) aŭ mastrumu per Agordoj.", + "Use an identity server to invite by email. Manage in Settings.": "Uzu identigan servilon por inviti per retpoŝto. Mastrumu per Agordoj.", + "Close dialog": "Fermi interagujon", + "Please enter a name for the room": "Bonvolu enigi nomon por la ĉambro", + "Set a room alias to easily share your room with other people.": "Agordu kromnomon de la ĉambro por facile ĝin kunhavigi al aliaj homoj.", + "This room is private, and can only be joined by invitation.": "Ĉi tiu ĉambro estas privata, kaj eblas aliĝi nur per invito.", + "Create a public room": "Krei publikan ĉambron", + "Create a private room": "Krei privatan ĉambron", + "Topic (optional)": "Temo (malnepra)", + "Make this room public": "Publikigi ĉi tiun ĉambron", + "Hide advanced": "Kaŝi specialajn", + "Show advanced": "Montri specialajn", + "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Bloki aliĝojn al ĉi tiu ĉambro de uzantoj el aliaj Matrix-serviloj (Ĉi tiun agordon ne eblas poste ŝanĝi!)", + "To verify that this device can be trusted, please check that the key you see in User Settings on that device matches the key below:": "Por kontroli ke tiu ĉi aparato estas fidinda, bonvolu kontroli, ke la ŝlosilo, kiun vi vidas en viaj Agordoj de uzanto je tiu aparato, akordas kun la ŝlosilo sube:", + "Please fill why you're reporting.": "Bonvolu skribi, kial vi raportas.", + "Report Content to Your Homeserver Administrator": "Raporti enhavon al la administrantode via hejmservilo", + "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Per raporto de ĝi tiu mesaĝo vi sendos ĝian unikan « eventan identigilon » al la administranto de via hejmservilo. Se mesaĝoj en ĉi tiu ĉambro estas ĉifrataj, la administranto de via hejmservilo ne povos legi la tekston de la mesaĝo, nek rigardi dosierojn aŭ bildojn.", + "Send report": "Sendi raporton", + "Command Help": "Helpo pri komando", + "Integrations Manager": "Kunigilo", + "To continue you need to accept the terms of this service.": "Por pluigi, vi devas akcepti la uzokondiĉojn de ĉi tiu servo.", + "Document": "Dokumento", + "Report Content": "Raporti enhavon", + "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Neniu identiga servilo estas agordita, kaj tial vi ne povas aldoni retpoŝtadreson por ose restarigi vian pasvorton.", + "Enter your custom homeserver URL What does this mean?": "Enigu vian propran hejmservilan URL-on. Kion tio signifas?", + "Enter your custom identity server URL What does this mean?": "Enigu vian propran URL-on de identiga servilo. Kion tio signifas?", + "%(creator)s created and configured the room.": "%(creator)s kreis kaj agordis la ĉambron.", + "Find a room… (e.g. %(exampleRoom)s)": "Trovi ĉambron… (ekzemple (%(exampleRoom)s)", + "Jump to first unread room.": "Salti al unua nelegita ĉambro.", + "Jump to first invite.": "Salti al unua invito.", + "No identity server is configured: add one in server settings to reset your password.": "Neniu identiga servilo estas agordita: aldonu iun per la servilaj agordoj, por restarigi vian pasvorton.", + "Command Autocomplete": "Memkompletigo de komandoj", + "Community Autocomplete": "Memkompletigo de komunumoj", + "DuckDuckGo Results": "Rezultoj de DuckDuckGo", + "Emoji Autocomplete": "Memkompletigo de mienetoj", + "Notification Autocomplete": "Memkompletigo de sciigoj", + "Room Autocomplete": "Memkompletigo de ĉambroj", + "User Autocomplete": "Memkompletigo de uzantoj" } From d545a1e0b2655a55766ef9bb3016830536ea3b0b Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sun, 10 Nov 2019 12:40:40 +0000 Subject: [PATCH 091/103] Translated using Weblate (Hungarian) Currently translated at 100.0% (1864 of 1864 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 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 5d21a17e37..67af8a6a57 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2267,5 +2267,16 @@ "Show tray icon and minimize window to it on close": "Tálcaikon mutatása és az ablak összecsukása bezáráskor", "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Ez a művelet az e-mail cím vagy telefonszám ellenőrzése miatt hozzáférést igényel az alapértelmezett azonosítási szerverhez (), de a szervernek nincsen semmilyen felhasználási feltétele.", "Trust": "Megbízom benne", - "Message Actions": "Üzenet Műveletek" + "Message Actions": "Üzenet Műveletek", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Send verification requests in direct message": "Ellenőrzés kérés küldése közvetlen üzenetben", + "You verified %(name)s": "Ellenőrizted: %(name)s", + "You cancelled verifying %(name)s": "Az ellenőrzést megszakítottad ehhez: %(name)s", + "%(name)s cancelled verifying": "%(name)s megszakította az ellenőrzést", + "You accepted": "Elfogadtad", + "%(name)s accepted": "%(name)s elfogadta", + "You cancelled": "Megszakítottad", + "%(name)s cancelled": "%(name)s megszakította", + "%(name)s wants to verify": "%(name)s ellenőrizni szeretné", + "You sent a verification request": "Ellenőrzési kérést küldtél" } From ab9f3780194637574b28f97c4f36719b054edee3 Mon Sep 17 00:00:00 2001 From: Elwyn Malethan Date: Sat, 9 Nov 2019 19:01:03 +0000 Subject: [PATCH 092/103] Translated using Weblate (Welsh) Currently translated at 0.5% (9 of 1864 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cy/ --- src/i18n/strings/cy.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/cy.json b/src/i18n/strings/cy.json index 0967ef424b..951468c747 100644 --- a/src/i18n/strings/cy.json +++ b/src/i18n/strings/cy.json @@ -1 +1,11 @@ -{} +{ + "This email address is already in use": "Mae'r cyfeiriad e-bost yma yn cael ei ddefnyddio eisoes", + "This phone number is already in use": "Mae'r rhif ffôn yma yn cael ei ddefnyddio eisoes", + "Add Email Address": "Ychwanegu Cyfeiriad E-bost", + "Failed to verify email address: make sure you clicked the link in the email": "Methiant gwirio cyfeiriad e-bost: gwnewch yn siŵr eich bod wedi clicio'r ddolen yn yr e-bost", + "Add Phone Number": "Ychwanegu Rhif Ffôn", + "The platform you're on": "Y platfform rydych chi arno", + "The version of Riot.im": "Fersiwn Riot.im", + "Whether or not you're logged in (we don't record your username)": "Os ydych wedi mewngofnodi ai peidio (nid ydym yn cofnodi'ch enw defnyddiwr)", + "Your language of choice": "Eich iaith o ddewis" +} From ef0529413308504b6fde2a1d177a6db00c98dfac Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 11 Nov 2019 10:24:40 +0000 Subject: [PATCH 093/103] Fix draw order when hovering composer format buttons This ensures all 4 sides of a button show the hover border colour as intended. Another part of https://github.com/vector-im/riot-web/issues/11203 --- res/css/views/rooms/_MessageComposerFormatBar.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/rooms/_MessageComposerFormatBar.scss b/res/css/views/rooms/_MessageComposerFormatBar.scss index 80909529ee..1b5a21bed0 100644 --- a/res/css/views/rooms/_MessageComposerFormatBar.scss +++ b/res/css/views/rooms/_MessageComposerFormatBar.scss @@ -40,6 +40,7 @@ limitations under the License. &:hover { border-color: $message-action-bar-hover-border-color; + z-index: 1; } &:first-child { From 44401d73b44b6de4daeb91613456d2760d50456d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:40:38 +0000 Subject: [PATCH 094/103] Replace all trivial Promise.defer usages with regular Promises --- src/ContentMessages.js | 174 +++++++++--------- src/Lifecycle.js | 8 +- src/components/views/rooms/Autocomplete.js | 29 ++- .../views/settings/ChangePassword.js | 9 +- src/rageshake/submit-rageshake.js | 40 ++-- 5 files changed, 122 insertions(+), 138 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 2d58622db8..dab8de2465 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -59,40 +59,38 @@ export class UploadCanceledError extends Error {} * and a thumbnail key. */ function createThumbnail(element, inputWidth, inputHeight, mimeType) { - const deferred = Promise.defer(); + return new Promise((resolve) => { + let targetWidth = inputWidth; + let targetHeight = inputHeight; + if (targetHeight > MAX_HEIGHT) { + targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); + targetHeight = MAX_HEIGHT; + } + if (targetWidth > MAX_WIDTH) { + targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); + targetWidth = MAX_WIDTH; + } - let targetWidth = inputWidth; - let targetHeight = inputHeight; - if (targetHeight > MAX_HEIGHT) { - targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); - targetHeight = MAX_HEIGHT; - } - if (targetWidth > MAX_WIDTH) { - targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); - targetWidth = MAX_WIDTH; - } - - const canvas = document.createElement("canvas"); - canvas.width = targetWidth; - canvas.height = targetHeight; - canvas.getContext("2d").drawImage(element, 0, 0, targetWidth, targetHeight); - canvas.toBlob(function(thumbnail) { - deferred.resolve({ - info: { - thumbnail_info: { - w: targetWidth, - h: targetHeight, - mimetype: thumbnail.type, - size: thumbnail.size, + const canvas = document.createElement("canvas"); + canvas.width = targetWidth; + canvas.height = targetHeight; + canvas.getContext("2d").drawImage(element, 0, 0, targetWidth, targetHeight); + canvas.toBlob(function(thumbnail) { + resolve({ + info: { + thumbnail_info: { + w: targetWidth, + h: targetHeight, + mimetype: thumbnail.type, + size: thumbnail.size, + }, + w: inputWidth, + h: inputHeight, }, - w: inputWidth, - h: inputHeight, - }, - thumbnail: thumbnail, - }); - }, mimeType); - - return deferred.promise; + thumbnail: thumbnail, + }); + }, mimeType); + }); } /** @@ -179,30 +177,29 @@ function infoForImageFile(matrixClient, roomId, imageFile) { * @return {Promise} A promise that resolves with the video image element. */ function loadVideoElement(videoFile) { - const deferred = Promise.defer(); + return new Promise((resolve, reject) => { + // Load the file into an html element + const video = document.createElement("video"); - // Load the file into an html element - const video = document.createElement("video"); + const reader = new FileReader(); - const reader = new FileReader(); - reader.onload = function(e) { - video.src = e.target.result; + reader.onload = function(e) { + video.src = e.target.result; - // Once ready, returns its size - // Wait until we have enough data to thumbnail the first frame. - video.onloadeddata = function() { - deferred.resolve(video); + // Once ready, returns its size + // Wait until we have enough data to thumbnail the first frame. + video.onloadeddata = function() { + resolve(video); + }; + video.onerror = function(e) { + reject(e); + }; }; - video.onerror = function(e) { - deferred.reject(e); + reader.onerror = function(e) { + reject(e); }; - }; - reader.onerror = function(e) { - deferred.reject(e); - }; - reader.readAsDataURL(videoFile); - - return deferred.promise; + reader.readAsDataURL(videoFile); + }); } /** @@ -236,16 +233,16 @@ function infoForVideoFile(matrixClient, roomId, videoFile) { * is read. */ function readFileAsArrayBuffer(file) { - const deferred = Promise.defer(); - const reader = new FileReader(); - reader.onload = function(e) { - deferred.resolve(e.target.result); - }; - reader.onerror = function(e) { - deferred.reject(e); - }; - reader.readAsArrayBuffer(file); - return deferred.promise; + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = function(e) { + resolve(e.target.result); + }; + reader.onerror = function(e) { + reject(e); + }; + reader.readAsArrayBuffer(file); + }); } /** @@ -461,33 +458,34 @@ export default class ContentMessages { content.info.mimetype = file.type; } - const def = Promise.defer(); - if (file.type.indexOf('image/') == 0) { - content.msgtype = 'm.image'; - infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ - extend(content.info, imageInfo); - def.resolve(); - }, (error)=>{ - console.error(error); + const prom = new Promise((resolve) => { + if (file.type.indexOf('image/') == 0) { + content.msgtype = 'm.image'; + infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ + extend(content.info, imageInfo); + resolve(); + }, (error)=>{ + console.error(error); + content.msgtype = 'm.file'; + resolve(); + }); + } else if (file.type.indexOf('audio/') == 0) { + content.msgtype = 'm.audio'; + resolve(); + } else if (file.type.indexOf('video/') == 0) { + content.msgtype = 'm.video'; + infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ + extend(content.info, videoInfo); + resolve(); + }, (error)=>{ + content.msgtype = 'm.file'; + resolve(); + }); + } else { content.msgtype = 'm.file'; - def.resolve(); - }); - } else if (file.type.indexOf('audio/') == 0) { - content.msgtype = 'm.audio'; - def.resolve(); - } else if (file.type.indexOf('video/') == 0) { - content.msgtype = 'm.video'; - infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ - extend(content.info, videoInfo); - def.resolve(); - }, (error)=>{ - content.msgtype = 'm.file'; - def.resolve(); - }); - } else { - content.msgtype = 'm.file'; - def.resolve(); - } + resolve(); + } + }); const upload = { fileName: file.name || 'Attachment', @@ -509,7 +507,7 @@ export default class ContentMessages { dis.dispatch({action: 'upload_progress', upload: upload}); } - return def.promise.then(function() { + return prom.then(function() { // XXX: upload.promise must be the promise that // is returned by uploadFile as it has an abort() // method hacked onto it. diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 13f3abccb1..53a9b7a998 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -312,18 +312,14 @@ async function _restoreFromLocalStorage(opts) { function _handleLoadSessionFailure(e) { console.error("Unable to load session", e); - const def = Promise.defer(); const SessionRestoreErrorDialog = sdk.getComponent('views.dialogs.SessionRestoreErrorDialog'); - Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { + const modal = Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { error: e.message, - onFinished: (success) => { - def.resolve(success); - }, }); - return def.promise.then((success) => { + return modal.finished.then(([success]) => { if (success) { // user clicked continue. _clearStorage(); diff --git a/src/components/views/rooms/Autocomplete.js b/src/components/views/rooms/Autocomplete.js index ad5fa198a3..d4b51081f4 100644 --- a/src/components/views/rooms/Autocomplete.js +++ b/src/components/views/rooms/Autocomplete.js @@ -26,6 +26,7 @@ import { Room } from 'matrix-js-sdk'; import SettingsStore from "../../../settings/SettingsStore"; import Autocompleter from '../../../autocomplete/Autocompleter'; +import {sleep} from "../../../utils/promise"; const COMPOSER_SELECTED = 0; @@ -105,13 +106,11 @@ export default class Autocomplete extends React.Component { autocompleteDelay = 0; } - const deferred = Promise.defer(); - this.debounceCompletionsRequest = setTimeout(() => { - this.processQuery(query, selection).then(() => { - deferred.resolve(); - }); - }, autocompleteDelay); - return deferred.promise; + return new Promise((resolve) => { + this.debounceCompletionsRequest = setTimeout(() => { + resolve(this.processQuery(query, selection)); + }, autocompleteDelay); + }); } processQuery(query, selection) { @@ -197,16 +196,16 @@ export default class Autocomplete extends React.Component { } forceComplete() { - const done = Promise.defer(); - this.setState({ - forceComplete: true, - hide: false, - }, () => { - this.complete(this.props.query, this.props.selection).then(() => { - done.resolve(this.countCompletions()); + return new Promise((resolve) => { + this.setState({ + forceComplete: true, + hide: false, + }, () => { + this.complete(this.props.query, this.props.selection).then(() => { + resolve(this.countCompletions()); + }); }); }); - return done.promise; } onCompletionClicked(selectionOffset: number): boolean { diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index a086efaa6d..91292b19f9 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -178,17 +178,12 @@ module.exports = createReactClass({ }, _optionallySetEmail: function() { - const deferred = Promise.defer(); // Ask for an email otherwise the user has no way to reset their password const SetEmailDialog = sdk.getComponent("dialogs.SetEmailDialog"); - Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { + const modal = Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { title: _t('Do you want to set an email address?'), - onFinished: (confirmed) => { - // ignore confirmed, setting an email is optional - deferred.resolve(confirmed); - }, }); - return deferred.promise; + return modal.finished.then(([confirmed]) => confirmed); }, _onExportE2eKeysClicked: function() { diff --git a/src/rageshake/submit-rageshake.js b/src/rageshake/submit-rageshake.js index 99c412a6ab..e772912e48 100644 --- a/src/rageshake/submit-rageshake.js +++ b/src/rageshake/submit-rageshake.js @@ -105,26 +105,22 @@ export default async function sendBugReport(bugReportEndpoint, opts) { } function _submitReport(endpoint, body, progressCallback) { - const deferred = Promise.defer(); - - const req = new XMLHttpRequest(); - req.open("POST", endpoint); - req.timeout = 5 * 60 * 1000; - req.onreadystatechange = function() { - if (req.readyState === XMLHttpRequest.LOADING) { - progressCallback(_t("Waiting for response from server")); - } else if (req.readyState === XMLHttpRequest.DONE) { - on_done(); - } - }; - req.send(body); - return deferred.promise; - - function on_done() { - if (req.status < 200 || req.status >= 400) { - deferred.reject(new Error(`HTTP ${req.status}`)); - return; - } - deferred.resolve(); - } + return new Promise((resolve, reject) => { + const req = new XMLHttpRequest(); + req.open("POST", endpoint); + req.timeout = 5 * 60 * 1000; + req.onreadystatechange = function() { + if (req.readyState === XMLHttpRequest.LOADING) { + progressCallback(_t("Waiting for response from server")); + } else if (req.readyState === XMLHttpRequest.DONE) { + // on done + if (req.status < 200 || req.status >= 400) { + reject(new Error(`HTTP ${req.status}`)); + return; + } + resolve(); + } + }; + req.send(body); + }); } From 6850c147393ba7be8b98d97dfc8d7244fa503461 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:45:28 +0000 Subject: [PATCH 095/103] Replace rest of defer usages using small shim. Add homebrew promise utils --- src/Modal.js | 3 +- src/components/structures/MatrixChat.js | 5 +-- src/utils/MultiInviter.js | 3 +- src/utils/promise.js | 46 +++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 src/utils/promise.js diff --git a/src/Modal.js b/src/Modal.js index 26c9da8bbb..cb19731f01 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -24,6 +24,7 @@ import sdk from './index'; import dis from './dispatcher'; import { _t } from './languageHandler'; import Promise from "bluebird"; +import {defer} from "./utils/promise"; const DIALOG_CONTAINER_ID = "mx_Dialog_Container"; const STATIC_DIALOG_CONTAINER_ID = "mx_Dialog_StaticContainer"; @@ -202,7 +203,7 @@ class ModalManager { } _getCloseFn(modal, props) { - const deferred = Promise.defer(); + const deferred = defer(); return [(...args) => { deferred.resolve(args); if (props && props.onFinished) props.onFinished.apply(null, args); diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index da67416400..d12eba88f7 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -60,6 +60,7 @@ import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils"; import DMRoomMap from '../../utils/DMRoomMap'; import { countRoomsWithNotif } from '../../RoomNotifs'; import { setTheme } from "../../theme"; +import {defer} from "../../utils/promise"; // Disable warnings for now: we use deprecated bluebird functions // and need to migrate, but they spam the console with warnings. @@ -236,7 +237,7 @@ export default createReactClass({ // Used by _viewRoom before getting state from sync this.firstSyncComplete = false; - this.firstSyncPromise = Promise.defer(); + this.firstSyncPromise = defer(); if (this.props.config.sync_timeline_limit) { MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit; @@ -1261,7 +1262,7 @@ export default createReactClass({ // since we're about to start the client and therefore about // to do the first sync this.firstSyncComplete = false; - this.firstSyncPromise = Promise.defer(); + this.firstSyncPromise = defer(); const cli = MatrixClientPeg.get(); const IncomingSasDialog = sdk.getComponent('views.dialogs.IncomingSasDialog'); diff --git a/src/utils/MultiInviter.js b/src/utils/MultiInviter.js index e8995b46d7..de5c2e7610 100644 --- a/src/utils/MultiInviter.js +++ b/src/utils/MultiInviter.js @@ -24,6 +24,7 @@ import {_t} from "../languageHandler"; import sdk from "../index"; import Modal from "../Modal"; import SettingsStore from "../settings/SettingsStore"; +import {defer} from "./promise"; /** * Invites multiple addresses to a room or group, handling rate limiting from the server @@ -71,7 +72,7 @@ export default class MultiInviter { }; } } - this.deferred = Promise.defer(); + this.deferred = defer(); this._inviteMore(0); return this.deferred.promise; diff --git a/src/utils/promise.js b/src/utils/promise.js new file mode 100644 index 0000000000..dd10f7fdd7 --- /dev/null +++ b/src/utils/promise.js @@ -0,0 +1,46 @@ +/* +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. +*/ + +// @flow + +// Returns a promise which resolves with a given value after the given number of ms +export const sleep = (ms: number, value: any): Promise => new Promise((resolve => { setTimeout(resolve, ms, value); })); + +// Returns a promise which resolves when the input promise resolves with its value +// or when the timeout of ms is reached with the value of given timeoutValue +export async function timeout(promise: Promise, timeoutValue: any, ms: number): Promise { + const timeoutPromise = new Promise((resolve) => { + const timeoutId = setTimeout(resolve, ms, timeoutValue); + promise.then(() => { + clearTimeout(timeoutId); + }); + }); + + return Promise.race([promise, timeoutPromise]); +} + +// Returns a Deferred +export function defer(): {resolve: () => {}, reject: () => {}, promise: Promise} { + let resolve; + let reject; + + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); + + return {resolve, reject, promise}; +} From 0a21957b2cac0cc2d0169f428187bc2e468251a9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:46:58 +0000 Subject: [PATCH 096/103] Replace Promise.delay with promise utils sleep --- src/components/structures/GroupView.js | 9 +++++---- .../views/context_menus/RoomTileContextMenu.js | 7 ++++--- src/components/views/dialogs/AddressPickerDialog.js | 3 ++- .../views/settings/tabs/user/SecurityUserSettingsTab.js | 3 ++- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 4d8f47003c..4056557a7c 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -38,6 +38,7 @@ import FlairStore from '../../stores/FlairStore'; import { showGroupAddRoomDialog } from '../../GroupAddressPicker'; import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks"; import {Group} from "matrix-js-sdk"; +import {sleep} from "../../utils/promise"; const LONG_DESC_PLACEHOLDER = _td( `

HTML for your community's page

@@ -692,7 +693,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await Promise.delay(500); + await sleep(500); GroupStore.acceptGroupInvite(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync @@ -711,7 +712,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await Promise.delay(500); + await sleep(500); GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync @@ -735,7 +736,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await Promise.delay(500); + await sleep(500); GroupStore.joinGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync @@ -787,7 +788,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await Promise.delay(500); + await sleep(500); GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync diff --git a/src/components/views/context_menus/RoomTileContextMenu.js b/src/components/views/context_menus/RoomTileContextMenu.js index 9bb573026f..541daef27f 100644 --- a/src/components/views/context_menus/RoomTileContextMenu.js +++ b/src/components/views/context_menus/RoomTileContextMenu.js @@ -32,6 +32,7 @@ import * as RoomNotifs from '../../../RoomNotifs'; import Modal from '../../../Modal'; import RoomListActions from '../../../actions/RoomListActions'; import RoomViewStore from '../../../stores/RoomViewStore'; +import {sleep} from "../../../utils/promise"; module.exports = createReactClass({ displayName: 'RoomTileContextMenu', @@ -62,7 +63,7 @@ module.exports = createReactClass({ _toggleTag: function(tagNameOn, tagNameOff) { if (!MatrixClientPeg.get().isGuest()) { - Promise.delay(500).then(() => { + sleep(500).then(() => { dis.dispatch(RoomListActions.tagRoom( MatrixClientPeg.get(), this.props.room, @@ -119,7 +120,7 @@ module.exports = createReactClass({ Rooms.guessAndSetDMRoom( this.props.room, newIsDirectMessage, - ).delay(500).finally(() => { + ).then(sleep(500)).finally(() => { // Close the context menu if (this.props.onFinished) { this.props.onFinished(); @@ -193,7 +194,7 @@ module.exports = createReactClass({ RoomNotifs.setRoomNotifsState(roomId, newState).done(() => { // delay slightly so that the user can see their state change // before closing the menu - return Promise.delay(500).then(() => { + return sleep(500).then(() => { if (this._unmounted) return; // Close the context menu if (this.props.onFinished) { diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index fb779fa96f..dc61f23956 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -32,6 +32,7 @@ import * as Email from '../../../email'; import IdentityAuthClient from '../../../IdentityAuthClient'; import { getDefaultIdentityServerUrl, useDefaultIdentityServer } from '../../../utils/IdentityServerUtils'; import { abbreviateUrl } from '../../../utils/UrlUtils'; +import {sleep} from "../../../utils/promise"; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; @@ -533,7 +534,7 @@ module.exports = createReactClass({ }; // wait a bit to let the user finish typing - await Promise.delay(500); + await sleep(500); if (cancelled) return null; try { diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js index e619791b01..222af48fa1 100644 --- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js @@ -25,6 +25,7 @@ import Analytics from "../../../../../Analytics"; import Promise from "bluebird"; import Modal from "../../../../../Modal"; import sdk from "../../../../.."; +import {sleep} from "../../../../../utils/promise"; export class IgnoredUser extends React.Component { static propTypes = { @@ -129,7 +130,7 @@ export default class SecurityUserSettingsTab extends React.Component { if (e.errcode === "M_LIMIT_EXCEEDED") { // Add a delay between each invite change in order to avoid rate // limiting by the server. - await Promise.delay(e.retry_after_ms || 2500); + await sleep(e.retry_after_ms || 2500); // Redo last action i--; From 09a8fec26187f12fe9b2d8d201c4b4fcb86af82a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:51:23 +0000 Subject: [PATCH 097/103] s/.done(/.then(/ since modern es6 track unhandled promise exceptions --- src/Lifecycle.js | 4 ++-- src/Notifier.js | 2 +- src/Resend.js | 2 +- src/ScalarMessaging.js | 8 ++++---- src/components/structures/GroupView.js | 4 ++-- src/components/structures/InteractiveAuth.js | 2 +- src/components/structures/MatrixChat.js | 8 ++++---- src/components/structures/MyGroups.js | 2 +- src/components/structures/RoomDirectory.js | 8 ++++---- src/components/structures/RoomView.js | 8 ++++---- src/components/structures/TimelinePanel.js | 4 ++-- src/components/structures/auth/ForgotPassword.js | 2 +- src/components/structures/auth/Login.js | 4 ++-- src/components/structures/auth/PostRegistration.js | 2 +- src/components/structures/auth/Registration.js | 2 +- .../views/auth/InteractiveAuthEntryComponents.js | 2 +- .../views/context_menus/RoomTileContextMenu.js | 4 ++-- .../views/dialogs/AddressPickerDialog.js | 4 ++-- src/components/views/dialogs/CreateGroupDialog.js | 2 +- src/components/views/dialogs/KeyShareDialog.js | 2 +- src/components/views/dialogs/SetEmailDialog.js | 4 ++-- src/components/views/elements/AppTile.js | 2 +- .../views/elements/EditableTextContainer.js | 4 ++-- src/components/views/elements/ErrorBoundary.js | 2 +- src/components/views/elements/ImageView.js | 2 +- src/components/views/elements/LanguageDropdown.js | 2 +- src/components/views/groups/GroupUserSettings.js | 2 +- src/components/views/messages/MAudioBody.js | 2 +- src/components/views/messages/MImageBody.js | 2 +- src/components/views/messages/MVideoBody.js | 2 +- src/components/views/right_panel/UserInfo.js | 2 +- src/components/views/rooms/LinkPreviewWidget.js | 2 +- src/components/views/rooms/MemberInfo.js | 6 +++--- src/components/views/settings/ChangeAvatar.js | 2 +- src/components/views/settings/ChangePassword.js | 2 +- src/components/views/settings/DevicesPanel.js | 2 +- src/components/views/settings/Notifications.js | 14 +++++++------- .../settings/tabs/user/HelpUserSettingsTab.js | 2 +- src/stores/RoomViewStore.js | 4 ++-- .../views/dialogs/InteractiveAuthDialog-test.js | 3 ++- .../views/elements/MemberEventListSummary-test.js | 2 +- .../views/rooms/MessageComposerInput-test.js | 3 ++- test/i18n-test/languageHandler-test.js | 2 +- 43 files changed, 74 insertions(+), 72 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 53a9b7a998..9bada98168 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -524,7 +524,7 @@ export function logout() { console.log("Failed to call logout API: token will not be invalidated"); onLoggedOut(); }, - ).done(); + ).then(); } export function softLogout() { @@ -608,7 +608,7 @@ export function onLoggedOut() { // that can occur when components try to use a null client. dis.dispatch({action: 'on_logged_out'}, true); stopMatrixClient(); - _clearStorage().done(); + _clearStorage().then(); } /** diff --git a/src/Notifier.js b/src/Notifier.js index cca0ea2b89..edb9850dfe 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -198,7 +198,7 @@ const Notifier = { if (enable) { // Attempt to get permission from user - plaf.requestNotificationPermission().done((result) => { + plaf.requestNotificationPermission().then((result) => { if (result !== 'granted') { // The permission request was dismissed or denied // TODO: Support alternative branding in messaging diff --git a/src/Resend.js b/src/Resend.js index 4eaee16d1b..51ec804c01 100644 --- a/src/Resend.js +++ b/src/Resend.js @@ -35,7 +35,7 @@ module.exports = { }, resend: function(event) { const room = MatrixClientPeg.get().getRoom(event.getRoomId()); - MatrixClientPeg.get().resendEvent(event, room).done(function(res) { + MatrixClientPeg.get().resendEvent(event, room).then(function(res) { dis.dispatch({ action: 'message_sent', event: event, diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 910a6c4f13..c0ffc3022d 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -279,7 +279,7 @@ function inviteUser(event, roomId, userId) { } } - client.invite(roomId, userId).done(function() { + client.invite(roomId, userId).then(function() { sendResponse(event, { success: true, }); @@ -398,7 +398,7 @@ function setPlumbingState(event, roomId, status) { sendError(event, _t('You need to be logged in.')); return; } - client.sendStateEvent(roomId, "m.room.plumbing", { status: status }).done(() => { + client.sendStateEvent(roomId, "m.room.plumbing", { status: status }).then(() => { sendResponse(event, { success: true, }); @@ -414,7 +414,7 @@ function setBotOptions(event, roomId, userId) { sendError(event, _t('You need to be logged in.')); return; } - client.sendStateEvent(roomId, "m.room.bot.options", event.data.content, "_" + userId).done(() => { + client.sendStateEvent(roomId, "m.room.bot.options", event.data.content, "_" + userId).then(() => { sendResponse(event, { success: true, }); @@ -444,7 +444,7 @@ function setBotPower(event, roomId, userId, level) { }, ); - client.setPowerLevel(roomId, userId, level, powerEvent).done(() => { + client.setPowerLevel(roomId, userId, level, powerEvent).then(() => { sendResponse(event, { success: true, }); diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 4056557a7c..b97d76d72a 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -639,7 +639,7 @@ export default createReactClass({ title: _t('Error'), description: _t('Failed to upload image'), }); - }).done(); + }).then(); }, _onJoinableChange: function(ev) { @@ -678,7 +678,7 @@ export default createReactClass({ this.setState({ avatarChanged: false, }); - }).done(); + }).then(); }, _saveGroup: async function() { diff --git a/src/components/structures/InteractiveAuth.js b/src/components/structures/InteractiveAuth.js index 5e06d124c4..86fc351515 100644 --- a/src/components/structures/InteractiveAuth.js +++ b/src/components/structures/InteractiveAuth.js @@ -121,7 +121,7 @@ export default createReactClass({ this.setState({ errorText: msg, }); - }).done(); + }).then(); this._intervalId = null; if (this.props.poll) { diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index d12eba88f7..c7bf2f181f 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -541,7 +541,7 @@ export default createReactClass({ const Loader = sdk.getComponent("elements.Spinner"); const modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner'); - MatrixClientPeg.get().leave(payload.room_id).done(() => { + MatrixClientPeg.get().leave(payload.room_id).then(() => { modal.close(); if (this.state.currentRoomId === payload.room_id) { dis.dispatch({action: 'view_next_room'}); @@ -862,7 +862,7 @@ export default createReactClass({ waitFor = this.firstSyncPromise.promise; } - waitFor.done(() => { + waitFor.then(() => { let presentedId = roomInfo.room_alias || roomInfo.room_id; const room = MatrixClientPeg.get().getRoom(roomInfo.room_id); if (room) { @@ -974,7 +974,7 @@ export default createReactClass({ const [shouldCreate, createOpts] = await modal.finished; if (shouldCreate) { - createRoom({createOpts}).done(); + createRoom({createOpts}).then(); } }, @@ -1750,7 +1750,7 @@ export default createReactClass({ return; } - cli.sendEvent(roomId, event.getType(), event.getContent()).done(() => { + cli.sendEvent(roomId, event.getType(), event.getContent()).then(() => { dis.dispatch({action: 'message_sent'}); }, (err) => { dis.dispatch({action: 'message_send_failed'}); diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 2de15a5444..63ae14ba09 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -47,7 +47,7 @@ export default createReactClass({ }, _fetch: function() { - this.context.matrixClient.getJoinedGroups().done((result) => { + this.context.matrixClient.getJoinedGroups().then((result) => { this.setState({groups: result.groups, error: null}); }, (err) => { if (err.errcode === 'M_GUEST_ACCESS_FORBIDDEN') { diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index 84f402e484..941381726d 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -89,7 +89,7 @@ module.exports = createReactClass({ this.setState({protocolsLoading: false}); return; } - MatrixClientPeg.get().getThirdpartyProtocols().done((response) => { + MatrixClientPeg.get().getThirdpartyProtocols().then((response) => { this.protocols = response; this.setState({protocolsLoading: false}); }, (err) => { @@ -135,7 +135,7 @@ module.exports = createReactClass({ publicRooms: [], loading: true, }); - this.getMoreRooms().done(); + this.getMoreRooms().then(); }, getMoreRooms: function() { @@ -246,7 +246,7 @@ module.exports = createReactClass({ if (!alias) return; step = _t('delete the alias.'); return MatrixClientPeg.get().deleteAlias(alias); - }).done(() => { + }).then(() => { modal.close(); this.refreshRoomList(); }, (err) => { @@ -348,7 +348,7 @@ module.exports = createReactClass({ }); return; } - MatrixClientPeg.get().getThirdpartyLocation(protocolName, fields).done((resp) => { + MatrixClientPeg.get().getThirdpartyLocation(protocolName, fields).then((resp) => { if (resp.length > 0 && resp[0].alias) { this.showRoomAlias(resp[0].alias, true); } else { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 4de573479d..d3ba517264 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1101,7 +1101,7 @@ module.exports = createReactClass({ } ContentMessages.sharedInstance().sendStickerContentToRoom(url, this.state.room.roomId, info, text, MatrixClientPeg.get()) - .done(undefined, (error) => { + .then(undefined, (error) => { if (error.name === "UnknownDeviceError") { // Let the staus bar handle this return; @@ -1145,7 +1145,7 @@ module.exports = createReactClass({ filter: filter, term: term, }); - this._handleSearchResult(searchPromise).done(); + this._handleSearchResult(searchPromise).then(); }, _handleSearchResult: function(searchPromise) { @@ -1316,7 +1316,7 @@ module.exports = createReactClass({ }, onForgetClick: function() { - MatrixClientPeg.get().forget(this.state.room.roomId).done(function() { + MatrixClientPeg.get().forget(this.state.room.roomId).then(function() { dis.dispatch({ action: 'view_next_room' }); }, function(err) { const errCode = err.errcode || _t("unknown error code"); @@ -1333,7 +1333,7 @@ module.exports = createReactClass({ this.setState({ rejecting: true, }); - MatrixClientPeg.get().leave(this.state.roomId).done(function() { + MatrixClientPeg.get().leave(this.state.roomId).then(function() { dis.dispatch({ action: 'view_next_room' }); self.setState({ rejecting: false, diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index faa6f2564a..573d82bb9d 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -462,7 +462,7 @@ const TimelinePanel = createReactClass({ // timeline window. // // see https://github.com/vector-im/vector-web/issues/1035 - this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false).done(() => { + this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false).then(() => { if (this.unmounted) { return; } const { events, liveEvents } = this._getEvents(); @@ -1088,7 +1088,7 @@ const TimelinePanel = createReactClass({ prom = prom.then(onLoaded, onError); } - prom.done(); + prom.then(); }, // handle the completion of a timeline load or localEchoUpdate, by diff --git a/src/components/structures/auth/ForgotPassword.js b/src/components/structures/auth/ForgotPassword.js index 46a5fa7bd7..6f68293caa 100644 --- a/src/components/structures/auth/ForgotPassword.js +++ b/src/components/structures/auth/ForgotPassword.js @@ -105,7 +105,7 @@ module.exports = createReactClass({ phase: PHASE_SENDING_EMAIL, }); this.reset = new PasswordReset(this.props.serverConfig.hsUrl, this.props.serverConfig.isUrl); - this.reset.resetPassword(email, password).done(() => { + this.reset.resetPassword(email, password).then(() => { this.setState({ phase: PHASE_EMAIL_SENT, }); diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index ad77ed49a5..84209e514f 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -253,7 +253,7 @@ module.exports = createReactClass({ this.setState({ busy: false, }); - }).done(); + }).then(); }, onUsernameChanged: function(username) { @@ -424,7 +424,7 @@ module.exports = createReactClass({ this.setState({ busy: false, }); - }).done(); + }).then(); }, _isSupportedFlow: function(flow) { diff --git a/src/components/structures/auth/PostRegistration.js b/src/components/structures/auth/PostRegistration.js index 66075c80f7..760163585d 100644 --- a/src/components/structures/auth/PostRegistration.js +++ b/src/components/structures/auth/PostRegistration.js @@ -43,7 +43,7 @@ module.exports = createReactClass({ const cli = MatrixClientPeg.get(); this.setState({busy: true}); const self = this; - cli.getProfileInfo(cli.credentials.userId).done(function(result) { + cli.getProfileInfo(cli.credentials.userId).then(function(result) { self.setState({ avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(result.avatar_url), busy: false, diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index 6321028457..6e0fc246d2 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -371,7 +371,7 @@ module.exports = createReactClass({ if (pushers[i].kind === 'email') { const emailPusher = pushers[i]; emailPusher.data = { brand: this.props.brand }; - matrixClient.setPusher(emailPusher).done(() => { + matrixClient.setPusher(emailPusher).then(() => { console.log("Set email branding to " + this.props.brand); }, (error) => { console.error("Couldn't set email branding: " + error); diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.js b/src/components/views/auth/InteractiveAuthEntryComponents.js index d19ce95b33..d61035210b 100644 --- a/src/components/views/auth/InteractiveAuthEntryComponents.js +++ b/src/components/views/auth/InteractiveAuthEntryComponents.js @@ -441,7 +441,7 @@ export const MsisdnAuthEntry = createReactClass({ this.props.fail(e); }).finally(() => { this.setState({requestingToken: false}); - }).done(); + }).then(); }, /* diff --git a/src/components/views/context_menus/RoomTileContextMenu.js b/src/components/views/context_menus/RoomTileContextMenu.js index 541daef27f..98628979e5 100644 --- a/src/components/views/context_menus/RoomTileContextMenu.js +++ b/src/components/views/context_menus/RoomTileContextMenu.js @@ -161,7 +161,7 @@ module.exports = createReactClass({ _onClickForget: function() { // FIXME: duplicated with RoomSettings (and dead code in RoomView) - MatrixClientPeg.get().forget(this.props.room.roomId).done(() => { + MatrixClientPeg.get().forget(this.props.room.roomId).then(() => { // Switch to another room view if we're currently viewing the // historical room if (RoomViewStore.getRoomId() === this.props.room.roomId) { @@ -191,7 +191,7 @@ module.exports = createReactClass({ this.setState({ roomNotifState: newState, }); - RoomNotifs.setRoomNotifsState(roomId, newState).done(() => { + RoomNotifs.setRoomNotifsState(roomId, newState).then(() => { // delay slightly so that the user can see their state change // before closing the menu return sleep(500).then(() => { diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index dc61f23956..caf6bc18c5 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -267,7 +267,7 @@ module.exports = createReactClass({ this.setState({ searchError: err.errcode ? err.message : _t('Something went wrong!'), }); - }).done(() => { + }).then(() => { this.setState({ busy: false, }); @@ -380,7 +380,7 @@ module.exports = createReactClass({ // Do a local search immediately this._doLocalSearch(query); } - }).done(() => { + }).then(() => { this.setState({ busy: false, }); diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index 11f4c21366..191d797a1e 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -93,7 +93,7 @@ export default createReactClass({ this.setState({createError: e}); }).finally(() => { this.setState({creating: false}); - }).done(); + }).then(); }, _onCancel: function() { diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index a10c25a0fb..51b02f1adf 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -78,7 +78,7 @@ export default createReactClass({ true, ); } - }).done(); + }).then(); }, componentWillUnmount: function() { diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index bedf713c4e..b527abffc9 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -62,7 +62,7 @@ export default createReactClass({ return; } this._addThreepid = new AddThreepid(); - this._addThreepid.addEmailAddress(emailAddress).done(() => { + this._addThreepid.addEmailAddress(emailAddress).then(() => { Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: _t( @@ -96,7 +96,7 @@ export default createReactClass({ }, verifyEmailAddress: function() { - this._addThreepid.checkEmailLinkClicked().done(() => { + this._addThreepid.checkEmailLinkClicked().then(() => { this.props.onFinished(true); }, (err) => { this.setState({emailBusy: false}); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 260b63dfd4..453630413c 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -205,7 +205,7 @@ export default class AppTile extends React.Component { if (!this._scalarClient) { this._scalarClient = defaultManager.getScalarClient(); } - this._scalarClient.getScalarToken().done((token) => { + this._scalarClient.getScalarToken().then((token) => { // Append scalar_token as a query param if not already present this._scalarClient.scalarToken = token; const u = url.parse(this._addWurlParams(this.props.url)); diff --git a/src/components/views/elements/EditableTextContainer.js b/src/components/views/elements/EditableTextContainer.js index 3bf37df951..cc49c3c67f 100644 --- a/src/components/views/elements/EditableTextContainer.js +++ b/src/components/views/elements/EditableTextContainer.js @@ -51,7 +51,7 @@ export default class EditableTextContainer extends React.Component { this.setState({busy: true}); - this.props.getInitialValue().done( + this.props.getInitialValue().then( (result) => { if (this._unmounted) { return; } this.setState({ @@ -83,7 +83,7 @@ export default class EditableTextContainer extends React.Component { errorString: null, }); - this.props.onSubmit(value).done( + this.props.onSubmit(value).then( () => { if (this._unmounted) { return; } this.setState({ diff --git a/src/components/views/elements/ErrorBoundary.js b/src/components/views/elements/ErrorBoundary.js index e53e1ec0fa..e36464c4ef 100644 --- a/src/components/views/elements/ErrorBoundary.js +++ b/src/components/views/elements/ErrorBoundary.js @@ -54,7 +54,7 @@ export default class ErrorBoundary extends React.PureComponent { if (!PlatformPeg.get()) return; MatrixClientPeg.get().stopClient(); - MatrixClientPeg.get().store.deleteAllData().done(() => { + MatrixClientPeg.get().store.deleteAllData().then(() => { PlatformPeg.get().reload(); }); }; diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 2772363bd0..09e0ff0e54 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -84,7 +84,7 @@ export default class ImageView extends React.Component { title: _t('Error'), description: _t('You cannot delete this image. (%(code)s)', {code: code}), }); - }).done(); + }).then(); }, }); }; diff --git a/src/components/views/elements/LanguageDropdown.js b/src/components/views/elements/LanguageDropdown.js index 365f9ded61..0c4b2b9d6a 100644 --- a/src/components/views/elements/LanguageDropdown.js +++ b/src/components/views/elements/LanguageDropdown.js @@ -49,7 +49,7 @@ export default class LanguageDropdown extends React.Component { this.setState({langs}); }).catch(() => { this.setState({langs: ['en']}); - }).done(); + }).then(); if (!this.props.value) { // If no value is given, we start with the first diff --git a/src/components/views/groups/GroupUserSettings.js b/src/components/views/groups/GroupUserSettings.js index 7d80bdd209..3cd5731b99 100644 --- a/src/components/views/groups/GroupUserSettings.js +++ b/src/components/views/groups/GroupUserSettings.js @@ -36,7 +36,7 @@ export default createReactClass({ }, componentWillMount: function() { - this.context.matrixClient.getJoinedGroups().done((result) => { + this.context.matrixClient.getJoinedGroups().then((result) => { this.setState({groups: result.groups || [], error: null}); }, (err) => { console.error(err); diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index b4f26d0cbd..0246d28542 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -55,7 +55,7 @@ export default class MAudioBody extends React.Component { decryptFile(content.file).then(function(blob) { decryptedBlob = blob; return URL.createObjectURL(decryptedBlob); - }).done((url) => { + }).then((url) => { this.setState({ decryptedUrl: url, decryptedBlob: decryptedBlob, diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 640baa1966..abfd8b64cd 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -289,7 +289,7 @@ export default class MImageBody extends React.Component { this.setState({ error: err, }); - }).done(); + }).then(); } // Remember that the user wanted to show this particular image diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index d277b6eae9..bc4dbf3374 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -115,7 +115,7 @@ module.exports = createReactClass({ this.setState({ error: err, }); - }).done(); + }).then(); } }, diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js index 207bf29998..192efcdd8a 100644 --- a/src/components/views/right_panel/UserInfo.js +++ b/src/components/views/right_panel/UserInfo.js @@ -870,7 +870,7 @@ const UserInfo = withLegacyMatrixClient(({matrixClient: cli, user, groupId, room }, ).finally(() => { stopUpdating(); - }).done(); + }).then(); }; const roomId = user.roomId; diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js index d93fe76b46..b06a9b9a30 100644 --- a/src/components/views/rooms/LinkPreviewWidget.js +++ b/src/components/views/rooms/LinkPreviewWidget.js @@ -53,7 +53,7 @@ module.exports = createReactClass({ ); }, (error)=>{ console.error("Failed to get URL preview: " + error); - }).done(); + }).then(); }, componentDidMount: function() { diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 2ea6392e96..68e494d5eb 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -248,7 +248,7 @@ module.exports = createReactClass({ return client.getStoredDevicesForUser(member.userId); }).finally(function() { self._cancelDeviceList = null; - }).done(function(devices) { + }).then(function(devices) { if (cancelled) { // we got cancelled - presumably a different user now return; @@ -572,7 +572,7 @@ module.exports = createReactClass({ }, ).finally(()=>{ this.setState({ updating: this.state.updating - 1 }); - }).done(); + }).then(); }, onPowerChange: async function(powerLevel) { @@ -629,7 +629,7 @@ module.exports = createReactClass({ this.setState({ updating: this.state.updating + 1 }); createRoom({dmUserId: this.props.member.userId}).finally(() => { this.setState({ updating: this.state.updating - 1 }); - }).done(); + }).then(); }, onLeaveClick: function() { diff --git a/src/components/views/settings/ChangeAvatar.js b/src/components/views/settings/ChangeAvatar.js index 32521006c7..904b17b15f 100644 --- a/src/components/views/settings/ChangeAvatar.js +++ b/src/components/views/settings/ChangeAvatar.js @@ -112,7 +112,7 @@ module.exports = createReactClass({ } }); - httpPromise.done(function() { + httpPromise.then(function() { self.setState({ phase: self.Phases.Display, avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(newUrl), diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 91292b19f9..15aa6203d7 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -174,7 +174,7 @@ module.exports = createReactClass({ newPassword: "", newPasswordConfirm: "", }); - }).done(); + }).then(); }, _optionallySetEmail: function() { diff --git a/src/components/views/settings/DevicesPanel.js b/src/components/views/settings/DevicesPanel.js index 30f507ea18..cb5db10be4 100644 --- a/src/components/views/settings/DevicesPanel.js +++ b/src/components/views/settings/DevicesPanel.js @@ -52,7 +52,7 @@ export default class DevicesPanel extends React.Component { } _loadDevices() { - MatrixClientPeg.get().getDevices().done( + MatrixClientPeg.get().getDevices().then( (resp) => { if (this._unmounted) { return; } this.setState({devices: resp.devices || []}); diff --git a/src/components/views/settings/Notifications.js b/src/components/views/settings/Notifications.js index e3b4cfe122..e67c61dff5 100644 --- a/src/components/views/settings/Notifications.js +++ b/src/components/views/settings/Notifications.js @@ -97,7 +97,7 @@ module.exports = createReactClass({ phase: this.phases.LOADING, }); - MatrixClientPeg.get().setPushRuleEnabled('global', self.state.masterPushRule.kind, self.state.masterPushRule.rule_id, !checked).done(function() { + MatrixClientPeg.get().setPushRuleEnabled('global', self.state.masterPushRule.kind, self.state.masterPushRule.rule_id, !checked).then(function() { self._refreshFromServer(); }); }, @@ -170,7 +170,7 @@ module.exports = createReactClass({ emailPusher.kind = null; emailPusherPromise = MatrixClientPeg.get().setPusher(emailPusher); } - emailPusherPromise.done(() => { + emailPusherPromise.then(() => { this._refreshFromServer(); }, (error) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -274,7 +274,7 @@ module.exports = createReactClass({ } } - Promise.all(deferreds).done(function() { + Promise.all(deferreds).then(function() { self._refreshFromServer(); }, function(error) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -343,7 +343,7 @@ module.exports = createReactClass({ } } - Promise.all(deferreds).done(function(resps) { + Promise.all(deferreds).then(function(resps) { self._refreshFromServer(); }, function(error) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -398,7 +398,7 @@ module.exports = createReactClass({ }; // Then, add the new ones - Promise.all(removeDeferreds).done(function(resps) { + Promise.all(removeDeferreds).then(function(resps) { const deferreds = []; let pushRuleVectorStateKind = self.state.vectorContentRules.vectorState; @@ -434,7 +434,7 @@ module.exports = createReactClass({ } } - Promise.all(deferreds).done(function(resps) { + Promise.all(deferreds).then(function(resps) { self._refreshFromServer(); }, onError); }, onError); @@ -650,7 +650,7 @@ module.exports = createReactClass({ externalContentRules: self.state.externalContentRules, externalPushRules: self.state.externalPushRules, }); - }).done(); + }).then(); MatrixClientPeg.get().getThreePids().then((r) => this.setState({threepids: r.threepids})); }, diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js index fbad327078..875f0bfc10 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js @@ -75,7 +75,7 @@ export default class HelpUserSettingsTab extends React.Component { // stopping in the middle of the logs. console.log("Clear cache & reload clicked"); MatrixClientPeg.get().stopClient(); - MatrixClientPeg.get().store.deleteAllData().done(() => { + MatrixClientPeg.get().store.deleteAllData().then(() => { PlatformPeg.get().reload(); }); }; diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 7e1b06c0bf..177b88c3f2 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -186,7 +186,7 @@ class RoomViewStore extends Store { roomLoading: true, roomLoadError: null, }); - MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done( + MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).then( (result) => { dis.dispatch({ action: 'view_room', @@ -223,7 +223,7 @@ class RoomViewStore extends Store { }); MatrixClientPeg.get().joinRoom( this._state.roomAlias || this._state.roomId, payload.opts, - ).done(() => { + ).then(() => { // We don't actually need to do anything here: we do *not* // clear the 'joining' flag because the Room object and/or // our 'joined' member event may not have come down the sync diff --git a/test/components/views/dialogs/InteractiveAuthDialog-test.js b/test/components/views/dialogs/InteractiveAuthDialog-test.js index b14ea7c242..7612b43b48 100644 --- a/test/components/views/dialogs/InteractiveAuthDialog-test.js +++ b/test/components/views/dialogs/InteractiveAuthDialog-test.js @@ -26,6 +26,7 @@ import sdk from 'matrix-react-sdk'; import MatrixClientPeg from '../../../../src/MatrixClientPeg'; import * as test_utils from '../../../test-utils'; +import {sleep} from "../../../../src/utils/promise"; const InteractiveAuthDialog = sdk.getComponent( 'views.dialogs.InteractiveAuthDialog', @@ -107,7 +108,7 @@ describe('InteractiveAuthDialog', function() { }, })).toBe(true); // let the request complete - return Promise.delay(1); + return sleep(1); }).then(() => { expect(onFinished.callCount).toEqual(1); expect(onFinished.calledWithExactly(true, {a: 1})).toBe(true); diff --git a/test/components/views/elements/MemberEventListSummary-test.js b/test/components/views/elements/MemberEventListSummary-test.js index 95f7e7999a..a31cbdebb5 100644 --- a/test/components/views/elements/MemberEventListSummary-test.js +++ b/test/components/views/elements/MemberEventListSummary-test.js @@ -91,7 +91,7 @@ describe('MemberEventListSummary', function() { testUtils.beforeEach(this); sandbox = testUtils.stubClient(); - languageHandler.setLanguage('en').done(done); + languageHandler.setLanguage('en').then(done); languageHandler.setMissingEntryGenerator(function(key) { return key.split('|', 2)[1]; }); diff --git a/test/components/views/rooms/MessageComposerInput-test.js b/test/components/views/rooms/MessageComposerInput-test.js index 1105a4af17..ed25c4d607 100644 --- a/test/components/views/rooms/MessageComposerInput-test.js +++ b/test/components/views/rooms/MessageComposerInput-test.js @@ -8,6 +8,7 @@ import * as testUtils from '../../../test-utils'; import sdk from 'matrix-react-sdk'; const MessageComposerInput = sdk.getComponent('views.rooms.MessageComposerInput'); import MatrixClientPeg from '../../../../src/MatrixClientPeg'; +import {sleep} from "../../../../src/utils/promise"; function addTextToDraft(text) { const components = document.getElementsByClassName('public-DraftEditor-content'); @@ -49,7 +50,7 @@ xdescribe('MessageComposerInput', () => { // warnings // (please can we make the components not setState() after // they are unmounted?) - Promise.delay(10).done(() => { + sleep(10).then(() => { if (parentDiv) { ReactDOM.unmountComponentAtNode(parentDiv); parentDiv.remove(); diff --git a/test/i18n-test/languageHandler-test.js b/test/i18n-test/languageHandler-test.js index 0d96bc15ab..8f21638703 100644 --- a/test/i18n-test/languageHandler-test.js +++ b/test/i18n-test/languageHandler-test.js @@ -11,7 +11,7 @@ describe('languageHandler', function() { testUtils.beforeEach(this); sandbox = testUtils.stubClient(); - languageHandler.setLanguage('en').done(done); + languageHandler.setLanguage('en').then(done); }); afterEach(function() { From d72dedb0cee9868792256bc8e34ee1e76e38c8dc Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 12 Nov 2019 11:43:18 +0000 Subject: [PATCH 098/103] Cache room alias to room ID mapping in memory This adds very basic cache (literally just a `Map` for now) to store room alias to room ID mappings. The improves the perceived performance of Riot when switching rooms via browser navigation (back / forward), as we no longer try to resolve the room alias every time. The cache is only in memory, so reloading manually or as part of the clear cache process will start afresh. Fixes https://github.com/vector-im/riot-web/issues/10020 --- src/RoomAliasCache.js | 35 +++++++++++++++++++++++++ src/components/structures/MatrixChat.js | 8 +++++- src/stores/RoomViewStore.js | 30 ++++++++++++++++----- 3 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 src/RoomAliasCache.js diff --git a/src/RoomAliasCache.js b/src/RoomAliasCache.js new file mode 100644 index 0000000000..bb511ba4d7 --- /dev/null +++ b/src/RoomAliasCache.js @@ -0,0 +1,35 @@ +/* +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. +*/ + +/** + * This is meant to be a cache of room alias to room ID so that moving between + * rooms happens smoothly (for example using browser back / forward buttons). + * + * For the moment, it's in memory only and so only applies for the current + * session for simplicity, but could be extended further in the future. + * + * A similar thing could also be achieved via `pushState` with a state object, + * but keeping it separate like this seems easier in case we do want to extend. + */ +const aliasToIDMap = new Map(); + +export function storeRoomAliasInCache(alias, id) { + aliasToIDMap.set(alias, id); +} + +export function getCachedRoomIDForAlias(alias) { + return aliasToIDMap.get(alias); +} diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index da67416400..6cc86bf6d7 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -60,6 +60,7 @@ import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils"; import DMRoomMap from '../../utils/DMRoomMap'; import { countRoomsWithNotif } from '../../RoomNotifs'; import { setTheme } from "../../theme"; +import { storeRoomAliasInCache } from '../../RoomAliasCache'; // Disable warnings for now: we use deprecated bluebird functions // and need to migrate, but they spam the console with warnings. @@ -866,7 +867,12 @@ export default createReactClass({ const room = MatrixClientPeg.get().getRoom(roomInfo.room_id); if (room) { const theAlias = Rooms.getDisplayAliasForRoom(room); - if (theAlias) presentedId = theAlias; + if (theAlias) { + presentedId = theAlias; + // Store display alias of the presented room in cache to speed future + // navigation. + storeRoomAliasInCache(theAlias, room.roomId); + } // Store this as the ID of the last room accessed. This is so that we can // persist which room is being stored across refreshes and browser quits. diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 7e1b06c0bf..e860ed8b24 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -20,6 +20,7 @@ import MatrixClientPeg from '../MatrixClientPeg'; import sdk from '../index'; import Modal from '../Modal'; import { _t } from '../languageHandler'; +import { getCachedRoomIDForAlias, storeRoomAliasInCache } from '../RoomAliasCache'; const INITIAL_STATE = { // Whether we're joining the currently viewed room (see isJoining()) @@ -137,7 +138,7 @@ class RoomViewStore extends Store { } } - _viewRoom(payload) { + async _viewRoom(payload) { if (payload.room_id) { const newState = { roomId: payload.room_id, @@ -176,6 +177,22 @@ class RoomViewStore extends Store { this._joinRoom(payload); } } else if (payload.room_alias) { + // Try the room alias to room ID navigation cache first to avoid + // blocking room navigation on the homeserver. + const roomId = getCachedRoomIDForAlias(payload.room_alias); + if (roomId) { + dis.dispatch({ + action: 'view_room', + room_id: roomId, + event_id: payload.event_id, + highlighted: payload.highlighted, + room_alias: payload.room_alias, + auto_join: payload.auto_join, + oob_data: payload.oob_data, + }); + return; + } + // Room alias cache miss, so let's ask the homeserver. // Resolve the alias and then do a second dispatch with the room ID acquired this._setState({ roomId: null, @@ -186,8 +203,9 @@ class RoomViewStore extends Store { roomLoading: true, roomLoadError: null, }); - MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done( - (result) => { + try { + const result = await MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias); + storeRoomAliasInCache(payload.room_alias, result.room_id); dis.dispatch({ action: 'view_room', room_id: result.room_id, @@ -197,14 +215,14 @@ class RoomViewStore extends Store { auto_join: payload.auto_join, oob_data: payload.oob_data, }); - }, (err) => { + } catch (err) { dis.dispatch({ action: 'view_room_error', room_id: null, room_alias: payload.room_alias, - err: err, + err, }); - }); + } } } From 168b1b68bb5b9700da9ad22b692b3db866f12128 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:56:21 +0000 Subject: [PATCH 099/103] Revert "s/.done(/.then(/ since modern es6 track unhandled promise exceptions" This reverts commit 09a8fec2 --- src/Lifecycle.js | 4 ++-- src/Notifier.js | 2 +- src/Resend.js | 2 +- src/ScalarMessaging.js | 8 ++++---- src/components/structures/GroupView.js | 4 ++-- src/components/structures/InteractiveAuth.js | 2 +- src/components/structures/MatrixChat.js | 8 ++++---- src/components/structures/MyGroups.js | 2 +- src/components/structures/RoomDirectory.js | 8 ++++---- src/components/structures/RoomView.js | 8 ++++---- src/components/structures/TimelinePanel.js | 4 ++-- src/components/structures/auth/ForgotPassword.js | 2 +- src/components/structures/auth/Login.js | 4 ++-- src/components/structures/auth/PostRegistration.js | 2 +- src/components/structures/auth/Registration.js | 2 +- .../views/auth/InteractiveAuthEntryComponents.js | 2 +- .../views/context_menus/RoomTileContextMenu.js | 4 ++-- .../views/dialogs/AddressPickerDialog.js | 4 ++-- src/components/views/dialogs/CreateGroupDialog.js | 2 +- src/components/views/dialogs/KeyShareDialog.js | 2 +- src/components/views/dialogs/SetEmailDialog.js | 4 ++-- src/components/views/elements/AppTile.js | 2 +- .../views/elements/EditableTextContainer.js | 4 ++-- src/components/views/elements/ErrorBoundary.js | 2 +- src/components/views/elements/ImageView.js | 2 +- src/components/views/elements/LanguageDropdown.js | 2 +- src/components/views/groups/GroupUserSettings.js | 2 +- src/components/views/messages/MAudioBody.js | 2 +- src/components/views/messages/MImageBody.js | 2 +- src/components/views/messages/MVideoBody.js | 2 +- src/components/views/right_panel/UserInfo.js | 2 +- src/components/views/rooms/LinkPreviewWidget.js | 2 +- src/components/views/rooms/MemberInfo.js | 6 +++--- src/components/views/settings/ChangeAvatar.js | 2 +- src/components/views/settings/ChangePassword.js | 2 +- src/components/views/settings/DevicesPanel.js | 2 +- src/components/views/settings/Notifications.js | 14 +++++++------- .../settings/tabs/user/HelpUserSettingsTab.js | 2 +- src/stores/RoomViewStore.js | 4 ++-- .../views/dialogs/InteractiveAuthDialog-test.js | 3 +-- .../views/elements/MemberEventListSummary-test.js | 2 +- .../views/rooms/MessageComposerInput-test.js | 3 +-- test/i18n-test/languageHandler-test.js | 2 +- 43 files changed, 72 insertions(+), 74 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 9bada98168..53a9b7a998 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -524,7 +524,7 @@ export function logout() { console.log("Failed to call logout API: token will not be invalidated"); onLoggedOut(); }, - ).then(); + ).done(); } export function softLogout() { @@ -608,7 +608,7 @@ export function onLoggedOut() { // that can occur when components try to use a null client. dis.dispatch({action: 'on_logged_out'}, true); stopMatrixClient(); - _clearStorage().then(); + _clearStorage().done(); } /** diff --git a/src/Notifier.js b/src/Notifier.js index edb9850dfe..cca0ea2b89 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -198,7 +198,7 @@ const Notifier = { if (enable) { // Attempt to get permission from user - plaf.requestNotificationPermission().then((result) => { + plaf.requestNotificationPermission().done((result) => { if (result !== 'granted') { // The permission request was dismissed or denied // TODO: Support alternative branding in messaging diff --git a/src/Resend.js b/src/Resend.js index 51ec804c01..4eaee16d1b 100644 --- a/src/Resend.js +++ b/src/Resend.js @@ -35,7 +35,7 @@ module.exports = { }, resend: function(event) { const room = MatrixClientPeg.get().getRoom(event.getRoomId()); - MatrixClientPeg.get().resendEvent(event, room).then(function(res) { + MatrixClientPeg.get().resendEvent(event, room).done(function(res) { dis.dispatch({ action: 'message_sent', event: event, diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index c0ffc3022d..910a6c4f13 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -279,7 +279,7 @@ function inviteUser(event, roomId, userId) { } } - client.invite(roomId, userId).then(function() { + client.invite(roomId, userId).done(function() { sendResponse(event, { success: true, }); @@ -398,7 +398,7 @@ function setPlumbingState(event, roomId, status) { sendError(event, _t('You need to be logged in.')); return; } - client.sendStateEvent(roomId, "m.room.plumbing", { status: status }).then(() => { + client.sendStateEvent(roomId, "m.room.plumbing", { status: status }).done(() => { sendResponse(event, { success: true, }); @@ -414,7 +414,7 @@ function setBotOptions(event, roomId, userId) { sendError(event, _t('You need to be logged in.')); return; } - client.sendStateEvent(roomId, "m.room.bot.options", event.data.content, "_" + userId).then(() => { + client.sendStateEvent(roomId, "m.room.bot.options", event.data.content, "_" + userId).done(() => { sendResponse(event, { success: true, }); @@ -444,7 +444,7 @@ function setBotPower(event, roomId, userId, level) { }, ); - client.setPowerLevel(roomId, userId, level, powerEvent).then(() => { + client.setPowerLevel(roomId, userId, level, powerEvent).done(() => { sendResponse(event, { success: true, }); diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index b97d76d72a..4056557a7c 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -639,7 +639,7 @@ export default createReactClass({ title: _t('Error'), description: _t('Failed to upload image'), }); - }).then(); + }).done(); }, _onJoinableChange: function(ev) { @@ -678,7 +678,7 @@ export default createReactClass({ this.setState({ avatarChanged: false, }); - }).then(); + }).done(); }, _saveGroup: async function() { diff --git a/src/components/structures/InteractiveAuth.js b/src/components/structures/InteractiveAuth.js index 86fc351515..5e06d124c4 100644 --- a/src/components/structures/InteractiveAuth.js +++ b/src/components/structures/InteractiveAuth.js @@ -121,7 +121,7 @@ export default createReactClass({ this.setState({ errorText: msg, }); - }).then(); + }).done(); this._intervalId = null; if (this.props.poll) { diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index c7bf2f181f..d12eba88f7 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -541,7 +541,7 @@ export default createReactClass({ const Loader = sdk.getComponent("elements.Spinner"); const modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner'); - MatrixClientPeg.get().leave(payload.room_id).then(() => { + MatrixClientPeg.get().leave(payload.room_id).done(() => { modal.close(); if (this.state.currentRoomId === payload.room_id) { dis.dispatch({action: 'view_next_room'}); @@ -862,7 +862,7 @@ export default createReactClass({ waitFor = this.firstSyncPromise.promise; } - waitFor.then(() => { + waitFor.done(() => { let presentedId = roomInfo.room_alias || roomInfo.room_id; const room = MatrixClientPeg.get().getRoom(roomInfo.room_id); if (room) { @@ -974,7 +974,7 @@ export default createReactClass({ const [shouldCreate, createOpts] = await modal.finished; if (shouldCreate) { - createRoom({createOpts}).then(); + createRoom({createOpts}).done(); } }, @@ -1750,7 +1750,7 @@ export default createReactClass({ return; } - cli.sendEvent(roomId, event.getType(), event.getContent()).then(() => { + cli.sendEvent(roomId, event.getType(), event.getContent()).done(() => { dis.dispatch({action: 'message_sent'}); }, (err) => { dis.dispatch({action: 'message_send_failed'}); diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 63ae14ba09..2de15a5444 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -47,7 +47,7 @@ export default createReactClass({ }, _fetch: function() { - this.context.matrixClient.getJoinedGroups().then((result) => { + this.context.matrixClient.getJoinedGroups().done((result) => { this.setState({groups: result.groups, error: null}); }, (err) => { if (err.errcode === 'M_GUEST_ACCESS_FORBIDDEN') { diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index 941381726d..84f402e484 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -89,7 +89,7 @@ module.exports = createReactClass({ this.setState({protocolsLoading: false}); return; } - MatrixClientPeg.get().getThirdpartyProtocols().then((response) => { + MatrixClientPeg.get().getThirdpartyProtocols().done((response) => { this.protocols = response; this.setState({protocolsLoading: false}); }, (err) => { @@ -135,7 +135,7 @@ module.exports = createReactClass({ publicRooms: [], loading: true, }); - this.getMoreRooms().then(); + this.getMoreRooms().done(); }, getMoreRooms: function() { @@ -246,7 +246,7 @@ module.exports = createReactClass({ if (!alias) return; step = _t('delete the alias.'); return MatrixClientPeg.get().deleteAlias(alias); - }).then(() => { + }).done(() => { modal.close(); this.refreshRoomList(); }, (err) => { @@ -348,7 +348,7 @@ module.exports = createReactClass({ }); return; } - MatrixClientPeg.get().getThirdpartyLocation(protocolName, fields).then((resp) => { + MatrixClientPeg.get().getThirdpartyLocation(protocolName, fields).done((resp) => { if (resp.length > 0 && resp[0].alias) { this.showRoomAlias(resp[0].alias, true); } else { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index d3ba517264..4de573479d 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1101,7 +1101,7 @@ module.exports = createReactClass({ } ContentMessages.sharedInstance().sendStickerContentToRoom(url, this.state.room.roomId, info, text, MatrixClientPeg.get()) - .then(undefined, (error) => { + .done(undefined, (error) => { if (error.name === "UnknownDeviceError") { // Let the staus bar handle this return; @@ -1145,7 +1145,7 @@ module.exports = createReactClass({ filter: filter, term: term, }); - this._handleSearchResult(searchPromise).then(); + this._handleSearchResult(searchPromise).done(); }, _handleSearchResult: function(searchPromise) { @@ -1316,7 +1316,7 @@ module.exports = createReactClass({ }, onForgetClick: function() { - MatrixClientPeg.get().forget(this.state.room.roomId).then(function() { + MatrixClientPeg.get().forget(this.state.room.roomId).done(function() { dis.dispatch({ action: 'view_next_room' }); }, function(err) { const errCode = err.errcode || _t("unknown error code"); @@ -1333,7 +1333,7 @@ module.exports = createReactClass({ this.setState({ rejecting: true, }); - MatrixClientPeg.get().leave(this.state.roomId).then(function() { + MatrixClientPeg.get().leave(this.state.roomId).done(function() { dis.dispatch({ action: 'view_next_room' }); self.setState({ rejecting: false, diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 573d82bb9d..faa6f2564a 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -462,7 +462,7 @@ const TimelinePanel = createReactClass({ // timeline window. // // see https://github.com/vector-im/vector-web/issues/1035 - this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false).then(() => { + this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false).done(() => { if (this.unmounted) { return; } const { events, liveEvents } = this._getEvents(); @@ -1088,7 +1088,7 @@ const TimelinePanel = createReactClass({ prom = prom.then(onLoaded, onError); } - prom.then(); + prom.done(); }, // handle the completion of a timeline load or localEchoUpdate, by diff --git a/src/components/structures/auth/ForgotPassword.js b/src/components/structures/auth/ForgotPassword.js index 6f68293caa..46a5fa7bd7 100644 --- a/src/components/structures/auth/ForgotPassword.js +++ b/src/components/structures/auth/ForgotPassword.js @@ -105,7 +105,7 @@ module.exports = createReactClass({ phase: PHASE_SENDING_EMAIL, }); this.reset = new PasswordReset(this.props.serverConfig.hsUrl, this.props.serverConfig.isUrl); - this.reset.resetPassword(email, password).then(() => { + this.reset.resetPassword(email, password).done(() => { this.setState({ phase: PHASE_EMAIL_SENT, }); diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index 84209e514f..ad77ed49a5 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -253,7 +253,7 @@ module.exports = createReactClass({ this.setState({ busy: false, }); - }).then(); + }).done(); }, onUsernameChanged: function(username) { @@ -424,7 +424,7 @@ module.exports = createReactClass({ this.setState({ busy: false, }); - }).then(); + }).done(); }, _isSupportedFlow: function(flow) { diff --git a/src/components/structures/auth/PostRegistration.js b/src/components/structures/auth/PostRegistration.js index 760163585d..66075c80f7 100644 --- a/src/components/structures/auth/PostRegistration.js +++ b/src/components/structures/auth/PostRegistration.js @@ -43,7 +43,7 @@ module.exports = createReactClass({ const cli = MatrixClientPeg.get(); this.setState({busy: true}); const self = this; - cli.getProfileInfo(cli.credentials.userId).then(function(result) { + cli.getProfileInfo(cli.credentials.userId).done(function(result) { self.setState({ avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(result.avatar_url), busy: false, diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index 6e0fc246d2..6321028457 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -371,7 +371,7 @@ module.exports = createReactClass({ if (pushers[i].kind === 'email') { const emailPusher = pushers[i]; emailPusher.data = { brand: this.props.brand }; - matrixClient.setPusher(emailPusher).then(() => { + matrixClient.setPusher(emailPusher).done(() => { console.log("Set email branding to " + this.props.brand); }, (error) => { console.error("Couldn't set email branding: " + error); diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.js b/src/components/views/auth/InteractiveAuthEntryComponents.js index d61035210b..d19ce95b33 100644 --- a/src/components/views/auth/InteractiveAuthEntryComponents.js +++ b/src/components/views/auth/InteractiveAuthEntryComponents.js @@ -441,7 +441,7 @@ export const MsisdnAuthEntry = createReactClass({ this.props.fail(e); }).finally(() => { this.setState({requestingToken: false}); - }).then(); + }).done(); }, /* diff --git a/src/components/views/context_menus/RoomTileContextMenu.js b/src/components/views/context_menus/RoomTileContextMenu.js index 98628979e5..541daef27f 100644 --- a/src/components/views/context_menus/RoomTileContextMenu.js +++ b/src/components/views/context_menus/RoomTileContextMenu.js @@ -161,7 +161,7 @@ module.exports = createReactClass({ _onClickForget: function() { // FIXME: duplicated with RoomSettings (and dead code in RoomView) - MatrixClientPeg.get().forget(this.props.room.roomId).then(() => { + MatrixClientPeg.get().forget(this.props.room.roomId).done(() => { // Switch to another room view if we're currently viewing the // historical room if (RoomViewStore.getRoomId() === this.props.room.roomId) { @@ -191,7 +191,7 @@ module.exports = createReactClass({ this.setState({ roomNotifState: newState, }); - RoomNotifs.setRoomNotifsState(roomId, newState).then(() => { + RoomNotifs.setRoomNotifsState(roomId, newState).done(() => { // delay slightly so that the user can see their state change // before closing the menu return sleep(500).then(() => { diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index caf6bc18c5..dc61f23956 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -267,7 +267,7 @@ module.exports = createReactClass({ this.setState({ searchError: err.errcode ? err.message : _t('Something went wrong!'), }); - }).then(() => { + }).done(() => { this.setState({ busy: false, }); @@ -380,7 +380,7 @@ module.exports = createReactClass({ // Do a local search immediately this._doLocalSearch(query); } - }).then(() => { + }).done(() => { this.setState({ busy: false, }); diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index 191d797a1e..11f4c21366 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -93,7 +93,7 @@ export default createReactClass({ this.setState({createError: e}); }).finally(() => { this.setState({creating: false}); - }).then(); + }).done(); }, _onCancel: function() { diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index 51b02f1adf..a10c25a0fb 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -78,7 +78,7 @@ export default createReactClass({ true, ); } - }).then(); + }).done(); }, componentWillUnmount: function() { diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index b527abffc9..bedf713c4e 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -62,7 +62,7 @@ export default createReactClass({ return; } this._addThreepid = new AddThreepid(); - this._addThreepid.addEmailAddress(emailAddress).then(() => { + this._addThreepid.addEmailAddress(emailAddress).done(() => { Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: _t( @@ -96,7 +96,7 @@ export default createReactClass({ }, verifyEmailAddress: function() { - this._addThreepid.checkEmailLinkClicked().then(() => { + this._addThreepid.checkEmailLinkClicked().done(() => { this.props.onFinished(true); }, (err) => { this.setState({emailBusy: false}); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 453630413c..260b63dfd4 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -205,7 +205,7 @@ export default class AppTile extends React.Component { if (!this._scalarClient) { this._scalarClient = defaultManager.getScalarClient(); } - this._scalarClient.getScalarToken().then((token) => { + this._scalarClient.getScalarToken().done((token) => { // Append scalar_token as a query param if not already present this._scalarClient.scalarToken = token; const u = url.parse(this._addWurlParams(this.props.url)); diff --git a/src/components/views/elements/EditableTextContainer.js b/src/components/views/elements/EditableTextContainer.js index cc49c3c67f..3bf37df951 100644 --- a/src/components/views/elements/EditableTextContainer.js +++ b/src/components/views/elements/EditableTextContainer.js @@ -51,7 +51,7 @@ export default class EditableTextContainer extends React.Component { this.setState({busy: true}); - this.props.getInitialValue().then( + this.props.getInitialValue().done( (result) => { if (this._unmounted) { return; } this.setState({ @@ -83,7 +83,7 @@ export default class EditableTextContainer extends React.Component { errorString: null, }); - this.props.onSubmit(value).then( + this.props.onSubmit(value).done( () => { if (this._unmounted) { return; } this.setState({ diff --git a/src/components/views/elements/ErrorBoundary.js b/src/components/views/elements/ErrorBoundary.js index e36464c4ef..e53e1ec0fa 100644 --- a/src/components/views/elements/ErrorBoundary.js +++ b/src/components/views/elements/ErrorBoundary.js @@ -54,7 +54,7 @@ export default class ErrorBoundary extends React.PureComponent { if (!PlatformPeg.get()) return; MatrixClientPeg.get().stopClient(); - MatrixClientPeg.get().store.deleteAllData().then(() => { + MatrixClientPeg.get().store.deleteAllData().done(() => { PlatformPeg.get().reload(); }); }; diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 09e0ff0e54..2772363bd0 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -84,7 +84,7 @@ export default class ImageView extends React.Component { title: _t('Error'), description: _t('You cannot delete this image. (%(code)s)', {code: code}), }); - }).then(); + }).done(); }, }); }; diff --git a/src/components/views/elements/LanguageDropdown.js b/src/components/views/elements/LanguageDropdown.js index 0c4b2b9d6a..365f9ded61 100644 --- a/src/components/views/elements/LanguageDropdown.js +++ b/src/components/views/elements/LanguageDropdown.js @@ -49,7 +49,7 @@ export default class LanguageDropdown extends React.Component { this.setState({langs}); }).catch(() => { this.setState({langs: ['en']}); - }).then(); + }).done(); if (!this.props.value) { // If no value is given, we start with the first diff --git a/src/components/views/groups/GroupUserSettings.js b/src/components/views/groups/GroupUserSettings.js index 3cd5731b99..7d80bdd209 100644 --- a/src/components/views/groups/GroupUserSettings.js +++ b/src/components/views/groups/GroupUserSettings.js @@ -36,7 +36,7 @@ export default createReactClass({ }, componentWillMount: function() { - this.context.matrixClient.getJoinedGroups().then((result) => { + this.context.matrixClient.getJoinedGroups().done((result) => { this.setState({groups: result.groups || [], error: null}); }, (err) => { console.error(err); diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index 0246d28542..b4f26d0cbd 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -55,7 +55,7 @@ export default class MAudioBody extends React.Component { decryptFile(content.file).then(function(blob) { decryptedBlob = blob; return URL.createObjectURL(decryptedBlob); - }).then((url) => { + }).done((url) => { this.setState({ decryptedUrl: url, decryptedBlob: decryptedBlob, diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index abfd8b64cd..640baa1966 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -289,7 +289,7 @@ export default class MImageBody extends React.Component { this.setState({ error: err, }); - }).then(); + }).done(); } // Remember that the user wanted to show this particular image diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index bc4dbf3374..d277b6eae9 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -115,7 +115,7 @@ module.exports = createReactClass({ this.setState({ error: err, }); - }).then(); + }).done(); } }, diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js index 192efcdd8a..207bf29998 100644 --- a/src/components/views/right_panel/UserInfo.js +++ b/src/components/views/right_panel/UserInfo.js @@ -870,7 +870,7 @@ const UserInfo = withLegacyMatrixClient(({matrixClient: cli, user, groupId, room }, ).finally(() => { stopUpdating(); - }).then(); + }).done(); }; const roomId = user.roomId; diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js index b06a9b9a30..d93fe76b46 100644 --- a/src/components/views/rooms/LinkPreviewWidget.js +++ b/src/components/views/rooms/LinkPreviewWidget.js @@ -53,7 +53,7 @@ module.exports = createReactClass({ ); }, (error)=>{ console.error("Failed to get URL preview: " + error); - }).then(); + }).done(); }, componentDidMount: function() { diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 68e494d5eb..2ea6392e96 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -248,7 +248,7 @@ module.exports = createReactClass({ return client.getStoredDevicesForUser(member.userId); }).finally(function() { self._cancelDeviceList = null; - }).then(function(devices) { + }).done(function(devices) { if (cancelled) { // we got cancelled - presumably a different user now return; @@ -572,7 +572,7 @@ module.exports = createReactClass({ }, ).finally(()=>{ this.setState({ updating: this.state.updating - 1 }); - }).then(); + }).done(); }, onPowerChange: async function(powerLevel) { @@ -629,7 +629,7 @@ module.exports = createReactClass({ this.setState({ updating: this.state.updating + 1 }); createRoom({dmUserId: this.props.member.userId}).finally(() => { this.setState({ updating: this.state.updating - 1 }); - }).then(); + }).done(); }, onLeaveClick: function() { diff --git a/src/components/views/settings/ChangeAvatar.js b/src/components/views/settings/ChangeAvatar.js index 904b17b15f..32521006c7 100644 --- a/src/components/views/settings/ChangeAvatar.js +++ b/src/components/views/settings/ChangeAvatar.js @@ -112,7 +112,7 @@ module.exports = createReactClass({ } }); - httpPromise.then(function() { + httpPromise.done(function() { self.setState({ phase: self.Phases.Display, avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(newUrl), diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 15aa6203d7..91292b19f9 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -174,7 +174,7 @@ module.exports = createReactClass({ newPassword: "", newPasswordConfirm: "", }); - }).then(); + }).done(); }, _optionallySetEmail: function() { diff --git a/src/components/views/settings/DevicesPanel.js b/src/components/views/settings/DevicesPanel.js index cb5db10be4..30f507ea18 100644 --- a/src/components/views/settings/DevicesPanel.js +++ b/src/components/views/settings/DevicesPanel.js @@ -52,7 +52,7 @@ export default class DevicesPanel extends React.Component { } _loadDevices() { - MatrixClientPeg.get().getDevices().then( + MatrixClientPeg.get().getDevices().done( (resp) => { if (this._unmounted) { return; } this.setState({devices: resp.devices || []}); diff --git a/src/components/views/settings/Notifications.js b/src/components/views/settings/Notifications.js index e67c61dff5..e3b4cfe122 100644 --- a/src/components/views/settings/Notifications.js +++ b/src/components/views/settings/Notifications.js @@ -97,7 +97,7 @@ module.exports = createReactClass({ phase: this.phases.LOADING, }); - MatrixClientPeg.get().setPushRuleEnabled('global', self.state.masterPushRule.kind, self.state.masterPushRule.rule_id, !checked).then(function() { + MatrixClientPeg.get().setPushRuleEnabled('global', self.state.masterPushRule.kind, self.state.masterPushRule.rule_id, !checked).done(function() { self._refreshFromServer(); }); }, @@ -170,7 +170,7 @@ module.exports = createReactClass({ emailPusher.kind = null; emailPusherPromise = MatrixClientPeg.get().setPusher(emailPusher); } - emailPusherPromise.then(() => { + emailPusherPromise.done(() => { this._refreshFromServer(); }, (error) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -274,7 +274,7 @@ module.exports = createReactClass({ } } - Promise.all(deferreds).then(function() { + Promise.all(deferreds).done(function() { self._refreshFromServer(); }, function(error) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -343,7 +343,7 @@ module.exports = createReactClass({ } } - Promise.all(deferreds).then(function(resps) { + Promise.all(deferreds).done(function(resps) { self._refreshFromServer(); }, function(error) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -398,7 +398,7 @@ module.exports = createReactClass({ }; // Then, add the new ones - Promise.all(removeDeferreds).then(function(resps) { + Promise.all(removeDeferreds).done(function(resps) { const deferreds = []; let pushRuleVectorStateKind = self.state.vectorContentRules.vectorState; @@ -434,7 +434,7 @@ module.exports = createReactClass({ } } - Promise.all(deferreds).then(function(resps) { + Promise.all(deferreds).done(function(resps) { self._refreshFromServer(); }, onError); }, onError); @@ -650,7 +650,7 @@ module.exports = createReactClass({ externalContentRules: self.state.externalContentRules, externalPushRules: self.state.externalPushRules, }); - }).then(); + }).done(); MatrixClientPeg.get().getThreePids().then((r) => this.setState({threepids: r.threepids})); }, diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js index 875f0bfc10..fbad327078 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js @@ -75,7 +75,7 @@ export default class HelpUserSettingsTab extends React.Component { // stopping in the middle of the logs. console.log("Clear cache & reload clicked"); MatrixClientPeg.get().stopClient(); - MatrixClientPeg.get().store.deleteAllData().then(() => { + MatrixClientPeg.get().store.deleteAllData().done(() => { PlatformPeg.get().reload(); }); }; diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 177b88c3f2..7e1b06c0bf 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -186,7 +186,7 @@ class RoomViewStore extends Store { roomLoading: true, roomLoadError: null, }); - MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).then( + MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done( (result) => { dis.dispatch({ action: 'view_room', @@ -223,7 +223,7 @@ class RoomViewStore extends Store { }); MatrixClientPeg.get().joinRoom( this._state.roomAlias || this._state.roomId, payload.opts, - ).then(() => { + ).done(() => { // We don't actually need to do anything here: we do *not* // clear the 'joining' flag because the Room object and/or // our 'joined' member event may not have come down the sync diff --git a/test/components/views/dialogs/InteractiveAuthDialog-test.js b/test/components/views/dialogs/InteractiveAuthDialog-test.js index 7612b43b48..b14ea7c242 100644 --- a/test/components/views/dialogs/InteractiveAuthDialog-test.js +++ b/test/components/views/dialogs/InteractiveAuthDialog-test.js @@ -26,7 +26,6 @@ import sdk from 'matrix-react-sdk'; import MatrixClientPeg from '../../../../src/MatrixClientPeg'; import * as test_utils from '../../../test-utils'; -import {sleep} from "../../../../src/utils/promise"; const InteractiveAuthDialog = sdk.getComponent( 'views.dialogs.InteractiveAuthDialog', @@ -108,7 +107,7 @@ describe('InteractiveAuthDialog', function() { }, })).toBe(true); // let the request complete - return sleep(1); + return Promise.delay(1); }).then(() => { expect(onFinished.callCount).toEqual(1); expect(onFinished.calledWithExactly(true, {a: 1})).toBe(true); diff --git a/test/components/views/elements/MemberEventListSummary-test.js b/test/components/views/elements/MemberEventListSummary-test.js index a31cbdebb5..95f7e7999a 100644 --- a/test/components/views/elements/MemberEventListSummary-test.js +++ b/test/components/views/elements/MemberEventListSummary-test.js @@ -91,7 +91,7 @@ describe('MemberEventListSummary', function() { testUtils.beforeEach(this); sandbox = testUtils.stubClient(); - languageHandler.setLanguage('en').then(done); + languageHandler.setLanguage('en').done(done); languageHandler.setMissingEntryGenerator(function(key) { return key.split('|', 2)[1]; }); diff --git a/test/components/views/rooms/MessageComposerInput-test.js b/test/components/views/rooms/MessageComposerInput-test.js index ed25c4d607..1105a4af17 100644 --- a/test/components/views/rooms/MessageComposerInput-test.js +++ b/test/components/views/rooms/MessageComposerInput-test.js @@ -8,7 +8,6 @@ import * as testUtils from '../../../test-utils'; import sdk from 'matrix-react-sdk'; const MessageComposerInput = sdk.getComponent('views.rooms.MessageComposerInput'); import MatrixClientPeg from '../../../../src/MatrixClientPeg'; -import {sleep} from "../../../../src/utils/promise"; function addTextToDraft(text) { const components = document.getElementsByClassName('public-DraftEditor-content'); @@ -50,7 +49,7 @@ xdescribe('MessageComposerInput', () => { // warnings // (please can we make the components not setState() after // they are unmounted?) - sleep(10).then(() => { + Promise.delay(10).done(() => { if (parentDiv) { ReactDOM.unmountComponentAtNode(parentDiv); parentDiv.remove(); diff --git a/test/i18n-test/languageHandler-test.js b/test/i18n-test/languageHandler-test.js index 8f21638703..0d96bc15ab 100644 --- a/test/i18n-test/languageHandler-test.js +++ b/test/i18n-test/languageHandler-test.js @@ -11,7 +11,7 @@ describe('languageHandler', function() { testUtils.beforeEach(this); sandbox = testUtils.stubClient(); - languageHandler.setLanguage('en').then(done); + languageHandler.setLanguage('en').done(done); }); afterEach(function() { From f9d6ed63f0e82056905fa8fcee1914d3de4deaf1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:56:32 +0000 Subject: [PATCH 100/103] Revert "Replace Promise.delay with promise utils sleep" This reverts commit 0a21957b --- src/components/structures/GroupView.js | 9 ++++----- .../views/context_menus/RoomTileContextMenu.js | 7 +++---- src/components/views/dialogs/AddressPickerDialog.js | 3 +-- .../views/settings/tabs/user/SecurityUserSettingsTab.js | 3 +-- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 4056557a7c..4d8f47003c 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -38,7 +38,6 @@ import FlairStore from '../../stores/FlairStore'; import { showGroupAddRoomDialog } from '../../GroupAddressPicker'; import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks"; import {Group} from "matrix-js-sdk"; -import {sleep} from "../../utils/promise"; const LONG_DESC_PLACEHOLDER = _td( `

HTML for your community's page

@@ -693,7 +692,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await sleep(500); + await Promise.delay(500); GroupStore.acceptGroupInvite(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync @@ -712,7 +711,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await sleep(500); + await Promise.delay(500); GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync @@ -736,7 +735,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await sleep(500); + await Promise.delay(500); GroupStore.joinGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync @@ -788,7 +787,7 @@ export default createReactClass({ // Wait 500ms to prevent flashing. Do this before sending a request otherwise we risk the // spinner disappearing after we have fetched new group data. - await sleep(500); + await Promise.delay(500); GroupStore.leaveGroup(this.props.groupId).then(() => { // don't reset membershipBusy here: wait for the membership change to come down the sync diff --git a/src/components/views/context_menus/RoomTileContextMenu.js b/src/components/views/context_menus/RoomTileContextMenu.js index 541daef27f..9bb573026f 100644 --- a/src/components/views/context_menus/RoomTileContextMenu.js +++ b/src/components/views/context_menus/RoomTileContextMenu.js @@ -32,7 +32,6 @@ import * as RoomNotifs from '../../../RoomNotifs'; import Modal from '../../../Modal'; import RoomListActions from '../../../actions/RoomListActions'; import RoomViewStore from '../../../stores/RoomViewStore'; -import {sleep} from "../../../utils/promise"; module.exports = createReactClass({ displayName: 'RoomTileContextMenu', @@ -63,7 +62,7 @@ module.exports = createReactClass({ _toggleTag: function(tagNameOn, tagNameOff) { if (!MatrixClientPeg.get().isGuest()) { - sleep(500).then(() => { + Promise.delay(500).then(() => { dis.dispatch(RoomListActions.tagRoom( MatrixClientPeg.get(), this.props.room, @@ -120,7 +119,7 @@ module.exports = createReactClass({ Rooms.guessAndSetDMRoom( this.props.room, newIsDirectMessage, - ).then(sleep(500)).finally(() => { + ).delay(500).finally(() => { // Close the context menu if (this.props.onFinished) { this.props.onFinished(); @@ -194,7 +193,7 @@ module.exports = createReactClass({ RoomNotifs.setRoomNotifsState(roomId, newState).done(() => { // delay slightly so that the user can see their state change // before closing the menu - return sleep(500).then(() => { + return Promise.delay(500).then(() => { if (this._unmounted) return; // Close the context menu if (this.props.onFinished) { diff --git a/src/components/views/dialogs/AddressPickerDialog.js b/src/components/views/dialogs/AddressPickerDialog.js index dc61f23956..fb779fa96f 100644 --- a/src/components/views/dialogs/AddressPickerDialog.js +++ b/src/components/views/dialogs/AddressPickerDialog.js @@ -32,7 +32,6 @@ import * as Email from '../../../email'; import IdentityAuthClient from '../../../IdentityAuthClient'; import { getDefaultIdentityServerUrl, useDefaultIdentityServer } from '../../../utils/IdentityServerUtils'; import { abbreviateUrl } from '../../../utils/UrlUtils'; -import {sleep} from "../../../utils/promise"; const TRUNCATE_QUERY_LIST = 40; const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200; @@ -534,7 +533,7 @@ module.exports = createReactClass({ }; // wait a bit to let the user finish typing - await sleep(500); + await Promise.delay(500); if (cancelled) return null; try { diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js index 222af48fa1..e619791b01 100644 --- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js @@ -25,7 +25,6 @@ import Analytics from "../../../../../Analytics"; import Promise from "bluebird"; import Modal from "../../../../../Modal"; import sdk from "../../../../.."; -import {sleep} from "../../../../../utils/promise"; export class IgnoredUser extends React.Component { static propTypes = { @@ -130,7 +129,7 @@ export default class SecurityUserSettingsTab extends React.Component { if (e.errcode === "M_LIMIT_EXCEEDED") { // Add a delay between each invite change in order to avoid rate // limiting by the server. - await sleep(e.retry_after_ms || 2500); + await Promise.delay(e.retry_after_ms || 2500); // Redo last action i--; From 7a512f7299f5316aba434cc639a01c4b65a5a3aa Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:56:43 +0000 Subject: [PATCH 101/103] Revert "Replace rest of defer usages using small shim. Add homebrew promise utils" This reverts commit 6850c147 --- src/Modal.js | 3 +- src/components/structures/MatrixChat.js | 5 ++- src/utils/MultiInviter.js | 3 +- src/utils/promise.js | 46 ------------------------- 4 files changed, 4 insertions(+), 53 deletions(-) delete mode 100644 src/utils/promise.js diff --git a/src/Modal.js b/src/Modal.js index cb19731f01..26c9da8bbb 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -24,7 +24,6 @@ import sdk from './index'; import dis from './dispatcher'; import { _t } from './languageHandler'; import Promise from "bluebird"; -import {defer} from "./utils/promise"; const DIALOG_CONTAINER_ID = "mx_Dialog_Container"; const STATIC_DIALOG_CONTAINER_ID = "mx_Dialog_StaticContainer"; @@ -203,7 +202,7 @@ class ModalManager { } _getCloseFn(modal, props) { - const deferred = defer(); + const deferred = Promise.defer(); return [(...args) => { deferred.resolve(args); if (props && props.onFinished) props.onFinished.apply(null, args); diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index d12eba88f7..da67416400 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -60,7 +60,6 @@ import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils"; import DMRoomMap from '../../utils/DMRoomMap'; import { countRoomsWithNotif } from '../../RoomNotifs'; import { setTheme } from "../../theme"; -import {defer} from "../../utils/promise"; // Disable warnings for now: we use deprecated bluebird functions // and need to migrate, but they spam the console with warnings. @@ -237,7 +236,7 @@ export default createReactClass({ // Used by _viewRoom before getting state from sync this.firstSyncComplete = false; - this.firstSyncPromise = defer(); + this.firstSyncPromise = Promise.defer(); if (this.props.config.sync_timeline_limit) { MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit; @@ -1262,7 +1261,7 @@ export default createReactClass({ // since we're about to start the client and therefore about // to do the first sync this.firstSyncComplete = false; - this.firstSyncPromise = defer(); + this.firstSyncPromise = Promise.defer(); const cli = MatrixClientPeg.get(); const IncomingSasDialog = sdk.getComponent('views.dialogs.IncomingSasDialog'); diff --git a/src/utils/MultiInviter.js b/src/utils/MultiInviter.js index de5c2e7610..e8995b46d7 100644 --- a/src/utils/MultiInviter.js +++ b/src/utils/MultiInviter.js @@ -24,7 +24,6 @@ import {_t} from "../languageHandler"; import sdk from "../index"; import Modal from "../Modal"; import SettingsStore from "../settings/SettingsStore"; -import {defer} from "./promise"; /** * Invites multiple addresses to a room or group, handling rate limiting from the server @@ -72,7 +71,7 @@ export default class MultiInviter { }; } } - this.deferred = defer(); + this.deferred = Promise.defer(); this._inviteMore(0); return this.deferred.promise; diff --git a/src/utils/promise.js b/src/utils/promise.js deleted file mode 100644 index dd10f7fdd7..0000000000 --- a/src/utils/promise.js +++ /dev/null @@ -1,46 +0,0 @@ -/* -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. -*/ - -// @flow - -// Returns a promise which resolves with a given value after the given number of ms -export const sleep = (ms: number, value: any): Promise => new Promise((resolve => { setTimeout(resolve, ms, value); })); - -// Returns a promise which resolves when the input promise resolves with its value -// or when the timeout of ms is reached with the value of given timeoutValue -export async function timeout(promise: Promise, timeoutValue: any, ms: number): Promise { - const timeoutPromise = new Promise((resolve) => { - const timeoutId = setTimeout(resolve, ms, timeoutValue); - promise.then(() => { - clearTimeout(timeoutId); - }); - }); - - return Promise.race([promise, timeoutPromise]); -} - -// Returns a Deferred -export function defer(): {resolve: () => {}, reject: () => {}, promise: Promise} { - let resolve; - let reject; - - const promise = new Promise((_resolve, _reject) => { - resolve = _resolve; - reject = _reject; - }); - - return {resolve, reject, promise}; -} From 548e38cba9fc24748b4fde73895ac9b30e53d2bf Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Nov 2019 11:56:53 +0000 Subject: [PATCH 102/103] Revert "Replace all trivial Promise.defer usages with regular Promises" This reverts commit 44401d73 --- src/ContentMessages.js | 174 +++++++++--------- src/Lifecycle.js | 8 +- src/components/views/rooms/Autocomplete.js | 29 +-- .../views/settings/ChangePassword.js | 9 +- src/rageshake/submit-rageshake.js | 40 ++-- 5 files changed, 138 insertions(+), 122 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index dab8de2465..2d58622db8 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -59,38 +59,40 @@ export class UploadCanceledError extends Error {} * and a thumbnail key. */ function createThumbnail(element, inputWidth, inputHeight, mimeType) { - return new Promise((resolve) => { - let targetWidth = inputWidth; - let targetHeight = inputHeight; - if (targetHeight > MAX_HEIGHT) { - targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); - targetHeight = MAX_HEIGHT; - } - if (targetWidth > MAX_WIDTH) { - targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); - targetWidth = MAX_WIDTH; - } + const deferred = Promise.defer(); - const canvas = document.createElement("canvas"); - canvas.width = targetWidth; - canvas.height = targetHeight; - canvas.getContext("2d").drawImage(element, 0, 0, targetWidth, targetHeight); - canvas.toBlob(function(thumbnail) { - resolve({ - info: { - thumbnail_info: { - w: targetWidth, - h: targetHeight, - mimetype: thumbnail.type, - size: thumbnail.size, - }, - w: inputWidth, - h: inputHeight, + let targetWidth = inputWidth; + let targetHeight = inputHeight; + if (targetHeight > MAX_HEIGHT) { + targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); + targetHeight = MAX_HEIGHT; + } + if (targetWidth > MAX_WIDTH) { + targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); + targetWidth = MAX_WIDTH; + } + + const canvas = document.createElement("canvas"); + canvas.width = targetWidth; + canvas.height = targetHeight; + canvas.getContext("2d").drawImage(element, 0, 0, targetWidth, targetHeight); + canvas.toBlob(function(thumbnail) { + deferred.resolve({ + info: { + thumbnail_info: { + w: targetWidth, + h: targetHeight, + mimetype: thumbnail.type, + size: thumbnail.size, }, - thumbnail: thumbnail, - }); - }, mimeType); - }); + w: inputWidth, + h: inputHeight, + }, + thumbnail: thumbnail, + }); + }, mimeType); + + return deferred.promise; } /** @@ -177,29 +179,30 @@ function infoForImageFile(matrixClient, roomId, imageFile) { * @return {Promise} A promise that resolves with the video image element. */ function loadVideoElement(videoFile) { - return new Promise((resolve, reject) => { - // Load the file into an html element - const video = document.createElement("video"); + const deferred = Promise.defer(); - const reader = new FileReader(); + // Load the file into an html element + const video = document.createElement("video"); - reader.onload = function(e) { - video.src = e.target.result; + const reader = new FileReader(); + reader.onload = function(e) { + video.src = e.target.result; - // Once ready, returns its size - // Wait until we have enough data to thumbnail the first frame. - video.onloadeddata = function() { - resolve(video); - }; - video.onerror = function(e) { - reject(e); - }; + // Once ready, returns its size + // Wait until we have enough data to thumbnail the first frame. + video.onloadeddata = function() { + deferred.resolve(video); }; - reader.onerror = function(e) { - reject(e); + video.onerror = function(e) { + deferred.reject(e); }; - reader.readAsDataURL(videoFile); - }); + }; + reader.onerror = function(e) { + deferred.reject(e); + }; + reader.readAsDataURL(videoFile); + + return deferred.promise; } /** @@ -233,16 +236,16 @@ function infoForVideoFile(matrixClient, roomId, videoFile) { * is read. */ function readFileAsArrayBuffer(file) { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = function(e) { - resolve(e.target.result); - }; - reader.onerror = function(e) { - reject(e); - }; - reader.readAsArrayBuffer(file); - }); + const deferred = Promise.defer(); + const reader = new FileReader(); + reader.onload = function(e) { + deferred.resolve(e.target.result); + }; + reader.onerror = function(e) { + deferred.reject(e); + }; + reader.readAsArrayBuffer(file); + return deferred.promise; } /** @@ -458,34 +461,33 @@ export default class ContentMessages { content.info.mimetype = file.type; } - const prom = new Promise((resolve) => { - if (file.type.indexOf('image/') == 0) { - content.msgtype = 'm.image'; - infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ - extend(content.info, imageInfo); - resolve(); - }, (error)=>{ - console.error(error); - content.msgtype = 'm.file'; - resolve(); - }); - } else if (file.type.indexOf('audio/') == 0) { - content.msgtype = 'm.audio'; - resolve(); - } else if (file.type.indexOf('video/') == 0) { - content.msgtype = 'm.video'; - infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ - extend(content.info, videoInfo); - resolve(); - }, (error)=>{ - content.msgtype = 'm.file'; - resolve(); - }); - } else { + const def = Promise.defer(); + if (file.type.indexOf('image/') == 0) { + content.msgtype = 'm.image'; + infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ + extend(content.info, imageInfo); + def.resolve(); + }, (error)=>{ + console.error(error); content.msgtype = 'm.file'; - resolve(); - } - }); + def.resolve(); + }); + } else if (file.type.indexOf('audio/') == 0) { + content.msgtype = 'm.audio'; + def.resolve(); + } else if (file.type.indexOf('video/') == 0) { + content.msgtype = 'm.video'; + infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ + extend(content.info, videoInfo); + def.resolve(); + }, (error)=>{ + content.msgtype = 'm.file'; + def.resolve(); + }); + } else { + content.msgtype = 'm.file'; + def.resolve(); + } const upload = { fileName: file.name || 'Attachment', @@ -507,7 +509,7 @@ export default class ContentMessages { dis.dispatch({action: 'upload_progress', upload: upload}); } - return prom.then(function() { + return def.promise.then(function() { // XXX: upload.promise must be the promise that // is returned by uploadFile as it has an abort() // method hacked onto it. diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 53a9b7a998..13f3abccb1 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -312,14 +312,18 @@ async function _restoreFromLocalStorage(opts) { function _handleLoadSessionFailure(e) { console.error("Unable to load session", e); + const def = Promise.defer(); const SessionRestoreErrorDialog = sdk.getComponent('views.dialogs.SessionRestoreErrorDialog'); - const modal = Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { + Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { error: e.message, + onFinished: (success) => { + def.resolve(success); + }, }); - return modal.finished.then(([success]) => { + return def.promise.then((success) => { if (success) { // user clicked continue. _clearStorage(); diff --git a/src/components/views/rooms/Autocomplete.js b/src/components/views/rooms/Autocomplete.js index d4b51081f4..ad5fa198a3 100644 --- a/src/components/views/rooms/Autocomplete.js +++ b/src/components/views/rooms/Autocomplete.js @@ -26,7 +26,6 @@ import { Room } from 'matrix-js-sdk'; import SettingsStore from "../../../settings/SettingsStore"; import Autocompleter from '../../../autocomplete/Autocompleter'; -import {sleep} from "../../../utils/promise"; const COMPOSER_SELECTED = 0; @@ -106,11 +105,13 @@ export default class Autocomplete extends React.Component { autocompleteDelay = 0; } - return new Promise((resolve) => { - this.debounceCompletionsRequest = setTimeout(() => { - resolve(this.processQuery(query, selection)); - }, autocompleteDelay); - }); + const deferred = Promise.defer(); + this.debounceCompletionsRequest = setTimeout(() => { + this.processQuery(query, selection).then(() => { + deferred.resolve(); + }); + }, autocompleteDelay); + return deferred.promise; } processQuery(query, selection) { @@ -196,16 +197,16 @@ export default class Autocomplete extends React.Component { } forceComplete() { - return new Promise((resolve) => { - this.setState({ - forceComplete: true, - hide: false, - }, () => { - this.complete(this.props.query, this.props.selection).then(() => { - resolve(this.countCompletions()); - }); + const done = Promise.defer(); + this.setState({ + forceComplete: true, + hide: false, + }, () => { + this.complete(this.props.query, this.props.selection).then(() => { + done.resolve(this.countCompletions()); }); }); + return done.promise; } onCompletionClicked(selectionOffset: number): boolean { diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 91292b19f9..a086efaa6d 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -178,12 +178,17 @@ module.exports = createReactClass({ }, _optionallySetEmail: function() { + const deferred = Promise.defer(); // Ask for an email otherwise the user has no way to reset their password const SetEmailDialog = sdk.getComponent("dialogs.SetEmailDialog"); - const modal = Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { + Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { title: _t('Do you want to set an email address?'), + onFinished: (confirmed) => { + // ignore confirmed, setting an email is optional + deferred.resolve(confirmed); + }, }); - return modal.finished.then(([confirmed]) => confirmed); + return deferred.promise; }, _onExportE2eKeysClicked: function() { diff --git a/src/rageshake/submit-rageshake.js b/src/rageshake/submit-rageshake.js index e772912e48..99c412a6ab 100644 --- a/src/rageshake/submit-rageshake.js +++ b/src/rageshake/submit-rageshake.js @@ -105,22 +105,26 @@ export default async function sendBugReport(bugReportEndpoint, opts) { } function _submitReport(endpoint, body, progressCallback) { - return new Promise((resolve, reject) => { - const req = new XMLHttpRequest(); - req.open("POST", endpoint); - req.timeout = 5 * 60 * 1000; - req.onreadystatechange = function() { - if (req.readyState === XMLHttpRequest.LOADING) { - progressCallback(_t("Waiting for response from server")); - } else if (req.readyState === XMLHttpRequest.DONE) { - // on done - if (req.status < 200 || req.status >= 400) { - reject(new Error(`HTTP ${req.status}`)); - return; - } - resolve(); - } - }; - req.send(body); - }); + const deferred = Promise.defer(); + + const req = new XMLHttpRequest(); + req.open("POST", endpoint); + req.timeout = 5 * 60 * 1000; + req.onreadystatechange = function() { + if (req.readyState === XMLHttpRequest.LOADING) { + progressCallback(_t("Waiting for response from server")); + } else if (req.readyState === XMLHttpRequest.DONE) { + on_done(); + } + }; + req.send(body); + return deferred.promise; + + function on_done() { + if (req.status < 200 || req.status >= 400) { + deferred.reject(new Error(`HTTP ${req.status}`)); + return; + } + deferred.resolve(); + } } From 3f2b77189e31c0cb3617d78105987190f10502a9 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 12 Nov 2019 13:29:01 +0000 Subject: [PATCH 103/103] Simplify dispatch blocks --- src/stores/RoomViewStore.js | 75 +++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index e860ed8b24..6a405124f4 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -179,50 +179,43 @@ class RoomViewStore extends Store { } else if (payload.room_alias) { // Try the room alias to room ID navigation cache first to avoid // blocking room navigation on the homeserver. - const roomId = getCachedRoomIDForAlias(payload.room_alias); - if (roomId) { - dis.dispatch({ - action: 'view_room', - room_id: roomId, - event_id: payload.event_id, - highlighted: payload.highlighted, - room_alias: payload.room_alias, - auto_join: payload.auto_join, - oob_data: payload.oob_data, + let roomId = getCachedRoomIDForAlias(payload.room_alias); + if (!roomId) { + // Room alias cache miss, so let's ask the homeserver. Resolve the alias + // and then do a second dispatch with the room ID acquired. + this._setState({ + roomId: null, + initialEventId: null, + initialEventPixelOffset: null, + isInitialEventHighlighted: null, + roomAlias: payload.room_alias, + roomLoading: true, + roomLoadError: null, }); - return; + try { + const result = await MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias); + storeRoomAliasInCache(payload.room_alias, result.room_id); + roomId = result.room_id; + } catch (err) { + dis.dispatch({ + action: 'view_room_error', + room_id: null, + room_alias: payload.room_alias, + err, + }); + return; + } } - // Room alias cache miss, so let's ask the homeserver. - // Resolve the alias and then do a second dispatch with the room ID acquired - this._setState({ - roomId: null, - initialEventId: null, - initialEventPixelOffset: null, - isInitialEventHighlighted: null, - roomAlias: payload.room_alias, - roomLoading: true, - roomLoadError: null, + + dis.dispatch({ + action: 'view_room', + room_id: roomId, + event_id: payload.event_id, + highlighted: payload.highlighted, + room_alias: payload.room_alias, + auto_join: payload.auto_join, + oob_data: payload.oob_data, }); - try { - const result = await MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias); - storeRoomAliasInCache(payload.room_alias, result.room_id); - dis.dispatch({ - action: 'view_room', - room_id: result.room_id, - event_id: payload.event_id, - highlighted: payload.highlighted, - room_alias: payload.room_alias, - auto_join: payload.auto_join, - oob_data: payload.oob_data, - }); - } catch (err) { - dis.dispatch({ - action: 'view_room_error', - room_id: null, - room_alias: payload.room_alias, - err, - }); - } } }