diff --git a/control/frontend/src/lib/ts/api_handler.ts b/control/frontend/src/lib/ts/api_handler.ts index 4698403..0f98bcd 100755 --- a/control/frontend/src/lib/ts/api_handler.ts +++ b/control/frontend/src/lib/ts/api_handler.ts @@ -9,6 +9,9 @@ import { } from './types'; import { dev } from '$app/environment'; import { get_sanitized_file_url } from './utils'; +import { online_displays } from './stores/displays'; +import { get } from 'svelte/store'; +import { update_display_status } from './main'; export async function get_screenshot(ip: string): Promise { const options = { method: 'PATCH' }; @@ -188,7 +191,23 @@ async function request_display( supress_error_handling_http_codes: number[] = [] ): Promise { const url = `http://${ip}:1323/api${api_route}`; - return await request(url, options, supress_error_handling_http_codes); + + const current_online_displays = get(online_displays); + if (!current_online_displays.map((d) => d.ip).includes(ip)) return { ok: false }; + + const response = await request(url, options, supress_error_handling_http_codes); + if (!response.ok && response.http_code === 408) { + // Network error -> device possibly not longer online -> test status and throw no error if its offline + const possible_displays = current_online_displays.filter((d) => d.ip === ip); + for (const display of possible_displays) { + const current_status = await update_display_status(display); + if (current_status === 'app_online') { + console.error(`No response from ${url}`) + notifications.push('error', "Netzwerk-Fehler bei API-Anfrage", `${url}`); + } + } + } + return response; } async function request_control( @@ -245,6 +264,7 @@ async function request( if (dev) { console.warn('Request failed - Is the targeted device online?'); } + return { ok: false, http_code: 408 }; } else { console.error(url, error); notifications.push('error', `Fataler Fehler bei API-Anfrage`, `${url}\nFehler: ${error}`); diff --git a/control/frontend/src/lib/ts/main.ts b/control/frontend/src/lib/ts/main.ts index 884ccf3..75a4f43 100755 --- a/control/frontend/src/lib/ts/main.ts +++ b/control/frontend/src/lib/ts/main.ts @@ -1,6 +1,6 @@ import { screenshot_loop } from './stores/displays'; import { ping_ip } from './api_handler'; -import type { Display } from './types'; +import type { Display, DisplayStatus } from './types'; import { update_folder_elements_recursively } from './stores/files'; import { db } from './database'; @@ -37,9 +37,9 @@ async function update_all_display_status(only_loading_displays: boolean) { } } -export async function update_display_status(display: Display) { +export async function update_display_status(display: Display): Promise { const new_status = await ping_ip(display.ip); - if (new_status === null && display.status !== null) return; + if (new_status === null && display.status !== null) return null; if (new_status !== display.status) { // status change if (new_status === 'app_offline') { @@ -53,6 +53,7 @@ export async function update_display_status(display: Display) { display.status = new_status; await db.displays.put(display); // save } + return new_status; } export function remove_display_from_loading_displays(display_id: string) { diff --git a/control/frontend/src/lib/ts/stores/displays.ts b/control/frontend/src/lib/ts/stores/displays.ts index 14c1835..f5887be 100755 --- a/control/frontend/src/lib/ts/stores/displays.ts +++ b/control/frontend/src/lib/ts/stores/displays.ts @@ -14,6 +14,15 @@ import { db } from '../database'; import { dev } from '$app/environment'; import { remove_display_from_loading_displays } from '../main'; import { preview_settings } from './ui_behavior'; +import { liveQuery } from 'dexie'; + +export const online_displays: Writable = writable([]); + +export const online_displays_sub = liveQuery(() => + db.displays.where('status').equals('app_online').toArray() +).subscribe((value) => { + online_displays.set(value); +}); export const local_displays: Writable = writable([]); @@ -204,7 +213,7 @@ export async function update_local_displays() { export async function update_db_displays() { local_displays.update((groups) => groups.filter((g) => g.displays.length !== 0)); - const filtered_local_display_groups = get(local_displays) + const filtered_local_display_groups = get(local_displays); const db_display_group_ids = (await db.display_groups.toArray()).map((group) => group.id); const local_display_group_ids = filtered_local_display_groups.map((group) => group.id); @@ -242,6 +251,16 @@ export function set_new_display_order(display_id_group_id: string, new_data: Dis }); } +export function no_active_display_selected( + selected_display_ids: string[], + online_displays: Display[] +) { + const online_and_selected_displays = online_displays.filter((d) => + selected_display_ids.includes(d.id) + ); + return online_and_selected_displays.length === 0; +} + if (dev) { setTimeout(add_testing_displays, 0); async function add_testing_displays() { diff --git a/control/frontend/src/routes/ControlView.svelte b/control/frontend/src/routes/ControlView.svelte index 34a7340..64f5eec 100644 --- a/control/frontend/src/routes/ControlView.svelte +++ b/control/frontend/src/routes/ControlView.svelte @@ -23,7 +23,12 @@ startup, show_html } from '$lib/ts/api_handler'; - import { get_display_by_id, run_on_all_selected_displays } from '$lib/ts/stores/displays'; + import { + get_display_by_id, + no_active_display_selected, + online_displays, + run_on_all_selected_displays + } from '$lib/ts/stores/displays'; import { selected_display_ids } from '$lib/ts/stores/select'; import TipTapInput from './TipTapInput.svelte'; import { db } from '$lib/ts/database'; @@ -217,7 +222,7 @@ { await send_single_key_press('VK_RIGHT'); }}> Text Anzeigen Text Anzeigen Tastatur-Eingaben Senden @@ -269,7 +275,8 @@
@@ -363,7 +364,7 @@ @@ -387,7 +388,7 @@
- {#if $selected_display_ids.length === 0} + {#if no_active_display_selected($selected_display_ids, $online_displays)} Es sind keine Bildschirme ausgewählt.