openvidu-components: Updated openvidu-angular docs

pull/713/head
csantosm 2022-04-07 10:03:50 +02:00
parent 027508acd3
commit 70e93df54d
20 changed files with 418 additions and 17 deletions

View File

@ -48,7 +48,7 @@ import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
* ```
*
* <div style="text-align: center">
* <img src="../doc/toolbardirective-example.png"/>
* <img src="../assets/toolbardirective-example.png"/>
* </div>
*
*/
@ -63,8 +63,9 @@ export class ToolbarDirective {
}
/**
* The ***ovToolbarAdditionalButtons** directive allows to add additional buttons to the toolbar. We've added the same buttons as the {@link ToolbarDirective}.
* Here we are using the {@link ParticipantService} fror checking the audio or video status.
* 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.
*
* _You can check the sample [here]()_.
*
@ -111,7 +112,7 @@ export class ToolbarDirective {
* }
* ```
* <div style="text-align: center">
* <img src="../doc/toolbarAdditionalButtonsDirective-example.png"/>
* <img src="../assets/toolbarAdditionalButtonsDirective-example.png"/>
* </div>
*/
@Directive({
@ -124,6 +125,43 @@ export class ToolbarAdditionalButtonsDirective {
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({
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({
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({
selector: '[ovAdditionalPanels]'
})
@ -181,14 +327,14 @@ export class AdditionalPanelsDirective {
* </div>
* </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)
* for sending messages to others, we can get it from the `onSessionCreated` event fired by the {@link VideoconferenceComponent} when the session has been created.
*
* Once we have the session created, we can use the `signal` method for sending our messages.
*
*
* Once we have the session created, we can use the
* [signal](https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Session.html#signal) method for sending our messages.
*
* ```javascript
* export class ChatPanelDirectiveComponent {
@ -227,7 +373,7 @@ export class AdditionalPanelsDirective {
* ```
*
* <div style="text-align: center">
* <img src="../doc/chatPanelDirective-example.png"/>
* <img src="../assets/chatPanelDirective-example.png"/>
* </div>
*/
@Directive({
@ -307,7 +453,7 @@ export class ChatPanelDirective {
* ```
*
* <div style="text-align: center">
* <img src="../doc/participantsPanelDirective-example.png"/>
* <img src="../assets/participantsPanelDirective-example.png"/>
* </div>
*/
@Directive({
@ -317,6 +463,54 @@ export class ParticipantsPanelDirective {
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({
selector: '[ovParticipantPanelItem]'
})
@ -324,6 +518,54 @@ export class ParticipantPanelItemDirective {
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({
selector: '[ovParticipantPanelItemElements]'
})
@ -402,7 +644,7 @@ export class ParticipantPanelItemElementsDirective {
* ```
*
* <div style="text-align: center">
* <img src="../doc/layoutDirective-example.png"/>
* <img src="../assets/layoutDirective-example.png"/>
* </div>
*/
@Directive({
@ -448,7 +690,7 @@ export class LayoutDirective {
* }
* ```
* <div style="text-align: center">
* <img src="../doc/streamDirective-example.png"/>
* <img src="../assets/streamDirective-example.png"/>
* </div>
*
*/

View File

@ -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 {
return this.getWebcamSession();
}
@ -121,7 +125,7 @@ export class OpenViduService {
}
/**
* @internal
* Leaves the session, destroying all local streams and clean all participant data.
*/
disconnect() {
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> {
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> {
if (this.participantService.isMyCameraActive()) {
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() {
if (this.participantService.haveICameraAndScreenActive()) {
// 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[] {
// Avoid screen connections
const remoteCameraConnections: Connection[] = Array.from(this.webcamSession.remoteConnections.values()).filter((conn) => {

View File

@ -8,6 +8,9 @@ import { LoggerService } from '../logger/logger.service';
providedIn: 'root'
})
export class PanelService {
/**
* Panel Observable which pushes the panel status in every update.
*/
panelOpenedObs: Observable<{ opened: boolean; type?: PanelType | string }>;
protected log: ILogger;
protected isChatOpened: boolean = false;
@ -24,6 +27,10 @@ export class PanelService {
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) {
this.log.d(`Toggling ${type} menu`);
let opened: boolean;
@ -57,6 +64,9 @@ export class PanelService {
return this.isChatPanelOpened() || this.isParticipantsPanelOpened() || this.isExternalPanelOpened();
}
/**
* Closes the panel (if opened)
*/
closePanel(): void {
this.isParticipantsOpened = false;
this.isChatOpened = false;
@ -64,10 +74,16 @@ export class PanelService {
this._panelOpened.next({ opened: false });
}
/**
* Whether the chat panel is opened or not.
*/
isChatPanelOpened(): boolean {
return this.isChatOpened;
}
/**
* Whether the participants panel is opened or not.
*/
isParticipantsPanelOpened(): boolean {
return this.isParticipantsOpened;
}

View File

@ -11,9 +11,15 @@ import { LoggerService } from '../logger/logger.service';
providedIn: 'root'
})
export class ParticipantService {
/**
* Local participant Observable which pushes the local participant object in every update.
*/
localParticipantObs: Observable<ParticipantAbstractModel>;
protected _localParticipant = <BehaviorSubject<ParticipantAbstractModel>>new BehaviorSubject(null);
/**
* Remote participants Observable which pushes the remote participants array in every update.
*/
remoteParticipantsObs: Observable<ParticipantAbstractModel[]>;
protected _remoteParticipants = <BehaviorSubject<ParticipantAbstractModel[]>>new BehaviorSubject([]);
@ -217,7 +223,6 @@ export class ParticipantService {
return this.isMyCameraActive() && this.isMyScreenActive();
}
/**
* @internal
*/
@ -225,6 +230,9 @@ export class ParticipantService {
return this.localParticipant.isScreenAudioActive();
}
/**
* Force to update the local participant object and fire a new {@link localParticipantObs} Observable event.
*/
updateLocalParticipant() {
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() {
this._remoteParticipants.next([...this.remoteParticipants]);
}

View File

@ -43,6 +43,7 @@ export * from './lib/models/video-type.model';
export * from './lib/models/notification-options.model';
export * from './lib/models/token.model';
export * from './lib/models/signal.model';
export * from './lib/models/panel.model';
// Pipes
export * from './lib/pipes/participant.pipe';

View File

@ -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);
}
}

View File

@ -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)
};
}
}

View File

@ -16,5 +16,5 @@
"theme": "gitbook",
"customFavicon": "src/favicon.ico",
"extTheme": "src/doc/",
"assetsFolder": "src/assets/doc"
"assetsFolder": "src/doc/assets"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 MiB

View File

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 MiB

View File

Before

Width:  |  Height:  |  Size: 383 KiB

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 KiB

View File

@ -87,7 +87,15 @@ code {
background-color: #FFFBF1;
}
.dark .warn-container {
background-color: #6b6045;
}
.info-container {
border: 2px solid #0077ff;
background-color: #f1feff;
}
.dark .info-container {
background-color: #556d6e;
}