openvidu-components: Added translations

pull/726/head
csantosm 2022-05-13 17:11:04 +02:00
parent cccf0474d1
commit ad3ad30e86
36 changed files with 1146 additions and 112 deletions

View File

@ -19,7 +19,7 @@ export interface DialogData {
<h1 mat-dialog-title>{{ data.title }}</h1>
<div mat-dialog-content>{{ data.description }}</div>
<div mat-dialog-actions *ngIf="data.showActionButtons">
<button mat-button (click)="close()">Close</button>
<button mat-button (click)="close()">{{'PANEL.CLOSE' | translate}}</button>
</div>
`
})

View File

@ -1,14 +1,14 @@
<div class="panel-container" id="background-effects-container" fxLayout="column" fxLayoutAlign="space-evenly none">
<div class="panel-header-container" fxFlex="55px" fxLayoutAlign="start center">
<h3 class="panel-title">Background effects</h3>
<button class="panel-close-button" mat-icon-button matTooltip="Close" (click)="close()">
<h3 class="panel-title">{{ 'PANEL.BACKGROUND.TITLE' | translate }}</h3>
<button class="panel-close-button" mat-icon-button matTooltip="{{ 'PANEL.CLOSE' | translate }}" (click)="close()">
<mat-icon>close</mat-icon>
</button>
</div>
<div class="effects-container" fxFlex="100%" fxLayoutAlign="space-evenly none">
<div>
<h4>No effects and blurred background</h4>
<h4>{{ 'PANEL.BACKGROUND.BLURRED_SECTION' | translate }}</h4>
<div>
<button
*ngFor="let effect of noEffectAndBlurredBackground"
@ -17,7 +17,14 @@
[class.active-effect-btn]="backgroundSelectedId === effect.id"
(click)="applyBackground(effect)"
>
<mat-icon [matTooltip]="effect.description">{{effect.thumbnail}}</mat-icon>
<mat-icon
[matTooltip]="
effect.type === effectType.NONE
? ('PANEL.BACKGROUND.NO_EFFECTS' | translate)
: ('PANEL.BACKGROUND.BLURRED_EFFECT' | translate)
"
>{{ effect.thumbnail }}</mat-icon
>
</button>
<!-- <button
mat-icon-button
@ -32,7 +39,7 @@
</div>
<hr />
<div>
<h4>Background images</h4>
<h4>{{ 'PANEL.BACKGROUND.IMAGES_SECTION' | translate }}</h4>
<div class="grid">
<div

View File

@ -14,6 +14,7 @@ import { VirtualBackgroundService } from '../../../services/virtual-background/v
export class BackgroundEffectsPanelComponent implements OnInit {
backgroundSelectedId: string;
effectType = EffectType;
backgroundImages: BackgroundEffect[] = [];
noEffectAndBlurredBackground: BackgroundEffect[] = [];
private backgrounds: BackgroundEffect[];

View File

@ -1,20 +1,20 @@
<div class="panel-container" id="chat-container" fxLayout="column" fxLayoutAlign="space-evenly none" >
<div class="panel-header-container" fxFlex="55px" fxLayoutAlign="start center">
<h3 class="panel-title">Chat</h3>
<button class="panel-close-button" mat-icon-button matTooltip="Close" (click)="close()">
<h3 class="panel-title">{{ 'PANEL.CHAT.TITLE' | translate }}</h3>
<button class="panel-close-button" mat-icon-button matTooltip="{{ 'PANEL.CLOSE' | translate }}" (click)="close()">
<mat-icon>close</mat-icon>
</button>
</div>
<div class="text-container" fxFlex="20px">
<p class="text-info">Messages will be removed at the end of the session</p>
<p class="text-info">{{ 'PANEL.CHAT.SUBTITLE' | translate }}</p>
</div>
<div class="messages-container" fxFlex="75%" fxLayoutAlign="space-evenly none" #chatScroll>
<div *ngFor="let data of messageList" class="message" [ngClass]="data.isLocal ? 'right' : 'left'">
<div class="msg-detail">
<div class="nickname-container">
<p *ngIf="data.isLocal">You</p>
<p *ngIf="data.isLocal">{{ 'PANEL.CHAT.YOU' | translate }}</p>
<p *ngIf="!data.isLocal">{{ data.nickname }}</p>
</div>
<div class="msg-content">
@ -29,14 +29,14 @@
#chatInput
maxlength="500"
rows="4"
placeholder="Send a message"
placeholder="{{ 'PANEL.CHAT.PLACEHOLDER' | translate }}"
autocomplete="off"
(keypress)="eventKeyPress($event)"
[(ngModel)]="message"
id="chat-input"
></textarea>
<button mat-icon-button id="send-btn" (click)="sendMessage()">
<mat-icon matTooltip="Send">send</mat-icon>
<mat-icon matTooltip="{{ 'PANEL.CHAT.SEND' | translate }}">send</mat-icon>
</button>
</div>
</div>

View File

@ -1,7 +1,7 @@
<div class="panel-container" id="participants-container">
<div class="panel-header-container">
<h3 class="panel-title">Participants</h3>
<button class="panel-close-button" mat-icon-button matTooltip="Close" (click)="close()">
<h3 class="panel-title">{{ 'PANEL.PARTICIPANTS.TITLE' | translate }}</h3>
<button class="panel-close-button" mat-icon-button matTooltip="{{ 'PANEL.CLOSE' | translate }}" (click)="close()">
<mat-icon>close</mat-icon>
</button>
</div>

View File

@ -1,9 +1,30 @@
.container {
height: 100%;
padding: 80px;
height: calc(100% - 64px);
padding: 50px 80px;
background-color: var(--ov-light-color);
}
.prejoin-toolbar {
background-color: var(--ov-light-color);
}
.spacer {
flex: 1 1 auto;
}
.lang-button {
background-color: var(--ov-logo-background-color);
color: var(--ov-text-color);
}
#branding-logo {
background-color: var(--ov-logo-background-color);
border-radius: var(--ov-panel-radius);
max-width: 35px;
max-height: 35px;
padding: 10px;
margin-right: 10px;
}
#layout-container {
display: block !important;
}
@ -25,7 +46,8 @@ hr {
height: 100% !important;
}
#prejoin-container ::ng-deep .mat-drawer-container, #prejoin-container ::ng-deep .sidenav-menu {
#prejoin-container ::ng-deep .mat-drawer-container,
#prejoin-container ::ng-deep .sidenav-menu {
background-color: var(--ov-light-color) !important;
}
#prejoin-container ::ng-deep .sidenav-menu {
@ -59,21 +81,22 @@ hr {
margin-bottom: 0px !important;
}
#nickname-input-container, .device-container-element {
#nickname-input-container,
.device-container-element {
display: flex;
}
#nickname-input-container button, .device-container-element button {
#nickname-input-container button,
.device-container-element button {
margin: auto 10px auto auto;
}
#nickname-input-container button.mat-button-disabled {
color: #000000 !important;
}
#nickname-input-container mat-form-field, .device-container-element mat-form-field {
#nickname-input-container mat-form-field,
.device-container-element mat-form-field {
width: 100%;
margin-top: 10px;
color: #000000;
@ -88,7 +111,6 @@ hr {
border-radius: var(--ov-video-radius);
}
.buttons-container {
border-radius: 5px;
padding: 10px 0px;
@ -100,7 +122,6 @@ hr {
border-radius: var(--ov-buttons-radius);
/* background-color: var(--ov-secondary-color) !important; */
/* color: var(--ov-text-color) !important; */
}
.join-btn-container {
@ -114,7 +135,6 @@ hr {
color: var(--ov-text-color);
background-color: var(--ov-tertiary-color);
border-radius: var(--ov-video-radius);
}
.warn-btn {
@ -141,12 +161,15 @@ hr {
color: #000000;
}
@media only screen and (max-width: 480px) {
.container, .media-panel-container, .buttons-container {
.container,
.media-panel-container,
.buttons-container {
padding: 0;
}
.nickname-container, .buttons-container, .join-btn-container {
.nickname-container,
.buttons-container,
.join-btn-container {
width: 90% !important;
margin: auto;
}
@ -159,17 +182,22 @@ hr {
}
@media only screen and (min-width: 480px) and (max-width: 959px) {
.container, .media-panel-container, .buttons-container {
.container,
.media-panel-container,
.buttons-container {
padding: 0;
}
.nickname-container, .buttons-container, .join-btn-container{
.nickname-container,
.buttons-container,
.join-btn-container {
width: 80% !important;
min-width: 80% !important;
margin: auto;
}
.buttons-container, .media-panel-container {
.buttons-container,
.media-panel-container {
padding-top: 0px;
max-width: 600px;
}

View File

@ -1,3 +1,19 @@
<mat-toolbar class="prejoin-toolbar">
<img *ngIf="!isMinimal && showLogo" id="branding-logo" src="assets/images/logo.png" ovLogo />
<!-- <span>OpenVidu Call</span> -->
<span class="spacer"></span>
<button mat-flat-button [matMenuTriggerFor]="menu" class="lang-button" *ngIf="!isMinimal">
<span>{{langSelected?.name}}</span>
<mat-icon>expand_more</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item *ngFor="let lang of languages" (click)="onLangSelected(lang.ISO)">
<span>{{lang.name}}</span>
</button>
</mat-menu>
</mat-toolbar>
<div class="container" id="prejoin-container" fxLayout.gt-sm="row" fxLayout.lt-md="column">
<div fxFlex.gt-sm="65%" fxFlex.lt-md="55%" fxLayoutAlign="center center" id="layout-container">
<ov-session [usedInPrejoinPage]="true">
@ -15,6 +31,7 @@
<button
*ngIf="!isMinimal && showBackgroundEffectsButton"
[disabled]="isVideoMuted"
matTooltip="{{ 'TOOLBAR.BACKGROUND' | translate }}"
mat-icon-button
id="background-effects-btn"
(click)="toggleBackgroundEffects()"
@ -31,14 +48,14 @@
<div fxLayout="column" fxLayoutGap="10px" class="media-panel-container">
<div fxLayout.gt-sm="column" fxLayout.lt-md="column" fxLayoutGap="10px" fxFlex="33%">
<div fxFlex.gt-sm="100%" fxFlex.lt-md="33%" fxLayoutAlign="center center" fxFlexFill class="nickname-container">
<h4 *ngIf="windowSize >= 960">Set your name</h4>
<h4 *ngIf="windowSize >= 960">{{ 'PREJOIN.NICKNAME_SECTION' | translate }}</h4>
<hr *ngIf="windowSize >= 960" />
<div id="nickname-input-container">
<button mat-icon-button disabled>
<mat-icon>person</mat-icon>
</button>
<mat-form-field appearance="standard">
<mat-label>Nickname</mat-label>
<mat-label>{{ 'PREJOIN.NICKNAME' | translate }}</mat-label>
<input
matInput
type="text"
@ -66,7 +83,7 @@
</div>
<div fxFlex.gt-sm="100%" fxFlex.lt-md="33%" fxLayoutAlign="center center" fxFlexFill class="buttons-container">
<h4 *ngIf="windowSize >= 960">Choose your devices</h4>
<h4 *ngIf="windowSize >= 960">{{ 'PREJOIN.DEVICE_SECTION' | translate }}</h4>
<hr *ngIf="windowSize >= 960" />
<!-- Camera -->
<div class="device-container-element">
@ -77,11 +94,15 @@
[class.warn-btn]="isVideoMuted"
(click)="toggleCam()"
>
<mat-icon *ngIf="!isVideoMuted" matTooltip="Mute Camera" id="videocam">videocam</mat-icon>
<mat-icon *ngIf="isVideoMuted" matTooltip="Unmute Camera" id="videocam_off">videocam_off</mat-icon>
<mat-icon *ngIf="!isVideoMuted" matTooltip="{{ 'TOOLBAR.MUTE_VIDEO' | translate }}" id="videocam"
>videocam</mat-icon
>
<mat-icon *ngIf="isVideoMuted" matTooltip="{{ 'TOOLBAR.UNMUTE_VIDEO' | translate }}" id="videocam_off"
>videocam_off</mat-icon
>
</button>
<mat-form-field>
<mat-label>Video devices</mat-label>
<mat-label>{{ 'PREJOIN.VIDEO_DEVICE' | translate }}</mat-label>
<mat-select
[disabled]="isVideoMuted || !hasVideoDevices"
[value]="cameraSelected?.device"
@ -103,11 +124,13 @@
[class.warn-btn]="isAudioMuted"
(click)="toggleMic()"
>
<mat-icon *ngIf="!isAudioMuted" matTooltip="Mute Audio" id="mic">mic</mat-icon>
<mat-icon *ngIf="isAudioMuted" matTooltip="Unmute Audio" id="mic_off">mic_off</mat-icon>
<mat-icon *ngIf="!isAudioMuted" matTooltip="{{ 'TOOLBAR.MUTE_AUDIO' | translate }}" id="mic">mic</mat-icon>
<mat-icon *ngIf="isAudioMuted" matTooltip="{{ 'TOOLBAR.UNMUTE_AUDIO' | translate }}" id="mic_off"
>mic_off</mat-icon
>
</button>
<mat-form-field>
<mat-label>Audio devices</mat-label>
<mat-label>{{ 'PREJOIN.AUDIO_DEVICE' | translate }}</mat-label>
<mat-select
[disabled]="isAudioMuted || !hasAudioDevices"
[value]="microphoneSelected?.device"
@ -122,7 +145,9 @@
</div>
<div fxFlex.gt-sm="60%" fxLayout.lt-md="column" fxLayoutAlign="center center" fxFlexFill class="join-btn-container">
<button mat-flat-button (click)="joinSession()" form="nicknameForm" id="join-button">Join session</button>
<button mat-flat-button (click)="joinSession()" form="nicknameForm" id="join-button">
{{ 'PREJOIN.JOIN' | translate }}
</button>
</div>
</div>
</div>

View File

@ -20,6 +20,7 @@ import { OpenViduService } from '../../services/openvidu/openvidu.service';
import { PanelService } from '../../services/panel/panel.service';
import { ParticipantService } from '../../services/participant/participant.service';
import { StorageService } from '../../services/storage/storage.service';
import { TranslateService } from '../../services/translate/translate.service';
import { VirtualBackgroundService } from '../../services/virtual-background/virtual-background.service';
/**
@ -32,6 +33,8 @@ import { VirtualBackgroundService } from '../../services/virtual-background/virt
})
export class PreJoinComponent implements OnInit, OnDestroy {
@Output() onJoinButtonClicked = new EventEmitter<any>();
languages: {name: string, ISO: string}[] = [];
langSelected: {name: string, ISO: string};
cameras: CustomDevice[];
microphones: CustomDevice[];
cameraSelected: CustomDevice;
@ -53,11 +56,13 @@ export class PreJoinComponent implements OnInit, OnDestroy {
* @ignore
*/
isMinimal: boolean = false;
showLogo: boolean = true;
private log: ILogger;
private localParticipantSubscription: Subscription;
private screenShareStateSubscription: Subscription;
private minimalSub: Subscription;
private displayLogoSub: Subscription;
private backgroundEffectsButtonSub: Subscription;
@HostListener('window:resize')
@ -75,7 +80,8 @@ export class PreJoinComponent implements OnInit, OnDestroy {
protected panelService: PanelService,
private libService: OpenViduAngularConfigService,
private storageSrv: StorageService,
private backgroundService: VirtualBackgroundService
private backgroundService: VirtualBackgroundService,
private translateService: TranslateService
) {
this.log = this.loggerSrv.get('PreJoinComponent');
}
@ -83,6 +89,8 @@ export class PreJoinComponent implements OnInit, OnDestroy {
ngOnInit() {
this.subscribeToPrejoinDirectives();
this.subscribeToLocalParticipantEvents();
this.languages = this.translateService.getLanguagesInfo();
this.langSelected = this.translateService.getLangSelected();
this.windowSize = window.innerWidth;
this.hasVideoDevices = this.deviceSrv.hasVideoDeviceAvailable();
@ -148,6 +156,12 @@ export class PreJoinComponent implements OnInit, OnDestroy {
}
}
onLangSelected(lang: string){
this.translateService.setLanguage(lang);
this.storageSrv.setLang(lang);
this.langSelected = this.translateService.getLangSelected();
}
async toggleCam() {
this.videoMuteChanging = true;
const publish = this.isVideoMuted;
@ -194,6 +208,10 @@ export class PreJoinComponent implements OnInit, OnDestroy {
this.isMinimal = value;
// this.cd.markForCheck();
});
this.displayLogoSub = this.libService.displayLogoObs.subscribe((value: boolean) => {
this.showLogo = value;
// this.cd.markForCheck();
});
this.backgroundEffectsButtonSub = this.libService.backgroundEffectsButton.subscribe((value: boolean) => {
this.showBackgroundEffectsButton = value;
// this.cd.markForCheck();

View File

@ -11,7 +11,15 @@ import {
TemplateRef,
ViewChild
} from '@angular/core';
import { Subscriber, Session, StreamEvent, StreamPropertyChangedEvent, SessionDisconnectedEvent, ConnectionEvent, RecordingEvent } from 'openvidu-browser';
import {
Subscriber,
Session,
StreamEvent,
StreamPropertyChangedEvent,
SessionDisconnectedEvent,
ConnectionEvent,
RecordingEvent
} from 'openvidu-browser';
import { VideoType } from '../../models/video-type.model';
import { ILogger } from '../../models/logger.model';
@ -30,6 +38,7 @@ import { Subscription, skip } from 'rxjs';
import { PanelType } from '../../models/panel.model';
import { PanelService } from '../../services/panel/panel.service';
import { RecordingService } from '../../services/recording/recording.service';
import { TranslateService } from '../../services/translate/translate.service';
/**
* @internal
@ -73,7 +82,8 @@ export class SessionComponent implements OnInit {
protected tokenService: TokenService,
protected layoutService: LayoutService,
protected panelService: PanelService,
private recordingService: RecordingService
private recordingService: RecordingService,
private translateService: TranslateService
) {
this.log = this.loggerSrv.get('SessionComponent');
}
@ -166,7 +176,7 @@ export class SessionComponent implements OnInit {
this.updateLayoutInterval = setInterval(() => this.layoutService.update(), 50);
});
this.menuSubscription = this.panelService.panelOpenedObs.pipe(skip(1)).subscribe((ev: { opened: boolean, type?: PanelType }) => {
this.menuSubscription = this.panelService.panelOpenedObs.pipe(skip(1)).subscribe((ev: { opened: boolean; type?: PanelType }) => {
if (this.sideMenu) {
ev.opened ? this.sideMenu.open() : this.sideMenu.close();
}
@ -196,7 +206,7 @@ export class SessionComponent implements OnInit {
} catch (error) {
// this._error.emit({ error: error.error, messgae: error.message, code: error.code, status: error.status });
this.log.e('There was an error connecting to the session:', error.code, error.message);
this.actionService.openDialog('There was an error connecting to the session:', error?.error || error?.message);
this.actionService.openDialog(this.translateService.translate('ERRORS.SESSION'), error?.error || error?.message || error);
}
}
@ -277,7 +287,11 @@ export class SessionComponent implements OnInit {
private subscribeToReconnection() {
this.session.on('reconnecting', () => {
this.log.w('Connection lost: Reconnecting');
this.actionService.openDialog('Connection Problem', 'Oops! Trying to reconnect to the session ...', false);
this.actionService.openDialog(
this.translateService.translate('ERRRORS.CONNECTION'),
this.translateService.translate('ERRRORS.RECONNECT'),
false
);
});
this.session.on('reconnected', () => {
this.log.w('Connection lost: Reconnected');

View File

@ -48,22 +48,22 @@
</div>
<div *ngIf="!isMinimal && showSettingsButton" id="settings-container" class="videoButtons">
<button mat-icon-button (click)="toggleVideoMenu($event)" matTooltip="Settings" aria-label="Video settings menu">
<button mat-icon-button (click)="toggleVideoMenu($event)" matTooltip="{{ 'STREAM.SETTINGS' | translate }}" aria-label="Video settings menu">
<mat-icon>more_vert</mat-icon>
</button>
<span [matMenuTriggerFor]="menu"></span>
<mat-menu #menu="matMenu" yPosition="above" xPosition="before">
<button mat-menu-item id="videoZoomButton" (click)="toggleVideoEnlarged()">
<mat-icon>{{ this.videoSizeIcon }}</mat-icon>
<span *ngIf="videoSizeIcon === videoSizeIconEnum.NORMAL">Zoom out</span>
<span *ngIf="videoSizeIcon === videoSizeIconEnum.BIG">Zoom in</span>
<span *ngIf="videoSizeIcon === videoSizeIconEnum.NORMAL">{{ 'STREAM.ZOOM_OUT' | translate }}</span>
<span *ngIf="videoSizeIcon === videoSizeIconEnum.BIG">{{ 'STREAM.ZOOM_IN' | translate }}</span>
</button>
<button mat-menu-item id="volumeButton" *ngIf="!this._stream.local" (click)="toggleMuteForcibly()">
<mat-icon *ngIf="!_stream.participant.isMutedForcibly">volume_up</mat-icon>
<span *ngIf="!_stream.participant.isMutedForcibly">Mute sound</span>
<span *ngIf="!_stream.participant.isMutedForcibly">{{ 'STREAM.MUTE_SOUND' | translate }}</span>
<mat-icon *ngIf="_stream.participant.isMutedForcibly">volume_off</mat-icon>
<span *ngIf="_stream.participant.isMutedForcibly">Unmute sound</span>
<span *ngIf="_stream.participant.isMutedForcibly">{{ 'STREAM.UNMUTE_SOUND' | translate }}</span>
</button>
<!-- <button mat-menu-item *ngIf="this._stream.streamManager?.stream?.videoActive" id="fullscreenButton" (click)="toggleFullscreen()">
<mat-icon *ngIf="!isFullscreenEnabled">fullscreen</mat-icon>
@ -80,7 +80,7 @@
*ngIf="!this._stream.streamManager?.remote && this._stream.streamManager?.stream?.typeOfVideo === videoTypeEnum.SCREEN"
>
<mat-icon>picture_in_picture</mat-icon>
<span>Replace screen</span>
<span>{{ 'STREAM.REPLACE_SCREEN' | translate }}</span>
</button>
</mat-menu>
</div>

View File

@ -20,8 +20,8 @@
[disabled]="isConnectionLost || !hasAudioDevices"
[class.warn-btn]="!isAudioActive"
>
<mat-icon *ngIf="isAudioActive" matTooltip="Mute your audio" id="mic">mic</mat-icon>
<mat-icon *ngIf="!isAudioActive" matTooltip="Unmute your audio" id="mic_off">mic_off</mat-icon>
<mat-icon *ngIf="isAudioActive" matTooltip="{{ 'TOOLBAR.MUTE_AUDIO' | translate }}" id="mic">mic</mat-icon>
<mat-icon *ngIf="!isAudioActive" matTooltip="{{ 'TOOLBAR.UNMUTE_AUDIO' | translate }}" id="mic_off">mic_off</mat-icon>
</button>
<!-- Camera button -->
@ -32,8 +32,8 @@
[disabled]="isConnectionLost || !hasVideoDevices || videoMuteChanging"
[class.warn-btn]="!isWebcamVideoActive"
>
<mat-icon *ngIf="isWebcamVideoActive" matTooltip="Mute your cam" id="videocam">videocam</mat-icon>
<mat-icon *ngIf="!isWebcamVideoActive" matTooltip="Unmute your cam" id="videocam_off">videocam_off</mat-icon>
<mat-icon *ngIf="isWebcamVideoActive" matTooltip="{{ 'TOOLBAR.MUTE_VIDEO' | translate }}" id="videocam">videocam</mat-icon>
<mat-icon *ngIf="!isWebcamVideoActive" matTooltip="{{ 'TOOLBAR.UNMUTE_VIDEO' | translate }}" id="videocam_off">videocam_off</mat-icon>
</button>
<!-- Screenshare button -->
@ -45,8 +45,8 @@
[disabled]="isConnectionLost"
[class.active-btn]="isScreenShareActive"
>
<mat-icon *ngIf="!isScreenShareActive" matTooltip="Enable screen share">screen_share</mat-icon>
<mat-icon *ngIf="isScreenShareActive" matTooltip="Disable screen share">screen_share</mat-icon>
<mat-icon *ngIf="!isScreenShareActive" matTooltip="{{ 'TOOLBAR.ENABLE_SCREEN' | translate }}">screen_share</mat-icon>
<mat-icon *ngIf="isScreenShareActive" matTooltip="{{ 'TOOLBAR.DISABLE_SCREEN' | translate }}">screen_share</mat-icon>
</button>
<!-- Fullscreen button -->
@ -58,8 +58,8 @@
[disabled]="isConnectionLost"
[class.active-btn]="isFullscreenActive"
>
<mat-icon *ngIf="isFullscreenActive" matTooltip="Exit Fullscreen">fullscreen_exit</mat-icon>
<mat-icon *ngIf="!isFullscreenActive" matTooltip="Fullscreen">fullscreen</mat-icon>
<mat-icon *ngIf="isFullscreenActive" matTooltip="{{ 'TOOLBAR.EXIT_FULLSCREEN' | translate }}">fullscreen_exit</mat-icon>
<mat-icon *ngIf="!isFullscreenActive" matTooltip="{{ 'TOOLBAR.FULLSCREEN' | translate }}">fullscreen</mat-icon>
</button>
<button
@ -69,16 +69,16 @@
[matMenuTriggerFor]="menu"
[disabled]="isConnectionLost"
>
<mat-icon matTooltip="More options">more_vert</mat-icon>
<mat-icon matTooltip="{{ 'TOOLBAR.MORE_OPTIONS' | translate }}">more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<!-- Fullscreen button -->
<button mat-menu-item id="fullscreen-btn" (click)="toggleFullscreen()">
<mat-icon *ngIf="!isFullscreenActive">fullscreen</mat-icon>
<span *ngIf="!isFullscreenActive">Fullscreen</span>
<span *ngIf="!isFullscreenActive">{{ 'TOOLBAR.FULLSCREEN' | translate }}</span>
<mat-icon *ngIf="isFullscreenActive">fullscreen_exit</mat-icon>
<span *ngIf="isFullscreenActive">Exit fullscreen</span>
<span *ngIf="isFullscreenActive">{{ 'TOOLBAR.EXIT_FULLSCREEN' | translate }}</span>
</button>
<!-- Recording button -->
@ -101,7 +101,7 @@
(click)="toggleBackgroundEffects()"
>
<mat-icon>auto_awesome</mat-icon>
<span>Background effects</span>
<span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span>
</button>
</mat-menu>
@ -112,7 +112,7 @@
<!-- Leave session button -->
<button mat-icon-button *ngIf="showLeaveButton" (click)="leaveSession()" id="leave-btn">
<mat-icon matTooltip="Leave the session">call_end</mat-icon>
<mat-icon matTooltip="{{ 'TOOLBAR.LEAVE' | translate }}">call_end</mat-icon>
</button>
</div>
<div fxFlex="20%" fxFlexOrder="3" fxLayoutAlign="end center" id="menu-buttons-container">
@ -134,7 +134,7 @@
mat-icon-button
id="participants-panel-btn"
*ngIf="!isMinimal && showParticipantsPanelButton"
matTooltip="Participants"
matTooltip="{{ 'TOOLBAR.PARTICIPANTS' | translate }}"
(click)="toggleParticipantsPanel()"
[disabled]="isConnectionLost"
[class.active-btn]="isParticipantsOpened"
@ -147,7 +147,7 @@
mat-icon-button
id="chat-panel-btn"
*ngIf="!isMinimal && showChatPanelButton"
matTooltip="Chat"
matTooltip="{{ 'TOOLBAR.CHAT' | translate }}"
(click)="toggleChatPanel()"
[disabled]="isConnectionLost"
[class.active-btn]="isChatOpened"

View File

@ -36,6 +36,7 @@ import { PlatformService } from '../../services/platform/platform.service';
import { MatMenuTrigger } from '@angular/material/menu';
import { RecordingInfo, RecordingService } from '../../services/recording/recording.service';
import { RecordingStatus } from '../../models/recording.model';
import { TranslateService } from '../../services/translate/translate.service';
/**
*
@ -321,7 +322,8 @@ export class ToolbarComponent implements OnInit, OnDestroy {
private cd: ChangeDetectorRef,
private libService: OpenViduAngularConfigService,
private platformService: PlatformService,
private recordingService: RecordingService
private recordingService: RecordingService,
private translateService: TranslateService
) {
this.log = this.loggerSrv.get('ToolbarComponent');
}
@ -391,7 +393,7 @@ export class ToolbarComponent implements OnInit, OnDestroy {
await this.openviduService.publishAudio(!this.isAudioActive);
} catch (error) {
this.log.e('There was an error toggling microphone:', error.code, error.message);
this.actionService.openDialog('There was an error toggling camera', error?.error || error?.message);
this.actionService.openDialog(this.translateService.translate('ERRORS.TOGGLE_MICROPHONE'), error?.error || error?.message || error);
}
}
@ -409,7 +411,7 @@ export class ToolbarComponent implements OnInit, OnDestroy {
await this.openviduService.publishVideo(publishVideo);
} catch (error) {
this.log.e('There was an error toggling camera:', error.code, error.message);
this.actionService.openDialog('There was an error toggling camera', error?.error || error?.message);
this.actionService.openDialog(this.translateService.translate('ERRORS.TOGGLE_CAMERA'), error?.error || error?.message || error);
}
this.videoMuteChanging = false;
}
@ -425,7 +427,7 @@ export class ToolbarComponent implements OnInit, OnDestroy {
} catch (error) {
this.log.e('There was an error toggling screen share', error.code, error.message);
if (error && error.name === 'SCREEN_SHARING_NOT_SUPPORTED') {
this.actionService.openDialog('Error sharing screen', 'Your browser does not support screen sharing');
this.actionService.openDialog(this.translateService.translate('ERRORS.SCREEN_SHARING'), this.translateService.translate('ERRORS.SCREEN_SUPPORT'));
}
}
}

View File

@ -6,7 +6,7 @@
<div id="spinner" *ngIf="(joinSessionClicked || !showPrejoin) && !participantReady && !error">
<mat-spinner [diameter]="50"></mat-spinner>
<span>Joining the room ...</span>
<span>{{ 'PREJOIN.PREPARING' | translate }}</span>
</div>
<div id="spinner" *ngIf="joinSessionClicked && !participantReady && error">

View File

@ -37,6 +37,7 @@ import { OpenViduEdition, OpenViduService } from '../../services/openvidu/openvi
import { ParticipantService } from '../../services/participant/participant.service';
import { StorageService } from '../../services/storage/storage.service';
import { TokenService } from '../../services/token/token.service';
import { TranslateService } from '../../services/translate/translate.service';
/**
* The **VideoconferenceComponent** is the parent of all OpenVidu components.
@ -52,6 +53,7 @@ import { TokenService } from '../../services/token/token.service';
* | **Parameter** | **Type** | **Reference** |
* | :----------------------------: | :-------: | :---------------------------------------------: |
* | **minimal** | `boolean` | {@link MinimalDirective} |
* | **lang** | `string` | {@link LangDirective} |
* | **prejoin** | `boolean` | {@link PrejoinDirective} |
* | **participantName** | `string` | {@link ParticipantNameDirective} |
* | **videoMuted** | `boolean` | {@link VideoMutedDirective} |
@ -374,7 +376,8 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
private openviduService: OpenViduService,
private actionService: ActionService,
private libService: OpenViduAngularConfigService,
private tokenService: TokenService
private tokenService: TokenService,
private translateService: TranslateService
) {
this.log = this.loggerSrv.get('VideoconferenceComponent');
}
@ -574,12 +577,12 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
return this.initwebcamPublisher();
}
if (e.name === OpenViduErrorName.DEVICE_ACCESS_DENIED) {
message = 'Access to media devices was not allowed.';
message = this.translateService.translate('ERRORS.MEDIA_ACCESS');
this.deviceSrv.disableVideoDevices();
this.deviceSrv.disableAudioDevices();
return this.initwebcamPublisher();
} else if (e.name === OpenViduErrorName.NO_INPUT_SOURCE_SET) {
message = 'No video or audio devices have been found. Please, connect at least one.';
message = this.translateService.translate('ERRORS.DEVICE_NOT_FOUND');
}
this.actionService.openDialog(e.name.replace(/_/g, ' '), message, true);
this.log.e(e.message);

View File

@ -22,13 +22,15 @@ import {
MinimalDirective,
PrejoinDirective,
VideoMutedDirective,
ParticipantNameDirective
ParticipantNameDirective,
LangDirective
} from './videoconference.directive';
@NgModule({
declarations: [
MinimalDirective,
LangDirective,
PrejoinDirective,
VideoMutedDirective,
AudioMutedDirective,
@ -50,6 +52,7 @@ import {
],
exports: [
MinimalDirective,
LangDirective,
PrejoinDirective,
VideoMutedDirective,
AudioMutedDirective,

View File

@ -1,5 +1,6 @@
import { Directive, Input, ElementRef, OnDestroy, OnInit } from '@angular/core';
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
import { TranslateService } from '../../services/translate/translate.service';
/**
* The **minimal** directive applies a minimal UI hiding all controls except for cam and mic.
@ -51,6 +52,67 @@ export class MinimalDirective implements OnDestroy {
}
}
/**
* The **lang** directive allows et the UI language to a default language.
*
* It is only available for {@link VideoconferenceComponent}.
*
* **Default:** English `en`
*
* **Available:**
*
* * English: `en`
* * Spanish: `es`
* * German: `de`
* * French: `fr`
* * Chinese: `cn`
* * Hindi: `hi`
* * Italian: `it`
* * Japanese: `ja`
* * Netherlands: `nl`
* * Portuguese: `pt`
*
* @example
* <ov-videoconference [lang]="es"></ov-videoconference>
*/
@Directive({
selector: 'ov-videoconference[lang]'
})
export class LangDirective implements OnDestroy {
/**
* @ignore
*/
@Input() set lang(value: string) {
this.update(value);
}
/**
* @ignore
*/
constructor(public elementRef: ElementRef, private translateService: TranslateService) {}
/**
* @ignore
*/
ngOnDestroy(): void {
this.clear();
}
/**
* @ignore
*/
clear() {
this.update('en');
}
/**
* @ignore
*/
update(value: string) {
this.translateService.setLanguage(value);
}
}
/**
* The **participantName** directive sets the participant name. It can be useful for aplications which doesn't need the prejoin page.
*

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "设置你的绰号",
"NICKNAME": "昵称",
"DEVICE_SECTION": "选择你的设备",
"VIDEO_DEVICE": "视频设备",
"AUDIO_DEVICE": "音频设备",
"JOIN": "加入会话",
"PREPARING": "筹备会议"
},
"TOOLBAR": {
"MUTE_AUDIO":"将你的音频静音",
"UNMUTE_AUDIO": "取消音频静音",
"MUTE_VIDEO": "将你的视频静音",
"UNMUTE_VIDEO": "取消你的视频静音",
"ENABLE_SCREEN":"启用屏幕共享",
"DISABLE_SCREEN":"禁用屏幕共享",
"MORE_OPTIONS":"更多选项",
"FULLSCREEN":"全屏",
"EXIT_FULLSCREEN": "退出全屏",
"BACKGROUND":"背景效果",
"START_RECORDING": "开始录音",
"STOP_RECORDING": "停止录制",
"LEAVE":"离开会议",
"PARTICIPANTS":"参与者",
"CHAT":"聊天",
"ACTIVITIES": "活动"
},
"STREAM": {
"SETTINGS":"设置",
"MUTE_SOUND":"静音",
"UNMUTE_SOUND":"取消静音",
"ZOOM_IN": "放大",
"ZOOM_OUT":"缩小",
"REPLACE_SCREEN": "更换屏幕"
},
"PANEL": {
"CLOSE": "关闭",
"CHAT": {
"TITLE": "聊天",
"YOU": "你",
"SUBTITLE": "信息将在会议结束时被删除",
"PLACEHOLDER": "发送消息...",
"SEND": "发送"
},
"PARTICIPANTS": {
"TITLE": "参与者",
"CAMERA": "摄像头",
"SCREEN": "屏幕"
},
"BACKGROUND": {
"TITLE": "背景效果",
"BLURRED_SECTION": "没有效果和模糊的背景",
"NO_EFFECTS": "没有背景效果",
"BLURRED_EFFECT": "模糊的背景",
"IMAGES_SECTION": "背景图像"
},
"RECORDING": {
"TITLE": "录音",
"SUBTITLE": "为后人记录你的会议",
"CONTENT_TITLE": "记录你的视频通话",
"CONTENT_SUBTITLE": "当录音完成后,你将可以轻松地下载它",
"STARTING": "开始录音"
}
},
"ERRORS": {
"SESSION": "连接到会话时有错误",
"CONNECTION": "连接丢失",
"RECONNECT": "试图重新连接到会话",
"TOGGLE_CAMERA": "切换相机时出现错误",
"TOGGLE_MICROPHONE": "切换麦克风时出现错误",
"SCREEN_SHARING": "分享屏幕出错",
"SCREEN_SUPPORT": "您的浏览器不支持屏幕共享",
"MEDIA_ACCESS": "不允许访问媒体设备",
"DEVICE_NOT_FOUND": "没有找到视频或音频设备 请至少连接一个"
}
}

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "Legen Sie Ihren Spitznamen fest",
"NICKNAME": "Spitzname",
"DEVICE_SECTION": "Wählen Sie Ihre Geräte",
"VIDEO_DEVICE": "Videogerät",
"AUDIO_DEVICE": "Audiogerät",
"JOIN": "Sitzung beitreten",
"PREPARING": "Sitzung vorbereiten..."
},
"TOOLBAR": {
"MUTE_AUDIO": "Stummschalten des Audios",
"UNMUTE_AUDIO": "Stummschaltung für Audio aufheben",
"MUTE_VIDEO": "Stummschalten des Videos",
"UNMUTE_VIDEO": "Heben Sie die Stummschaltung Ihres Videos auf",
"ENABLE_SCREEN": "Bildschirmfreigabe aktivieren",
"DISABLE_SCREEN": "Bildschirmfreigabe deaktivieren",
"MORE_OPTIONS": "Weitere Optionen",
"FULLSCREEN": "Vollbild",
"EXIT_FULLSCREEN": "Vollbildmodus beenden",
"BACKGROUND": "Hintergrund-Effekte",
"START_RECORDING": "Aufzeichnung starten",
"STOP_RECORDING": "Aufzeichnung stoppen",
"LEAVE": "Die Sitzung verlassen",
"PARTICIPANTS": "Teilnehmer",
"CHAT": "Chat",
"ACTIVITIES": "Aktivitäten"
},
"STREAM": {
"SETTINGS": "Einstellungen",
"MUTE_SOUND": "Ton stummschalten",
"UNMUTE_SOUND": "Stummschaltung aufheben",
"ZOOM_IN": "Vergrößern",
"ZOOM_OUT": "Herauszoomen",
"REPLACE_SCREEN": "Bildschirm austauschen"
},
"PANEL": {
"CLOSE": "Schließen",
"CHAT": {
"TITLE": "Chat",
"YOU": "Sie",
"SUBTITLE": "Nachrichten werden am Ende der Sitzung entfernt",
"PLACEHOLDER": "Eine Nachricht senden...",
"SEND": "Senden"
},
"PARTICIPANTS": {
"TITLE": "Teilnehmer",
"CAMERA": "KAMERA",
"SCREEN": "BILDSCHIRM"
},
"BACKGROUND": {
"TITLE": "Hintergrund-Effekte",
"BLURRED_SECTION": "Keine Effekte und unscharfer Hintergrund",
"NO_EFFECTS": "Kein Hintergrundeffekt",
"BLURRED_EFFECT": "Unscharfer Hintergrund",
"IMAGES_SECTION": "Hintergrundbilder"
},
"RECORDING": {
"TITLE": "Aufnahme",
"SUBTITLE": "Zeichnen Sie Ihr Meeting für die Nachwelt auf",
"CONTENT_TITLE": "Ihr Videogespräch aufzeichnen",
"CONTENT_SUBTITLE": "Wenn die Aufzeichnung beendet ist, können Sie sie ganz einfach herunterladen",
"STARTING": "Aufzeichnung starten"
}
},
"ERRORS": {
"SESSION": "Es ist ein Fehler beim Verbinden mit der Sitzung aufgetreten",
"CONNECTION": "Verbindung verloren",
"RECONNECT": "Ich versuche, die Verbindung zur Sitzung wiederherzustellen...",
"TOGGLE_CAMERA": "Es gab einen Fehler beim Umschalten der Kamera",
"TOGGLE_MICROPHONE": "Es ist ein Fehler beim Umschalten des Mikrofons aufgetreten",
"SCREEN_SHARING": "Fehler beim Teilen des Bildschirms",
"SCREEN_SUPPORT": "Ihr Browser unterstützt keine Bildschirmfreigabe",
"MEDIA_ACCESS": "Der Zugriff auf Mediengeräte war nicht erlaubt.",
"DEVICE_NOT_FOUND": "Es wurden keine Video- oder Audiogeräte gefunden. Bitte schließen Sie mindestens eines an."
}
}

View File

@ -1,7 +1,77 @@
{
"Chat": "Chat",
"Close": "Close",
"You": "You",
"Send": "Send",
"Chat_warn_message": "Messages will be removed at the end of the session",
"PREJOIN": {
"NICKNAME_SECTION": "Set your nickname",
"NICKNAME": "Nickname",
"DEVICE_SECTION": "Choose your devices",
"VIDEO_DEVICE": "Video device",
"AUDIO_DEVICE": "Audio device",
"JOIN": "Join session",
"PREPARING": "Preparing session..."
},
"TOOLBAR": {
"MUTE_AUDIO":"Mute your audio",
"UNMUTE_AUDIO": "Unmute your audio",
"MUTE_VIDEO":"Mute your video",
"UNMUTE_VIDEO": "Unmute your video",
"ENABLE_SCREEN": "Enable screen share",
"DISABLE_SCREEN": "Disable screen share",
"MORE_OPTIONS": "More options",
"FULLSCREEN": "Fullscreen",
"EXIT_FULLSCREEN": "Exit fullscreen",
"BACKGROUND": "Background effects",
"START_RECORDING": "Start recording",
"STOP_RECORDING": "Stop recording",
"LEAVE": "Leave the session",
"PARTICIPANTS": "Participants",
"CHAT": "Chat",
"ACTIVITIES": "Activities"
},
"STREAM": {
"SETTINGS": "Settings",
"MUTE_SOUND": "Mute sound",
"UNMUTE_SOUND": "Unmute sound",
"ZOOM_IN": "Zoom in",
"ZOOM_OUT": "Zoom out",
"REPLACE_SCREEN": "Replace screen"
},
"PANEL": {
"CLOSE": "Close",
"CHAT": {
"TITLE": "Chat",
"YOU": "You",
"SUBTITLE": "Messages will be removed at the end of the session",
"PLACEHOLDER": "Send a message...",
"SEND": "Send"
},
"PARTICIPANTS": {
"TITLE": "Participants",
"CAMERA": "CAMERA",
"SCREEN": "SCREEN"
},
"BACKGROUND": {
"TITLE": "Background effects",
"BLURRED_SECTION": "No effects and blurred background",
"NO_EFFECTS": "No background effect",
"BLURRED_EFFECT": "Blurred background",
"IMAGES_SECTION": "Background images"
},
"RECORDING": {
"TITLE": "Recording",
"SUBTITLE": "Record your meeting for posterity",
"CONTENT_TITLE": "Record your video call",
"CONTENT_SUBTITLE": "When recording has finished you will can download it with ease",
"STARTING": "Starting recording"
}
},
"ERRORS": {
"SESSION": "There was an error connecting to the session",
"CONNECTION": "Connection lost",
"RECONNECT": "Oops! Trying to reconnect to the session...",
"TOGGLE_CAMERA": "There was an error toggling camera",
"TOGGLE_MICROPHONE": "There was an error toggling microhpone",
"SCREEN_SHARING": "Error sharing screen",
"SCREEN_SUPPORT": "Your browser does not support screen sharing",
"MEDIA_ACCESS": "Access to media devices was not allowed.",
"DEVICE_NOT_FOUND": "No video or audio devices have been found. Please, connect at least one."
}
}

View File

@ -0,0 +1,66 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "Elige tu nombre",
"NICKNAME": "Nombre",
"DEVICE_SECTION": "Elige tus dispositivos",
"VIDEO_DEVICE": "Dispositivo de video",
"AUDIO_DEVICE": "Dispositivo de audio",
"PREPARING": "Preparando la session ...",
"JOIN": "Unirme ahora"
},
"TOOLBAR": {
"MUTE_AUDIO":"Silenciar tu audio",
"UNMUTE_AUDIO": "Activar tu audio",
"MUTE_VIDEO":"Silenciar tu video",
"UNMUTE_VIDEO": "Activar tu video",
"ENABLE_SCREEN": "Compartir pantalla",
"DISABLE_SCREEN": "Dejar de compartir pantalla",
"MORE_OPTIONS": "Más opciones",
"EXIT_FULLSCREEN": "Quitar pantalla completa",
"FULLSCREEN": "Pantalla completa",
"BACKGROUND": "Efectos de fondo",
"START_RECORDING": "Iniciar grabación",
"STOP_RECORDING": "Detener grabación",
"LEAVE": "Salir de la sesión",
"PARTICIPANTS": "Participantes",
"CHAT": "Chat",
"ACTIVITIES": "Actividades"
},
"STREAM": {
"SETTINGS": "Ajustes",
"MUTE_SOUND": "Silenciar sonido",
"UNMUTE_SOUND": "Activar sonido",
"ZOOM_IN": "Aumentar tamaño",
"ZOOM_OUT": "Disminuir tamaño",
"REPLACE_SCREEN": "Reemplazar pantalla"
},
"PANEL": {
"CLOSE": "Cerrar",
"CHAT": {
"TITLE": "Chat",
"YOU": "Tú",
"SUBTITLE": "Los mensajes se borrarán al finalizar la sesión",
"PLACEHOLDER": "Enviar mensaje...",
"SEND": "Enviar"
},
"PARTICIPANTS": {
"TITLE": "Participantes",
"CAMERA": "CÁMARA",
"SCREEN": "PANTALLA"
},
"BACKGROUND": {
"TITLE": "Efectos de fondo",
"BLURRED_SECTION": "Sin efectos y fondo desenfocado",
"NO_EFFECTS": "Sin efecto",
"BLURRED_EFFECT": "Fondo desenfocado",
"IMAGES_SECTION": "Imágenes de fondo"
},
"RECORDING": {
"TITLE": "Grabación",
"SUBTITLE": "Graba tus llamadas para la posteridad",
"CONTENT_TITLE": "Graba tu video conferencia",
"CONTENT_SUBTITLE": "Cuando la grabación haya finalizado, podrás descargarla con facilidad",
"STARTING": "Iniciar grabación"
}
}
}

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "Définir votre surnom",
"NICKNAME": "Surnom",
"DEVICE_SECTION": "Choisissez vos appareils",
"VIDEO_DEVICE": "Périphérique vidéo",
"AUDIO_DEVICE": "Périphérique audio",
"JOIN": "Joindre une session",
"PREPARING": "Préparation de la session ..."
},
"TOOLBAR": {
"MUTE_AUDIO": "Mettez votre audio en sourdine",
"UNMUTE_AUDIO": "Désactiver le son",
"MUTE_VIDEO": "Couper le son de votre vidéo",
"UNMUTE_VIDEO": "Unmute your video",
"ENABLE_SCREEN": "Activer le partage d'écran",
"DISABLE_SCREEN": "Désactiver le partage d'écran",
"MORE_OPTIONS": "Plus d'options",
"FULLSCREEN": "Plein écran",
"EXIT_FULLSCREEN": "Quitter le plein écran",
"BACKGROUND": "Effets de fond",
"START_RECORDING": "démarrer l'enregistrement",
"STOP_RECORDING": "Arrêter l'enregistrement",
"LEAVE": "Quitter la session",
"PARTICIPANTS": "Participants",
"CHAT": "Chat",
"ACTIVITES": "Activités"
},
"STREAM": {
"SETTINGS": "Paramètres",
"MUTE_SOUND": "Couper le son",
"UNMUTE_SOUND": "Désactiver le son",
"ZOOM_IN": "Zoom avant",
"ZOOM_OUT": "Zoom arrière",
"REPLACE_SCREEN": "Remplacer l'écran"
},
"PANEL": {
"CLOSE": "Fermer",
"CHAT": {
"TITLE": "Chat",
"YOU": "Vous",
"SUBTITLE": "Les messages seront supprimés à la fin de la session",
"PLACEHOLDER": "Envoyer un message...",
"SEND": "Envoyer"
},
"PARTICIPANTS": {
"TITLE": "Participants",
"CAMERA": "CAMÉRA",
"SCREEN": "ÉCRAN"
},
"BACKGROUND": {
"TITLE": "Effets de fond",
"BLURRED_SECTION": "Aucun effet et arrière-plan flou",
"NO_EFFECTS": "Aucun effet de fond",
"BLURRED_EFFECT": "Arrière-plan flou",
"IMAGES_SECTION": "Images d'arrière-plan"
},
"RECORDING": {
"TITLE": "Enregistrement",
"SUBTITLE": "Enregistrez votre réunion pour la postérité",
"CONTENT_TITLE": "Enregistrez votre appel vidéo",
"CONTENT_SUBTITLE": "Une fois l'enregistrement terminé, vous pourrez le télécharger facilement",
"STARTING": "Début de l'enregistrement"
}
},
"ERRORS": {
"SESSION": "There was an error connecting to the session",
"CONNECTION": "Connexion perdue",
"RECONNECT": "Oups ! Tentative de reconnexion à la session...",
"TOGGLE_CAMERA": "There was an error toggle camera",
"TOGGLE_MICROPHONE": "There was an error toggling microhpone",
"SCREEN_SHARING": "Erreur de partage d'écran",
"SCREEN_SUPPORT": "Votre navigateur ne prend pas en charge le partage d'écran",
"MEDIA_ACCESS": "L'accès aux périphériques médias n'a pas été autorisé",
"DEVICE_NOT_FOUND": "Aucun périphérique vidéo ou audio n'a été trouvé. Veuillez en connecter au moins un."
}
}

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "अपना निकनेम सेट करें",
"NICKNAME": "निकनेम",
"DEVICE_SECTION": "अपने डिवाइस चुनें",
"VIDEO_DEVICE": "वीडियो डिवाइस",
"AUDIO_DEVICE": "ऑडियो डिवाइस",
"JOIN": "सत्र में शामिल हों",
"PREPARING": "सत्र तैयार कर रहा है ..."
},
"TOOLBAR": {
"MUTE_AUDIO": "अपनी ऑडियो को मौन करें",
"UNMUTE_AUDIO": "अपनी ऑडियो को अनमौन करें",
"MUTE_VIDEO": "अपनी वीडियो को मौन करें",
"UNMUTE_VIDEO": "अपनी वीडियो को अनमौन करें",
"ENABLE_SCREEN": "स्क्रीन शेयर सक्षम करें",
"DISABLE_SCREEN": "स्क्रीन शेयर अक्षम करें",
"MORE_OPTIONS": "अधिक विकल्प",
"FULLSCREEN": "पूर्ण स्क्रीन",
"EXIT_FULLSCREEN": "पूर्ण स्क्रीन से बाहर निकलें",
"BACKGROUND": "पृष्ठभूमि प्रभाव",
"START_RECORDING": "रिकॉर्डिंग प्रारंभ करें",
"STOP_RECORDING": "रिकॉर्डिंग रोकें",
"LEAVE": "सत्र छोड़ें",
"PARTICIPANTS": "सदस्य",
"CHAT": "बातचीत",
"ACTIVITIES": "गतिविधियाँ"
},
"STREAM": {
"SETTINGS": "सेटिंग्स",
"MUTE_SOUND": "ध्वनि बंद करें",
"UNMUTE_SOUND": "ध्वनि चालू करें",
"ZOOM_IN": "ज़ूम इन करें",
"ZOOM_OUT": "ज़ूम आउट करें",
"REPLACE_SCREEN": "स्क्रीन को बदलें"
},
"PANEL": {
"CLOSE": "बंद करें",
"CHAT": {
"TITLE": "बातचीत",
"YOU": "आप",
"SUBTITLE": "सत्र समाप्त होने पर संदेश हटा दिए जाएंगे",
"PLACEHOLDER": "एक संदेश भेजें ...",
"SEND": "भेजें"
},
"PARTICIPANTS": {
"TITLE": "सदस्य",
"CAMERA": "कैमरा",
"SCREEN": "स्क्रीन"
},
"BACKGROUND": {
"TITLE": "पृष्ठभूमि प्रभाव",
"BLURRED_SECTION": "कोई प्रभाव नहीं है और पृष्ठभूमि धुंधली है",
"NO_EFFECTS": "कोई पृष्ठभूमि प्रभाव नहीं है",
"BLURRED_EFFECT": "पृष्ठभूमि धुंधली है",
"IMAGES_SECTION": "पृष्ठभूमि छवियां"
},
"RECORDING": {
"TITLE": "रिकॉर्डिंग",
"SUBTITLE": "अपनी बैठक को भावी पीढ़ी के लिए रिकॉर्ड करें",
"CONTENT_TITLE": "अपना वीडियो कॉल रिकॉर्ड करें",
"CONTENT_SUBTITLE": "रिकॉर्डिंग समाप्त हो जाने पर आप इसे आसानी से डाउनलोड कर सकेंगे",
"STARTING": "रिकॉर्डिंग शुरू कर रहा है"
}
},
"ERRORS": {
"SESSION": "सत्र से जुड़ने में त्रुटि हुई",
"CONNECTION": "कनेक्शन खो गया",
"RECONNECT": "ओह! सत्र से फिर से कनेक्ट करने का प्रयास कर रहा है",
"TOGGLE_CAMERA": "कैमरा टॉगल करने में त्रुटि हुई",
"TOGGLE_MICROPHONE": "माइक्रोफ़ोन को चालू करने में त्रुटि हुई",
"SCREEN_SHARING": "स्क्रीन साझा करने में त्रुटि",
"SCREEN_SUPPORT": "आपका ब्राउज़र स्क्रीन साझाकरण का समर्थन नहीं करता",
"MEDIA_ACCESS": "मीडिया उपकरणों तक पहुंच की अनुमति नहीं थी।",
"DEVICE_NOT_FOUND": "कोई वीडियो या ऑडियो डिवाइस नहीं मिला। कृपया, कम से कम एक कनेक्ट करें।"
}
}

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "Imposta il tuo soprannome",
"NICKNAME": "Soprannome",
"DEVICE_SECTION": "Scegli i tuoi dispositivi",
"VIDEO_DEVICE": "Dispositivo video",
"AUDIO_DEVICE": "Dispositivo audio",
"JOIN": "Unisciti alla sessione",
"PREPARING": "Preparazione della sessione in corso..."
},
"TOOLBAR": {
"MUTE_AUDIO": "Disattiva l'audio",
"UNMUTE_AUDIO": "Attiva l'audio",
"MUTE_VIDEO": "Disattiva il video",
"UNMUTE_VIDEO": "Attiva il video",
"ENABLE_SCREEN": "Abilita la condivisione dello schermo",
"DISABLE_SCREEN": "Disabilita la condivisione dello schermo",
"MORE_OPTIONS": "Altre opzioni",
"FULLSCREEN": "Schermo intero",
"EXIT_FULLSCREEN": "Esci dallo schermo intero",
"BACKGROUND": "Effetti di sfondo",
"START_RECORDING": "Avvia registrazione",
"STOP_RECORDING": "Interrompi registrazione",
"LEAVE": "Abbandona la sessione",
"PARTICIPANTS": "Partecipanti",
"CHAT": "Chat",
"ACTIVITIES": "Attività"
},
"STREAM": {
"SETTINGS": "Impostazioni",
"MUTE_SOUND": "Disattiva l'audio",
"UNMUTE_SOUND": "Attiva l'audio",
"ZOOM_IN": "Ingrandisci",
"ZOOM_OUT": "Riduci",
"REPLACE_SCREEN": "Sostituisci lo schermo"
},
"PANEL": {
"CLOSE": "Chiudi",
"CHAT": {
"TITLE": "Chat",
"YOU": "Tu",
"SUBTITLE": "I messaggi verranno rimossi alla fine della sessione",
"PLACEHOLDER": "Invia un messaggio...",
"SEND": "Invia"
},
"PARTICIPANTS": {
"TITLE": "Partecipanti",
"CAMERA": "CAMERA",
"SCREEN": "SCREEN"
},
"BACKGROUND": {
"TITLE": "Effetti di sfondo",
"BLURRED_SECTION": "Nessun effetto e sfondo sfocato",
"NO_EFFECTS": "Nessun effetto di sfondo",
"BLURRED_EFFECT": "Sfondo sfocato",
"IMAGES_SECTION": "Immagini di sfondo"
},
"RECORDING": {
"TITLE": "Registrazione",
"SUBTITLE": "Registra la tua riunione per i posteri",
"CONTENT_TITLE": "Registra la tua videochiamata",
"CONTENT_SUBTITLE": "Al termine della registrazione potrete scaricarla con facilità",
"STARTING": "Avvio della registrazione"
}
},
"ERRORS": {
"SESSION": "Si è verificato un errore di connessione alla sessione",
"CONNECTION": "Connessione persa",
"RECONNECT": "Oops! Si sta cercando di riconnettersi alla sessione...",
"TOGGLE_CAMERA": "Si è verificato un errore nell'attivazione della telecamera",
"TOGGLE_MICROPHONE": "Si è verificato un errore nell'attivazione del microfono",
"SCREEN_SHARING": "Errore nella condivisione dello schermo",
"SCREEN_SUPPORT": "Il browser non supporta la condivisione dello schermo",
"MEDIA_ACCESS": "L'accesso ai dispositivi multimediali non è stato consentito",
"DEVICE_NOT_FOUND": "Non sono stati trovati dispositivi video o audio. Si prega di collegarne almeno uno"
}
}

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "ニックネームを設定してください",
"NICKNAME": "ニックネーム",
"DEVICE_SECTION": "デバイスを選択してください",
"VIDEO_DEVICE": "ビデオデバイス",
"AUDIO_DEVICE": "オーディオデバイス",
"JOIN": "セッションに参加する",
"PREPARING": "セッションの準備中..."
},
"TOOLBAR": {
"MUTE_AUDIO": "オーディオをミュートする",
"UNMUTE_AUDIO": "オーディオをミュートしない",
"MUTE_VIDEO": "ビデオをミュートする",
"UNMUTE_VIDEO": "ビデオをミュートしない",
"ENABLE_SCREEN": "スクリーン共有を有効にする",
"DISABLE_SCREEN": "スクリーン共有を無効にする",
"MORE_OPTIONS": "その他のオプション",
"FULLSCREEN": "フルスクリーン",
"EXIT_FULLSCREEN": "フルスクリーンを終了する",
"BACKGROUND": "背景効果",
"START_RECORDING": "録画開始",
"STOP_RECORDING": "録画の停止",
"LEAVE": "セッションを終了する",
"PARTICIPANTS": "参加者",
"CHAT": "チャット",
"ACTIVITIES": "アクティビティ"
},
"STREAM": {
"SETTINGS": "設定",
"MUTE_SOUND": "サウンドをミュートする",
"UNMUTE_SOUND": "サウンドをミュートしない",
"ZOOM_IN": "拡大する",
"ZOOM_OUT": "縮小する",
"REPLACE_SCREEN": "スクリーンを入れ替える"
},
"PANEL": {
"CLOSE": "閉じる",
"CHAT": {
"TITLE": "チャット",
"YOU": "あなた",
"SUBTITLE": "メッセージはセッション終了時に削除されます",
"PLACEHOLDER": "メッセージを送信...",
"SEND": "送信する"
},
"PARTICIPANTS": {
"TITLE": "参加者",
"CAMERA": "カメラ",
"SCREEN": "スクリーン"
},
"BACKGROUND": {
"TITLE": "背景効果",
"BLURRED_SECTION": "エフェクトなし、ぼやけた背景",
"NO_EFFECTS": "背景エフェクトなし",
"BLURRED_EFFECT": "ぼやけた背景",
"IMAGES_SECTION": "背景画像"
},
"RECORDING": {
"TITLE": "レコーディング",
"SUBTITLE": "会議を録音して後世に残す",
"CONTENT_TITLE": "ビデオ通話を録音する",
"CONTENT_SUBTITLE": "録音が完了したら、簡単にダウンロードできます",
"STARTING": "録画開始"
}
},
"ERRORS": {
"SESSION": "セッションへの接続にエラーが発生しました",
"CONNECTION": "接続が失われました",
"RECONNECT": "セッションへの再接続を試みています",
"TOGGLE_CAMERA": "カメラのトグルエラーが発生しました",
"TOGGLE_MICROPHONE": "マイクロフォンのトグルにエラーが発生しました",
"SCREEN_SHARING": "画面共有にエラーが発生しました",
"SCREEN_SUPPORT": "お使いのブラウザは画面共有に対応していません",
"MEDIA_ACCESS": "メディアデバイスへのアクセスが許可されませんでした",
"DEVICE_NOT_FOUND": "ビデオまたはオーディオデバイスが見つかりませんでした 最低1台は接続してください"
}
}

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "Stel je bijnaam in",
"NICKNAME": "Bijnaam",
"DEVICE_SECTION": "Kies je apparaten",
"VIDEO_DEVICE": "Videospeler",
"AUDIO_DEVICE": "Audiospeler",
"JOIN": "Deelnemen aan sessie",
"PREPARING": "Sessie voorbereiden ..."
},
"TOOLBAR": {
"MUTE_AUDIO": "Audio dempen",
"UNMUTE_AUDIO": "Audio niet meer dempen",
"MUTE_VIDEO": "Video dempen",
"UNMUTE_VIDEO": "Video niet meer dempen",
"ENABLE_SCREEN": "Scherm delen inschakelen",
"DISABLE_SCREEN": "Scherm delen uitschakelen",
"MORE_OPTIONS": "Meer opties",
"FULLSCREEN": "Volledig scherm",
"EXIT_FULLSCREEN": "Volledig scherm verlaten",
"BACKGROUND": "Achtergrondeffecten",
"START_RECORDING": "Start opname",
"STOP_RECORDING": "Stop opname",
"LEAVE": "Verlaat de sessie",
"PARTICIPANTS": "Deelnemers",
"CHAT": "Chat",
"ACTIVITIES": "Activiteiten"
},
"STREAM": {
"SETTINGS": "Instellingen",
"MUTE_SOUND": "Geluid dempen",
"UNMUTE_SOUND": "Geluid niet meer dempen",
"ZOOM_IN": "Inzoomen",
"ZOOM_OUT": "Uitzoomen",
"REPLACE_SCREEN": "Vervang scherm"
},
"PANEL": {
"CLOSE": "Sluiten",
"CHAT": {
"TITLE": "Chat",
"YOU": "Jij",
"SUBTITLE": "Berichten worden aan het einde van de sessie verwijderd",
"PLACEHOLDER": "Stuur een bericht ...",
"SEND": "Versturen"
},
"PARTICIPANTS": {
"TITLE": "Deelnemers",
"CAMERA": "CAMERA",
"SCREEN": "SCHERM"
},
"BACKGROUND": {
"TITLE": "Achtergrondeffecten",
"BLURRED_SECTION": "Geen effecten en onscherpe achtergrond",
"NO_EFFECTS": "Geen achtergrondeffect",
"BLURRED_EFFECT": "Onscherpe achtergrond",
"IMAGES_SECTION": "Achtergrondafbeeldingen"
},
"RECORDING": {
"TITLE": "Opname",
"SUBTITLE": "Neem uw vergadering op voor het nageslacht",
"CONTENT_TITLE": "Neem uw videogesprek op",
"CONTENT_SUBTITLE": "Als de opname klaar is kunt u deze met gemak downloaden",
"STARTING": "Beginnen met opnemen"
}
},
"ERRORS": {
"SESSION": "Er is een fout opgetreden bij het verbinden met de sessie",
"CONNECTION": "Verbinding verloren",
"RECONNECT": "Oeps! Proberen opnieuw verbinding te maken met de sessie...",
"TOGGLE_CAMERA": "Er is een fout opgetreden bij het overschakelen naar een andere camera",
"TOGGLE_MICROPHONE": "Er is een fout opgetreden bij het overschakelen naar een microfoon",
"SCREEN_SHARING": "Fout bij het delen van het scherm",
"SCREEN_SUPPORT": "Uw browser ondersteunt het delen van schermen niet",
"MEDIA_ACCESS": "Toegang tot media-apparaten was niet toegestaan.",
"DEVICE_NOT_FOUND": "Er zijn geen video- of audioapparaten gevonden. Sluit er alstublieft ten minste één aan."
}
}

View File

@ -0,0 +1,77 @@
{
"PREJOIN": {
"NICKNAME_SECTION": "Defina seu apelido",
"NICKNAME": "Apelido",
"DEVICE_SECTION": "Escolha seus dispositivos",
"VIDEO_DEVICE": "Dispositivo de vídeo",
"AUDIO_DEVICE": "Dispositivo de áudio",
"JOIN": "Entrar na sessão",
"PREPARING": "Preparando sessão..."
},
"TOOLBAR": {
"MUTE_AUDIO": "Mute seu áudio",
"UNMUTE_AUDIO": "Desmute seu áudio",
"MUTE_VIDEO": "Mute seu vídeo",
"UNMUTE_VIDEO": "Desmute seu vídeo",
"ENABLE_SCREEN": "Habilitar compartilhamento de tela",
"DISABLE_SCREEN": "Desabilitar compartilhamento de tela",
"MORE_OPTIONS": "Mais opções",
"FULLSCREEN": "Tela cheia",
"EXIT_FULLSCREEN": "Sair da tela cheia",
"BACKGROUND": "Efeitos de fundo",
"START_RECORDING": "Iniciar_gravação",
"STOP_RECORDING": "Parar de gravar",
"LEAVE": "Sair da sessão",
"PARTICIPANTS": "Participantes",
"CHAT": "Chat",
"ACTIVITIES": "Actividades"
},
"STREAM": {
"SETTINGS": "Configurações",
"MUTE_SOUND": "Mudo",
"UNMUTE_SOUND": "Com som",
"ZOOM_IN": "Aumentar zoom",
"ZOOM_OUT": "Diminuir zoom",
"REPLACE_SCREEN": "Trocar tela"
},
"PANEL": {
"CLOSE": "Fechar",
"CHAT": {
"TITLE": "Chat",
"YOU": "Você",
"SUBTITLE": "As mensagens serão removidas no final da sessão",
"PLACEHOLDER": "Enviar uma mensagem...",
"SEND": "Enviar"
},
"PARTICIPANTS": {
"TITLE": "Participantes",
"CAMERA": "CÂMERA",
"SCREEN": "TELA"
},
"BACKGROUND": {
"TITLE": "Efeitos de fundo",
"BLURRED_SECTION": "Sem efeitos e fundo desfocado",
"NO_EFFECTS": "Sem efeito de fundo",
"BLURRED_EFFECT": "Fundo desfocado",
"IMAGES_SECTION": "Imagens de fundo"
},
"RECORDING": {
"TITLE": "Gravação",
"SUBTITLE": "Grave a sua reunião para a posteridade",
"CONTENT_TITLE": "Grave a sua videochamada",
"CONTENT_SUBTITLE": "Quando a gravação tiver terminado, poderá descarregá-la com facilidade",
"STARTING": "Começar a gravação"
}
},
"ERRORS": {
"SESSION": "Houve um erro de ligação à sessão",
"CONNECTION": "Ligação perdida",
"RECONNECT": "A tentar restabelecer a ligação à sessão...",
"TOGGLE_CAMERA": "Houve um erro ao alternar a câmara",
"TOGGLE_MICROPHONE": "Houve um erro ao alternar microhpone",
"SCREEN_SHARING": "ecrã_partilha de erros",
"SCREEN_SUPPORT": "O seu browser não suporta a partilha de ecrãs",
"MEDIA_ACCESS": "Não foi permitido o acesso a dispositivos de media",
"DEVICE_NOT_FOUND": "Nenhum dispositivo de vídeo ou áudio foi encontrado. Por favor, ligue pelo menos um"
}
}

View File

@ -9,5 +9,4 @@ export interface BackgroundEffect {
type: EffectType;
thumbnail: string;
src?: string;
description?: string;
}

View File

@ -6,5 +6,6 @@ export enum Storage{
VIDEO_DEVICE = 'openviduCallVideoDevice',
AUDIO_DEVICE = 'openviduCallAudioDevice',
AUDIO_MUTED = 'openviduCallAudioMuted',
VIDEO_MUTED = 'openviduCallVideoMuted'
VIDEO_MUTED = 'openviduCallVideoMuted',
LANG = "openviduCallLang"
}

View File

@ -27,6 +27,7 @@ import { CommonModule } from '@angular/common';
import { ModuleWithProviders, NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { ToolbarComponent } from './components/toolbar/toolbar.component';
import { VideoComponent } from './components/video/video.component';
import { ChatPanelComponent } from './components/panel/chat-panel/chat-panel.component';
@ -36,6 +37,7 @@ import { StreamComponent } from './components/stream/stream.component';
import { DialogTemplateComponent } from './components/material/dialog.component';
import { LinkifyPipe } from './pipes/linkify.pipe';
import { TranslatePipe } from './pipes/translate.pipe';
import { StreamTypesEnabledPipe, ParticipantStreamsPipe } from './pipes/participant.pipe';
import { OpenViduAngularConfig } from './config/openvidu-angular.config';
@ -79,6 +81,7 @@ import { RecordingActivityComponent } from './components/panel/activities-panel/
LinkifyPipe,
ParticipantStreamsPipe,
StreamTypesEnabledPipe,
TranslatePipe,
ParticipantPanelItemComponent,
ParticipantsPanelComponent,
VideoconferenceComponent,
@ -88,7 +91,7 @@ import { RecordingActivityComponent } from './components/panel/activities-panel/
PreJoinComponent,
BackgroundEffectsPanelComponent,
ActivitiesPanelComponent,
RecordingActivityComponent,
RecordingActivityComponent
],
imports: [
CommonModule,

View File

@ -1,5 +1,6 @@
import { Pipe, PipeTransform } from '@angular/core';
import { StreamModel, ParticipantAbstractModel } from '../models/participant.model';
import { TranslateService } from '../services/translate/translate.service';
@Pipe({ name: 'streams' })
export class ParticipantStreamsPipe implements PipeTransform {
@ -26,10 +27,18 @@ export class ParticipantStreamsPipe implements PipeTransform {
*/
@Pipe({ name: 'streamTypesEnabled' })
export class StreamTypesEnabledPipe implements PipeTransform {
constructor() {}
constructor(private translateService: TranslateService) {}
transform(participant: ParticipantAbstractModel): string {
const activeStreams = participant?.getConnectionTypesActive().toString();
return `(${activeStreams.replace(',', ', ')})`;
let result = '';
let activeStreams = participant?.getConnectionTypesActive().toString();
const activeStreamsArr: string[] = activeStreams.split(',');
activeStreamsArr.forEach((type, index) => {
result += this.translateService.translate(`PANEL.PARTICIPANTS.${type}`)
if(activeStreamsArr.length > 0 && index < activeStreamsArr.length - 1){
result += ', ';
}
});
return `(${result})`;
}
}

View File

@ -0,0 +1,14 @@
import { Pipe, PipeTransform } from '@angular/core';
import { TranslateService } from '../services/translate/translate.service';
/**
* @internal
*/
@Pipe({ name: 'translate', pure: false })
export class TranslatePipe implements PipeTransform {
constructor(private translateService: TranslateService) {}
transform(str: string): string {
return this.translateService.translate(str);
}
}

View File

@ -54,6 +54,14 @@ export class StorageService {
this.set(Storage.AUDIO_MUTED, `${muted}`);
}
setLang(lang: string){
this.set(Storage.LANG, lang);
}
getLang(): string {
return this.get(Storage.LANG);
}
private set(key: string, item: any) {
const value = JSON.stringify({ item: item });
// this.log.d('Storing on localStorage "' + key + '" with value "' + value + '"');

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { TranslateService } from './translate.service';
describe('TranslateService', () => {
let service: TranslateService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(TranslateService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,67 @@
import { Injectable } from '@angular/core';
import * as en from '../../lang/en.json';
import * as es from '../../lang/es.json';
import * as de from '../../lang/de.json';
import * as fr from '../../lang/fr.json';
import * as cn from '../../lang/cn.json';
import * as hi from '../../lang/hi.json';
import * as ja from '../../lang/ja.json';
import * as it from '../../lang/it.json';
import * as nl from '../../lang/nl.json';
import * as pt from '../../lang/pt.json';
import { StorageService } from '../storage/storage.service';
@Injectable({
providedIn: 'root'
})
export class TranslateService {
private availableLanguages = { en, es, de, fr, cn, hi, it, ja, nl, pt };
private langTitles = [
{ name: 'English', ISO: 'en' },
{ name: 'Español', ISO: 'es' },
{ name: 'Deutsch', ISO: 'de' },
{ name: 'Français', ISO: 'fr' },
{ name: '中国', ISO: 'cn' },
{ name: 'हिन्दी', ISO: 'hi' },
{ name: 'Italiano', ISO: 'it' },
{ name: 'やまと', ISO: 'ja' },
{ name: 'Dutch', ISO: 'nl' },
{ name: 'Português', ISO: 'pt' }
];
private currentLang: any;
langSelected: { name: string; ISO: string };
constructor(private storageService: StorageService) {
const iso = this.storageService.getLang() || 'en';
this.langSelected = this.langTitles.find((lang) => lang.ISO === iso);
this.currentLang = this.availableLanguages[this.langSelected.ISO];
}
setLanguage(lang: string) {
if(this.langTitles.some(l => l.ISO === lang)){
this.currentLang = this.availableLanguages[lang];
this.langSelected = this.langTitles.find((l) => l.ISO === lang);
}
}
getLangSelected(): { name: string; ISO: string } {
return this.langSelected;
}
getLanguagesInfo() {
return this.langTitles;
}
translate(key: string) {
let result = this.currentLang;
key.split('.').forEach((prop) => {
try {
result = result[prop];
} catch (error) {
return '';
}
});
return result;
}
}

View File

@ -3,6 +3,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
import { BackgroundEffect, EffectType } from '../../models/background-effect.model';
import { ParticipantService } from '../participant/participant.service';
import { TokenService } from '../token/token.service';
import { TranslateService } from '../translate/translate.service';
@Injectable({
providedIn: 'root'
@ -11,8 +12,8 @@ export class VirtualBackgroundService {
backgroundSelected = <BehaviorSubject<string>>new BehaviorSubject('');
backgroundSelectedObs: Observable<string>;
backgrounds: BackgroundEffect[] = [
{ id: 'no_effect', type: EffectType.NONE, thumbnail: 'block', description: 'No background effect' },
{ id: 'soft_blur', type: EffectType.BLUR, thumbnail: 'blur_on', description: 'Blur effect' },
{ id: 'no_effect', type: EffectType.NONE, thumbnail: 'block' },
{ id: 'soft_blur', type: EffectType.BLUR, thumbnail: 'blur_on' },
{ id: '1', type: EffectType.IMAGE, thumbnail: 'assets/backgrounds/thumbnails/bg-1.jpg', src: 'assets/backgrounds/bg-1.jpg' },
{ id: '2', type: EffectType.IMAGE, thumbnail: 'assets/backgrounds/thumbnails/bg-2.jpg', src: 'assets/backgrounds/bg-2.jpg' },
{ id: '3', type: EffectType.IMAGE, thumbnail: 'assets/backgrounds/thumbnails/bg-3.jpg', src: 'assets/backgrounds/bg-3.jpg' },
@ -34,7 +35,7 @@ export class VirtualBackgroundService {
{ id: '18', type: EffectType.IMAGE, thumbnail: 'assets/backgrounds/thumbnails/bg-18.jpg', src: 'assets/backgrounds/bg-18.jpg' }
];
constructor(private participantService: ParticipantService, private tokenService: TokenService) {
constructor(private participantService: ParticipantService, private translateService: TranslateService, private tokenService: TokenService) {
this.backgroundSelectedObs = this.backgroundSelected.asObservable();
}

View File

@ -6,6 +6,7 @@
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"resolveJsonModule": true,
"types": []
},
"exclude": [