UNPKG

angular-openvidu

Version:

Simple, robust, OpenVidu room videochat component for Angular

209 lines (184 loc) 9.89 kB
<opv-template #openviduApi="openviduApi" [wsUrl]="wsUrl" [sessionId]="sessionId" [participantId]="participantId" (updateMainSpeaker)="handleOnUpdateMainSpeaker($event)" (serverConnected)="handleOnServerConnected()" (errorServer)="handleOnErrorServer($event)" (roomConnected)="handleOnRoomConnected($event)" (errorRoom)="handleOnErrorRoom($event)" (cameraAccessChange)="handleOnCameraAccessChange($event)" (participantJoined)="handleOnParticipantJoined($event)" (participantLeft)="handleOnParticipantLeft($event)" (streamAdded)="handleOnStreamAdded($event)" (streamRemoved)="handleOnStreamRemoved($event)" (errorMedia)="handleOnErrorMedia($event)" (leaveRoom)="handleOnLeaveRoom()" (newMessage)="handleOnNewMessage($event)" (customNotification)="handleOnCustomNotification($event)"> <div #main class="openvidu-gotomeeting" [ngClass]="{'fullscreen': isFullscreen}"> <!-- WELCOME MESSAGE --> <div id="welcome" *ngIf="welcome"> <header class="room-connecting-content-header"> <h1>{{_intl.youAreEnteringRoomLabel}}</h1> </header> <section class="body" *ngIf="connectionUiState == ConnectionState.NOT_CONNECTED"> <div class="spinner"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" x="0px" y="0px" viewBox="0 0 512 512" width="100" height="100"> <g transform="translate(1, 42)"> <path class="ring" d="M277.334 1.088v-42.666c124.33 10.283 223.317 109.269 233.6 233.6h-42.666c-10.048-100.65-90.304-180.906-190.934-190.933zM234.667 425.579v42.666c-124.331-10.262-223.317-109.248-233.6-233.578h42.666c10.048 100.629 90.304 180.886 190.934 190.912zM43.755 192h-42.666c10.261-124.33 109.248-223.317 233.578-233.6v42.666c-100.63 10.048-180.886 90.304-190.912 190.934zM468.245 234.667h42.666c-10.262 124.331-109.248 223.317-233.579 233.6v-42.666c100.63-10.048 180.885-90.304 190.912-190.934z" ></path> <path class="segment" d="M234.667 425.579v42.666c-124.331-10.262-223.317-109.248-233.6-233.578h42.666c10.048 100.629 90.304 180.886 190.934 190.912z"></path> </g> </svg> </div> <p class="text-state">{{_intl.connectingLabel}}</p> </section> <section class="body" *ngIf="connectionUiState == ConnectionState.CONNECTED_TO_SERVER"> <div class="spinner"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" x="0px" y="0px" viewBox="0 0 512 512" width="100" height="100"> <g transform="translate(1, 42)"> <path class="ring" d="M277.334 1.088v-42.666c124.33 10.283 223.317 109.269 233.6 233.6h-42.666c-10.048-100.65-90.304-180.906-190.934-190.933zM234.667 425.579v42.666c-124.331-10.262-223.317-109.248-233.6-233.578h42.666c10.048 100.629 90.304 180.886 190.934 190.912zM43.755 192h-42.666c10.261-124.33 109.248-223.317 233.578-233.6v42.666c-100.63 10.048-180.886 90.304-190.912 190.934zM468.245 234.667h42.666c-10.262 124.331-109.248 223.317-233.579 233.6v-42.666c100.63-10.048 180.885-90.304 190.912-190.934z" ></path> <path class="segment" d="M234.667 425.579v42.666c-124.331-10.262-223.317-109.248-233.6-233.578h42.666c10.048 100.629 90.304 180.886 190.934 190.912z"></path> </g> </svg> </div> <p class="text-state">{{_intl.joiningRoomLabel}}</p> </section> <section class="body" *ngIf="connectionUiState == ConnectionState.CONNECTED_TO_ROOM || connectionUiState == ConnectionState.REQUESTING_CAMERA_ACCESS"> <div class="spinner"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" x="0px" y="0px" viewBox="0 0 512 512" width="100" height="100"> <g transform="translate(1, 42)"> <path class="ring" d="M277.334 1.088v-42.666c124.33 10.283 223.317 109.269 233.6 233.6h-42.666c-10.048-100.65-90.304-180.906-190.934-190.933zM234.667 425.579v42.666c-124.331-10.262-223.317-109.248-233.6-233.578h42.666c10.048 100.629 90.304 180.886 190.934 190.912zM43.755 192h-42.666c10.261-124.33 109.248-223.317 233.578-233.6v42.666c-100.63 10.048-180.886 90.304-190.912 190.934zM468.245 234.667h42.666c-10.262 124.331-109.248 223.317-233.579 233.6v-42.666c100.63-10.048 180.885-90.304 190.912-190.934z" ></path> <path class="segment" d="M234.667 425.579v42.666c-124.331-10.262-223.317-109.248-233.6-233.578h42.666c10.048 100.629 90.304 180.886 190.934 190.912z"></path> </g> </svg> </div> <p class="text-state">{{_intl.loadingCameraLabel}}</p> </section> <section class="body" *ngIf="connectionUiState == ConnectionState.CAMERA_ACCESS_DENIED"> <h2>{{_intl.browserBlockingLabel}}</h2> <figure> <img src="https://d1x2efl61akomv.cloudfront.net/images/blocked-camera-chrome.4c7620aa.png" height="38"> </figure> <p class="text">{{_intl.browserBlockingExplainOneLabel}}</p> <p class="text">{{_intl.browserBlockingExplainTwoLabel}}</p> </section> </div> <!-- GOODBYE MESSAGE --> <div class="feedback-wrapper" *ngIf="!session && !welcome"> <div class="thank-you-message"> <p class="body">{{_intl.youLeftTheRoomLabel}}</p> </div> </div> <div class="wrapper" *ngIf="session && !welcome"> <!-- SIDENAV --> <mat-sidenav-container> <mat-sidenav #sidenav align="end" mode="side" (close-start)="onSidenavCloseStart()"> <div class="people" *ngIf="showPeople"> <button class="close" (click)="togglePeople()"> <mat-icon>close</mat-icon> </button> <h2>{{_intl.peopleLabel}}</h2> <ul> <li *ngFor="let key of participants | ObjNgFor"> <p> {{JSON.parse(participants[key].data).username}} </p> </li> </ul> </div> <div class="chat" *ngIf="showChat"> <button class="close" (click)="toggleChat()"> <mat-icon>close</mat-icon> </button> <h2>{{_intl.chatLabel}}</h2> <ul> <li *ngFor="let message of chatMessages" [ngClass]="{'me': message.username == participantId}"> <p> {{message.message}} </p> </li> </ul> <div class="message-input-container" (submit)="sendMessage(messageInput.value);" accept-charset="UTF-8"> <form> <mat-form-field color="primary" floatPlaceholder="never"> <input matInput #messageInput placeholder="{{_intl.sendAMessageLabel}}"> </mat-form-field> </form> </div> </div> </mat-sidenav> <div class="mat-sidenav-content"> <div class="panel"> <horizontal-split-pane primary-component-minsize="50" secondary-component-minsize="50" local-storage-key="split-pane" primary-component-initialratio="0.5" [secondary-component-toggled-off]="!showSecondaryContent" (on-change)="onChangeSplitPane()"> <div class="split-pane-content-primary"> <!-- PANEL VIDEO --> <div #panelVideo class="panel-videos"> <div class="stream-flex"> <opv-stream-gotomeeting #streamGoToMeeting *ngFor="let s of streams" class="stream" [stream]="s" [style.max-width]="streamMaxWidth" [style.max-height]="streamMaxHeight" (sourceAdded)="handleOnSourceAdded()"> </opv-stream-gotomeeting> </div> </div> </div> <div class="split-pane-content-secondary"> <!-- PANEL CONTENT --> <div #panelContent class="panel-content"> <ng-content></ng-content> </div> </div> </horizontal-split-pane> </div> <!-- BUTTONS --> <div class="buttons"> <div class="up"> <button mat-button class="close-session" (click)="leaveRoom()" title="{{_intl.leaveRoomLabel}}"> <mat-icon>close</mat-icon> <div>{{_intl.leaveRoomLabel}}</div> </button> <button mat-icon-button class="toggle-mic" [ngClass]="{'disabled': !openviduApi.micEnabled}" (click)="toggleMic()" matTooltip="{{(openviduApi.micEnabled) ? _intl.muteLabel : _intl.unmuteLabel}}" matTooltipPosition="left"> <mat-icon>mic</mat-icon> <mat-icon class="disabled-icon">mic_off</mat-icon> </button> <button mat-icon-button class="toggle-camera" [ngClass]="{'disabled': !openviduApi.camEnabled}" (click)="toggleCamera()" matTooltip="{{(openviduApi.micEnabled) ? _intl.videoOffLabel : _intl.videoOnLabel}}" matTooltipPosition="left"> <mat-icon>videocam</mat-icon> <mat-icon class="disabled-icon">videocam_off</mat-icon> </button> </div> <hr /> <div class="middle"> <button mat-button class="show-people" [ngClass]="{'active': showPeople}" (click)="togglePeople()" matTooltip="{{_intl.peopleLabel}}" matTooltipPosition="left"> <mat-icon>people</mat-icon> </button> <button mat-button class="show-chat" [ngClass]="{'active': showChat}" (click)="toggleChat()" matTooltip="{{_intl.chatLabel}}" matTooltipPosition="left"> <mat-icon>chat</mat-icon> </button> </div> <div class="bottom"> <ng-container *ngFor="let option of toolbarOptions"> <button mat-button *ngIf="option.icon !== null" (click)="option.onClick !== null && option.onClick()" matTooltip="{{(option.label) ? option.label : ''}}" matTooltipPosition="left"> <mat-icon>{{option.icon}}</mat-icon> </button> </ng-container> <button mat-button (click)="toggleFullscreen()" *ngIf="!isFullscreen" matTooltip="{{_intl.fullscreenLabel}}" matTooltipPosition="left"> <mat-icon>fullscreen</mat-icon> </button> <button mat-button (click)="toggleFullscreen()" *ngIf="isFullscreen" matTooltip="{{_intl.exitFullscreenLabel}}" matTooltipPosition="left"> <mat-icon>clear</mat-icon> </button> </div> </div> </div> </mat-sidenav-container> </div> </div> </opv-template>