mirror of
https://codeberg.org/PLG-Development/PLG-MuDiCS
synced 2026-07-05 16:37:09 +00:00
feat(control): bind arrow keys to arrow buttons
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
|
||||
{#if content.open}
|
||||
<div
|
||||
class="absolute inset-0 backdrop-blur flex justify-center items-center z-50 {className}"
|
||||
class="popup absolute inset-0 backdrop-blur flex justify-center items-center z-50 {className}"
|
||||
transition:fade={{ duration: 100 }}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
import { liveQuery, type Observable } from 'dexie';
|
||||
import TextInput from '$lib/components/TextInput.svelte';
|
||||
import { add_to_keyboard_queue } from '$lib/ts/utils';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let all_display_states: Observable<'on' | 'off' | 'mixed'> | undefined = $state();
|
||||
$effect(() => {
|
||||
@@ -44,11 +45,16 @@
|
||||
let popup_content: PopupContent = $state({
|
||||
open: false,
|
||||
snippet: null,
|
||||
title: '',
|
||||
title: ''
|
||||
});
|
||||
|
||||
let current_text = $state('');
|
||||
|
||||
const key_pressed = $state({
|
||||
ArrowRight: false,
|
||||
ArrowLeft: false
|
||||
});
|
||||
|
||||
function popup_close_function() {
|
||||
popup_content.open = false;
|
||||
}
|
||||
@@ -79,7 +85,7 @@
|
||||
snippet: website_popup,
|
||||
title: 'Webseite Anzeigen',
|
||||
window_class: 'w-xl',
|
||||
title_icon: Globe,
|
||||
title_icon: Globe
|
||||
};
|
||||
};
|
||||
|
||||
@@ -102,7 +108,7 @@
|
||||
open: true,
|
||||
snippet: ask_shutdown_popup,
|
||||
title: 'Bildschirm Herunterfahren',
|
||||
title_icon: PowerOff,
|
||||
title_icon: PowerOff
|
||||
};
|
||||
}
|
||||
|
||||
@@ -110,7 +116,10 @@
|
||||
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', preview: { currently_updating: false, url: null} });
|
||||
db.displays.update(d.id, {
|
||||
status: 'app_offline',
|
||||
preview: { currently_updating: false, url: null }
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
@@ -143,10 +152,58 @@
|
||||
|
||||
async function send_website() {
|
||||
popup_content.open = false;
|
||||
await run_on_all_selected_displays((d) =>
|
||||
open_website(d.ip, website_url)
|
||||
);
|
||||
await run_on_all_selected_displays((d) => open_website(d.ip, website_url));
|
||||
}
|
||||
|
||||
function has_open_popup(): boolean {
|
||||
return document.querySelector('.popup') !== null;
|
||||
}
|
||||
|
||||
function handle_key(
|
||||
event: KeyboardEvent,
|
||||
key: 'ArrowRight' | 'ArrowLeft',
|
||||
action: 'press' | 'release'
|
||||
) {
|
||||
if (event.key === key) {
|
||||
const current_press_state: boolean = key_pressed[key];
|
||||
if (
|
||||
(action === 'press' && (current_press_state === true || has_open_popup())) ||
|
||||
(action === 'release' && current_press_state === false)
|
||||
)
|
||||
return;
|
||||
|
||||
key_pressed[key] = !current_press_state;
|
||||
add_to_keyboard_queue(async () => {
|
||||
await run_on_all_selected_displays(
|
||||
(d) => send_keyboard_input(d.ip, [{ key, action }]),
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function add_remove_event_listeners(
|
||||
add_remove_function: (type: string, listener: (e: KeyboardEvent) => void) => void
|
||||
) {
|
||||
const actions = {
|
||||
keydown: 'press',
|
||||
keyup: 'release'
|
||||
} as const;
|
||||
const keys = ['ArrowRight', 'ArrowLeft'] as const;
|
||||
|
||||
for (const [action_type, action_value] of Object.entries(actions)) {
|
||||
for (const key of keys) {
|
||||
add_remove_function(action_type, (e: KeyboardEvent) => handle_key(e, key, action_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
add_remove_event_listeners(window.addEventListener);
|
||||
return () => {
|
||||
add_remove_event_listeners(window.removeEventListener);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet website_popup()}
|
||||
@@ -185,11 +242,11 @@
|
||||
{/snippet}
|
||||
|
||||
{#snippet send_keys_popup()}
|
||||
<KeyInput {popup_close_function}/>
|
||||
<KeyInput {popup_close_function} />
|
||||
{/snippet}
|
||||
|
||||
{#snippet text_popup()}
|
||||
<TipTapInput bind:text={current_text}/>
|
||||
<TipTapInput bind:text={current_text} />
|
||||
{/snippet}
|
||||
|
||||
<div class="grid grid-rows-[2.5rem_auto] bg-stone-800 rounded-2xl min-w-0">
|
||||
@@ -202,15 +259,19 @@
|
||||
<div class="flex flex-row gap-2 w-75 justify-normal">
|
||||
<button
|
||||
title="Vorherige Folie (Pfeil nach Links) [gedrückt halten möglich]"
|
||||
class="px-9 bg-stone-700 {$selected_online_display_ids.length === 0
|
||||
class="px-9 {key_pressed.ArrowLeft
|
||||
? 'bg-stone-500'
|
||||
: 'bg-stone-700'} {$selected_online_display_ids.length === 0
|
||||
? '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_online_display_ids.length === 0}
|
||||
disabled={$selected_online_display_ids.length === 0 || key_pressed.ArrowLeft}
|
||||
onmousedown={() => {
|
||||
add_to_keyboard_queue(async () => await send_single_key_press('ArrowLeft', 'press'));
|
||||
}}
|
||||
onmouseup={() => {
|
||||
add_to_keyboard_queue(async () => await send_single_key_press('ArrowLeft', 'release'));
|
||||
add_to_keyboard_queue(
|
||||
async () => await send_single_key_press('ArrowLeft', 'release')
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ArrowBigLeft />
|
||||
@@ -218,15 +279,21 @@
|
||||
|
||||
<button
|
||||
title="Nächste Folie (Pfeil nach Rechts) [gedrückt halten möglich]"
|
||||
class="px-9 bg-stone-700 {$selected_online_display_ids.length === 0
|
||||
? '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_online_display_ids.length === 0}
|
||||
class="px-9 {key_pressed.ArrowRight
|
||||
? 'bg-stone-500 cursor-not-allowed'
|
||||
: `bg-stone-700 ${
|
||||
$selected_online_display_ids.length === 0
|
||||
? '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_online_display_ids.length === 0 || key_pressed.ArrowRight}
|
||||
onmousedown={() => {
|
||||
add_to_keyboard_queue(async () => await send_single_key_press('ArrowRight', 'press'));
|
||||
}}
|
||||
onmouseup={() => {
|
||||
add_to_keyboard_queue(async () => await send_single_key_press('ArrowRight', 'release'));
|
||||
add_to_keyboard_queue(
|
||||
async () => await send_single_key_press('ArrowRight', 'release')
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ArrowBigRight />
|
||||
@@ -271,8 +338,7 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<Button
|
||||
className="px-3 flex gap-3 w-full xl:w-75 justify-normal"
|
||||
disabled={$all_display_states === 'on' ||
|
||||
$selected_display_ids.length === 0}
|
||||
disabled={$all_display_states === 'on' || $selected_display_ids.length === 0}
|
||||
click_function={startup_action}
|
||||
>
|
||||
<Power /> Bildschirm Hochfahren
|
||||
@@ -280,8 +346,7 @@
|
||||
|
||||
<Button
|
||||
className="px-3 flex gap-3 w-full xl:w-75 justify-normal"
|
||||
disabled={$all_display_states === 'off' ||
|
||||
$selected_online_display_ids.length === 0}
|
||||
disabled={$all_display_states === 'off' || $selected_online_display_ids.length === 0}
|
||||
click_function={ask_shutdown}
|
||||
>
|
||||
<PowerOff /> Bildschirm Herunterfahren</Button
|
||||
|
||||
Reference in New Issue
Block a user