Replace jitsi mat dialog
Replace Jitsis Mat Dialog with an div container Fixes an issue where observables in jitsi would register multiple times Clear the IndexedDB on logout
This commit is contained in:
parent
bb10c25974
commit
c2a1b62c8b
@ -8,6 +8,7 @@ import { DEFAULT_AUTH_TYPE, UserAuthType } from 'app/shared/models/users/user';
|
||||
import { DataStoreService } from './data-store.service';
|
||||
import { HttpService } from './http.service';
|
||||
import { OpenSlidesService } from './openslides.service';
|
||||
import { StorageService } from './storage.service';
|
||||
|
||||
/**
|
||||
* Authenticates an OpenSlides user with username and password
|
||||
@ -29,7 +30,8 @@ export class AuthService {
|
||||
private operator: OperatorService,
|
||||
private OpenSlides: OpenSlidesService,
|
||||
private router: Router,
|
||||
private DS: DataStoreService
|
||||
private DS: DataStoreService,
|
||||
private storageService: StorageService
|
||||
) {}
|
||||
|
||||
/**
|
||||
@ -106,10 +108,12 @@ export class AuthService {
|
||||
// We do nothing on failures. Reboot OpenSlides anyway.
|
||||
}
|
||||
this.router.navigate(['/']);
|
||||
await this.storageService.clear();
|
||||
await this.DS.clear();
|
||||
await this.operator.setWhoAmI(response);
|
||||
await this.OpenSlides.reboot();
|
||||
} else if (authType === 'saml') {
|
||||
await this.storageService.clear();
|
||||
await this.DS.clear();
|
||||
await this.operator.setWhoAmI(null);
|
||||
window.location.href = environment.urlPrefix + '/saml/?slo'; // Bye
|
||||
|
@ -1,29 +1,30 @@
|
||||
<!-- iFrame Dialog -->
|
||||
<ng-template #conferenceDialog>
|
||||
<div class="jitsi-iframe-wrapper" #jitsi></div>
|
||||
<div mat-dialog-actions>
|
||||
<button
|
||||
type="button"
|
||||
mat-button
|
||||
color=""
|
||||
(click)="openExternal()"
|
||||
matTooltip="{{ 'Open Jitsi in new tab' | translate }}"
|
||||
>
|
||||
<mat-icon>open_in_new</mat-icon>
|
||||
</button>
|
||||
<div class="jitsi-fake-dialog-wrapper" [ngClass]="{'jitsi-dialog-hide': !isJitsiDialogOpen}">
|
||||
<mat-card class="jitsi-fake-dialog">
|
||||
<div class="jitsi-iframe-wrapper" #jitsi></div>
|
||||
<div class="jitsi-dialog-actions">
|
||||
<button
|
||||
type="button"
|
||||
mat-button
|
||||
color="primary"
|
||||
(click)="openExternal()"
|
||||
matTooltip="{{ 'Open Jitsi in new tab' | translate }}"
|
||||
>
|
||||
<mat-icon>open_in_new</mat-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="minimize-jitsi-dialog-button"
|
||||
type="button"
|
||||
mat-button
|
||||
color="primary"
|
||||
(click)="hideJitsiDialog()"
|
||||
>
|
||||
<span>{{ 'Minimize' | translate }}</span>
|
||||
<mat-icon>fullscreen_exit</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
<button
|
||||
type="button"
|
||||
mat-button
|
||||
color="primary"
|
||||
(click)="hideJitsiDialog()"
|
||||
>
|
||||
<span>{{ 'Minimize' | translate }}</span>
|
||||
<mat-icon>fullscreen_exit</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<div class="jitsi-integration" *ngIf="enableJitsi || (videoStreamUrl && canSeeLiveStream)">
|
||||
<!-- Audio-Conference-bar -->
|
||||
@ -172,7 +173,7 @@
|
||||
<os-vjs-player
|
||||
[videoUrl]="videoStreamUrl"
|
||||
(started)="onSteamStarted()"
|
||||
*ngIf="canSeeLiveStream && !streamActiveInAnotherTab || streamRunning"
|
||||
*ngIf="(canSeeLiveStream && !streamActiveInAnotherTab) || streamRunning"
|
||||
></os-vjs-player>
|
||||
<div class="disconnected" *ngIf="streamActiveInAnotherTab && !streamRunning">
|
||||
<span>{{ 'The livestream is already running in your OpenSlides session.' | translate }}</span>
|
||||
|
@ -1,19 +1,39 @@
|
||||
.jitsi-fake-dialog-wrapper {
|
||||
z-index: 98;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 20px 10% 20px 5%;
|
||||
|
||||
.jitsi-fake-dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 90%;
|
||||
|
||||
.jitsi-iframe-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.jitsi-dialog-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.jitsi-dialog-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jitsi-iframe-wrapper {
|
||||
height: 70vh;
|
||||
}
|
||||
|
||||
.minimize-jitsi-dialog-button {
|
||||
margin-left: auto !important;
|
||||
span {
|
||||
line-height: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.jitsi-integration {
|
||||
z-index: 99;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
.cast-shadow {
|
||||
box-shadow: -3px -3px 10px 0px rgba(0, 0, 0, 0.2) !important;
|
||||
}
|
||||
|
@ -1,27 +1,17 @@
|
||||
import {
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Component, ElementRef, HostListener, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
|
||||
import { StorageMap } from '@ngx-pwa/local-storage';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { distinctUntilChanged } from 'rxjs/operators';
|
||||
|
||||
import { BaseComponent } from 'app/base.component';
|
||||
import { ConstantsService } from 'app/core/core-services/constants.service';
|
||||
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 { largeDialogSettings } from 'app/shared/utils/dialog-settings';
|
||||
import { BaseViewComponent } from 'app/site/base/base-view';
|
||||
|
||||
declare var JitsiMeetExternalAPI: any;
|
||||
|
||||
@ -66,7 +56,7 @@ enum ConferenceState {
|
||||
styleUrls: ['./jitsi.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class JitsiComponent extends BaseComponent implements OnInit, OnDestroy {
|
||||
export class JitsiComponent extends BaseViewComponent implements OnInit, OnDestroy {
|
||||
public enableJitsi: boolean;
|
||||
|
||||
private autoconnect: boolean;
|
||||
@ -87,11 +77,6 @@ export class JitsiComponent extends BaseComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('jitsi')
|
||||
private jitsiNode: ElementRef;
|
||||
|
||||
@ViewChild('conferenceDialog', { static: true })
|
||||
public conferenceDialog: TemplateRef<string>;
|
||||
|
||||
private confDialogRef: MatDialogRef<any>;
|
||||
|
||||
// JitsiMeet api object
|
||||
private api: any | null;
|
||||
|
||||
@ -109,8 +94,8 @@ export class JitsiComponent extends BaseComponent implements OnInit, OnDestroy {
|
||||
private configsLoaded: Deferred<void> = new Deferred();
|
||||
|
||||
// storage locks
|
||||
public isJitsiActiveInAnotherTab: boolean;
|
||||
public streamActiveInAnotherTab: boolean;
|
||||
public isJitsiActiveInAnotherTab = false;
|
||||
public streamActiveInAnotherTab = false;
|
||||
|
||||
private RTC_LOGGED_STORAGE_KEY = 'rtcIsLoggedIn';
|
||||
private STREAM_RUNNING_STORAGE_KEY = 'streamIsRunning';
|
||||
@ -176,26 +161,22 @@ export class JitsiComponent extends BaseComponent implements OnInit, OnDestroy {
|
||||
public constructor(
|
||||
titleService: Title,
|
||||
translate: TranslateService,
|
||||
snackBar: MatSnackBar,
|
||||
private operator: OperatorService,
|
||||
private storageMap: StorageMap,
|
||||
private userRepo: UserRepositoryService,
|
||||
private constantsService: ConstantsService,
|
||||
private configService: ConfigService,
|
||||
private dialog: MatDialog
|
||||
private configService: ConfigService
|
||||
) {
|
||||
super(titleService, translate);
|
||||
super(titleService, translate, snackBar);
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.confDialogRef = this.dialog.open(this.conferenceDialog, {
|
||||
...largeDialogSettings,
|
||||
panelClass: 'jitsi-dialog-hide',
|
||||
hasBackdrop: false
|
||||
});
|
||||
this.setUp();
|
||||
}
|
||||
|
||||
public async ngOnDestroy(): Promise<void> {
|
||||
super.ngOnDestroy();
|
||||
this.stopConference();
|
||||
}
|
||||
|
||||
@ -214,25 +195,29 @@ export class JitsiComponent extends BaseComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private async setUp(): Promise<void> {
|
||||
this.storageMap
|
||||
.watch(this.RTC_LOGGED_STORAGE_KEY)
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe((inUse: boolean) => {
|
||||
this.isJitsiActiveInAnotherTab = inUse;
|
||||
this.lockLoaded.resolve();
|
||||
if (!inUse && !this.isJitsiActive) {
|
||||
this.startJitsi();
|
||||
}
|
||||
});
|
||||
this.subscriptions.push(
|
||||
this.storageMap
|
||||
.watch(this.RTC_LOGGED_STORAGE_KEY)
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe((inUse: boolean) => {
|
||||
console.log('RTC_LOGGED_STORAGE_KEY is in use: ', inUse);
|
||||
|
||||
this.storageMap
|
||||
.watch(this.STREAM_RUNNING_STORAGE_KEY)
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe((running: boolean) => {
|
||||
this.streamActiveInAnotherTab = running;
|
||||
});
|
||||
this.isJitsiActiveInAnotherTab = inUse;
|
||||
this.lockLoaded.resolve();
|
||||
if (!inUse && !this.isJitsiActive) {
|
||||
this.startJitsi();
|
||||
}
|
||||
}),
|
||||
this.storageMap
|
||||
.watch(this.STREAM_RUNNING_STORAGE_KEY)
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe((running: boolean) => {
|
||||
this.streamActiveInAnotherTab = running;
|
||||
})
|
||||
);
|
||||
|
||||
await this.lockLoaded;
|
||||
|
||||
this.constantsService.get<JitsiSettings>('Settings').subscribe(settings => {
|
||||
if (settings) {
|
||||
this.jitsiDomain = settings.JITSI_DOMAIN;
|
||||
@ -243,63 +228,64 @@ export class JitsiComponent extends BaseComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
await this.constantsLoaded;
|
||||
this.configService
|
||||
.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;
|
||||
if (this.enableJitsi && this.autoconnect) {
|
||||
this.startJitsi();
|
||||
} else {
|
||||
this.stopJitsi();
|
||||
}
|
||||
});
|
||||
|
||||
this.configService.get<boolean>('general_system_conference_los_restriction').subscribe(restricted => {
|
||||
this.restricted = restricted;
|
||||
});
|
||||
|
||||
this.configService.get<string>('general_system_stream_url').subscribe(url => {
|
||||
this.videoStreamUrl = url;
|
||||
this.configsLoaded.resolve();
|
||||
});
|
||||
this.subscriptions.push(
|
||||
this.configService
|
||||
.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;
|
||||
if (this.enableJitsi && this.autoconnect) {
|
||||
this.startJitsi();
|
||||
} else {
|
||||
this.stopJitsi();
|
||||
}
|
||||
}),
|
||||
this.configService.get<boolean>('general_system_conference_los_restriction').subscribe(restricted => {
|
||||
this.restricted = restricted;
|
||||
}),
|
||||
this.configService.get<string>('general_system_stream_url').subscribe(url => {
|
||||
this.videoStreamUrl = url;
|
||||
this.configsLoaded.resolve();
|
||||
})
|
||||
);
|
||||
|
||||
await this.configsLoaded;
|
||||
// after configs are loaded
|
||||
this.storageMap
|
||||
.watch(this.CONFERENCE_STATE_STORAGE_KEY)
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe((confState: ConferenceState) => {
|
||||
if (confState in ConferenceState) {
|
||||
if (this.enableJitsi && (!this.videoStreamUrl || !this.canSeeLiveStream)) {
|
||||
this.currentState = ConferenceState.jitsi;
|
||||
} else if (!this.enableJitsi && this.videoStreamUrl && this.canSeeLiveStream) {
|
||||
this.currentState = ConferenceState.stream;
|
||||
|
||||
this.subscriptions.push(
|
||||
this.storageMap
|
||||
.watch(this.CONFERENCE_STATE_STORAGE_KEY)
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe((confState: ConferenceState) => {
|
||||
if (confState in ConferenceState) {
|
||||
if (this.enableJitsi && (!this.videoStreamUrl || !this.canSeeLiveStream)) {
|
||||
this.currentState = ConferenceState.jitsi;
|
||||
} else if (!this.enableJitsi && this.videoStreamUrl && this.canSeeLiveStream) {
|
||||
this.currentState = ConferenceState.stream;
|
||||
} else {
|
||||
this.currentState = confState;
|
||||
}
|
||||
} else {
|
||||
this.currentState = confState;
|
||||
this.setDefaultConfState();
|
||||
}
|
||||
} else {
|
||||
this.setDefaultConfState();
|
||||
}
|
||||
// show stream window when the state changes to stream
|
||||
if (this.currentState === ConferenceState.stream && !this.streamActiveInAnotherTab) {
|
||||
this.showJitsiWindow = true;
|
||||
}
|
||||
});
|
||||
// show stream window when the state changes to stream
|
||||
if (this.currentState === ConferenceState.stream && !this.streamActiveInAnotherTab) {
|
||||
this.showJitsiWindow = true;
|
||||
}
|
||||
}),
|
||||
// check if the user is on the clos, remove from room if not permitted
|
||||
this.operator
|
||||
.isOnCurrentListOfSpeakersObservable()
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe(isOnList => {
|
||||
this.isOnCurrentLos = isOnList;
|
||||
console.log('this.isOnCurrentLos: ', this.isOnCurrentLos);
|
||||
|
||||
// check if the user is on the clos, remove from room if not permitted
|
||||
this.operator
|
||||
.isOnCurrentListOfSpeakersObservable()
|
||||
.pipe(distinctUntilChanged())
|
||||
.subscribe(isOnList => {
|
||||
this.isOnCurrentLos = isOnList;
|
||||
console.log('this.isOnCurrentLos: ', this.isOnCurrentLos);
|
||||
|
||||
if (!this.isAccessPermitted) {
|
||||
this.viewStream();
|
||||
}
|
||||
});
|
||||
if (!this.isAccessPermitted) {
|
||||
this.viewStream();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public toggleMute(): void {
|
||||
@ -463,13 +449,12 @@ export class JitsiComponent extends BaseComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public hideJitsiDialog(): void {
|
||||
this.confDialogRef.addPanelClass('jitsi-dialog-hide');
|
||||
this.isJitsiDialogOpen = false;
|
||||
}
|
||||
|
||||
public showJitsiDialog(): void {
|
||||
this.confDialogRef.removePanelClass('jitsi-dialog-hide');
|
||||
this.isJitsiDialogOpen = true;
|
||||
this.showJitsiWindow = false;
|
||||
}
|
||||
|
||||
public async viewStream(): Promise<void> {
|
||||
|
@ -41,7 +41,7 @@
|
||||
{{ assignment.getListTitle() }}
|
||||
</div>
|
||||
<mat-chip-list class="ellipsis-overflow" *ngIf="vp.isMobile">
|
||||
<mat-chip color="" selected>
|
||||
<mat-chip color="primary" selected>
|
||||
{{ assignment.phaseString | translate }}
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
@ -136,10 +136,6 @@ mat-sidenav-container {
|
||||
}
|
||||
|
||||
.toolbars {
|
||||
z-index: 99;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
|
||||
* {
|
||||
|
Loading…
Reference in New Issue
Block a user