feat(launcher): move Reset Apps to always-visible controls bar
Adds a presenter-accessible "Reset Apps" button to menu_launcher_controls that is always visible (no edit mode required). Kills presentation apps (PowerPoint, Keynote, Acrobat, VLC, soffice) — critical recovery path for presenters stuck on stage with a frozen app. Also: warning colors on All Files / All Sessions when showing non-default (hidden) content, and state-aware tooltips on the Display Mode toggle that describe current state and what pressing will do. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,15 +10,20 @@
|
||||
*
|
||||
* SECTIONS:
|
||||
* 1. Visibility toggles (edit mode only) — show/hide draft files and hidden sessions
|
||||
* 2. Accessibility controls (always visible) — font size cycler and light/dark toggle
|
||||
* 2. Accessibility controls (always visible) — Reset Apps, font size cycler, light/dark toggle
|
||||
*
|
||||
* WHY ALWAYS-VISIBLE ACCESSIBILITY CONTROLS:
|
||||
* Projector-connected screens, tablets, and phones at conference venues vary wildly
|
||||
* in lighting. Operators and presenters need quick one-tap access to font size and
|
||||
* theme mode without hunting through the system menu or requiring admin access.
|
||||
*
|
||||
* WHY RESET APPS IS ALWAYS VISIBLE:
|
||||
* If a presentation app (PowerPoint, Keynote, etc.) hangs or stalls on stage, the
|
||||
* presenter needs a one-tap way to force-close it and recover — without entering edit
|
||||
* mode or navigating the config menu. This button is intentionally prominent.
|
||||
*/
|
||||
|
||||
import { Moon, Sun, Eye, EyeOff, Columns2, Copy } from '@lucide/svelte';
|
||||
import { Moon, Sun, Eye, EyeOff, Columns2, Copy, XCircle } from '@lucide/svelte';
|
||||
|
||||
import { ae_loc } from '$lib/stores/ae_stores';
|
||||
import { events_loc } from '$lib/stores/ae_events_stores';
|
||||
@@ -52,12 +57,35 @@ async function toggle_display_mode() {
|
||||
($events_loc.launcher as any).display_mode = next;
|
||||
}
|
||||
}
|
||||
|
||||
// Process names closed when presenter hits "Reset Apps". Covers the standard
|
||||
// conference app set. Override per device via event_device.other_json.launcher.kill_process_li.
|
||||
const DEFAULT_KILL_LIST = [
|
||||
'Microsoft PowerPoint',
|
||||
'Keynote',
|
||||
'Adobe Acrobat Reader DC',
|
||||
'VLC',
|
||||
'soffice'
|
||||
];
|
||||
|
||||
let reset_apps_status = $state('');
|
||||
|
||||
async function handle_reset_apps() {
|
||||
const native_device = ($ae_loc as any).native_device ?? null;
|
||||
const process_name_li: string[] =
|
||||
native_device?.other_json?.launcher?.kill_process_li ?? DEFAULT_KILL_LIST;
|
||||
reset_apps_status = 'Resetting...';
|
||||
await native.kill_processes({ process_name_li });
|
||||
reset_apps_status = 'Done';
|
||||
setTimeout(() => (reset_apps_status = ''), 3000);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex w-full max-w-full flex-col items-center justify-center gap-1">
|
||||
<!-- ── Edit mode controls ── -->
|
||||
{#if $ae_loc.edit_mode}
|
||||
<!-- All Files / All Sessions toggles -->
|
||||
<!-- All Files / All Sessions toggles.
|
||||
Warning color when showing hidden content — signals non-default state to operators. -->
|
||||
<div class="flex w-full max-w-full flex-row items-center justify-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
@@ -70,8 +98,16 @@ async function toggle_display_mode() {
|
||||
$events_loc.launcher.show_content__internal_files = true;
|
||||
}
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-tertiary hover:preset-filled-tertiary-500 w-1/2 max-w-1/2 text-xs transition-all"
|
||||
title="Toggle visibility of hidden and draft files.">
|
||||
class="btn btn-sm w-1/2 max-w-1/2 text-xs transition-all"
|
||||
class:preset-tonal-warning={$events_loc.launcher.show_content__hidden_files}
|
||||
class:hover:preset-filled-warning-500={$events_loc.launcher
|
||||
.show_content__hidden_files}
|
||||
class:preset-tonal-tertiary={!$events_loc.launcher.show_content__hidden_files}
|
||||
class:hover:preset-filled-tertiary-500={!$events_loc.launcher
|
||||
.show_content__hidden_files}
|
||||
title={$events_loc.launcher.show_content__hidden_files
|
||||
? 'Showing all files including hidden and draft. Tap to hide them again.'
|
||||
: 'Showing only public files. Tap to show all files including hidden and draft.'}>
|
||||
{#if $events_loc.launcher.show_content__hidden_files}
|
||||
<EyeOff size="0.85em" class="m-1" />
|
||||
Hide Files
|
||||
@@ -87,8 +123,16 @@ async function toggle_display_mode() {
|
||||
$events_loc.launcher.show_content__hidden_sessions =
|
||||
!$events_loc.launcher.show_content__hidden_sessions;
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-tertiary hover:preset-filled-tertiary-500 w-1/2 max-w-1/2 text-xs transition-all"
|
||||
title="Toggle visibility of hidden and cancelled sessions.">
|
||||
class="btn btn-sm w-1/2 max-w-1/2 text-xs transition-all"
|
||||
class:preset-tonal-warning={$events_loc.launcher.show_content__hidden_sessions}
|
||||
class:hover:preset-filled-warning-500={$events_loc.launcher
|
||||
.show_content__hidden_sessions}
|
||||
class:preset-tonal-tertiary={!$events_loc.launcher.show_content__hidden_sessions}
|
||||
class:hover:preset-filled-tertiary-500={!$events_loc.launcher
|
||||
.show_content__hidden_sessions}
|
||||
title={$events_loc.launcher.show_content__hidden_sessions
|
||||
? 'Showing all sessions including cancelled and hidden. Tap to hide them again.'
|
||||
: 'Showing only active sessions. Tap to show all sessions including hidden and cancelled.'}>
|
||||
{#if $events_loc.launcher.show_content__hidden_sessions}
|
||||
<EyeOff size="0.85em" class="m-1" />
|
||||
Hide Sessions
|
||||
@@ -99,7 +143,9 @@ async function toggle_display_mode() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Display mode: single toggle button — tertiary when extending (normal), warning when mirroring (special) -->
|
||||
<!-- Display mode toggle — warning color when mirroring (non-default operator setting).
|
||||
Tooltip describes the CURRENT state and what pressing will do, so operators know
|
||||
which way they are switching before they tap. -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={toggle_display_mode}
|
||||
@@ -108,7 +154,9 @@ async function toggle_display_mode() {
|
||||
class:hover:preset-filled-tertiary-500={quick_display_mode === 'extend'}
|
||||
class:preset-tonal-warning={quick_display_mode === 'mirror'}
|
||||
class:hover:preset-filled-warning-500={quick_display_mode === 'mirror'}
|
||||
title="Toggle display layout between Extend (separate screens) and Mirror (same content on both).">
|
||||
title={quick_display_mode === 'extend'
|
||||
? 'Screens are extended: laptop can show notes while projector shows slides. Tap to mirror — make both screens show the same content.'
|
||||
: 'Screens are mirrored: both screens show the same content. Tap to extend — allow the laptop and projector to show different content.'}>
|
||||
{#if quick_display_mode === 'extend'}
|
||||
<Columns2 size="0.85em" class="m-1" />
|
||||
Display: Extend
|
||||
@@ -119,7 +167,19 @@ async function toggle_display_mode() {
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<!-- ── Accessibility controls — always visible ── -->
|
||||
<!-- ── Always-visible controls ── -->
|
||||
|
||||
<!-- Reset Apps: force-closes hung presentation apps without requiring edit mode.
|
||||
Essential recovery tool for presenters stuck on stage with a frozen app. -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={handle_reset_apps}
|
||||
class="btn btn-sm preset-tonal-error hover:preset-filled-error-500 w-full text-xs transition-all"
|
||||
title="Close all presentation apps (PowerPoint, Keynote, Adobe Acrobat, VLC). Use this if a presentation is frozen or stuck.">
|
||||
<XCircle size="0.85em" class="m-1 shrink-0" />
|
||||
{reset_apps_status || 'Reset Apps'}
|
||||
</button>
|
||||
|
||||
<div class="flex w-full max-w-full flex-row items-center justify-center gap-1">
|
||||
<!-- Font size cycler: default → larger → smaller → default -->
|
||||
<button
|
||||
@@ -135,7 +195,8 @@ async function toggle_display_mode() {
|
||||
}
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-tertiary hover:preset-filled-tertiary-500 group w-1/2 max-w-1/2 text-xs transition-all"
|
||||
title="Cycle font size (default → larger → smaller). Current: {$ae_loc.font_size_mode ?? 'default'}">
|
||||
title="Cycle font size (default → larger → smaller). Current: {$ae_loc.font_size_mode ??
|
||||
'default'}">
|
||||
{#if !$ae_loc.font_size_mode || $ae_loc.font_size_mode === 'default'}
|
||||
<span class="m-1 font-mono text-sm leading-none font-bold">A</span>
|
||||
<span class="hidden text-xs group-hover:inline-block">Font: Normal</span>
|
||||
|
||||
Reference in New Issue
Block a user