Files
gpx.studio/website/src/lib/components/file-list/FileListNodeContent.svelte

144 lines
4.1 KiB
Svelte
Raw Normal View History

2024-05-17 15:02:45 +02:00
<script lang="ts">
2024-09-12 11:13:55 +02:00
import { GPXFile, Track, Waypoint, type AnyGPXTreeElement, type GPXTreeElement } from 'gpx';
2025-10-17 23:54:45 +02:00
import { getContext, onDestroy, onMount } from 'svelte';
2025-10-26 12:12:23 +01:00
import { type Readable } from 'svelte/store';
2024-09-12 11:13:55 +02:00
import FileListNodeStore from './FileListNodeStore.svelte';
import FileListNode from './FileListNode.svelte';
2025-10-26 12:12:23 +01:00
import FileListNodeContent from './FileListNodeContent.svelte';
import { ListFileItem, ListLevel, ListWaypointsItem, type ListItem } from './file-list';
2025-10-18 00:31:14 +02:00
import type { GPXFileWithStatistics } from '$lib/logic/statistics-tree';
2025-10-26 12:12:23 +01:00
import { allowedMoves, dragging, SortableFileList } from './sortable-file-list';
2025-10-17 23:54:45 +02:00
let {
node,
item,
waypointRoot = false,
}: {
node:
| Map<string, Readable<GPXFileWithStatistics | undefined>>
| GPXTreeElement<AnyGPXTreeElement>
2025-10-26 12:12:23 +01:00
| Waypoint[]
2025-10-17 23:54:45 +02:00
| Waypoint;
item: ListItem;
waypointRoot?: boolean;
} = $props();
2024-09-12 11:13:55 +02:00
let container: HTMLElement;
let sortableLevel: ListLevel =
node instanceof Map
? ListLevel.FILE
: node instanceof GPXFile
? waypointRoot
? ListLevel.WAYPOINTS
: item instanceof ListWaypointsItem
? ListLevel.WAYPOINT
: ListLevel.TRACK
: node instanceof Track
? ListLevel.SEGMENT
: ListLevel.WAYPOINT;
let orientation = getContext<'vertical' | 'horizontal'>('orientation');
2025-10-26 12:12:23 +01:00
let canDrop = $derived($dragging !== null && allowedMoves[$dragging].includes(sortableLevel));
2024-09-12 11:13:55 +02:00
2025-10-26 12:12:23 +01:00
let sortable: SortableFileList;
2024-09-12 11:13:55 +02:00
onMount(() => {
2025-10-26 12:12:23 +01:00
sortable = new SortableFileList(
container,
node,
item,
waypointRoot,
sortableLevel,
orientation
);
2024-09-12 11:13:55 +02:00
});
2025-11-02 16:01:17 +01:00
$effect(() => {
if (sortable) {
sortable.updateElements();
}
});
2024-09-12 11:13:55 +02:00
onDestroy(() => {
2025-10-26 12:12:23 +01:00
sortable.destroy();
2024-09-12 11:13:55 +02:00
});
2024-05-17 15:02:45 +02:00
</script>
<div
2024-09-12 11:13:55 +02:00
bind:this={container}
class="sortable {orientation} flex {orientation === 'vertical'
? 'flex-col'
: 'flex-row gap-1'} {canDrop ? 'min-h-5' : ''}"
>
2024-09-12 11:13:55 +02:00
{#if node instanceof Map}
{#each node as [fileId, file] (fileId)}
<div data-id={fileId}>
<FileListNodeStore {file} />
</div>
{/each}
{:else if node instanceof GPXFile}
{#if item instanceof ListWaypointsItem}
{#each node.wpt as wpt, i (wpt)}
<div data-id={i} class="ml-1">
<FileListNode node={wpt} item={item.extend(i)} />
</div>
{/each}
{:else if waypointRoot}
{#if node.wpt.length > 0}
<div data-id="waypoints">
<FileListNode {node} item={item.extend('waypoints')} />
</div>
{/if}
{:else}
{#each node.children as child, i (child)}
<div data-id={i}>
<FileListNode node={child} item={item.extend(i)} />
</div>
{/each}
{/if}
{:else if node instanceof Track}
{#each node.children as child, i (child)}
<div data-id={i} class="ml-1">
<FileListNode node={child} item={item.extend(i)} />
</div>
{/each}
{/if}
2024-05-17 15:02:45 +02:00
</div>
2024-07-02 20:04:17 +02:00
{#if node instanceof GPXFile && item instanceof ListFileItem}
2024-09-12 11:13:55 +02:00
{#if !waypointRoot}
2025-10-26 12:12:23 +01:00
<FileListNodeContent {node} {item} waypointRoot={true} />
2024-09-12 11:13:55 +02:00
{/if}
2024-05-21 13:22:14 +02:00
{/if}
2024-05-17 15:02:45 +02:00
<style lang="postcss">
2025-06-21 21:07:36 +02:00
@reference "../../../app.css";
2024-09-12 11:13:55 +02:00
.sortable > div {
@apply rounded-md;
@apply h-fit;
@apply leading-none;
}
.vertical :global(button) {
@apply hover:bg-muted;
}
.vertical :global(.sortable-selected button) {
@apply hover:bg-accent;
}
.vertical :global(.sortable-selected) {
@apply bg-accent;
}
.horizontal :global(button) {
@apply bg-accent;
@apply hover:bg-muted;
}
.horizontal :global(.sortable-selected button) {
@apply bg-background;
}
2024-05-17 15:02:45 +02:00
</style>