mirror of https://github.com/OpenVidu/openvidu.git
ov-components: Add participant panel directive for enhanced user experience
parent
413dec3e0f
commit
e9ecceeb77
|
@ -7,14 +7,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="scrollable">
|
<div class="scrollable">
|
||||||
|
|
||||||
<div class="local-participant-container" *ngIf="localParticipant">
|
<div class="local-participant-container" *ngIf="localParticipant">
|
||||||
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: localParticipant }"></ng-container>
|
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: localParticipant }"></ng-container>
|
||||||
<mat-divider *ngIf="true"></mat-divider>
|
<mat-divider *ngIf="true"></mat-divider>
|
||||||
</div>
|
</div>
|
||||||
|
<ng-container *ngTemplateOutlet="participantPanelAfterLocalParticipantTemplate"></ng-container>
|
||||||
|
|
||||||
<div class="remote-participants-container" id="remote-participants-container" *ngIf="remoteParticipants.length > 0">
|
<div class="remote-participants-container" id="remote-participants-container" *ngIf="remoteParticipants.length > 0">
|
||||||
|
|
||||||
<div *ngFor="let participant of this.remoteParticipants" id="remote-participant-item">
|
<div *ngFor="let participant of this.remoteParticipants" id="remote-participant-item">
|
||||||
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: participant }"></ng-container>
|
<ng-container *ngTemplateOutlet="participantPanelItemTemplate; context: { $implicit: participant }"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,9 +13,10 @@ import {
|
||||||
import { ParticipantService } from '../../../../services/participant/participant.service';
|
import { ParticipantService } from '../../../../services/participant/participant.service';
|
||||||
import { PanelService } from '../../../../services/panel/panel.service';
|
import { PanelService } from '../../../../services/panel/panel.service';
|
||||||
import { ParticipantPanelItemDirective } from '../../../../directives/template/openvidu-components-angular.directive';
|
import { ParticipantPanelItemDirective } from '../../../../directives/template/openvidu-components-angular.directive';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
import { ParticipantModel } from '../../../../models/participant.model';
|
import { ParticipantModel } from '../../../../models/participant.model';
|
||||||
import { TemplateManagerService, ParticipantsPanelTemplateConfiguration } from '../../../../services/template/template-manager.service';
|
import { TemplateManagerService, ParticipantsPanelTemplateConfiguration } from '../../../../services/template/template-manager.service';
|
||||||
|
import { OpenViduComponentsConfigService } from '../../../../services/config/directive-config.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The **ParticipantsPanelComponent** is hosted inside of the {@link PanelComponent}.
|
* The **ParticipantsPanelComponent** is hosted inside of the {@link PanelComponent}.
|
||||||
|
@ -49,6 +50,12 @@ export class ParticipantsPanelComponent implements OnInit, OnDestroy, AfterViewI
|
||||||
*/
|
*/
|
||||||
@ContentChild('participantPanelItem', { read: TemplateRef }) participantPanelItemTemplate: TemplateRef<any>;
|
@ContentChild('participantPanelItem', { read: TemplateRef }) participantPanelItemTemplate: TemplateRef<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
@ContentChild('participantPanelAfterLocalParticipant', { read: TemplateRef })
|
||||||
|
participantPanelAfterLocalParticipantTemplate: TemplateRef<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
@ -69,8 +76,7 @@ export class ParticipantsPanelComponent implements OnInit, OnDestroy, AfterViewI
|
||||||
// Store directive references for template setup
|
// Store directive references for template setup
|
||||||
private _externalParticipantPanelItem?: ParticipantPanelItemDirective;
|
private _externalParticipantPanelItem?: ParticipantPanelItemDirective;
|
||||||
|
|
||||||
private localParticipantSubs: Subscription;
|
private destroy$ = new Subject<void>();
|
||||||
private remoteParticipantsSubs: Subscription;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ignore
|
* @ignore
|
||||||
|
@ -79,7 +85,8 @@ export class ParticipantsPanelComponent implements OnInit, OnDestroy, AfterViewI
|
||||||
private participantService: ParticipantService,
|
private participantService: ParticipantService,
|
||||||
private panelService: PanelService,
|
private panelService: PanelService,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
private templateManagerService: TemplateManagerService
|
private templateManagerService: TemplateManagerService,
|
||||||
|
private libService: OpenViduComponentsConfigService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,25 +95,15 @@ export class ParticipantsPanelComponent implements OnInit, OnDestroy, AfterViewI
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.setupTemplates();
|
this.setupTemplates();
|
||||||
|
|
||||||
this.localParticipantSubs = this.participantService.localParticipant$.subscribe((p: ParticipantModel | undefined) => {
|
this.subscribeToParticipantsChanges();
|
||||||
if (p) {
|
|
||||||
this.localParticipant = p;
|
|
||||||
this.cd.markForCheck();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.remoteParticipantsSubs = this.participantService.remoteParticipants$.subscribe((p: ParticipantModel[]) => {
|
|
||||||
this.remoteParticipants = p;
|
|
||||||
this.cd.markForCheck();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
if (this.localParticipantSubs) this.localParticipantSubs.unsubscribe();
|
this.destroy$.next();
|
||||||
if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe;
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,6 +118,21 @@ export class ParticipantsPanelComponent implements OnInit, OnDestroy, AfterViewI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private subscribeToParticipantsChanges() {
|
||||||
|
this.participantService.localParticipant$.pipe(takeUntil(this.destroy$)).subscribe((p: ParticipantModel | undefined) => {
|
||||||
|
if (p) {
|
||||||
|
this.localParticipant = p;
|
||||||
|
this.cd.markForCheck();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.participantService.remoteParticipants$.pipe(takeUntil(this.destroy$)).subscribe((p: ParticipantModel[]) => {
|
||||||
|
this.remoteParticipants = p;
|
||||||
|
this.cd.markForCheck();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* Sets up all templates using the template manager service
|
* Sets up all templates using the template manager service
|
||||||
|
@ -143,6 +155,9 @@ export class ParticipantsPanelComponent implements OnInit, OnDestroy, AfterViewI
|
||||||
if (this.templateConfig.participantPanelItemTemplate) {
|
if (this.templateConfig.participantPanelItemTemplate) {
|
||||||
this.participantPanelItemTemplate = this.templateConfig.participantPanelItemTemplate;
|
this.participantPanelItemTemplate = this.templateConfig.participantPanelItemTemplate;
|
||||||
}
|
}
|
||||||
|
if (this.templateConfig.participantPanelAfterLocalParticipantTemplate) {
|
||||||
|
this.participantPanelAfterLocalParticipantTemplate = this.templateConfig.participantPanelAfterLocalParticipantTemplate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,7 +26,11 @@
|
||||||
<span>{{ componentState.error?.message }}</span>
|
<span>{{ componentState.error?.message }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div [@inOutAnimation] id="vc-container" *ngIf="componentState.isRoomReady && !componentState.showPrejoin && !componentState.isLoading && !componentState.error?.hasError">
|
<div
|
||||||
|
[@inOutAnimation]
|
||||||
|
id="vc-container"
|
||||||
|
*ngIf="componentState.isRoomReady && !componentState.showPrejoin && !componentState.isLoading && !componentState.error?.hasError"
|
||||||
|
>
|
||||||
<ov-session
|
<ov-session
|
||||||
(onRoomCreated)="onRoomCreated.emit($event)"
|
(onRoomCreated)="onRoomCreated.emit($event)"
|
||||||
(onRoomReconnecting)="onRoomDisconnected.emit()"
|
(onRoomReconnecting)="onRoomDisconnected.emit()"
|
||||||
|
@ -148,6 +152,9 @@
|
||||||
*ngTemplateOutlet="openviduAngularParticipantPanelItemTemplate; context: { $implicit: participant }"
|
*ngTemplateOutlet="openviduAngularParticipantPanelItemTemplate; context: { $implicit: participant }"
|
||||||
></ng-container>
|
></ng-container>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
<ng-template #participantPanelAfterLocalParticipant>
|
||||||
|
<ng-container *ngTemplateOutlet="openviduAngularParticipantPanelAfterLocalParticipantTemplate"></ng-container>
|
||||||
|
</ng-template>
|
||||||
</ov-participants-panel>
|
</ov-participants-panel>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
ParticipantPanelItemDirective,
|
ParticipantPanelItemDirective,
|
||||||
ParticipantPanelItemElementsDirective,
|
ParticipantPanelItemElementsDirective,
|
||||||
ParticipantsPanelDirective,
|
ParticipantsPanelDirective,
|
||||||
PreJoinDirective,
|
|
||||||
StreamDirective,
|
StreamDirective,
|
||||||
ToolbarAdditionalButtonsDirective,
|
ToolbarAdditionalButtonsDirective,
|
||||||
ToolbarAdditionalPanelButtonsDirective,
|
ToolbarAdditionalPanelButtonsDirective,
|
||||||
|
@ -43,6 +42,7 @@ import {
|
||||||
} from '../../models/recording.model';
|
} from '../../models/recording.model';
|
||||||
import { BroadcastingStartRequestedEvent, BroadcastingStopRequestedEvent } from '../../models/broadcasting.model';
|
import { BroadcastingStartRequestedEvent, BroadcastingStopRequestedEvent } from '../../models/broadcasting.model';
|
||||||
import { LangOption } from '../../models/lang.model';
|
import { LangOption } from '../../models/lang.model';
|
||||||
|
import { ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from '../../directives/template/internals.directive';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The **VideoconferenceComponent** is the parent of all OpenVidu components.
|
* The **VideoconferenceComponent** is the parent of all OpenVidu components.
|
||||||
|
@ -129,6 +129,11 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
@ContentChild(PreJoinDirective) externalPreJoin: PreJoinDirective;
|
@ContentChild(PreJoinDirective) externalPreJoin: PreJoinDirective;
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ContentChild(ParticipantPanelAfterLocalParticipantDirective) externalParticipantPanelAfterLocalParticipant: ParticipantPanelAfterLocalParticipantDirective;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
|
@ -198,6 +203,10 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
openviduAngularAdditionalPanelsTemplate: TemplateRef<any>;
|
openviduAngularAdditionalPanelsTemplate: TemplateRef<any>;
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
openviduAngularParticipantPanelAfterLocalParticipantTemplate: TemplateRef<any>;
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
@ -516,6 +525,7 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
||||||
chatPanel: this.externalChatPanel,
|
chatPanel: this.externalChatPanel,
|
||||||
activitiesPanel: this.externalActivitiesPanel,
|
activitiesPanel: this.externalActivitiesPanel,
|
||||||
participantsPanel: this.externalParticipantsPanel,
|
participantsPanel: this.externalParticipantsPanel,
|
||||||
|
participantPanelAfterLocalParticipant: this.externalParticipantPanelAfterLocalParticipant,
|
||||||
participantPanelItem: this.externalParticipantPanelItem,
|
participantPanelItem: this.externalParticipantPanelItem,
|
||||||
participantPanelItemElements: this.externalParticipantPanelItemElements,
|
participantPanelItemElements: this.externalParticipantPanelItemElements,
|
||||||
layout: this.externalLayout,
|
layout: this.externalLayout,
|
||||||
|
@ -565,6 +575,9 @@ export class VideoconferenceComponent implements OnDestroy, AfterViewInit {
|
||||||
if (this.templateConfig.additionalPanelsTemplate) {
|
if (this.templateConfig.additionalPanelsTemplate) {
|
||||||
this.openviduAngularAdditionalPanelsTemplate = this.templateConfig.additionalPanelsTemplate;
|
this.openviduAngularAdditionalPanelsTemplate = this.templateConfig.additionalPanelsTemplate;
|
||||||
}
|
}
|
||||||
|
if (this.templateConfig.participantPanelAfterLocalParticipantTemplate) {
|
||||||
|
this.openviduAngularParticipantPanelAfterLocalParticipantTemplate = this.templateConfig.participantPanelAfterLocalParticipantTemplate;
|
||||||
|
}
|
||||||
if (this.templateConfig.participantPanelItemElementsTemplate) {
|
if (this.templateConfig.participantPanelItemElementsTemplate) {
|
||||||
this.openviduAngularParticipantPanelItemElementsTemplate = this.templateConfig.participantPanelItemElementsTemplate;
|
this.openviduAngularParticipantPanelItemElementsTemplate = this.templateConfig.participantPanelItemElementsTemplate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,4 +473,4 @@ export class RecordingActivityShowRecordingsListDirective implements AfterViewIn
|
||||||
private update(value: boolean) {
|
private update(value: boolean) {
|
||||||
this.libService.updateRecordingActivityConfig({ showRecordingsList: value });
|
this.libService.updateRecordingActivityConfig({ showRecordingsList: value });
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
/**
|
||||||
|
* The ***ovPreJoin** directive empowers you to substitute the default pre-join component template with a custom one.
|
||||||
|
* This directive allows you to create a completely custom pre-join experience while maintaining the core functionality.
|
||||||
|
*
|
||||||
|
* In the example below, we demonstrate how to replace the pre-join template with a custom one that includes
|
||||||
|
* device selection and a custom join button.
|
||||||
|
*
|
||||||
|
* <!--ovPreJoin-start-tutorial-->
|
||||||
|
* ```typescript
|
||||||
|
* import { HttpClient } from '@angular/common/http';
|
||||||
|
* import { Component } from '@angular/core';
|
||||||
|
* import { lastValueFrom } from 'rxjs';
|
||||||
|
* import { FormsModule } from '@angular/forms';
|
||||||
|
*
|
||||||
|
* import {
|
||||||
|
* DeviceService,
|
||||||
|
* ParticipantService,
|
||||||
|
* OpenViduComponentsModule,
|
||||||
|
* } from 'openvidu-components-angular';
|
||||||
|
*
|
||||||
|
* @Component({
|
||||||
|
* selector: 'app-root',
|
||||||
|
* template: `
|
||||||
|
* <ov-videoconference
|
||||||
|
* [token]="token"
|
||||||
|
* [livekitUrl]="LIVEKIT_URL"
|
||||||
|
* (onTokenRequested)="onTokenRequested($event)"
|
||||||
|
* (onReadyToJoin)="onReadyToJoin()"
|
||||||
|
* >
|
||||||
|
* <!-- Custom Pre-Join Component -->
|
||||||
|
* <div *ovPreJoin class="custom-prejoin">
|
||||||
|
* <h2>Join Meeting</h2>
|
||||||
|
* <div class="prejoin-form">
|
||||||
|
* <input
|
||||||
|
* type="text"
|
||||||
|
* placeholder="Enter your name"
|
||||||
|
* [(ngModel)]="participantName"
|
||||||
|
* class="name-input"
|
||||||
|
* />
|
||||||
|
* <button
|
||||||
|
* (click)="joinMeeting()"
|
||||||
|
* [disabled]="!participantName"
|
||||||
|
* class="join-button"
|
||||||
|
* >
|
||||||
|
* Join Meeting
|
||||||
|
* </button>
|
||||||
|
* </div>
|
||||||
|
* </div>
|
||||||
|
* </ov-videoconference>
|
||||||
|
* `,
|
||||||
|
* styles: `
|
||||||
|
* .custom-prejoin {
|
||||||
|
* display: flex;
|
||||||
|
* flex-direction: column;
|
||||||
|
* align-items: center;
|
||||||
|
* justify-content: center;
|
||||||
|
* height: 100vh;
|
||||||
|
* background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
* color: white;
|
||||||
|
* }
|
||||||
|
* .prejoin-form {
|
||||||
|
* display: flex;
|
||||||
|
* flex-direction: column;
|
||||||
|
* gap: 20px;
|
||||||
|
* align-items: center;
|
||||||
|
* }
|
||||||
|
* .name-input {
|
||||||
|
* padding: 12px;
|
||||||
|
* border: none;
|
||||||
|
* border-radius: 8px;
|
||||||
|
* font-size: 16px;
|
||||||
|
* min-width: 250px;
|
||||||
|
* }
|
||||||
|
* .join-button {
|
||||||
|
* padding: 12px 24px;
|
||||||
|
* background: #4CAF50;
|
||||||
|
* color: white;
|
||||||
|
* border: none;
|
||||||
|
* border-radius: 8px;
|
||||||
|
* font-size: 16px;
|
||||||
|
* cursor: pointer;
|
||||||
|
* transition: background 0.3s;
|
||||||
|
* }
|
||||||
|
* .join-button:hover:not(:disabled) {
|
||||||
|
* background: #45a049;
|
||||||
|
* }
|
||||||
|
* .join-button:disabled {
|
||||||
|
* background: #cccccc;
|
||||||
|
* cursor: not-allowed;
|
||||||
|
* }
|
||||||
|
* `,
|
||||||
|
* standalone: true,
|
||||||
|
* imports: [OpenViduComponentsModule, FormsModule],
|
||||||
|
* })
|
||||||
|
* export class AppComponent {
|
||||||
|
* // For local development, leave these variables empty
|
||||||
|
* // For production, configure them with correct URLs depending on your deployment
|
||||||
|
* APPLICATION_SERVER_URL = '';
|
||||||
|
* LIVEKIT_URL = '';
|
||||||
|
*
|
||||||
|
* // Define the name of the room and initialize the token variable
|
||||||
|
* roomName = 'custom-prejoin';
|
||||||
|
* token!: string;
|
||||||
|
* participantName: string = '';
|
||||||
|
*
|
||||||
|
* constructor(
|
||||||
|
* private httpClient: HttpClient,
|
||||||
|
* private deviceService: DeviceService,
|
||||||
|
* private participantService: ParticipantService
|
||||||
|
* ) {
|
||||||
|
* this.configureUrls();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* private configureUrls() {
|
||||||
|
* // If APPLICATION_SERVER_URL is not configured, use default value from local development
|
||||||
|
* if (!this.APPLICATION_SERVER_URL) {
|
||||||
|
* if (window.location.hostname === 'localhost') {
|
||||||
|
* this.APPLICATION_SERVER_URL = 'http://localhost:6080/';
|
||||||
|
* } else {
|
||||||
|
* this.APPLICATION_SERVER_URL =
|
||||||
|
* 'https://' + window.location.hostname + ':6443/';
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // If LIVEKIT_URL is not configured, use default value from local development
|
||||||
|
* if (!this.LIVEKIT_URL) {
|
||||||
|
* if (window.location.hostname === 'localhost') {
|
||||||
|
* this.LIVEKIT_URL = 'ws://localhost:7880/';
|
||||||
|
* } else {
|
||||||
|
* this.LIVEKIT_URL = 'wss://' + window.location.hostname + ':7443/';
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Function to request a token when a participant joins the room
|
||||||
|
* async onTokenRequested(participantName: string) {
|
||||||
|
* const { token } = await this.getToken(this.roomName, participantName);
|
||||||
|
* this.token = token;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Function called when ready to join
|
||||||
|
* onReadyToJoin() {
|
||||||
|
* console.log('Ready to join the meeting');
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Function to join the meeting
|
||||||
|
* async joinMeeting() {
|
||||||
|
* if (this.participantName.trim()) {
|
||||||
|
* // Request token with the participant name
|
||||||
|
* await this.onTokenRequested(this.participantName);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Function to get a token from the server
|
||||||
|
* getToken(roomName: string, participantName: string): Promise<any> {
|
||||||
|
* try {
|
||||||
|
* // Send a POST request to the server to obtain a token
|
||||||
|
* return lastValueFrom(
|
||||||
|
* this.httpClient.post<any>(this.APPLICATION_SERVER_URL + 'token', {
|
||||||
|
* roomName,
|
||||||
|
* participantName,
|
||||||
|
* })
|
||||||
|
* );
|
||||||
|
* } catch (error: any) {
|
||||||
|
* // Handle errors, e.g., if the server is not reachable
|
||||||
|
* if (error.status === 404) {
|
||||||
|
* throw {
|
||||||
|
* status: error.status,
|
||||||
|
* message:
|
||||||
|
* 'Cannot connect with the backend. ' + error.url + ' not found',
|
||||||
|
* };
|
||||||
|
* }
|
||||||
|
* throw error;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* <!--ovPreJoin-end-tutorial-->
|
||||||
|
*
|
||||||
|
* For a detailed tutorial on customizing the pre-join component, please visit [this link](https://openvidu.io/latest/docs/tutorials/angular-components/openvidu-custom-prejoin/).
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[ovPreJoin]',
|
||||||
|
standalone: false
|
||||||
|
})
|
||||||
|
export class PreJoinDirective {
|
||||||
|
constructor(
|
||||||
|
public template: TemplateRef<any>,
|
||||||
|
public container: ViewContainerRef
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The **ovParticipantPanelAfterLocalParticipant** directive allows you to inject custom HTML or Angular templates
|
||||||
|
* immediately after the local participant item in the participant panel.
|
||||||
|
* This enables you to extend the participant panel with additional controls, information, or UI elements.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
* ```html
|
||||||
|
* <ov-participant-panel>
|
||||||
|
* <ng-container *ovParticipantPanelAfterLocalParticipant>
|
||||||
|
* <div class="custom-content">
|
||||||
|
* <!-- Your custom HTML here -->
|
||||||
|
* <span>Custom content after local participant</span>
|
||||||
|
* </div>
|
||||||
|
* </ng-container>
|
||||||
|
* </ov-participant-panel>
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
@Directive({
|
||||||
|
selector: '[ovParticipantPanelAfterLocalParticipant]',
|
||||||
|
standalone: false
|
||||||
|
})
|
||||||
|
export class ParticipantPanelAfterLocalParticipantDirective {
|
||||||
|
constructor(
|
||||||
|
public template: TemplateRef<any>,
|
||||||
|
public container: ViewContainerRef
|
||||||
|
) {}
|
||||||
|
}
|
|
@ -12,9 +12,9 @@ import {
|
||||||
ToolbarAdditionalPanelButtonsDirective,
|
ToolbarAdditionalPanelButtonsDirective,
|
||||||
AdditionalPanelsDirective,
|
AdditionalPanelsDirective,
|
||||||
ActivitiesPanelDirective,
|
ActivitiesPanelDirective,
|
||||||
BackgroundEffectsPanelDirective,
|
BackgroundEffectsPanelDirective
|
||||||
PreJoinDirective
|
|
||||||
} from './openvidu-components-angular.directive';
|
} from './openvidu-components-angular.directive';
|
||||||
|
import { ParticipantPanelAfterLocalParticipantDirective, PreJoinDirective } from './internals.directive';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -31,6 +31,7 @@ import {
|
||||||
ParticipantPanelItemElementsDirective,
|
ParticipantPanelItemElementsDirective,
|
||||||
ActivitiesPanelDirective,
|
ActivitiesPanelDirective,
|
||||||
PreJoinDirective,
|
PreJoinDirective,
|
||||||
|
ParticipantPanelAfterLocalParticipantDirective
|
||||||
// BackgroundEffectsPanelDirective
|
// BackgroundEffectsPanelDirective
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
@ -47,6 +48,7 @@ import {
|
||||||
ParticipantPanelItemElementsDirective,
|
ParticipantPanelItemElementsDirective,
|
||||||
ActivitiesPanelDirective,
|
ActivitiesPanelDirective,
|
||||||
PreJoinDirective,
|
PreJoinDirective,
|
||||||
|
ParticipantPanelAfterLocalParticipantDirective
|
||||||
// BackgroundEffectsPanelDirective
|
// BackgroundEffectsPanelDirective
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -1815,196 +1815,3 @@ export class StreamDirective {
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The ***ovPreJoin** directive empowers you to substitute the default pre-join component template with a custom one.
|
|
||||||
* This directive allows you to create a completely custom pre-join experience while maintaining the core functionality.
|
|
||||||
*
|
|
||||||
* In the example below, we demonstrate how to replace the pre-join template with a custom one that includes
|
|
||||||
* device selection and a custom join button.
|
|
||||||
*
|
|
||||||
* <!--ovPreJoin-start-tutorial-->
|
|
||||||
* ```typescript
|
|
||||||
* import { HttpClient } from '@angular/common/http';
|
|
||||||
* import { Component } from '@angular/core';
|
|
||||||
* import { lastValueFrom } from 'rxjs';
|
|
||||||
* import { FormsModule } from '@angular/forms';
|
|
||||||
*
|
|
||||||
* import {
|
|
||||||
* DeviceService,
|
|
||||||
* ParticipantService,
|
|
||||||
* OpenViduComponentsModule,
|
|
||||||
* } from 'openvidu-components-angular';
|
|
||||||
*
|
|
||||||
* @Component({
|
|
||||||
* selector: 'app-root',
|
|
||||||
* template: `
|
|
||||||
* <ov-videoconference
|
|
||||||
* [token]="token"
|
|
||||||
* [livekitUrl]="LIVEKIT_URL"
|
|
||||||
* (onTokenRequested)="onTokenRequested($event)"
|
|
||||||
* (onReadyToJoin)="onReadyToJoin()"
|
|
||||||
* >
|
|
||||||
* <!-- Custom Pre-Join Component -->
|
|
||||||
* <div *ovPreJoin class="custom-prejoin">
|
|
||||||
* <h2>Join Meeting</h2>
|
|
||||||
* <div class="prejoin-form">
|
|
||||||
* <input
|
|
||||||
* type="text"
|
|
||||||
* placeholder="Enter your name"
|
|
||||||
* [(ngModel)]="participantName"
|
|
||||||
* class="name-input"
|
|
||||||
* />
|
|
||||||
* <button
|
|
||||||
* (click)="joinMeeting()"
|
|
||||||
* [disabled]="!participantName"
|
|
||||||
* class="join-button"
|
|
||||||
* >
|
|
||||||
* Join Meeting
|
|
||||||
* </button>
|
|
||||||
* </div>
|
|
||||||
* </div>
|
|
||||||
* </ov-videoconference>
|
|
||||||
* `,
|
|
||||||
* styles: `
|
|
||||||
* .custom-prejoin {
|
|
||||||
* display: flex;
|
|
||||||
* flex-direction: column;
|
|
||||||
* align-items: center;
|
|
||||||
* justify-content: center;
|
|
||||||
* height: 100vh;
|
|
||||||
* background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
||||||
* color: white;
|
|
||||||
* }
|
|
||||||
* .prejoin-form {
|
|
||||||
* display: flex;
|
|
||||||
* flex-direction: column;
|
|
||||||
* gap: 20px;
|
|
||||||
* align-items: center;
|
|
||||||
* }
|
|
||||||
* .name-input {
|
|
||||||
* padding: 12px;
|
|
||||||
* border: none;
|
|
||||||
* border-radius: 8px;
|
|
||||||
* font-size: 16px;
|
|
||||||
* min-width: 250px;
|
|
||||||
* }
|
|
||||||
* .join-button {
|
|
||||||
* padding: 12px 24px;
|
|
||||||
* background: #4CAF50;
|
|
||||||
* color: white;
|
|
||||||
* border: none;
|
|
||||||
* border-radius: 8px;
|
|
||||||
* font-size: 16px;
|
|
||||||
* cursor: pointer;
|
|
||||||
* transition: background 0.3s;
|
|
||||||
* }
|
|
||||||
* .join-button:hover:not(:disabled) {
|
|
||||||
* background: #45a049;
|
|
||||||
* }
|
|
||||||
* .join-button:disabled {
|
|
||||||
* background: #cccccc;
|
|
||||||
* cursor: not-allowed;
|
|
||||||
* }
|
|
||||||
* `,
|
|
||||||
* standalone: true,
|
|
||||||
* imports: [OpenViduComponentsModule, FormsModule],
|
|
||||||
* })
|
|
||||||
* export class AppComponent {
|
|
||||||
* // For local development, leave these variables empty
|
|
||||||
* // For production, configure them with correct URLs depending on your deployment
|
|
||||||
* APPLICATION_SERVER_URL = '';
|
|
||||||
* LIVEKIT_URL = '';
|
|
||||||
*
|
|
||||||
* // Define the name of the room and initialize the token variable
|
|
||||||
* roomName = 'custom-prejoin';
|
|
||||||
* token!: string;
|
|
||||||
* participantName: string = '';
|
|
||||||
*
|
|
||||||
* constructor(
|
|
||||||
* private httpClient: HttpClient,
|
|
||||||
* private deviceService: DeviceService,
|
|
||||||
* private participantService: ParticipantService
|
|
||||||
* ) {
|
|
||||||
* this.configureUrls();
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* private configureUrls() {
|
|
||||||
* // If APPLICATION_SERVER_URL is not configured, use default value from local development
|
|
||||||
* if (!this.APPLICATION_SERVER_URL) {
|
|
||||||
* if (window.location.hostname === 'localhost') {
|
|
||||||
* this.APPLICATION_SERVER_URL = 'http://localhost:6080/';
|
|
||||||
* } else {
|
|
||||||
* this.APPLICATION_SERVER_URL =
|
|
||||||
* 'https://' + window.location.hostname + ':6443/';
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // If LIVEKIT_URL is not configured, use default value from local development
|
|
||||||
* if (!this.LIVEKIT_URL) {
|
|
||||||
* if (window.location.hostname === 'localhost') {
|
|
||||||
* this.LIVEKIT_URL = 'ws://localhost:7880/';
|
|
||||||
* } else {
|
|
||||||
* this.LIVEKIT_URL = 'wss://' + window.location.hostname + ':7443/';
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Function to request a token when a participant joins the room
|
|
||||||
* async onTokenRequested(participantName: string) {
|
|
||||||
* const { token } = await this.getToken(this.roomName, participantName);
|
|
||||||
* this.token = token;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Function called when ready to join
|
|
||||||
* onReadyToJoin() {
|
|
||||||
* console.log('Ready to join the meeting');
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Function to join the meeting
|
|
||||||
* async joinMeeting() {
|
|
||||||
* if (this.participantName.trim()) {
|
|
||||||
* // Request token with the participant name
|
|
||||||
* await this.onTokenRequested(this.participantName);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Function to get a token from the server
|
|
||||||
* getToken(roomName: string, participantName: string): Promise<any> {
|
|
||||||
* try {
|
|
||||||
* // Send a POST request to the server to obtain a token
|
|
||||||
* return lastValueFrom(
|
|
||||||
* this.httpClient.post<any>(this.APPLICATION_SERVER_URL + 'token', {
|
|
||||||
* roomName,
|
|
||||||
* participantName,
|
|
||||||
* })
|
|
||||||
* );
|
|
||||||
* } catch (error: any) {
|
|
||||||
* // Handle errors, e.g., if the server is not reachable
|
|
||||||
* if (error.status === 404) {
|
|
||||||
* throw {
|
|
||||||
* status: error.status,
|
|
||||||
* message:
|
|
||||||
* 'Cannot connect with the backend. ' + error.url + ' not found',
|
|
||||||
* };
|
|
||||||
* }
|
|
||||||
* throw error;
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* <!--ovPreJoin-end-tutorial-->
|
|
||||||
*
|
|
||||||
* For a detailed tutorial on customizing the pre-join component, please visit [this link](https://openvidu.io/latest/docs/tutorials/angular-components/openvidu-custom-prejoin/).
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[ovPreJoin]',
|
|
||||||
standalone: false
|
|
||||||
})
|
|
||||||
export class PreJoinDirective {
|
|
||||||
constructor(
|
|
||||||
public template: TemplateRef<any>,
|
|
||||||
public container: ViewContainerRef
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,12 +10,12 @@ import {
|
||||||
ParticipantPanelItemDirective,
|
ParticipantPanelItemDirective,
|
||||||
ParticipantPanelItemElementsDirective,
|
ParticipantPanelItemElementsDirective,
|
||||||
ParticipantsPanelDirective,
|
ParticipantsPanelDirective,
|
||||||
PreJoinDirective,
|
|
||||||
StreamDirective,
|
StreamDirective,
|
||||||
ToolbarAdditionalButtonsDirective,
|
ToolbarAdditionalButtonsDirective,
|
||||||
ToolbarAdditionalPanelButtonsDirective,
|
ToolbarAdditionalPanelButtonsDirective,
|
||||||
ToolbarDirective
|
ToolbarDirective
|
||||||
} from '../../directives/template/openvidu-components-angular.directive';
|
} from '../../directives/template/openvidu-components-angular.directive';
|
||||||
|
import { PreJoinDirective, ParticipantPanelAfterLocalParticipantDirective } from '../../directives/template/internals.directive';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration object for all templates in the videoconference component
|
* Configuration object for all templates in the videoconference component
|
||||||
|
@ -34,6 +34,7 @@ export interface TemplateConfiguration {
|
||||||
additionalPanelsTemplate?: TemplateRef<any>;
|
additionalPanelsTemplate?: TemplateRef<any>;
|
||||||
|
|
||||||
// Participant templates
|
// Participant templates
|
||||||
|
participantPanelAfterLocalParticipantTemplate?: TemplateRef<any>;
|
||||||
participantPanelItemTemplate: TemplateRef<any>;
|
participantPanelItemTemplate: TemplateRef<any>;
|
||||||
participantPanelItemElementsTemplate?: TemplateRef<any>;
|
participantPanelItemElementsTemplate?: TemplateRef<any>;
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ export interface ToolbarTemplateConfiguration {
|
||||||
*/
|
*/
|
||||||
export interface ParticipantsPanelTemplateConfiguration {
|
export interface ParticipantsPanelTemplateConfiguration {
|
||||||
participantPanelItemTemplate?: TemplateRef<any>;
|
participantPanelItemTemplate?: TemplateRef<any>;
|
||||||
|
participantPanelAfterLocalParticipantTemplate?: TemplateRef<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,6 +102,7 @@ export interface ExternalDirectives {
|
||||||
chatPanel?: ChatPanelDirective;
|
chatPanel?: ChatPanelDirective;
|
||||||
activitiesPanel?: ActivitiesPanelDirective;
|
activitiesPanel?: ActivitiesPanelDirective;
|
||||||
participantsPanel?: ParticipantsPanelDirective;
|
participantsPanel?: ParticipantsPanelDirective;
|
||||||
|
participantPanelAfterLocalParticipant?: ParticipantPanelAfterLocalParticipantDirective;
|
||||||
participantPanelItem?: ParticipantPanelItemDirective;
|
participantPanelItem?: ParticipantPanelItemDirective;
|
||||||
participantPanelItemElements?: ParticipantPanelItemElementsDirective;
|
participantPanelItemElements?: ParticipantPanelItemElementsDirective;
|
||||||
layout?: LayoutDirective;
|
layout?: LayoutDirective;
|
||||||
|
@ -138,10 +141,7 @@ export class TemplateManagerService {
|
||||||
/**
|
/**
|
||||||
* Sets up all templates based on external directives and default templates
|
* Sets up all templates based on external directives and default templates
|
||||||
*/
|
*/
|
||||||
setupTemplates(
|
setupTemplates(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateConfiguration {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateConfiguration {
|
|
||||||
this.log.d('Setting up templates...');
|
this.log.d('Setting up templates...');
|
||||||
|
|
||||||
const config: TemplateConfiguration = {
|
const config: TemplateConfiguration = {
|
||||||
|
@ -155,7 +155,8 @@ export class TemplateManagerService {
|
||||||
participantsPanelTemplate: this.setupParticipantsPanelTemplate(externalDirectives, defaultTemplates),
|
participantsPanelTemplate: this.setupParticipantsPanelTemplate(externalDirectives, defaultTemplates),
|
||||||
activitiesPanelTemplate: this.setupActivitiesPanelTemplate(externalDirectives, defaultTemplates),
|
activitiesPanelTemplate: this.setupActivitiesPanelTemplate(externalDirectives, defaultTemplates),
|
||||||
participantPanelItemTemplate: this.setupParticipantPanelItemTemplate(externalDirectives, defaultTemplates),
|
participantPanelItemTemplate: this.setupParticipantPanelItemTemplate(externalDirectives, defaultTemplates),
|
||||||
streamTemplate: this.setupStreamTemplate(externalDirectives, defaultTemplates)
|
streamTemplate: this.setupStreamTemplate(externalDirectives, defaultTemplates),
|
||||||
|
participantPanelAfterLocalParticipantTemplate: this.setupParticipantPanelAfterLocalParticipantTemplate(externalDirectives)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Optional templates
|
// Optional templates
|
||||||
|
@ -183,13 +184,21 @@ export class TemplateManagerService {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the participantPanelAfterLocalParticipant template
|
||||||
|
*/
|
||||||
|
private setupParticipantPanelAfterLocalParticipantTemplate(externalDirectives: ExternalDirectives): TemplateRef<any> | undefined {
|
||||||
|
if (externalDirectives.participantPanelAfterLocalParticipant) {
|
||||||
|
this.log.d('Setting EXTERNAL PARTICIPANT PANEL AFTER LOCAL PARTICIPANT');
|
||||||
|
return (externalDirectives.participantPanelAfterLocalParticipant as any).template;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the toolbar template
|
* Sets up the toolbar template
|
||||||
*/
|
*/
|
||||||
private setupToolbarTemplate(
|
private setupToolbarTemplate(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateRef<any> {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateRef<any> {
|
|
||||||
if (externalDirectives.toolbar) {
|
if (externalDirectives.toolbar) {
|
||||||
this.log.d('Setting EXTERNAL TOOLBAR');
|
this.log.d('Setting EXTERNAL TOOLBAR');
|
||||||
return externalDirectives.toolbar.template;
|
return externalDirectives.toolbar.template;
|
||||||
|
@ -202,10 +211,7 @@ export class TemplateManagerService {
|
||||||
/**
|
/**
|
||||||
* Sets up the panel template
|
* Sets up the panel template
|
||||||
*/
|
*/
|
||||||
private setupPanelTemplate(
|
private setupPanelTemplate(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateRef<any> {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateRef<any> {
|
|
||||||
if (externalDirectives.panel) {
|
if (externalDirectives.panel) {
|
||||||
this.log.d('Setting EXTERNAL PANEL');
|
this.log.d('Setting EXTERNAL PANEL');
|
||||||
return externalDirectives.panel.template;
|
return externalDirectives.panel.template;
|
||||||
|
@ -218,10 +224,7 @@ export class TemplateManagerService {
|
||||||
/**
|
/**
|
||||||
* Sets up the layout template
|
* Sets up the layout template
|
||||||
*/
|
*/
|
||||||
private setupLayoutTemplate(
|
private setupLayoutTemplate(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateRef<any> {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateRef<any> {
|
|
||||||
if (externalDirectives.layout) {
|
if (externalDirectives.layout) {
|
||||||
this.log.d('Setting EXTERNAL LAYOUT');
|
this.log.d('Setting EXTERNAL LAYOUT');
|
||||||
return externalDirectives.layout.template;
|
return externalDirectives.layout.template;
|
||||||
|
@ -247,10 +250,7 @@ export class TemplateManagerService {
|
||||||
/**
|
/**
|
||||||
* Sets up the chat panel template
|
* Sets up the chat panel template
|
||||||
*/
|
*/
|
||||||
private setupChatPanelTemplate(
|
private setupChatPanelTemplate(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateRef<any> {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateRef<any> {
|
|
||||||
if (externalDirectives.chatPanel) {
|
if (externalDirectives.chatPanel) {
|
||||||
this.log.d('Setting EXTERNAL CHAT PANEL');
|
this.log.d('Setting EXTERNAL CHAT PANEL');
|
||||||
return externalDirectives.chatPanel.template;
|
return externalDirectives.chatPanel.template;
|
||||||
|
@ -263,10 +263,7 @@ export class TemplateManagerService {
|
||||||
/**
|
/**
|
||||||
* Sets up the participants panel template
|
* Sets up the participants panel template
|
||||||
*/
|
*/
|
||||||
private setupParticipantsPanelTemplate(
|
private setupParticipantsPanelTemplate(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateRef<any> {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateRef<any> {
|
|
||||||
if (externalDirectives.participantsPanel) {
|
if (externalDirectives.participantsPanel) {
|
||||||
this.log.d('Setting EXTERNAL PARTICIPANTS PANEL');
|
this.log.d('Setting EXTERNAL PARTICIPANTS PANEL');
|
||||||
return externalDirectives.participantsPanel.template;
|
return externalDirectives.participantsPanel.template;
|
||||||
|
@ -279,10 +276,7 @@ export class TemplateManagerService {
|
||||||
/**
|
/**
|
||||||
* Sets up the activities panel template
|
* Sets up the activities panel template
|
||||||
*/
|
*/
|
||||||
private setupActivitiesPanelTemplate(
|
private setupActivitiesPanelTemplate(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateRef<any> {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateRef<any> {
|
|
||||||
if (externalDirectives.activitiesPanel) {
|
if (externalDirectives.activitiesPanel) {
|
||||||
this.log.d('Setting EXTERNAL ACTIVITIES PANEL');
|
this.log.d('Setting EXTERNAL ACTIVITIES PANEL');
|
||||||
return externalDirectives.activitiesPanel.template;
|
return externalDirectives.activitiesPanel.template;
|
||||||
|
@ -311,10 +305,7 @@ export class TemplateManagerService {
|
||||||
/**
|
/**
|
||||||
* Sets up the stream template
|
* Sets up the stream template
|
||||||
*/
|
*/
|
||||||
private setupStreamTemplate(
|
private setupStreamTemplate(externalDirectives: ExternalDirectives, defaultTemplates: DefaultTemplates): TemplateRef<any> {
|
||||||
externalDirectives: ExternalDirectives,
|
|
||||||
defaultTemplates: DefaultTemplates
|
|
||||||
): TemplateRef<any> {
|
|
||||||
if (externalDirectives.stream) {
|
if (externalDirectives.stream) {
|
||||||
this.log.d('Setting EXTERNAL STREAM');
|
this.log.d('Setting EXTERNAL STREAM');
|
||||||
return externalDirectives.stream.template;
|
return externalDirectives.stream.template;
|
||||||
|
@ -363,12 +354,14 @@ export class TemplateManagerService {
|
||||||
*/
|
*/
|
||||||
setupParticipantsPanelTemplates(
|
setupParticipantsPanelTemplates(
|
||||||
externalParticipantPanelItem?: ParticipantPanelItemDirective,
|
externalParticipantPanelItem?: ParticipantPanelItemDirective,
|
||||||
defaultParticipantPanelItem?: TemplateRef<any>
|
defaultParticipantPanelItem?: TemplateRef<any>,
|
||||||
|
externalParticipantPanelAfterLocalParticipant?: TemplateRef<any>
|
||||||
): ParticipantsPanelTemplateConfiguration {
|
): ParticipantsPanelTemplateConfiguration {
|
||||||
this.log.d('Setting up participants panel templates...');
|
this.log.d('Setting up participants panel templates...');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
participantPanelItemTemplate: externalParticipantPanelItem?.template || defaultParticipantPanelItem
|
participantPanelItemTemplate: externalParticipantPanelItem?.template || defaultParticipantPanelItem,
|
||||||
|
participantPanelAfterLocalParticipantTemplate: externalParticipantPanelAfterLocalParticipant
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ export * from './lib/components/toolbar/toolbar.component';
|
||||||
export * from './lib/components/videoconference/videoconference.component';
|
export * from './lib/components/videoconference/videoconference.component';
|
||||||
export * from './lib/config/openvidu-components-angular.config';
|
export * from './lib/config/openvidu-components-angular.config';
|
||||||
// Directives
|
// Directives
|
||||||
|
export * from './lib/directives/template/internals.directive';
|
||||||
export * from './lib/directives/api/activities-panel.directive';
|
export * from './lib/directives/api/activities-panel.directive';
|
||||||
export * from './lib/directives/api/admin.directive';
|
export * from './lib/directives/api/admin.directive';
|
||||||
export * from './lib/directives/api/api.directive.module';
|
export * from './lib/directives/api/api.directive.module';
|
||||||
|
|
Loading…
Reference in New Issue