Web player general changes #22
@@ -11,6 +11,28 @@
|
|||||||
const idx = player.tracks.findIndex((t) => t.id === player.currentId);
|
const idx = player.tracks.findIndex((t) => t.id === player.currentId);
|
||||||
return idx === -1 ? player.tracks : player.tracks.slice(idx + 1);
|
return idx === -1 ? player.tracks : player.tracks.slice(idx + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let dragFrom = $state<number | null>(null);
|
||||||
|
let dropAt = $state<number | null>(null);
|
||||||
|
|
||||||
|
function onDragOver(event: DragEvent, index: number) {
|
||||||
|
if (dragFrom === null) return;
|
||||||
|
event.preventDefault();
|
||||||
|
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';
|
||||||
|
const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();
|
||||||
|
dropAt = event.clientY < rect.top + rect.height / 2 ? index : index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDrop(event: DragEvent) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (dragFrom !== null && dropAt !== null) player.moveQueueItem(dragFrom, dropAt);
|
||||||
|
endDrag();
|
||||||
|
}
|
||||||
|
|
||||||
|
function endDrag() {
|
||||||
|
dragFrom = null;
|
||||||
|
dropAt = null;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -58,6 +80,27 @@
|
|||||||
<div class="flex flex-1 flex-col gap-px overflow-y-auto">
|
<div class="flex flex-1 flex-col gap-px overflow-y-auto">
|
||||||
{#each upcoming as track, i (track.id)}
|
{#each upcoming as track, i (track.id)}
|
||||||
{@const index = player.tracks.length - upcoming.length + i}
|
{@const index = player.tracks.length - upcoming.length + i}
|
||||||
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
|
<div
|
||||||
|
draggable="true"
|
||||||
|
ondragstart={(event) => {
|
||||||
|
dragFrom = index;
|
||||||
|
if (event.dataTransfer) event.dataTransfer.effectAllowed = 'move';
|
||||||
|
}}
|
||||||
|
ondragover={(event) => onDragOver(event, index)}
|
||||||
|
ondrop={onDrop}
|
||||||
|
ondragend={endDrag}
|
||||||
|
class="relative transition-opacity {dragFrom === index ? 'opacity-40' : ''}"
|
||||||
|
>
|
||||||
|
{#if dropAt === index && dragFrom !== null}
|
||||||
|
<div
|
||||||
|
class="pointer-events-none absolute inset-x-2 top-0 h-0.5 rounded-full bg-accent"
|
||||||
|
></div>
|
||||||
|
{:else if dropAt === index + 1 && dropAt === player.tracks.length && dragFrom !== null}
|
||||||
|
<div
|
||||||
|
class="pointer-events-none absolute inset-x-2 bottom-0 h-0.5 rounded-full bg-accent"
|
||||||
|
></div>
|
||||||
|
{/if}
|
||||||
<ListRow
|
<ListRow
|
||||||
onclick={() => player.playQueueIndex(index)}
|
onclick={() => player.playQueueIndex(index)}
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -69,10 +112,13 @@
|
|||||||
>
|
>
|
||||||
{#snippet trailing()}
|
{#snippet trailing()}
|
||||||
{#if track.duration}
|
{#if track.duration}
|
||||||
<span class="shrink-0 text-xs text-fg-2 tabular-nums">{fmtTime(track.duration)}</span>
|
<span class="shrink-0 text-xs text-fg-2 tabular-nums"
|
||||||
|
>{fmtTime(track.duration)}</span
|
||||||
|
>
|
||||||
{/if}
|
{/if}
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</ListRow>
|
</ListRow>
|
||||||
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="px-2 py-6 text-center text-xs text-fg-2">No hay más canciones en la cola.</p>
|
<p class="px-2 py-6 text-center text-xs text-fg-2">No hay más canciones en la cola.</p>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -456,6 +456,16 @@ class PlayerState {
|
|||||||
this.#loadCurrent();
|
this.#loadCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveQueueItem(from: number, insertAt: number) {
|
||||||
|
if (from < 0 || from >= this.tracks.length) return;
|
||||||
|
const target = insertAt > from ? insertAt - 1 : insertAt;
|
||||||
|
if (target === from) return;
|
||||||
|
const tracks = [...this.tracks];
|
||||||
|
const [item] = tracks.splice(from, 1);
|
||||||
|
tracks.splice(target, 0, item);
|
||||||
|
this.tracks = tracks;
|
||||||
|
}
|
||||||
|
|
||||||
clearUpcoming() {
|
clearUpcoming() {
|
||||||
this.tracks = this.currentId === null ? [] : [this.current];
|
this.tracks = this.currentId === null ? [] : [this.current];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user