From 2956c049d62ab8f4416dd9de090f19db5787425c Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 11:41:16 +0100 Subject: [PATCH 01/11] Wait for echo from server when adding user widgets As hopefully all explained in comments. Fixes https://github.com/vector-im/riot-web/issues/6727 --- src/ScalarMessaging.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index a163bf7bbd..906dc6fb0f 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -286,6 +286,30 @@ function inviteUser(event, roomId, userId) { }); } +/** + * Returns a promise that resolves when a widget with the given + * ID has been added as a user widget (ie. the accountData event + * arrives) or rejects after a timeout + */ +function waitForUserWidget(widgetId) { + return new Promise((resolve, reject) => { + let timerId; + function onAccountData(ev) { + if (ev.getContent()[widgetId] !== undefined) { + MatrixClientPeg.get().removeListener('accountData', onAccountData); + clearTimeout(timerId); + resolve(); + } + } + timerId = setTimeout(() => { + console.log("Timed out waiting for widget ID " + widgetId + " to appear"); + MatrixClientPeg.get().removeListener('accountData', onAccountData); + reject(); + }, 10000); + MatrixClientPeg.get().on('accountData', onAccountData); + }); +} + function setWidget(event, roomId) { const widgetId = event.data.widget_id; const widgetType = event.data.type; @@ -355,7 +379,15 @@ function setWidget(event, roomId) { }; } + // This starts listening for when the echo comes back from the server + // since the widget won't appear added until this happens. If we don't + // wait for this, the action will complete but if the user is fast enough, + // the widget still won't actually be there. + // start listening now otherwise we could race + const widgetAddPromise = waitForUserWidget(widgetId); client.setAccountData('m.widgets', userWidgets).then(() => { + return widgetAddPromise; + }).then(() => { sendResponse(event, { success: true, }); @@ -373,6 +405,7 @@ function setWidget(event, roomId) { // TODO - Room widgets need to be moved to 'm.widget' state events // https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit?usp=sharing client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).done(() => { + // XXX: We should probably wait for the echo of the state event to come back from the server, sendResponse(event, { success: true, }); From 142ce4c2567ae1db25d2105c050ecb4b2eec5863 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 11:50:24 +0100 Subject: [PATCH 02/11] better comment --- src/ScalarMessaging.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 906dc6fb0f..5b81e7e7bf 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -406,6 +406,7 @@ function setWidget(event, roomId) { // https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit?usp=sharing client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).done(() => { // XXX: We should probably wait for the echo of the state event to come back from the server, + // as we do with user widgets. sendResponse(event, { success: true, }); From f4d69e26e980e5aa58bfe3baa213d3b32d782171 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 12:06:23 +0100 Subject: [PATCH 03/11] PR feedback --- src/ScalarMessaging.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 5b81e7e7bf..a229ecf693 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -293,18 +293,22 @@ function inviteUser(event, roomId, userId) { */ function waitForUserWidget(widgetId) { return new Promise((resolve, reject) => { + if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { + resolve(); + return; + } + let timerId; function onAccountData(ev) { - if (ev.getContent()[widgetId] !== undefined) { + if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); resolve(); } } timerId = setTimeout(() => { - console.log("Timed out waiting for widget ID " + widgetId + " to appear"); MatrixClientPeg.get().removeListener('accountData', onAccountData); - reject(); + reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear")); }, 10000); MatrixClientPeg.get().on('accountData', onAccountData); }); @@ -383,10 +387,8 @@ function setWidget(event, roomId) { // since the widget won't appear added until this happens. If we don't // wait for this, the action will complete but if the user is fast enough, // the widget still won't actually be there. - // start listening now otherwise we could race - const widgetAddPromise = waitForUserWidget(widgetId); client.setAccountData('m.widgets', userWidgets).then(() => { - return widgetAddPromise; + return waitForUserWidget(widgetId); }).then(() => { sendResponse(event, { success: true, From d0ec467c34d80b9954af28559a7f9e75f4694d73 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 14:13:56 +0100 Subject: [PATCH 04/11] Oops, actually get account data event. Also ignore any account data events that aren;t widgets. --- src/ScalarMessaging.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index a229ecf693..796252fc1b 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -293,13 +293,20 @@ function inviteUser(event, roomId, userId) { */ function waitForUserWidget(widgetId) { return new Promise((resolve, reject) => { - if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { + const currentAccountDataEvent = MatrixClientPeg.get().getAccountData('m.widgets'); + if ( + currentAccountDataEvent && + currentAccountDataEvent.getContent() && + currentAccountDataEvent.getContent()[widgetId] !== undefined + ) { resolve(); return; } let timerId; function onAccountData(ev) { + if (ev.getType() != 'm.widgets') return; + if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); From e9336eab63daa5ad04cac28b50a3ff52bb7ab5cb Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 14:18:02 +0100 Subject: [PATCH 05/11] lint --- src/ScalarMessaging.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 796252fc1b..5940565517 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -290,6 +290,9 @@ function inviteUser(event, roomId, userId) { * Returns a promise that resolves when a widget with the given * ID has been added as a user widget (ie. the accountData event * arrives) or rejects after a timeout + * + * @param {string} widgetId The ID of the widget to wait for + * @returns {Promise} that resolves when the widget is available */ function waitForUserWidget(widgetId) { return new Promise((resolve, reject) => { @@ -303,7 +306,6 @@ function waitForUserWidget(widgetId) { return; } - let timerId; function onAccountData(ev) { if (ev.getType() != 'm.widgets') return; @@ -313,7 +315,7 @@ function waitForUserWidget(widgetId) { resolve(); } } - timerId = setTimeout(() => { + const timerId = setTimeout(() => { MatrixClientPeg.get().removeListener('accountData', onAccountData); reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear")); }, 10000); From 7bfe84f8beec1aecd3a6d465f7a0dfc378e3e7a5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 14:53:49 +0100 Subject: [PATCH 06/11] Catch errors adding widget --- src/ScalarMessaging.js | 2 ++ src/i18n/strings/en_EN.json | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 5940565517..bc5e6b7fe1 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -404,6 +404,8 @@ function setWidget(event, roomId) { }); dis.dispatch({ action: "user_widget_updated" }); + }).catch((e) => { + sendError(event, _t('Error adding widget')); }); } else { // Room widget if (!roomId) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9b932ef2b6..e78a06cccd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,6 +103,7 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", + "Error adding widget": "Error adding widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", @@ -190,7 +191,6 @@ "Message Replies": "Message Replies", "Message Pinning": "Message Pinning", "Tag Panel": "Tag Panel", - "Sticker Messages": "Sticker Messages", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", "Use compact timeline layout": "Use compact timeline layout", "Hide removed messages": "Hide removed messages", @@ -566,8 +566,6 @@ "Download %(text)s": "Download %(text)s", "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", - "This image cannot be displayed.": "This image cannot be displayed.", - "Image '%(Body)s' cannot be displayed.": "Image '%(Body)s' cannot be displayed.", "Error decrypting video": "Error decrypting video", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", @@ -815,8 +813,8 @@ "Encryption key request": "Encryption key request", "Sign out": "Sign out", "Log out and remove encryption keys?": "Log out and remove encryption keys?", - "Send Logs": "Send Logs", "Clear Storage and Sign Out": "Clear Storage and Sign Out", + "Send Logs": "Send Logs", "Refresh": "Refresh", "Unable to restore session": "Unable to restore session", "We encountered an error trying to restore your previous session.": "We encountered an error trying to restore your previous session.", From 5b781043a5b61ec2307a89d212d79faa3750a46c Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 15:02:24 +0100 Subject: [PATCH 07/11] just use the one if statement --- src/ScalarMessaging.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index bc5e6b7fe1..ba60af29d1 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -307,9 +307,7 @@ function waitForUserWidget(widgetId) { } function onAccountData(ev) { - if (ev.getType() != 'm.widgets') return; - - if (ev.getContent() && ev.getContent()[widgetId] !== undefined) { + if (ev.getType() === 'm.widgets' && ev.getContent() && ev.getContent()[widgetId] !== undefined) { MatrixClientPeg.get().removeListener('accountData', onAccountData); clearTimeout(timerId); resolve(); From 464e093f40b2fdeb2e2c3f374295a20de9d31071 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 15:14:33 +0100 Subject: [PATCH 08/11] log exception --- src/ScalarMessaging.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index ba60af29d1..961f7a13d8 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -403,6 +403,7 @@ function setWidget(event, roomId) { dis.dispatch({ action: "user_widget_updated" }); }).catch((e) => { + console.log("Error adding widget", e); sendError(event, _t('Error adding widget')); }); } else { // Room widget From 9d5ba25131648ce0121fb15471241eecbbee9a30 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 May 2018 15:19:28 +0100 Subject: [PATCH 09/11] oh, sendError does support sending the error --- src/ScalarMessaging.js | 3 +-- src/i18n/strings/en_EN.json | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 961f7a13d8..0c10642cd7 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -403,8 +403,7 @@ function setWidget(event, roomId) { dis.dispatch({ action: "user_widget_updated" }); }).catch((e) => { - console.log("Error adding widget", e); - sendError(event, _t('Error adding widget')); + sendError(event, _t('Unable to create widget.'), e); }); } else { // Room widget if (!roomId) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e78a06cccd..957deb35c5 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -103,7 +103,6 @@ "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", - "Error adding widget": "Error adding widget", "Missing roomId.": "Missing roomId.", "Failed to send request.": "Failed to send request.", "This room is not recognised.": "This room is not recognised.", From b64e10a0951031a144b1521bd3c63e9a3b8faae7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:54:14 +0100 Subject: [PATCH 10/11] Prepare changelog for v0.12.4-rc.5 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54664ac124..36e256f10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.12.4-rc.5](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.5) (2018-05-15) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.4...v0.12.4-rc.5) + + * Wait for echo from server when adding user widgets + [\#1905](https://github.com/matrix-org/matrix-react-sdk/pull/1905) + Changes in [0.12.4-rc.4](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.12.4-rc.4) (2018-05-14) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.12.4-rc.3...v0.12.4-rc.4) From db092c81d340176d08504012a7cb97ed19874beb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 15 May 2018 15:54:15 +0100 Subject: [PATCH 11/11] v0.12.4-rc.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77ba18ba04..96c7e94ad1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.12.4-rc.4", + "version": "0.12.4-rc.5", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": {