Changes
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Álbumes · Musify</title>
|
||||
<title>Álbumes</title>
|
||||
<meta name="description" content="Los álbumes que has publicado con tu música subida." />
|
||||
</svelte:head>
|
||||
|
||||
|
||||
@@ -38,7 +38,9 @@ export const load: PageServerLoad = async ({ params, locals, url, fetch }) => {
|
||||
(track) => track.source === 'Local' && !inAlbum.has(track.id)
|
||||
);
|
||||
|
||||
return { album, tracks, library, isOwner: Number(album.ownerUserId) === Number(user.sub) };
|
||||
const isOwner = Number(album.ownerUserId) === Number(user.sub);
|
||||
|
||||
return { album, tracks, library, isOwner, section: isOwner ? '/albums' : null };
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
|
||||
@@ -31,13 +31,12 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{album.title} · Musify</title>
|
||||
<meta name="description" content="Álbum {album.title} en Musify." />
|
||||
<title>{album.title}</title>
|
||||
<meta name="description" content="Álbum {album.title}." />
|
||||
</svelte:head>
|
||||
|
||||
<Page>
|
||||
<AlbumHeader
|
||||
id={album.id}
|
||||
title={album.title}
|
||||
description={album.description ?? undefined}
|
||||
releaseYear={album.releaseYear === null ? undefined : Number(album.releaseYear)}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
<script lang="ts">
|
||||
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
||||
import Play from '@lucide/svelte/icons/play';
|
||||
import Pause from '@lucide/svelte/icons/pause';
|
||||
import SquarePencil from '@lucide/svelte/icons/square-pen';
|
||||
import Trash from '@lucide/svelte/icons/trash';
|
||||
import PlaylistArt from '$lib/components/ui/PlaylistArt.svelte';
|
||||
import BackLink from '$lib/components/ui/BackLink.svelte';
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
releaseYear?: number;
|
||||
@@ -22,7 +20,6 @@
|
||||
}
|
||||
|
||||
let {
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
releaseYear,
|
||||
@@ -44,20 +41,14 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<a
|
||||
href="/albums"
|
||||
class="group inline-flex items-center text-fg-3 transition-colors hover:text-accent-soft"
|
||||
>
|
||||
<span class="grid h-8 w-8 place-items-center transition-colors group-hover:text-accent-soft">
|
||||
<ArrowLeft class="h-4 w-4" />
|
||||
</span>
|
||||
Volver a tus álbumes
|
||||
</a>
|
||||
<BackLink
|
||||
href={isOwner ? '/albums' : '/'}
|
||||
label={isOwner ? 'Volver a tus álbumes' : 'Volver al inicio'}
|
||||
/>
|
||||
|
||||
<div class="mt-5 flex flex-col gap-5 sm:mt-6 sm:flex-row sm:items-end sm:gap-6">
|
||||
<PlaylistArt
|
||||
{trackIds}
|
||||
hue={hueFor(id)}
|
||||
size="large"
|
||||
class="h-36 w-36 shrink-0 rounded-art-lg shadow-art-lg sm:h-44 sm:w-44"
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
toQueueItems,
|
||||
type ApiTrackLike
|
||||
} from '$lib/player/player.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { fmtTime } from '$lib/format';
|
||||
import IconButton from '$lib/components/ui/IconButton.svelte';
|
||||
import TrackTable from '$lib/components/ui/TrackTable.svelte';
|
||||
@@ -43,7 +42,6 @@
|
||||
trackId={track.id}
|
||||
title={track.title}
|
||||
artist={track.artist}
|
||||
hue={hueFor(track.id)}
|
||||
explicit={track.isExplicit}
|
||||
onClick={() => playFrom(i)}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { enhance } from '$app/forms';
|
||||
import Plus from '@lucide/svelte/icons/plus';
|
||||
import { player, toQueueItems, type ApiTrackLike } from '$lib/player/player.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { fmtTime } from '$lib/format';
|
||||
import SectionHeading from '$lib/components/ui/SectionHeading.svelte';
|
||||
import IconButton from '$lib/components/ui/IconButton.svelte';
|
||||
@@ -34,7 +33,6 @@
|
||||
trackId={track.id}
|
||||
title={track.title}
|
||||
artist={track.artist}
|
||||
hue={hueFor(track.id)}
|
||||
explicit={track.isExplicit}
|
||||
onClick={() => playFrom(i)}
|
||||
>
|
||||
|
||||
@@ -18,7 +18,7 @@ export const load: PageServerLoad = async ({ params, locals, url, fetch }) => {
|
||||
|
||||
const album = unwrapOrError(albumRes, 'No se pudo cargar el álbum de YouTube Music.', 404);
|
||||
|
||||
return { album, playlists: playlistsRes.data?.items ?? [] };
|
||||
return { album, playlists: playlistsRes.data?.items ?? [], section: null };
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<script lang="ts">
|
||||
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
||||
import Play from '@lucide/svelte/icons/play';
|
||||
import Pause from '@lucide/svelte/icons/pause';
|
||||
import { player, type QueueItem } from '$lib/player/player.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { fmtTime } from '$lib/format';
|
||||
import Page from '$lib/components/ui/Page.svelte';
|
||||
import BackLink from '$lib/components/ui/BackLink.svelte';
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import Cover from '$lib/components/ui/Cover.svelte';
|
||||
import Alert from '$lib/components/ui/Alert.svelte';
|
||||
@@ -73,26 +72,17 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{album.title} · Musify</title>
|
||||
<meta name="description" content="Álbum {album.title} de {album.artist} en YouTube Music." />
|
||||
<title>{album.title}</title>
|
||||
<meta name="description" content="Álbum {album.title} de {album.artist}," />
|
||||
</svelte:head>
|
||||
|
||||
<Page>
|
||||
<a
|
||||
href="/explore"
|
||||
class="group inline-flex items-center text-fg-3 transition-colors hover:text-accent-soft"
|
||||
>
|
||||
<span class="grid h-8 w-8 place-items-center transition-colors group-hover:text-accent-soft">
|
||||
<ArrowLeft class="h-4 w-4" />
|
||||
</span>
|
||||
Volver a explorar
|
||||
</a>
|
||||
<BackLink href="/explore" label="Volver a explorar" />
|
||||
|
||||
<div class="mt-5 flex flex-col gap-5 sm:mt-6 sm:flex-row sm:items-end sm:gap-6">
|
||||
<Cover
|
||||
trackId={album.albumId}
|
||||
src={album.thumbnailUrl}
|
||||
hue={hueFor(album.albumId)}
|
||||
size="large"
|
||||
alt={album.title}
|
||||
class="h-36 w-36 shrink-0 rounded-art-lg shadow-art-lg sm:h-44 sm:w-44"
|
||||
@@ -100,7 +90,7 @@
|
||||
/>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="text-sm tracking-[0.14em] text-fg-3 uppercase">
|
||||
{album.isSingle ? 'Single' : album.isEp ? 'EP' : 'Álbum'} · YouTube Music
|
||||
{album.isSingle ? 'Single' : album.isEp ? 'EP' : 'Álbum'}
|
||||
</p>
|
||||
<h1
|
||||
class="mt-1.5 text-3xl font-semibold tracking-tight break-words text-fg sm:text-5xl md:text-7xl"
|
||||
@@ -154,7 +144,6 @@
|
||||
title={track.title}
|
||||
artist={album.artist}
|
||||
coverSrc={album.thumbnailUrl}
|
||||
hue={hueFor(track.videoId)}
|
||||
explicit={track.isExplicit}
|
||||
onClick={() => playFrom(i)}
|
||||
/>
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
import NowPlaying from '$lib/components/ui/NowPlaying.svelte';
|
||||
import ExplicitBadge from '$lib/components/ui/ExplicitBadge.svelte';
|
||||
import SectionHeading from '$lib/components/ui/SectionHeading.svelte';
|
||||
import { EXPLORE_PAGE_SIZE, SEARCH_DEBOUNCE_MS } from '$lib/config';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { EXPLORE_ALBUMS_LIMIT, EXPLORE_PAGE_SIZE, SEARCH_DEBOUNCE_MS } from '$lib/config';
|
||||
import type { YouTubeSong } from '$lib/types';
|
||||
import TrackContextMenu, {
|
||||
contextMenuStateFor,
|
||||
@@ -113,10 +112,12 @@
|
||||
type YouTubeAlbum = (typeof data.youtubeAlbums)[number];
|
||||
type AlbumEntry = { kind: 'local'; album: LocalAlbum } | { kind: 'youtube'; album: YouTubeAlbum };
|
||||
|
||||
const albumEntries = $derived<AlbumEntry[]>([
|
||||
...albums.map((album) => ({ kind: 'local' as const, album })),
|
||||
...youtubeAlbums.map((album) => ({ kind: 'youtube' as const, album }))
|
||||
]);
|
||||
const albumEntries = $derived<AlbumEntry[]>(
|
||||
[
|
||||
...albums.map((album) => ({ kind: 'local' as const, album })),
|
||||
...youtubeAlbums.map((album) => ({ kind: 'youtube' as const, album }))
|
||||
].slice(0, EXPLORE_ALBUMS_LIMIT)
|
||||
);
|
||||
|
||||
const hasAlbums = $derived(albumEntries.length > 0);
|
||||
const hasUsers = $derived(users.length > 0);
|
||||
@@ -215,7 +216,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Buscar · Musify</title>
|
||||
<title>Buscar</title>
|
||||
<meta name="description" content="Busca canciones, álbumes y usuarios en Musify." />
|
||||
</svelte:head>
|
||||
|
||||
@@ -261,7 +262,6 @@
|
||||
<div class="relative">
|
||||
<PlaylistArt
|
||||
trackIds={entry.album.coverTrackIds}
|
||||
hue={hueFor(entry.album.id)}
|
||||
class="aspect-square w-full rounded-art shadow-art ring-1 ring-line transition duration-300 ease-out ring-inset group-hover/card:shadow-art-lg"
|
||||
/>
|
||||
</div>
|
||||
@@ -285,7 +285,6 @@
|
||||
<Cover
|
||||
trackId={entry.album.albumId}
|
||||
src={entry.album.thumbnailUrl}
|
||||
hue={hueFor(entry.album.albumId)}
|
||||
size="large"
|
||||
alt={entry.album.title}
|
||||
class="aspect-square w-full rounded-art shadow-art ring-1 ring-line transition duration-300 ease-out ring-inset group-hover/card:shadow-art-lg"
|
||||
@@ -316,7 +315,7 @@
|
||||
class="group/artist animate-enter shrink-0"
|
||||
style="animation-delay:{Math.min(i, 10) * 45}ms"
|
||||
>
|
||||
<ArtistAvatar id={u.id} name={u.name} size={96} />
|
||||
<ArtistAvatar name={u.name} size={96} />
|
||||
<div class="mt-1 w-24 truncate text-center text-xs text-fg-3">@{u.handle}</div>
|
||||
</div>
|
||||
{/each}
|
||||
@@ -339,7 +338,6 @@
|
||||
<Cover
|
||||
trackId={targetId(item)}
|
||||
src={targetCoverSrc(item)}
|
||||
hue={hueFor(targetId(item))}
|
||||
size="small"
|
||||
alt={targetTitle(item)}
|
||||
class="h-11 w-11 shrink-0 rounded-control shadow-art ring-1 ring-line ring-inset"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import X from '@lucide/svelte/icons/x';
|
||||
import Music from '@lucide/svelte/icons/music';
|
||||
import { player, toQueueItems } from '$lib/player/player.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { fmtTime, fmtDate } from '$lib/format';
|
||||
import Page from '$lib/components/ui/Page.svelte';
|
||||
import PageHeader from '$lib/components/ui/PageHeader.svelte';
|
||||
@@ -28,7 +27,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Tus canciones subidas · Musify</title>
|
||||
<title>Tus canciones subidas</title>
|
||||
<meta name="description" content="Todas tus canciones subidas a Musify." />
|
||||
</svelte:head>
|
||||
|
||||
@@ -65,12 +64,7 @@
|
||||
playing={player.playing}
|
||||
onToggle={() => togglePlay(i)}
|
||||
/>
|
||||
<TrackTitleCell
|
||||
trackId={track.id}
|
||||
title={track.title}
|
||||
hue={hueFor(track.id)}
|
||||
onClick={() => togglePlay(i)}
|
||||
/>
|
||||
<TrackTitleCell trackId={track.id} title={track.title} onClick={() => togglePlay(i)} />
|
||||
<TrackMeta class="hidden sm:block">{fmtDate(track.createdAt)}</TrackMeta>
|
||||
<TrackMeta class="hidden sm:block">{Number(track.listensCount)}</TrackMeta>
|
||||
<TrackMeta>{fmtTime(Number(track.duration))}</TrackMeta>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<script lang="ts">
|
||||
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
||||
import Play from '@lucide/svelte/icons/play';
|
||||
import Pause from '@lucide/svelte/icons/pause';
|
||||
import Shuffle from '@lucide/svelte/icons/shuffle';
|
||||
import { player } from '$lib/player/player.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { fmtTime } from '$lib/format';
|
||||
import { shuffle } from '$lib/collections';
|
||||
import Page from '$lib/components/ui/Page.svelte';
|
||||
import BackLink from '$lib/components/ui/BackLink.svelte';
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import Alert from '$lib/components/ui/Alert.svelte';
|
||||
import MixArt from '$lib/components/ui/MixArt.svelte';
|
||||
@@ -61,27 +60,15 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{mix.title} · Musify</title>
|
||||
<title>{mix.title}</title>
|
||||
<meta name="description" content="Mezcla {mix.title}, hecha para ti." />
|
||||
</svelte:head>
|
||||
|
||||
<Page>
|
||||
<a
|
||||
href="/"
|
||||
class="group inline-flex items-center text-fg-3 transition-colors hover:text-accent-soft"
|
||||
>
|
||||
<span class="grid h-8 w-8 place-items-center transition-colors group-hover:text-accent-soft">
|
||||
<ArrowLeft class="h-4 w-4" />
|
||||
</span>
|
||||
Volver al inicio
|
||||
</a>
|
||||
<BackLink href="/" label="Volver al inicio" />
|
||||
|
||||
<div class="mt-5 flex flex-col gap-5 sm:mt-6 sm:flex-row sm:items-end sm:gap-6">
|
||||
<MixArt
|
||||
{items}
|
||||
hue={hueFor(mix.id)}
|
||||
class="h-36 w-36 shrink-0 rounded-art-lg shadow-art-lg sm:h-44 sm:w-44"
|
||||
/>
|
||||
<MixArt {items} class="h-36 w-36 shrink-0 rounded-art-lg shadow-art-lg sm:h-44 sm:w-44" />
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="text-sm tracking-[0.14em] text-fg-3 uppercase">Mezcla</p>
|
||||
<h1
|
||||
@@ -133,7 +120,6 @@
|
||||
title={targetTitle(targets[i])}
|
||||
artist={targetArtist(targets[i])}
|
||||
coverSrc={targetCoverSrc(targets[i])}
|
||||
hue={hueFor(mixItemKey(item))}
|
||||
explicit={item.isExplicit}
|
||||
onClick={() => playFrom(i)}
|
||||
/>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Mis listas · Musify</title>
|
||||
<title>Mis listas</title>
|
||||
<meta name="description" content="Mis listas en Musify." />
|
||||
</svelte:head>
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{playlist.name} · Musify</title>
|
||||
<title>{playlist.name}</title>
|
||||
<meta name="description" content="Playlist {playlist.name} en Musify." />
|
||||
</svelte:head>
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<script lang="ts">
|
||||
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
|
||||
import Play from '@lucide/svelte/icons/play';
|
||||
import Pause from '@lucide/svelte/icons/pause';
|
||||
import SquarePencil from '@lucide/svelte/icons/square-pen';
|
||||
import Trash from '@lucide/svelte/icons/trash';
|
||||
import PlaylistArt from '$lib/components/ui/PlaylistArt.svelte';
|
||||
import BackLink from '$lib/components/ui/BackLink.svelte';
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
@@ -24,21 +23,12 @@
|
||||
$props();
|
||||
</script>
|
||||
|
||||
<a
|
||||
href="/playlists"
|
||||
class="group inline-flex items-center text-fg-3 transition-colors hover:text-accent-soft"
|
||||
>
|
||||
<span class="grid h-8 w-8 place-items-center transition-colors group-hover:text-accent-soft">
|
||||
<ArrowLeft class="h-4 w-4" />
|
||||
</span>
|
||||
Volver a tus listas
|
||||
</a>
|
||||
<BackLink href="/playlists" label="Volver a tus listas" />
|
||||
|
||||
<div class="mt-5 flex flex-col gap-5 sm:mt-6 sm:flex-row sm:items-end sm:gap-6">
|
||||
<PlaylistArt
|
||||
playlistId={id}
|
||||
{trackIds}
|
||||
hue={hueFor(id)}
|
||||
size="large"
|
||||
version={updatedAt}
|
||||
class="h-36 w-36 shrink-0 rounded-art-lg shadow-art-lg sm:h-44 sm:w-44"
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
youTubeThumbnailUrl,
|
||||
type ApiTrackLike
|
||||
} from '$lib/player/player.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { fmtTime, fmtDate } from '$lib/format';
|
||||
import Badge from '$lib/components/ui/Badge.svelte';
|
||||
import IconButton from '$lib/components/ui/IconButton.svelte';
|
||||
@@ -48,7 +47,6 @@
|
||||
coverSrc={isPendingYouTubeTrack(track) && track.externalId
|
||||
? youTubeThumbnailUrl(track.externalId)
|
||||
: undefined}
|
||||
hue={hueFor(track.id)}
|
||||
explicit={track.isExplicit}
|
||||
onClick={() => playFrom(i)}
|
||||
>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
type ApiTrackLike,
|
||||
type QueueItem
|
||||
} from '$lib/player/player.svelte';
|
||||
import { hueFor } from '$lib/theme/color';
|
||||
import { fmtTime } from '$lib/format';
|
||||
import type { YouTubeSong } from '$lib/types';
|
||||
import SectionHeading from '$lib/components/ui/SectionHeading.svelte';
|
||||
@@ -92,7 +91,6 @@
|
||||
title={item.kind === 'youtube' ? item.song.title : item.track.title}
|
||||
artist={item.kind === 'youtube' ? item.song.artist : item.track.artist}
|
||||
coverSrc={item.kind === 'youtube' ? item.song.thumbnailUrl : undefined}
|
||||
hue={hueFor(idFor(item))}
|
||||
explicit={item.kind === 'youtube' && item.song.isExplicit}
|
||||
onClick={() => playFrom(i)}
|
||||
>
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Subir música · Musify</title>
|
||||
<title>Subir música</title>
|
||||
<meta name="description" content="Sube tus canciones a Musify: portada, audio y título." />
|
||||
</svelte:head>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user