diff --git a/openvidu-components-angular/package-lock.json b/openvidu-components-angular/package-lock.json
index aaeb7aa4..f2a7f0b7 100644
--- a/openvidu-components-angular/package-lock.json
+++ b/openvidu-components-angular/package-lock.json
@@ -20,6 +20,7 @@
"@angular/router": "13.0.0",
"autolinker": "3.14.3",
"buffer": "^6.0.3",
+ "ng-dynamic-component": "^10.1.0",
"openvidu-browser": "2.21.0-beta1",
"rxjs": "7.4.0",
"tslib": "2.3.1",
@@ -9065,6 +9066,19 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
+ "node_modules/ng-dynamic-component": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/ng-dynamic-component/-/ng-dynamic-component-10.1.0.tgz",
+ "integrity": "sha512-P3ejLAuezi/a7DfLk6SaqGUcDIhM8tfeNbJ3fAu2sPXgOOpHLPkEKw9nJc8C365B+fsZVX0B5GYuDX4pXa3GMQ==",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "@angular/common": "^12.0.0 || ^13.0.0",
+ "@angular/core": "^12.0.0 || ^13.0.0",
+ "rxjs": "^6.0.0 || ^7.0.0"
+ }
+ },
"node_modules/ng-packagr": {
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-13.0.3.tgz",
@@ -21901,6 +21915,14 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
+ "ng-dynamic-component": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/ng-dynamic-component/-/ng-dynamic-component-10.1.0.tgz",
+ "integrity": "sha512-P3ejLAuezi/a7DfLk6SaqGUcDIhM8tfeNbJ3fAu2sPXgOOpHLPkEKw9nJc8C365B+fsZVX0B5GYuDX4pXa3GMQ==",
+ "requires": {
+ "tslib": "^2.0.0"
+ }
+ },
"ng-packagr": {
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-13.0.3.tgz",
diff --git a/openvidu-components-angular/package.json b/openvidu-components-angular/package.json
index 7576d7b0..02c8207b 100644
--- a/openvidu-components-angular/package.json
+++ b/openvidu-components-angular/package.json
@@ -27,6 +27,7 @@
"@angular/router": "13.0.0",
"autolinker": "3.14.3",
"buffer": "^6.0.3",
+ "ng-dynamic-component": "10.1.0",
"openvidu-browser": "2.21.0-beta1",
"rxjs": "7.4.0",
"tslib": "2.3.1",
diff --git a/openvidu-components-angular/projects/openvidu-angular/package.json b/openvidu-components-angular/projects/openvidu-angular/package.json
index 1b2ff923..e4fb25f2 100644
--- a/openvidu-components-angular/projects/openvidu-angular/package.json
+++ b/openvidu-components-angular/projects/openvidu-angular/package.json
@@ -10,7 +10,8 @@
"@angular/flex-layout": "^13.0.0-beta.36",
"autolinker": "^3.14.3",
"buffer": "^6.0.3",
- "openvidu-browser": "^2.20.0"
+ "openvidu-browser": "^2.20.0",
+ "ng-dynamic-component": "^10.1.0"
},
"dependencies": {
"tslib": "^2.3.0"
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 db8e1767..3ac34cdd 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,35 +1,22 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
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 86815573..c27ed0b6 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,8 +1,11 @@
-import { AfterViewInit, Component, ContentChild, OnDestroy, OnInit, TemplateRef } from '@angular/core';
+import { AfterViewInit, Component, OnDestroy, OnInit, Type, ViewChild, ViewContainerRef } from '@angular/core';
import { Subscription } from 'rxjs';
import { ParticipantService } from '../../services/participant/participant.service';
import { ParticipantAbstractModel } from '../../models/participant.model';
import { LayoutService } from '../../services/layout/layout.service';
+import { LibraryComponents } from '../../config/lib.config';
+import { LibraryConfigService } from '../../services/library-config/library-config.service';
+import { StreamComponent } from '../stream/stream.component';
@Component({
selector: 'ov-layout',
@@ -10,8 +13,10 @@ import { LayoutService } from '../../services/layout/layout.service';
styleUrls: ['./layout.component.css']
})
export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
- @ContentChild('customLocalParticipant', { read: TemplateRef }) customLocalParticipantTemplate: TemplateRef;
- @ContentChild('customRemoteParticipants', { read: TemplateRef }) customRemoteParticipantsTemplate: TemplateRef;
+ _localStream: ViewContainerRef;
+ _localStreamComponent: Type;
+ _remoteStream: ViewContainerRef;
+ _remoteStreamComponent: Type;
localParticipant: ParticipantAbstractModel;
remoteParticipants: ParticipantAbstractModel[] = [];
@@ -19,10 +24,48 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
protected remoteParticipantsSubs: Subscription;
protected updateLayoutInterval: NodeJS.Timer;
- constructor(protected layoutService: LayoutService, protected participantService: ParticipantService) {}
+ constructor(
+ protected libraryConfigSrv: LibraryConfigService,
+ protected layoutService: LayoutService,
+ protected participantService: ParticipantService
+ ) {}
+
+ @ViewChild('localStream', { static: false, read: ViewContainerRef })
+ set stream(reference: ViewContainerRef) {
+ setTimeout(() => {
+ this._localStream = reference;
+
+ if (this._localStream) {
+ let component = StreamComponent;
+ if (this.libraryConfigSrv.isCustomComponentDefined(LibraryComponents.STREAM)) {
+ component = this.libraryConfigSrv.getCustomComponent(LibraryComponents.STREAM);
+ }
+ // this._stream?.clear();
+ this._localStreamComponent = component;
+ // this._stream.createComponent(component);
+ }
+ }, 0);
+ }
+
+ @ViewChild('remoteStream', { static: false, read: ViewContainerRef })
+ set remoteStream(reference: ViewContainerRef) {
+ setTimeout(() => {
+ this._remoteStream = reference;
+
+ if (this._remoteStream) {
+ let component = StreamComponent;
+ if (this.libraryConfigSrv.isCustomComponentDefined(LibraryComponents.STREAM)) {
+ component = this.libraryConfigSrv.getCustomComponent(LibraryComponents.STREAM);
+ }
+ // this.remoteStream?.clear();
+ this._remoteStreamComponent = component;
+ // this._stream.createComponent(component);
+ }
+ }, 0);
+ }
ngOnInit(): void {
- this.subscribeToUsers();
+ this.subscribeToParticipants();
}
ngAfterViewInit() {}
@@ -34,7 +77,7 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe();
}
- protected subscribeToUsers() {
+ protected subscribeToParticipants() {
this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => {
this.localParticipant = p;
this.layoutService.update();
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.css
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.css
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.css
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.html
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.html
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.html
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.spec.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.spec.ts
similarity index 82%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.spec.ts
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.spec.ts
index 8cc7ff68..0204558a 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.spec.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.spec.ts
@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { ChatService } from '../../services/chat/chat.service';
-import { ChatServiceMock } from '../../services/chat/chat.service.mock';
+import { ChatService } from '../../../services/chat/chat.service';
+import { ChatServiceMock } from '../../../services/chat/chat.service.mock';
import { ChatPanelComponent } from './chat-panel.component';
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.ts
similarity index 87%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.ts
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.ts
index 4182525d..a885dce2 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/chat-panel/chat-panel.component.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/chat-panel/chat-panel.component.ts
@@ -1,9 +1,9 @@
import { AfterViewInit, Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
import { Subscription } from 'rxjs';
-import { ChatMessage } from '../../models/chat.model';
-import { MenuType } from '../../models/menu.model';
-import { ChatService } from '../../services/chat/chat.service';
-import { SidenavMenuService } from '../../services/sidenav-menu/sidenav-menu.service';
+import { ChatMessage } from '../../../models/chat.model';
+import { MenuType } from '../../../models/menu.model';
+import { ChatService } from '../../../services/chat/chat.service';
+import { SidenavMenuService } from '../../../services/sidenav-menu/sidenav-menu.service';
@Component({
selector: 'ov-chat-panel',
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.css
new file mode 100644
index 00000000..e69de29b
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.html
new file mode 100644
index 00000000..4d33588b
--- /dev/null
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.html
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.spec.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.spec.ts
new file mode 100644
index 00000000..b0f6a9d7
--- /dev/null
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PanelComponent } from './panel.component';
+
+describe('PanelComponent', () => {
+ let component: PanelComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ PanelComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PanelComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.ts
new file mode 100644
index 00000000..af3393f6
--- /dev/null
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/panel.component.ts
@@ -0,0 +1,71 @@
+import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
+import { skip, Subscription } from 'rxjs';
+import { LibraryComponents } from '../../config/lib.config';
+import { MenuType } from '../../models/menu.model';
+import { LibraryConfigService } from '../../services/library-config/library-config.service';
+import { SidenavMenuService } from '../../services/sidenav-menu/sidenav-menu.service';
+import { ChatPanelComponent } from './chat-panel/chat-panel.component';
+import { ParticipantsPanelComponent } from './participants-panel/participants-panel/participants-panel.component';
+
+@Component({
+ selector: 'ov-panel',
+ templateUrl: './panel.component.html',
+ styleUrls: ['./panel.component.css']
+})
+export class PanelComponent implements OnInit, OnDestroy {
+ isParticipantsPanelOpened: boolean;
+ isChatPanelOpened: boolean;
+ _chat: ViewContainerRef;
+ _participants: ViewContainerRef;
+ menuSubscription: Subscription;
+
+ @ViewChild('chat', { static: false, read: ViewContainerRef })
+ set chat(reference: ViewContainerRef) {
+ setTimeout(() => {
+ this._chat = reference;
+
+ if (this._chat) {
+ let component = ChatPanelComponent;
+ if (this.libraryConfigSrv.isCustomComponentDefined(LibraryComponents.CHAT_PANEL)) {
+ component = this.libraryConfigSrv.getCustomComponent(LibraryComponents.CHAT_PANEL);
+ }
+ this._chat?.clear();
+ this._chat.createComponent(component);
+ }
+ }, 0);
+ }
+
+ @ViewChild('participants', { static: false, read: ViewContainerRef })
+ set participants(reference: ViewContainerRef) {
+ setTimeout(() => {
+ this._participants = reference;
+
+ if (this._participants) {
+ let component = ParticipantsPanelComponent;
+ if (this.libraryConfigSrv.isCustomComponentDefined(LibraryComponents.PARTICIPANTS_PANEL)) {
+ component = this.libraryConfigSrv.getCustomComponent(LibraryComponents.PARTICIPANTS_PANEL);
+ }
+ this._participants?.clear();
+ this._participants.createComponent(component);
+ }
+ }, 0);
+ }
+
+ constructor(protected libraryConfigSrv: LibraryConfigService, protected menuService: SidenavMenuService) {}
+
+ ngOnInit(): void {
+ this.subscribeToPanelToggling();
+ }
+ subscribeToPanelToggling() {
+ this.menuSubscription = this.menuService.menuOpenedObs.pipe(skip(1)).subscribe((ev: { opened: boolean; type?: MenuType }) => {
+ this.isChatPanelOpened = ev.opened && ev.type === MenuType.CHAT;
+ this.isParticipantsPanelOpened = ev.opened && ev.type === MenuType.PARTICIPANTS;
+ });
+ }
+
+ ngOnDestroy() {
+ this.isChatPanelOpened = false;
+ this.isParticipantsPanelOpened = false;
+ if (this.menuSubscription) this.menuSubscription.unsubscribe();
+ }
+}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.css
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.css
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.css
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.html
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.html
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.html
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.spec.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.spec.ts
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.spec.ts
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.spec.ts
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.ts
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participant-item/participant-item.component.ts
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participant-item/participant-item.component.ts
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.css
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.css
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.css
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.html
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.html
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.html
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.spec.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.spec.ts
similarity index 100%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.spec.ts
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.spec.ts
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.ts
similarity index 83%
rename from openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.ts
rename to openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.ts
index 07496acb..a84faf49 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/participants-panel/participants-panel/participants-panel.component.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/panel/participants-panel/participants-panel/participants-panel.component.ts
@@ -1,7 +1,7 @@
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
-import { ParticipantAbstractModel, ParticipantModel } from '../../../models/participant.model';
-import { ParticipantService } from '../../../services/participant/participant.service';
-import { SidenavMenuService } from '../../../services/sidenav-menu/sidenav-menu.service';
+import { ParticipantAbstractModel, ParticipantModel } from '../../../../models/participant.model';
+import { ParticipantService } from '../../../../services/participant/participant.service';
+import { SidenavMenuService } from '../../../../services/sidenav-menu/sidenav-menu.service';
@Component({
selector: 'ov-participants-panel',
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 85367ff7..d27b1a43 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
@@ -11,22 +11,30 @@
fixedBottomGap="0"
>
-
-
-
+
+
+
-
+
+
+
+
+
-
+
+
+
+
+
@@ -37,9 +45,11 @@
-->
-
+
+
+
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 8aa833f4..aced0154 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,15 @@
-import { Component, ContentChild, EventEmitter, HostListener, Input, OnInit, Output, TemplateRef, ViewChild } from '@angular/core';
+import {
+ Component,
+ ContentChild,
+ EventEmitter,
+ HostListener,
+ Input,
+ OnInit,
+ Output,
+ TemplateRef,
+ ViewChild,
+ ViewContainerRef
+} from '@angular/core';
import { Subscriber, Session, StreamEvent, StreamPropertyChangedEvent, SessionDisconnectedEvent, ConnectionEvent } from 'openvidu-browser';
import { VideoType } from '../../models/video-type.model';
@@ -8,7 +19,6 @@ import { ChatService } from '../../services/chat/chat.service';
import { LoggerService } from '../../services/logger/logger.service';
import { WebrtcService } from '../../services/webrtc/webrtc.service';
import { TokenService } from '../../services/token/token.service';
-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';
@@ -18,6 +28,11 @@ 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';
+import { ToolbarComponent } from '../toolbar/toolbar.component';
+import { LibraryConfigService } from '../../services/library-config/library-config.service';
+import { LayoutComponent } from '../layout/layout.component';
+import { PanelComponent } from '../panel/panel.component';
+import { LibraryComponents } from '../../config/lib.config';
@Component({
selector: 'ov-session',
@@ -25,14 +40,14 @@ import { SidenavMenuService } from '../../services/sidenav-menu/sidenav-menu.ser
styleUrls: ['./session.component.css']
})
export class SessionComponent implements OnInit {
- @ContentChild('toolbar', { read: TemplateRef }) toolbarTemplate: TemplateRef;
+ // @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();
- @Output() _error = new EventEmitter();
+ // @Output() _session = new EventEmitter();
+ // @Output() _publisher = new EventEmitter();
+ // @Output() _error = new EventEmitter();
session: Session;
sessionScreen: Session;
@@ -40,8 +55,7 @@ export class SessionComponent implements OnInit {
sideMenu: MatSidenav;
sidenavMode: SidenavMode = SidenavMode.SIDE;
- isParticipantsPanelOpened: boolean;
- isChatPanelOpened: boolean;
+
protected readonly SIDENAV_WIDTH_LIMIT_MODE = 790;
protected menuSubscription: Subscription;
@@ -51,6 +65,10 @@ export class SessionComponent implements OnInit {
protected log: ILogger;
+ _toolbar: ViewContainerRef;
+ _layout: ViewContainerRef;
+ _panel: ViewContainerRef;
+
constructor(
protected actionService: ActionService,
protected webrtcService: WebrtcService,
@@ -60,12 +78,63 @@ export class SessionComponent implements OnInit {
protected tokenService: TokenService,
protected layoutService: LayoutService,
protected menuService: SidenavMenuService,
-
- protected platformService: PlatformService
+ protected libraryConfigSrv: LibraryConfigService
) {
this.log = this.loggerSrv.get('SessionComponent');
}
+ @ViewChild('toolbar', { static: false, read: ViewContainerRef })
+ set toolbar(reference: ViewContainerRef) {
+ setTimeout(() => {
+ this._toolbar = reference;
+
+ if (this._toolbar) {
+ let component = ToolbarComponent;
+ // Inject the custom component if exists
+ if (this.libraryConfigSrv.isCustomComponentDefined(LibraryComponents.TOOLBAR)) {
+ component = this.libraryConfigSrv.getCustomComponent(LibraryComponents.TOOLBAR);
+ }
+ this._toolbar?.clear();
+ this._toolbar.createComponent(component);
+ }
+ }, 0);
+ }
+
+ @ViewChild('layout', { static: false, read: ViewContainerRef })
+ set layout(reference: ViewContainerRef) {
+ setTimeout(() => {
+ this._layout = reference;
+
+ if (this._layout) {
+ let component = LayoutComponent;
+ // Inject the custom component if exists
+ if (this.libraryConfigSrv.isCustomComponentDefined(LibraryComponents.LAYOUT)) {
+ component = this.libraryConfigSrv.getCustomComponent(LibraryComponents.LAYOUT);
+ }
+ this._layout?.clear();
+ this._layout.createComponent(component);
+ this.layoutService.initialize();
+ }
+ }, 0);
+ }
+
+ @ViewChild('panel', { static: false, read: ViewContainerRef })
+ set panel(reference: ViewContainerRef) {
+ setTimeout(() => {
+ this._panel = reference;
+
+ if (this._panel) {
+ let component = PanelComponent;
+ // Inject the custom component if exists
+ // if (this.libraryConfigSrv.isCustomComponentDefined(LibraryComponents.PANEL)) {
+ // component = this.libraryConfigSrv.getCustomComponent(LibraryComponents.PANEL);
+ // }
+ this._panel?.clear();
+ this._panel.createComponent(component);
+ }
+ }, 0);
+ }
+
@HostListener('window:beforeunload')
beforeunloadHandler() {
this.leaveSession();
@@ -87,8 +156,6 @@ export class SessionComponent implements OnInit {
}
async ngOnInit() {
- this.layoutService.initialize();
-
if (this.webrtcService.getWebcamSession() === null) {
this.webrtcService.initialize();
await this.webrtcService.initDefaultPublisher(undefined);
@@ -113,7 +180,7 @@ export class SessionComponent implements OnInit {
// this.webrtcService.publishVideo(this.localUserService.getMyCameraPublisher(), false);
// }
- this._session.emit(this.session);
+ // this._session.emit(this.session);
}
ngOnDestroy() {
@@ -124,8 +191,6 @@ export class SessionComponent implements OnInit {
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();
}
@@ -152,11 +217,7 @@ export class SessionComponent implements OnInit {
});
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();
- }
+ this.sideMenu && ev.opened ? this.sideMenu.open() : this.sideMenu.close();
});
}
@@ -181,7 +242,7 @@ export class SessionComponent implements OnInit {
await this.webrtcService.publish(this.participantService.getMyCameraPublisher());
}
} catch (error) {
- this._error.emit({ error: error.error, messgae: error.message, code: error.code, status: error.status });
+ // this._error.emit({ error: error.error, messgae: error.message, code: error.code, status: error.status });
this.log.e('There was an error connecting to the session:', error.code, error.message);
this.actionService.openDialog('There was an error connecting to the session:', error?.error || error?.message);
}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts
index 1e4dac9f..1cfa1afe 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/stream/stream.component.ts
@@ -52,16 +52,10 @@ export class StreamComponent implements OnInit {
// this.isFullscreenEnabled = !this.isFullscreenEnabled;
// }
- // Has been mandatory fullscreen Input because of Input user did not fire changing
- // the fullscreen user property in publisherStartSpeaking event in SessionComponent
- @Input()
- set videoEnlarged(enlarged: boolean) {
- this.checkVideoSizeBigIcon(enlarged);
- }
-
@Input()
set participant(participant: StreamModel) {
this._participant = participant;
+ this.checkVideoSizeBigIcon(this._participant.videoEnlarged);
this.nicknameFormControl = new FormControl(this._participant.nickname, [Validators.maxLength(25), Validators.required]);
}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.css b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.css
index 4c7809f9..60df9c8b 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.css
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.css
@@ -1,5 +1,5 @@
#toolbar {
- height: 100%;
+ /* height: 100%; */
background-color: transparent;
color: var(--ov-light-color);
}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts
index 6d8d0372..52502895 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/toolbar/toolbar.component.ts
@@ -1,4 +1,15 @@
-import { Component, ContentChild, EventEmitter, HostListener, OnDestroy, OnInit, Output, TemplateRef } from '@angular/core';
+import {
+ AfterViewInit,
+ Component,
+ ContentChild,
+ EventEmitter,
+ HostListener,
+ OnDestroy,
+ OnInit,
+ Output,
+ TemplateRef,
+ ViewChild
+} from '@angular/core';
import { skip, Subscription } from 'rxjs';
import { TokenService } from '../../services/token/token.service';
import { ChatService } from '../../services/chat/chat.service';
@@ -103,10 +114,8 @@ export class ToolbarComponent implements OnInit, OnDestroy {
this.subscribeToUserMediaProperties();
this.subscribeToReconnection();
- if(!this.libraryConfigSrv.isUsingProLibrary()){
- this.subscribeToMenuToggling();
- this.subscribeToChatMessages();
- }
+ this.subscribeToMenuToggling();
+ this.subscribeToChatMessages();
}
toggleMicrophone() {
@@ -268,7 +277,7 @@ export class ToolbarComponent implements OnInit, OnDestroy {
});
}
protected subscribeToMenuToggling() {
- this.menuTogglingSubscription = this.menuService.menuOpenedObs.subscribe((ev: {opened: boolean, type?: MenuType}) => {
+ this.menuTogglingSubscription = this.menuService.menuOpenedObs.subscribe((ev: { opened: boolean; type?: MenuType }) => {
this.isChatOpened = ev.opened && ev.type === MenuType.CHAT;
this.isParticipantsOpened = ev.opened && ev.type === MenuType.PARTICIPANTS;
if (this.isChatOpened) {
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.html b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.html
index 20e6bc43..655bfc34 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.html
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.html
@@ -1,6 +1,6 @@
-
+
@@ -10,21 +10,23 @@
error
- {{errorMessage}}
+ {{ errorMessage }}
-
-
+
+
+
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts
index f51d6949..ec918c9c 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/videoconference/videoconference.component.ts
@@ -1,17 +1,31 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { RestService } from '../../services/rest/rest.service';
+import {
+ Component,
+ Input,
+ OnInit,
+ Output,
+ EventEmitter,
+ ViewChild,
+ ChangeDetectorRef,
+ AfterViewInit,
+ ViewContainerRef
+} from '@angular/core';
+import { LibraryConfigService } from '../../services/library-config/library-config.service';
+import { ToolbarComponent } from '../toolbar/toolbar.component';
@Component({
selector: 'ov-videoconference',
templateUrl: './videoconference.component.html',
styleUrls: ['./videoconference.component.css']
})
-export class VideoconferenceComponent implements OnInit {
+export class VideoconferenceComponent implements OnInit, AfterViewInit {
@Input() sessionName: string;
@Input() userName: string;
@Input() openviduServerUrl: string;
@Input() openviduSecret: string;
- @Input() tokens: { webcam: string; screen: string };
+ // @Input() tokens: { webcam: string; screen: string };
+
+ @Output() onJoinClicked = new EventEmitter
();
+ @Output() onCloseClicked = new EventEmitter();
joinSessionClicked: boolean = false;
closeClicked: boolean = false;
@@ -20,42 +34,91 @@ export class VideoconferenceComponent implements OnInit {
error: boolean = false;
errorMessage: string = '';
- constructor(private restService: RestService) {}
+ _toolbar: ViewContainerRef;
- ngOnInit() {}
+ constructor(protected libraryConfigSrv: LibraryConfigService, private cd: ChangeDetectorRef) {}
- async onJoinClicked() {
- if (!this.tokens || (!this.tokens?.webcam && !this.tokens?.screen)) {
- //No tokens received
+ // @ViewChild('toolbar', { static: false, read: ViewContainerRef })
+ // set toolbar(reference: ViewContainerRef) {
+ // setTimeout(() => {
+ // console.log('setting ref', reference);
+ // this._toolbar = reference;
- if (!!this.sessionName && !!this.openviduServerUrl && !!this.openviduSecret) {
- // Generate tokens
- this._tokens = {
- webcam: await this.restService.getToken(this.sessionName, this.openviduServerUrl, this.openviduSecret),
- screen: await this.restService.getToken(this.sessionName, this.openviduServerUrl, this.openviduSecret)
- };
- } else {
- // No tokens received and can't generate them
- this.error = true;
- this.errorMessage = `Cannot access to OpenVidu Server with url '${this.openviduServerUrl}' to genere tokens for session '${this.sessionName}'`;
- throw this.errorMessage;
- }
- } else if (!this.tokens?.webcam || !this.tokens?.screen) {
+ // if (this._toolbar) {
+ // let component = ToolbarComponent;
+ // if (this.libraryConfigSrv.isCustomComponentDefined('ov-toolbar')) {
+ // component = this.libraryConfigSrv.getToolbarComponent();
+ // }
+ // this._toolbar?.clear();
+ // this._toolbar.createComponent(component);
+ // }
+ // }, 100);
+ // }
+
+ ngAfterViewInit() {
+ // if(this.customToolbar && this.libraryConfigSrv.isCustomComponentDefined('ov-toolbar')){
+ // const viewContainerRef = this.customToolbar.viewContainerRef;
+ // viewContainerRef.clear();
+ // const componentRef = viewContainerRef.createComponent(this.libraryConfigSrv.getToolbarComponent());
+ // } else {
+ // this.customToolbar.viewContainerRef.clear();
+ // const viewContainerRef = this.toolbar.viewContainerRef;
+ // viewContainerRef.clear();
+ // viewContainerRef.createComponent(ToolbarComponent);
+ // }
+ }
+
+ ngOnInit() {
+ }
+
+ @Input('tokens')
+ set tokens(tokens: { webcam: string; screen: string }) {
+ if (!!tokens?.webcam || !!this.tokens?.screen) {
// 1 token received
- const aditionalToken = await this.restService.getToken(this.sessionName, this.openviduServerUrl, this.openviduSecret);
- this._tokens = {
- webcam: !!this.tokens.webcam ? this.tokens.webcam : aditionalToken,
- screen: !!this.tokens.screen ? this.tokens.screen : aditionalToken
- };
+ this.cd.detectChanges();
+ // this.cd.markForCheck();
+ this._tokens = tokens;
+ this.joinSessionClicked = true;
+ this.isSessionAlive = true;
} else {
- // 2 tokens received.
- this._tokens = {
- webcam: this.tokens.webcam,
- screen: this.tokens.screen
- };
+ //No tokens received
+ throw new Error('No tokens received');
}
- this.joinSessionClicked = true;
- this.isSessionAlive = true;
+ }
+
+ async _onJoinClicked() {
+ this.onJoinClicked.emit();
+ // if (!this.tokens || (!this.tokens?.webcam && !this.tokens?.screen)) {
+ // //No tokens received
+
+ // if (!!this.sessionName && !!this.openviduServerUrl && !!this.openviduSecret) {
+ // // Generate tokens
+ // this._tokens = {
+ // webcam: await this.restService.getToken(this.sessionName, this.openviduServerUrl, this.openviduSecret),
+ // screen: await this.restService.getToken(this.sessionName, this.openviduServerUrl, this.openviduSecret)
+ // };
+ // } else {
+ // // No tokens received and can't generate them
+ // this.error = true;
+ // this.errorMessage = `Cannot access to OpenVidu Server with url '${this.openviduServerUrl}' to genere tokens for session '${this.sessionName}'`;
+ // throw this.errorMessage;
+ // }
+ // } else if (!this.tokens?.webcam || !this.tokens?.screen) {
+ // // 1 token received
+ // const aditionalToken = await this.restService.getToken(this.sessionName, this.openviduServerUrl, this.openviduSecret);
+ // this._tokens = {
+ // webcam: !!this.tokens.webcam ? this.tokens.webcam : aditionalToken,
+ // screen: !!this.tokens.screen ? this.tokens.screen : aditionalToken
+ // };
+ // } else {
+ // // 2 tokens received.
+ // this._tokens = {
+ // webcam: this.tokens.webcam,
+ // screen: this.tokens.screen
+ // };
+ // }
+ // this.joinSessionClicked = true;
+ // this.isSessionAlive = true;
}
onLeaveSessionClicked() {
this.isSessionAlive = false;
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/config/lib.config.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/config/lib.config.ts
index 5c9f3fdc..084f1b8d 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/config/lib.config.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/config/lib.config.ts
@@ -1,6 +1,19 @@
+import { Type } from '@angular/core';
+
export interface LibConfig {
environment: {
production: boolean;
- useProdLibrary?: boolean
+ useProdLibrary?: boolean;
+ customComponents?: { LibraryComponents: Type };
};
}
+
+
+export enum LibraryComponents {
+ TOOLBAR = 'ov-toolbar',
+ LAYOUT = 'ov-layout',
+ PANEL = 'ov-panel',
+ CHAT_PANEL = 'ov-chat-panel',
+ PARTICIPANTS_PANEL = 'ov-participants-panel',
+ STREAM = "ov-stream"
+}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts
index 6885fe47..4cfb4445 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/openvidu-angular.module.ts
@@ -29,7 +29,7 @@ import { HttpClientModule } from '@angular/common/http';
import { UserSettingsComponent } from './components/user-settings/user-settings.component';
import { ToolbarComponent } from './components/toolbar/toolbar.component';
import { VideoComponent } from './components/video/video.component';
-import { ChatPanelComponent } from './components/chat-panel/chat-panel.component';
+import { ChatPanelComponent } from './components/panel/chat-panel/chat-panel.component';
import { SessionComponent } from './components/session/session.component';
import { LayoutComponent } from './components/layout/layout.component';
import { StreamComponent } from './components/stream/stream.component';
@@ -54,9 +54,14 @@ import { DocumentService } from './services/document/document.service';
import { LayoutService } from './services/layout/layout.service';
import { SidenavMenuService } from './services/sidenav-menu/sidenav-menu.service';
import { ParticipantService } from './services/participant/participant.service';
-import { ParticipantItemComponent } from './components/participants-panel/participant-item/participant-item.component';
-import { ParticipantsPanelComponent } from './components/participants-panel/participants-panel/participants-panel.component';
+import { ParticipantItemComponent } from './components/panel/participants-panel/participant-item/participant-item.component';
+import { ParticipantsPanelComponent } from './components/panel/participants-panel/participants-panel/participants-panel.component';
import { VideoconferenceComponent } from './components/videoconference/videoconference.component';
+import { PanelComponent } from './components/panel/panel.component';
+
+// Used for loading dynamic components because of Inputs and Outputs are not supported in the official Angular way
+// https://github.com/angular/angular/issues/15360
+import { DynamicIoModule } from 'ng-dynamic-component';
@NgModule({
declarations: [
@@ -75,7 +80,8 @@ import { VideoconferenceComponent } from './components/videoconference/videoconf
NicknamePipe,
ParticipantItemComponent,
ParticipantsPanelComponent,
- VideoconferenceComponent
+ VideoconferenceComponent,
+ PanelComponent,
],
imports: [
CommonModule,
@@ -102,7 +108,8 @@ import { VideoconferenceComponent } from './components/videoconference/videoconf
FlexLayoutModule,
MatMenuModule,
MatDividerModule,
- MatListModule
+ MatListModule,
+ DynamicIoModule
],
providers: [
ActionService,
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/library-config/library-config.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/library-config/library-config.service.ts
index 51c28a4b..d6b81fae 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/library-config/library-config.service.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/library-config/library-config.service.ts
@@ -5,12 +5,12 @@ import { LibConfig } from '../../config/lib.config';
@Injectable()
export class LibraryConfigService {
+
private configuration: LibConfig;
constructor(@Inject('LIB_CONFIG') config: LibConfig) {
this.configuration = config;
console.log(this.configuration);
- this.isUsingProLibrary() ? console.log('Using PRO library') : console.log('Using CE library');
if(this.isProduction()) console.log('Production Mode');
// console.log(version)
}
@@ -22,7 +22,11 @@ export class LibraryConfigService {
return this.configuration?.environment?.production;
}
- isUsingProLibrary(): boolean {
- return !!this.configuration?.environment?.useProdLibrary;
+ isCustomComponentDefined(component: string): boolean {
+ return !!this.configuration?.environment?.customComponents && !!this.configuration.environment.customComponents[component];
+ }
+
+ getCustomComponent(component: string){
+ return this.configuration.environment.customComponents[component];
}
}
diff --git a/openvidu-components-angular/projects/openvidu-angular/src/public-api.ts b/openvidu-components-angular/projects/openvidu-angular/src/public-api.ts
index 143daa78..d7fef6a0 100644
--- a/openvidu-components-angular/projects/openvidu-angular/src/public-api.ts
+++ b/openvidu-components-angular/projects/openvidu-angular/src/public-api.ts
@@ -24,8 +24,8 @@ export * from './lib/services/storage/storage.service';
export * from './lib/components/videoconference/videoconference.component';
export * from './lib/components/user-settings/user-settings.component';
export * from './lib/components/toolbar/toolbar.component';
-export * from './lib/components/chat-panel/chat-panel.component';
-export * from './lib/components/participants-panel/participants-panel/participants-panel.component';
+export * from './lib/components/panel/chat-panel/chat-panel.component';
+export * from './lib/components/panel/participants-panel/participants-panel/participants-panel.component';
export * from './lib/components/session/session.component';
export * from './lib/components/layout/layout.component';
export * from './lib/components/stream/stream.component';