Autoconnect the next X speaker to jitsi

In config, set "general_system_conference_auto_connect_next_speakers"
to let the next X speakers on the current list of speakers
automatically join the jitsi conference.
Updates automatically
This commit is contained in:
Sean 2020-11-18 10:25:26 +01:00 committed by Emanuel Schütze
parent 65c7d3491c
commit d6467d5bbf
4 changed files with 76 additions and 17 deletions

View File

@ -38,6 +38,8 @@ _('Livestream url');
_('Remove URL to deactivate livestream. Check extra group permission to see livestream.');
_('Livestream poster image url');
_('Shows if livestream is not started. Recommended image format: 500x281px, PNG or JPG');
_('Number of next speakers automatically connecting to the live conference');
_('Live conference has to be active. Choose 0 to disable auto connect.');
_('Show this text on the login page');
_('OpenSlides Theme');
_('Export');

View File

@ -12,6 +12,7 @@ import { OperatorService } from 'app/core/core-services/operator.service';
import { Deferred } from 'app/core/promises/deferred';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service';
import { UserListIndexType } from 'app/site/agenda/models/view-list-of-speakers';
import { BaseViewComponentDirective } from 'app/site/base/base-view';
import { CurrentListOfSpeakersService } from 'app/site/projector/services/current-list-of-speakers.service';
@ -85,6 +86,7 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
public restricted = false;
public videoStreamUrl: string;
private nextSpeakerAmount: number;
// do not set the password twice
private isPasswortSet = false;
@ -330,6 +332,11 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
this.configService.get<boolean>('general_system_conference_los_restriction').subscribe(restricted => {
this.restricted = restricted;
}),
this.configService
.get<number>('general_system_conference_auto_connect_next_speakers')
.subscribe(nextSpeakerAmount => {
this.nextSpeakerAmount = nextSpeakerAmount;
}),
this.configService.get<string>('general_system_stream_url').subscribe(url => {
this.videoStreamUrl = url;
this.configsLoaded.resolve();
@ -359,17 +366,10 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
// check if the operator is on the clos, remove from room if not permitted
this.closService.currentListOfSpeakersObservable
.pipe(
map(los => (los ? los.isUserOnList(this.operator.user.id) : false)),
map(los => los?.findUserIndexOnList(this.operator.user.id) ?? -1),
distinctUntilChanged()
)
.subscribe(isOnList => {
this.isOnCurrentLos = isOnList;
this.triggerMeetingRoomButtonAnimation();
if (!this.isAccessPermitted) {
this.viewStream();
}
})
.subscribe(userLosIndex => this.autoJoinJitsiByLosIndex(userLosIndex))
);
}
@ -446,6 +446,31 @@ export class JitsiComponent extends BaseViewComponentDirective implements OnInit
}
}
private autoJoinJitsiByLosIndex(operatorClosIndex: number): void {
if (operatorClosIndex !== UserListIndexType.NotOnList) {
if (!this.isOnCurrentLos) {
this.isOnCurrentLos = true;
this.triggerMeetingRoomButtonAnimation();
}
if (
this.nextSpeakerAmount &&
this.nextSpeakerAmount > 0 &&
operatorClosIndex > UserListIndexType.Active &&
operatorClosIndex <= this.nextSpeakerAmount &&
!this.isJitsiActive
) {
this.enterConversation();
}
} else {
this.isOnCurrentLos = false;
}
if (!this.isAccessPermitted) {
this.viewStream();
}
}
private setRoomPassword(): void {
if (this.roomPassword && !this.isPasswortSet) {
// You can only set the password after the server has recognized that you are

View File

@ -12,6 +12,12 @@ export interface ListOfSpeakersTitleInformation {
title_information: object;
}
export enum UserListIndexType {
Finished = -2,
NotOnList = -1,
Active = 0
}
/**
* TODO: Resolve potential circular dependencies with {@link BaseViewModelWithListOfSpeakers}.
*/
@ -25,6 +31,10 @@ export class ViewListOfSpeakers
return this._model;
}
public get activeSpeaker(): ViewSpeaker {
return this.speakers.find(speaker => speaker.state === SpeakerState.CURRENT);
}
public get finishedSpeakers(): ViewSpeaker[] {
return this.speakers.filter(speaker => speaker.state === SpeakerState.FINISHED);
}
@ -65,8 +75,20 @@ export class ViewListOfSpeakers
return this.finishedSpeakers.findIndex(speaker => speaker.user_id === checkSpeaker.user_id) !== -1;
}
public isUserOnList(userId: number): boolean {
return !!this.speakers.find(speaker => speaker.user_id === userId);
public findUserIndexOnList(userId: number): number {
if (this.activeSpeaker?.user.id === userId) {
return UserListIndexType.Active;
} else {
const waitingSpeakersIndex = this.waitingSpeakers.findIndex(speaker => speaker.user_id === userId);
const finishedSpeakersIndex = this.finishedSpeakers.findIndex(speaker => speaker.user_id === userId);
if (waitingSpeakersIndex !== -1) {
return waitingSpeakersIndex + 1;
} else if (finishedSpeakersIndex !== -1) {
return UserListIndexType.Finished;
} else {
return UserListIndexType.NotOnList;
}
}
}
}
interface IListOfSpeakersRelations {

View File

@ -102,31 +102,41 @@ def get_config_variables():
)
yield ConfigVariable(
name="general_system_conference_auto_connect",
name="general_system_conference_los_restriction",
default_value=False,
input_type="boolean",
label="Connect all users to live conference automatically",
label="Allow only current speakers and list of speakers managers to enter the live conference",
help_text="Server settings required to activate Jitsi Meet integration.",
weight=141,
subgroup="Live conference",
)
yield ConfigVariable(
name="general_system_conference_los_restriction",
name="general_system_conference_auto_connect",
default_value=False,
input_type="boolean",
label="Allow only current speakers and list of speakers managers to enter the live conference",
label="Connect all users to live conference automatically",
help_text="Server settings required to activate Jitsi Meet integration.",
weight=142,
subgroup="Live conference",
)
yield ConfigVariable(
name="general_system_conference_auto_connect_next_speakers",
default_value=0,
input_type="integer",
label="Number of next speakers automatically connecting to the live conference",
help_text="Live conference has to be active. Choose 0 to disable auto connect.",
weight=143,
subgroup="Live conference",
)
yield ConfigVariable(
name="general_system_stream_url",
default_value="",
label="Livestream url",
help_text="Remove URL to deactivate livestream. Check extra group permission to see livestream.",
weight=143,
weight=146,
subgroup="Live conference",
)
@ -135,7 +145,7 @@ def get_config_variables():
default_value="",
label="Livestream poster image url",
help_text="Shows if livestream is not started. Recommended image format: 500x281px, PNG or JPG",
weight=144,
weight=147,
subgroup="Live conference",
)