Skip to content

Commit

Permalink
openvidu-components: Allowed override lang options with a directive
Browse files Browse the repository at this point in the history
  • Loading branch information
CSantosM committed Jun 21, 2023
1 parent 7c6ba2b commit 5847916
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 27 deletions.
9 changes: 9 additions & 0 deletions openvidu-components-angular/e2e/webcomponent-app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import monkeyPatchMediaDevices from './utils/media-devices.js';
var MINIMAL;
var LANG;
var CAPTIONS_LANG;
var CUSTOM_LANG_OPTIONS;
var CUSTOM_CAPTIONS_LANG_OPTIONS;
var PREJOIN;
var VIDEO_MUTED;
Expand Down Expand Up @@ -52,6 +53,8 @@ $(document).ready(() => {
MINIMAL = url.searchParams.get('minimal') === null ? false : url.searchParams.get('minimal') === 'true';
LANG = url.searchParams.get('lang') || 'en';
CAPTIONS_LANG = url.searchParams.get('captionsLang') || 'en-US';
CUSTOM_LANG_OPTIONS =
url.searchParams.get('langOptions') === null ? false : url.searchParams.get('langOptions') === 'true';
CUSTOM_CAPTIONS_LANG_OPTIONS =
url.searchParams.get('captionsLangOptions') === null ? false : url.searchParams.get('captionsLangOptions') === 'true';
PARTICIPANT_NAME = url.searchParams.get('participantName') || 'TEST_USER';
Expand Down Expand Up @@ -216,6 +219,12 @@ async function joinSession(sessionName, participantName) {
webComponent.minimal = MINIMAL;
webComponent.lang = LANG;
webComponent.captionsLang = CAPTIONS_LANG;
if (CUSTOM_LANG_OPTIONS) {
webComponent.langOptions = [
{ name: 'Esp', lang: 'es' },
{ name: 'Eng', lang: 'en' }
];
}
if (CUSTOM_CAPTIONS_LANG_OPTIONS) {
webComponent.captionsLangOptions = [
{ name: 'Esp', lang: 'es-ES' },
Expand Down
44 changes: 44 additions & 0 deletions openvidu-components-angular/e2e/webcomponent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,50 @@ describe('Testing API Directives', () => {
expect(await element.getText()).equal('Unirme ahora');
});

it('should override the LANG OPTIONS', async () => {
await browser.get(`${url}&prejoin=true&langOptions=true`);


await utils.checkPrejoinIsPresent();
await utils.waitForElement('.lang-button');
await utils.clickOn('.lang-button');
await browser.sleep(500);
expect(await utils.getNumberOfElements('.lang-menu-opt')).equals(2);

await utils.clickOn('.lang-menu-opt');
await browser.sleep(500);

await utils.clickOn('#join-button');

await utils.checkSessionIsPresent();

// Checking if toolbar is present
await utils.checkToolbarIsPresent();

// Open more options menu
await utils.clickOn('#more-options-btn');

await browser.sleep(500);

// Checking if button panel is present
await utils.waitForElement('.mat-menu-content');
expect(await utils.isPresent('.mat-menu-content')).to.be.true;

// Checking if captions button is present
await utils.waitForElement('#toolbar-settings-btn');
expect(await utils.isPresent('#toolbar-settings-btn')).to.be.true;
await utils.clickOn('#toolbar-settings-btn');

await utils.waitForElement('#settings-container');
await utils.waitForElement('.lang-button');
await utils.clickOn('.lang-button');

await browser.sleep(500);

expect(await utils.getNumberOfElements('.lang-menu-opt')).equals(2);

});

it('should show the PREJOIN page', async () => {
await browser.get(`${url}&prejoin=true`);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<mat-icon>expand_more</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item *ngFor="let lang of languages" (click)="onLangSelected(lang.lang)">
<button mat-menu-item *ngFor="let lang of languages" (click)="onLangSelected(lang.lang)" class="lang-menu-opt">
<span>{{lang.name}}</span>
</button>
</mat-menu>
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { AfterViewInit, Component, OnInit, Output, ViewChild, EventEmitter } from '@angular/core';
import { AfterViewInit, Component, OnInit, Output, ViewChild, EventEmitter, OnDestroy } from '@angular/core';
import { MatMenuTrigger } from '@angular/material/menu';
import { MatSelect } from '@angular/material/select';
import { StorageService } from '../../../services/storage/storage.service';
import { TranslateService } from '../../../services/translate/translate.service';
import { LangOption } from '../../../models/lang.model';
import { Subscription } from 'rxjs';

/**
* @internal
Expand All @@ -13,11 +14,13 @@ import { LangOption } from '../../../models/lang.model';
templateUrl: './lang-selector.component.html',
styleUrls: ['./lang-selector.component.css']
})
export class LangSelectorComponent implements OnInit, AfterViewInit {
export class LangSelectorComponent implements OnInit, AfterViewInit, OnDestroy {
@Output() onLangSelectorClicked = new EventEmitter<void>();
langSelected: LangOption | undefined;
languages: LangOption[] = [];

private langSub: Subscription;

/**
* @ignore
*/
Expand All @@ -31,8 +34,12 @@ export class LangSelectorComponent implements OnInit, AfterViewInit {
constructor(private translateService: TranslateService, private storageSrv: StorageService) {}

ngOnInit(): void {
this.subscribeToLangSelected();
this.languages = this.translateService.getLanguagesInfo();
this.langSelected = this.translateService.getLangSelected();
}

ngOnDestroy(): void {
this.langSub?.unsubscribe();
}

ngAfterViewInit() {
Expand All @@ -47,6 +54,11 @@ export class LangSelectorComponent implements OnInit, AfterViewInit {
onLangSelected(lang: string) {
this.translateService.setLanguage(lang);
this.storageSrv.setLang(lang);
this.langSelected = this.translateService.getLangSelected();
}

subscribeToLangSelected() {
this.langSub = this.translateService.langSelectedObs.subscribe((lang) => {
this.langSelected = lang;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { LangOption } from '../../models/lang.model';
* | :----------------------------: | :-------: | :---------------------------------------------: |
* | **minimal** | `boolean` | {@link MinimalDirective} |
* | **lang** | `string` | {@link LangDirective} |
* | **langOptions** | `LangOption []` | {@link LangOptionsDirective} |
* | **captionsLang** | `string` | {@link CaptionsLangDirective} |
* | **captionsLangOptions** | `CaptionsLangOption []` | {@link CaptionsLangOptionsDirective} |
* | **prejoin** | `boolean` | {@link PrejoinDirective} |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
AudioMutedDirective,
CaptionsLangDirective,
CaptionsLangOptionsDirective,
LangOptionsDirective,
LangDirective,
MinimalDirective,
ParticipantNameDirective,
Expand All @@ -38,6 +39,7 @@ import {
declarations: [
MinimalDirective,
LangDirective,
LangOptionsDirective,
CaptionsLangOptionsDirective,
CaptionsLangDirective,
PrejoinDirective,
Expand Down Expand Up @@ -73,6 +75,7 @@ import {
exports: [
MinimalDirective,
LangDirective,
LangOptionsDirective,
CaptionsLangOptionsDirective,
CaptionsLangDirective,
PrejoinDirective,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CaptionsLangOption } from '../../models/caption.model';
import { CaptionService } from '../../services/caption/caption.service';
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
import { TranslateService } from '../../services/translate/translate.service';
import { LangOption } from '../../models/lang.model';


/**
Expand Down Expand Up @@ -116,6 +117,72 @@ export class LangDirective implements OnDestroy {
}
}

/**
* The **langOptions** directive allows to set the application language options.
* It will override the application languages provided by default.
* This propety is an array of objects which must comply with the {@link LangOption} interface.
*
* It is only available for {@link VideoconferenceComponent}.
*
* Default: ```
* [
* { name: 'English', lang: 'en' },
* { name: 'Español', lang: 'es' },
* { name: 'Deutsch', lang: 'de' },
* { name: 'Français', lang: 'fr' },
* { name: '中国', lang: 'cn' },
* { name: 'हिन्दी', lang: 'hi' },
* { name: 'Italiano', lang: 'it' },
* { name: 'やまと', lang: 'ja' },
* { name: 'Dutch', lang: 'nl' },
* { name: 'Português', lang: 'pt' }
* ]```
*
* Note: If you want to add a new language, you must add a new object with the name and the language code (e.g. `{ name: 'Custom', lang: 'cus' }`)
* and then add the language file in the `assets/lang` folder with the name `cus.json`.
*
*
* @example
* <ov-videoconference [langOptions]="[{name:'Spanish', lang: 'es'}]"></ov-videoconference>
*/
@Directive({
selector: 'ov-videoconference[langOptions]'
})
export class LangOptionsDirective implements OnDestroy {
/**
* @ignore
*/
@Input() set langOptions(value: LangOption []) {
this.update(value);
}

/**
* @ignore
*/
constructor(public elementRef: ElementRef, private translateService: TranslateService) {}

/**
* @ignore
*/
ngOnDestroy(): void {
this.clear();
}

/**
* @ignore
*/
clear() {
this.update(undefined);
}

/**
* @ignore
*/
update(value: LangOption [] | undefined) {
this.translateService.setLanguageOptions(value);
}
}

/**
* The **captionsLang** directive allows specify the deafult language that OpenVidu will try to recognise.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as ja from '../../lang/ja.json';
import * as nl from '../../lang/nl.json';
import * as pt from '../../lang/pt.json';
import { StorageService } from '../storage/storage.service';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { BehaviorSubject, Observable } from 'rxjs';
import { LangOption } from '../../models/lang.model';

/**
Expand All @@ -36,20 +36,24 @@ export class TranslateService {
private currentLang: any;
langSelected: LangOption | undefined;
langSelectedObs: Observable<LangOption | undefined>;
private _langSelected: BehaviorSubject<LangOption | undefined> = new BehaviorSubject<LangOption | undefined>(undefined);
private _langSelected: BehaviorSubject<LangOption | undefined> = new BehaviorSubject<LangOption | undefined>(undefined);

constructor(private storageService: StorageService) {
const iso = this.storageService.getLang() || 'en';
this.langSelected = this.langOptions.find((l) => l.lang === iso) || this.langOptions[0];
this.currentLang = this.availableLanguages[this.langSelected.lang];
this.langSelectedObs = this._langSelected.asObservable();
this._langSelected.next(this.langSelected);
this.updateLangSelected();
}

setLanguageOptions(options: LangOption[] | undefined) {
if (options && options.length > 0) {
this.langOptions = options;
this.updateLangSelected();
}
}

setLanguage(lang: string) {
async setLanguage(lang: string) {
const matchingLang = this.langOptions.find((l) => l.lang === lang);
if (matchingLang) {
this.currentLang = this.availableLanguages[lang];
this.currentLang = await this.getLangData(lang);
this.langSelected = matchingLang;
this._langSelected.next(this.langSelected);
}
Expand All @@ -75,4 +79,32 @@ export class TranslateService {
});
return result;
}

private async updateLangSelected() {
const storageLang = this.storageService.getLang();
const langOpt = this.langOptions.find((opt) => opt.lang === storageLang);
if (storageLang && langOpt) {
this.langSelected = langOpt;
} else {
this.langSelected = this.langOptions[0];
}
this.currentLang = await this.getLangData(this.langSelected.lang);
this._langSelected.next(this.langSelected);

}

private async getLangData(lang: string): Promise<void> {
if (!(lang in this.availableLanguages)) {
// Language not found in default languages options
// Try to find it in the assets/lang directory
try {
const response = await fetch(`assets/lang/${lang}.json`);
return await response.json();
} catch (error) {
console.error(`Not found ${lang}.json in assets/lang`, error);
}
} else {
return this.availableLanguages[lang];
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<ov-videoconference
[tokens]="tokens"
[minimal]="false"
[lang]="'en'"
[lang]="'es'"
[langOptions]="[{ name: 'Spanish', lang: 'es' },{ name: 'custom', lang: 'cus' }]"
[captionsLang]=""
[captionsLangOptions]="[{ name: 'Spanish', ISO: 'es-ES' },{ name: 'English', ISO: 'en-US' }]"
[captionsLangOptions]="[{ name: 'Spanish', lang: 'es-ES' },{ name: 'English', lang: 'en-US' }]"
[prejoin]="true"
[participantName]="'Participant'"
[videoMuted]="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[tokens]="_tokens"
[minimal]="_minimal"
[lang]="_lang"
[langOptions]="_langOptions"
[captionsLang]="_captionsLang"
[captionsLangOptions]="_captionsLangOptions"
[prejoin]="_prejoin"
Expand Down

0 comments on commit 5847916

Please sign in to comment.