add rough left side of frontend

This commit is contained in:
E44
2025-10-19 23:05:45 +02:00
parent 296c8bd04b
commit 19cc4c4415
16 changed files with 5410 additions and 3 deletions
+108
View File
@@ -0,0 +1,108 @@
import { get, writable, type Writable } from "svelte/store";
export const displays: Writable<DisplayGroup[]> = writable<DisplayGroup[]>([{
id: crypto.randomUUID(),
data: []
}]);
export const selected_display_ids: Writable<string[]> = writable<string[]>([]);
add_testing_displays();
function add_display(ip: string, mac: string, name: string, status: string) {
displays.update((displays: DisplayGroup[]) => {
displays[0].data.push({ id: crypto.randomUUID(), ip, mac, name, status });
return displays;
});
}
export function select(display_id: string, new_value: boolean | null = null) {
selected_display_ids.update((all_ids: string[]) => {
if (all_ids.includes(display_id)) {
const index = all_ids.indexOf(display_id);
if (index > -1 && new_value !== true) {
all_ids.splice(index, 1);
}
} else if (new_value !== false) {
all_ids.push(display_id);
}
return all_ids;
});
}
export function is_selected(display_id: string, current_selected_display_ids: string[]): boolean {
return current_selected_display_ids.includes(display_id);
}
export function all_displays_of_group_selected(display_group: DisplayGroup, current_selected_displays: string[]) {
if (display_group.data.length === 0) return false;
for (const display of display_group.data) {
if (!is_selected(display.id, current_selected_displays)) {
return false;
}
}
return true;
}
export function select_all_of_group(display_group: DisplayGroup, new_value: boolean | null = null) {
for (const display of display_group.data) {
select(display.id, new_value);
}
}
export function set_new_display_group_data(display_group_id: string, new_data: Display[]) {
displays.update((displays: DisplayGroup[]) => {
for (const display_group of displays) {
if (display_group.id === display_group_id) {
display_group.data = new_data;
}
}
return displays;
});
}
export function get_display_by_id(display_id: string) {
const displays_array = get(displays);
for (const display_group of displays_array) {
for (const display of display_group.data) {
if (display.id === display_id) {
return display;
}
}
}
return null;
}
export function add_empty_display_group() {
displays.update((displays: DisplayGroup[]) => {
displays.push({
id: crypto.randomUUID(),
data: [],
});
return displays;
});
}
export function remove_empty_display_groups() {
displays.update((displays: DisplayGroup[]) => {
for (let i = displays.length - 1; i >= 0; i--) {
if (displays[i].data.length === 0) {
displays.splice(i, 1);
}
}
return displays;
});
}
function add_testing_displays() {
const names = ["Vorne Rechts", "Vorne Links", "Vorne Mitte", "Fernseher Rechts", "Fernseher Bühne", "UIUIUIUIUIUIUISEHRLANGERTEXT DER IST WIRKLICH LANG, DER TEXT, so lang, dass er wirklich nirgendswo hinpasst, nichtmal da oben /\\"];
for (const name of names) {
add_display("192.168.1.42", "00:1A:2B:3C:4D:5E", name, "Offline");
}
}
@@ -0,0 +1,57 @@
import type { NumericRange } from "@sveltejs/kit";
import { get, writable, type Writable } from "svelte/store";
const screen_height_step_size = 5;
export const dnd_flip_duration_ms = 300;
const min_display_screen_height = 15;
const max_display_screen_height = 40;
export const display_screen_height: Writable<number> = writable<number>(25);
export const is_group_drag: Writable<boolean> = writable<boolean>(false);
export const is_display_drag: Writable<boolean> = writable<boolean>(false);
export const pinned_display_id: Writable<string | null> = writable<string | null>(null);
export function change_display_screen_height(factor: number) {
display_screen_height.update((current_height) => {
const new_size = current_height + (factor * screen_height_step_size);
if (new_size > max_display_screen_height || new_size < min_display_screen_height) {
return current_height;
} else {
return new_size;
}
});
}
export function next_step_possible(current_height: number, factor: number) {
const new_size = current_height + (factor * screen_height_step_size);
return new_size > max_display_screen_height || new_size < min_display_screen_height;
}
export function get_selectable_color_classes(
selected: boolean,
returning_classes: { bg?: boolean; hover?: boolean; active?: boolean; text?: boolean } = {},
base_bg_distance: number = 0,
shifted_distance: number = 0
) {
let base_bg = selected ? 'bg-stone-400' : 'bg-stone-600';
const base_text = selected ? 'text-stone-950' : 'text-stone-200';
base_bg = get_shifted_color(base_bg, base_bg_distance);
const { bg = false, hover = false, active = false, text = false } = returning_classes;
const out: string[] = [];
if (bg) out.push(base_bg);
if (hover) out.push('hover:' + get_shifted_color(base_bg, 100 + shifted_distance));
if (active) out.push('active:' + get_shifted_color(base_bg, 150 + shifted_distance));
if (text) out.push(base_text);
return out.join(' ');
}
export function get_shifted_color(base_color: string, distance: number): string {
return base_color.replace(/(\d+)(?=(?:\/\d+)?$)/, (m: string) => String(+Number(m) - distance));
}
+22
View File
@@ -0,0 +1,22 @@
import type { Component } from "lucide-svelte";
export type Display = {
id: string;
ip: string;
mac: string;
name: string;
status: string;
}
export type DisplayGroup = {
id: string;
data: Display[];
};
export type MenuOption = {
icon?: Component;
name: string;
on_select?: () => void;
disabled?: boolean;
}