frontend: Add version, logo and background image to ContextService and refactor code

This commit is contained in:
juancarmore 2025-03-17 15:18:29 +01:00
parent d1d3a1d96d
commit b5b39ac560
6 changed files with 202 additions and 180 deletions

View File

@ -11,6 +11,9 @@ export interface ContextData {
edition: Edition; edition: Edition;
leaveRedirectUrl: string; leaveRedirectUrl: string;
parentDomain: string; parentDomain: string;
version: string;
openviduLogoUrl: string;
backgroundImageUrl: string;
} }
export enum ApplicationMode { export enum ApplicationMode {

View File

@ -1,171 +1,150 @@
<div class="section1"> <div class="section1" [style]="{ '--background-image-url': 'url(' + backgroundImageUrl + ')' }">
<mat-toolbar id="header"> <mat-toolbar id="header">
@if (isUserLogged) { @if (isUserLogged) {
<div id="logout-content"> <div id="logout-content">
<span>Hi {{ username }}, do you want to logout?</span> <span>Hi {{ username }}, do you want to logout?</span>
<button matTooltip="Logout" mat-icon-button id="logout-btn" (click)="logout()"> <button matTooltip="Logout" mat-icon-button id="logout-btn" (click)="logout()">
<mat-icon>logout</mat-icon> <mat-icon>logout</mat-icon>
</button> </button>
</div> </div>
} }
</mat-toolbar> </mat-toolbar>
<div class="openvidu-slogan-container"> <div class="openvidu-slogan-container">
<a href="https://openvidu.io/" target="_blank"> <a href="https://openvidu.io/" target="_blank">
<img id="form-img" src="assets/images/openvidu_logo.png" /> <img id="form-img" [src]="openviduLogoUrl" />
</a> </a>
<h4 id="slogan-text">Videoconference rooms in one click</h4> <h4 id="slogan-text">Videoconference rooms in one click</h4>
</div> </div>
@if (!loading) { @if (!loading) {
<div class="form-container"> <div class="form-container">
<div class="grid"> <div class="grid">
@if (isPrivateAccess && !isUserLogged) { @if (isPrivateAccess && !isUserLogged) {
<form <form [formGroup]="loginForm" novalidate (ngSubmit)="login()" id="form-login" class="form login">
[formGroup]="loginForm" <div class="form-field" id="login-username">
novalidate <label for="login-username" [ngClass]="{ error: loginError }">
(ngSubmit)="login()" <mat-icon matTooltip="Username">person</mat-icon>
id="form-login" <span class="hidden">Username</span>
class="form login" </label>
> <input
<div class="form-field" id="login-username"> formControlName="username"
<label for="login-username" [ngClass]="{ error: loginError }"> autocomplete="off"
<mat-icon matTooltip="Username">person</mat-icon> type="text"
<span class="hidden">Username</span> name="username"
</label> class="form-input"
<input placeholder="Username"
formControlName="username" />
autocomplete="off" </div>
type="text" <div class="form-field" id="login-password">
name="username" <label for="login-password" [ngClass]="{ error: loginError }">
class="form-input" <mat-icon matTooltip="Password">lock</mat-icon>
placeholder="Username" <span class="hidden">Password</span>
/> </label>
</div> <input
<div class="form-field" id="login-password"> formControlName="password"
<label for="login-password" [ngClass]="{ error: loginError }"> type="password"
<mat-icon matTooltip="Password">lock</mat-icon> name="password"
<span class="hidden">Password</span> class="form-input"
</label> placeholder="Password"
<input />
formControlName="password" </div>
type="password" @if (loginError) {
name="password" <div class="roomError" id="login-error">Authentication failed. Try again.</div>
class="form-input" }
placeholder="Password" <div class="form-field">
/> <button mat-button id="join-btn" type="submit" [disabled]="loginForm.invalid">Login</button>
</div> </div>
@if (loginError) { @if (serverConnectionError) {
<div class="roomError" id="login-error">Authentication failed. Try again.</div> <div class="roomError" id="serverConnectionError">
} <mat-icon>error</mat-icon>
<div class="form-field"> <span>Server connection failed!</span>
<button </div>
mat-button }
id="join-btn" </form>
type="submit" }
[disabled]="loginForm.invalid" @if (isUserLogged || !isPrivateAccess) {
> <form
Login [formGroup]="roomForm"
</button> novalidate
</div> (ngSubmit)="goToVideoRoom()"
@if (serverConnectionError) { id="form-room"
<div class="roomError" id="serverConnectionError"> class="form login"
<mat-icon>error</mat-icon> >
<span>Server connection failed!</span> <div class="form-field">
</div> <label for="room-name-input" [ngClass]="{ error: roomForm.get('roomNamePrefix')?.invalid }">
} <mat-icon matTooltip="Room name">video_camera_front</mat-icon>
</form> <span class="hidden">Room Name</span></label
} >
@if (isUserLogged || !isPrivateAccess) { <input
<form formControlName="roomNamePrefix"
[formGroup]="roomForm" autocomplete="off"
novalidate id="room-name-input"
(ngSubmit)="goToVideoRoom()" type="text"
id="form-room" name="roomNamePrefix"
class="form login" class="form-input"
> placeholder="Room Name"
<div class="form-field"> (keydown)="keyDown($event)"
<label for="room-name-input" [ngClass]="{ error: roomForm.get('roomNamePrefix')?.invalid }"> />
<mat-icon matTooltip="Room name">video_camera_front</mat-icon> @if (roomForm.get('roomNamePrefix')?.value) {
<span class="hidden">Room Name</span></label <button
> matSuffix
<input mat-icon-button
formControlName="roomNamePrefix" aria-label="Clear"
autocomplete="off" id="clear-room-name-btn"
id="room-name-input" (click)="clearRoomName()"
type="text" >
name="roomNamePrefix" <mat-icon>close</mat-icon>
class="form-input" </button>
placeholder="Room Name" }
(keydown)="keyDown($event)" <button
/> matTooltip="Generate room name prefix"
@if (roomForm.get('roomNamePrefix')?.value) { mat-icon-button
<button matSuffix mat-icon-button aria-label="Clear" id="clear-room-name-btn" (click)="clearRoomName()"> id="room-name-generator-btn"
<mat-icon>close</mat-icon> (click)="generateRoomName($event)"
</button> >
} <mat-icon>cached</mat-icon>
<button </button>
matTooltip="Generate room name prefix" </div>
mat-icon-button @if (roomForm.get('roomNamePrefix')?.hasError('required')) {
id="room-name-generator-btn" <div class="roomError" id="requiredNameError">Room name is required</div>
(click)="generateRoomName($event)" }
> @if (roomForm.get('roomNamePrefix')?.hasError('minlength')) {
<mat-icon>cached</mat-icon> <div class="roomError" id="shortNameError">Room name is too short!</div>
</button> }
</div> <div class="form-field">
@if (roomForm.get('roomNamePrefix')?.hasError('required')) { <button mat-button id="join-btn" type="submit" [disabled]="roomForm.invalid">JOIN</button>
<div </div>
class="roomError" @if (serverConnectionError) {
id="requiredNameError" <div class="roomError" id="serverConnectionError">
> <mat-icon>error</mat-icon>
Room name is required <span>Server connection failed!</span>
</div> </div>
} }
@if (roomForm.get('roomNamePrefix')?.hasError('minlength')) { </form>
<div class="roomError" id="shortNameError"> }
Room name is too short! </div>
</div> </div>
} }
<div class="form-field">
<button
mat-button
id="join-btn"
type="submit"
[disabled]="roomForm.invalid"
>
JOIN
</button>
</div>
@if (serverConnectionError) {
<div class="roomError" id="serverConnectionError">
<mat-icon>error</mat-icon>
<span>Server connection failed!</span>
</div>
}
</form>
}
</div>
</div>
}
<mat-toolbar class="footer"> <mat-toolbar class="footer">
<span> <span>
Photo by Photo by
<a <a
rel="noopener noreferrer" rel="noopener noreferrer"
target="_blank" target="_blank"
href="https://unsplash.com/@danielleone?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText" href="https://unsplash.com/@danielleone?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"
> >
Daniel Leone Daniel Leone
</a> </a>
on on
<a <a
href="https://unsplash.com/s/photos/mountain?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText" href="https://unsplash.com/s/photos/mountain?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"
target="_blank" target="_blank"
> >
Unsplash Unsplash
</a> </a>
</span> </span>
<div id="meet-version"> <div id="meet-version">
<span>{{ version }}</span> <span>{{ version }}</span>
</div> </div>
</mat-toolbar> </mat-toolbar>
</div> </div>

View File

@ -17,7 +17,7 @@ $formGap: 0.375rem;
.section1 { .section1 {
background: background:
linear-gradient(rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)), linear-gradient(rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)),
url('/assets/images/bg.webp') top center no-repeat; var(--background-image-url) top center no-repeat;
background-size: cover; background-size: cover;
height: 100%; height: 100%;
text-align: center; text-align: center;

View File

@ -14,10 +14,9 @@ import { NgClass } from '@angular/common';
import { MatToolbar } from '@angular/material/toolbar'; import { MatToolbar } from '@angular/material/toolbar';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { HttpService } from '../../services/http/http.service'; import { ContextService, HttpService } from '../../services/index';
import { OpenViduMeetRoom, OpenViduMeetRoomOptions } from '../../typings/ce/room'; import { OpenViduMeetRoom, OpenViduMeetRoomOptions } from '../../typings/ce/room';
import { animals, colors, Config, uniqueNamesGenerator } from 'unique-names-generator'; import { animals, colors, Config, uniqueNamesGenerator } from 'unique-names-generator';
import packageInfo from '../../../../../../package.json';
@Component({ @Component({
selector: 'app-room-creator', selector: 'app-room-creator',
@ -27,9 +26,12 @@ import packageInfo from '../../../../../../package.json';
imports: [MatToolbar, MatIconButton, MatTooltip, MatIcon, FormsModule, ReactiveFormsModule, NgClass, MatButton] imports: [MatToolbar, MatIconButton, MatTooltip, MatIcon, FormsModule, ReactiveFormsModule, NgClass, MatButton]
}) })
export class RoomCreatorComponent implements OnInit, OnDestroy { export class RoomCreatorComponent implements OnInit, OnDestroy {
version = '';
openviduLogoUrl = '';
backgroundImageUrl = '';
roomForm: FormGroup; roomForm: FormGroup;
loginForm: FormGroup; loginForm: FormGroup;
version = '';
isPrivateAccess = false; isPrivateAccess = false;
username = ''; username = '';
loginError = false; loginError = false;
@ -44,7 +46,8 @@ export class RoomCreatorComponent implements OnInit, OnDestroy {
private httpService: HttpService, private httpService: HttpService,
// private callService: ConfigService, // private callService: ConfigService,
private fb: FormBuilder, private fb: FormBuilder,
private route: ActivatedRoute private route: ActivatedRoute,
private contextService: ContextService
) { ) {
this.loginForm = this.fb.group({ this.loginForm = this.fb.group({
username: [ username: [
@ -60,7 +63,9 @@ export class RoomCreatorComponent implements OnInit, OnDestroy {
} }
async ngOnInit() { async ngOnInit() {
this.version = packageInfo.version; this.version = this.contextService.getVersion();
this.openviduLogoUrl = this.contextService.getOpenViduLogoUrl();
this.backgroundImageUrl = this.contextService.getBackgroundImageUrl();
this.subscribeToQueryParams(); this.subscribeToQueryParams();
try { try {

View File

@ -26,7 +26,10 @@ export class ContextService {
mode: ApplicationMode.STANDALONE, mode: ApplicationMode.STANDALONE,
edition: Edition.CE, edition: Edition.CE,
leaveRedirectUrl: '', leaveRedirectUrl: '',
parentDomain: '' parentDomain: '',
version: '',
openviduLogoUrl: '',
backgroundImageUrl: ''
}; };
private log; private log;
@ -38,6 +41,30 @@ export class ContextService {
this.log = this.loggerService.get('OpenVidu Meet - ContextService'); this.log = this.loggerService.get('OpenVidu Meet - ContextService');
} }
setVersion(version: string): void {
this.context.version = version;
}
getVersion(): string {
return this.context.version;
}
setOpenViduLogoUrl(openviduLogoUrl: string): void {
this.context.openviduLogoUrl = openviduLogoUrl;
}
getOpenViduLogoUrl(): string {
return this.context.openviduLogoUrl;
}
setBackgroundImageUrl(backgroundImageUrl: string): void {
this.context.backgroundImageUrl = backgroundImageUrl;
}
getBackgroundImageUrl(): string {
return this.context.backgroundImageUrl;
}
/** /**
* Sets the application mode. * Sets the application mode.
* @param mode - An ApplicationMode value representing the application mode. * @param mode - An ApplicationMode value representing the application mode.

View File

@ -1,5 +1,7 @@
import { Component } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { RouterOutlet } from '@angular/router'; import { RouterOutlet } from '@angular/router';
import { ContextService } from 'shared-meet-components';
import packageInfo from '../../package.json';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@ -8,6 +10,12 @@ import { RouterOutlet } from '@angular/router';
standalone: true, standalone: true,
imports: [RouterOutlet] imports: [RouterOutlet]
}) })
export class AppComponent { export class AppComponent implements OnInit {
title = 'OpenVidu Meet'; constructor(private contextService: ContextService) {}
ngOnInit() {
this.contextService.setVersion(packageInfo.version);
this.contextService.setOpenViduLogoUrl('assets/images/openvidu_logo.png');
this.contextService.setBackgroundImageUrl('/assets/images/bg.webp');
}
} }