@@ -203,7 +216,7 @@
is_selected(file.id, $selected_file_ids)
)} duration-200 transition-colors"
>
- {#if get_display_ids_where_file_is_missing($current_file_path, file, $selected_display_ids, $all_files)[1].length !== 0}
+
{
+export async function get_file_data(ip: string, path: string): Promise {
interface FileInfo {
name: string;
type: string;
@@ -44,25 +44,20 @@ export async function get_file_data(ip: string, path: string): Promise {
- const options = {
- method: 'PATCH',
- headers: { 'content-type': 'application/json' },
- body: JSON.stringify({
- command: `cd ".${path}" && tree -Js`
- })
- };
- const raw_response = await request_display(ip, '/shellCommand', options);
+ const raw_response = await run_shell_command(ip, `cd ".${path}" && tree -Js`);
if (!raw_response.ok || !raw_response.json) return null;
const json_response = raw_response.json as ShellCommandResponse;
@@ -110,6 +98,25 @@ export async function get_file_tree_data(ip: string, path: string): Promise {
+ let command = `cd ".${path}"`;
+
+ for (const part of folder_names) {
+ command += `&& mkdir "${part}" && cd "${part}/"`;
+ }
+
+ await run_shell_command(ip, command);
+}
+
+export async function delete_files(ip: string, current_path: string, file_names: string[]) {
+ let del_string: string = '';
+ for (const file_name of file_names) {
+ del_string += `&& rm -r "${file_name}"`;
+ }
+ await run_shell_command(ip, `cd ".${current_path}" ${del_string}`);
+
+}
+
export async function show_blackscreen(ip: string): Promise {
const options = {
@@ -122,19 +129,17 @@ export async function show_blackscreen(ip: string): Promise {
await request_display(ip, '/showHTML', options);
}
-
-export async function ping_ip(ip: string): Promise {
- const raw_response = await request_control(`/ping?ip=${ip}`, { method: 'GET' });
- if (!raw_response.ok || !raw_response.json) return null;
- return raw_response.json.status ? to_display_status(raw_response.json.status) : null;
-}
-
export async function get_thumbnail_blob(ip: string, path_to_file: string): Promise {
const raw_response = await request_display(ip, `/file/preview${path_to_file}`, { method: 'GET' }, [415]);
if (!raw_response.ok || !raw_response.blob) return null
return raw_response.blob;
}
+export async function ping_ip(ip: string): Promise {
+ const raw_response = await request_control(`/ping?ip=${ip}`, { method: 'GET' });
+ if (!raw_response.ok || !raw_response.json) return null;
+ return raw_response.json.status ? to_display_status(raw_response.json.status) : null;
+}
@@ -203,4 +208,15 @@ function is_cd_directory_error(ip: string, shell_response: ShellCommandResponse)
}
if (shell_response.stdout.trim() === '') return true;
return false;
+}
+
+async function run_shell_command(ip: string, command: string): Promise {
+ const options = {
+ method: 'PATCH',
+ headers: { 'content-type': 'application/json' },
+ body: JSON.stringify({
+ command: command
+ })
+ };
+ return await request_display(ip, '/shellCommand', options);
}
\ No newline at end of file
diff --git a/control/frontend/src/ts/stores/files.ts b/control/frontend/src/ts/stores/files.ts
index 41f7777..f9e3c17 100644
--- a/control/frontend/src/ts/stores/files.ts
+++ b/control/frontend/src/ts/stores/files.ts
@@ -1,7 +1,7 @@
import { get, writable, type Writable } from "svelte/store";
import type { Display, FolderElement, TreeElement } from "../types";
-import { displays } from "./displays";
-import { selected_file_ids } from "./select";
+import { displays, get_display_by_id } from "./displays";
+import { selected_display_ids, selected_file_ids } from "./select";
import { get_file_data, get_file_tree_data } from "../api_handler";
import { notifications } from "./notification";
import { CirclePoundSterling } from "lucide-svelte";
@@ -45,8 +45,17 @@ export async function change_file_path(new_path: string) {
}
}
+export async function update_current_folder_on_selected_displays() {
+ const current_path = get(current_file_path);
+ for (const display_id of get(selected_display_ids)) {
+ const display = get_display_by_id(display_id, get(displays));
+ if (!display) continue;
+ update_folder_elements_recursively(display, current_path);
+ }
+}
+
export function get_display_ids_where_file_is_missing(path: string, file: FolderElement, selected_display_ids: string[], all_files: Record>): string[][] {
- if (!all_files.hasOwnProperty(path)) return [];
+ if (!all_files.hasOwnProperty(path)) return [selected_display_ids, []];
const missing: string[] = [];
const colliding: string[] = [];
Display:
@@ -68,6 +77,17 @@ export function get_display_ids_where_file_is_missing(path: string, file: Folder
return [missing, colliding];
}
+export function get_display_ids_where_path_does_not_exist(path: string, selected_display_ids: string[], all_files: Record>): string[] {
+ if (!all_files.hasOwnProperty(path)) return selected_display_ids;
+ const out: string[] = [];
+ for (const selected_display_id of selected_display_ids) {
+ if (!all_files[path].hasOwnProperty(selected_display_id)) {
+ out.push(selected_display_id);
+ }
+ }
+ return out;
+}
+
async function get_changed_directory_paths(display: Display, file_path: string): Promise {
const current_folder = await get_file_tree_data(display.ip, file_path);
if (current_folder === null) return [file_path];
@@ -103,6 +123,7 @@ function get_recursive_changed_directory_paths(display: Display, current_file_pa
export async function update_folder_elements_recursively(display: Display, file_path: string = '/'): Promise {
const new_folder_elements = await get_file_data(display.ip, file_path);
+ if (new_folder_elements === null) return 0;
all_files.update((files: Record>) => {
if (!files.hasOwnProperty(file_path)) {
files[file_path] = {};
@@ -223,8 +244,54 @@ function sort_files(files: FolderElement[]) {
if (nameCompare !== 0) return nameCompare;
// Wenn name gleich, absteigend nach date_created
+ if (!b.date_created || !a.date_created) return -1;
return b.date_created.getTime() - a.date_created.getTime();
});
return files;
}
+export function get_file_from_id(file_id: string, all_files: Record>, current_file_path: string): FolderElement | null {
+ const current_path_elements: Record | undefined = all_files[current_file_path];
+ if (!current_path_elements) return null;
+ const all_folder_elements = Object.values(current_path_elements).flat();
+ const found = all_folder_elements.find(el => el.id === file_id);
+ if (!found) return null;
+ return found
+}
+
+export async function run_for_selected_files_on_selected_displays(action: (ip: string, file_names: string[]) => Promise): Promise {
+ const files = get(all_files);
+ const file_path = get(current_file_path);
+ const folder_element_hashs: string[] = get(selected_file_ids)
+ .map((file_id) => get_file_from_id(file_id, files, file_path))
+ .filter((element) => element !== null)
+ .map((folder_element) => folder_element.hash)
+ .filter((hash) => hash !== null);
+
+ for (const display_id of get(selected_display_ids)) {
+ if (!files[file_path].hasOwnProperty(display_id)) continue;
+ const files_on_display = files[file_path][display_id];
+
+ const selected_file_names_on_display: string[] = files_on_display.filter((e) => e.hash && folder_element_hashs.includes(e.hash)).map((folder_element) => folder_element.name);
+ if (selected_file_names_on_display.length === 0) continue;
+
+ const display = get_display_by_id(display_id, get(displays));
+ if (!display) continue
+
+ await action(display.ip, selected_file_names_on_display);
+ }
+
+}
+
+export function get_longest_existing_path_and_needed_parts(path: string, display_id: string, all_files: Record>): { existing: string; needed: string[] } {
+ const path_parts = path.slice(0, path.length - 1).split('/');
+ for (let i = path_parts.length; i > 1; i--) {
+ const current_path = [...path_parts].splice(0, i).join('/') + '/';;
+ if (all_files.hasOwnProperty(current_path)) {
+ if (all_files[current_path].hasOwnProperty(display_id)) {
+ return { existing: current_path, needed: [...path_parts].splice(i) };
+ }
+ }
+ }
+ return { existing: '/', needed: path_parts };
+}
\ No newline at end of file