diff --git a/TODO.md b/TODO.md index 4664e50a..cbd44c07 100644 --- a/TODO.md +++ b/TODO.md @@ -26,12 +26,13 @@ This is a list of tasks to be completed before the next event/show/conference. - [x] **Shared Observables:** Refactored lists to accept `liveQuery` props for flicker-free SWR transitions. - [x] **Store Initialization:** Hardened persisted stores against `undefined` reactivity triggers. 2. **String-Only ID Standardization:** - - [ ] Audit and resort ID prioritization logic across all `.ts` and `.svelte` files. - - [ ] Preferred Order: `[obj_type]_id` || `id` || `[obj_type]_id_random` || `id_random`. - - [ ] Ensure `+layout.ts` cleans incoming raw data from the native bridge. + - [x] Audit and resort ID prioritization logic across all `.ts` and `.svelte` files. (Phase 1 Completed 2026-01-30) + - [x] Preferred Order: `[obj_type]_id` || `id` || `[obj_type]_id_random` || `id_random`. + - [x] Ensure `+layout.ts` cleans incoming raw data from the native bridge. 3. **Native Launcher Refinement (Phase 5):** - - [x] **Office Automation:** Implemented AppleScript handlers for PowerPoint/Keynote. - - [x] **Telemetry Dashboard:** Built visual CPU/RAM gauges in Launcher Config. + - [x] **Office Automation:** Implemented AppleScript handlers for PowerPoint/Keynote. (Completed 2026-01-30) + - [x] **Telemetry Dashboard:** Built visual CPU/RAM gauges in Launcher Config. (Completed 2026-01-30) + - [x] **System Management:** Added UI for Wallpaper, Recording, Display Layout, and Power Control. (Completed 2026-01-30) 3. **Codebase Consistency:** - [x] **Field Mapping:** Renamed `default_qry_string` to `default_qry_str` project-wide for V3 API compliance. @@ -89,3 +90,6 @@ This is a list of tasks to be completed before the next event/show/conference. - [x] Refinement: Built Telemetry Dashboard in Launcher Config. + + + diff --git a/src/lib/electron/electron_relay.ts b/src/lib/electron/electron_relay.ts index 7cce0a89..254481c4 100644 --- a/src/lib/electron/electron_relay.ts +++ b/src/lib/electron/electron_relay.ts @@ -183,6 +183,43 @@ export async function control_presentation({ return { success: false, error: `Unsupported app or action: ${app}/${action}` }; } +// 4. System Management (Phase 5+) + +export async function set_wallpaper({ path }: { path: string }) { + if (!native || !native.set_wallpaper) return { success: false, error: 'Native handler set_wallpaper not available' }; + return await native.set_wallpaper({ path }); +} + +export async function update_app(args: { source: 'url' | 'file', url?: string, path?: string }) { + if (!native || !native.update_app) return { success: false, error: 'Native handler update_app not available' }; + return await native.update_app(args); +} + +export async function window_control({ action, value }: { action: string, value?: any }) { + if (!native || !native.window_control) return { success: false, error: 'Native handler window_control not available' }; + return await native.window_control({ action, value }); +} + +export async function manage_recording({ action, options }: { action: 'start' | 'stop' | 'status', options?: any }) { + if (!native || !native.manage_recording) return { success: false, error: 'Native handler manage_recording not available' }; + return await native.manage_recording({ action, options }); +} + +export async function set_display_layout({ mode, configStr }: { mode: 'mirror' | 'extend', configStr?: string }) { + if (!native || !native.set_display_layout) return { success: false, error: 'Native handler set_display_layout not available' }; + return await native.set_display_layout({ mode, configStr }); +} + +export async function power_control({ action }: { action: 'shutdown' | 'reboot' | 'sleep' }) { + if (!native || !native.power_control) return { success: false, error: 'Native handler power_control not available' }; + return await native.power_control({ action }); +} + +export async function open_external({ url, app }: { url: string, app?: 'chrome' | 'firefox' | 'default' }) { + if (!native || !native.open_external) return { success: false, error: 'Native handler open_external not available' }; + return await native.open_external({ url, app }); +} + /** * List Tools (Self-Documentation) * Returns a JSON manifest of all available native bridge functions. diff --git a/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_native_os.svelte b/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_native_os.svelte index ee2f3104..4ca03a71 100644 --- a/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_native_os.svelte +++ b/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_native_os.svelte @@ -6,6 +6,7 @@ let test_cmd_result = $state(''); let remote_app: 'powerpoint' | 'keynote' = $state('powerpoint'); let remote_status = $state(''); + let system_status = $state(''); async function handle_remote_control(action: 'next' | 'prev' | 'start' | 'stop') { remote_status = `Sending ${action}...`; @@ -17,6 +18,20 @@ } setTimeout(() => remote_status = '', 3000); } + + async function handle_system_action(promise: Promise, label: string) { + system_status = `Executing ${label}...`; + const res = await promise; + if (res.success) { + system_status = `Success: ${label}`; + } else { + system_status = `Error: ${res.error || 'Unknown error'}`; + } + setTimeout(() => system_status = '', 3000); + } + + // Modal state for dangerous actions + let show_power_confirm = $state<{ action: string, label: string } | null>(null); {#if $ae_loc.is_native} @@ -38,7 +53,7 @@ {:else} {/if} - Native OS Handlers & Folders + Native OS Management Active @@ -48,32 +63,100 @@ class="flex flex-col gap-2 p-2 items-center justify-start w-full" class:hidden={!$events_loc.launcher.show_section__native_os} > -
- - - + {#if system_status} +
+ {system_status} +
+ {/if} + + +
+ +
+ + + + +
- -
+ +
+ +
+ + + + + +
+
+ + +
+ +
+ + +
+
+ + +
- - @@ -94,36 +177,35 @@
{#if remote_status} -
{remote_status}
+
{remote_status}
{/if}
-
-
- -
- - -
+ +
+ +
+ +
{#if test_cmd_result} @@ -140,4 +222,30 @@ {/if} + +{#if show_power_confirm} +
+
+

Confirm System Action

+

+ Are you sure you want to {show_power_confirm.action} this host machine? + This will terminate the native application and any active presentations. +

+
+ + +
+
+
+{/if} + diff --git a/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_updates.svelte b/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_updates.svelte new file mode 100644 index 00000000..bcdb8893 --- /dev/null +++ b/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_updates.svelte @@ -0,0 +1,133 @@ + + +{#if $ae_loc.is_native} +
+

+ +

+ +
+
+
+ +
+ + +
+
+ + {#if update_source === 'file'} + + {:else} + + {/if} + + + + {#if update_status} +
+ {update_status} +
+ {/if} + + {#if download_result} + + {/if} +
+
+
+{/if} diff --git a/src/routes/events/[event_id]/(launcher)/launcher_cfg.svelte b/src/routes/events/[event_id]/(launcher)/launcher_cfg.svelte index 79071134..e3a43368 100644 --- a/src/routes/events/[event_id]/(launcher)/launcher_cfg.svelte +++ b/src/routes/events/[event_id]/(launcher)/launcher_cfg.svelte @@ -27,6 +27,7 @@ import LauncherCfgNativeOS from './cfg_components/launcher_cfg_native_os.svelte'; import LauncherCfgSyncTimers from './cfg_components/launcher_cfg_sync_timers.svelte'; import LauncherCfgHealth from './cfg_components/launcher_cfg_health.svelte'; + import LauncherCfgUpdates from './cfg_components/launcher_cfg_updates.svelte'; import LauncherCfgController from './cfg_components/launcher_cfg_controller.svelte'; import LauncherCfgScreenSaver from './cfg_components/launcher_cfg_screen_saver.svelte'; import LauncherCfgAppModes from './cfg_components/launcher_cfg_app_modes.svelte'; @@ -58,6 +59,7 @@ + {/if}