mirror of https://github.com/OpenVidu/openvidu.git
openvidu-components: Updated the dynamic components injection
Allowed the custom components injection from the view instead of the config file.pull/707/head
parent
bfd21ecd1e
commit
00087a7dc7
|
@ -1,35 +1,23 @@
|
|||
<div id="layout" class="bounds">
|
||||
<!-- Custom local participant -->
|
||||
<ng-container *ngIf="customLocalParticipantTemplate; else defaultLocalParticipant">
|
||||
<ng-container *ngTemplateOutlet="customLocalParticipantTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Default local participant if custom participant is not injected -->
|
||||
<ng-template #defaultLocalParticipant>
|
||||
<div
|
||||
class="OT_root OT_publisher"
|
||||
id="localUser"
|
||||
*ngFor="let connection of localParticipant | connections"
|
||||
[ngClass]="{ OV_small: !connection.streamManager?.stream?.videoActive }"
|
||||
>
|
||||
<ov-stream [participant]="connection" [videoEnlarged]="connection.videoEnlarged"></ov-stream>
|
||||
<ng-container *ngTemplateOutlet="streamTemplate; context: { stream: connection }"></ng-container>
|
||||
</div>
|
||||
</ng-template>
|
||||
<!-- <ng-template #stream let-stream="stream">
|
||||
<p>{{prueba.videoEnlarged}}</p>
|
||||
<ov-stream [participant]="prueba"></ov-stream>
|
||||
</ng-template> -->
|
||||
|
||||
<!-- Custom remote participant -->
|
||||
<ng-container *ngIf="customRemoteParticipantsTemplate; else defaultRemoteParticipants">
|
||||
<ng-container *ngTemplateOutlet="customRemoteParticipantsTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Default remote participants if custom participants is not injected -->
|
||||
<ng-template #defaultRemoteParticipants>
|
||||
<div
|
||||
*ngFor="let connection of remoteParticipants | connections"
|
||||
class="OT_root OT_publisher"
|
||||
id="remote-participant"
|
||||
[ngClass]="{ OV_small: !connection.streamManager?.stream?.videoActive }"
|
||||
>
|
||||
<ov-stream [participant]="connection" [videoEnlarged]="connection.videoEnlarged"></ov-stream>
|
||||
<ng-container *ngTemplateOutlet="streamTemplate; context: { stream: connection }"></ng-container>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AfterViewInit, Component, ContentChild, OnDestroy, OnInit, TemplateRef } from '@angular/core';
|
||||
import { AfterViewInit, Component, ComponentRef, ContentChild, Directive, Input, OnDestroy, OnInit, TemplateRef, Type, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { ParticipantService } from '../../services/participant/participant.service';
|
||||
import { ParticipantAbstractModel } from '../../models/participant.model';
|
||||
|
@ -10,8 +10,13 @@ import { LayoutService } from '../../services/layout/layout.service';
|
|||
styleUrls: ['./layout.component.css']
|
||||
})
|
||||
export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
@ContentChild('customLocalParticipant', { read: TemplateRef }) customLocalParticipantTemplate: TemplateRef<any>;
|
||||
@ContentChild('customRemoteParticipants', { read: TemplateRef }) customRemoteParticipantsTemplate: TemplateRef<any>;
|
||||
// @ContentChild('customLocalParticipant', { read: TemplateRef }) customLocalParticipantTemplate: TemplateRef<any>;
|
||||
// @ContentChild('customRemoteParticipants', { read: TemplateRef }) customRemoteParticipantsTemplate: TemplateRef<any>;
|
||||
|
||||
@ContentChild('stream', { read: TemplateRef }) streamTemplate: TemplateRef<any>;
|
||||
|
||||
|
||||
|
||||
|
||||
localParticipant: ParticipantAbstractModel;
|
||||
remoteParticipants: ParticipantAbstractModel[] = [];
|
||||
|
@ -22,6 +27,8 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
constructor(protected layoutService: LayoutService, protected participantService: ParticipantService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.layoutService.initialize();
|
||||
|
||||
this.subscribeToUsers();
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
<p>panel works!</p>
|
||||
<!-- Custom chat panel -->
|
||||
<ng-container *ngIf="chatPanelTemplate && isChatPanelOpened">
|
||||
<ng-container *ngTemplateOutlet="chatPanelTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Custom participants panel -->
|
||||
<ng-container *ngIf="participantsPanelTemplate && isParticipantsPanelOpened">
|
||||
<ng-container *ngTemplateOutlet="participantsPanelTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, ContentChild, OnInit, TemplateRef } from '@angular/core';
|
||||
import { skip, Subscription } from 'rxjs';
|
||||
import { MenuType } from '../../models/menu.model';
|
||||
import { SidenavMenuService } from '../../services/sidenav-menu/sidenav-menu.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ov-panel',
|
||||
|
@ -6,10 +9,27 @@ import { Component, OnInit } from '@angular/core';
|
|||
styleUrls: ['./panel.component.css']
|
||||
})
|
||||
export class PanelComponent implements OnInit {
|
||||
@ContentChild('participantsPanel', { read: TemplateRef }) participantsPanelTemplate: TemplateRef<any>;
|
||||
@ContentChild('chatPanel', { read: TemplateRef }) chatPanelTemplate: TemplateRef<any>;
|
||||
|
||||
constructor() { }
|
||||
isParticipantsPanelOpened: boolean;
|
||||
isChatPanelOpened: boolean;
|
||||
menuSubscription: Subscription;
|
||||
constructor(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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<div id="session-container">
|
||||
<mat-sidenav-container class="sidenav-container">
|
||||
<!-- OPENVIDU PANELS -->
|
||||
<mat-sidenav
|
||||
#sidenav
|
||||
mode="{{ sidenavMode }}"
|
||||
|
@ -10,33 +9,23 @@
|
|||
fixedTopGap="0"
|
||||
fixedBottomGap="0"
|
||||
>
|
||||
<!-- Custom menu content -->
|
||||
<ng-container *ngIf="customPanelContentTemplate; else defaultPanelContent">
|
||||
<ng-container *ngTemplateOutlet="customPanelContentTemplate"></ng-container>
|
||||
<!-- OPENVIDU PANEL -->
|
||||
<ng-container *ngIf="panelTemplate">
|
||||
<ng-container *ngTemplateOutlet="panelTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Default menu content if custom menu content is not injected -->
|
||||
<ng-template #defaultPanelContent>
|
||||
<ov-chat-panel *ngIf="isChatPanelOpened"></ov-chat-panel>
|
||||
<ov-participants-panel *ngIf="isParticipantsPanelOpened"></ov-participants-panel>
|
||||
</ng-template>
|
||||
</mat-sidenav>
|
||||
|
||||
<!-- OPENVIDU LAYOUT -->
|
||||
<mat-sidenav-content class="sidenav-main">
|
||||
<ng-container *ngIf="layoutTemplate">
|
||||
<div id="layout-container">
|
||||
<ng-content select="[layout]"></ng-content>
|
||||
<ng-container *ngTemplateOutlet="layoutTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
||||
<!-- Custom toolbar -->
|
||||
<!-- <ng-container *ngIf="toolbarTemplate">
|
||||
<div id="toolbar-container">
|
||||
<ng-container *ngTemplateOutlet="toolbarTemplate"></ng-container>
|
||||
</div>
|
||||
</ng-container> -->
|
||||
|
||||
<!-- OPENVIDU TOOLBAR -->
|
||||
<ng-container *ngIf="toolbarTemplate">
|
||||
<div id="footer-container">
|
||||
<ng-container *ngTemplateOutlet="toolbarTemplate"></ng-container>
|
||||
|
|
|
@ -26,8 +26,8 @@ import { SidenavMenuService } from '../../services/sidenav-menu/sidenav-menu.ser
|
|||
})
|
||||
export class SessionComponent implements OnInit {
|
||||
@ContentChild('toolbar', { read: TemplateRef }) toolbarTemplate: TemplateRef<any>;
|
||||
@ContentChild('customPanelContent', { read: TemplateRef }) customPanelContentTemplate: TemplateRef<any>;
|
||||
@ContentChild('customLayoutElement', { read: TemplateRef }) customLayoutElementTemplate: TemplateRef<any>;
|
||||
@ContentChild('layout', { read: TemplateRef }) layoutTemplate: TemplateRef<any>;
|
||||
@ContentChild('panel', { read: TemplateRef }) panelTemplate: TemplateRef<any>;
|
||||
|
||||
@Input() tokens: { webcam: string; screen: string };
|
||||
@Output() _session = new EventEmitter<any>();
|
||||
|
@ -87,7 +87,7 @@ export class SessionComponent implements OnInit {
|
|||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.layoutService.initialize();
|
||||
// this.layoutService.initialize();
|
||||
|
||||
if (this.webrtcService.getWebcamSession() === null) {
|
||||
this.webrtcService.initialize();
|
||||
|
|
|
@ -52,16 +52,11 @@ 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(participant.videoEnlarged);
|
||||
this.nicknameFormControl = new FormControl(this._participant.nickname, [Validators.maxLength(25), Validators.required]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div id="call-container">
|
||||
<div id="user-settings-container" *ngIf="!joinSessionClicked && !closeClicked">
|
||||
<ov-user-settings (onJoinClicked)="onJoinClicked()" (onCloseClicked)="onLeaveSessionClicked()"></ov-user-settings>
|
||||
<ov-user-settings (onJoinClicked)="_onJoinClicked()" (onCloseClicked)="onLeaveSessionClicked()"></ov-user-settings>
|
||||
</div>
|
||||
|
||||
<div id="spinner" *ngIf="joinSessionClicked && !isSessionAlive && !error">
|
||||
|
@ -15,16 +15,83 @@
|
|||
|
||||
<div id="session-container" *ngIf="joinSessionClicked && isSessionAlive && !error">
|
||||
<ov-session [tokens]="_tokens">
|
||||
|
||||
<!-- Toolbar container injection -->
|
||||
<ng-template #toolbar>
|
||||
<ov-toolbar
|
||||
(onCamClicked)="onCamClicked()"
|
||||
(onMicClicked)="onMicClicked()"
|
||||
(onScreenShareClicked)="onScreenShareClicked()"
|
||||
(onSpeakerLayoutClicked)="onSpeakerLayoutClicked()"
|
||||
(onLeaveSessionClicked)="onLeaveSessionClicked()"
|
||||
></ov-toolbar>
|
||||
<!-- Custom toolbar -->
|
||||
<ng-container *ngIf="toolbarTemplate; else defaultToolbar">
|
||||
<ng-container *ngTemplateOutlet="toolbarTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Default toolbar if custom toolbar is not injected -->
|
||||
<ng-template #defaultToolbar>
|
||||
<ov-toolbar></ov-toolbar>
|
||||
</ng-template>
|
||||
<ov-layout layout></ov-layout>
|
||||
|
||||
</ng-template>
|
||||
|
||||
<ng-template #panel>
|
||||
<!-- Custom panel -->
|
||||
<ng-container *ngIf="panelTemplate; else defaultPanel">
|
||||
<ng-container *ngTemplateOutlet="panelTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Default panel if custom panel is not injected -->
|
||||
<ng-template #defaultPanel>
|
||||
<ov-panel>
|
||||
<!-- CHAT panel -->
|
||||
<ng-template #chatPanel>
|
||||
<ng-container *ngIf="chatPanelTemplate; else defaultChatPanel">
|
||||
<ng-container *ngTemplateOutlet="chatPanelTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #defaultChatPanel>
|
||||
<ov-chat-panel></ov-chat-panel>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
||||
<!-- PARTICIPANTS panel -->
|
||||
<ng-template #participantsPanel>
|
||||
<ng-container *ngIf="participantsPanelTemplate; else defaultParticipantsPanel">
|
||||
<ng-container *ngTemplateOutlet="participantsPanelTemplate"></ng-container>
|
||||
</ng-container>
|
||||
<ng-template #defaultParticipantsPanel>
|
||||
<ov-participants-panel></ov-participants-panel>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</ov-panel>
|
||||
</ng-template>
|
||||
|
||||
</ng-template>
|
||||
|
||||
|
||||
<!-- Layout container injection -->
|
||||
<ng-template #layout>
|
||||
<!-- Custom layout -->
|
||||
<ng-container *ngIf="layoutTemplate; else defaultLayout">
|
||||
<ng-container *ngTemplateOutlet="layoutTemplate"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Default layout if custom layout is not injected -->
|
||||
<ng-template #defaultLayout>
|
||||
<ov-layout>
|
||||
<ng-template #stream let-stream="stream">
|
||||
<!-- Custom stream component -->
|
||||
<!-- We must to bind a context for the 'participant' input property -->
|
||||
<ng-container *ngIf="streamTemplate; else defaultStream">
|
||||
<ng-container *ngTemplateOutlet="streamTemplate;context:{stream:stream}"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Default stream component if custom component is not injected -->
|
||||
<!-- We must to bind a context for the 'participant' input property -->
|
||||
<ng-template #defaultStream>
|
||||
<ov-stream [participant]="stream"></ov-stream>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</ov-layout>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
||||
</ov-session>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, ContentChild, EventEmitter, Input, OnInit, Output, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { RestService } from '../../services/rest/rest.service';
|
||||
|
||||
@Component({
|
||||
|
@ -7,12 +7,22 @@ import { RestService } from '../../services/rest/rest.service';
|
|||
styleUrls: ['./videoconference.component.css']
|
||||
})
|
||||
export class VideoconferenceComponent implements OnInit {
|
||||
@ContentChild('toolbar', { read: TemplateRef }) toolbarTemplate: TemplateRef<any>;
|
||||
@ContentChild('layout', { read: TemplateRef }) layoutTemplate: TemplateRef<any>;
|
||||
@ContentChild('panel', { read: TemplateRef }) panelTemplate: TemplateRef<any>;
|
||||
@ContentChild('chatPanel', { read: TemplateRef }) chatPanelTemplate: TemplateRef<any>;
|
||||
@ContentChild('participantsPanel', { read: TemplateRef }) participantsPanelTemplate: TemplateRef<any>;
|
||||
@ContentChild('stream', { read: TemplateRef }) streamTemplate: TemplateRef<any>;
|
||||
|
||||
@Input() sessionName: string;
|
||||
@Input() userName: string;
|
||||
@Input() openviduServerUrl: string;
|
||||
@Input() openviduSecret: string;
|
||||
@Input() tokens: { webcam: string; screen: string };
|
||||
|
||||
@Output() onJoinClicked = new EventEmitter<any>();
|
||||
@Output() onCloseClicked = new EventEmitter<any>();
|
||||
|
||||
joinSessionClicked: boolean = false;
|
||||
closeClicked: boolean = false;
|
||||
isSessionAlive: boolean = false;
|
||||
|
@ -24,36 +34,38 @@ export class VideoconferenceComponent implements OnInit {
|
|||
|
||||
ngOnInit() {}
|
||||
|
||||
async onJoinClicked() {
|
||||
if (!this.tokens || (!this.tokens?.webcam && !this.tokens?.screen)) {
|
||||
//No tokens received
|
||||
async _onJoinClicked() {
|
||||
|
||||
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.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;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div id="call-container">
|
||||
<!-- <div id="call-container">
|
||||
<div id="userSettings" *ngIf="!joinSessionClicked && !closeClicked || !isSessionAlive">
|
||||
<ov-user-settings (onJoinClicked)="onJoinClicked()" (onCloseClicked)="onCloseClicked()"></ov-user-settings>
|
||||
</div>
|
||||
|
@ -17,4 +17,39 @@
|
|||
<ov-layout layout></ov-layout>
|
||||
</ov-session>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<ov-videoconference (onJoinClicked)="onJoinClicked()" [tokens]="tokens">
|
||||
|
||||
<!-- <ng-template #toolbar>
|
||||
<ov-toolbar postion="top" (onCamClicked)="onCamClicked()"></ov-toolbar>
|
||||
</ng-template> -->
|
||||
|
||||
<!-- <ng-template #layout>
|
||||
<ov-toolbar postion="top" (onCamClicked)="onCamClicked()"></ov-toolbar>
|
||||
</ng-template> -->
|
||||
|
||||
|
||||
<!-- <ng-template #panel>
|
||||
<ov-toolbar postion="top" (onCamClicked)="onCamClicked()"></ov-toolbar>
|
||||
</ng-template> -->
|
||||
|
||||
<!-- <ng-template #chatPanel>
|
||||
<ov-toolbar postion="top" (onCamClicked)="onCamClicked()"></ov-toolbar>
|
||||
</ng-template> -->
|
||||
|
||||
<!-- <ng-template #participantsPanel>
|
||||
<ov-toolbar postion="top" (onCamClicked)="onCamClicked()"></ov-toolbar>
|
||||
</ng-template> -->
|
||||
|
||||
<!-- <ng-template #stream let-stream="stream">
|
||||
|
||||
<ov-stream postion="top" [participant]="stream">
|
||||
<button network-quality> hola</button>
|
||||
</ov-stream>
|
||||
|
||||
</ng-template> -->
|
||||
|
||||
|
||||
|
||||
</ov-videoconference>
|
||||
|
|
|
@ -37,7 +37,9 @@ export class CallComponent implements OnInit {
|
|||
|
||||
onMicClicked() {}
|
||||
|
||||
onCamClicked() {}
|
||||
onCamClicked() {
|
||||
console.log('APP: CAM CLIKED')
|
||||
}
|
||||
|
||||
onScreenShareClicked() {}
|
||||
|
||||
|
|
Loading…
Reference in New Issue