From 88d729720d9cef796722f9576475afad7a01e517 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Tue, 10 May 2022 09:59:02 +0200 Subject: [PATCH 1/5] Support avatar_url in the scalar client API Signed-off-by: Oliver Sand --- src/ScalarMessaging.ts | 44 +++++++++++++++++++++++++++++++++------- src/utils/WidgetUtils.ts | 2 ++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/ScalarMessaging.ts b/src/ScalarMessaging.ts index a380c760b56..2076099e98b 100644 --- a/src/ScalarMessaging.ts +++ b/src/ScalarMessaging.ts @@ -148,6 +148,8 @@ Request: can configure/lay out the widget in different ways. All widgets must have a type. - `name` (String) is an optional human-readable string about the widget. - `data` (Object) is some optional data about the widget, and can contain arbitrary key/value pairs. + - `avatar_url` (String|Blob) is some optional avatar of the widget. Can contain either be an existing mxc: + URL or the mxc: URL of a Blob that is automatically uploaded to the room. Response: { success: true @@ -313,12 +315,13 @@ function inviteUser(event: MessageEvent, roomId: string, userId: string): v }); } -function setWidget(event: MessageEvent, roomId: string): void { +async function setWidget(event: MessageEvent, roomId: string): void { const widgetId = event.data.widget_id; let widgetType = event.data.type; const widgetUrl = event.data.url; const widgetName = event.data.name; // optional const widgetData = event.data.data; // optional + let widgetAvatarUrl = event.data.avatar_url; // optional const userWidget = event.data.userWidget; // both adding/removing widgets need these checks @@ -337,6 +340,15 @@ function setWidget(event: MessageEvent, roomId: string): void { sendError(event, _t("Unable to create widget."), new Error("Optional field 'data' must be an Object.")); return; } + if (widgetAvatarUrl !== undefined && typeof widgetAvatarUrl !== 'string' + && !(widgetAvatarUrl instanceof Blob)) { + sendError( + event, + _t("Unable to create widget."), + new Error("Optional field 'avatar_url' must be a string or Blob."), + ); + return; + } if (typeof widgetType !== 'string') { sendError(event, _t("Unable to create widget."), new Error("Field 'type' must be a string.")); return; @@ -347,30 +359,48 @@ function setWidget(event: MessageEvent, roomId: string): void { } } + // A blob was transmitted as a widget avatar url, so we have to upload it to + // the room first + if (widgetAvatarUrl && widgetAvatarUrl instanceof Blob) { + try { + const client = MatrixClientPeg.get(); + widgetAvatarUrl = await client.uploadContent(widgetAvatarUrl, { + type: widgetAvatarUrl.type, + }); + } catch (err) { + sendError(event, _t('Unable to create widget.'), err); + } + } + // convert the widget type to a known widget type widgetType = WidgetType.fromString(widgetType); if (userWidget) { - WidgetUtils.setUserWidget(widgetId, widgetType, widgetUrl, widgetName, widgetData).then(() => { + try { + await WidgetUtils.setUserWidget(widgetId, widgetType, widgetUrl, widgetName, widgetData); + sendResponse(event, { success: true, }); dis.dispatch({ action: "user_widget_updated" }); - }).catch((e) => { + } catch (e) { sendError(event, _t('Unable to create widget.'), e); - }); + } } else { // Room widget if (!roomId) { sendError(event, _t('Missing roomId.'), null); } - WidgetUtils.setRoomWidget(roomId, widgetId, widgetType, widgetUrl, widgetName, widgetData).then(() => { + try { + await WidgetUtils.setRoomWidget(roomId, widgetId, widgetType, widgetUrl, widgetName, widgetData, + widgetAvatarUrl); + sendResponse(event, { success: true, }); - }, (err) => { + } catch (err) { sendError(event, _t('Failed to send request.'), err); - }); + } } } diff --git a/src/utils/WidgetUtils.ts b/src/utils/WidgetUtils.ts index b2f33b22253..8eebed3871c 100644 --- a/src/utils/WidgetUtils.ts +++ b/src/utils/WidgetUtils.ts @@ -286,6 +286,7 @@ export default class WidgetUtils { widgetUrl?: string, widgetName?: string, widgetData?: object, + widgetAvatarUrl?: string, ) { let content; @@ -299,6 +300,7 @@ export default class WidgetUtils { url: widgetUrl, name: widgetName, data: widgetData, + avatar_url: widgetAvatarUrl, }; } else { content = {}; From b94eaa6c90b2512c0fe17a1f33a0411d66c2ae4e Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Tue, 10 May 2022 10:48:48 +0200 Subject: [PATCH 2/5] Fix return type --- src/ScalarMessaging.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScalarMessaging.ts b/src/ScalarMessaging.ts index 2076099e98b..2dda1725e39 100644 --- a/src/ScalarMessaging.ts +++ b/src/ScalarMessaging.ts @@ -315,7 +315,7 @@ function inviteUser(event: MessageEvent, roomId: string, userId: string): v }); } -async function setWidget(event: MessageEvent, roomId: string): void { +async function setWidget(event: MessageEvent, roomId: string): Promise { const widgetId = event.data.widget_id; let widgetType = event.data.type; const widgetUrl = event.data.url; From 61f7aaa900a2fae3dd3234c380c2cf903b035dd9 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Wed, 11 May 2022 10:46:05 +0200 Subject: [PATCH 3/5] Remove automatic upload --- src/ScalarMessaging.ts | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/ScalarMessaging.ts b/src/ScalarMessaging.ts index 2dda1725e39..360731846de 100644 --- a/src/ScalarMessaging.ts +++ b/src/ScalarMessaging.ts @@ -148,8 +148,7 @@ Request: can configure/lay out the widget in different ways. All widgets must have a type. - `name` (String) is an optional human-readable string about the widget. - `data` (Object) is some optional data about the widget, and can contain arbitrary key/value pairs. - - `avatar_url` (String|Blob) is some optional avatar of the widget. Can contain either be an existing mxc: - URL or the mxc: URL of a Blob that is automatically uploaded to the room. + - `avatar_url` (String) is some optional mxc: URI pointing to the avatar of the widget. Response: { success: true @@ -315,7 +314,7 @@ function inviteUser(event: MessageEvent, roomId: string, userId: string): v }); } -async function setWidget(event: MessageEvent, roomId: string): Promise { +function setWidget(event: MessageEvent, roomId: string): Promise { const widgetId = event.data.widget_id; let widgetType = event.data.type; const widgetUrl = event.data.url; @@ -340,12 +339,11 @@ async function setWidget(event: MessageEvent, roomId: string): Promise, roomId: string): Promise { sendResponse(event, { success: true, }); dis.dispatch({ action: "user_widget_updated" }); - } catch (e) { + }).catch((e) => { sendError(event, _t('Unable to create widget.'), e); - } + }); } else { // Room widget if (!roomId) { sendError(event, _t('Missing roomId.'), null); } - try { - await WidgetUtils.setRoomWidget(roomId, widgetId, widgetType, widgetUrl, widgetName, widgetData, - widgetAvatarUrl); - + WidgetUtils.setRoomWidget(roomId, widgetId, widgetType, widgetUrl, widgetName, widgetData, widgetAvatarUrl) + .then(() => { sendResponse(event, { success: true, }); - } catch (err) { + }, (err) => { sendError(event, _t('Failed to send request.'), err); - } + }); } } From f2c3f667c997d96cb4eddd6590c600550981299d Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Wed, 11 May 2022 10:49:48 +0200 Subject: [PATCH 4/5] Remove return type --- src/ScalarMessaging.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScalarMessaging.ts b/src/ScalarMessaging.ts index 360731846de..5443eefc37a 100644 --- a/src/ScalarMessaging.ts +++ b/src/ScalarMessaging.ts @@ -314,7 +314,7 @@ function inviteUser(event: MessageEvent, roomId: string, userId: string): v }); } -function setWidget(event: MessageEvent, roomId: string): Promise { +function setWidget(event: MessageEvent, roomId: string): void { const widgetId = event.data.widget_id; let widgetType = event.data.type; const widgetUrl = event.data.url; From 9a50fb720fe443eaef917c1db52fbd469a1a2103 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Wed, 11 May 2022 10:58:15 +0200 Subject: [PATCH 5/5] Fix indention --- src/ScalarMessaging.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ScalarMessaging.ts b/src/ScalarMessaging.ts index 5443eefc37a..337b9c8167b 100644 --- a/src/ScalarMessaging.ts +++ b/src/ScalarMessaging.ts @@ -320,7 +320,7 @@ function setWidget(event: MessageEvent, roomId: string): void { const widgetUrl = event.data.url; const widgetName = event.data.name; // optional const widgetData = event.data.data; // optional - let widgetAvatarUrl = event.data.avatar_url; // optional + const widgetAvatarUrl = event.data.avatar_url; // optional const userWidget = event.data.userWidget; // both adding/removing widgets need these checks @@ -375,13 +375,13 @@ function setWidget(event: MessageEvent, roomId: string): void { sendError(event, _t('Missing roomId.'), null); } WidgetUtils.setRoomWidget(roomId, widgetId, widgetType, widgetUrl, widgetName, widgetData, widgetAvatarUrl) - .then(() => { - sendResponse(event, { - success: true, + .then(() => { + sendResponse(event, { + success: true, + }); + }, (err) => { + sendError(event, _t('Failed to send request.'), err); }); - }, (err) => { - sendError(event, _t('Failed to send request.'), err); - }); } }