Voice rooms prototype (#21476)
* Document voice rooms labs flag Signed-off-by: Robin Townsend <robin@robin.town> * Add join and mute handlers to Jitsi wrapper Signed-off-by: Robin Townsend <robin@robin.town> * Document voice rooms labs flag Signed-off-by: Robin Townsend <robin@robin.town> * Mark voice rooms as in development Signed-off-by: Robin Townsend <robin@robin.town> * ack at the end of widget event handlers Signed-off-by: Robin Townsend <robin@robin.town> * Move acks back before suspend points Signed-off-by: Robin Townsend <robin@robin.town>
This commit is contained in:
parent
269ec4609a
commit
6103f4a9d3
2 changed files with 71 additions and 7 deletions
|
@ -196,3 +196,7 @@ Threading allows users to branch out a new conversation from the main timeline o
|
||||||
Threads can be access by clicking their summary below the root event on the room timeline. Users can find a comprehensive list of threads by click the icon on the room header button.
|
Threads can be access by clicking their summary below the root event on the room timeline. Users can find a comprehensive list of threads by click the icon on the room header button.
|
||||||
|
|
||||||
This feature might work in degraded mode if the homeserver a user is connected to does not advertise support for the unstable feature `org.matrix.msc3440` when calling the `/versions` API endpoint.
|
This feature might work in degraded mode if the homeserver a user is connected to does not advertise support for the unstable feature `org.matrix.msc3440` when calling the `/versions` API endpoint.
|
||||||
|
|
||||||
|
## Voice & video rooms (`feature_voice_rooms`) [In Development]
|
||||||
|
|
||||||
|
Enables support for creating and joining voice & video rooms, which are persistent voice chats that users can jump in and out of.
|
||||||
|
|
|
@ -56,6 +56,8 @@ let widgetApi: WidgetApi;
|
||||||
let meetApi: any; // JitsiMeetExternalAPI
|
let meetApi: any; // JitsiMeetExternalAPI
|
||||||
let skipOurWelcomeScreen = false;
|
let skipOurWelcomeScreen = false;
|
||||||
|
|
||||||
|
const ack = (ev: CustomEvent<IWidgetApiRequest>) => widgetApi.transport.reply(ev.detail, {});
|
||||||
|
|
||||||
(async function() {
|
(async function() {
|
||||||
try {
|
try {
|
||||||
// Queue a config.json lookup asap, so we can use it later on. We want this to be concurrent with
|
// Queue a config.json lookup asap, so we can use it later on. We want this to be concurrent with
|
||||||
|
@ -133,7 +135,6 @@ let skipOurWelcomeScreen = false;
|
||||||
|
|
||||||
if (widgetApi) {
|
if (widgetApi) {
|
||||||
await readyPromise;
|
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
|
// See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
|
||||||
if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) {
|
if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) {
|
||||||
|
@ -142,12 +143,48 @@ let skipOurWelcomeScreen = false;
|
||||||
logger.log("Got OpenID Connect token");
|
logger.log("Got OpenID Connect token");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: register widgetApi listeners for PTT controls (https://github.com/vector-im/element-web/issues/12795)
|
widgetApi.on(`action:${ElementWidgetActions.JoinCall}`,
|
||||||
|
(ev: CustomEvent<IWidgetApiRequest>) => {
|
||||||
|
joinConference();
|
||||||
|
ack(ev);
|
||||||
|
},
|
||||||
|
);
|
||||||
widgetApi.on(`action:${ElementWidgetActions.HangupCall}`,
|
widgetApi.on(`action:${ElementWidgetActions.HangupCall}`,
|
||||||
(ev: CustomEvent<IWidgetApiRequest>) => {
|
(ev: CustomEvent<IWidgetApiRequest>) => {
|
||||||
if (meetApi) meetApi.executeCommand('hangup');
|
meetApi?.executeCommand('hangup');
|
||||||
widgetApi.transport.reply(ev.detail, {}); // ack
|
ack(ev);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
widgetApi.on(`action:${ElementWidgetActions.MuteAudio}`,
|
||||||
|
async (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||||
|
ack(ev);
|
||||||
|
if (meetApi && !await meetApi.isAudioMuted()) {
|
||||||
|
meetApi.executeCommand('toggleAudio');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
widgetApi.on(`action:${ElementWidgetActions.UnmuteAudio}`,
|
||||||
|
async (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||||
|
ack(ev);
|
||||||
|
if (meetApi && await meetApi.isAudioMuted()) {
|
||||||
|
meetApi.executeCommand('toggleAudio');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
widgetApi.on(`action:${ElementWidgetActions.MuteVideo}`,
|
||||||
|
async (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||||
|
ack(ev);
|
||||||
|
if (meetApi && !await meetApi.isVideoMuted()) {
|
||||||
|
meetApi.executeCommand('toggleVideo');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
widgetApi.on(`action:${ElementWidgetActions.UnmuteVideo}`,
|
||||||
|
async (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||||
|
ack(ev);
|
||||||
|
if (meetApi && await meetApi.isVideoMuted()) {
|
||||||
|
meetApi.executeCommand('toggleVideo');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
widgetApi.on(`action:${ElementWidgetActions.StartLiveStream}`,
|
widgetApi.on(`action:${ElementWidgetActions.StartLiveStream}`,
|
||||||
|
@ -160,7 +197,7 @@ let skipOurWelcomeScreen = false;
|
||||||
//rtmpStreamKey: ev.detail.data.rtmpStreamKey,
|
//rtmpStreamKey: ev.detail.data.rtmpStreamKey,
|
||||||
youtubeStreamKey: ev.detail.data.rtmpStreamKey,
|
youtubeStreamKey: ev.detail.data.rtmpStreamKey,
|
||||||
});
|
});
|
||||||
widgetApi.transport.reply(ev.detail, {}); // ack
|
ack(ev);
|
||||||
} else {
|
} else {
|
||||||
widgetApi.transport.reply(ev.detail, { error: { message: "Conference not joined" } });
|
widgetApi.transport.reply(ev.detail, { error: { message: "Conference not joined" } });
|
||||||
}
|
}
|
||||||
|
@ -293,6 +330,7 @@ function joinConference() { // event handler bound in HTML
|
||||||
// ignored promise because we don't care if it works
|
// ignored promise because we don't care if it works
|
||||||
// noinspection JSIgnoredPromiseFromCall
|
// noinspection JSIgnoredPromiseFromCall
|
||||||
widgetApi.setAlwaysOnScreen(true);
|
widgetApi.setAlwaysOnScreen(true);
|
||||||
|
widgetApi.transport.send(ElementWidgetActions.JoinCall, {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -300,9 +338,13 @@ function joinConference() { // event handler bound in HTML
|
||||||
switchVisibleContainers();
|
switchVisibleContainers();
|
||||||
|
|
||||||
if (widgetApi) {
|
if (widgetApi) {
|
||||||
|
// We send the hangup event before setAlwaysOnScreen, because the latter
|
||||||
|
// can cause the receiving side to instantly stop listening.
|
||||||
// ignored promise because we don't care if it works
|
// ignored promise because we don't care if it works
|
||||||
// noinspection JSIgnoredPromiseFromCall
|
// noinspection JSIgnoredPromiseFromCall
|
||||||
widgetApi.setAlwaysOnScreen(false);
|
widgetApi.transport.send(ElementWidgetActions.HangupCall, {}).then(() =>
|
||||||
|
widgetApi.setAlwaysOnScreen(false),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("jitsiContainer").innerHTML = "";
|
document.getElementById("jitsiContainer").innerHTML = "";
|
||||||
|
@ -312,4 +354,22 @@ function joinConference() { // event handler bound in HTML
|
||||||
skipToJitsiSplashScreen();
|
skipToJitsiSplashScreen();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
meetApi.on("audioMuteStatusChanged", ({ muted }) => {
|
||||||
|
const action = muted ? ElementWidgetActions.MuteAudio : ElementWidgetActions.UnmuteAudio;
|
||||||
|
widgetApi.transport.send(action, {});
|
||||||
|
});
|
||||||
|
|
||||||
|
meetApi.on("videoMuteStatusChanged", ({ muted }) => {
|
||||||
|
const action = muted ? ElementWidgetActions.MuteVideo : ElementWidgetActions.UnmuteVideo;
|
||||||
|
widgetApi.transport.send(action, {});
|
||||||
|
});
|
||||||
|
|
||||||
|
["videoConferenceJoined", "participantJoined", "participantLeft"].forEach(event => {
|
||||||
|
meetApi.on(event, () => {
|
||||||
|
widgetApi?.transport.send(ElementWidgetActions.CallParticipants, {
|
||||||
|
participants: meetApi.getParticipantsInfo(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue