frontend: implement layout selector feature with conditional rendering in settings and toolbar
This commit is contained in:
parent
c3ca84ad66
commit
bd021c9576
@ -40,6 +40,11 @@ export class MeetingLayoutComponent {
|
||||
return this.meetingContextService.canModerateRoom() && remoteParticipants.length === 0;
|
||||
});
|
||||
|
||||
/**
|
||||
* Whether the layout selector feature is enabled
|
||||
*/
|
||||
protected readonly showLayoutSelector = this.meetingContextService.showLayoutSelector;
|
||||
|
||||
/**
|
||||
* Tracks the order of active speakers (most recent last)
|
||||
*/
|
||||
@ -48,9 +53,16 @@ export class MeetingLayoutComponent {
|
||||
/**
|
||||
* Computed signal that provides the filtered list of participants to display.
|
||||
* Automatically reacts to changes in layout service configuration.
|
||||
* When showLayoutSelector is false, returns all remote participants (default behavior).
|
||||
*/
|
||||
readonly filteredRemoteParticipants = computed(() => {
|
||||
const remoteParticipants = this.meetingContextService.remoteParticipants();
|
||||
|
||||
// If layout selector is disabled, use default behavior (show all participants)
|
||||
if (!this.showLayoutSelector()) {
|
||||
return remoteParticipants;
|
||||
}
|
||||
|
||||
const isLastSpeakersMode = this.layoutService.isSmartMosaicEnabled();
|
||||
|
||||
if (!isLastSpeakersMode) {
|
||||
@ -91,13 +103,16 @@ export class MeetingLayoutComponent {
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
if (this.meetingContextService.lkRoom()) {
|
||||
// Only setup active speakers if layout selector is enabled
|
||||
if (this.showLayoutSelector() && this.meetingContextService.lkRoom()) {
|
||||
this.setupActiveSpeakersListener();
|
||||
}
|
||||
});
|
||||
|
||||
// Effect to handle active speakers cleanup when participants leave
|
||||
effect(() => {
|
||||
// Skip if layout selector is disabled
|
||||
if (!this.showLayoutSelector()) return;
|
||||
if (!this.layoutService.isSmartMosaicEnabled()) return;
|
||||
|
||||
const remoteParticipants = this.meetingContextService.remoteParticipants();
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
<!-- Grid Layout Configuration Section -->
|
||||
<div class="layout-section">
|
||||
<div class="section-header">
|
||||
<mat-icon class="section-icon material-symbols-outlined">browse</mat-icon>
|
||||
<h4 class="section-title">Layout settings</h4>
|
||||
</div>
|
||||
@if (showLayoutSelector()) {
|
||||
<div class="layout-section">
|
||||
<div class="section-header">
|
||||
<mat-icon class="section-icon material-symbols-outlined">browse</mat-icon>
|
||||
<h4 class="section-title">Layout settings</h4>
|
||||
</div>
|
||||
|
||||
<!-- Layout Mode Selection -->
|
||||
<div class="layout-mode-container">
|
||||
@ -55,4 +56,5 @@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MeetLayoutMode } from '../../../models/layout.model';
|
||||
import { MeetLayoutService } from '../../../services/layout.service';
|
||||
import { MeetingContextService } from '../../../services/meeting/meeting-context.service';
|
||||
|
||||
/**
|
||||
* Component for additional settings in the Settings Panel.
|
||||
@ -30,12 +31,18 @@ import { MeetLayoutService } from '../../../services/layout.service';
|
||||
})
|
||||
export class MeetingSettingsPanelComponent {
|
||||
private readonly layoutService = inject(MeetLayoutService);
|
||||
protected readonly meetingContextService = inject(MeetingContextService);
|
||||
|
||||
/**
|
||||
* Expose LayoutMode enum to template
|
||||
*/
|
||||
readonly LayoutMode = MeetLayoutMode;
|
||||
|
||||
/**
|
||||
* Whether the layout selector feature is enabled
|
||||
*/
|
||||
protected readonly showLayoutSelector = this.meetingContextService.showLayoutSelector;
|
||||
|
||||
/**
|
||||
* Current layout mode
|
||||
*/
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
<!-- Grid Layout Settings Button -->
|
||||
<button
|
||||
mat-menu-item
|
||||
id="grid-layout-settings-btn"
|
||||
(click)="onOpenSettings()"
|
||||
[matTooltip]="isMobileView() ? '' : 'Configure grid layout'"
|
||||
>
|
||||
<mat-icon class="material-symbols-outlined">browser</mat-icon>
|
||||
<span>Adjust Layout</span>
|
||||
</button>
|
||||
@if (showLayoutSelector()) {
|
||||
<button
|
||||
mat-menu-item
|
||||
id="grid-layout-settings-btn"
|
||||
(click)="onOpenSettings()"
|
||||
[matTooltip]="isMobileView() ? '' : 'Configure grid layout'"
|
||||
>
|
||||
<mat-icon class="material-symbols-outlined">browser</mat-icon>
|
||||
<span>Adjust Layout</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { PanelService, ViewportService, PanelType } from 'openvidu-components-angular';
|
||||
import { MeetingContextService } from '../../../services/meeting/meeting-context.service';
|
||||
|
||||
/**
|
||||
* Component for additional menu items in the toolbar's "More Options" menu.
|
||||
@ -36,6 +37,11 @@ export class MeetingToolbarMoreOptionsButtonsComponent {
|
||||
*/
|
||||
private panelService = inject(PanelService);
|
||||
|
||||
/**
|
||||
* Meeting context service for feature flags
|
||||
*/
|
||||
private meetingContextService = inject(MeetingContextService);
|
||||
|
||||
/**
|
||||
* Computed properties for responsive button behavior
|
||||
* These follow the same pattern as toolbar-media-buttons component
|
||||
@ -44,6 +50,11 @@ export class MeetingToolbarMoreOptionsButtonsComponent {
|
||||
readonly isTabletView = computed(() => this.viewportService.isTablet());
|
||||
readonly isDesktopView = computed(() => this.viewportService.isDesktop());
|
||||
|
||||
/**
|
||||
* Whether the layout selector feature is enabled
|
||||
*/
|
||||
readonly showLayoutSelector = computed(() => this.meetingContextService.showLayoutSelector());
|
||||
|
||||
/**
|
||||
* Opens the settings panel to allow users to change grid layout
|
||||
*/
|
||||
|
||||
@ -28,6 +28,7 @@ export interface ApplicationFeatures {
|
||||
showSettings: boolean;
|
||||
showFullscreen: boolean;
|
||||
showThemeSelector: boolean;
|
||||
showLayoutSelector: boolean;
|
||||
|
||||
// Permissions
|
||||
canModerateRoom: boolean;
|
||||
@ -56,6 +57,7 @@ const DEFAULT_FEATURES: ApplicationFeatures = {
|
||||
showSettings: true,
|
||||
showFullscreen: true,
|
||||
showThemeSelector: true,
|
||||
showLayoutSelector: false,
|
||||
|
||||
canModerateRoom: false,
|
||||
canRecordRoom: false,
|
||||
|
||||
@ -98,13 +98,16 @@ export class MeetingContextService {
|
||||
|
||||
/**
|
||||
* Computed signal for whether the current user can moderate the room
|
||||
* Derived from FeatureConfigurationService
|
||||
*/
|
||||
readonly canModerateRoom = computed(() => this.featureConfigService.features().canModerateRoom);
|
||||
|
||||
/**
|
||||
* Computed signal for whether the layout selector feature is enabled
|
||||
*/
|
||||
readonly showLayoutSelector = computed(() => this.featureConfigService.features().showLayoutSelector);
|
||||
|
||||
/**
|
||||
* Computed signal for whether the device is mobile
|
||||
* Derived from ViewportService for responsive UI
|
||||
*/
|
||||
readonly isMobile = computed(() => this.viewportService.isMobile());
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user