diff --git a/src/lib/ae_events/ae_events__event_file.ts b/src/lib/ae_events/ae_events__event_file.ts index 1650c694..28cc6919 100644 --- a/src/lib/ae_events/ae_events__event_file.ts +++ b/src/lib/ae_events/ae_events__event_file.ts @@ -539,7 +539,6 @@ export const properties_to_save = [ 'filename', 'extension', 'open_in_os', - 'cfg_json', 'lu_file_purpose_id', 'lu_event_file_purpose_name', 'file_purpose', 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 00be4aa4..39a4278f 100644 --- a/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte +++ b/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte @@ -93,6 +93,14 @@ let open_file_status: null | string = $state(null); let open_file_status_message: null | string = $state(null); 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. */ +const current_display_override = $derived.by(() => { + const overrides = (($events_loc.launcher as Record)?.file_display_overrides ?? {}) as Record; + return (overrides[event_file_id] ?? null) as 'extend' | 'mirror' | 'none' | null; +}); + /** State for the native test mode debug popup */ let test_mode_popup_open: boolean = $state(false); let test_mode_popup_data: Record | null = $state(null); @@ -135,7 +143,11 @@ function get_launch_profile( native_device?.launch_profiles ?? null; const local_profiles = ($events_loc as any).launcher?.launch_profiles ?? null; - const display_override = file_obj?.cfg_json?.display_override ?? null; + // Display override is stored per-device in $events_loc — not in the backend (event_file has no JSON column). + // This is intentional: display mode is a room/device preference, not a global file property. + const launcher_kv = $events_loc.launcher 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; // 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. @@ -469,12 +481,11 @@ async function handle_open_file() { open_file_status_message = 'Downloading (Onsite Mode)...'; open_file_error_detail = null; + // Append 'win' to the filename for extensions that have Windows file associations + // (pptx→pptxwin, ppt→pptwin, odp→odpwin, pdf→pdfwin). Must match WIN_EXTENSION_MAP. + const WIN_ONSITE_EXTS = ['pptx', 'ppt', 'odp', 'pdf']; let filename = event_file_obj.filename; - if ( - (event_file_obj.extension === 'ppt' || - event_file_obj.extension === 'pptx') && - event_file_obj.open_in_os === 'win' - ) { + if (event_file_obj.open_in_os === 'win' && WIN_ONSITE_EXTS.includes(event_file_obj.extension)) { filename = event_file_obj.filename + 'win'; } @@ -620,7 +631,7 @@ function prevent_default(fn: (event: T) => void) { click={handle_open_file}> {#snippet label()} {@const file_id = event_file_obj.hosted_file_id} - + {#await ae_promises[event_file_id]} (fn: (event: T) => void) { {/if} {:then result} + {#if is_url} - - url - {#if !is_online}{/if} + + url + {#if !is_online}{/if} {:else} {@const FileIcon = ae_util.file_extension_icon_lucide( event_file_obj.extension )} - + {event_file_obj.extension} {#if result === null || result === false} - Failed! + class="inline" />Failed! {/if} {/if} + {:catch error} - Error! @@ -687,79 +700,71 @@ function prevent_default(fn: (event: T) => void) { - - {#if $ae_loc.trusted_access} - - + + {#if $ae_loc.edit_mode} + +