frontend: Updated service names for better maintainability and comprehensibility

This commit is contained in:
CSantosM 2026-02-10 11:55:53 +01:00
parent dbca91f0c3
commit 7cdfdf20f9
20 changed files with 86 additions and 84 deletions

View File

@ -8,7 +8,7 @@ import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { RouterModule } from '@angular/router';
import { ConsoleNavLink } from '../../../../shared/models/sidenav.model';
import { AppDataService } from '../../../../shared/services/app-data.service';
import { AppContextService } from '../../../../shared/services/app-context.service';
import { ThemeService } from '../../../../shared/services/theme.service';
@Component({
@ -39,10 +39,10 @@ export class ConsoleNavComponent {
@Output() onLogoutClicked: EventEmitter<void> = new EventEmitter<void>();
constructor(
private appDataService: AppDataService,
private appCtxService: AppContextService,
private themeService: ThemeService
) {
this.version = `v${this.appDataService.version()} (${this.appDataService.edition()})`;
this.version = `v${this.appCtxService.version()} (${this.appCtxService.edition()})`;
this.isDarkMode = this.themeService.isDark;
}

View File

@ -4,7 +4,7 @@ import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { ActivatedRoute } from '@angular/router';
import { NavigationErrorReason } from '../../../../shared/models/navigation.model';
import { AppDataService } from '../../../../shared/services/app-data.service';
import { AppContextService } from '../../../../shared/services/app-context.service';
import { NavigationService } from '../../../../shared/services/navigation.service';
import { AuthService } from '../../../auth/services/auth.service';
import { MeetingWebComponentManagerService } from '../../../meeting/services/meeting-webcomponent-manager.service';
@ -26,7 +26,7 @@ export class ErrorComponent implements OnInit {
private route: ActivatedRoute,
protected authService: AuthService,
protected navService: NavigationService,
protected appDataService: AppDataService,
protected appCtxService: AppContextService,
protected wcManagerService: MeetingWebComponentManagerService
) {}
@ -105,7 +105,7 @@ export class ErrorComponent implements OnInit {
* Sets the back button text based on the application mode and user role
*/
async setBackButtonText() {
const isStandaloneMode = this.appDataService.isStandaloneMode();
const isStandaloneMode = this.appCtxService.isStandaloneMode();
const redirection = this.navService.getLeaveRedirectURL();
const isAdmin = await this.authService.isAdmin();
@ -126,7 +126,7 @@ export class ErrorComponent implements OnInit {
* If in standalone mode without a redirect URL, it navigates to the admin console
*/
async goBack() {
if (this.appDataService.isEmbeddedMode()) {
if (this.appCtxService.isEmbeddedMode()) {
this.wcManagerService.close();
}
@ -137,7 +137,7 @@ export class ErrorComponent implements OnInit {
return;
}
if (this.appDataService.isStandaloneMode()) {
if (this.appCtxService.isStandaloneMode()) {
// Navigate to the admin console
await this.navService.navigateTo('/overview', undefined, true);
}

View File

@ -4,7 +4,7 @@ import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { ActivatedRoute } from '@angular/router';
import { LeftEventReason } from '@openvidu-meet/typings';
import { AppDataService } from '../../../../shared/services/app-data.service';
import { AppContextService } from '../../../../shared/services/app-context.service';
import { NavigationService } from '../../../../shared/services/navigation.service';
import { AuthService } from '../../../auth/services/auth.service';
import { MeetingWebComponentManagerService } from '../../services/meeting-webcomponent-manager.service';
@ -26,7 +26,7 @@ export class EndMeetingComponent implements OnInit {
private route: ActivatedRoute,
protected authService: AuthService,
protected navService: NavigationService,
protected appDataService: AppDataService,
protected appCtxService: AppContextService,
protected wcManagerService: MeetingWebComponentManagerService
) {}
@ -92,7 +92,7 @@ export class EndMeetingComponent implements OnInit {
* Sets the back button text based on the application mode and user role
*/
private async setBackButtonText() {
const isStandaloneMode = this.appDataService.isStandaloneMode();
const isStandaloneMode = this.appCtxService.isStandaloneMode();
const redirection = this.navService.getLeaveRedirectURL();
const isAdmin = await this.authService.isAdmin();
@ -113,7 +113,7 @@ export class EndMeetingComponent implements OnInit {
* If in standalone mode without a redirect URL, it navigates to the admin console
*/
async goBack() {
if (this.appDataService.isEmbeddedMode()) {
if (this.appCtxService.isEmbeddedMode()) {
this.wcManagerService.close();
}
@ -124,7 +124,7 @@ export class EndMeetingComponent implements OnInit {
return;
}
if (this.appDataService.isStandaloneMode()) {
if (this.appCtxService.isStandaloneMode()) {
// Navigate to the admin console
await this.navService.navigateTo('/overview', undefined, true);
}

View File

@ -11,11 +11,11 @@ import {
Track
} from 'openvidu-components-angular';
import { Subject } from 'rxjs';
import { ApplicationFeatures } from '../../../../shared/models/app.model';
import { AppConfigService } from '../../../../shared/services/app-config.service';
import { FeatureConfigurationService } from '../../../../shared/services/feature-configuration.service';
import { RoomFeatures } from '../../../../shared/models/app.model';
import { GlobalConfigService } from '../../../../shared/services/global-config.service';
import { NotificationService } from '../../../../shared/services/notification.service';
import { RoomFeatureService } from '../../../../shared/services/room-feature.service';
import { RuntimeConfigService } from '../../../../shared/services/runtime-config.service';
import { SoundService } from '../../../../shared/services/sound.service';
import { RoomMemberContextService } from '../../../room-members/services/room-member-context.service';
import { MeetingLobbyComponent } from '../../components/meeting-lobby/meeting-lobby.component';
@ -62,9 +62,9 @@ export class MeetingComponent implements OnInit {
*/
protected isMeetingLeft = signal(false);
protected features: Signal<ApplicationFeatures>;
protected features: Signal<RoomFeatures>;
protected participantService = inject(RoomMemberContextService);
protected featureConfService = inject(FeatureConfigurationService);
protected roomFeatureService = inject(RoomFeatureService);
protected ovThemeService = inject(OpenViduThemeService);
protected configService = inject(GlobalConfigService);
protected notificationService = inject(NotificationService);
@ -73,7 +73,7 @@ export class MeetingComponent implements OnInit {
protected eventHandlerService = inject(MeetingEventHandlerService);
protected captionsService = inject(MeetingCaptionsService);
protected soundService = inject(SoundService);
protected appConfigService = inject(AppConfigService);
protected runtimeConfigService = inject(RuntimeConfigService);
protected destroy$ = new Subject<void>();
// === LOBBY PHASE COMPUTED SIGNALS (when showLobby = true) ===
@ -96,7 +96,7 @@ export class MeetingComponent implements OnInit {
protected hasRecordings = computed(() => this.meetingContextService.hasRecordings());
constructor() {
this.features = this.featureConfService.features;
this.features = this.roomFeatureService.features;
// Change theme variables when custom theme is enabled
effect(() => {
@ -210,7 +210,7 @@ export class MeetingComponent implements OnInit {
// }
async onViewRecordingsClicked() {
const basePath = this.appConfigService.basePath;
const basePath = this.runtimeConfigService.basePath;
const basePathForUrl = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;
window.open(`${basePathForUrl}/room/${this.roomId()}/recordings?secret=${this.roomSecret()}`, '_blank');
}

View File

@ -1,8 +1,7 @@
import { computed, effect, inject, Injectable, signal } from '@angular/core';
import { MeetRoom } from 'node_modules/@openvidu-meet/typings/dist/room';
import { ParticipantService, Room, ViewportService } from 'openvidu-components-angular';
import { AppConfigService } from '../../../shared/services/app-config.service';
import { FeatureConfigurationService } from '../../../shared/services/feature-configuration.service';
import { RoomFeatureService } from '../../../shared/services/room-feature.service';
import { SessionStorageService } from '../../../shared/services/session-storage.service';
import { CustomParticipantModel } from '../models';
@ -16,10 +15,9 @@ import { CustomParticipantModel } from '../models';
})
export class MeetingContextService {
private readonly ovParticipantService = inject(ParticipantService);
private readonly featureConfigService = inject(FeatureConfigurationService);
private readonly roomFeatureService = inject(RoomFeatureService);
private readonly viewportService = inject(ViewportService);
private readonly sessionStorageService = inject(SessionStorageService);
private readonly appConfigService = inject(AppConfigService);
private readonly _meetRoom = signal<MeetRoom | undefined>(undefined);
private readonly _lkRoom = signal<Room | undefined>(undefined);
@ -101,12 +99,12 @@ export class MeetingContextService {
/**
* Computed signal for whether the current user can moderate the room
*/
readonly canModerateRoom = computed(() => this.featureConfigService.features().canModerateRoom);
readonly canModerateRoom = computed(() => this.roomFeatureService.features().canModerateRoom);
/**
* Computed signal for whether layout switching is allowed
*/
readonly allowLayoutSwitching = computed(() => this.featureConfigService.features().allowLayoutSwitching);
readonly allowLayoutSwitching = computed(() => this.roomFeatureService.features().allowLayoutSwitching);
/**
* Computed signal for whether the device is mobile
@ -195,7 +193,7 @@ export class MeetingContextService {
* @returns CaptionsStatus ('HIDDEN' | 'ENABLED' | 'DISABLED_WITH_WARNING')
*/
getCaptionsStatus() {
return this.featureConfigService.features().captionsStatus;
return this.roomFeatureService.features().captionsStatus;
}
/**

View File

@ -18,9 +18,9 @@ import {
Room,
RoomEvent
} from 'openvidu-components-angular';
import { FeatureConfigurationService } from '../../../shared/services/feature-configuration.service';
import { NavigationService } from '../../../shared/services/navigation.service';
import { NotificationService } from '../../../shared/services/notification.service';
import { RoomFeatureService } from '../../../shared/services/room-feature.service';
import { SessionStorageService } from '../../../shared/services/session-storage.service';
import { SoundService } from '../../../shared/services/sound.service';
import { TokenStorageService } from '../../../shared/services/token-storage.service';
@ -38,7 +38,7 @@ import { MeetingWebComponentManagerService } from './meeting-webcomponent-manage
@Injectable()
export class MeetingEventHandlerService {
protected meetingContext = inject(MeetingContextService);
protected featureConfService = inject(FeatureConfigurationService);
protected roomFeatureService = inject(RoomFeatureService);
protected recordingService = inject(RecordingService);
protected roomMemberService = inject(RoomMemberContextService);
protected sessionStorageService = inject(SessionStorageService);

View File

@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router';
import { MeetRoomStatus } from '@openvidu-meet/typings';
import { LoggerService } from 'openvidu-components-angular';
import { NavigationErrorReason } from '../../../shared/models/navigation.model';
import { AppDataService } from '../../../shared/services/app-data.service';
import { AppContextService } from '../../../shared/services/app-context.service';
import { NavigationService } from '../../../shared/services/navigation.service';
import { AuthService } from '../../auth/services/auth.service';
import { RecordingService } from '../../recordings/services/recording.service';
@ -48,7 +48,7 @@ export class MeetingLobbyService {
protected authService: AuthService = inject(AuthService);
protected roomMemberService: RoomMemberContextService = inject(RoomMemberContextService);
protected navigationService: NavigationService = inject(NavigationService);
protected appDataService: AppDataService = inject(AppDataService);
protected appCtxService: AppContextService = inject(AppContextService);
protected wcManagerService: MeetingWebComponentManagerService = inject(MeetingWebComponentManagerService);
protected loggerService = inject(LoggerService);
protected log = this.loggerService.get('OpenVidu Meet - MeetingLobbyService');
@ -204,7 +204,7 @@ export class MeetingLobbyService {
*/
async goBack() {
try {
if (this.appDataService.isEmbeddedMode()) {
if (this.appCtxService.isEmbeddedMode()) {
this.wcManagerService.close();
}
@ -215,7 +215,7 @@ export class MeetingLobbyService {
return;
}
if (this.appDataService.isStandaloneMode()) {
if (this.appCtxService.isStandaloneMode()) {
// Navigate to rooms page
await this.navigationService.navigateTo('/rooms');
}
@ -267,7 +267,7 @@ export class MeetingLobbyService {
* Sets the back button text based on the application mode and user role
*/
protected async setBackButtonText(): Promise<void> {
const isStandaloneMode = this.appDataService.isStandaloneMode();
const isStandaloneMode = this.appCtxService.isStandaloneMode();
const redirection = this.navigationService.getLeaveRedirectURL();
const isAdmin = await this.authService.isAdmin();

View File

@ -6,7 +6,7 @@ import {
WebComponentOutboundEventMessage
} from '@openvidu-meet/typings';
import { LoggerService, OpenViduService } from 'openvidu-components-angular';
import { AppDataService } from '../../../shared/services/app-data.service';
import { AppContextService } from '../../../shared/services/app-context.service';
import { RoomMemberContextService } from '../../room-members/services/room-member-context.service';
import { MeetingContextService } from './meeting-context.service';
import { MeetingService } from './meeting.service';
@ -30,13 +30,13 @@ export class MeetingWebComponentManagerService {
protected readonly openviduService = inject(OpenViduService);
protected readonly meetingService = inject(MeetingService);
protected readonly loggerService = inject(LoggerService);
protected readonly appDataService = inject(AppDataService);
protected readonly appCtxService = inject(AppContextService);
constructor() {
this.log = this.loggerService.get('OpenVidu Meet - WebComponentManagerService');
this.boundHandleMessage = this.handleMessage.bind(this);
effect(() => {
if (this.appDataService.isEmbeddedMode()) {
if (this.appCtxService.isEmbeddedMode()) {
this.initialize();
}
});

View File

@ -6,7 +6,7 @@ import {
MeetRoomMemberTokenOptions
} from '@openvidu-meet/typings';
import { E2eeService, LoggerService } from 'openvidu-components-angular';
import { FeatureConfigurationService } from '../../../shared/services/feature-configuration.service';
import { RoomFeatureService } from '../../../shared/services/room-feature.service';
import { TokenStorageService } from '../../../shared/services/token-storage.service';
import { decodeToken } from '../../../shared/utils/token.utils';
import { RoomMemberService } from './room-member.service';
@ -27,7 +27,7 @@ export class RoomMemberContextService {
constructor(
protected loggerService: LoggerService,
protected roomMemberService: RoomMemberService,
protected featureConfService: FeatureConfigurationService,
protected roomFeatureService: RoomFeatureService,
protected tokenStorageService: TokenStorageService,
protected e2eeService: E2eeService
) {
@ -122,8 +122,8 @@ export class RoomMemberContextService {
this.permissions = metadata.effectivePermissions;
// Update feature configuration
this.featureConfService.setRoomMemberRole(this.role);
this.featureConfService.setRoomMemberPermissions(this.permissions);
this.roomFeatureService.setRoomMemberRole(this.role);
this.roomFeatureService.setRoomMemberPermissions(this.permissions);
} catch (error) {
this.log.e('Error decoding room member token:', error);
throw new Error('Invalid room member token');

View File

@ -12,8 +12,8 @@ import {
MeetRoomStatus
} from '@openvidu-meet/typings';
import { ILogger, LoggerService } from 'openvidu-components-angular';
import { FeatureConfigurationService } from '../../../shared/services/feature-configuration.service';
import { HttpService } from '../../../shared/services/http.service';
import { RoomFeatureService } from '../../../shared/services/room-feature.service';
import { MeetRoomClientResponseOptions } from '../models/room-request';
@Injectable({
@ -25,7 +25,7 @@ export class RoomService {
protected httpService: HttpService = inject(HttpService);
protected loggerService: LoggerService = inject(LoggerService);
protected featureConfService: FeatureConfigurationService = inject(FeatureConfigurationService);
protected roomFeatureService: RoomFeatureService = inject(RoomFeatureService);
protected log: ILogger = this.loggerService.get('OpenVidu Meet - RoomService');
@ -121,7 +121,7 @@ export class RoomService {
try {
const config = await this.getRoomConfig(roomId);
this.featureConfService.setRoomConfig(config);
this.roomFeatureService.setRoomConfig(config);
this.log.d('Room config loaded:', config);
} catch (error) {
this.log.e('Error loading room config', error);

View File

@ -24,7 +24,7 @@ export type CaptionsStatus = 'HIDDEN' | 'ENABLED' | 'DISABLED_WITH_WARNING';
/**
* Interface that defines all available features in the application
*/
export interface ApplicationFeatures {
export interface RoomFeatures {
// Media Features
/**
* Indicates if video is enabled for the participant

View File

@ -1,10 +1,14 @@
import { Injectable, WritableSignal, computed, signal } from '@angular/core';
import { ApplicationMode, Edition } from '../models';
/**
* Centralized service to manage application-wide context such as mode (embedded vs standalone), edition, and version.
* This service provides a single source of truth for application-level metadata that can be consumed across the app.
*/
@Injectable({
providedIn: 'root'
})
export class AppDataService {
export class AppContextService {
private readonly _mode: WritableSignal<ApplicationMode> = signal(ApplicationMode.STANDALONE);
private readonly _edition: WritableSignal<Edition> = signal(Edition.CE);
private readonly _version: WritableSignal<string> = signal('');

View File

@ -1,8 +1,8 @@
import { inject, Injectable } from '@angular/core';
import { MeetAppearanceConfig, SecurityConfig, WebhookConfig } from '@openvidu-meet/typings';
import { ILogger, LoggerService } from 'openvidu-components-angular';
import { FeatureConfigurationService } from './feature-configuration.service';
import { HttpService } from './http.service';
import { RoomFeatureService } from './room-feature.service';
@Injectable({
providedIn: 'root'
@ -12,7 +12,7 @@ export class GlobalConfigService {
protected loggerService: LoggerService = inject(LoggerService);
protected httpService: HttpService = inject(HttpService);
protected featureConfService: FeatureConfigurationService = inject(FeatureConfigurationService);
protected roomFeatureService: RoomFeatureService = inject(RoomFeatureService);
protected log: ILogger = this.loggerService.get('OpenVidu Meet - GlobalConfigService');
@ -51,7 +51,7 @@ export class GlobalConfigService {
async loadRoomsAppearanceConfig(): Promise<void> {
try {
const config = await this.getRoomsAppearanceConfig();
this.featureConfService.setAppearanceConfig(config.appearance);
this.roomFeatureService.setAppearanceConfig(config.appearance);
} catch (error) {
this.log.e('Error loading rooms appearance config:', error);
throw error;
@ -71,7 +71,7 @@ export class GlobalConfigService {
async loadCaptionsConfig(): Promise<void> {
try {
const config = await this.getCaptionsConfig();
this.featureConfService.setCaptionsGlobalConfig(config.enabled);
this.roomFeatureService.setCaptionsGlobalConfig(config.enabled);
} catch (error) {
this.log.e('Error loading captions config:', error);
throw error;

View File

@ -1,13 +1,13 @@
export * from './analytics.service';
export * from './api-key.service';
export * from './app-config.service';
export * from './app-data.service';
export * from './feature-configuration.service';
export * from './app-context.service';
export * from './global-config.service';
export * from './http-error-notifier.service';
export * from './http.service';
export * from './navigation.service';
export * from './notification.service';
export * from './room-feature.service';
export * from './runtime-config.service';
export * from './session-storage.service';
export * from './storage.service';
export * from './theme.service';

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { Params, Router, UrlTree } from '@angular/router';
import { NavigationErrorReason } from '../models/navigation.model';
import { AppDataService } from './app-data.service';
import { AppContextService } from './app-context.service';
import { SessionStorageService } from './session-storage.service';
@Injectable({
@ -13,7 +13,7 @@ export class NavigationService {
constructor(
private router: Router,
private sessionStorageService: SessionStorageService,
private appDataService: AppDataService
private appCtxService: AppContextService
) {}
setLeaveRedirectUrl(leaveRedirectUrl: string): void {
@ -46,7 +46,7 @@ export class NavigationService {
return;
}
const isEmbeddedMode = this.appDataService.isEmbeddedMode();
const isEmbeddedMode = this.appCtxService.isEmbeddedMode();
if (isEmbeddedMode) {
// Change the top window location if in embedded mode
window.top!.location.href = url;

View File

@ -7,12 +7,12 @@ import {
MeetRoomMemberRole
} from '@openvidu-meet/typings';
import { LoggerService } from 'openvidu-components-angular';
import { ApplicationFeatures, CaptionsStatus } from '../models/app.model';
import { CaptionsStatus, RoomFeatures } from '../models/app.model';
/**
* Base configuration for default features
* Base configuration for features, used as a starting point before applying room-specific and user-specific configurations
*/
const DEFAULT_FEATURES: ApplicationFeatures = {
const DEFAULT_FEATURES: RoomFeatures = {
videoEnabled: true,
audioEnabled: true,
showCamera: true,
@ -38,16 +38,16 @@ const DEFAULT_FEATURES: ApplicationFeatures = {
};
/**
* Centralized service to manage feature configuration
* based on room config and participant permissions
* Service responsible for calculating and providing the current set of enabled features in the meeting based on room configuration, participant role, permissions, and appearance settings.
* This service acts as a single source of truth for feature availability across the app.
*/
@Injectable({
providedIn: 'root'
})
export class FeatureConfigurationService {
export class RoomFeatureService {
protected log;
// Signals to handle reactive
// Signals to handle reactive state
protected roomConfig = signal<MeetRoomConfig | undefined>(undefined);
protected roomMemberRole = signal<MeetRoomMemberRole | undefined>(undefined);
protected roomMemberPermissions = signal<MeetRoomMemberPermissions | undefined>(undefined);
@ -55,7 +55,7 @@ export class FeatureConfigurationService {
protected captionsGlobalConfig = signal<boolean>(false);
// Computed signal to derive features based on current configurations
public readonly features = computed<ApplicationFeatures>(() =>
public readonly features = computed<RoomFeatures>(() =>
this.calculateFeatures(
this.roomConfig(),
this.roomMemberRole(),
@ -66,7 +66,7 @@ export class FeatureConfigurationService {
);
constructor(protected loggerService: LoggerService) {
this.log = this.loggerService.get('OpenVidu Meet - FeatureConfigurationService');
this.log = this.loggerService.get('OpenVidu Meet - RoomFeatureService');
}
/**
@ -118,9 +118,9 @@ export class FeatureConfigurationService {
permissions?: MeetRoomMemberPermissions,
appearanceConfig?: MeetAppearanceConfig,
captionsGlobalEnabled: boolean = false
): ApplicationFeatures {
): RoomFeatures {
// Start with default configuration
const features: ApplicationFeatures = { ...DEFAULT_FEATURES };
const features: RoomFeatures = { ...DEFAULT_FEATURES };
// Apply room configurations
if (roomConfig) {

View File

@ -9,13 +9,14 @@ declare global {
}
/**
* Service that provides access to runtime application configuration.
* Reads configuration injected by the server at runtime.
* Service responsible for managing runtime configuration such as base paths for assets.
* It reads from a global configuration object injected at runtime (e.g., by the server or hosting environment) and provides utility methods to resolve asset paths.
* This allows the application to be flexible in different deployment contexts (e.g., served from root, subpath, or embedded in an iframe).
*/
@Injectable({
providedIn: 'root'
})
export class AppConfigService {
export class RuntimeConfigService {
private _basePath: string;
constructor() {

View File

@ -1,12 +1,12 @@
import { inject, Injectable } from '@angular/core';
import { AppConfigService } from './app-config.service';
import { RuntimeConfigService } from './runtime-config.service';
/**
* Service responsible for managing sound effects within the application.
*/
@Injectable()
export class SoundService {
private appConfig = inject(AppConfigService);
private runtimeConfig = inject(RuntimeConfigService);
constructor() {}
@ -14,7 +14,7 @@ export class SoundService {
* Plays a sound to indicate that a participant has joined the meeting.
*/
playParticipantJoinedSound(): void {
const audio = new Audio(this.appConfig.resolveAssetPath('assets/sounds/participant-joined.mp3'));
const audio = new Audio(this.runtimeConfig.resolveAssetPath('assets/sounds/participant-joined.mp3'));
audio.volume = 0.4;
audio.play();
}
@ -23,17 +23,16 @@ export class SoundService {
* Plays a sound to indicate that a participant's role has been upgraded.
*/
playParticipantRoleUpgradedSound(): void {
const audio = new Audio(this.appConfig.resolveAssetPath('assets/sounds/role-upgraded.wav'));
const audio = new Audio(this.runtimeConfig.resolveAssetPath('assets/sounds/role-upgraded.wav'));
audio.volume = 0.4;
audio.play();
}
/**
* Plays a sound to indicate that a participant's role has been downgraded.
*/
playParticipantRoleDowngradedSound(): void {
const audio = new Audio(this.appConfig.resolveAssetPath('assets/sounds/role-downgraded.wav'));
const audio = new Audio(this.runtimeConfig.resolveAssetPath('assets/sounds/role-downgraded.wav'));
audio.volume = 0.4;
audio.play();
}

View File

@ -1,8 +1,8 @@
import { inject } from "@angular/core";
import { ActivatedRouteSnapshot } from "@angular/router";
import { WebComponentProperty } from "@openvidu-meet/typings";
import { AppContextService } from "../services/app-context.service";
import { NavigationService } from "../services/navigation.service";
import { AppDataService } from "../services/app-data.service";
import { inject } from "@angular/core";
export const extractParams = ({ params, queryParams }: ActivatedRouteSnapshot) => ({
roomId: params['room-id'] as string,
@ -18,8 +18,8 @@ export const extractParams = ({ params, queryParams }: ActivatedRouteSnapshot) =
*/
export const handleLeaveRedirectUrl = (leaveRedirectUrl: string | undefined) => {
const navigationService = inject(NavigationService);
const appDataService = inject(AppDataService);
const isEmbeddedMode = appDataService.isEmbeddedMode();
const appCtxService = inject(AppContextService);
const isEmbeddedMode = appCtxService.isEmbeddedMode();
// Explicit valid URL provided - use as is
if (leaveRedirectUrl && isValidUrl(leaveRedirectUrl)) {

View File

@ -1,6 +1,6 @@
import { Component, OnInit, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { AppDataService } from '@openvidu-meet/shared-components';
import { AppContextService } from '@openvidu-meet/shared-components';
import packageInfo from '../../package.json';
@Component({
@ -10,9 +10,9 @@ import packageInfo from '../../package.json';
imports: [RouterOutlet]
})
export class AppComponent implements OnInit {
private readonly appDataService = inject(AppDataService);
private readonly appCtxService = inject(AppContextService);
ngOnInit() {
this.appDataService.setVersion(packageInfo.version);
this.appCtxService.setVersion(packageInfo.version);
}
}