frontend: enhance layout management with reactive settings and storage integration
This commit is contained in:
parent
c8cfb6598e
commit
153af9c673
@ -1,5 +1,4 @@
|
||||
import { Component, signal, computed, effect, inject, DestroyRef, input, untracked } from '@angular/core';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { Participant } from 'livekit-client';
|
||||
import { LoggerService, OpenViduService, ILogger, OpenViduComponentsUiModule } from 'openvidu-components-angular';
|
||||
import { MeetLayoutMode } from '../../../models/layout.model';
|
||||
@ -23,66 +22,45 @@ import { MeetingService } from '../../../services/meeting/meeting.service';
|
||||
})
|
||||
export class MeetingLayoutComponent {
|
||||
private readonly loggerSrv = inject(LoggerService);
|
||||
private readonly layoutService = inject(MeetLayoutService);
|
||||
protected readonly layoutService = inject(MeetLayoutService);
|
||||
protected readonly openviduService = inject(OpenViduService);
|
||||
protected meetingContextService = inject(MeetingContextService);
|
||||
protected meetingService = inject(MeetingService);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
protected readonly destroyRef = inject(DestroyRef);
|
||||
private readonly log: ILogger = this.loggerSrv.get('MeetingLayoutComponent');
|
||||
protected readonly linkOverlayTitle = 'Start collaborating';
|
||||
protected readonly linkOverlaySubtitle = 'Share this link to bring others into the meeting';
|
||||
protected readonly linkOverlayTitleSize: 'sm' | 'md' | 'lg' | 'xl' = 'xl';
|
||||
protected readonly linkOverlayTitleWeight: 'normal' | 'bold' = 'bold';
|
||||
|
||||
/**
|
||||
* Maximum number of active remote speakers to show in the layout when the last speakers layout is enabled.
|
||||
*/
|
||||
readonly maxRemoteSpeakers = input<number>(4);
|
||||
protected readonly meetingUrl = computed(() => this.meetingContextService.meetingUrl());
|
||||
|
||||
protected meetingUrl = computed(() => {
|
||||
return this.meetingContextService.meetingUrl();
|
||||
});
|
||||
|
||||
protected showMeetingLinkOverlay = computed(() => {
|
||||
protected readonly showMeetingLinkOverlay = computed(() => {
|
||||
const remoteParticipants = this.meetingContextService.remoteParticipants();
|
||||
return this.meetingContextService.canModerateRoom() && remoteParticipants.length === 0;
|
||||
});
|
||||
|
||||
// Reactive state with Signals - now using MeetingContextService
|
||||
private readonly remoteParticipants = computed(() => this.meetingContextService.remoteParticipants());
|
||||
|
||||
private readonly layoutMode = toSignal(this.layoutService.layoutMode$, {
|
||||
initialValue: MeetLayoutMode.SMART_MOSAIC
|
||||
});
|
||||
|
||||
/**
|
||||
* Tracks the order of active speakers (most recent last)
|
||||
* Using array instead of Map for better ordered iteration performance
|
||||
*/
|
||||
private readonly activeSpeakersOrder = signal<string[]>([]);
|
||||
|
||||
/**
|
||||
* Computed signal that determines if last speakers layout is enabled
|
||||
*/
|
||||
private readonly isLastSpeakersLayoutEnabled = computed(() => this.layoutMode() === MeetLayoutMode.SMART_MOSAIC);
|
||||
|
||||
/**
|
||||
* Computed signal that provides the filtered list of participants to display.
|
||||
* This is the main output used by the template.
|
||||
* Optimized with memoization via computed()
|
||||
* Automatically reacts to changes in layout service configuration.
|
||||
*/
|
||||
readonly filteredRemoteParticipants = computed(() => {
|
||||
const remoteParticipants = this.remoteParticipants();
|
||||
const isLastSpeakersMode = this.isLastSpeakersLayoutEnabled();
|
||||
const remoteParticipants = this.meetingContextService.remoteParticipants();
|
||||
const isLastSpeakersMode = this.layoutService.isSmartMosaicEnabled();
|
||||
|
||||
if (!isLastSpeakersMode) {
|
||||
// DEFAULT layout mode: show all participants
|
||||
// MOSAIC layout mode: show all participants
|
||||
return remoteParticipants;
|
||||
}
|
||||
|
||||
// LAST_SPEAKERS layout mode: show only active speakers
|
||||
// SMART_MOSAIC layout mode: show only active speakers
|
||||
const activeSpeakersOrder = this.activeSpeakersOrder();
|
||||
const maxSpeakers = this.maxRemoteSpeakers();
|
||||
const maxSpeakers = this.layoutService.maxRemoteSpeakers();
|
||||
|
||||
// If no active speakers yet, initialize with first N remote participants
|
||||
if (activeSpeakersOrder.length === 0) {
|
||||
@ -113,42 +91,22 @@ export class MeetingLayoutComponent {
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
const lkRoom = this.meetingContextService.lkRoom();
|
||||
if (lkRoom) {
|
||||
if (this.meetingContextService.lkRoom()) {
|
||||
this.setupActiveSpeakersListener();
|
||||
}
|
||||
});
|
||||
|
||||
// Effect to log layout mode changes (development only)
|
||||
effect(() => {
|
||||
const mode = this.layoutMode();
|
||||
this.log.d(`Layout mode changed to: ${mode}`);
|
||||
});
|
||||
|
||||
// Effect to handle active speakers cleanup when participants leave
|
||||
effect(() => {
|
||||
const remoteParticipants = this.remoteParticipants();
|
||||
if (!this.layoutService.isSmartMosaicEnabled()) return;
|
||||
|
||||
const remoteParticipants = this.meetingContextService.remoteParticipants();
|
||||
const activeSpeakersOrder = this.activeSpeakersOrder();
|
||||
|
||||
// Only cleanup in last speakers mode
|
||||
if (!this.isLastSpeakersLayoutEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create set of current participant identities for O(1) lookup
|
||||
const currentIdentities = new Set(remoteParticipants.map((p) => p.identity));
|
||||
|
||||
// Filter out speakers who are no longer in the room
|
||||
const cleanedOrder = activeSpeakersOrder.filter((identity) => currentIdentities.has(identity));
|
||||
|
||||
// Only update if something changed
|
||||
if (cleanedOrder.length !== activeSpeakersOrder.length) {
|
||||
untracked(() => {
|
||||
this.activeSpeakersOrder.set(cleanedOrder);
|
||||
this.log.d(
|
||||
`Cleaned active speakers order. Removed ${activeSpeakersOrder.length - cleanedOrder.length} participants`
|
||||
);
|
||||
});
|
||||
untracked(() => this.activeSpeakersOrder.set(cleanedOrder));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -184,76 +142,46 @@ export class MeetingLayoutComponent {
|
||||
|
||||
/**
|
||||
* Handles active speakers changed events from LiveKit
|
||||
* Optimized with early returns and Set operations
|
||||
*/
|
||||
private readonly handleActiveSpeakersChanged = (speakers: Participant[]): void => {
|
||||
// Early return if not in last speakers mode
|
||||
if (!this.isLastSpeakersLayoutEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (!this.layoutService.isSmartMosaicEnabled()) return;
|
||||
|
||||
// Filter out local participant
|
||||
const remoteSpeakers = speakers.filter((p) => !p.isLocal);
|
||||
if (remoteSpeakers.length === 0) return;
|
||||
|
||||
if (remoteSpeakers.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get new speaker identities (trimmed to max)
|
||||
const maxSpeakers = this.maxRemoteSpeakers();
|
||||
const maxSpeakers = this.layoutService.maxRemoteSpeakers();
|
||||
const newSpeakerIdentities = remoteSpeakers.map((p) => p.identity).slice(0, maxSpeakers);
|
||||
|
||||
// Early return if speakers haven't changed (optimization)
|
||||
if (this.isSameSpeakersList(newSpeakerIdentities)) {
|
||||
return;
|
||||
}
|
||||
if (this.isSameSpeakersList(newSpeakerIdentities)) return;
|
||||
|
||||
// Update active speakers order
|
||||
this.updateActiveSpeakersOrder(newSpeakerIdentities);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the new speakers list is identical to the current one
|
||||
* Optimized comparison with early returns
|
||||
*/
|
||||
private isSameSpeakersList(newIdentities: string[]): boolean {
|
||||
const currentOrder = this.activeSpeakersOrder();
|
||||
const maxSpeakers = this.maxRemoteSpeakers();
|
||||
|
||||
// Get the current active speakers (last N)
|
||||
const maxSpeakers = this.layoutService.maxRemoteSpeakers();
|
||||
const currentActiveIdentities = currentOrder.slice(-maxSpeakers);
|
||||
|
||||
// Quick length check
|
||||
if (currentActiveIdentities.length !== newIdentities.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare elements in order
|
||||
return currentActiveIdentities.every((identity, index) => identity === newIdentities[index]);
|
||||
return (
|
||||
currentActiveIdentities.length === newIdentities.length &&
|
||||
currentActiveIdentities.every((identity, index) => identity === newIdentities[index])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the active speakers order with new speakers
|
||||
* Maintains order with most recent speakers at the end
|
||||
* Uses efficient Set operations for O(1) lookups
|
||||
*/
|
||||
private updateActiveSpeakersOrder(newSpeakerIdentities: string[]): void {
|
||||
const currentOrder = this.activeSpeakersOrder();
|
||||
const newIdentitiesSet = new Set(newSpeakerIdentities);
|
||||
|
||||
// Remove new speakers from current position (if they exist)
|
||||
const filteredOrder = currentOrder.filter((identity) => !newIdentitiesSet.has(identity));
|
||||
|
||||
// Add new speakers to the end (most recent)
|
||||
const updatedOrder = [...filteredOrder, ...newSpeakerIdentities];
|
||||
|
||||
// Trim to reasonable max size to prevent memory leaks
|
||||
// Keep 2x maxRemoteSpeakers for smooth transitions
|
||||
const maxSpeakers = this.maxRemoteSpeakers();
|
||||
const maxSpeakers = this.layoutService.maxRemoteSpeakers();
|
||||
const trimmedOrder = updatedOrder.slice(-(maxSpeakers * 2));
|
||||
|
||||
this.activeSpeakersOrder.set(trimmedOrder);
|
||||
|
||||
this.log.d(`Active speakers updated: ${trimmedOrder.length} in order`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<div class="layout-mode-container">
|
||||
<mat-radio-group
|
||||
class="layout-radio-group"
|
||||
[(ngModel)]="layoutMode"
|
||||
[ngModel]="layoutMode()"
|
||||
(ngModelChange)="onLayoutModeChange($event)"
|
||||
aria-label="Select layout mode"
|
||||
>
|
||||
@ -41,11 +41,12 @@
|
||||
[max]="6"
|
||||
[step]="1"
|
||||
[displayWith]="formatLabel"
|
||||
[showTickMarks]="true"
|
||||
discrete
|
||||
>
|
||||
<input
|
||||
matSliderThumb
|
||||
[(ngModel)]="participantCount"
|
||||
[ngModel]="participantCount()"
|
||||
(ngModelChange)="onParticipantCountChange($event)"
|
||||
aria-label="Number of participants to display"
|
||||
/>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, computed, signal } from '@angular/core';
|
||||
import { Component, computed, inject } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
@ -8,12 +8,10 @@ import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MeetLayoutMode } from '../../../models/layout.model';
|
||||
import { MeetLayoutService } from '../../../services/layout.service';
|
||||
|
||||
/**
|
||||
* Component for additional settings in the Settings Panel.
|
||||
* This component allows users to configure grid layout preferences including:
|
||||
* - Layout mode (Mosaic or Mosaic Smart)
|
||||
* - Number of participants to display in Smart mode
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ov-meeting-settings-panel',
|
||||
@ -31,43 +29,40 @@ import { MeetLayoutMode } from '../../../models/layout.model';
|
||||
styleUrl: './meeting-settings-panel.component.scss'
|
||||
})
|
||||
export class MeetingSettingsPanelComponent {
|
||||
private readonly layoutService = inject(MeetLayoutService);
|
||||
|
||||
/**
|
||||
* Expose LayoutMode enum to template
|
||||
*/
|
||||
readonly LayoutMode = MeetLayoutMode;
|
||||
|
||||
/**
|
||||
* Current selected layout mode
|
||||
* Current layout mode
|
||||
*/
|
||||
layoutMode = signal<MeetLayoutMode>(MeetLayoutMode.MOSAIC);
|
||||
protected readonly layoutMode = computed(() => this.layoutService.layoutMode());
|
||||
|
||||
/**
|
||||
* Number of participants to display in Smart mode
|
||||
* Range: 1-20
|
||||
* Current participant count
|
||||
*/
|
||||
participantCount = signal<number>(6);
|
||||
protected readonly participantCount = computed(() => this.layoutService.maxRemoteSpeakers());
|
||||
|
||||
/**
|
||||
* Computed property to check if Smart mode is active
|
||||
* Computed property to check if Smart Mosaic mode is active
|
||||
*/
|
||||
isSmartMode = computed(() => this.layoutMode() === MeetLayoutMode.SMART_MOSAIC);
|
||||
readonly isSmartMode = this.layoutService.isSmartMosaicEnabled;
|
||||
|
||||
/**
|
||||
* Handler for layout mode change
|
||||
*/
|
||||
onLayoutModeChange(mode: MeetLayoutMode): void {
|
||||
this.layoutMode.set(mode);
|
||||
console.log('Layout mode changed to:', mode);
|
||||
// TODO: Integrate with layout service when available
|
||||
this.layoutService.setLayoutMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for participant count change
|
||||
*/
|
||||
onParticipantCountChange(count: number): void {
|
||||
this.participantCount.set(count);
|
||||
console.log('Participant count changed to:', count);
|
||||
// TODO: Integrate with layout service when available
|
||||
this.layoutService.setMaxRemoteSpeakers(count);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
export enum MeetStorageKeys {
|
||||
LAYOUT_MODE = 'layoutMode'
|
||||
LAYOUT_MODE = 'layoutMode',
|
||||
MAX_REMOTE_SPEAKERS = 'maxRemoteSpeakers'
|
||||
}
|
||||
|
||||
export const STORAGE_PREFIX = 'OpenViduMeet-';
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, signal, computed, effect } from '@angular/core';
|
||||
import { LayoutService, LoggerService, ViewportService } from 'openvidu-components-angular';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { MeetLayoutMode } from '../models/layout.model';
|
||||
import { MeetStorageService } from './storage.service';
|
||||
|
||||
@ -8,9 +7,21 @@ import { MeetStorageService } from './storage.service';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MeetLayoutService extends LayoutService {
|
||||
private layoutMode: MeetLayoutMode = MeetLayoutMode.MOSAIC;
|
||||
layoutModeSubject: Subject<MeetLayoutMode> = new Subject<MeetLayoutMode>();
|
||||
layoutMode$: Observable<MeetLayoutMode> = this.layoutModeSubject.asObservable();
|
||||
|
||||
private DEFAULT_MIN_REMOTE_SPEAKERS = 1;
|
||||
private DEFAULT_SMART_MOSAIC_SPEAKERS = 4;
|
||||
private DEFAULT_LAYOUT_MODE = MeetLayoutMode.MOSAIC;
|
||||
|
||||
private readonly _layoutMode = signal<MeetLayoutMode>(MeetLayoutMode.MOSAIC);
|
||||
readonly layoutMode = this._layoutMode.asReadonly();
|
||||
private readonly _maxRemoteSpeakers = signal<number>(this.DEFAULT_SMART_MOSAIC_SPEAKERS);
|
||||
readonly maxRemoteSpeakers = this._maxRemoteSpeakers.asReadonly();
|
||||
|
||||
/**
|
||||
* Computed signal that checks if Smart Mosaic layout is enabled
|
||||
* This is automatically recomputed when layoutMode changes
|
||||
*/
|
||||
readonly isSmartMosaicEnabled = computed(() => this._layoutMode() === MeetLayoutMode.SMART_MOSAIC);
|
||||
|
||||
constructor(
|
||||
protected loggerService: LoggerService,
|
||||
@ -21,48 +32,125 @@ export class MeetLayoutService extends LayoutService {
|
||||
this.log = this.loggerService.get('MeetLayoutService');
|
||||
|
||||
this.initializeLayoutMode();
|
||||
this.initializeMaxRemoteSpeakers();
|
||||
|
||||
// Effect to persist layout mode changes to storage
|
||||
effect(() => {
|
||||
const mode = this._layoutMode();
|
||||
this.storageService.setLayoutMode(mode);
|
||||
this.log.d(`Layout mode persisted to storage: ${mode}`);
|
||||
});
|
||||
|
||||
// Effect to persist max remote speakers changes to storage
|
||||
effect(() => {
|
||||
const count = this._maxRemoteSpeakers();
|
||||
this.storageService.setMaxRemoteSpeakers(count);
|
||||
this.log.d(`Max remote speakers persisted to storage: ${count}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the layout mode for the application.
|
||||
*
|
||||
* This method retrieves the layout mode from the storage service. If the retrieved
|
||||
* layout mode is valid and exists in the `LayoutMode` enum, it sets the layout mode
|
||||
* to the retrieved value. Otherwise, it defaults to `LayoutMode.DEFAULT`.
|
||||
* Retrieves the layout mode from storage or defaults to MOSAIC.
|
||||
*/
|
||||
private initializeLayoutMode() {
|
||||
private initializeLayoutMode(): void {
|
||||
const layoutMode = this.storageService.getLayoutMode();
|
||||
if (layoutMode && Object.values(MeetLayoutMode).includes(layoutMode)) {
|
||||
this.layoutMode = layoutMode;
|
||||
this._layoutMode.set(layoutMode);
|
||||
} else {
|
||||
this.layoutMode = MeetLayoutMode.MOSAIC;
|
||||
this._layoutMode.set(this.DEFAULT_LAYOUT_MODE);
|
||||
}
|
||||
this.log.d(`Layout mode initialized: ${this._layoutMode()}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the max remote speakers count from storage.
|
||||
*/
|
||||
private initializeMaxRemoteSpeakers(): void {
|
||||
const count = this.storageService.getMaxRemoteSpeakers();
|
||||
if (count && count >= this.DEFAULT_MIN_REMOTE_SPEAKERS && count <= this.DEFAULT_SMART_MOSAIC_SPEAKERS) {
|
||||
this._maxRemoteSpeakers.set(count);
|
||||
} else {
|
||||
this._maxRemoteSpeakers.set(this.DEFAULT_SMART_MOSAIC_SPEAKERS);
|
||||
}
|
||||
this.log.d(`Max remote speakers initialized: ${this._maxRemoteSpeakers()}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current layout mode is set to display the last speakers.
|
||||
*
|
||||
* @returns {boolean} `true` if the layout mode is set to `LAST_SPEAKERS`, otherwise `false`.
|
||||
* @deprecated Use isSmartMosaicEnabled computed signal instead
|
||||
* @returns {boolean} `true` if the layout mode is set to `SMART_MOSAIC`, otherwise `false`.
|
||||
*/
|
||||
isLastSpeakersLayoutEnabled(): boolean {
|
||||
return this.layoutMode === MeetLayoutMode.SMART_MOSAIC;
|
||||
return this._layoutMode() === MeetLayoutMode.SMART_MOSAIC;
|
||||
}
|
||||
|
||||
setLayoutMode(layoutMode: MeetLayoutMode) {
|
||||
const layoutNeedsUpdate = this.layoutMode !== layoutMode && Object.values(MeetLayoutMode).includes(layoutMode);
|
||||
/**
|
||||
* Sets the layout mode and triggers layout update.
|
||||
* This method validates the mode and only updates if it's different.
|
||||
*
|
||||
* @param layoutMode - The new layout mode to set
|
||||
*/
|
||||
setLayoutMode(layoutMode: MeetLayoutMode): void {
|
||||
const currentMode = this._layoutMode();
|
||||
const isValidMode = Object.values(MeetLayoutMode).includes(layoutMode);
|
||||
|
||||
if (!layoutNeedsUpdate) {
|
||||
if (!isValidMode) {
|
||||
this.log.w(`Invalid layout mode: ${layoutMode}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.log.d(`Layout mode updated from ${this.layoutMode} to ${layoutMode}`);
|
||||
this.layoutMode = layoutMode;
|
||||
this.layoutModeSubject.next(this.layoutMode);
|
||||
this.storageService.setLayoutMode(layoutMode);
|
||||
if (currentMode === layoutMode) {
|
||||
this.log.d(`Layout mode already set to: ${layoutMode}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.log.d(`Layout mode updated from ${currentMode} to ${layoutMode}`);
|
||||
this._layoutMode.set(layoutMode);
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of remote speakers to display in Smart Mosaic mode.
|
||||
* Validates the count is between the default minimum and the default maximum.
|
||||
*
|
||||
* @param count - Number of remote participants to display (default minimum to default maximum)
|
||||
*/
|
||||
setMaxRemoteSpeakers(count: number): void {
|
||||
if (count < this.DEFAULT_MIN_REMOTE_SPEAKERS || count > this.DEFAULT_SMART_MOSAIC_SPEAKERS) {
|
||||
this.log.w(`Invalid max remote speakers count: ${count}. Must be between ${this.DEFAULT_MIN_REMOTE_SPEAKERS} and ${this.DEFAULT_SMART_MOSAIC_SPEAKERS}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const currentCount = this._maxRemoteSpeakers();
|
||||
if (currentCount === count) {
|
||||
this.log.d(`Max remote speakers already set to: ${count}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.log.d(`Max remote speakers updated from ${currentCount} to ${count}`);
|
||||
this._maxRemoteSpeakers.set(count);
|
||||
|
||||
// Trigger layout update if in Smart Mosaic mode
|
||||
if (this.isSmartMosaicEnabled()) {
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current layout mode.
|
||||
* @deprecated Use layoutMode signal directly instead
|
||||
* @returns {MeetLayoutMode} The current layout mode
|
||||
*/
|
||||
getLayoutMode(): MeetLayoutMode {
|
||||
return this.layoutMode;
|
||||
return this._layoutMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current max remote speakers count.
|
||||
* @returns {number} The current max remote speakers count
|
||||
*/
|
||||
getMaxRemoteSpeakers(): number {
|
||||
return this._maxRemoteSpeakers();
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,16 +17,35 @@ export class MeetStorageService extends StorageService {
|
||||
*
|
||||
* @param layoutMode - The layout mode to be set.
|
||||
*/
|
||||
setLayoutMode(layoutMode: MeetLayoutMode) {
|
||||
setLayoutMode(layoutMode: MeetLayoutMode): void {
|
||||
this.set(MeetStorageKeys.LAYOUT_MODE, layoutMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current layout mode from storage.
|
||||
*
|
||||
* @returns {string} The layout mode stored in the storage, or an empty string if not found.
|
||||
* @returns {MeetLayoutMode | null} The layout mode stored in the storage, or null if not found.
|
||||
*/
|
||||
getLayoutMode(): MeetLayoutMode | null {
|
||||
return this.get(MeetStorageKeys.LAYOUT_MODE) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of remote speakers to display in Smart Mosaic mode.
|
||||
*
|
||||
* @param count - The maximum number of remote speakers (1-20).
|
||||
*/
|
||||
setMaxRemoteSpeakers(count: number): void {
|
||||
this.set(MeetStorageKeys.MAX_REMOTE_SPEAKERS, count.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the maximum number of remote speakers from storage.
|
||||
*
|
||||
* @returns {number | null} The max remote speakers count, or null if not found.
|
||||
*/
|
||||
getMaxRemoteSpeakers(): number | null {
|
||||
const value = this.get(MeetStorageKeys.MAX_REMOTE_SPEAKERS);
|
||||
return value ? parseInt(value, 10) : null;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user