From 42b63fbc811a0bc98acd6baa18d023d843a8fa91 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 14 Feb 2020 09:36:10 +0000 Subject: [PATCH 01/21] Fix share message context menu option keyboard a11y Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/context_menus/MessageContextMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 7215a45be2..136c31803e 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -414,7 +414,7 @@ export default createReactClass({ } // XXX: if we use room ID, we should also include a server where the event can be found (other than in the domain of the event ID) const permalinkButton = ( - + { mxEvent.isRedacted() || mxEvent.getType() !== 'm.room.message' ? _t('Share Permalink') : _t('Share Message') } From 46e63fd5715c9c6b96133a445202afb4e3859efb Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 18 Feb 2020 11:14:16 +0100 Subject: [PATCH 02/21] cancel on dialog close --- .../views/dialogs/VerificationRequestDialog.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/views/dialogs/VerificationRequestDialog.js b/src/components/views/dialogs/VerificationRequestDialog.js index 8080fa09f3..abcf925f96 100644 --- a/src/components/views/dialogs/VerificationRequestDialog.js +++ b/src/components/views/dialogs/VerificationRequestDialog.js @@ -26,10 +26,15 @@ export default class VerificationRequestDialog extends React.Component { onFinished: PropTypes.func.isRequired, }; + constructor(...args) { + super(...args); + this.onFinished = this.onFinished.bind(this); + } + render() { const BaseDialog = sdk.getComponent("views.dialogs.BaseDialog"); const EncryptionPanel = sdk.getComponent("views.right_panel.EncryptionPanel"); - return ; } + + onFinished() { + this.props.verificationRequest.cancel(); + this.props.onFinished(); + } } From 600cb64d001fca0cd93ed6469ec0e9da2ef577d5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 18 Feb 2020 15:04:57 +0000 Subject: [PATCH 03/21] don't nest inside Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/context_menus/MessageContextMenu.js | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 136c31803e..ea5623fe48 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -414,11 +414,16 @@ export default createReactClass({ } // XXX: if we use room ID, we should also include a server where the event can be found (other than in the domain of the event ID) const permalinkButton = ( - - - { mxEvent.isRedacted() || mxEvent.getType() !== 'm.room.message' - ? _t('Share Permalink') : _t('Share Message') } - + + { mxEvent.isRedacted() || mxEvent.getType() !== 'm.room.message' + ? _t('Share Permalink') : _t('Share Message') } ); @@ -436,16 +441,15 @@ export default createReactClass({ isUrlPermitted(mxEvent.event.content.external_url) ) { externalURLButton = ( - - - { _t('Source URL') } - + + { _t('Source URL') } ); } From cb5882d59bb0d3f7efb2d8aff75cc2489d470466 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 19 Feb 2020 10:40:00 +0100 Subject: [PATCH 04/21] add null check --- src/components/structures/RightPanel.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js index eddd26c857..20df323c10 100644 --- a/src/components/structures/RightPanel.js +++ b/src/components/structures/RightPanel.js @@ -92,6 +92,7 @@ export default class RightPanel extends React.Component { // not mounted in time to get the dispatch. // Until then, let this code serve as a warning from history. if ( + rps.roomPanelPhaseParams.member && userForPanel.userId === rps.roomPanelPhaseParams.member.userId && rps.roomPanelPhaseParams.verificationRequest ) { From 59f8b4f6b1095c49c2eee25c493ba2c607ea7e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 18 Feb 2020 14:13:08 +0100 Subject: [PATCH 05/21] EventIndex: Don't index key verification events. Since cross-signing is a thing key verification events have become part of the timeline and room history. Those events are m.room.message events for backwards compatibility, so clients that don't support key verification in the timeline print out a fall-back message. --- src/indexing/EventIndex.js | 48 +++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/indexing/EventIndex.js b/src/indexing/EventIndex.js index 5769080511..475509c2bc 100644 --- a/src/indexing/EventIndex.js +++ b/src/indexing/EventIndex.js @@ -240,6 +240,36 @@ export default class EventIndex extends EventEmitter { this.crawlerCheckpoints.push(backwardsCheckpoint); } + /** + * Check if an event should be added to the event index. + * + * Most notably we filter events for which decryption failed, are redacted + * or aren't of a type that we know how to index. + * + * @param {MatrixEvent} ev The event that should checked. + */ + isValidEvent(ev) { + const validEventType = ([ + "m.room.message", + "m.room.name", + "m.room.topic", + ].indexOf(ev.getType()) >= 0 + && !ev.isRedacted() && !ev.isDecryptionFailure() + ); + + let validMsgType = true; + + if (ev.getType() === "m.room.message" && !ev.isRedacted()) { + // Expand this if there are more invalid msgtypes. + const msgtype = ev.getContent().msgtype; + + if (!msgtype) validMsgType = false; + else validMsgType = !msgtype.startsWith("m.key.verification"); + } + + return validEventType && validMsgType; + } + /** * Queue up live events to be added to the event index. * @@ -248,10 +278,7 @@ export default class EventIndex extends EventEmitter { async addLiveEventToIndex(ev) { const indexManager = PlatformPeg.get().getEventIndexingManager(); - if (["m.room.message", "m.room.name", "m.room.topic"] - .indexOf(ev.getType()) == -1) { - return; - } + if (!this.isValidEvent(ev)) return; const jsonEvent = ev.toJSON(); const e = ev.isEncrypted() ? jsonEvent.decrypted : jsonEvent; @@ -407,22 +434,11 @@ export default class EventIndex extends EventEmitter { // Let us wait for all the events to get decrypted. await Promise.all(decryptionPromises); - // We filter out events for which decryption failed, are redacted - // or aren't of a type that we know how to index. - const isValidEvent = (value) => { - return ([ - "m.room.message", - "m.room.name", - "m.room.topic", - ].indexOf(value.getType()) >= 0 - && !value.isRedacted() && !value.isDecryptionFailure() - ); - }; // TODO if there are no events at this point we're missing a lot // decryption keys, do we want to retry this checkpoint at a later // stage? - const filteredEvents = matrixEvents.filter(isValidEvent); + const filteredEvents = matrixEvents.filter(this.isValidEvent); // Let us convert the events back into a format that EventIndex can // consume. From 156c6b8db8be9025389cb68bd47cde2feea5b933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 18 Feb 2020 14:45:03 +0100 Subject: [PATCH 06/21] EventIndex: Document the return value of the isValidEvent method. --- src/indexing/EventIndex.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/indexing/EventIndex.js b/src/indexing/EventIndex.js index 475509c2bc..1d85d83f07 100644 --- a/src/indexing/EventIndex.js +++ b/src/indexing/EventIndex.js @@ -247,6 +247,8 @@ export default class EventIndex extends EventEmitter { * or aren't of a type that we know how to index. * * @param {MatrixEvent} ev The event that should checked. + * @returns {bool} Returns true if the event can be indexed, false + * otherwise. */ isValidEvent(ev) { const validEventType = ([ From 7f71e551da203a7412df01bd167dd89e57a4e840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 19 Feb 2020 14:36:21 +0100 Subject: [PATCH 07/21] EventIndex: Split out the statements that check for a valid event type. --- src/indexing/EventIndex.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/indexing/EventIndex.js b/src/indexing/EventIndex.js index 1d85d83f07..c8a9a4c1fa 100644 --- a/src/indexing/EventIndex.js +++ b/src/indexing/EventIndex.js @@ -251,13 +251,8 @@ export default class EventIndex extends EventEmitter { * otherwise. */ isValidEvent(ev) { - const validEventType = ([ - "m.room.message", - "m.room.name", - "m.room.topic", - ].indexOf(ev.getType()) >= 0 - && !ev.isRedacted() && !ev.isDecryptionFailure() - ); + const isUsefulType = ["m.room.message", "m.room.name", "m.room.topic"].includes(ev.getType()); + const validEventType = isUsefulType && !ev.isRedacted() && !ev.isDecryptionFailure(); let validMsgType = true; From a5b9682572880379fb196b69b2f4f55ed52a0713 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 19 Feb 2020 15:15:05 +0100 Subject: [PATCH 08/21] show spinner while loading local aliases --- .../views/room_settings/AliasSettings.js | 91 +++++++++++-------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index d7befa488d..a52fa09c87 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -91,6 +91,7 @@ export default class AliasSettings extends React.Component { remoteDomains: [], // [ domain.com, foobar.com ] canonicalAlias: null, // #canonical:domain.com updatingCanonicalAlias: false, + localAliasesLoading: true, }; if (props.canonicalAliasEvent) { @@ -102,28 +103,32 @@ export default class AliasSettings extends React.Component { async componentWillMount() { const cli = MatrixClientPeg.get(); - if (await cli.doesServerSupportUnstableFeature("org.matrix.msc2432")) { - const response = await cli.unstableGetLocalAliases(this.props.roomId); - const localAliases = response.aliases; - const localDomain = cli.getDomain(); - const domainToAliases = Object.assign( - {}, - // FIXME, any localhost alt_aliases will be ignored as they are overwritten by localAliases - this.aliasesToDictionary(this._getAltAliases()), - {[localDomain]: localAliases || []}, - ); - const remoteDomains = Object.keys(domainToAliases).filter((domain) => { - return domain !== localDomain && domainToAliases[domain].length > 0; - }); - this.setState({ domainToAliases, remoteDomains }); - } else { - const state = {}; - const localDomain = cli.getDomain(); - state.domainToAliases = this.aliasEventsToDictionary(this.props.aliasEvents || []); - state.remoteDomains = Object.keys(state.domainToAliases).filter((domain) => { - return domain !== localDomain && state.domainToAliases[domain].length > 0; - }); - this.setState(state); + try { + if (await cli.doesServerSupportUnstableFeature("org.matrix.msc2432")) { + const response = await cli.unstableGetLocalAliases(this.props.roomId); + const localAliases = response.aliases; + const localDomain = cli.getDomain(); + const domainToAliases = Object.assign( + {}, + // FIXME, any localhost alt_aliases will be ignored as they are overwritten by localAliases + this.aliasesToDictionary(this._getAltAliases()), + {[localDomain]: localAliases || []}, + ); + const remoteDomains = Object.keys(domainToAliases).filter((domain) => { + return domain !== localDomain && domainToAliases[domain].length > 0; + }); + this.setState({ domainToAliases, remoteDomains }); + } else { + const state = {}; + const localDomain = cli.getDomain(); + state.domainToAliases = this.aliasEventsToDictionary(this.props.aliasEvents || []); + state.remoteDomains = Object.keys(state.domainToAliases).filter((domain) => { + return domain !== localDomain && state.domainToAliases[domain].length > 0; + }); + this.setState(state); + } + } finally { + this.setState({localAliasesLoading: false}); } } @@ -302,26 +307,34 @@ export default class AliasSettings extends React.Component { ); } + let localAliasesList; + if (this.state.localAliasesLoading) { + const Spinner = sdk.getComponent("elements.Spinner"); + localAliasesList = ; + } else { + localAliasesList = ; + } + return (
{canonicalAliasSection} - + {localAliasesList} {remoteAliasesSection}
); From a687d158e881186db04ffef39f034dd94479759e Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 19 Feb 2020 15:59:37 +0000 Subject: [PATCH 09/21] Released js-sdk --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 793692d8b4..5aa4163b51 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "is-ip": "^2.0.0", "linkifyjs": "^2.1.6", "lodash": "^4.17.14", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", + "matrix-js-sdk": "5.0.1", "minimist": "^1.2.0", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 1ed39459d0..6924d7dcc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5760,10 +5760,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@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-5.0.0.tgz#dcbab35f1afdb35ef0364eb232e78e0fb7dc2a5b" - integrity sha512-A/aeE2Zn2OHq1n/9wIHCszrQZ7oXfThUHWi5Kz7illVCPUJ3JrZ31XVvx02k6vBasDcUtjAfZblHdTVN62cWLw== +matrix-js-sdk@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-5.0.1.tgz#ffbbc89d2436f9eb378cd81bd3993f59ec8fb895" + integrity sha512-1Jl18tYDGQNo+PWC2mBdYd6WNrL20jhG9+FF1p2w6paS7IBC74QDCEKP3GLXr3SSmWdNuAYTFB94vZQRJ31HzA== dependencies: "@babel/runtime" "^7.8.3" another-json "^0.2.0" From faf8a5c2db57149a73bb448f98bdf26b310fa7a2 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 19 Feb 2020 16:03:57 +0000 Subject: [PATCH 10/21] Prepare changelog for v2.1.1 --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4e0b41883..fa02dc1ae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +Changes in [2.1.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v2.1.1) (2020-02-19) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.1.0...v2.1.1) + + * show spinner while loading local aliases + [\#4090](https://github.com/matrix-org/matrix-react-sdk/pull/4090) + * Don't index key verification events. + [\#4083](https://github.com/matrix-org/matrix-react-sdk/pull/4083) + * Get rid of dependence on usercontent.riot.im + [\#4046](https://github.com/matrix-org/matrix-react-sdk/pull/4046) + * also detect aliases using new /aliases endpoint for room access settings + [\#4089](https://github.com/matrix-org/matrix-react-sdk/pull/4089) + * get local aliases from /aliases in room settings + [\#4086](https://github.com/matrix-org/matrix-react-sdk/pull/4086) + * Start verification sessions in an E2E DM where possible + [\#4080](https://github.com/matrix-org/matrix-react-sdk/pull/4080) + * Only show supported verification methods + [\#4077](https://github.com/matrix-org/matrix-react-sdk/pull/4077) + * Use local echo in VerificationRequest for accepting/declining a verification + request + [\#4072](https://github.com/matrix-org/matrix-react-sdk/pull/4072) + * Report installed PWA, touch input status in rageshakes, analytics + [\#4078](https://github.com/matrix-org/matrix-react-sdk/pull/4078) + * refactor event grouping into separate helper classes + [\#4059](https://github.com/matrix-org/matrix-react-sdk/pull/4059) + * Find existing requests when starting a new verification request + [\#4070](https://github.com/matrix-org/matrix-react-sdk/pull/4070) + * Always speak the full text of the typing indicator when it updates. + [\#4074](https://github.com/matrix-org/matrix-react-sdk/pull/4074) + * Fix escaped markdown passing backslashes through + [\#4008](https://github.com/matrix-org/matrix-react-sdk/pull/4008) + * Move the sidebar to below the sidebar tab buttons for screen readers. + [\#4071](https://github.com/matrix-org/matrix-react-sdk/pull/4071) + Changes in [2.1.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v2.1.0) (2020-02-17) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.1.0-rc.2...v2.1.0) From 2d05205c9e5a8b2aa68fcfe3d44f601fd3a290cd Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 19 Feb 2020 16:03:58 +0000 Subject: [PATCH 11/21] v2.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5aa4163b51..a68dcfddb4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "2.1.0", + "version": "2.1.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From ffde11ca912213148ef52a0e118995b2f960c150 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 Feb 2020 00:38:08 +0000 Subject: [PATCH 12/21] Use Persistent Storage where possible Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/MatrixChat.js | 3 +++ src/rageshake/submit-rageshake.js | 19 +++++++++++++++++++ src/utils/StorageManager.js | 10 ++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 3ccc4627e1..229c741310 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -65,6 +65,7 @@ import { ThemeWatcher } from "../../theme"; import { storeRoomAliasInCache } from '../../RoomAliasCache'; import { defer } from "../../utils/promise"; import ToastStore from "../../stores/ToastStore"; +import * as StorageManager from "../../utils/StorageManager"; /** constants for MatrixChat.state.view */ export const VIEWS = { @@ -1193,6 +1194,8 @@ export default createReactClass({ } else { this._showScreenAfterLogin(); } + + StorageManager.tryPersistStorage(); }, _showScreenAfterLogin: function() { diff --git a/src/rageshake/submit-rageshake.js b/src/rageshake/submit-rageshake.js index 091f64bf93..b17dc62168 100644 --- a/src/rageshake/submit-rageshake.js +++ b/src/rageshake/submit-rageshake.js @@ -106,6 +106,25 @@ export default async function sendBugReport(bugReportEndpoint, opts) { body.append('enabled_labs', enabledLabs.join(', ')); } + // add storage persistence/quota information + if (navigator.storage && navigator.storage.persisted) { + try { + body.append("storageManager_persisted", await navigator.storage.persisted()); + } catch (e) {} + } + if (navigator.storage && navigator.storage.estimate) { + try { + const estimate = await navigator.storage.estimate(); + body.append("storageManager_quota", estimate.quota); + body.append("storageManager_usage", estimate.usage); + if (estimate.usageDetails) { + Object.keys(estimate.usageDetails).forEach(k => { + body.append(`storageManager_usage_${k}`, estimate.usageDetails[k]); + }); + } + } catch (e) {} + } + if (opts.sendLogs) { progressCallback(_t("Collecting logs")); const logs = await rageshake.getLogsForReport(); diff --git a/src/utils/StorageManager.js b/src/utils/StorageManager.js index c5a9f7aeed..4ed118da8a 100644 --- a/src/utils/StorageManager.js +++ b/src/utils/StorageManager.js @@ -43,6 +43,16 @@ function track(action) { Analytics.trackEvent("StorageManager", action); } +export function tryPersistStorage() { + if (navigator.storage && navigator.storage.persist) { + navigator.storage.persist().then(persistent => { + console.log("StorageManager: Persistent?", persistent); + }); + } else { + console.log("StorageManager: Persistence unsupported"); + } +} + export async function checkConsistency() { log("Checking storage consistency"); log(`Local storage supported? ${!!localStorage}`); From 16bbea0b59aa6e76d1067d637075901b837003e7 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 Feb 2020 02:35:30 +0000 Subject: [PATCH 13/21] Fix various leaks due to method re-binding Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Notifier.js | 12 +++++++----- .../dialogs/eventindex/ManageEventIndexDialog.js | 8 ++++---- src/components/structures/FilePanel.js | 8 ++++---- src/components/views/settings/EventIndexPanel.js | 8 ++++---- .../views/settings/tabs/room/RolesRoomSettingsTab.js | 8 ++++---- src/integrations/IntegrationManagers.js | 8 ++++---- src/mjolnir/Mjolnir.js | 8 ++++---- 7 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/Notifier.js b/src/Notifier.js index b030f1b6f9..36a6f13bb6 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -153,10 +153,12 @@ const Notifier = { }, start: function() { - this.boundOnEvent = this.onEvent.bind(this); - this.boundOnSyncStateChange = this.onSyncStateChange.bind(this); - this.boundOnRoomReceipt = this.onRoomReceipt.bind(this); - this.boundOnEventDecrypted = this.onEventDecrypted.bind(this); + // do not re-bind in the case of repeated call + this.boundOnEvent = this.boundOnEvent || this.onEvent.bind(this); + this.boundOnSyncStateChange = this.boundOnSyncStateChange || this.onSyncStateChange.bind(this); + this.boundOnRoomReceipt = this.boundOnRoomReceipt || this.onRoomReceipt.bind(this); + this.boundOnEventDecrypted = this.boundOnEventDecrypted || this.onEventDecrypted.bind(this); + MatrixClientPeg.get().on('event', this.boundOnEvent); MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt); MatrixClientPeg.get().on('Event.decrypted', this.boundOnEventDecrypted); @@ -166,7 +168,7 @@ const Notifier = { }, stop: function() { - if (MatrixClientPeg.get() && this.boundOnRoomTimeline) { + if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener('Event', this.boundOnEvent); MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt); MatrixClientPeg.get().removeListener('Event.decrypted', this.boundOnEventDecrypted); diff --git a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js index 5ae90b694e..6aab777ee1 100644 --- a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js +++ b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js @@ -46,7 +46,7 @@ export default class ManageEventIndexDialog extends React.Component { }; } - async updateCurrentRoom(room) { + updateCurrentRoom = async (room) => { const eventIndex = EventIndexPeg.get(); const stats = await eventIndex.getStats(); let currentRoom = null; @@ -63,13 +63,13 @@ export default class ManageEventIndexDialog extends React.Component { roomCount: roomCount, currentRoom: currentRoom, }); - } + }; componentWillUnmount(): void { const eventIndex = EventIndexPeg.get(); if (eventIndex !== null) { - eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom.bind(this)); + eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom); } } @@ -83,7 +83,7 @@ export default class ManageEventIndexDialog extends React.Component { const eventIndex = EventIndexPeg.get(); if (eventIndex !== null) { - eventIndex.on("changedCheckpoint", this.updateCurrentRoom.bind(this)); + eventIndex.on("changedCheckpoint", this.updateCurrentRoom); const stats = await eventIndex.getStats(); const roomStats = eventIndex.crawlingRooms(); diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index 4c02f925fc..f8c03be864 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -95,8 +95,8 @@ const FilePanel = createReactClass({ // this could be made more general in the future or the filter logic // could be fixed. if (EventIndexPeg.get() !== null) { - client.on('Room.timeline', this.onRoomTimeline.bind(this)); - client.on('Event.decrypted', this.onEventDecrypted.bind(this)); + client.on('Room.timeline', this.onRoomTimeline); + client.on('Event.decrypted', this.onEventDecrypted); } }, @@ -107,8 +107,8 @@ const FilePanel = createReactClass({ if (!MatrixClientPeg.get().isRoomEncrypted(this.props.roomId)) return; if (EventIndexPeg.get() !== null) { - client.removeListener('Room.timeline', this.onRoomTimeline.bind(this)); - client.removeListener('Event.decrypted', this.onEventDecrypted.bind(this)); + client.removeListener('Room.timeline', this.onRoomTimeline); + client.removeListener('Event.decrypted', this.onEventDecrypted); } }, diff --git a/src/components/views/settings/EventIndexPanel.js b/src/components/views/settings/EventIndexPanel.js index 68faa53e53..ded62354cb 100644 --- a/src/components/views/settings/EventIndexPanel.js +++ b/src/components/views/settings/EventIndexPanel.js @@ -37,7 +37,7 @@ export default class EventIndexPanel extends React.Component { }; } - async updateCurrentRoom(room) { + updateCurrentRoom = async (room) => { const eventIndex = EventIndexPeg.get(); const stats = await eventIndex.getStats(); @@ -45,13 +45,13 @@ export default class EventIndexPanel extends React.Component { eventIndexSize: stats.size, roomCount: stats.roomCount, }); - } + }; componentWillUnmount(): void { const eventIndex = EventIndexPeg.get(); if (eventIndex !== null) { - eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom.bind(this)); + eventIndex.removeListener("changedCheckpoint", this.updateCurrentRoom); } } @@ -68,7 +68,7 @@ export default class EventIndexPanel extends React.Component { let roomCount = 0; if (eventIndex !== null) { - eventIndex.on("changedCheckpoint", this.updateCurrentRoom.bind(this)); + eventIndex.on("changedCheckpoint", this.updateCurrentRoom); const stats = await eventIndex.getStats(); eventIndexSize = stats.size; diff --git a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js index 42947d1fb2..a3a9cb78c5 100644 --- a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js @@ -107,20 +107,20 @@ export default class RolesRoomSettingsTab extends React.Component { }; componentDidMount(): void { - MatrixClientPeg.get().on("RoomState.members", this._onRoomMembership.bind(this)); + MatrixClientPeg.get().on("RoomState.members", this._onRoomMembership); } componentWillUnmount(): void { const client = MatrixClientPeg.get(); if (client) { - client.removeListener("RoomState.members", this._onRoomMembership.bind(this)); + client.removeListener("RoomState.members", this._onRoomMembership); } } - _onRoomMembership(event, state, member) { + _onRoomMembership = (event, state, member) => { if (state.roomId !== this.props.roomId) return; this.forceUpdate(); - } + }; _populateDefaultPlEvents(eventsSection, stateLevel, eventsLevel) { for (const desiredEvent of Object.keys(plEventsToShow)) { diff --git a/src/integrations/IntegrationManagers.js b/src/integrations/IntegrationManagers.js index c933e5c433..3ba1aab135 100644 --- a/src/integrations/IntegrationManagers.js +++ b/src/integrations/IntegrationManagers.js @@ -54,14 +54,14 @@ export class IntegrationManagers { startWatching(): void { this.stopWatching(); this._client = MatrixClientPeg.get(); - this._client.on("accountData", this._onAccountData.bind(this)); + this._client.on("accountData", this._onAccountData); this._compileManagers(); setInterval(() => this._setupHomeserverManagers(), HS_MANAGERS_REFRESH_INTERVAL); } stopWatching(): void { if (!this._client) return; - this._client.removeListener("accountData", this._onAccountData.bind(this)); + this._client.removeListener("accountData", this._onAccountData); if (this._wellknownRefreshTimerId !== null) clearInterval(this._wellknownRefreshTimerId); } @@ -136,11 +136,11 @@ export class IntegrationManagers { this._primaryManager = null; // reset primary } - _onAccountData(ev: MatrixEvent): void { + _onAccountData = (ev: MatrixEvent): void => { if (ev.getType() === 'm.widgets') { this._compileManagers(); } - } + }; hasManager(): boolean { return this._managers.length > 0; diff --git a/src/mjolnir/Mjolnir.js b/src/mjolnir/Mjolnir.js index 4970d8e8af..0c99306278 100644 --- a/src/mjolnir/Mjolnir.js +++ b/src/mjolnir/Mjolnir.js @@ -61,7 +61,7 @@ export class Mjolnir { setup() { if (!MatrixClientPeg.get()) return; this._updateLists(SettingsStore.getValue("mjolnirRooms")); - MatrixClientPeg.get().on("RoomState.events", this._onEvent.bind(this)); + MatrixClientPeg.get().on("RoomState.events", this._onEvent); } stop() { @@ -76,7 +76,7 @@ export class Mjolnir { } if (!MatrixClientPeg.get()) return; - MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent.bind(this)); + MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent); } async getOrCreatePersonalList(): Promise { @@ -130,13 +130,13 @@ export class Mjolnir { this._lists = this._lists.filter(b => b.roomId !== roomId); } - _onEvent(event) { + _onEvent = (event) => { if (!MatrixClientPeg.get()) return; if (!this._roomIds.includes(event.getRoomId())) return; if (!ALL_RULE_TYPES.includes(event.getType())) return; this._updateLists(this._roomIds); - } + }; _onListsChanged(settingName, roomId, atLevel, newValue) { // We know that ban lists are only recorded at one level so we don't need to re-eval them From fb28bbbaa68a5cf19a6f1f1e565018f1290925c5 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 20 Feb 2020 12:06:34 +0100 Subject: [PATCH 14/21] dont say we can scan when we dont --- src/MatrixClientPeg.js | 3 +-- src/components/views/dialogs/DeviceVerifyDialog.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 448c6d9e9b..98fcc85d60 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -32,7 +32,7 @@ import MatrixClientBackedSettingsHandler from "./settings/handlers/MatrixClientB import * as StorageManager from './utils/StorageManager'; import IdentityAuthClient from './IdentityAuthClient'; import { crossSigningCallbacks } from './CrossSigningManager'; -import {SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; +import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; interface MatrixClientCreds { homeserverUrl: string, @@ -221,7 +221,6 @@ class _MatrixClientPeg { verificationMethods: [ verificationMethods.SAS, SHOW_QR_CODE_METHOD, - SCAN_QR_CODE_METHOD, // XXX: We don't actually support scanning yet! verificationMethods.RECIPROCATE_QR_CODE, ], unstableClientRelationAggregation: true, diff --git a/src/components/views/dialogs/DeviceVerifyDialog.js b/src/components/views/dialogs/DeviceVerifyDialog.js index 835b7daf02..f7826b9c27 100644 --- a/src/components/views/dialogs/DeviceVerifyDialog.js +++ b/src/components/views/dialogs/DeviceVerifyDialog.js @@ -27,7 +27,7 @@ import {verificationMethods} from 'matrix-js-sdk/src/crypto'; import {ensureDMExists} from "../../../createRoom"; import dis from "../../../dispatcher"; import SettingsStore from '../../../settings/SettingsStore'; -import {SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; +import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; import VerificationQREmojiOptions from "../verification/VerificationQREmojiOptions"; const MODE_LEGACY = 'legacy'; @@ -135,7 +135,6 @@ export default class DeviceVerifyDialog extends React.Component { this._request = await client.requestVerification(this.props.userId, [ verificationMethods.SAS, SHOW_QR_CODE_METHOD, - SCAN_QR_CODE_METHOD, verificationMethods.RECIPROCATE_QR_CODE, ]); From 766f523c0020ee4e677095d4ac293bc054f2cc78 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 20 Feb 2020 11:41:53 +0000 Subject: [PATCH 15/21] Reset matrix-js-sdk back to develop branch --- package.json | 2 +- yarn.lock | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index a68dcfddb4..09393f052a 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "is-ip": "^2.0.0", "linkifyjs": "^2.1.6", "lodash": "^4.17.14", - "matrix-js-sdk": "5.0.1", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", "minimist": "^1.2.0", "pako": "^1.0.5", "png-chunks-extract": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 6924d7dcc0..17b0b97ac9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5760,10 +5760,9 @@ mathml-tag-names@^2.0.1: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" integrity sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw== -matrix-js-sdk@5.0.1: +"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": version "5.0.1" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-5.0.1.tgz#ffbbc89d2436f9eb378cd81bd3993f59ec8fb895" - integrity sha512-1Jl18tYDGQNo+PWC2mBdYd6WNrL20jhG9+FF1p2w6paS7IBC74QDCEKP3GLXr3SSmWdNuAYTFB94vZQRJ31HzA== + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/a998006842ae558f02819ca84fbaad43685cc10b" dependencies: "@babel/runtime" "^7.8.3" another-json "^0.2.0" From 31e82b8050b04795db02b7ecc42ca19bce88dd76 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 20 Feb 2020 12:05:07 +0000 Subject: [PATCH 16/21] Remove exec so release script continues We now want to do post-processing after the JS SDK release script, so we can't use `exec` here. --- release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.sh b/release.sh index c585708326..3c28084bb7 100755 --- a/release.sh +++ b/release.sh @@ -35,7 +35,7 @@ do fi done -exec ./node_modules/matrix-js-sdk/release.sh -z "$@" +./node_modules/matrix-js-sdk/release.sh -z "$@" release="${1#v}" prerelease=0 From 9e3b0fdf7cd9be0bc7c0e018185705900b6fd22c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 18 Feb 2020 11:46:42 +0100 Subject: [PATCH 17/21] EventIndexPanel: Fix the removal of the updateCurrentRoom listeners. The event listeners that update the current room and try to get the current stats from the event index don't seem to be unmounted because this != this confusion. Turning them into arrow methods of the react class fixes this. --- .../views/dialogs/eventindex/ManageEventIndexDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js index 6aab777ee1..fa00477c1a 100644 --- a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js +++ b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js @@ -46,7 +46,7 @@ export default class ManageEventIndexDialog extends React.Component { }; } - updateCurrentRoom = async (room) => { + updateCurrentRoom = async(room) => { const eventIndex = EventIndexPeg.get(); const stats = await eventIndex.getStats(); let currentRoom = null; From 1897d67818a1bf1990bf7ed235e015ac8bbffce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 18 Feb 2020 12:21:47 +0100 Subject: [PATCH 18/21] EventIndexPanel: Catch getStats failures. Getting the stats can fail when used with Seshat. Tantivy periodically garbage collects its files. Smaller files are merged and the old ones are removed. If garbage collection occurs while we try to get the stats, which go trough the files and figure out their sizes, we can end up trying to figure out the file size of a removed file. The getStats call will fail in this case but we can ignore the failure since we will likely get a nice result next time we try. --- .../eventindex/ManageEventIndexDialog.js | 21 +++++++++++++++---- .../views/settings/EventIndexPanel.js | 19 +++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js index fa00477c1a..aea37c1875 100644 --- a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js +++ b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js @@ -48,7 +48,16 @@ export default class ManageEventIndexDialog extends React.Component { updateCurrentRoom = async(room) => { const eventIndex = EventIndexPeg.get(); - const stats = await eventIndex.getStats(); + let stats; + + // This call may fail if sporadically, not a huge issue as we will try + // later again and probably succeed. + try { + stats = await eventIndex.getStats(); + } catch { + return; + } + let currentRoom = null; if (room) currentRoom = room.name; @@ -85,12 +94,16 @@ export default class ManageEventIndexDialog extends React.Component { if (eventIndex !== null) { eventIndex.on("changedCheckpoint", this.updateCurrentRoom); - const stats = await eventIndex.getStats(); + try { + const stats = await eventIndex.getStats(); + eventIndexSize = stats.size; + eventCount = stats.eventCount; + } catch { + } + const roomStats = eventIndex.crawlingRooms(); - eventIndexSize = stats.size; crawlingRoomsCount = roomStats.crawlingRooms.size; roomCount = roomStats.totalRooms.size; - eventCount = stats.eventCount; const room = eventIndex.currentRoom(); if (room) currentRoom = room.name; diff --git a/src/components/views/settings/EventIndexPanel.js b/src/components/views/settings/EventIndexPanel.js index ded62354cb..c74d99cec9 100644 --- a/src/components/views/settings/EventIndexPanel.js +++ b/src/components/views/settings/EventIndexPanel.js @@ -39,7 +39,15 @@ export default class EventIndexPanel extends React.Component { updateCurrentRoom = async (room) => { const eventIndex = EventIndexPeg.get(); - const stats = await eventIndex.getStats(); + let stats; + + // This call may fail if sporadically, not a huge issue as we will try + // later again and probably succeed. + try { + stats = await eventIndex.getStats(); + } catch { + return; + } this.setState({ eventIndexSize: stats.size, @@ -70,9 +78,12 @@ export default class EventIndexPanel extends React.Component { if (eventIndex !== null) { eventIndex.on("changedCheckpoint", this.updateCurrentRoom); - const stats = await eventIndex.getStats(); - eventIndexSize = stats.size; - roomCount = stats.roomCount; + try { + const stats = await eventIndex.getStats(); + eventIndexSize = stats.size; + roomCount = stats.roomCount; + } catch { + } } this.setState({ From a650c47d6bfc44b7dce9fc652c00190f1e587e5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 18 Feb 2020 13:15:28 +0100 Subject: [PATCH 19/21] ManageEventIndexDialog: Add a space before the function parenthesis. --- .../views/dialogs/eventindex/ManageEventIndexDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js index aea37c1875..318ef9ec8f 100644 --- a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js +++ b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js @@ -46,7 +46,7 @@ export default class ManageEventIndexDialog extends React.Component { }; } - updateCurrentRoom = async(room) => { + updateCurrentRoom = async (room) => { const eventIndex = EventIndexPeg.get(); let stats; From 81e61d6f9d946d0ee9cc6868831573b7c2094f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 19 Feb 2020 14:17:19 +0100 Subject: [PATCH 20/21] EventIndexPanel: Move the comments around for the getStats calls. --- .../views/dialogs/eventindex/ManageEventIndexDialog.js | 7 +++++-- src/components/views/settings/EventIndexPanel.js | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js index 318ef9ec8f..f3ea3beb1c 100644 --- a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js +++ b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js @@ -50,11 +50,11 @@ export default class ManageEventIndexDialog extends React.Component { const eventIndex = EventIndexPeg.get(); let stats; - // This call may fail if sporadically, not a huge issue as we will try - // later again and probably succeed. try { stats = await eventIndex.getStats(); } catch { + // This call may fail if sporadically, not a huge issue as we will + // try later again and probably succeed. return; } @@ -99,6 +99,9 @@ export default class ManageEventIndexDialog extends React.Component { eventIndexSize = stats.size; eventCount = stats.eventCount; } catch { + // This call may fail if sporadically, not a huge issue as we + // will try later again in the updateCurrentRoom call and + // probably succeed. } const roomStats = eventIndex.crawlingRooms(); diff --git a/src/components/views/settings/EventIndexPanel.js b/src/components/views/settings/EventIndexPanel.js index c74d99cec9..80d93c4562 100644 --- a/src/components/views/settings/EventIndexPanel.js +++ b/src/components/views/settings/EventIndexPanel.js @@ -41,11 +41,11 @@ export default class EventIndexPanel extends React.Component { const eventIndex = EventIndexPeg.get(); let stats; - // This call may fail if sporadically, not a huge issue as we will try - // later again and probably succeed. try { stats = await eventIndex.getStats(); } catch { + // This call may fail if sporadically, not a huge issue as we will + // try later again and probably succeed. return; } @@ -83,6 +83,9 @@ export default class EventIndexPanel extends React.Component { eventIndexSize = stats.size; roomCount = stats.roomCount; } catch { + // This call may fail if sporadically, not a huge issue as we + // will try later again in the updateCurrentRoom call and + // probably succeed. } } From fee9c7d21f533ff3f14f59ab3a7afb092e94b1b5 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 20 Feb 2020 17:43:33 +0100 Subject: [PATCH 21/21] accept canonical alias for pills --- src/components/views/elements/Pill.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index 59c0bde177..cd7277cdeb 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -128,7 +128,8 @@ const Pill = createReactClass({ case Pill.TYPE_ROOM_MENTION: { const localRoom = resourceId[0] === '#' ? MatrixClientPeg.get().getRooms().find((r) => { - return r.getAliases().includes(resourceId); + return r.getCanonicalAlias() === resourceId || + r.getAliases().includes(resourceId); }) : MatrixClientPeg.get().getRoom(resourceId); room = localRoom; if (!localRoom) {