angular-openvidu
Version:
Simple, robust, OpenVidu room videochat component for Angular
209 lines (184 loc) • 9.89 kB
HTML
<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>