From 0e87ca3ae1e8fb28bda818ff3261dde03cf6266d Mon Sep 17 00:00:00 2001 From: E44 <129310925+programmer-44@users.noreply.github.com> Date: Sun, 18 Jan 2026 22:22:30 +0100 Subject: [PATCH] fix(control): screenshot_loop is no longer blocking, preview states are now consistently changed --- .../src/lib/components/DisplayObject.svelte | 2 +- control/frontend/src/lib/ts/main.ts | 6 +- .../frontend/src/lib/ts/stores/displays.ts | 88 +++++++++++-------- control/frontend/src/routes/+page.svelte | 22 ++++- .../frontend/src/routes/ControlView.svelte | 2 +- 5 files changed, 77 insertions(+), 43 deletions(-) diff --git a/control/frontend/src/lib/components/DisplayObject.svelte b/control/frontend/src/lib/components/DisplayObject.svelte index 63bb362..47aba60 100755 --- a/control/frontend/src/lib/components/DisplayObject.svelte +++ b/control/frontend/src/lib/components/DisplayObject.svelte @@ -41,7 +41,7 @@ } else { $pinned_display_id = display_id_object.id; } - await screenshot_loop(display_id_object.id); + screenshot_loop(display_id_object.id); e.stopPropagation(); } diff --git a/control/frontend/src/lib/ts/main.ts b/control/frontend/src/lib/ts/main.ts index 75a4f43..5d17d2f 100755 --- a/control/frontend/src/lib/ts/main.ts +++ b/control/frontend/src/lib/ts/main.ts @@ -12,7 +12,9 @@ const loading_display_ids: string[] = []; export async function on_app_start() { await db.files.clear(); await db.files_on_display.clear(); - await db.displays.toCollection().modify({ status: null }); + await db.displays + .toCollection() + .modify({ status: null, preview: { currently_updating: false, url: null } }); await update_all_display_status(false); await setInterval( () => update_all_display_status(false), @@ -65,5 +67,5 @@ export function remove_display_from_loading_displays(display_id: string) { async function on_display_start(display: Display) { await update_folder_elements_recursively(display, '/'); - await screenshot_loop(display.id); + screenshot_loop(display.id); } diff --git a/control/frontend/src/lib/ts/stores/displays.ts b/control/frontend/src/lib/ts/stores/displays.ts index f5887be..435f5b8 100755 --- a/control/frontend/src/lib/ts/stores/displays.ts +++ b/control/frontend/src/lib/ts/stores/displays.ts @@ -71,8 +71,15 @@ export async function edit_display_data( ): Promise { let display = await db.displays.get(display_id); if (!display) return null; - display = { ...display, ip: ip, mac: mac, name: name }; + display = { + ...display, + ip: ip, + mac: mac, + name, + preview: { currently_updating: false, url: null } + }; await db.displays.put(display); // save + screenshot_loop(display.id); return display; } @@ -127,49 +134,60 @@ export async function get_display_by_id(display_id: string): Promise { + let settings = get(preview_settings); + if (settings.mode === 'never') return; - const initial_retry_count = settings.retry_count.now; - const retry_seconds = get(preview_settings).retry_seconds.now; + const initial_retry_count = settings.retry_count.now; + const retry_seconds = get(preview_settings).retry_seconds.now; - const display = await db.displays.get(display_id); - if (!display || display.preview.currently_updating) return; + const display = await db.displays.get(display_id); + if (!display || display.preview.currently_updating) return; - display.preview.currently_updating = true; - await db.displays.update(display.id, { preview: display.preview }); + display.preview.currently_updating = true; + await db.displays.update(display.id, { preview: display.preview }); - let last_hash: number | null = null; + let last_hash: number | null = null; - let retry_count = initial_retry_count; - while (retry_count > 0) { - if (settings.mode !== 'always') retry_count -= 1; + let retry_count = initial_retry_count; + while (retry_count > 0) { + settings = get(preview_settings); + if (settings.mode === 'never') break; + if (settings.mode !== 'always') retry_count -= 1; - const new_blob = await get_screenshot(display.ip); - if (!new_blob) { - display.preview = { currently_updating: false, url: null }; - await db.displays.update(display.id, { preview: display.preview }); - return; - } - const new_hash = await image_content_hash(new_blob); - if (last_hash !== new_hash) { - if (display.preview.url) { - URL.revokeObjectURL(display.preview.url); + const new_blob = await get_screenshot(display.ip); + settings = get(preview_settings); + if (settings.mode === 'never') break; + + if (!new_blob) { + display.preview = { currently_updating: false, url: null }; + await db.displays.update(display.id, { preview: display.preview }); + return; + } + const new_hash = await image_content_hash(new_blob); + if (last_hash !== new_hash) { + if (display.preview.url) { + URL.revokeObjectURL(display.preview.url); + } + + last_hash = new_hash; + display.preview.url = URL.createObjectURL(new_blob); + await db.displays.update(display.id, { preview: display.preview }); + + retry_count = initial_retry_count; } - last_hash = new_hash; - display.preview.url = URL.createObjectURL(new_blob); - await db.displays.update(display.id, { preview: display.preview }); - - retry_count = initial_retry_count; + await new Promise((resolve) => setTimeout(resolve, retry_seconds * 1000)); // sleep } - await new Promise((resolve) => setTimeout(resolve, retry_seconds * 1000)); // sleep - } - - display.preview.currently_updating = false; - await db.displays.update(display.id, { preview: display.preview }); + if (settings.mode === 'never') { + await db.displays.update(display.id, { preview: { currently_updating: false, url: null } }); + } else { + display.preview.currently_updating = false; + await db.displays.update(display.id, { preview: display.preview }); + } + }, 0); } export async function run_on_all_selected_displays( @@ -188,7 +206,7 @@ export async function run_on_all_selected_displays( if (!display || (ignore_offline && display.status === 'host_offline')) return; await run_function(display); if (update_screenshot_afterwards) { - await screenshot_loop(display.id); + screenshot_loop(display.id); } }) ); diff --git a/control/frontend/src/routes/+page.svelte b/control/frontend/src/routes/+page.svelte index f7b0bfa..a1d90f9 100644 --- a/control/frontend/src/routes/+page.svelte +++ b/control/frontend/src/routes/+page.svelte @@ -25,7 +25,8 @@ edit_display_data, get_display_by_id, is_display_name_taken, - remove_display + remove_display, + screenshot_loop } from '$lib/ts/stores/displays'; import { notifications } from '$lib/ts/stores/notification'; import { ping_ip } from '$lib/ts/api_handler'; @@ -35,6 +36,7 @@ import HighlightedText from '$lib/components/HighlightedText.svelte'; import { preview_settings } from '$lib/ts/stores/ui_behavior'; import NumberSettingInput from '$lib/components/NumberSettingInput.svelte'; + import { db } from '$lib/ts/database'; const ip_regex = /^(?:(?:10|127)\.(?:25[0-5]|2[0-4]\d|1?\d?\d)\.(?:25[0-5]|2[0-4]\d|1?\d?\d)\.(?:25[0-5]|2[0-4]\d|1?\d?\d)|192\.168\.(?:25[0-5]|2[0-4]\d|1?\d?\d)\.(?:25[0-5]|2[0-4]\d|1?\d?\d)|172\.(?:1[6-9]|2\d|3[0-1])\.(?:25[0-5]|2[0-4]\d|1?\d?\d)\.(?:25[0-5]|2[0-4]\d|1?\d?\d))$/; @@ -93,6 +95,20 @@ } } + async function change_preview_mode(mode: 'never' | 'normal' | 'always') { + $preview_settings.mode = mode; + if (mode === 'never') { + await db.displays + .toCollection() + .modify({ preview: { currently_updating: false, url: null } }); + } else { + const display_ids = (await db.displays.toArray()).map((d) => d.id); + for (const display_id of display_ids) { + screenshot_loop(display_id); + } + } + } + function popup_close_function() { popup_content.open = false; } @@ -332,9 +348,7 @@ menu_options={(['never', 'normal', 'always'] as const).map((mode) => ({ icon: mode === $preview_settings.mode ? SquareCheckBig : Square, name: get_display_preview_mode(mode), - on_select: () => { - $preview_settings.mode = mode; - } + on_select: async () => await change_preview_mode(mode) }))}>{get_display_preview_mode($preview_settings.mode)} diff --git a/control/frontend/src/routes/ControlView.svelte b/control/frontend/src/routes/ControlView.svelte index 534c918..cdfe78f 100644 --- a/control/frontend/src/routes/ControlView.svelte +++ b/control/frontend/src/routes/ControlView.svelte @@ -112,7 +112,7 @@ popup_content.open = false; await run_on_all_selected_displays((d) => { shutdown(d.ip); // no await here because we want to be fast - db.displays.update(d.id, { status: 'app_offline' }); + db.displays.update(d.id, { status: 'app_offline', preview: { currently_updating: false, url: null} }); }, false); }