From e7903bde095049da258246c62ba82cec0a7df11d Mon Sep 17 00:00:00 2001 From: E44 <129310925+programmer-44@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:47:54 +0100 Subject: [PATCH] Restructering and adding preview support in pinned view --- control/frontend/src/components/Button.svelte | 6 +- .../src/components/ControlView.svelte | 53 +++ .../src/components/DisplayObject.svelte | 12 +- .../src/components/DisplayView.svelte | 218 ++++++++++ .../frontend/src/components/FileView.svelte | 106 +++++ .../src/components/FolderElementObject.svelte | 4 +- control/frontend/src/components/PopUp.svelte | 4 +- control/frontend/src/routes/+page.svelte | 404 +----------------- control/frontend/src/tailwind.config.js | 3 + control/frontend/src/ts/stores/displays.ts | 8 +- 10 files changed, 415 insertions(+), 403 deletions(-) create mode 100644 control/frontend/src/components/ControlView.svelte create mode 100644 control/frontend/src/components/DisplayView.svelte create mode 100644 control/frontend/src/components/FileView.svelte diff --git a/control/frontend/src/components/Button.svelte b/control/frontend/src/components/Button.svelte index 9787035..137622b 100644 --- a/control/frontend/src/components/Button.svelte +++ b/control/frontend/src/components/Button.svelte @@ -154,7 +154,7 @@ transition:fade={{ duration: 50 }} class="absolute {position_bottom ? 'top-full' - : 'bottom-full'} {menu_class} z-100 my-1.5 min-w-64 rounded-xl backdrop-blur bg-stone-600/30 border border-stone-400/10 shadow-xl/20 p-2 flex flex-col gap-2 text-stone-200 cursor-auto" + : 'bottom-full'} {menu_class} z-100 my-1.5 min-w-64 rounded-xl backdrop-blur bg-black/20 border border-stone-400/10 shadow-xl/20 p-2 flex flex-col gap-2 text-stone-200 cursor-auto" onclick={(e) => { e.stopPropagation(); }} @@ -162,9 +162,9 @@ {#each menu_options as option} + + + + +
+ + +
+ + +
+
+ + +
+ +
+ + + diff --git a/control/frontend/src/components/DisplayObject.svelte b/control/frontend/src/components/DisplayObject.svelte index 3c54969..d84fc66 100644 --- a/control/frontend/src/components/DisplayObject.svelte +++ b/control/frontend/src/components/DisplayObject.svelte @@ -49,9 +49,7 @@
{:else if display.preview_url} - API-Bild + preview {:else} - +
+ +
{/if} @@ -129,7 +129,7 @@ { icon: Trash2, name: 'Bildschirm löschen', - class: 'text-red-400 hover:text-stone-200 hover:!bg-red-400' + class: 'text-red-400 hover:text-stone-200 hover:!bg-red-400 active:!bg-red-500' } ]} > diff --git a/control/frontend/src/components/DisplayView.svelte b/control/frontend/src/components/DisplayView.svelte new file mode 100644 index 0000000..a355ffd --- /dev/null +++ b/control/frontend/src/components/DisplayView.svelte @@ -0,0 +1,218 @@ + + + + +
+ {#if $pinned_display_id} + +
+
+
+ + {pinned_display?.name} + +
+ + + + +
+
+ +
+ {#if pinned_display?.preview_url} + preview + {:else} +
+ +
+ {/if} +
+
+
+ {/if} + +
+ +
+ + Bereits verbundene Displays + +
+ +
+ + +
+
+
+
+
{ + $is_group_drag = true; + $displays = e.detail.items; + }} + onfinalize={(e: CustomEvent) => { + $displays = e.detail.items; + $is_group_drag = false; + }} + > + {#each $displays as display_group (display_group.id)} + +
+ +
+ {/each} +
+
+
+
diff --git a/control/frontend/src/components/FileView.svelte b/control/frontend/src/components/FileView.svelte new file mode 100644 index 0000000..22772ba --- /dev/null +++ b/control/frontend/src/components/FileView.svelte @@ -0,0 +1,106 @@ + + +
+
+ + Dateien anzeigen und verwalten + +
+ + +
+
+
+
+ +
+
+ +
+ + +
+ +
+
+ + +
+ + +
+
+
+
+
+ {#each get_current_folder_elements($all_files, $current_file_path, $selected_display_ids) as folder_element (folder_element.id)} +
+ +
+ {/each} +
+
+ +
+
diff --git a/control/frontend/src/components/FolderElementObject.svelte b/control/frontend/src/components/FolderElementObject.svelte index 810e5aa..4bff961 100644 --- a/control/frontend/src/components/FolderElementObject.svelte +++ b/control/frontend/src/components/FolderElementObject.svelte @@ -30,7 +30,7 @@ import RefreshPlay from './RefreshPlay.svelte'; import { get_file_size_display_string } from '../ts/utils'; import { open_file } from '../ts/api_handler'; - import { get_display_by_id, update_screenshot } from '../ts/stores/displays'; + import { displays, get_display_by_id, update_screenshot } from '../ts/stores/displays'; let { file } = $props<{ file: FolderElement }>(); @@ -98,7 +98,7 @@ } else { const path_to_file = $current_file_path + file.name; for (const display_id of $selected_display_ids) { - const ip = get_display_by_id(display_id)?.ip ?? null; + const ip = get_display_by_id(display_id, $displays)?.ip ?? null; if (ip) { await open_file(ip, path_to_file); await update_screenshot(display_id); diff --git a/control/frontend/src/components/PopUp.svelte b/control/frontend/src/components/PopUp.svelte index c91b34b..de93b25 100644 --- a/control/frontend/src/components/PopUp.svelte +++ b/control/frontend/src/components/PopUp.svelte @@ -27,9 +27,9 @@ // }); -
+
- import { - ArrowBigLeft, - ArrowBigRight, - ArrowUp, - ChevronDown, - ClipboardPaste, - Download, - FolderOutput, - FolderPlus, - Info, - Keyboard, - Menu, - Minus, - Pen, - Pencil, - PinOff, - Plus, - Power, - PowerOff, - Presentation, - RefreshCcw, - Scissors, - Settings, - Square, - SquareTerminal, - TextAlignStart, - TrafficCone, - Trash2, - TvMinimalPlay, - Upload, - VideoOff, - X - } from 'lucide-svelte'; + import { Plus, Settings } from 'lucide-svelte'; import Button from '../components/Button.svelte'; + import FileView from '../components/FileView.svelte'; + import ControlView from '../components/ControlView.svelte'; + import DisplayView from '../components/DisplayView.svelte'; import SplashScreen from './../../../../shared/splash_screen.html?raw'; - import { - change_height, - current_height, - dnd_flip_duration_ms, - get_selectable_color_classes, - is_display_drag, - is_group_drag, - next_height_step_size, - pinned_display_id - } from '../ts/stores/ui_behavior'; - import { dragHandleZone } from 'svelte-dnd-action'; - import { - all_displays_of_group_selected, - displays, - get_display_by_id, - select_all_of_group - } from '../ts/stores/displays'; - import { cubicOut } from 'svelte/easing'; - import { flip } from 'svelte/animate'; - import DisplayGroupObject from '../components/DisplayGroupObject.svelte'; - import { blur, draw, fade, fly, scale, slide } from 'svelte/transition'; - import OnlineState from '../components/OnlineState.svelte'; - import type { DisplayGroup } from '../ts/types'; import PopUp from '../components/PopUp.svelte'; - import FileObject from '../components/FolderElementObject.svelte'; - import FolderElementObject from '../components/FolderElementObject.svelte'; - import PathBar from '../components/PathBar.svelte'; - import { all_files, current_file_path, get_current_folder_elements } from '../ts/stores/files'; - import { selected_display_ids, selected_file_ids } from '../ts/stores/select'; - - let displays_scroll_box: HTMLElement; - - function select_all(current_displays: DisplayGroup[], current_selected_display_ids: string[]) { - const new_value = !all_selected(current_displays, current_selected_display_ids); - for (const display_group of current_displays) { - select_all_of_group(display_group, new_value); - } - } - - function all_selected(current_displays: DisplayGroup[], current_selected_display_ids: string[]) { - for (const display_group of current_displays) { - if (!all_displays_of_group_selected(display_group, current_selected_display_ids)) { - return false; - } - } - return true; - } - - function on_wheel(e: WheelEvent) { - if (!$is_group_drag && !$is_display_drag) return; - if (!displays_scroll_box) return; - - // apply custom scroll feature - e.preventDefault(); - (displays_scroll_box as HTMLElement).scrollBy?.({ - top: e.deltaY, - behavior: 'auto' - }); - } - -
- +
PLG MuDiCS -
-
- {#if $pinned_display_id} - -
-
-
- - {get_display_by_id($pinned_display_id)?.name} - -
- - - - -
-
- -
-
- -
-
-
-
- {/if} - -
- -
- - Bereits verbundene Displays - -
- -
- - -
-
-
-
-
{ - $is_group_drag = true; - $displays = e.detail.items; - }} - onfinalize={(e: CustomEvent) => { - $displays = e.detail.items; - $is_group_drag = false; - }} - > - {#each $displays as display_group (display_group.id)} - -
- -
- {/each} -
-
-
-
+
-
-
- {'Bildschirme steuern (' + $selected_display_ids.length + ' ausgewählt)'} -
-
-
-
-
- - -
- - -
- - -
- -
-
-
- - -
- -
-
-
-
-
-
- - Dateien anzeigen und verwalten - -
- - -
-
-
-
- -
-
- -
- - -
- -
-
- - -
- - -
-
-
-
-
- {#each get_current_folder_elements($all_files, $current_file_path, $selected_display_ids) as folder_element (folder_element.id)} -
- -
- {/each} -
-
-
-
+ +
-
diff --git a/control/frontend/src/tailwind.config.js b/control/frontend/src/tailwind.config.js index be77b68..5de1f28 100644 --- a/control/frontend/src/tailwind.config.js +++ b/control/frontend/src/tailwind.config.js @@ -190,5 +190,8 @@ module.exports = { 'right-0', 'left-0', + + 'hover:bg-red-400', + 'active:bg-red-500', ], } diff --git a/control/frontend/src/ts/stores/displays.ts b/control/frontend/src/ts/stores/displays.ts index 52f5e23..2205dfd 100644 --- a/control/frontend/src/ts/stores/displays.ts +++ b/control/frontend/src/ts/stores/displays.ts @@ -44,8 +44,8 @@ export function set_new_display_group_data(display_group_id: string, new_data: D }); } -export function get_display_by_id(display_id: string) { - const displays_array = get(displays); +export function get_display_by_id(display_id: string, display_group_array: DisplayGroup[]) { + const displays_array = display_group_array; for (const display_group of displays_array) { for (const display of display_group.data) { if (display.id === display_id) { @@ -80,10 +80,10 @@ export function remove_empty_display_groups() { } export async function update_screenshot(display_id: string, check_type: "first_check" | "last_check_different" | "last_check_same" = "first_check") { - const display_ip = get_display_by_id(display_id)?.ip; + const display_ip = get_display_by_id(display_id, get(displays))?.ip; if (!display_ip) return; const new_blob = await get_screenshot(display_ip); - const display = get_display_by_id(display_id); + const display = get_display_by_id(display_id, get(displays)); let update_needed = check_type === "first_check"; if (check_type !== "first_check") {