From 2168873d3adb15847a6cb08db88378992016f8eb Mon Sep 17 00:00:00 2001
From: E44 <129310925+programmer-44@users.noreply.github.com>
Date: Thu, 6 Nov 2025 11:50:21 +0100
Subject: [PATCH] add control requests, use pings and improve display_status
---
.../src/components/OnlineState.svelte | 14 +++---
control/frontend/src/routes/+page.svelte | 19 ++++++--
control/frontend/src/ts/api_handler.ts | 48 +++++++++++++++----
control/frontend/src/ts/stores/displays.ts | 6 +--
control/frontend/src/ts/types.ts | 23 ++++++++-
5 files changed, 85 insertions(+), 25 deletions(-)
diff --git a/control/frontend/src/components/OnlineState.svelte b/control/frontend/src/components/OnlineState.svelte
index 6487800..b224b7c 100644
--- a/control/frontend/src/components/OnlineState.svelte
+++ b/control/frontend/src/components/OnlineState.svelte
@@ -1,17 +1,19 @@
- {status}
+ {display_status_to_info(status)}
diff --git a/control/frontend/src/routes/+page.svelte b/control/frontend/src/routes/+page.svelte
index 9789314..a39f5de 100644
--- a/control/frontend/src/routes/+page.svelte
+++ b/control/frontend/src/routes/+page.svelte
@@ -6,7 +6,7 @@
import DisplayView from '../components/DisplayView.svelte';
import SplashScreen from './../../../../shared/splash_screen.html?raw';
import PopUp from '../components/PopUp.svelte';
- import type { PopupContent } from '../ts/types';
+ import { display_status_to_info, type PopupContent } from '../ts/types';
import TextInput from '../components/TextInput.svelte';
import {
add_display,
@@ -17,6 +17,8 @@
remove_display
} from '../ts/stores/displays';
import { text } from '@sveltejs/kit';
+ import { notifications } from '../ts/stores/notification';
+ import { ping_ip } from '../ts/api_handler';
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))$/;
@@ -45,14 +47,15 @@
return true;
}
- function finalize_add_edit_display(existing_display_id: string|null) {
+ async function finalize_add_edit_display(existing_display_id: string | null) {
const ip = text_inputs_valid.ip.value;
const mac = text_inputs_valid.mac.value === '' ? null : text_inputs_valid.mac.value;
const name = text_inputs_valid.name.value;
if (!!existing_display_id) {
edit_display_data(existing_display_id, ip, mac, name);
} else {
- add_display(ip, mac, name, 'Online');
+ const status = await ping_ip(text_inputs_valid.ip.value);
+ add_display(ip, mac, name, status);
}
popup_close_function();
}
@@ -153,8 +156,14 @@
className="grow"
/>
- {
+ const status = await ping_ip(text_inputs_valid.ip.value);
+ notifications.push('info', `Ping '${text_inputs_valid.ip.value}'`, `Aktueller Zustand: ${display_status_to_info(status)}`);
+ }}> Ping
diff --git a/control/frontend/src/ts/api_handler.ts b/control/frontend/src/ts/api_handler.ts
index 193996f..831d7b6 100644
--- a/control/frontend/src/ts/api_handler.ts
+++ b/control/frontend/src/ts/api_handler.ts
@@ -1,14 +1,16 @@
-import type { FolderElement } from "./types";
+import { notifications } from "./stores/notification";
+import { to_display_status, type DisplayStatus, type FolderElement } from "./types";
import { get_uuid } from "./utils";
export async function get_screenshot(ip: string) {
const options = { method: 'PATCH' };
- return await request(ip, '/takeScreenshot', options);
+ return await request_display(ip, '/takeScreenshot', options);
}
-export async function open_file(ip: string, path_to_file: string) {
+export async function open_file(ip: string, path_to_file: string): Promise {
const options = { method: 'PATCH', headers: { 'content-type': 'application/octet-stream' } };
- const raw_response = await request(ip, `/file${path_to_file}`, options);
+ const raw_response = await request_display(ip, `/file${path_to_file}`, options);
+ return !!raw_response;
}
export async function get_file_data(ip: string, path: string): Promise {
@@ -34,7 +36,8 @@ export async function get_file_data(ip: string, path: string): Promise {
+ const raw_response = await request_control(`/ping?ip=${ip}`, { method: 'GET' });
+ console.log(raw_request);
+ if (!raw_response) return null;
+ return raw_response.status ? to_display_status(raw_response.status) : null;
+}
-async function request(ip: string, api_route: string, options: { method: string, headers?: Record, body?: any }) {
+
+
+
+async function request_display(ip: string, api_route: string, options: { method: string, headers?: Record, body?: any }): Promise {
+ const url = `http://${ip}:1323/api${api_route}`;
+ return await raw_request(url, options);
+}
+
+async function request_control(api_route: string, options: { method: string, headers?: Record, body?: any }): Promise {
+ const url = `${window.location.origin}/api${api_route}`;
+ return await raw_request(url, options);
+}
+
+
+async function raw_request(url: string, options: { method: string, headers?: Record, body?: any }): Promise {
try {
- const url = `http://${ip}:1323/api${api_route}?t=${Date.now()}`;
- console.log(url)
- const response = await fetch(url, options);
+ const cache_buster = `${url.includes('?') ? '&' : '?'}=${Date.now()}`;
+ console.log(url + cache_buster)
+ const response = await fetch(url + cache_buster, options);
if (!response.ok) {
console.error(`HTTP error! Status: ${response.status}`);
}
@@ -75,9 +98,14 @@ async function request(ip: string, api_route: string, options: { method: string,
if (!contentType.includes("application/json")) {
return await response.blob();
} else {
- return await response.json();
+ const json = await response.json();
+ if (json.error && json.error !== '') {
+ notifications.push("error", `Fehler bei Anfrage '${url}'`, json.error);
+ }
+ return json;
}
} catch (error) {
console.error(error);
+ return null;
}
}
\ No newline at end of file
diff --git a/control/frontend/src/ts/stores/displays.ts b/control/frontend/src/ts/stores/displays.ts
index beffe48..199460e 100644
--- a/control/frontend/src/ts/stores/displays.ts
+++ b/control/frontend/src/ts/stores/displays.ts
@@ -1,5 +1,5 @@
import { get, writable, type Writable } from "svelte/store";
-import type { Display, DisplayGroup } from "../types";
+import type { Display, DisplayGroup, DisplayStatus } from "../types";
import { is_selected, select, selected_display_ids } from "./select";
import { get_uuid, image_content_hash } from "../utils";
import { get_screenshot } from "../api_handler";
@@ -17,7 +17,7 @@ export function is_display_name_taken(name: string): boolean {
);
}
-export function add_display(ip: string, mac: string | null, name: string, status: string) {
+export function add_display(ip: string, mac: string | null, name: string, status: DisplayStatus) {
displays.update((displays: DisplayGroup[]) => {
displays[0].data.push({ id: get_uuid(), ip, preview_url: null, preview_timeout_id: null, mac, name, status });
return displays;
@@ -164,6 +164,6 @@ function add_testing_displays() {
// add_display("127.0.0.1", "00:1A:2B:3C:4D:5E", name, "Offline");
// }
- add_display("127.0.0.1", "00:1A:2B:3C:4D:5E", "PC", "Offline");
+ add_display("127.0.0.1", "00:1A:2B:3C:4D:5E", "PC", "host_offline");
// add_display("192.168.178.111", "D4:81:D7:C0:DF:3C", "Laptop", "Online");
}
\ No newline at end of file
diff --git a/control/frontend/src/ts/types.ts b/control/frontend/src/ts/types.ts
index 0cf2c01..606dd96 100644
--- a/control/frontend/src/ts/types.ts
+++ b/control/frontend/src/ts/types.ts
@@ -63,7 +63,7 @@ export type Display = {
preview_timeout_id: number | null;
mac: string | null;
name: string;
- status: string;
+ status: DisplayStatus;
}
export type DisplayGroup = {
@@ -88,4 +88,25 @@ export type PopupContent = {
title_class?: string;
title_icon?: typeof X | null;
closable?: boolean;
+}
+
+export type DisplayStatus = "host_offline" | "app_offline" | "app_online" | null;
+
+export function to_display_status(value: string): DisplayStatus {
+ return ["host_offline", "app_offline", "app_online"].includes(value)
+ ? (value as DisplayStatus)
+ : null;
+}
+
+export function display_status_to_info(status: DisplayStatus): string {
+ switch (status) {
+ case 'app_online':
+ return 'Online';
+ case 'app_offline':
+ return 'Lädt';
+ case 'host_offline':
+ return 'Offline';
+ case null:
+ return '???';
+ }
}
\ No newline at end of file