From 69745bbd40069439b6765aff0e2219ac6566e455 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 4 Sep 2020 21:55:50 -0600 Subject: [PATCH 1/9] Switch to using the Widget API SDK for Jitsi widgets --- src/vector/jitsi/index.ts | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index 081246c0a..3ebbc7d3b 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -18,7 +18,12 @@ limitations under the License. require("./index.scss"); import * as qs from 'querystring'; -import { Capability, WidgetApi } from "matrix-react-sdk/src/widgets/WidgetApi"; +import { + IWidgetApiRequest, + IWidgetApiRequestEmptyData, + VideoConferenceCapabilities, + WidgetApi +} from "matrix-widget-api"; // Dev note: we use raw JS without many dependencies to reduce bundle size. // We do not need all of React to render a Jitsi conference. @@ -56,11 +61,19 @@ let widgetApi: WidgetApi; const widgetId = qsParam('widgetId', true); // Set this up as early as possible because Element will be hitting it almost immediately. + let readyPromise: Promise<[void, void]>; if (parentUrl && widgetId) { - widgetApi = new WidgetApi(qsParam('parentUrl'), qsParam('widgetId'), [ - Capability.AlwaysOnScreen, + const parentOrigin = new URL(qsParam('parentUrl')).origin; + widgetApi = new WidgetApi(qsParam("widgetId"), parentOrigin); + widgetApi.requestCapabilities(VideoConferenceCapabilities); + readyPromise = Promise.all([ + widgetApi.waitFor>("im.vector.ready") + .then(ev => widgetApi.transport.reply(ev.detail, {})), + widgetApi.waitFor("ready"), ]); - widgetApi.expectingExplicitReady = true; + widgetApi.start(); + } else { + throw new Error("No parent URL or no widget ID"); } // Populate the Jitsi params now @@ -70,10 +83,8 @@ let widgetApi: WidgetApi; avatarUrl = qsParam('avatarUrl', true); // http not mxc userId = qsParam('userId'); - if (widgetApi) { - await widgetApi.waitReady(); - await widgetApi.setAlwaysOnScreen(false); // start off as detachable from the screen - } + await readyPromise; + await widgetApi.setAlwaysOnScreen(false); // start off as detachable from the screen // TODO: register widgetApi listeners for PTT controls (https://github.com/vector-im/riot-web/issues/12795) From 2fa8b0f8b2bfe616f6348ef88166a5e3c08e169a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 4 Sep 2020 22:02:18 -0600 Subject: [PATCH 2/9] Make the types happy --- src/vector/jitsi/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index 3ebbc7d3b..f31bf46ba 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -69,7 +69,7 @@ let widgetApi: WidgetApi; readyPromise = Promise.all([ widgetApi.waitFor>("im.vector.ready") .then(ev => widgetApi.transport.reply(ev.detail, {})), - widgetApi.waitFor("ready"), + widgetApi.waitFor("ready").then(), ]); widgetApi.start(); } else { From c7617c2538c2273a82da7c02228ac7f72522b7e1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 22 Sep 2020 09:01:55 -0600 Subject: [PATCH 3/9] Fix bad merge --- src/vector/jitsi/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index 5d391c19e..ad2eb5825 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -18,7 +18,6 @@ limitations under the License. require("./index.scss"); import * as qs from 'querystring'; -import {Capability, WidgetApi} from 'matrix-react-sdk/src/widgets/WidgetApi'; import {KJUR} from 'jsrsasign'; import { IWidgetApiRequest, @@ -92,13 +91,14 @@ let widgetApi: WidgetApi; roomId = qsParam('roomId', true); if (widgetApi) { - await widgetApi.waitReady(); + await readyPromise; await widgetApi.setAlwaysOnScreen(false); // start off as detachable from the screen // See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) { // Request credentials, give callback to continue when received - widgetApi.requestOpenIDCredentials(credentialsResponseCallback); + // TODO: Implement in widget API + //widgetApi.requestOpenIDCredentials(credentialsResponseCallback); } else { enableJoinButton(); } From 82749c3de39f18e905bb947c686fd103398b1ef5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 24 Sep 2020 13:25:59 -0600 Subject: [PATCH 4/9] Fix Jitsi for new widget-api --- src/vector/jitsi/index.ts | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index ad2eb5825..b60715344 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -20,6 +20,7 @@ require("./index.scss"); import * as qs from 'querystring'; import {KJUR} from 'jsrsasign'; import { + IOpenIDCredentials, IWidgetApiRequest, IWidgetApiRequestEmptyData, VideoConferenceCapabilities, @@ -43,6 +44,7 @@ let avatarUrl: string; let userId: string; let jitsiAuth: string; let roomId: string; +let openIdToken: IOpenIDCredentials; let widgetApi: WidgetApi; @@ -72,9 +74,16 @@ let widgetApi: WidgetApi; widgetApi = new WidgetApi(qsParam("widgetId"), parentOrigin); widgetApi.requestCapabilities(VideoConferenceCapabilities); readyPromise = Promise.all([ - widgetApi.waitFor>("im.vector.ready") - .then(ev => widgetApi.transport.reply(ev.detail, {})), - widgetApi.waitFor("ready").then(), + new Promise(resolve => { + widgetApi.once>("action:im.vector.ready", ev => { + ev.preventDefault(); + widgetApi.transport.reply(ev.detail, {}); + resolve(); + }); + }), + new Promise(resolve => { + widgetApi.once("ready", () => resolve()); + }), ]); widgetApi.start(); } else { @@ -97,8 +106,9 @@ let widgetApi: WidgetApi; // See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) { // Request credentials, give callback to continue when received - // TODO: Implement in widget API - //widgetApi.requestOpenIDCredentials(credentialsResponseCallback); + openIdToken = await widgetApi.requestOpenIDConnectToken(); + console.log("Got OpenID Connect token"); + enableJoinButton(); } else { enableJoinButton(); } @@ -112,19 +122,6 @@ let widgetApi: WidgetApi; } })(); -/** - * Enable or show error depending on what the credentials response is. - */ -function credentialsResponseCallback() { - if (widgetApi.openIDCredentials) { - console.info('Successfully got OpenID credentials.'); - enableJoinButton(); - } else { - console.warn('OpenID credentials request was blocked by user.'); - document.getElementById("widgetActionContainer").innerText = "Failed to load Jitsi widget"; - } -} - function enableJoinButton() { document.getElementById("joinButton").onclick = () => joinConference(); } @@ -154,7 +151,7 @@ function createJWTToken() { room: "*", context: { matrix: { - token: widgetApi.openIDCredentials.accessToken, + token: openIdToken.access_token, room_id: roomId, }, user: { @@ -177,7 +174,7 @@ function createJWTToken() { function joinConference() { // event handler bound in HTML let jwt; if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) { - if (!widgetApi.openIDCredentials || !widgetApi.openIDCredentials.accessToken) { + if (!openIdToken?.access_token) { // We've failing to get a token, don't try to init conference console.warn('Expected to have an OpenID credential, cannot initialize widget.'); document.getElementById("widgetActionContainer").innerText = "Failed to load Jitsi widget"; From c56368cdbbd28164b8f2a206f367382bc0abf8d0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Sep 2020 13:20:16 -0600 Subject: [PATCH 5/9] Fix hangup button handler --- src/vector/jitsi/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index cf7b02373..acfad9afa 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -116,8 +116,9 @@ let meetApi: any; // JitsiMeetExternalAPI // TODO: register widgetApi listeners for PTT controls (https://github.com/vector-im/riot-web/issues/12795) - widgetApi.on('hangup', () => { + widgetApi.addEventListener('hangup', (ev: CustomEvent) => { if (meetApi) meetApi.executeCommand('hangup'); + widgetApi.transport.reply(ev.detail, {}); // ack }); } else { enableJoinButton(); From 7b93c56bd0861f28b9b181710ba4baa0f9d76372 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 30 Sep 2020 20:09:42 -0600 Subject: [PATCH 6/9] Fix custom hangup button --- src/vector/jitsi/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index acfad9afa..83691f7b5 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -22,10 +22,10 @@ import {KJUR} from 'jsrsasign'; import { IOpenIDCredentials, IWidgetApiRequest, - IWidgetApiRequestEmptyData, VideoConferenceCapabilities, - WidgetApi + WidgetApi, } from "matrix-widget-api"; +import { ElementWidgetActions } from "matrix-react-sdk/src/stores/widgets/ElementWidgetActions"; const JITSI_OPENIDTOKEN_JWT_AUTH = 'openidtoken-jwt'; @@ -76,7 +76,7 @@ let meetApi: any; // JitsiMeetExternalAPI widgetApi.requestCapabilities(VideoConferenceCapabilities); readyPromise = Promise.all([ new Promise(resolve => { - widgetApi.once>("action:im.vector.ready", ev => { + widgetApi.once>(`action:${ElementWidgetActions.ClientReady}`, ev => { ev.preventDefault(); widgetApi.transport.reply(ev.detail, {}); resolve(); @@ -116,7 +116,7 @@ let meetApi: any; // JitsiMeetExternalAPI // TODO: register widgetApi listeners for PTT controls (https://github.com/vector-im/riot-web/issues/12795) - widgetApi.addEventListener('hangup', (ev: CustomEvent) => { + widgetApi.addEventListener(`action:${ElementWidgetActions.HangupCall}`, (ev: CustomEvent) => { if (meetApi) meetApi.executeCommand('hangup'); widgetApi.transport.reply(ev.detail, {}); // ack }); From 408766366c740d67968521b55f37f80e214c9786 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 30 Sep 2020 20:43:21 -0600 Subject: [PATCH 7/9] Use the beta release of the widget-api --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index 59d998d90..1754ba41d 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "jsrsasign": "^9.1.5", "matrix-js-sdk": "8.4.1", "matrix-react-sdk": "3.5.0", + "matrix-widget-api": "^0.1.0-beta.2", "olm": "https://packages.matrix.org/npm/olm/olm-3.1.4.tgz", "prop-types": "^15.7.2", "react": "^16.9.0", diff --git a/yarn.lock b/yarn.lock index 059621479..e8c121366 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8373,6 +8373,11 @@ matrix-react-test-utils@^0.2.2: resolved "https://registry.yarnpkg.com/matrix-react-test-utils/-/matrix-react-test-utils-0.2.2.tgz#c87144d3b910c7edc544a6699d13c7c2bf02f853" integrity sha512-49+7gfV6smvBIVbeloql+37IeWMTD+fiywalwCqk8Dnz53zAFjKSltB3rmWHso1uecLtQEcPtCijfhzcLXAxTQ== +matrix-widget-api@^0.1.0-beta.2: + version "0.1.0-beta.2" + resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-0.1.0-beta.2.tgz#367da1ccd26b711f73fc5b6e02edf55ac2ea2692" + integrity sha512-q5g5RZN+RRjM4HmcJ+LYoQAYrB1wzyERmoQ+LvKbTV/+9Ov36Kp0QEP8CleSXEd5WLp6bkRlt60axDaY6pWGmg== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" From cdf9547220dec41ff855ff153eaa2939bf95cab1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 30 Sep 2020 20:51:31 -0600 Subject: [PATCH 8/9] Appease the linter --- src/vector/jitsi/index.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index 83691f7b5..69f858a0d 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -116,10 +116,12 @@ let meetApi: any; // JitsiMeetExternalAPI // TODO: register widgetApi listeners for PTT controls (https://github.com/vector-im/riot-web/issues/12795) - widgetApi.addEventListener(`action:${ElementWidgetActions.HangupCall}`, (ev: CustomEvent) => { - if (meetApi) meetApi.executeCommand('hangup'); - widgetApi.transport.reply(ev.detail, {}); // ack - }); + widgetApi.addEventListener(`action:${ElementWidgetActions.HangupCall}`, + (ev: CustomEvent) => { + if (meetApi) meetApi.executeCommand('hangup'); + widgetApi.transport.reply(ev.detail, {}); // ack + }, + ); } else { enableJoinButton(); } @@ -181,7 +183,7 @@ function createJWTToken() { function joinConference() { // event handler bound in HTML let jwt; if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) { - if (!openIdToken?.access_token) { + if (!openIdToken?.access_token) { // eslint-disable-line camelcase // We've failing to get a token, don't try to init conference console.warn('Expected to have an OpenID credential, cannot initialize widget.'); document.getElementById("widgetActionContainer").innerText = "Failed to load Jitsi widget"; From 9cb823b2103ba7de1be3dc637bb19c86dc0dbd1b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 1 Oct 2020 09:59:13 -0600 Subject: [PATCH 9/9] Fix join button --- src/vector/jitsi/index.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vector/jitsi/index.ts b/src/vector/jitsi/index.ts index 69f858a0d..e1b6a58bc 100644 --- a/src/vector/jitsi/index.ts +++ b/src/vector/jitsi/index.ts @@ -109,9 +109,6 @@ let meetApi: any; // JitsiMeetExternalAPI // Request credentials, give callback to continue when received openIdToken = await widgetApi.requestOpenIDConnectToken(); console.log("Got OpenID Connect token"); - enableJoinButton(); - } else { - enableJoinButton(); } // TODO: register widgetApi listeners for PTT controls (https://github.com/vector-im/riot-web/issues/12795) @@ -122,9 +119,9 @@ let meetApi: any; // JitsiMeetExternalAPI widgetApi.transport.reply(ev.detail, {}); // ack }, ); - } else { - enableJoinButton(); } + + enableJoinButton(); // always enable the button } catch (e) { console.error("Error setting up Jitsi widget", e); document.getElementById("widgetActionContainer").innerText = "Failed to load Jitsi widget";