Add helpdesk icon and feature

Adds a "helpdesk" Jitsi room feature.
Can be enabled using the OpenSlides config page

Shows a 'Call support' button in the conference control bar
clicking the support button will connect the user
to a "support" jitsi room
The name of the support room will be
`JITSI_ROOM_NAME`-SUPPORT
This commit is contained in:
Sean 2021-01-28 15:30:49 +01:00
parent cc65b756c7
commit 024b9c74e6
3 changed files with 67 additions and 13 deletions

View File

@ -61,7 +61,7 @@
matTooltip="{{ 'Exit live conference and continue livestream' | translate }}"
*ngIf="videoStreamUrl && canSeeLiveStream && !isJitsiDialogOpen"
>
<mat-icon color="warn"> meeting_room </mat-icon>
<mat-icon color="warn">meeting_room</mat-icon>
</button>
<!-- mute/unmute button -->
@ -85,7 +85,7 @@
*ngIf="enableJitsi && isAccessPermitted"
class="quick-icon indicator"
mat-mini-fab
(click)="enterConversation()"
(click)="enterConferenceRoom()"
matTooltip="{{ 'Enter live conference' | translate }}"
>
<mat-icon
@ -109,6 +109,18 @@
</a>
</ng-container>
<!-- Call support button -->
<button
class="indicator quick-icon"
mat-mini-fab
(click)="enterSupportRoom()"
[disabled]="isJitsiActive"
matTooltip="{{ 'Access help desk' | translate }}"
*ngIf="canAccessSupport"
>
<mat-icon color="primary">live_help</mat-icon>
</button>
<!-- applause button -->
<button
class="quick-icon indicator"
@ -137,7 +149,8 @@
<!-- open-window button -->
<button class="toggle-list-button" mat-button (click)="toggleShowJitsi()">
<ng-container *ngIf="currentState == state.jitsi">
<div class="ellipsis-overflow">{{ 'Live conference' | translate }}</div>
<div *ngIf="!connectToHelpDesk" class="ellipsis-overflow">{{ 'Live conference' | translate }}</div>
<div *ngIf="connectToHelpDesk" class="ellipsis-overflow">{{ 'Help desk' | translate }}</div>
<div class="one-line">
&nbsp;
<span *ngIf="currentDominantSpeaker">
@ -248,7 +261,7 @@
<button
mat-mini-fab
color="accent"
(click)="enterConversation()"
(click)="enterConferenceRoom()"
[disabled]="
!enableJitsi || isJitsiActive || isJitsiActiveInAnotherTab || !isAccessPermitted
"

View File

@ -82,9 +82,13 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
public enableJitsi: boolean;
private autoconnect: boolean;
private roomName: string;
private defaultRoomName: string;
private actualRoomName: string;
private roomPassword: string;
private jitsiDomain: string;
private isSupportEnabled: boolean;
public connectToHelpDesk = false;
public restricted = false;
public videoStreamUrl: string;
@ -139,6 +143,10 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
return this.roomPassword?.length > 0;
}
public get canAccessSupport(): boolean {
return this.isSupportEnabled && this.enableJitsi && !!this.defaultRoomName;
}
private isOnCurrentLos: boolean;
public canSeeLiveStream: boolean;
@ -174,7 +182,7 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
}
public get jitsiMeetUrl(): string {
return `https://${this.jitsiDomain}/${this.roomName}`;
return `https://${this.jitsiDomain}/${this.actualRoomName}`;
}
/**
@ -339,7 +347,7 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
this.constantsService.get<JitsiSettings>('Settings').subscribe(settings => {
if (settings) {
this.jitsiDomain = settings.JITSI_DOMAIN;
this.roomName = settings.JITSI_ROOM_NAME;
this.defaultRoomName = settings.JITSI_ROOM_NAME;
this.roomPassword = settings.JITSI_ROOM_PASSWORD;
this.constantsLoaded.resolve();
}
@ -352,7 +360,7 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
.get<boolean>('general_system_conference_auto_connect')
.subscribe(autoconnect => (this.autoconnect = autoconnect)),
this.configService.get<boolean>('general_system_conference_show').subscribe(show => {
this.enableJitsi = show && !!this.jitsiDomain && !!this.roomName;
this.enableJitsi = show && !!this.jitsiDomain && !!this.defaultRoomName;
if (this.enableJitsi && this.autoconnect) {
this.startJitsi();
} else {
@ -392,6 +400,9 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
} else {
this.isApplausBarUsed = false;
}
}),
this.configService.get<boolean>('general_system_conference_enable_helpdesk').subscribe(enabled => {
this.isSupportEnabled = enabled;
})
);
@ -425,19 +436,22 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
private startJitsi(): void {
if (!this.isJitsiActiveInAnotherTab && this.enableJitsi && !this.isJitsiActive && this.jitsiNode) {
this.enterConversation();
this.enterConferenceRoom();
}
}
public async enterConversation(): Promise<void> {
private async enterConversation(): Promise<void> {
await this.operator.loaded;
try {
await this.userMediaPermService.requestMediaAccess();
this.storageMap.set(this.RTC_LOGGED_STORAGE_KEY, true).subscribe(() => {});
this.setConferenceState(ConferenceState.jitsi);
this.setOptions();
if (this.api) {
this.api.dispose();
this.api = undefined;
}
this.api = new JitsiMeetExternalAPI(this.jitsiDomain, this.options);
const jitsiname = this.userRepo.getShortName(this.operator.user);
this.api.executeCommand('displayName', jitsiname);
this.loadApiCallbacks();
@ -503,7 +517,7 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
operatorClosIndex <= this.nextSpeakerAmount &&
!this.isJitsiActive
) {
this.enterConversation();
this.enterConferenceRoom();
}
} else {
this.isOnCurrentLos = false;
@ -563,6 +577,7 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
}
public async stopJitsi(): Promise<void> {
this.connectToHelpDesk = false;
if (this.isJitsiActive) {
this.api.executeCommand('hangup');
this.clearMembers();
@ -578,7 +593,7 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
private setOptions(): void {
this.options = {
roomName: this.roomName,
roomName: this.actualRoomName,
parentNode: this.jitsiNode.nativeElement,
configOverwrite: this.configOverwrite,
interfaceConfigOverwrite: this.interfaceConfigOverwrite
@ -617,6 +632,18 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
this.storageMap.set(this.STREAM_RUNNING_STORAGE_KEY, true).subscribe(() => {});
}
public enterConferenceRoom(): void {
this.actualRoomName = this.defaultRoomName;
this.connectToHelpDesk = false;
this.enterConversation();
}
public enterSupportRoom(): void {
this.actualRoomName = `${this.defaultRoomName}-SUPPORT`;
this.connectToHelpDesk = true;
this.enterConversation();
}
private onLiveStreamAvailable(liveStreamUrl: string): void {
this.videoStreamUrl = liveStreamUrl;
// this is the "dead" state; you would see the jitsi state; but are not connected

View File

@ -169,6 +169,20 @@ def get_config_variables():
subgroup="Live conference",
)
yield ConfigVariable(
name="general_system_conference_enable_helpdesk",
default_value=False,
input_type="boolean",
label="Enable help desk",
help_text="""
Shows a help icon in the conference bar.
Users can connect to a dedicated conference.
The conference host has to manually ensure the coverage of the help desk.
""",
weight=148,
subgroup="Live conference",
)
# Applause
yield ConfigVariable(