diff --git a/web/app/shared/services/scalar/scalar-widget.api.ts b/web/app/shared/services/scalar/scalar-widget.api.ts index 5cc01f4..61aaa53 100644 --- a/web/app/shared/services/scalar/scalar-widget.api.ts +++ b/web/app/shared/services/scalar/scalar-widget.api.ts @@ -63,6 +63,14 @@ export class ScalarWidgetApi { }); } + public static sendSetAlwaysOnScreen(alwaysVisible: boolean): void { + ScalarWidgetApi.callAction("set_always_on_screen", { + data: { + value: alwaysVisible, + }, + }); + } + private static callAction(action, payload) { if (!window.opener) { return; diff --git a/web/app/widget-wrappers/capable-widget.ts b/web/app/widget-wrappers/capable-widget.ts index eff981a..cb86980 100644 --- a/web/app/widget-wrappers/capable-widget.ts +++ b/web/app/widget-wrappers/capable-widget.ts @@ -9,6 +9,7 @@ export abstract class CapableWidget implements OnInit, OnDestroy { // The capabilities we support protected supportsScreenshots = false; protected supportsStickers = false; + protected supportsAlwaysOnScreen = false; public ngOnInit() { this.widgetApiSubscription = ScalarWidgetApi.requestReceived.subscribe(request => { @@ -17,8 +18,10 @@ export abstract class CapableWidget implements OnInit, OnDestroy { if (this.supportsScreenshots) capabilities.push("m.capability.screenshot"); if (this.supportsStickers) capabilities.push("m.sticker"); + if (this.supportsAlwaysOnScreen) capabilities.push("m.always_on_screen"); ScalarWidgetApi.replyCapabilities(request, capabilities); + this.onCapabilitiesSent(); } }); } @@ -26,4 +29,8 @@ export abstract class CapableWidget implements OnInit, OnDestroy { public ngOnDestroy() { if (this.widgetApiSubscription) this.widgetApiSubscription.unsubscribe(); } + + protected onCapabilitiesSent(): void { + if (this.supportsAlwaysOnScreen) ScalarWidgetApi.sendSetAlwaysOnScreen(true); + } } \ No newline at end of file diff --git a/web/app/widget-wrappers/jitsi/jitsi.component.ts b/web/app/widget-wrappers/jitsi/jitsi.component.ts index 790f280..e6b06c7 100644 --- a/web/app/widget-wrappers/jitsi/jitsi.component.ts +++ b/web/app/widget-wrappers/jitsi/jitsi.component.ts @@ -3,6 +3,7 @@ import { ActivatedRoute } from "@angular/router"; import * as $ from "jquery"; import { FE_JitsiWidget } from "../../shared/models/integration"; import { WidgetApiService } from "../../shared/services/integrations/widget-api.service"; +import { CapableWidget } from "../capable-widget"; declare var JitsiMeetExternalAPI: any; @@ -11,7 +12,7 @@ declare var JitsiMeetExternalAPI: any; templateUrl: "jitsi.component.html", styleUrls: ["jitsi.component.scss"], }) -export class JitsiWidgetWrapperComponent implements OnInit { +export class JitsiWidgetWrapperComponent extends CapableWidget implements OnInit { public isJoined = false; @@ -23,16 +24,20 @@ export class JitsiWidgetWrapperComponent implements OnInit { private jitsiApiObj: any; constructor(activatedRoute: ActivatedRoute, private widgetApi: WidgetApiService) { + super(); + this.supportsAlwaysOnScreen = true; + let params: any = activatedRoute.snapshot.queryParams; - this.domain = params.domain; + this.domain = params.domain || "jitsi.riot.im"; // Riot doesn't supply a domain, so we default this.conferenceId = params.confId || params.conferenceId; this.displayName = params.displayName; this.avatarUrl = params.avatarUrl; - this.userId = params.userId; + this.userId = params.userId || params.email; // Riot uses `email` when placing a conference call } public ngOnInit() { + super.ngOnInit(); this.widgetApi.getWidget("jitsi").then(integration => { const widget = integration; $.getScript(widget.options.scriptUrl);