mirror of
https://codeberg.org/PLG-Development/PLG-MuDiCS
synced 2026-07-05 16:37:09 +00:00
@@ -0,0 +1,176 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { add_upload } from '$lib/ts/file_transfer_handler';
|
||||||
|
import { selected_online_display_ids } from '$lib/ts/stores/displays';
|
||||||
|
import { current_file_path } from '$lib/ts/stores/files';
|
||||||
|
import HighlightedText from './HighlightedText.svelte';
|
||||||
|
|
||||||
|
let { className } = $props();
|
||||||
|
|
||||||
|
let drop_zone: HTMLDivElement | undefined;
|
||||||
|
|
||||||
|
let is_dragging = $state(false);
|
||||||
|
let is_dragging_over_drop_zone = $state(false);
|
||||||
|
let is_dragging_multiple_files = $state(false);
|
||||||
|
|
||||||
|
let drag_counter = 0;
|
||||||
|
|
||||||
|
function contains_files(event: DragEvent): boolean {
|
||||||
|
return Array.from(event.dataTransfer?.types ?? []).includes('Files');
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset_drag_vars(): void {
|
||||||
|
drag_counter = 0;
|
||||||
|
is_dragging = false;
|
||||||
|
is_dragging_over_drop_zone = false;
|
||||||
|
is_dragging_multiple_files = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_inside_drop_zone(event: DragEvent): boolean {
|
||||||
|
if (!drop_zone) return false;
|
||||||
|
|
||||||
|
const rect = drop_zone.getBoundingClientRect();
|
||||||
|
|
||||||
|
return (
|
||||||
|
event.clientX >= rect.left &&
|
||||||
|
event.clientX <= rect.right &&
|
||||||
|
event.clientY >= rect.top &&
|
||||||
|
event.clientY <= rect.bottom
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_window_drag_enter(event: DragEvent): void {
|
||||||
|
if (!contains_files(event)) return;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
drag_counter += 1;
|
||||||
|
is_dragging = true;
|
||||||
|
is_dragging_multiple_files =
|
||||||
|
(event.dataTransfer?.items.length ?? 0) > 1;
|
||||||
|
|
||||||
|
if (event.dataTransfer) {
|
||||||
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_window_drag_over(event: DragEvent): void {
|
||||||
|
if (!contains_files(event)) return;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
is_dragging = true;
|
||||||
|
is_dragging_multiple_files =
|
||||||
|
(event.dataTransfer?.items.length ?? 0) > 1;
|
||||||
|
|
||||||
|
is_dragging_over_drop_zone =
|
||||||
|
$selected_online_display_ids.length > 0 &&
|
||||||
|
is_inside_drop_zone(event);
|
||||||
|
|
||||||
|
if (event.dataTransfer) {
|
||||||
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_window_drag_leave(event: DragEvent): void {
|
||||||
|
if (!contains_files(event) && !is_dragging) return;
|
||||||
|
|
||||||
|
drag_counter = Math.max(0, drag_counter - 1);
|
||||||
|
|
||||||
|
if (drag_counter === 0) {
|
||||||
|
reset_drag_vars();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_window_drop_capture(event: DragEvent): void {
|
||||||
|
if (!contains_files(event)) return;
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_window_drop(event: DragEvent): void {
|
||||||
|
if (!contains_files(event)) return;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
reset_drag_vars();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handle_drop_zone_drop(
|
||||||
|
event: DragEvent
|
||||||
|
): Promise<void> {
|
||||||
|
if (!contains_files(event)) return;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
const may_import =
|
||||||
|
$selected_online_display_ids.length > 0 &&
|
||||||
|
is_inside_drop_zone(event);
|
||||||
|
|
||||||
|
const items = Array.from(event.dataTransfer?.items ?? []);
|
||||||
|
|
||||||
|
reset_drag_vars();
|
||||||
|
|
||||||
|
if (!may_import) return;
|
||||||
|
|
||||||
|
const transfer = new DataTransfer();
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.kind !== 'file') continue;
|
||||||
|
|
||||||
|
const file = item.getAsFile();
|
||||||
|
const entry = item.webkitGetAsEntry?.();
|
||||||
|
|
||||||
|
if (file && (!entry || entry.isFile)) {
|
||||||
|
transfer.items.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transfer.files.length === 0) return;
|
||||||
|
|
||||||
|
await add_upload(
|
||||||
|
transfer.files,
|
||||||
|
$selected_online_display_ids,
|
||||||
|
$current_file_path
|
||||||
|
);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:window
|
||||||
|
ondragenter={handle_window_drag_enter}
|
||||||
|
ondragover={handle_window_drag_over}
|
||||||
|
ondragleave={handle_window_drag_leave}
|
||||||
|
ondrop={handle_window_drop}
|
||||||
|
ondropcapture={handle_window_drop_capture}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="fixed {is_dragging
|
||||||
|
? 'bg-black/50 opacity-100'
|
||||||
|
: 'opacity-0'} pointer-events-none p-10 z-1000 inset-0 transition-all duration-100 flex items-center justify-center text-xl text-white font-bold select-none"
|
||||||
|
>
|
||||||
|
{$selected_online_display_ids.length === 0
|
||||||
|
? 'Für das Hochladen von Dateien müssen erreichbare Displays ausgewählt werden!'
|
||||||
|
: ''}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={drop_zone}
|
||||||
|
aria-hidden="true"
|
||||||
|
ondrop={handle_drop_zone_drop}
|
||||||
|
class="{className} absolute p-6 inset-0 flex z-1001 justify-center items-center transition-all duration-200 {$selected_online_display_ids.length >
|
||||||
|
0 && is_dragging
|
||||||
|
? 'opacity-100'
|
||||||
|
: 'opacity-0 pointer-events-none'} {is_dragging_over_drop_zone
|
||||||
|
? 'bg-stone-500'
|
||||||
|
: 'bg-stone-700'}"
|
||||||
|
>
|
||||||
|
<p class="text-lg pointer-events-none">
|
||||||
|
Hier {is_dragging_multiple_files ? 'Dateien' : 'Datei'} ablegen, um sie auf {$selected_online_display_ids.length ===
|
||||||
|
1
|
||||||
|
? 'dem ausgewählten Display'
|
||||||
|
: 'den ausgewählten Displays'} in den Pfad <HighlightedText
|
||||||
|
className="transition-colors duration-200"
|
||||||
|
bg={is_dragging_over_drop_zone ? 'bg-stone-550' : 'bg-stone-750'}
|
||||||
|
>{$current_file_path}</HighlightedText
|
||||||
|
> hochzuladen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
import { liveQuery, type Observable } from 'dexie';
|
import { liveQuery, type Observable } from 'dexie';
|
||||||
import { download_file, add_upload, add_sync_recursively } from '$lib/ts/file_transfer_handler';
|
import { download_file, add_upload, add_sync_recursively } from '$lib/ts/file_transfer_handler';
|
||||||
import { selected_online_display_ids } from '$lib/ts/stores/displays';
|
import { selected_online_display_ids } from '$lib/ts/stores/displays';
|
||||||
|
import FileDropZone from '$lib/components/FileDropZone.svelte';
|
||||||
|
|
||||||
let current_name: string = $state('');
|
let current_name: string = $state('');
|
||||||
let current_valid: boolean = $state(false);
|
let current_valid: boolean = $state(false);
|
||||||
@@ -59,7 +60,7 @@
|
|||||||
$effect(() => {
|
$effect(() => {
|
||||||
const s = $selected_file_ids;
|
const s = $selected_file_ids;
|
||||||
one_file_selected = liveQuery(async () => {
|
one_file_selected = liveQuery(async () => {
|
||||||
if (s.length !== 1) return false
|
if (s.length !== 1) return false;
|
||||||
const inode = await get_file_by_id(s[0]);
|
const inode = await get_file_by_id(s[0]);
|
||||||
if (!inode) return false;
|
if (!inode) return false;
|
||||||
return !is_folder(inode);
|
return !is_folder(inode);
|
||||||
@@ -285,7 +286,7 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="bg-stone-800 h-full rounded-2xl grid grid-rows-[2.5rem_1fr] min-h-0">
|
<div class="bg-stone-800 size-full rounded-2xl grid grid-rows-[2.5rem_1fr] min-h-0">
|
||||||
<div class="bg-stone-700 flex justify-between w-full p-1 rounded-t-2xl min-w-0 gap-2">
|
<div class="bg-stone-700 flex justify-between w-full p-1 rounded-t-2xl min-w-0 gap-2">
|
||||||
<span class="text-xl font-bold pl-2 content-center truncate min-w-0">
|
<span class="text-xl font-bold pl-2 content-center truncate min-w-0">
|
||||||
Dateien Anzeigen und Verwalten
|
Dateien Anzeigen und Verwalten
|
||||||
@@ -388,32 +389,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-h-0 h-full overflow-y-auto overflow-x-hidden bg-stone-750 rounded-xl">
|
|
||||||
<div class="flex flex-col gap-2 p-2 min-h-0 max-w-full">
|
<div class="min-h-0 size-full overflow-y-auto overflow-x-hidden bg-stone-750 rounded-xl relative">
|
||||||
{#if $selected_online_display_ids.length === 0}
|
<FileDropZone className="rounded-xl size-full"/>
|
||||||
<span class="text-stone-450 px-10 py-6 leading-relaxed text-center">
|
<div class="flex flex-col gap-2 p-2 min-h-0 max-w-full">
|
||||||
Es sind keine Bildschirme ausgewählt.
|
{#if $selected_online_display_ids.length === 0}
|
||||||
</span>
|
<span class="text-stone-450 px-10 py-6 leading-relaxed text-center">
|
||||||
{:else}
|
Es sind keine Bildschirme ausgewählt.
|
||||||
{#each $current_folder_elements ?? [] as folder_element (get_file_primary_key(folder_element))}
|
|
||||||
<section in:slide={{ duration: 100 }} class="outline-none">
|
|
||||||
<InodeElement file={folder_element} />
|
|
||||||
</section>
|
|
||||||
{/each}
|
|
||||||
{#if ($current_folder_elements ?? []).length === 0}
|
|
||||||
<span class="text-stone-450 px-10 py-6 leading-relaxed text-center max-w-full">
|
|
||||||
Es existieren keine Dateien auf {$selected_display_ids.length === 1
|
|
||||||
? 'dem ausgewähltem Bildchirm'
|
|
||||||
: 'den ausgewählten Bildschirmen'} im aktuellen Ordner. Klicke auf <HighlightedText
|
|
||||||
bg="bg-stone-700"
|
|
||||||
fg="text-stone-400"
|
|
||||||
className="p-1!"><Upload class="inline pb-1" /></HighlightedText
|
|
||||||
> um Datei(en) hochzuladen.
|
|
||||||
</span>
|
</span>
|
||||||
|
{:else}
|
||||||
|
{#each $current_folder_elements ?? [] as folder_element (get_file_primary_key(folder_element))}
|
||||||
|
<section in:slide={{ duration: 100 }} class="outline-none">
|
||||||
|
<InodeElement file={folder_element} />
|
||||||
|
</section>
|
||||||
|
{/each}
|
||||||
|
{#if ($current_folder_elements ?? []).length === 0}
|
||||||
|
<span class="text-stone-450 px-10 py-6 leading-relaxed text-center max-w-full">
|
||||||
|
Es existieren keine Dateien auf {$selected_display_ids.length === 1
|
||||||
|
? 'dem ausgewähltem Bildchirm'
|
||||||
|
: 'den ausgewählten Bildschirmen'} im aktuellen Ordner. Klicke auf <HighlightedText
|
||||||
|
bg="bg-stone-700"
|
||||||
|
fg="text-stone-400"
|
||||||
|
className="p-1!"><Upload class="inline pb-1" /></HighlightedText
|
||||||
|
> um Datei(en) hochzuladen.
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<PopUp
|
<PopUp
|
||||||
content={popup_content}
|
content={popup_content}
|
||||||
close_function={popup_close_function}
|
close_function={popup_close_function}
|
||||||
|
|||||||
Reference in New Issue
Block a user