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 209c423a..ebd5451a 100644 --- a/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte +++ b/src/routes/events/[event_id]/(launcher)/launcher_file_cont.svelte @@ -277,6 +277,17 @@ async function handle_open_file() { open_file_clicked = true; open_file_status = 'checking_cache'; open_file_status_message = 'Checking local cache...'; + open_file_error_detail = null; // Fix 1: clear stale error from any previous attempt + + // Fix 2: safety valve — if a native call hangs and no path resets the button, + // force-release it after 60s. All normal paths reset within ~8s so this is last resort. + setTimeout(() => { + if (open_file_clicked) { + open_file_clicked = false; + open_file_status = 'error'; + open_file_status_message = 'Timed out — please try again'; + } + }, 60_000); const exists = await native.check_hash_file_cache({ cache_root, @@ -364,6 +375,14 @@ async function handle_open_file() { } } + // Fix 3: update the status message as soon as the open call returns so "Opening..." doesn't + // appear stuck for the entire post_script sleep. OS has the request; we're just waiting now. + if (open_ok) { + open_file_status_message = profile.post_script + ? `${profile.app} opened — running setup...` + : `${profile.app} opened`; + } + // --- Step 5: Wait for app to load before running post-script --- // Only delay if there is actually a post_script to run — no point waiting for nothing. if (open_ok && profile.post_script) { @@ -426,6 +445,7 @@ async function handle_open_file() { open_file_clicked = true; open_file_status = 'downloading_onsite'; open_file_status_message = 'Downloading (Onsite Mode)...'; + open_file_error_detail = null; let filename = event_file_obj.filename; if ( @@ -457,6 +477,7 @@ async function handle_open_file() { open_file_clicked = true; open_file_status = 'downloading_default'; open_file_status_message = 'Downloading...'; + open_file_error_detail = null; const dl_promise = api.get_object({ api_cfg: $ae_api,