web-player: split player, navigation and accent state into focused modules
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
name?: string | null;
|
||||
ownerUserId?: string | number | null;
|
||||
ownerUserId?: string | null;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import { trackCover } from '$lib/utils/hrefs';
|
||||
|
||||
type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'hero' | 'fill';
|
||||
|
||||
interface Props {
|
||||
src?: string | null;
|
||||
trackIds?: (string | number)[];
|
||||
trackIds?: string[];
|
||||
size: Size;
|
||||
shape?: 'auto' | 'round';
|
||||
imageSize?: 'small' | 'medium' | 'large';
|
||||
@@ -76,7 +77,6 @@
|
||||
const showSrc = $derived(!!src && !srcFailed);
|
||||
const showMosaic = $derived(!showSrc && trackIds.length >= 4);
|
||||
const singleId = $derived(!showSrc && !showMosaic && trackIds.length > 0 ? trackIds[0] : null);
|
||||
const showSingle = $derived(singleId !== null && !singleFailed);
|
||||
</script>
|
||||
|
||||
<div class="relative overflow-hidden {DIMENSION[size]} {radius} {klass}">
|
||||
@@ -94,7 +94,7 @@
|
||||
<div class="grid h-full w-full grid-cols-2 grid-rows-2">
|
||||
{#each trackIds.slice(0, 4) as id (id)}
|
||||
<img
|
||||
src="/api/tracks/{id}/cover?size=small"
|
||||
src={trackCover(id, 'small')}
|
||||
alt=""
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
@@ -104,9 +104,9 @@
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
{:else if showSingle}
|
||||
{:else if singleId !== null && !singleFailed}
|
||||
<img
|
||||
src="/api/tracks/{singleId}/cover?size={resolvedImageSize}"
|
||||
src={trackCover(singleId, resolvedImageSize)}
|
||||
{alt}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
variant?: 'row' | 'card';
|
||||
title: string;
|
||||
subtitle?: string | null;
|
||||
subtitleHref?: string | number | null;
|
||||
subtitleHref?: string | null;
|
||||
explicit?: boolean;
|
||||
trackId?: string | number;
|
||||
trackIds?: (string | number)[];
|
||||
trackId?: string;
|
||||
trackIds?: string[];
|
||||
coverSrc?: string | null;
|
||||
art?: Snippet;
|
||||
overlay?: Snippet;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
title: string;
|
||||
subtitle?: string | null;
|
||||
src?: string | null;
|
||||
trackIds?: (string | number)[];
|
||||
trackIds?: string[];
|
||||
onPlay?: (event: MouseEvent) => void;
|
||||
art?: Snippet;
|
||||
oncontextmenu?: (event: MouseEvent) => void;
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
import ArtistLink from './ArtistLink.svelte';
|
||||
|
||||
interface Props {
|
||||
trackId?: string | number;
|
||||
trackIds?: (string | number)[];
|
||||
trackId?: string;
|
||||
trackIds?: string[];
|
||||
title: string;
|
||||
artist?: string | null;
|
||||
ownerUserId?: string | number | null;
|
||||
ownerUserId?: string | null;
|
||||
coverSrc?: string | null;
|
||||
size?: 'xs' | 'sm' | 'lg';
|
||||
explicit?: boolean;
|
||||
|
||||
@@ -1,24 +1,6 @@
|
||||
<script lang="ts" module>
|
||||
import { MENU_WIDTH, SUBMENU_WIDTH } from '$lib/config';
|
||||
|
||||
export interface MenuPosition {
|
||||
x: number;
|
||||
y: number;
|
||||
openLeft: boolean;
|
||||
}
|
||||
|
||||
export function contextMenuPosition(event: MouseEvent): MenuPosition {
|
||||
event.preventDefault();
|
||||
return {
|
||||
x: Math.max(8, Math.min(event.clientX, window.innerWidth - MENU_WIDTH - 8)),
|
||||
y: Math.max(8, Math.min(event.clientY, window.innerHeight - 60)),
|
||||
openLeft: event.clientX + MENU_WIDTH + SUBMENU_WIDTH + 16 > window.innerWidth
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import { playlistCover } from '$lib/utils/hrefs';
|
||||
import type { LucideIcon } from '@lucide/svelte';
|
||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||
import MediaIdentity from '../media/MediaIdentity.svelte';
|
||||
@@ -32,7 +14,7 @@
|
||||
onClose: () => void;
|
||||
items: { icon: LucideIcon; label: string; onclick: () => void }[];
|
||||
playlistAction?: { action: string; fields: Record<string, string>; label: string };
|
||||
playlists?: { id: string; name: string }[];
|
||||
playlists?: { id: string; name: string; updatedAt: string }[];
|
||||
}
|
||||
|
||||
let { x, y, openLeft, onClose, items, playlistAction, playlists = [] }: Props = $props();
|
||||
@@ -97,7 +79,7 @@
|
||||
>
|
||||
<MediaIdentity
|
||||
title={playlist.name}
|
||||
coverSrc="/api/playlists/{playlist.id}/cover?size=small"
|
||||
coverSrc={playlistCover(playlist, 'small')}
|
||||
size="xs"
|
||||
titleClass="text-fg-2"
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
||||
import { previousPage } from '$lib/state/navigation.svelte';
|
||||
import { previousPage } from '$lib/state/history.svelte';
|
||||
|
||||
interface Props {
|
||||
href: string;
|
||||
|
||||
Reference in New Issue
Block a user