feat: bring over the albums, explore and player work from the worktree
Moves the remaining uncommitted work: the home gets quick mixes and a "Tus álbumes" shelf, saving a YouTube album now goes through addYoutubeAlbumToPlaylistAction instead of the SaveYouTubeAlbum command, and UserAlbum drops its unused ExternalId. The mixes section keeps its current shape (no refresh action, no badge, hidden when empty) rather than the older version the worktree carried.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { fail, type RequestEvent } from '@sveltejs/kit';
|
||||
import { createApiClient, requireAccessTokenAction } from '$lib/server/api';
|
||||
import { ALBUM_TRACKS_PAGE_SIZE } from '$lib/config';
|
||||
|
||||
export async function addTrackAction({ request, params, locals, fetch }: RequestEvent) {
|
||||
const accessToken = requireAccessTokenAction(locals);
|
||||
@@ -59,3 +60,79 @@ export async function addYouTubeToPlaylistAction({ request, params, locals, fetc
|
||||
|
||||
return { added: true, videoId, playlistId };
|
||||
}
|
||||
|
||||
export async function addAlbumToPlaylistAction({ request, params, locals, fetch }: RequestEvent) {
|
||||
const accessToken = requireAccessTokenAction(locals);
|
||||
if (typeof accessToken !== 'string') return accessToken;
|
||||
|
||||
const form = await request.formData();
|
||||
const playlistId = String(form.get('playlistId') ?? '') || String(params.id ?? '');
|
||||
const albumId = String(form.get('albumId') ?? '');
|
||||
|
||||
if (!playlistId || !albumId) {
|
||||
return fail(400, { message: 'Faltan datos del álbum.' });
|
||||
}
|
||||
|
||||
const api = createApiClient({ fetch, accessToken });
|
||||
const { data: tracks, error: tracksErr } = await api.GET('/albums/{albumId}/tracks', {
|
||||
params: { path: { albumId }, query: { pageNumber: 1, pageSize: ALBUM_TRACKS_PAGE_SIZE } }
|
||||
});
|
||||
|
||||
if (tracksErr || !tracks) {
|
||||
return fail(502, { message: 'No se pudo cargar el álbum.', albumId });
|
||||
}
|
||||
|
||||
let added = 0;
|
||||
for (const track of tracks.items) {
|
||||
const { error: err } = await api.POST('/playlists/{playlistId}/tracks/{trackId}', {
|
||||
params: { path: { playlistId, trackId: String(track.id) } }
|
||||
});
|
||||
if (!err) added++;
|
||||
}
|
||||
|
||||
return { addedAlbum: true, albumId, playlistId, added };
|
||||
}
|
||||
|
||||
export async function addYoutubeAlbumToPlaylistAction({
|
||||
request,
|
||||
params,
|
||||
locals,
|
||||
fetch
|
||||
}: RequestEvent) {
|
||||
const accessToken = requireAccessTokenAction(locals);
|
||||
if (typeof accessToken !== 'string') return accessToken;
|
||||
|
||||
const form = await request.formData();
|
||||
const playlistId = String(form.get('playlistId') ?? '') || String(params.id ?? '');
|
||||
const albumId = String(form.get('albumId') ?? '');
|
||||
|
||||
if (!playlistId || !albumId) {
|
||||
return fail(400, { message: 'Faltan datos del álbum.' });
|
||||
}
|
||||
|
||||
const api = createApiClient({ fetch, accessToken });
|
||||
const { data: detail, error: detailErr } = await api.GET('/youtube/albums/{albumId}', {
|
||||
params: { path: { albumId } }
|
||||
});
|
||||
|
||||
if (detailErr || !detail) {
|
||||
return fail(502, { message: 'No se pudo cargar el álbum de YouTube.', albumId });
|
||||
}
|
||||
|
||||
let added = 0;
|
||||
for (const track of detail.tracks) {
|
||||
const { error: err } = await api.POST('/playlists/{playlistId}/youtube-tracks', {
|
||||
params: { path: { playlistId } },
|
||||
body: {
|
||||
videoId: track.videoId,
|
||||
title: track.title,
|
||||
artist: detail.album.artist,
|
||||
durationSeconds: Number(track.durationSeconds),
|
||||
thumbnailUrl: detail.album.thumbnailUrl
|
||||
}
|
||||
});
|
||||
if (!err) added++;
|
||||
}
|
||||
|
||||
return { addedAlbum: true, albumId, playlistId, added };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user