diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css index e0b58fb4..2b7b924a 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.css @@ -2,34 +2,6 @@ height: 100%; } -.sidenav-container { - position: relative; - width: 100%; - height: 100%; - min-height: -webkit-fill-available; - overflow: hidden; -} - -.sidenav-menu { - display: flex; - align-items: center; - justify-content: center; - width: 360px; - background-color: var(--ov-primary-color); - border-left: none; - position: absolute; -} - -.mat-drawer-container { - background-color: var(--ov-primary-color); -} - -.sidenav-main { - height: 100%; - overflow: hidden; - min-height: -webkit-fill-available; - min-height: -moz-available; -} .bounds { position: absolute; diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html index 6d130bee..db8e1767 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.html @@ -1,67 +1,35 @@ - - - - - - +
+ + + + - - - - - - - - - -
- - - - - - - - -
- -
-
- - - - - - - - - - - - - -
- -
-
+ + +
+
- - +
+ + + + + + + + +
+ +
+
+
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts index 59449e93..86815573 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/layout/layout.component.ts @@ -1,12 +1,8 @@ -import { AfterViewInit, Component, ContentChild, HostListener, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { MatSidenav } from '@angular/material/sidenav'; -import { skip, Subscription } from 'rxjs'; -import { SidenavMode } from '../../models/layout.model'; -import { LayoutService } from '../../services/layout/layout.service'; +import { AfterViewInit, Component, ContentChild, OnDestroy, OnInit, TemplateRef } from '@angular/core'; +import { Subscription } from 'rxjs'; import { ParticipantService } from '../../services/participant/participant.service'; -import { SidenavMenuService } from '../../services/sidenav-menu/sidenav-menu.service'; import { ParticipantAbstractModel } from '../../models/participant.model'; -import { MenuType } from '../../models/menu.model'; +import { LayoutService } from '../../services/layout/layout.service'; @Component({ selector: 'ov-layout', @@ -16,96 +12,28 @@ import { MenuType } from '../../models/menu.model'; export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit { @ContentChild('customLocalParticipant', { read: TemplateRef }) customLocalParticipantTemplate: TemplateRef; @ContentChild('customRemoteParticipants', { read: TemplateRef }) customRemoteParticipantsTemplate: TemplateRef; - @ContentChild('customMenuContent', { read: TemplateRef }) customMenuContentTemplate: TemplateRef; - @ContentChild('customLayoutElement', { read: TemplateRef }) customLayoutElementTemplate: TemplateRef; - showCustomParticipant = true; - sideMenu: MatSidenav; localParticipant: ParticipantAbstractModel; remoteParticipants: ParticipantAbstractModel[] = []; - sidenavMode: SidenavMode = SidenavMode.SIDE; - isParticipantsOpened: boolean; - isChatOpened: boolean; - protected readonly SIDENAV_WIDTH_LIMIT_MODE = 790; - protected menuSubscription: Subscription; - protected layoutWidthSubscription: Subscription; protected localParticipantSubs: Subscription; protected remoteParticipantsSubs: Subscription; protected updateLayoutInterval: NodeJS.Timer; - @HostListener('window:resize') - sizeChange() { - this.layoutService.update(); - } - - constructor( - protected participantService: ParticipantService, - protected layoutService: LayoutService, - protected menuService: SidenavMenuService - ) {} - - @ViewChild('sidenav') - set sidenavMenu(menu: MatSidenav) { - setTimeout(() => { - if (menu) { - this.sideMenu = menu; - this.subscribeToTogglingMenu(); - } - }, 0); - } + constructor(protected layoutService: LayoutService, protected participantService: ParticipantService) {} ngOnInit(): void { - this.layoutService.initialize(); - this.subscribeToLayoutWidth(); - this.subscribeToUsers(); } ngAfterViewInit() {} ngOnDestroy() { - this.layoutService.clear(); this.localParticipant = null; this.remoteParticipants = []; - this.isChatOpened = false; - this.isParticipantsOpened = false; - if (this.menuSubscription) this.menuSubscription.unsubscribe(); - if (this.layoutWidthSubscription) this.layoutWidthSubscription.unsubscribe(); if (this.localParticipantSubs) this.localParticipantSubs.unsubscribe(); if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe(); } - protected subscribeToTogglingMenu() { - this.sideMenu.openedChange.subscribe(() => { - if(this.updateLayoutInterval) { - clearInterval(this.updateLayoutInterval); - } - this.layoutService.update(); - }); - - this.sideMenu.openedStart.subscribe(() => { - this.updateLayoutInterval = setInterval(() => this.layoutService.update(), 50); - }); - - this.sideMenu.closedStart.subscribe(() => { - this.updateLayoutInterval = setInterval(() => this.layoutService.update(), 50); - }); - - this.menuSubscription = this.menuService.menuOpenedObs.pipe(skip(1)).subscribe((ev: { opened: boolean; type?: MenuType }) => { - if (this.sideMenu) { - this.isChatOpened = ev.opened && ev.type === MenuType.CHAT; - this.isParticipantsOpened = ev.opened && ev.type === MenuType.PARTICIPANTS; - ev.opened ? this.sideMenu.open() : this.sideMenu.close(); - } - }); - } - - protected subscribeToLayoutWidth() { - this.layoutWidthSubscription = this.layoutService.layoutWidthObs.subscribe((width) => { - this.sidenavMode = width <= this.SIDENAV_WIDTH_LIMIT_MODE ? SidenavMode.OVER : SidenavMode.SIDE; - }); - } - protected subscribeToUsers() { this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => { this.localParticipant = p; diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.css index 6ff3f795..b7eff885 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.css +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.css @@ -4,6 +4,36 @@ height: 100%; } +.sidenav-container { + position: relative; + height: calc(100% - 80px); + min-height: calc(100% - 80px); + padding-top: 10px; + width: 100%; + overflow: hidden; +} + +.sidenav-menu { + display: flex; + align-items: center; + justify-content: center; + width: 360px; + background-color: var(--ov-primary-color); + border-left: none; + position: absolute; +} + +.sidenav-main { + height: 100%; + overflow: hidden; + min-height: -webkit-fill-available; + min-height: -moz-available; +} + +.mat-drawer-container { + background-color: var(--ov-primary-color); +} + #toolbar-container, #footer-container { background-color: var(--ov-primary-color); min-width: 400px !important; @@ -24,11 +54,6 @@ } -#layout-container { - height: calc(100% - 80px); - padding-top: 10px; -} - .reconnecting-container{ width: 100%; diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.html index e879b998..85367ff7 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.html +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.html @@ -1,4 +1,34 @@
+ + + + + + + + + + + + + + + + + +
+ +
+
+
- -
- -
- -
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts index f11307d2..8aa833f4 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts @@ -1,4 +1,4 @@ -import { Component, ContentChild, EventEmitter, HostListener, Input, OnInit, Output, TemplateRef } from '@angular/core'; +import { Component, ContentChild, EventEmitter, HostListener, Input, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; import { Subscriber, Session, StreamEvent, StreamPropertyChangedEvent, SessionDisconnectedEvent, ConnectionEvent } from 'openvidu-browser'; import { VideoType } from '../../models/video-type.model'; @@ -12,6 +12,12 @@ import { PlatformService } from '../../services/platform/platform.service'; import { ActionService } from '../../services/action/action.service'; import { Signal } from '../../models/signal.model'; import { ParticipantService } from '../../services/participant/participant.service'; +import { MatSidenav } from '@angular/material/sidenav'; +import { SidenavMode } from '../../models/layout.model'; +import { LayoutService } from '../../services/layout/layout.service'; +import { Subscription, skip } from 'rxjs'; +import { MenuType } from '../../models/menu.model'; +import { SidenavMenuService } from '../../services/sidenav-menu/sidenav-menu.service'; @Component({ selector: 'ov-session', @@ -20,6 +26,9 @@ import { ParticipantService } from '../../services/participant/participant.servi }) export class SessionComponent implements OnInit { @ContentChild('toolbar', { read: TemplateRef }) toolbarTemplate: TemplateRef; + @ContentChild('customPanelContent', { read: TemplateRef }) customPanelContentTemplate: TemplateRef; + @ContentChild('customLayoutElement', { read: TemplateRef }) customLayoutElementTemplate: TemplateRef; + @Input() tokens: { webcam: string; screen: string }; @Output() _session = new EventEmitter(); @Output() _publisher = new EventEmitter(); @@ -27,6 +36,19 @@ export class SessionComponent implements OnInit { session: Session; sessionScreen: Session; + + sideMenu: MatSidenav; + + sidenavMode: SidenavMode = SidenavMode.SIDE; + isParticipantsPanelOpened: boolean; + isChatPanelOpened: boolean; + protected readonly SIDENAV_WIDTH_LIMIT_MODE = 790; + + protected menuSubscription: Subscription; + protected layoutWidthSubscription: Subscription; + + protected updateLayoutInterval: NodeJS.Timer; + protected log: ILogger; constructor( @@ -36,6 +58,9 @@ export class SessionComponent implements OnInit { protected loggerSrv: LoggerService, protected chatService: ChatService, protected tokenService: TokenService, + protected layoutService: LayoutService, + protected menuService: SidenavMenuService, + protected platformService: PlatformService ) { this.log = this.loggerSrv.get('SessionComponent'); @@ -46,7 +71,24 @@ export class SessionComponent implements OnInit { this.leaveSession(); } + @HostListener('window:resize') + sizeChange() { + this.layoutService.update(); + } + + @ViewChild('sidenav') + set sidenavMenu(menu: MatSidenav) { + setTimeout(() => { + if (menu) { + this.sideMenu = menu; + this.subscribeToTogglingMenu(); + } + }, 0); + } + async ngOnInit() { + this.layoutService.initialize(); + if (this.webrtcService.getWebcamSession() === null) { this.webrtcService.initialize(); await this.webrtcService.initDefaultPublisher(undefined); @@ -81,6 +123,11 @@ export class SessionComponent implements OnInit { this.participantService.clear(); this.session = null; this.sessionScreen = null; + this.layoutService.clear(); + this.isChatPanelOpened = false; + this.isParticipantsPanelOpened = false; + if (this.menuSubscription) this.menuSubscription.unsubscribe(); + if (this.layoutWidthSubscription) this.layoutWidthSubscription.unsubscribe(); } leaveSession() { @@ -88,6 +135,37 @@ export class SessionComponent implements OnInit { this.webrtcService.disconnect(); } + protected subscribeToTogglingMenu() { + this.sideMenu.openedChange.subscribe(() => { + if (this.updateLayoutInterval) { + clearInterval(this.updateLayoutInterval); + } + this.layoutService.update(); + }); + + this.sideMenu.openedStart.subscribe(() => { + this.updateLayoutInterval = setInterval(() => this.layoutService.update(), 50); + }); + + this.sideMenu.closedStart.subscribe(() => { + this.updateLayoutInterval = setInterval(() => this.layoutService.update(), 50); + }); + + this.menuSubscription = this.menuService.menuOpenedObs.pipe(skip(1)).subscribe((ev: { opened: boolean; type?: MenuType }) => { + if (this.sideMenu) { + this.isChatPanelOpened = ev.opened && ev.type === MenuType.CHAT; + this.isParticipantsPanelOpened = ev.opened && ev.type === MenuType.PARTICIPANTS; + ev.opened ? this.sideMenu.open() : this.sideMenu.close(); + } + }); + } + + protected subscribeToLayoutWidth() { + this.layoutWidthSubscription = this.layoutService.layoutWidthObs.subscribe((width) => { + this.sidenavMode = width <= this.SIDENAV_WIDTH_LIMIT_MODE ? SidenavMode.OVER : SidenavMode.SIDE; + }); + } + private async connectToSession(): Promise { try { if (this.participantService.areBothEnabled()) { @@ -117,7 +195,6 @@ export class SessionComponent implements OnInit { const isCameraConnection: boolean = !nickname?.includes(`_${VideoType.SCREEN}`); const data = event.connection?.data; - if (isRemoteConnection && isCameraConnection) { // Adding participant when connection is created and it's not screen this.participantService.addRemoteConnection(connectionId, data, null); @@ -167,7 +244,6 @@ export class SessionComponent implements OnInit { // this.session.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => { // const connectionId = event.stream.connection.connectionId; // const isRemoteConnection: boolean = !this.webrtcService.isMyOwnConnection(connectionId); - // if (isRemoteConnection) { // if (event.changedProperty === 'videoActive') { // // this.participantService.updateUsers();