diff --git a/src/lib/stores/ae_events_stores__launcher_defaults.ts b/src/lib/stores/ae_events_stores__launcher_defaults.ts index d93783d9..d983257f 100644 --- a/src/lib/stores/ae_events_stores__launcher_defaults.ts +++ b/src/lib/stores/ae_events_stores__launcher_defaults.ts @@ -7,6 +7,8 @@ * launcher_sess_defaults → events_sess.launcher (in-memory, resets on page load) */ +import type { LaunchProfile } from '$lib/ae_events/ae_launcher__default_launch_profiles'; + /** 3-way section collapse state used throughout the Launcher UI. */ export type SectionState = 'collapsed' | 'auto' | 'pinned'; @@ -91,6 +93,18 @@ export interface LauncherLocState { * device/OS without deploying to the Mac laptop. */ native_test_mode: boolean; + /** + * Per-file display mode overrides, keyed by event_file_id. + * Stored locally (per-device) because event_file has no cfg_json column yet. + * TODO: migrate to event_file.cfg_json once the backend column is added. + */ + file_display_overrides: Record; + /** + * Local per-device launch profile overrides, keyed by profile/extension name. + * Overrides DEFAULT_LAUNCH_PROFILES for this device only. + * Priority: device API config > this local override > built-in defaults. + */ + launch_profiles: Record> | null; } export interface LauncherSessState { @@ -219,7 +233,9 @@ export const launcher_loc_defaults: LauncherLocState = { controller_client_id: null, native_test_mode: false, wallpaper_applied_url: null, - wallpaper_applied_url_external: null + wallpaper_applied_url_external: null, + file_display_overrides: {}, + launch_profiles: null // controller_cmd: null, // controller_trigger_send: null, }; diff --git a/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte b/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte index 0a3f7741..464bbc02 100644 --- a/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte +++ b/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte @@ -95,10 +95,9 @@ let open_file_error_detail: string | null = $state(null); let open_in_os_loading: boolean = $state(false); -/** Reactive display override for this file — stored in $events_loc (localStorage) not in the backend. */ +/** Reactive display override for this file — stored locally (per-device) because event_file has no cfg_json column yet. */ const current_display_override = $derived.by(() => { - const overrides = ((launcher_loc.current as Record)?.file_display_overrides ?? {}) as Record; - return (overrides[event_file_id] ?? null) as 'extend' | 'mirror' | 'none' | null; + return (launcher_loc.current.file_display_overrides[event_file_id] ?? null) as 'extend' | 'mirror' | 'none' | null; }); /** State for the native test mode debug popup */ @@ -143,11 +142,9 @@ function get_launch_profile( native_device?.launch_profiles ?? null; const local_profiles = launcher_loc.current?.launch_profiles ?? null; - // Display override is stored per-device in $events_loc — not in the backend (event_file has no JSON column). + // Display override is stored per-device in launcher_loc — not in the backend (event_file has no cfg_json column yet). // This is intentional: display mode is a room/device preference, not a global file property. - const launcher_kv = launcher_loc.current as Record; - const file_display_overrides = (launcher_kv?.file_display_overrides ?? {}) as Record; - const display_override = (file_display_overrides[event_file_id] ?? null) as 'extend' | 'mirror' | 'none' | null; + const display_override = (launcher_loc.current.file_display_overrides[event_file_id] ?? null) as 'extend' | 'mirror' | 'none' | null; // open_in_os = 'win' routes to the Windows-variant profile for apps that have one. // These profiles target Windows PowerPoint / LibreOffice / Acrobat running via Parallels or CrossOver. @@ -749,14 +746,13 @@ function prevent_default(fn: (event: T) => void) { onclick={() => { const cur = current_display_override; const next: 'extend' | 'mirror' | null = !cur ? 'extend' : cur === 'extend' ? 'mirror' : null; - const launcher = launcher_loc.current as Record; - const new_overrides = { ...((launcher?.file_display_overrides ?? {}) as Record) }; + const new_overrides = { ...launcher_loc.current.file_display_overrides }; if (next === null) { delete new_overrides[event_file_id]; } else { new_overrides[event_file_id] = next; } - launcher.file_display_overrides = new_overrides; + launcher_loc.current.file_display_overrides = new_overrides; }} class="btn btn-sm transition-all" class:preset-tonal-primary={current_display_override === 'extend'}