fix(control): screenshot_loop is no longer blocking, preview states are now consistently changed

This commit is contained in:
E44
2026-01-18 22:22:30 +01:00
parent d61ef0fe94
commit 0e87ca3ae1
5 changed files with 77 additions and 43 deletions
@@ -41,7 +41,7 @@
} else { } else {
$pinned_display_id = display_id_object.id; $pinned_display_id = display_id_object.id;
} }
await screenshot_loop(display_id_object.id); screenshot_loop(display_id_object.id);
e.stopPropagation(); e.stopPropagation();
} }
</script> </script>
+4 -2
View File
@@ -12,7 +12,9 @@ const loading_display_ids: string[] = [];
export async function on_app_start() { export async function on_app_start() {
await db.files.clear(); await db.files.clear();
await db.files_on_display.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 update_all_display_status(false);
await setInterval( await setInterval(
() => update_all_display_status(false), () => 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) { async function on_display_start(display: Display) {
await update_folder_elements_recursively(display, '/'); await update_folder_elements_recursively(display, '/');
await screenshot_loop(display.id); screenshot_loop(display.id);
} }
+53 -35
View File
@@ -71,8 +71,15 @@ export async function edit_display_data(
): Promise<Display | null> { ): Promise<Display | null> {
let display = await db.displays.get(display_id); let display = await db.displays.get(display_id);
if (!display) return null; 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 await db.displays.put(display); // save
screenshot_loop(display.id);
return display; return display;
} }
@@ -127,49 +134,60 @@ export async function get_display_by_id(display_id: string): Promise<Display | n
return (await db.displays.get(display_id)) ?? null; return (await db.displays.get(display_id)) ?? null;
} }
export async function screenshot_loop(display_id: string) { export function screenshot_loop(display_id: string) {
const settings = get(preview_settings); setTimeout(async () => {
if (settings.mode === 'never') return; let settings = get(preview_settings);
if (settings.mode === 'never') return;
const initial_retry_count = settings.retry_count.now; const initial_retry_count = settings.retry_count.now;
const retry_seconds = get(preview_settings).retry_seconds.now; const retry_seconds = get(preview_settings).retry_seconds.now;
const display = await db.displays.get(display_id); const display = await db.displays.get(display_id);
if (!display || display.preview.currently_updating) return; if (!display || display.preview.currently_updating) return;
display.preview.currently_updating = true; display.preview.currently_updating = true;
await db.displays.update(display.id, { preview: display.preview }); 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; let retry_count = initial_retry_count;
while (retry_count > 0) { while (retry_count > 0) {
if (settings.mode !== 'always') retry_count -= 1; settings = get(preview_settings);
if (settings.mode === 'never') break;
if (settings.mode !== 'always') retry_count -= 1;
const new_blob = await get_screenshot(display.ip); const new_blob = await get_screenshot(display.ip);
if (!new_blob) { settings = get(preview_settings);
display.preview = { currently_updating: false, url: null }; if (settings.mode === 'never') break;
await db.displays.update(display.id, { preview: display.preview });
return; if (!new_blob) {
} display.preview = { currently_updating: false, url: null };
const new_hash = await image_content_hash(new_blob); await db.displays.update(display.id, { preview: display.preview });
if (last_hash !== new_hash) { return;
if (display.preview.url) { }
URL.revokeObjectURL(display.preview.url); 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; await new Promise((resolve) => setTimeout(resolve, retry_seconds * 1000)); // sleep
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 if (settings.mode === 'never') {
} await db.displays.update(display.id, { preview: { currently_updating: false, url: null } });
} else {
display.preview.currently_updating = false; display.preview.currently_updating = false;
await db.displays.update(display.id, { preview: display.preview }); await db.displays.update(display.id, { preview: display.preview });
}
}, 0);
} }
export async function run_on_all_selected_displays( 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; if (!display || (ignore_offline && display.status === 'host_offline')) return;
await run_function(display); await run_function(display);
if (update_screenshot_afterwards) { if (update_screenshot_afterwards) {
await screenshot_loop(display.id); screenshot_loop(display.id);
} }
}) })
); );
+18 -4
View File
@@ -25,7 +25,8 @@
edit_display_data, edit_display_data,
get_display_by_id, get_display_by_id,
is_display_name_taken, is_display_name_taken,
remove_display remove_display,
screenshot_loop
} from '$lib/ts/stores/displays'; } from '$lib/ts/stores/displays';
import { notifications } from '$lib/ts/stores/notification'; import { notifications } from '$lib/ts/stores/notification';
import { ping_ip } from '$lib/ts/api_handler'; import { ping_ip } from '$lib/ts/api_handler';
@@ -35,6 +36,7 @@
import HighlightedText from '$lib/components/HighlightedText.svelte'; import HighlightedText from '$lib/components/HighlightedText.svelte';
import { preview_settings } from '$lib/ts/stores/ui_behavior'; import { preview_settings } from '$lib/ts/stores/ui_behavior';
import NumberSettingInput from '$lib/components/NumberSettingInput.svelte'; import NumberSettingInput from '$lib/components/NumberSettingInput.svelte';
import { db } from '$lib/ts/database';
const ip_regex = 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))$/; /^(?:(?: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() { function popup_close_function() {
popup_content.open = false; popup_content.open = false;
} }
@@ -332,9 +348,7 @@
menu_options={(['never', 'normal', 'always'] as const).map((mode) => ({ menu_options={(['never', 'normal', 'always'] as const).map((mode) => ({
icon: mode === $preview_settings.mode ? SquareCheckBig : Square, icon: mode === $preview_settings.mode ? SquareCheckBig : Square,
name: get_display_preview_mode(mode), name: get_display_preview_mode(mode),
on_select: () => { on_select: async () => await change_preview_mode(mode)
$preview_settings.mode = mode;
}
}))}>{get_display_preview_mode($preview_settings.mode)} <ChevronDown /></Button }))}>{get_display_preview_mode($preview_settings.mode)} <ChevronDown /></Button
> >
</div> </div>
@@ -112,7 +112,7 @@
popup_content.open = false; popup_content.open = false;
await run_on_all_selected_displays((d) => { await run_on_all_selected_displays((d) => {
shutdown(d.ip); // no await here because we want to be fast 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); }, false);
} }