openvidu-components: Updated openvidu-angular docs
|
@ -48,7 +48,7 @@ import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* <div style="text-align: center">
|
* <div style="text-align: center">
|
||||||
* <img src="../doc/toolbardirective-example.png"/>
|
* <img src="../assets/toolbardirective-example.png"/>
|
||||||
* </div>
|
* </div>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,8 @@ export class ToolbarDirective {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ***ovToolbarAdditionalButtons** directive allows to add additional buttons to the toolbar. We've added the same buttons as the {@link ToolbarDirective}.
|
* The ***ovToolbarAdditionalButtons** directive allows to add additional buttons to center buttons group.
|
||||||
|
* We've added the same buttons as the {@link ToolbarDirective}.
|
||||||
* Here we are using the {@link ParticipantService} fror checking the audio or video status.
|
* Here we are using the {@link ParticipantService} fror checking the audio or video status.
|
||||||
*
|
*
|
||||||
* _You can check the sample [here]()_.
|
* _You can check the sample [here]()_.
|
||||||
|
@ -111,7 +112,7 @@ export class ToolbarDirective {
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
* <div style="text-align: center">
|
* <div style="text-align: center">
|
||||||
* <img src="../doc/toolbarAdditionalButtonsDirective-example.png"/>
|
* <img src="../assets/toolbarAdditionalButtonsDirective-example.png"/>
|
||||||
* </div>
|
* </div>
|
||||||
*/
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
|
@ -124,6 +125,43 @@ export class ToolbarAdditionalButtonsDirective {
|
||||||
constructor(public template: TemplateRef<any>, public viewContainer: ViewContainerRef) {}
|
constructor(public template: TemplateRef<any>, public viewContainer: ViewContainerRef) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ***ovToolbarAdditionalPanelButtons** directive allows to add additional **panel buttons** to the toolbar.
|
||||||
|
* We've added a simple button without any functionality. For being able to toggle the panel you can see the {@link AdditionalPanelsDirective}.
|
||||||
|
*
|
||||||
|
* _You can check the sample [here]()_.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*```html
|
||||||
|
* <ov-videoconference (onJoinButtonClicked)="onJoinButtonClicked()" [tokens]="tokens">
|
||||||
|
* <div *ovToolbarAdditionalPanelButtons style="text-align: center;">
|
||||||
|
* <button>MY PANEL</button>
|
||||||
|
* </div>
|
||||||
|
* </ov-videoconference>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* export class ToolbarAdditionalPanelButtonsDirectiveComponent {
|
||||||
|
* tokens: TokenModel;
|
||||||
|
* sessionId = 'toolbar-additionalPanelbtn';
|
||||||
|
* OPENVIDU_URL = 'https://localhost:4443';
|
||||||
|
* OPENVIDU_SECRET = 'MY_SECRET';
|
||||||
|
*
|
||||||
|
* constructor(private restService: RestService) {}
|
||||||
|
*
|
||||||
|
* async onJoinButtonClicked() {
|
||||||
|
* this.tokens = {
|
||||||
|
* webcam: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET),
|
||||||
|
* screen: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET)
|
||||||
|
* };
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* <div style="text-align: center">
|
||||||
|
* <img src="../assets/toolbarAdditionalPanelButtonsDirective-example.png"/>
|
||||||
|
* </div>
|
||||||
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[ovToolbarAdditionalPanelButtons]'
|
selector: '[ovToolbarAdditionalPanelButtons]'
|
||||||
})
|
})
|
||||||
|
@ -135,6 +173,47 @@ export class ToolbarAdditionalPanelButtonsDirective {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ***ovPanel** directive allows to replace the default panels with yours. This directive also allows us insert elements
|
||||||
|
* tagged with the {@link ChatPanelDirective}, {@link ParticipantsPanelDirective} and {@link AdditionalPanelsDirective}.
|
||||||
|
*
|
||||||
|
* In this example we're going to replace the entire {@link PanelComponent} using the ***ovPanel** directive. Inside of it, we're customizing
|
||||||
|
* the {@link ParticipantsPanelComponent} and {@link ChatPanelcomponent} using theirs directives.
|
||||||
|
*
|
||||||
|
* _You can check the sample [here]()_.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*```html
|
||||||
|
* <ov-videoconference (onJoinButtonClicked)="onJoinButtonClicked()" [tokens]="tokens">
|
||||||
|
* <ov-panel *ovPanel>
|
||||||
|
* <div *ovChatPanel>This is my custom chat panel</div>
|
||||||
|
* <div *ovParticipantsPanel id="my-participants-panel">This is my custom participants panel</div>
|
||||||
|
* </ov-panel>
|
||||||
|
* </ov-videoconference>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* export class PanelDirectiveComponent {
|
||||||
|
* tokens: TokenModel;
|
||||||
|
* sessionId = 'panel-directive-example';
|
||||||
|
*
|
||||||
|
* OPENVIDU_URL = 'https://localhost:4443';
|
||||||
|
* OPENVIDU_SECRET = 'MY_SECRET';
|
||||||
|
*
|
||||||
|
* constructor(private restService: RestService) {}
|
||||||
|
*
|
||||||
|
* async onJoinButtonClicked() {
|
||||||
|
* this.tokens = {
|
||||||
|
* webcam: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET),
|
||||||
|
* screen: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET)
|
||||||
|
* };
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* <div style="text-align: center">
|
||||||
|
* <img src="../assets/panelDirective.gif"/>
|
||||||
|
* </div>
|
||||||
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[ovPanel]'
|
selector: '[ovPanel]'
|
||||||
})
|
})
|
||||||
|
@ -146,6 +225,73 @@ export class PanelDirective {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ***ovAdditionalPanels** directive allows to add more extra panels to the {@link PanelComponent}. In this example we've added a new
|
||||||
|
* panel besides the defaults.
|
||||||
|
*
|
||||||
|
* As we want to toggle this new panel as the others, we need to add a new button in the {@link ToolbarComponent}
|
||||||
|
* using the {@link ToolbarAdditionalPanelButtonsDirective}.
|
||||||
|
*
|
||||||
|
* _You can check the sample [here]()_.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*```html
|
||||||
|
* <ov-videoconference (onJoinButtonClicked)="onJoinButtonClicked()" [tokens]="tokens">
|
||||||
|
* <div *ovToolbarAdditionalPanelButtons style="text-align: center;">
|
||||||
|
* <button (click)="toggleMyPanel('my-panel')">MY PANEL</button>
|
||||||
|
* <button (click)="toggleMyPanel('my-panel2')">OTHER PANEL</button>
|
||||||
|
* </div>
|
||||||
|
* <div *ovAdditionalPanels id="my-panels">
|
||||||
|
* <div id="my-panel1" *ngIf="showExternalPanel">
|
||||||
|
* <h2>NEW PANEL</h2>
|
||||||
|
* <p>This is my new additional panel</p>
|
||||||
|
* </div>
|
||||||
|
* <div id="my-panel2" *ngIf="showExternalPanel2">
|
||||||
|
* <h2>NEW PANEL 2</h2>
|
||||||
|
* <p>This is other new panel</p>
|
||||||
|
* </div>
|
||||||
|
* </div>
|
||||||
|
* </ov-videoconference>
|
||||||
|
* ```
|
||||||
|
* <br/>
|
||||||
|
*
|
||||||
|
* We need to subscribe to the {@link ../injectables/PanelService.html#panelOpenedObs panelOpenedObs} Observable for listening the panel status and update our boolean variables
|
||||||
|
* (`showExternalPanel` and `showExternalPanel2`) for show and hide our panels.
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* export class AdditionalPanelsDirectiveComponent implements OnInit {
|
||||||
|
* tokens: TokenModel;
|
||||||
|
* sessionId = 'chat-panel-directive-example';
|
||||||
|
* OPENVIDU_URL = 'https://localhost:4443';
|
||||||
|
* OPENVIDU_SECRET = 'MY_SECRET';
|
||||||
|
* showExternalPanel: boolean = false;
|
||||||
|
* showExternalPanel2: boolean = false;
|
||||||
|
* constructor(private restService: RestService, private panelService: PanelService) {}
|
||||||
|
*
|
||||||
|
* ngOnInit() {
|
||||||
|
* this.subscribeToPanelToggling();
|
||||||
|
* }
|
||||||
|
* subscribeToPanelToggling() {
|
||||||
|
* this.panelService.panelOpenedObs.subscribe((ev: { opened: boolean; type?: PanelType | string }) => {
|
||||||
|
* this.showExternalPanel = ev.opened && ev.type === 'my-panel';
|
||||||
|
* this.showExternalPanel2 = ev.opened && ev.type === 'my-panel2';
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
* async onJoinButtonClicked() {
|
||||||
|
* this.tokens = {
|
||||||
|
* webcam: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET),
|
||||||
|
* screen: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET)
|
||||||
|
* };
|
||||||
|
* }
|
||||||
|
* toggleMyPanel(type: string) {
|
||||||
|
* this.panelService.togglePanel(type);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* <div style="text-align: center">
|
||||||
|
* <img src="../assets/additionalPanelsDirective-example.gif"/>
|
||||||
|
* </div>
|
||||||
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[ovAdditionalPanels]'
|
selector: '[ovAdditionalPanels]'
|
||||||
})
|
})
|
||||||
|
@ -181,14 +327,14 @@ export class AdditionalPanelsDirective {
|
||||||
* </div>
|
* </div>
|
||||||
* </ov-videoconference>
|
* </ov-videoconference>
|
||||||
*```
|
*```
|
||||||
|
* <br/>
|
||||||
*
|
*
|
||||||
|
* As we need to get the **openvidu-browser [Session](https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Session.html)**
|
||||||
|
* for sending messages to others, we can get it from the `onSessionCreated` event fired by the {@link VideoconferenceComponent}
|
||||||
|
* when the session has been created.
|
||||||
*
|
*
|
||||||
* As we need to get the OpenVidu Browser [Session](https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Session.html)
|
* Once we have the session created, we can use the
|
||||||
* for sending messages to others, we can get it from the `onSessionCreated` event fired by the {@link VideoconferenceComponent} when the session has been created.
|
* [signal](https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Session.html#signal) method for sending our messages.
|
||||||
*
|
|
||||||
* Once we have the session created, we can use the `signal` method for sending our messages.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* ```javascript
|
* ```javascript
|
||||||
* export class ChatPanelDirectiveComponent {
|
* export class ChatPanelDirectiveComponent {
|
||||||
|
@ -227,7 +373,7 @@ export class AdditionalPanelsDirective {
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* <div style="text-align: center">
|
* <div style="text-align: center">
|
||||||
* <img src="../doc/chatPanelDirective-example.png"/>
|
* <img src="../assets/chatPanelDirective-example.png"/>
|
||||||
* </div>
|
* </div>
|
||||||
*/
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
|
@ -307,7 +453,7 @@ export class ChatPanelDirective {
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* <div style="text-align: center">
|
* <div style="text-align: center">
|
||||||
* <img src="../doc/participantsPanelDirective-example.png"/>
|
* <img src="../assets/participantsPanelDirective-example.png"/>
|
||||||
* </div>
|
* </div>
|
||||||
*/
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
|
@ -317,6 +463,54 @@ export class ParticipantsPanelDirective {
|
||||||
constructor(public template: TemplateRef<any>, public viewContainer: ViewContainerRef) {}
|
constructor(public template: TemplateRef<any>, public viewContainer: ViewContainerRef) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ***ovParticipantPanelItem** directive allows to replace the default participant panel item template in the {@link ParticipantsPanelComponent} injecting your own component.
|
||||||
|
*
|
||||||
|
* With ***ovParticipantPanelItem** directive we can access to the participant object from its context using
|
||||||
|
* the `let` keyword and referencing to the `participant` variable: `*ovParticipantPanelItem="let participant"`.
|
||||||
|
* Now we can access to the {@link ParticipantAbstractModel} object.
|
||||||
|
*
|
||||||
|
* _You can check the sample [here]()_.
|
||||||
|
*
|
||||||
|
* ```html
|
||||||
|
* <ov-videoconference (onJoinButtonClicked)="onJoinButtonClicked()" [tokens]="tokens">
|
||||||
|
* <div *ovParticipantPanelItem="let participant" style="display: flex">
|
||||||
|
* <p>{{ participant.nickname }}</p>
|
||||||
|
* <button mat-icon-button [matMenuTriggerFor]="menu"><mat-icon>more_vert</mat-icon></button>
|
||||||
|
* <mat-menu #menu="matMenu">
|
||||||
|
* <button mat-menu-item>Button 1</button>
|
||||||
|
* <button mat-menu-item>Button 2</button>
|
||||||
|
* </mat-menu>
|
||||||
|
* </div>
|
||||||
|
* </ov-videoconference>
|
||||||
|
*```
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* export class ParticipantPanelItemDirectiveComponent {
|
||||||
|
* tokens: TokenModel;
|
||||||
|
* sessionId = 'participants-panel-directive-example';
|
||||||
|
* OPENVIDU_URL = 'https://localhost:4443';
|
||||||
|
* OPENVIDU_SECRET = 'MY_SECRET';
|
||||||
|
*
|
||||||
|
* constructor(private restService: RestService) {}
|
||||||
|
*
|
||||||
|
* async onJoinButtonClicked() {
|
||||||
|
* this.tokens = {
|
||||||
|
* webcam: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET),
|
||||||
|
* screen: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET)
|
||||||
|
* };
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* <div style="text-align: center">
|
||||||
|
* <img src="../assets/participantPanelItemDirective-example.gif"/>
|
||||||
|
* </div>
|
||||||
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[ovParticipantPanelItem]'
|
selector: '[ovParticipantPanelItem]'
|
||||||
})
|
})
|
||||||
|
@ -324,6 +518,54 @@ export class ParticipantPanelItemDirective {
|
||||||
constructor(public template: TemplateRef<any>, public viewContainer: ViewContainerRef) {}
|
constructor(public template: TemplateRef<any>, public viewContainer: ViewContainerRef) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ***ovParticipantPanelItemElements** directive allows to add elements to the {@link ParticipantsPanelItemComponent}.
|
||||||
|
* Here we're going to add a simple button for disconnecting to the session.
|
||||||
|
*
|
||||||
|
* With ***ovParticipantPanelItemElements** directive we can access to the participant object from its context using
|
||||||
|
* the `let` keyword and referencing to the `participant` variable: `*ovParticipantPanelItem="let participant"`.
|
||||||
|
* Now we can access to the {@link ParticipantAbstractModel} object and enable the button just for local participants.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* _You can check the sample [here]()_.
|
||||||
|
*
|
||||||
|
* ```html
|
||||||
|
* <ov-videoconference (onJoinButtonClicked)="onJoinButtonClicked()" [tokens]="tokens">
|
||||||
|
* <div *ovParticipantPanelItemElements="let participant">
|
||||||
|
* <button *ngIf="participant.local" (click)="leaveSession()">Leave</button>
|
||||||
|
* </div>
|
||||||
|
* </ov-videoconference>
|
||||||
|
*```
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* export class ParticipantPanelItemElementsDirectiveComponent {
|
||||||
|
* tokens: TokenModel;
|
||||||
|
* sessionId = 'participants-panel-directive-example';
|
||||||
|
* OPENVIDU_URL = 'https://localhost:4443';
|
||||||
|
* OPENVIDU_SECRET = 'MY_SECRET';
|
||||||
|
*
|
||||||
|
* constructor(private restService: RestService, private openviduService: OpenViduService) {}
|
||||||
|
*
|
||||||
|
* async onJoinButtonClicked() {
|
||||||
|
* this.tokens = {
|
||||||
|
* webcam: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET),
|
||||||
|
* screen: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET)
|
||||||
|
* };
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* leaveSession() {
|
||||||
|
* this.openviduService.disconnect();
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* <div style="text-align: center">
|
||||||
|
* <img src="../assets/participantPanelItemElementsDirective-example.gif"/>
|
||||||
|
* </div>
|
||||||
|
*/
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[ovParticipantPanelItemElements]'
|
selector: '[ovParticipantPanelItemElements]'
|
||||||
})
|
})
|
||||||
|
@ -402,7 +644,7 @@ export class ParticipantPanelItemElementsDirective {
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* <div style="text-align: center">
|
* <div style="text-align: center">
|
||||||
* <img src="../doc/layoutDirective-example.png"/>
|
* <img src="../assets/layoutDirective-example.png"/>
|
||||||
* </div>
|
* </div>
|
||||||
*/
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
|
@ -448,7 +690,7 @@ export class LayoutDirective {
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
* <div style="text-align: center">
|
* <div style="text-align: center">
|
||||||
* <img src="../doc/streamDirective-example.png"/>
|
* <img src="../assets/streamDirective-example.png"/>
|
||||||
* </div>
|
* </div>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -60,6 +60,10 @@ export class OpenViduService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns the local Session. See {@link https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Session.html Session} object.
|
||||||
|
*/
|
||||||
getSession(): Session {
|
getSession(): Session {
|
||||||
return this.getWebcamSession();
|
return this.getWebcamSession();
|
||||||
}
|
}
|
||||||
|
@ -121,7 +125,7 @@ export class OpenViduService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* Leaves the session, destroying all local streams and clean all participant data.
|
||||||
*/
|
*/
|
||||||
disconnect() {
|
disconnect() {
|
||||||
this.disconnectSession(this.webcamSession);
|
this.disconnectSession(this.webcamSession);
|
||||||
|
@ -220,6 +224,11 @@ export class OpenViduService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish or unpublish the video stream (if available).
|
||||||
|
* It hides the camera muted stream if screen is sharing.
|
||||||
|
* See openvidu-browser {@link https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Publisher.html#publishVideo publishVideo}
|
||||||
|
*/
|
||||||
async publishVideo(publish: boolean): Promise<void> {
|
async publishVideo(publish: boolean): Promise<void> {
|
||||||
const publishAudio = this.participantService.isMyAudioActive();
|
const publishAudio = this.participantService.isMyAudioActive();
|
||||||
|
|
||||||
|
@ -258,6 +267,10 @@ export class OpenViduService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish or unpublish the audio stream (if available).
|
||||||
|
* See openvidu-browser {@link https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Publisher.html#publishAudio publishAudio}.
|
||||||
|
*/
|
||||||
async publishAudio(publish: boolean): Promise<void> {
|
async publishAudio(publish: boolean): Promise<void> {
|
||||||
if (this.participantService.isMyCameraActive()) {
|
if (this.participantService.isMyCameraActive()) {
|
||||||
if (this.participantService.isMyScreenActive() && this.participantService.hasScreenAudioActive()) {
|
if (this.participantService.isMyScreenActive() && this.participantService.hasScreenAudioActive()) {
|
||||||
|
@ -270,6 +283,10 @@ export class OpenViduService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Share or unshare the screen.
|
||||||
|
* Hide the camera muted stream when screen is sharing.
|
||||||
|
*/
|
||||||
async toggleScreenshare() {
|
async toggleScreenshare() {
|
||||||
if (this.participantService.haveICameraAndScreenActive()) {
|
if (this.participantService.haveICameraAndScreenActive()) {
|
||||||
// Disabling screenShare
|
// Disabling screenShare
|
||||||
|
@ -521,6 +538,11 @@ export class OpenViduService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns the remote connections of the Session.
|
||||||
|
* See {@link https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Connection.html Connection} object.
|
||||||
|
*/
|
||||||
getRemoteConnections(): Connection[] {
|
getRemoteConnections(): Connection[] {
|
||||||
// Avoid screen connections
|
// Avoid screen connections
|
||||||
const remoteCameraConnections: Connection[] = Array.from(this.webcamSession.remoteConnections.values()).filter((conn) => {
|
const remoteCameraConnections: Connection[] = Array.from(this.webcamSession.remoteConnections.values()).filter((conn) => {
|
||||||
|
|
|
@ -8,6 +8,9 @@ import { LoggerService } from '../logger/logger.service';
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class PanelService {
|
export class PanelService {
|
||||||
|
/**
|
||||||
|
* Panel Observable which pushes the panel status in every update.
|
||||||
|
*/
|
||||||
panelOpenedObs: Observable<{ opened: boolean; type?: PanelType | string }>;
|
panelOpenedObs: Observable<{ opened: boolean; type?: PanelType | string }>;
|
||||||
protected log: ILogger;
|
protected log: ILogger;
|
||||||
protected isChatOpened: boolean = false;
|
protected isChatOpened: boolean = false;
|
||||||
|
@ -24,6 +27,10 @@ export class PanelService {
|
||||||
this.panelOpenedObs = this._panelOpened.asObservable();
|
this.panelOpenedObs = this._panelOpened.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open or close the panel type received. Calling this method with the panel opened and the same type panel, will closes the panel.
|
||||||
|
* If the type is differente, it will switch to the properly panel.
|
||||||
|
*/
|
||||||
togglePanel(type: PanelType | string) {
|
togglePanel(type: PanelType | string) {
|
||||||
this.log.d(`Toggling ${type} menu`);
|
this.log.d(`Toggling ${type} menu`);
|
||||||
let opened: boolean;
|
let opened: boolean;
|
||||||
|
@ -57,6 +64,9 @@ export class PanelService {
|
||||||
return this.isChatPanelOpened() || this.isParticipantsPanelOpened() || this.isExternalPanelOpened();
|
return this.isChatPanelOpened() || this.isParticipantsPanelOpened() || this.isExternalPanelOpened();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the panel (if opened)
|
||||||
|
*/
|
||||||
closePanel(): void {
|
closePanel(): void {
|
||||||
this.isParticipantsOpened = false;
|
this.isParticipantsOpened = false;
|
||||||
this.isChatOpened = false;
|
this.isChatOpened = false;
|
||||||
|
@ -64,10 +74,16 @@ export class PanelService {
|
||||||
this._panelOpened.next({ opened: false });
|
this._panelOpened.next({ opened: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the chat panel is opened or not.
|
||||||
|
*/
|
||||||
isChatPanelOpened(): boolean {
|
isChatPanelOpened(): boolean {
|
||||||
return this.isChatOpened;
|
return this.isChatOpened;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the participants panel is opened or not.
|
||||||
|
*/
|
||||||
isParticipantsPanelOpened(): boolean {
|
isParticipantsPanelOpened(): boolean {
|
||||||
return this.isParticipantsOpened;
|
return this.isParticipantsOpened;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,15 @@ import { LoggerService } from '../logger/logger.service';
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class ParticipantService {
|
export class ParticipantService {
|
||||||
|
/**
|
||||||
|
* Local participant Observable which pushes the local participant object in every update.
|
||||||
|
*/
|
||||||
localParticipantObs: Observable<ParticipantAbstractModel>;
|
localParticipantObs: Observable<ParticipantAbstractModel>;
|
||||||
protected _localParticipant = <BehaviorSubject<ParticipantAbstractModel>>new BehaviorSubject(null);
|
protected _localParticipant = <BehaviorSubject<ParticipantAbstractModel>>new BehaviorSubject(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote participants Observable which pushes the remote participants array in every update.
|
||||||
|
*/
|
||||||
remoteParticipantsObs: Observable<ParticipantAbstractModel[]>;
|
remoteParticipantsObs: Observable<ParticipantAbstractModel[]>;
|
||||||
protected _remoteParticipants = <BehaviorSubject<ParticipantAbstractModel[]>>new BehaviorSubject([]);
|
protected _remoteParticipants = <BehaviorSubject<ParticipantAbstractModel[]>>new BehaviorSubject([]);
|
||||||
|
|
||||||
|
@ -217,7 +223,6 @@ export class ParticipantService {
|
||||||
return this.isMyCameraActive() && this.isMyScreenActive();
|
return this.isMyCameraActive() && this.isMyScreenActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
@ -225,6 +230,9 @@ export class ParticipantService {
|
||||||
return this.localParticipant.isScreenAudioActive();
|
return this.localParticipant.isScreenAudioActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force to update the local participant object and fire a new {@link localParticipantObs} Observable event.
|
||||||
|
*/
|
||||||
updateLocalParticipant() {
|
updateLocalParticipant() {
|
||||||
this._localParticipant.next(Object.assign(Object.create(this.localParticipant), this.localParticipant));
|
this._localParticipant.next(Object.assign(Object.create(this.localParticipant), this.localParticipant));
|
||||||
}
|
}
|
||||||
|
@ -381,6 +389,9 @@ export class ParticipantService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force to update the remote participants object and fire a new {@link remoteParticipantsObs} Observable event.
|
||||||
|
*/
|
||||||
updateRemoteParticipants() {
|
updateRemoteParticipants() {
|
||||||
this._remoteParticipants.next([...this.remoteParticipants]);
|
this._remoteParticipants.next([...this.remoteParticipants]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ export * from './lib/models/video-type.model';
|
||||||
export * from './lib/models/notification-options.model';
|
export * from './lib/models/notification-options.model';
|
||||||
export * from './lib/models/token.model';
|
export * from './lib/models/token.model';
|
||||||
export * from './lib/models/signal.model';
|
export * from './lib/models/signal.model';
|
||||||
|
export * from './lib/models/panel.model';
|
||||||
|
|
||||||
// Pipes
|
// Pipes
|
||||||
export * from './lib/pipes/participant.pipe';
|
export * from './lib/pipes/participant.pipe';
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { PanelService, TokenModel, PanelType } from 'openvidu-angular';
|
||||||
|
import { RestService } from 'src/app/services/rest.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-chatPanel-directive',
|
||||||
|
template: `
|
||||||
|
<ov-videoconference (onJoinButtonClicked)="onJoinButtonClicked()" [tokens]="tokens" [toolbarDisplaySessionName]="false">
|
||||||
|
<div *ovToolbarAdditionalPanelButtons style="text-align: center;">
|
||||||
|
<button (click)="toggleMyPanel('my-panel')">MY PANEL</button>
|
||||||
|
<button (click)="toggleMyPanel('my-panel2')">OTHER PANEL</button>
|
||||||
|
</div>
|
||||||
|
<div *ovAdditionalPanels id="my-panels">
|
||||||
|
<div id="my-panel1" *ngIf="showExternalPanel">
|
||||||
|
<h2>NEW PANEL</h2>
|
||||||
|
<p>This is my new additional panel</p>
|
||||||
|
</div>
|
||||||
|
<div id="my-panel2" *ngIf="showExternalPanel2">
|
||||||
|
<h2>NEW PANEL 2</h2>
|
||||||
|
<p>This is other new panel</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ov-videoconference>
|
||||||
|
`,
|
||||||
|
styles: [
|
||||||
|
`
|
||||||
|
#my-panels {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#my-panel1, #my-panel2 {
|
||||||
|
text-align: center;
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
#my-panel1 {
|
||||||
|
background: #c9ffb2;
|
||||||
|
}
|
||||||
|
#my-panel2 {
|
||||||
|
background: #ddf2ff;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AdditionalPanelsDirectiveComponent implements OnInit {
|
||||||
|
tokens: TokenModel;
|
||||||
|
sessionId = 'chat-panel-directive-example';
|
||||||
|
OPENVIDU_URL = 'https://localhost:4443';
|
||||||
|
OPENVIDU_SECRET = 'MY_SECRET';
|
||||||
|
showExternalPanel: boolean = false;
|
||||||
|
showExternalPanel2: boolean = false;
|
||||||
|
constructor(private restService: RestService, private panelService: PanelService) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.subscribeToPanelToggling();
|
||||||
|
}
|
||||||
|
subscribeToPanelToggling() {
|
||||||
|
this.panelService.panelOpenedObs.subscribe((ev: { opened: boolean; type?: PanelType | string }) => {
|
||||||
|
this.showExternalPanel = ev.opened && ev.type === 'my-panel';
|
||||||
|
this.showExternalPanel2 = ev.opened && ev.type === 'my-panel2';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async onJoinButtonClicked() {
|
||||||
|
this.tokens = {
|
||||||
|
webcam: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET),
|
||||||
|
screen: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
toggleMyPanel(type: string) {
|
||||||
|
this.panelService.togglePanel(type);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { TokenModel } from 'openvidu-angular';
|
||||||
|
import { RestService } from 'src/app/services/rest.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-toolbarAdditionalButtons-directive',
|
||||||
|
template: `
|
||||||
|
<ov-videoconference (onJoinButtonClicked)="onJoinButtonClicked()" [tokens]="tokens" [toolbarDisplaySessionName]="false">
|
||||||
|
<div *ovToolbarAdditionalPanelButtons style="text-align: center;">
|
||||||
|
<button>MY PANEL</button>
|
||||||
|
</div>
|
||||||
|
</ov-videoconference>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
export class ToolbarAdditionalPanelButtonsDirectiveComponent {
|
||||||
|
tokens: TokenModel;
|
||||||
|
sessionId = 'toolbar-additionalPanelbtn';
|
||||||
|
OPENVIDU_URL = 'https://localhost:4443';
|
||||||
|
OPENVIDU_SECRET = 'MY_SECRET';
|
||||||
|
|
||||||
|
constructor(private restService: RestService) {}
|
||||||
|
|
||||||
|
async onJoinButtonClicked() {
|
||||||
|
this.tokens = {
|
||||||
|
webcam: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET),
|
||||||
|
screen: await this.restService.getToken(this.sessionId, this.OPENVIDU_URL, this.OPENVIDU_SECRET)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,5 +16,5 @@
|
||||||
"theme": "gitbook",
|
"theme": "gitbook",
|
||||||
"customFavicon": "src/favicon.ico",
|
"customFavicon": "src/favicon.ico",
|
||||||
"extTheme": "src/doc/",
|
"extTheme": "src/doc/",
|
||||||
"assetsFolder": "src/assets/doc"
|
"assetsFolder": "src/doc/assets"
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 22 MiB |
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 274 KiB |
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
After Width: | Height: | Size: 6.4 MiB |
After Width: | Height: | Size: 20 MiB |
After Width: | Height: | Size: 5.9 MiB |
Before Width: | Height: | Size: 211 KiB After Width: | Height: | Size: 211 KiB |
Before Width: | Height: | Size: 383 KiB After Width: | Height: | Size: 383 KiB |
Before Width: | Height: | Size: 387 KiB After Width: | Height: | Size: 387 KiB |
After Width: | Height: | Size: 546 KiB |
Before Width: | Height: | Size: 459 KiB After Width: | Height: | Size: 459 KiB |
|
@ -87,7 +87,15 @@ code {
|
||||||
background-color: #FFFBF1;
|
background-color: #FFFBF1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark .warn-container {
|
||||||
|
background-color: #6b6045;
|
||||||
|
}
|
||||||
|
|
||||||
.info-container {
|
.info-container {
|
||||||
border: 2px solid #0077ff;
|
border: 2px solid #0077ff;
|
||||||
background-color: #f1feff;
|
background-color: #f1feff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark .info-container {
|
||||||
|
background-color: #556d6e;
|
||||||
|
}
|