Changes
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { toQueueItems, type ApiTrackLike, type QueueItem } from '$lib/player/player.svelte';
|
||||
|
||||
interface YouTubeAlbumTracksResponse {
|
||||
album: { artist: string; thumbnailUrl: string };
|
||||
tracks: { videoId: string; title: string; isExplicit: boolean }[];
|
||||
}
|
||||
|
||||
export async function fetchAlbumQueueItems(
|
||||
kind: 'local' | 'youtube',
|
||||
albumId: string
|
||||
): Promise<QueueItem[]> {
|
||||
if (kind === 'local') {
|
||||
const res = await fetch(`/api/albums/${albumId}/tracks`);
|
||||
if (!res.ok) return [];
|
||||
const data = (await res.json()) as { items: ApiTrackLike[] };
|
||||
return toQueueItems(data.items ?? []);
|
||||
}
|
||||
|
||||
const res = await fetch(`/api/albums/youtube/${albumId}/tracks`);
|
||||
if (!res.ok) return [];
|
||||
const detail = (await res.json()) as YouTubeAlbumTracksResponse;
|
||||
return detail.tracks.map((track) => ({
|
||||
id: track.videoId,
|
||||
title: track.title,
|
||||
artist: detail.album.artist,
|
||||
source: 'youtube' as const,
|
||||
coverUrl: detail.album.thumbnailUrl,
|
||||
explicit: track.isExplicit
|
||||
}));
|
||||
}
|
||||
@@ -25,15 +25,19 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||
import ListPlus from '@lucide/svelte/icons/list-plus';
|
||||
import ListEnd from '@lucide/svelte/icons/list-end';
|
||||
import PlaylistArt from '$lib/components/ui/PlaylistArt.svelte';
|
||||
|
||||
interface Props {
|
||||
menu: AlbumMenuState;
|
||||
playlists: { id: string; name: string }[];
|
||||
onClose: () => void;
|
||||
onPlayNext: () => void;
|
||||
onAddToQueue: () => void;
|
||||
}
|
||||
|
||||
let { menu, playlists, onClose }: Props = $props();
|
||||
let { menu, playlists, onClose, onPlayNext, onAddToQueue }: Props = $props();
|
||||
|
||||
function onWindowKeydown(event: KeyboardEvent) {
|
||||
if (event.key === 'Escape') onClose();
|
||||
@@ -55,6 +59,22 @@
|
||||
class="fixed z-40 w-60 rounded-panel border border-line bg-elevated p-1.5 shadow-menu"
|
||||
style="left:{menu.x}px; top:{menu.y}px;"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onclick={onPlayNext}
|
||||
class="flex w-full items-center gap-3 rounded-control px-2 py-2.5 text-left text-sm text-fg-2 transition hover:bg-hover"
|
||||
>
|
||||
<ListPlus class="h-5 w-5 shrink-0" strokeWidth={2} />
|
||||
<span class="text-base">Reproducir a continuación</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onclick={onAddToQueue}
|
||||
class="flex w-full items-center gap-3 rounded-control px-2 py-2.5 text-left text-sm text-fg-2 transition hover:bg-hover"
|
||||
>
|
||||
<ListEnd class="h-5 w-5 shrink-0" strokeWidth={2} />
|
||||
<span class="text-base">Añadir a la cola</span>
|
||||
</button>
|
||||
{#if playlists.length > 0}
|
||||
<div class="group/addmenu relative">
|
||||
<div
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
: ''}"
|
||||
></div>
|
||||
<div
|
||||
class="pointer-events-none absolute inset-0 bg-scrim/25 opacity-0 transition-opacity duration-300 group-hover/tile:opacity-100"
|
||||
class="pointer-events-none absolute inset-0 bg-scrim/25 opacity-0 transition-opacity duration-300"
|
||||
></div>
|
||||
<div
|
||||
class="relative flex h-full flex-col justify-end p-3 sm:p-4 {banner
|
||||
|
||||
@@ -342,15 +342,29 @@ class PlayerState {
|
||||
}
|
||||
|
||||
addToQueue(item: QueueItem) {
|
||||
this.playNext([item]);
|
||||
}
|
||||
|
||||
playNext(items: QueueItem[]) {
|
||||
if (items.length === 0) return;
|
||||
if (this.currentId === null) {
|
||||
this.playQueue([item], 0);
|
||||
this.playQueue(items, 0);
|
||||
return;
|
||||
}
|
||||
const tracks = [...this.tracks];
|
||||
tracks.splice(this.#index() + 1, 0, toTrack(item));
|
||||
tracks.splice(this.#index() + 1, 0, ...items.map(toTrack));
|
||||
this.tracks = tracks;
|
||||
}
|
||||
|
||||
appendToQueue(items: QueueItem[]) {
|
||||
if (items.length === 0) return;
|
||||
if (this.currentId === null) {
|
||||
this.playQueue(items, 0);
|
||||
return;
|
||||
}
|
||||
this.tracks = [...this.tracks, ...items.map(toTrack)];
|
||||
}
|
||||
|
||||
playTrack(id: string | number) {
|
||||
if (this.currentId === id) {
|
||||
this.toggle();
|
||||
|
||||
Reference in New Issue
Block a user