Merge pull request #6102 from tsiegleauq/hide-conf-bar-sometimes

Hide conference bar without interaction
This commit is contained in:
Emanuel Schütze 2021-06-03 20:50:24 +02:00 committed by GitHub
commit 4938c34d50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 116 deletions

View File

@ -72,15 +72,17 @@
</div>
<div class="exit">
<!-- Exit jitsi, view stream -->
<button
mat-icon-button
color="primary"
matTooltip="{{ 'Continue livestream' | translate }}"
(click)="viewStream()"
*ngIf="!!(liveStreamUrl | async)?.trim()"
>
<mat-icon>live_tv</mat-icon>
</button>
<ng-container *osPerms="permission.coreCanSeeLiveStream">
<button
mat-icon-button
color="primary"
matTooltip="{{ 'Continue livestream' | translate }}"
(click)="viewStream()"
*ngIf="hasLiveStreamUrl | async"
>
<mat-icon>live_tv</mat-icon>
</button>
</ng-container>
</div>
</div>
</div>

View File

@ -38,6 +38,8 @@ export class CallComponent extends BaseViewComponentDirective implements OnInit,
public isJitsiActiveInAnotherTab: Observable<boolean> = this.rtcService.inOtherTab;
public canEnterCall: Observable<boolean> = this.callRestrictionService.canEnterCallObservable;
public isJitsiDialogOpen: Observable<boolean> = this.rtcService.showCallDialogObservable;
public showParticles: Observable<boolean> = this.applauseService.showParticles;
public hasLiveStreamUrl: Observable<boolean> = this.streamService.hasLiveStreamUrlObvervable;
public isJitsiActive: boolean;
public isJoined: boolean;
@ -64,18 +66,6 @@ export class CallComponent extends BaseViewComponentDirective implements OnInit,
return this.isJitsiActive && this.isJoined;
}
public get showParticles(): Observable<boolean> {
return this.applauseService.showParticles;
}
public get canSeeLiveStream(): Observable<boolean> {
return this.streamService.canSeeLiveStreamObservable;
}
public get liveStreamUrl(): Observable<string> {
return this.streamService.liveStreamUrlObservable;
}
private autoConnect: boolean;
@Output()

View File

@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Title } from '@angular/platform-browser';
@ -18,7 +18,7 @@ import { StreamService } from '../../services/stream.service';
styleUrls: ['./interaction-container.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class InteractionContainerComponent extends BaseViewComponentDirective {
export class InteractionContainerComponent extends BaseViewComponentDirective implements OnInit {
public showBody = false;
private streamRunning = false;
@ -63,11 +63,6 @@ export class InteractionContainerComponent extends BaseViewComponentDirective {
) {
super(titleService, translate, matSnackBar);
this.subscriptions.push(
interactionService.conferenceStateObservable.pipe(distinctUntilChanged()).subscribe(state => {
if (state) {
this.clearTitles();
}
}),
rtcService.showCallDialogObservable.subscribe(show => {
if (show) {
this.showBody = false;
@ -91,9 +86,20 @@ export class InteractionContainerComponent extends BaseViewComponentDirective {
);
}
public ngOnInit(): void {
this.subscriptions.push(
this.interactionService.conferenceStateObservable.pipe(distinctUntilChanged()).subscribe(state => {
if (state) {
this.clearTitles();
}
})
);
}
private clearTitles(): void {
this.containerHeadTitle = '';
this.containerHeadSubtitle = '';
this.cd.markForCheck();
this.cd.detectChanges();
}
@ -104,14 +110,14 @@ export class InteractionContainerComponent extends BaseViewComponentDirective {
public updateTitle(title: string): void {
if (title !== this.containerHeadTitle) {
this.containerHeadTitle = title ?? '';
this.cd.detectChanges();
this.cd.markForCheck();
}
}
public updateSubtitle(title: string): void {
if (title !== this.containerHeadSubtitle) {
this.containerHeadSubtitle = title ?? '';
this.cd.detectChanges();
this.cd.markForCheck();
}
}
}

View File

@ -88,7 +88,7 @@ export class CallRestrictionService {
) {
this.hasToEnterCallSubject.next();
}
} else if (operatorClosIndex === UserListIndexType.NotOnList && this.restricted) {
} else if (operatorClosIndex === UserListIndexType.NotOnList && this.restricted && !this.canManageSpeaker) {
this.hasToLeaveCallSubject.next();
}
}

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { ConfigService } from 'app/core/ui-services/config.service';
import { CallRestrictionService } from './call-restriction.service';
@ -9,9 +9,9 @@ import { RtcService } from './rtc.service';
import { StreamService } from './stream.service';
export enum ConferenceState {
none,
stream,
jitsi
none = 1,
stream = 2,
jitsi = 3
}
@Injectable({
@ -20,17 +20,14 @@ export enum ConferenceState {
export class InteractionService {
private conferenceStateSubject = new BehaviorSubject<ConferenceState>(ConferenceState.none);
public conferenceStateObservable = this.conferenceStateSubject.asObservable();
public showLiveConfObservable: Observable<boolean>;
public showLiveConfObservable: Observable<boolean> = this.configService.get<boolean>(
'general_system_conference_show'
);
private get conferenceState(): ConferenceState {
return this.conferenceStateSubject.value;
}
private isJitsiEnabled: boolean;
private isInCall: boolean;
private isJitsiActive: boolean;
private hasLiveStreamUrl: boolean;
private canSeeLiveStream: boolean;
private showLiveConf: boolean;
public get isConfStateStream(): Observable<boolean> {
return this.conferenceStateObservable.pipe(map(state => state === ConferenceState.stream));
@ -50,36 +47,38 @@ export class InteractionService {
private rtcService: RtcService,
private callRestrictionService: CallRestrictionService
) {
this.showLiveConfObservable = this.configService.get<boolean>('general_system_conference_show');
combineLatest(
this.showLiveConfObservable,
this.streamService.hasLiveStreamUrlObvervable,
this.streamService.canSeeLiveStreamObservable,
this.rtcService.isJitsiEnabledObservable,
this.rtcService.isJoinedObservable,
this.rtcService.isJitsiActiveObservable,
this.callRestrictionService.canEnterCallObservable,
(showConf, hasStreamUrl, canSeeStream, jitsiEnabled, inCall, jitsiActive, canEnterCall) => {
this.isInCall = inCall;
/**
* If you want to somehow simplify this using rxjs merge-map magic or something
* be my guest.
*/
this.streamService.liveStreamUrlObservable.subscribe(url => {
this.hasLiveStreamUrl = !!url?.trim() ?? false;
this.detectDeadState();
});
this.streamService.canSeeLiveStreamObservable.subscribe(canSee => {
this.canSeeLiveStream = canSee;
this.detectDeadState();
});
this.rtcService.isJitsiEnabledObservable.subscribe(enabled => {
this.isJitsiEnabled = enabled;
this.detectDeadState();
});
this.rtcService.isJoinedObservable.subscribe(joined => {
this.isInCall = joined;
this.detectDeadState();
});
this.rtcService.isJitsiActiveObservable.subscribe(isActive => {
this.isJitsiActive = isActive;
this.detectDeadState();
});
/**
* most importantly, if there is a call, to not change the state here
*/
if (inCall || jitsiActive) {
return;
}
if (hasStreamUrl && canSeeStream) {
return ConferenceState.stream;
} else if (showConf && jitsiEnabled && canEnterCall && (!hasStreamUrl || !canSeeStream)) {
return ConferenceState.jitsi;
} else {
return ConferenceState.none;
}
}
)
.pipe(distinctUntilChanged())
.subscribe(state => {
if (state) {
this.setConferenceState(state);
}
});
this.callRestrictionService.hasToEnterCallObservable.subscribe(() => {
if (!this.isInCall) {
@ -91,13 +90,6 @@ export class InteractionService {
this.callRestrictionService.hasToLeaveCallObservable.subscribe(() => {
this.viewStream();
});
this.showLiveConfObservable.subscribe(showConf => {
this.showLiveConf = showConf;
this.detectDeadState();
});
this.detectDeadState();
}
public async enterCall(): Promise<void> {
@ -117,37 +109,4 @@ export class InteractionService {
this.conferenceStateSubject.next(newState);
}
}
/**
* this is the "dead" state; you would see the jitsi state; but are not connected
* or the connection is prohibited. If this occurs and a live stream
* becomes available, switch to the stream state
*/
private detectDeadState(): void {
if (
this.isInCall === undefined ||
this.isJitsiActive === undefined ||
this.hasLiveStreamUrl === undefined ||
this.conferenceState === undefined ||
this.canSeeLiveStream === undefined ||
this.isJitsiEnabled === undefined
) {
return;
}
/**
* most importantly, if there is a call, to not change the state!
*/
if (this.isInCall || this.isJitsiActive) {
return;
}
if (this.hasLiveStreamUrl && this.canSeeLiveStream) {
this.viewStream();
} else if (this.showLiveConf && (!this.hasLiveStreamUrl || !this.canSeeLiveStream) && this.isJitsiEnabled) {
this.enterCall();
} else {
this.setConferenceState(ConferenceState.none);
}
}
}

View File

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { StorageMap } from '@ngx-pwa/local-storage';
import { Observable, Subject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ConfigService } from 'app/core/ui-services/config.service';
@ -13,7 +13,10 @@ const STREAM_RUNNING_STORAGE_KEY = 'streamIsRunning';
providedIn: 'root'
})
export class StreamService {
public liveStreamUrlObservable: Observable<string>;
public liveStreamUrlObservable: Observable<string> = this.configService.get<string>('general_system_stream_url');
public hasLiveStreamUrlObvervable: Observable<boolean> = this.liveStreamUrlObservable.pipe(
map(url => !!url?.trim() || false)
);
/**
* undefined is controlled behavior, meaning, this property was not
@ -28,9 +31,11 @@ export class StreamService {
private canSeeLiveStreamSubject = new Subject<boolean>();
public canSeeLiveStreamObservable = this.canSeeLiveStreamSubject.asObservable();
public constructor(private storageMap: StorageMap, operator: OperatorService, configService: ConfigService) {
this.liveStreamUrlObservable = configService.get<string>('general_system_stream_url');
public constructor(
private storageMap: StorageMap,
operator: OperatorService,
private configService: ConfigService
) {
this.streamLoadedOnceObservable = this.storageMap
.watch(STREAM_RUNNING_STORAGE_KEY, { type: 'boolean' })
.pipe(distinctUntilChanged());