fix(launcher): poster session display — metadata, image modal, file paths

1. launcher_presentation_view: accept session_type prop from parent
   instead of relying on event_session_type_code on file objects (which
   is not reliably populated in Dexie). Use session_type to correctly
   set hide_meta, session_type, and open_method on the file container.

2. launcher_session_view: pass session_type={type_code} to
   Launcher_presentation_view; restore Launcher_presenter_view_posters
   in the presenter list for poster mode (hide_name=true). Some events
   store poster files at the PRESENTER level (for_id=event_presenter_id)
   — particularly group/company presenters — so both paths must render.

3. launcher/+layout.svelte: fix poster modal image 403. The img src was
   using the event_file download endpoint which requires auth headers a
   plain img tag cannot send. Switched to the hosted_file endpoint with
   key=account_id, which is browser-compatible. Also guarded on
   modal__event_file_obj.hosted_file_id for safer access.

4. launcher_cfg_screen_saver: rename section title to 'Poster Screen Saver'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-04 19:15:32 -05:00
parent 795c12c1db
commit b2fa6228a6
4 changed files with 23 additions and 18 deletions

View File

@@ -10,7 +10,7 @@
</script>
<Launcher_Cfg_Section
title="Digital Screen Saver"
title="Poster Screen Saver"
icon="fa-id-badge"
bind:state={$events_loc.launcher.section_state__screen_saver}
{on_expand}

View File

@@ -870,11 +870,16 @@
Close Remote Poster Display Only
</button>
{#if $events_sess.launcher.modal__open_event_file_id}
{#if $events_sess.launcher.modal__event_file_obj?.hosted_file_id}
<!-- WHY: Use hosted_file endpoint (not event_file) — the event_file download
endpoint requires auth headers that a plain <img> tag cannot send (→ 403).
The hosted_file endpoint accepts key=account_id as a query param and is
the proven browser-compatible path for direct file display. -->
<img
src="{$ae_api.base_url}/v3/action/event_file/{$events_sess.launcher
.modal__open_event_file_id}/download?filename={$events_slct
.event_file_obj.filename}&key={$ae_api.account_id}"
src="{$ae_api.base_url}/v3/action/hosted_file/{$events_sess.launcher
.modal__event_file_obj.hosted_file_id}/download?return_file=true&filename={encodeURIComponent(
$events_sess.launcher.modal__event_file_obj.filename ?? ''
)}&key={$ae_api.account_id}"
alt="Poster"
class="min-h-28 min-w-md max-h-full max-w-full"
/>

View File

@@ -1,9 +1,10 @@
<script lang="ts">
interface Props {
lq__event_presentation_obj: any;
session_type?: string;
}
let { lq__event_presentation_obj }: Props = $props();
let { lq__event_presentation_obj, session_type = '' }: Props = $props();
import { liveQuery } from 'dexie';
import { db_events } from '$lib/ae_events/db_events';
@@ -67,17 +68,13 @@
event_file_id={event_file_obj.event_file_id}
{event_file_obj}
hide_created_on={false}
hide_meta={event_file_obj?.event_session_type_code == 'poster'}
hide_meta={session_type == 'poster'}
bind:hide_draft={
$events_loc.launcher.hide_content__draft_files
}
show_bak_download={$ae_loc.trusted_access}
session_type={event_file_obj?.event_session_type_code ??
'oral'}
open_method={event_file_obj?.event_session_type_code ==
'poster'
? 'modal'
: null}
session_type={session_type || 'oral'}
open_method={session_type == 'poster' ? 'modal' : null}
modal_title={lq__event_presentation_obj?.name}
bind:modal__title={$events_sess.launcher.modal__title}
bind:modal__open_event_file_id={

View File

@@ -414,9 +414,17 @@
<!-- Presentation-level files -->
<Launcher_presentation_view
lq__event_presentation_obj={event_presentation_obj}
session_type={type_code}
/>
<!-- The presenter list -->
<!-- WHY: In poster mode, presenter names are already shown inline
in the presentation header above, so hide_name=true.
We still render Launcher_presenter_view_posters here because
some events store files at the PRESENTER level (for_id=event_presenter_id)
rather than the presentation level — particularly group/company presenters.
The component renders nothing if there are no presenter-level files,
so this has no visual cost for events that use presentation-level files. -->
{#if $lq__event_presenter_obj_li && $lq__event_presenter_obj_li.length}
<ul class="event_presentation_presenter_list">
@@ -442,15 +450,10 @@
lq__event_presenter_obj={event_presenter_obj}
/>
{/if}
<!-- {index} -->
</li>
{/if}
{/each}
</ul>
{:else}
<span class="event_launcher_no_presenters"
>No presenters to display</span
>
{/if}
</li>
{/each}