From bfb1736b353af80151679f8d0bfc3629962bf018 Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Wed, 1 Oct 2025 12:08:25 +0200 Subject: [PATCH] frontend/backend: add accent color support in theme configuration and update related components --- .../appearance-config.controller.ts | 1 + .../room-validator.middleware.ts | 1 + .../api/global-config/appearance.test.ts | 1 + .../pages/console/config/config.component.scss | 4 ++-- .../pages/console/config/config.component.ts | 18 ++++++++++++++++-- .../src/lib/pages/meeting/meeting.component.ts | 1 + typings/src/room-config.ts | 1 + 7 files changed, 23 insertions(+), 4 deletions(-) diff --git a/backend/src/controllers/global-config/appearance-config.controller.ts b/backend/src/controllers/global-config/appearance-config.controller.ts index 568d8e2..66dc3ac 100644 --- a/backend/src/controllers/global-config/appearance-config.controller.ts +++ b/backend/src/controllers/global-config/appearance-config.controller.ts @@ -22,6 +22,7 @@ export const updateRoomsAppearanceConfig = async (req: Request, res: Response) = newTheme.backgroundColor = newTheme.backgroundColor || existingTheme.backgroundColor; newTheme.primaryColor = newTheme.primaryColor || existingTheme.primaryColor; newTheme.secondaryColor = newTheme.secondaryColor || existingTheme.secondaryColor; + newTheme.accentColor = newTheme.accentColor || existingTheme.accentColor; newTheme.surfaceColor = newTheme.surfaceColor || existingTheme.surfaceColor; } diff --git a/backend/src/middlewares/request-validators/room-validator.middleware.ts b/backend/src/middlewares/request-validators/room-validator.middleware.ts index 6cca94a..35f2c05 100644 --- a/backend/src/middlewares/request-validators/room-validator.middleware.ts +++ b/backend/src/middlewares/request-validators/room-validator.middleware.ts @@ -105,6 +105,7 @@ const RoomThemeSchema = z.object({ backgroundColor: hexColorSchema.optional(), primaryColor: hexColorSchema.optional(), secondaryColor: hexColorSchema.optional(), + accentColor: hexColorSchema.optional(), surfaceColor: hexColorSchema.optional() }); diff --git a/backend/tests/integration/api/global-config/appearance.test.ts b/backend/tests/integration/api/global-config/appearance.test.ts index f0149db..da20e4e 100644 --- a/backend/tests/integration/api/global-config/appearance.test.ts +++ b/backend/tests/integration/api/global-config/appearance.test.ts @@ -31,6 +31,7 @@ describe('Rooms Appearance Config API Tests', () => { backgroundColor: '#121212', primaryColor: '#bb86fc', secondaryColor: '#03dac6', + accentColor: '#09554dff', surfaceColor: '#1f1f1f' } ] diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss index 94497b8..61b67ea 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss @@ -49,13 +49,13 @@ // Color picker grid layout - responsive and clean .color-picker-grid { display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: repeat(5, 1fr); gap: var(--ov-meet-spacing-xl); margin: var(--ov-meet-spacing-lg) 0; // Tablet and larger - maintain 4 columns @include ov-tablet-up { - gap: var(--ov-meet-spacing-xxl); + gap: var(--ov-meet-spacing-xs); } // Small tablets - 2 columns diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts index 53d2e4d..02f967e 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts @@ -14,12 +14,13 @@ import { GlobalConfigService, NotificationService } from '@lib/services'; import { MeetAppearanceConfig, MeetRoomTheme, MeetRoomThemeMode } from '@lib/typings/ce'; import { OPENVIDU_COMPONENTS_DARK_THEME, OPENVIDU_COMPONENTS_LIGHT_THEME } from 'openvidu-components-angular'; -type ColorField = 'backgroundColor' | 'primaryColor' | 'secondaryColor' | 'surfaceColor'; +type ColorField = 'backgroundColor' | 'primaryColor' | 'secondaryColor' | 'accentColor' | 'surfaceColor'; interface ThemeColors { backgroundColor: string; primaryColor: string; secondaryColor: string; + accentColor: string; surfaceColor: string; } @@ -56,6 +57,7 @@ export class ConfigComponent implements OnInit { backgroundColor: new FormControl('', { nonNullable: true }), primaryColor: new FormControl('', { nonNullable: true }), secondaryColor: new FormControl('', { nonNullable: true }), + accentColor: new FormControl('', { nonNullable: true }), surfaceColor: new FormControl('', { nonNullable: true }) }); @@ -75,8 +77,13 @@ export class ConfigComponent implements OnInit { }, { key: 'secondaryColor', + label: 'Secondary buttons', + description: 'Colors for secondary elements such as logo and icons backgrounds, borders and other subtle details' + }, + { + key: 'accentColor', label: 'Highlights & accents', - description: 'Colors for active states, borders, and participant names' + description: 'Colors for active states, highlights and interactive elements' }, { key: 'surfaceColor', @@ -93,12 +100,14 @@ export class ConfigComponent implements OnInit { backgroundColor: OPENVIDU_COMPONENTS_LIGHT_THEME['--ov-background-color'] as string, primaryColor: OPENVIDU_COMPONENTS_LIGHT_THEME['--ov-primary-action-color'] as string, secondaryColor: OPENVIDU_COMPONENTS_LIGHT_THEME['--ov-secondary-action-color'] as string, + accentColor: OPENVIDU_COMPONENTS_LIGHT_THEME['--ov-accent-action-color'] as string, surfaceColor: OPENVIDU_COMPONENTS_LIGHT_THEME['--ov-surface-color'] as string }, [MeetRoomThemeMode.DARK]: { backgroundColor: OPENVIDU_COMPONENTS_DARK_THEME['--ov-background-color'] as string, primaryColor: OPENVIDU_COMPONENTS_DARK_THEME['--ov-primary-action-color'] as string, secondaryColor: OPENVIDU_COMPONENTS_DARK_THEME['--ov-secondary-action-color'] as string, + accentColor: OPENVIDU_COMPONENTS_DARK_THEME['--ov-accent-action-color'] as string, surfaceColor: OPENVIDU_COMPONENTS_DARK_THEME['--ov-surface-color'] as string } }; @@ -191,6 +200,7 @@ export class ConfigComponent implements OnInit { backgroundColor: themeConfig.backgroundColor || '', primaryColor: themeConfig.primaryColor || '', secondaryColor: themeConfig.secondaryColor || '', + accentColor: themeConfig.accentColor || '', surfaceColor: themeConfig.surfaceColor || '' }); } else { @@ -201,6 +211,7 @@ export class ConfigComponent implements OnInit { backgroundColor: '', primaryColor: '', secondaryColor: '', + accentColor: '', surfaceColor: '' }); } @@ -214,6 +225,7 @@ export class ConfigComponent implements OnInit { backgroundColor: '', primaryColor: '', secondaryColor: '', + accentColor: '', surfaceColor: '' }); this.storeInitialValues(); @@ -305,6 +317,7 @@ export class ConfigComponent implements OnInit { backgroundColor: this.initialFormValue.backgroundColor, primaryColor: this.initialFormValue.primaryColor, secondaryColor: this.initialFormValue.secondaryColor, + accentColor: this.initialFormValue.accentColor, surfaceColor: this.initialFormValue.surfaceColor }); this.hasColorChanges.set(false); @@ -344,6 +357,7 @@ export class ConfigComponent implements OnInit { backgroundColor: formData.backgroundColor?.trim() || defaults.backgroundColor, primaryColor: formData.primaryColor?.trim() || defaults.primaryColor, secondaryColor: formData.secondaryColor?.trim() || defaults.secondaryColor, + accentColor: formData.accentColor?.trim() || defaults.accentColor, surfaceColor: formData.surfaceColor?.trim() || defaults.surfaceColor }; } diff --git a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts index dad1acd..a76e1ca 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts @@ -143,6 +143,7 @@ export class MeetingComponent implements OnInit { this.ovThemeService.updateThemeVariables({ '--ov-primary-action-color': theme?.primaryColor, '--ov-secondary-action-color': theme?.secondaryColor, + '--ov-accent-action-color': theme?.accentColor, '--ov-background-color': theme?.backgroundColor, '--ov-surface-color': theme?.surfaceColor }); diff --git a/typings/src/room-config.ts b/typings/src/room-config.ts index feca0d6..4b04523 100644 --- a/typings/src/room-config.ts +++ b/typings/src/room-config.ts @@ -41,6 +41,7 @@ export interface MeetRoomTheme { backgroundColor?: string; primaryColor?: string; secondaryColor?: string; + accentColor?: string; surfaceColor?: string; }