diff --git a/control/frontend/src/lib/ts/stores/displays.ts b/control/frontend/src/lib/ts/stores/displays.ts index 435f5b8..264e54f 100755 --- a/control/frontend/src/lib/ts/stores/displays.ts +++ b/control/frontend/src/lib/ts/stores/displays.ts @@ -201,7 +201,7 @@ export async function run_on_all_selected_displays( ); const displays: Display[] = maybe_displays.filter((d): d is Display => d !== null); - Promise.all( + await Promise.all( displays.map(async (display) => { if (!display || (ignore_offline && display.status === 'host_offline')) return; await run_function(display); diff --git a/control/frontend/src/lib/ts/utils.ts b/control/frontend/src/lib/ts/utils.ts index a8279f0..e1d96cb 100644 --- a/control/frontend/src/lib/ts/utils.ts +++ b/control/frontend/src/lib/ts/utils.ts @@ -113,3 +113,12 @@ export function get_sanitized_file_url(file_path: string, is_preview = false) { return `/file/${is_preview ? 'preview/' : ''}${[...pathSegments].join('/')}`; } + + +let keyboard_queue = Promise.resolve(); + +export function add_to_keyboard_queue(task: () => Promise) { + keyboard_queue = keyboard_queue.then(task).catch((err) => { + console.error('Error in input queue:', err); + }); +} diff --git a/control/frontend/src/routes/ControlView.svelte b/control/frontend/src/routes/ControlView.svelte index 0cec977..4a34805 100644 --- a/control/frontend/src/routes/ControlView.svelte +++ b/control/frontend/src/routes/ControlView.svelte @@ -34,6 +34,7 @@ import { db } from '$lib/ts/database'; import { liveQuery, type Observable } from 'dexie'; import TextInput from '$lib/components/TextInput.svelte'; + import { add_to_keyboard_queue } from '$lib/ts/utils'; let all_display_states: Observable<'on' | 'off' | 'mixed'> | undefined = $state(); $effect(() => { @@ -206,11 +207,11 @@ ? 'text-stone-500 cursor-not-allowed' : 'hover:bg-stone-600 active:bg-stone-500 cursor-pointer'} py-2 rounded-xl flex justify-center items-center transition-colors duration-200" disabled={$selected_display_ids.length === 0} - onmousedown={async () => { - await send_single_key_press('ArrowLeft', 'press'); + onmousedown={() => { + add_to_keyboard_queue(async () => await send_single_key_press('ArrowLeft', 'press')); }} - onmouseup={async () => { - await send_single_key_press('ArrowLeft', 'release'); + onmouseup={() => { + add_to_keyboard_queue(async () => await send_single_key_press('ArrowLeft', 'release')); }} > @@ -222,11 +223,11 @@ ? 'text-stone-500 cursor-not-allowed' : 'hover:bg-stone-600 active:bg-stone-500 cursor-pointer'} py-2 rounded-xl flex justify-center items-center transition-colors duration-200" disabled={$selected_display_ids.length === 0} - onmousedown={async () => { - await send_single_key_press('ArrowRight', 'press'); + onmousedown={() => { + add_to_keyboard_queue(async () => await send_single_key_press('ArrowRight', 'press')); }} - onmouseup={async () => { - await send_single_key_press('ArrowRight', 'release'); + onmouseup={() => { + add_to_keyboard_queue(async () => await send_single_key_press('ArrowRight', 'release')); }} > diff --git a/control/frontend/src/routes/KeyInput.svelte b/control/frontend/src/routes/KeyInput.svelte index cf5c1a7..7ace3ec 100644 --- a/control/frontend/src/routes/KeyInput.svelte +++ b/control/frontend/src/routes/KeyInput.svelte @@ -7,6 +7,7 @@ import { ArrowDownToLine, ArrowUpFromLine, Grid2x2, Grid2X2, Option } from 'lucide-svelte'; import Button from '$lib/components/Button.svelte'; import { onDestroy } from 'svelte'; + import { add_to_keyboard_queue } from '$lib/ts/utils'; let { popup_close_function @@ -58,17 +59,21 @@ const action: 'press' | 'release' = key_down ? 'press' : 'release'; add_to_last_keys(action.toUpperCase() + ' ' + key); - await run_on_all_selected_displays((d) => send_keyboard_input(d.ip, [{ key, action }]), true); + add_to_keyboard_queue(async () => { + await run_on_all_selected_displays((d) => send_keyboard_input(d.ip, [{ key, action }]), true); + }); } - async function release_all_pressed_keys() { + function release_all_pressed_keys() { const inputs: { key: string; action: 'press' | 'release' }[] = []; for (let i = current_keys.length - 1; i >= 0; i--) { inputs.push({ key: current_keys[i], action: 'release' }); current_keys.splice(i, 1); } - await run_on_all_selected_displays((d) => send_keyboard_input(d.ip, inputs), true); + add_to_keyboard_queue(async () => { + await run_on_all_selected_displays((d) => send_keyboard_input(d.ip, inputs), true); + }); } onDestroy(() => { @@ -91,7 +96,7 @@ }} onblur={async () => { active = false; - await release_all_pressed_keys(); + release_all_pressed_keys(); }} onkeydown={(e) => on_keyboard_input(e, true)} onkeyup={(e) => on_keyboard_input(e, false)}