refactor(web-player): drop the quick mixes shelf
The server-generated mixes cover the same ground and pick better songs, so the two shuffle-what-is-on-screen cards are redundant.
This commit is contained in:
@@ -14,7 +14,6 @@
|
|||||||
} from '$lib/tracks';
|
} from '$lib/tracks';
|
||||||
import { hueFor } from '$lib/theme/color';
|
import { hueFor } from '$lib/theme/color';
|
||||||
import Cover from '$lib/components/ui/Cover.svelte';
|
import Cover from '$lib/components/ui/Cover.svelte';
|
||||||
import PlaylistArt from '$lib/components/ui/PlaylistArt.svelte';
|
|
||||||
import PlaylistCard from '$lib/components/ui/PlaylistCard.svelte';
|
import PlaylistCard from '$lib/components/ui/PlaylistCard.svelte';
|
||||||
import MixCard from '$lib/components/ui/MixCard.svelte';
|
import MixCard from '$lib/components/ui/MixCard.svelte';
|
||||||
import AlbumCard from '$lib/components/ui/AlbumCard.svelte';
|
import AlbumCard from '$lib/components/ui/AlbumCard.svelte';
|
||||||
@@ -31,7 +30,7 @@
|
|||||||
type ContextMenuState
|
type ContextMenuState
|
||||||
} from '$lib/components/TrackContextMenu.svelte';
|
} from '$lib/components/TrackContextMenu.svelte';
|
||||||
import type { YouTubeSong } from '$lib/types';
|
import type { YouTubeSong } from '$lib/types';
|
||||||
import { appendUnique, shuffle } from '$lib/collections';
|
import { appendUnique } from '$lib/collections';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
@@ -116,51 +115,6 @@
|
|||||||
player.playOrToggle(latest.map(queueItemForTarget), index);
|
player.playOrToggle(latest.map(queueItemForTarget), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function playShuffledLocal() {
|
|
||||||
if (localLatest.length === 0) return;
|
|
||||||
player.playQueue(shuffle(localLatest).map(queueItemForTarget), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function playShuffledYoutube() {
|
|
||||||
if (youtubeFillerItems.length === 0) return;
|
|
||||||
const targets = youtubeFillerItems.map((song) => ({ kind: 'youtube' as const, song }));
|
|
||||||
player.playQueue(shuffle(targets).map(queueItemForTarget), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QuickMix {
|
|
||||||
key: string;
|
|
||||||
title: string;
|
|
||||||
subtitle: string;
|
|
||||||
coverIds?: (string | number)[];
|
|
||||||
coverSongs?: YouTubeSong[];
|
|
||||||
onClick: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const quickMixes = $derived<QuickMix[]>(
|
|
||||||
(
|
|
||||||
[
|
|
||||||
localLatest.length > 0
|
|
||||||
? {
|
|
||||||
key: 'local',
|
|
||||||
title: 'Mezcla Musify',
|
|
||||||
subtitle: `${localLatest.length} ${localLatest.length === 1 ? 'canción' : 'canciones'}`,
|
|
||||||
coverIds: localLatest.map((item) => targetId(item)),
|
|
||||||
onClick: playShuffledLocal
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
youtubeFillerItems.length > 0
|
|
||||||
? {
|
|
||||||
key: 'youtube',
|
|
||||||
title: 'Mezcla YouTube Music',
|
|
||||||
subtitle: `${youtubeFillerItems.length} ${youtubeFillerItems.length === 1 ? 'canción' : 'canciones'}`,
|
|
||||||
coverSongs: youtubeFillerItems.slice(0, 4),
|
|
||||||
onClick: playShuffledYoutube
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
] as (QuickMix | null)[]
|
|
||||||
).filter((mix): mix is QuickMix => mix !== null)
|
|
||||||
);
|
|
||||||
|
|
||||||
function openContextMenu(event: MouseEvent, target: TrackTarget) {
|
function openContextMenu(event: MouseEvent, target: TrackTarget) {
|
||||||
contextMenu = contextMenuStateFor(event, target);
|
contextMenu = contextMenuStateFor(event, target);
|
||||||
}
|
}
|
||||||
@@ -273,46 +227,6 @@
|
|||||||
</section>
|
</section>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if quickMixes.length > 0}
|
|
||||||
<section class="page-x pt-5 pb-3 sm:pt-6">
|
|
||||||
<SectionHeading title="Mezclas rápidas" />
|
|
||||||
<MediaGrid>
|
|
||||||
{#each quickMixes as mix, i (mix.key)}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onclick={mix.onClick}
|
|
||||||
class="group animate-enter min-w-0 text-left"
|
|
||||||
style="animation-delay:{i * 45}ms"
|
|
||||||
>
|
|
||||||
{#if mix.coverSongs}
|
|
||||||
<div
|
|
||||||
class="grid aspect-square w-full grid-cols-2 grid-rows-2 overflow-hidden rounded-art shadow-art transition group-hover:shadow-art-lg"
|
|
||||||
>
|
|
||||||
{#each mix.coverSongs as song (song.videoId)}
|
|
||||||
<Cover
|
|
||||||
trackId={song.videoId}
|
|
||||||
src={song.thumbnailUrl}
|
|
||||||
hue={hueFor(song.videoId)}
|
|
||||||
size="small"
|
|
||||||
class="h-full w-full"
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<PlaylistArt
|
|
||||||
trackIds={mix.coverIds ?? []}
|
|
||||||
hue={hueFor(mix.key)}
|
|
||||||
class="aspect-square w-full rounded-art shadow-art transition group-hover:shadow-art-lg"
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
<div class="mt-2.5 truncate text-fg">{mix.title}</div>
|
|
||||||
<div class="mt-0.5 truncate text-sm text-fg-3">{mix.subtitle}</div>
|
|
||||||
</button>
|
|
||||||
{/each}
|
|
||||||
</MediaGrid>
|
|
||||||
</section>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if mixes.length > 0}
|
{#if mixes.length > 0}
|
||||||
<section class="page-x pt-5 pb-3 sm:pt-6">
|
<section class="page-x pt-5 pb-3 sm:pt-6">
|
||||||
<SectionHeading title="Hechas para ti" />
|
<SectionHeading title="Hechas para ti" />
|
||||||
|
|||||||
Reference in New Issue
Block a user