From 62b0ab37a9e574064600c367c146b60cebb649a8 Mon Sep 17 00:00:00 2001 From: XShine555 Date: Mon, 20 Jul 2026 20:49:56 +0200 Subject: [PATCH] feat(web-player): page the album results and save YouTube albums MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The albums section keeps a Ver más button while YouTube Music has another page, fed by a new /api/youtube/albums route that forwards the continuation token. The YouTube album page gains a save button that drops the whole album, tracks included, into your library and takes you to it. --- web-player/src/lib/api/schema.d.ts | 60 +++++++++++++++++++ .../albums/youtube/[albumId]/+page.server.ts | 33 +++++++++- .../albums/youtube/[albumId]/+page.svelte | 26 +++++++- .../src/routes/(app)/explore/+page.server.ts | 1 + .../src/routes/(app)/explore/+page.svelte | 45 +++++++++++++- .../src/routes/api/youtube/albums/+server.ts | 21 +++++++ 6 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 web-player/src/routes/api/youtube/albums/+server.ts diff --git a/web-player/src/lib/api/schema.d.ts b/web-player/src/lib/api/schema.d.ts index a23394a..4190136 100644 --- a/web-player/src/lib/api/schema.d.ts +++ b/web-player/src/lib/api/schema.d.ts @@ -73,6 +73,23 @@ export interface paths { patch?: never; trace?: never; }; + "/albums/youtube/{albumId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Save A YouTube Music Album To Your Library With All Of Its Tracks. */ + post: operations["SaveYouTubeAlbum"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/albums/{albumId}": { parameters: { query?: never; @@ -964,6 +981,49 @@ export interface operations { }; }; }; + SaveYouTubeAlbum: { + parameters: { + query?: never; + header?: never; + path: { + albumId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Created */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AlbumApplicationResponse"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; UpdateAlbum: { parameters: { query?: never; diff --git a/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.server.ts b/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.server.ts index 0f76dd2..2984775 100644 --- a/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.server.ts +++ b/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.server.ts @@ -1,5 +1,11 @@ import type { PageServerLoad, Actions } from './$types'; -import { createApiClient, requireUser, unwrapOrError } from '$lib/server/api'; +import { fail, redirect } from '@sveltejs/kit'; +import { + createApiClient, + requireAccessTokenAction, + requireUser, + unwrapOrError +} from '$lib/server/api'; import { addYouTubeToPlaylistAction } from '$lib/server/playlistActions'; export const load: PageServerLoad = async ({ params, locals, url, fetch }) => { @@ -19,5 +25,28 @@ export const load: PageServerLoad = async ({ params, locals, url, fetch }) => { }; export const actions: Actions = { - addYouTubeToPlaylist: addYouTubeToPlaylistAction + addYouTubeToPlaylist: addYouTubeToPlaylistAction, + + save: async ({ params, locals, fetch }) => { + const accessToken = requireAccessTokenAction(locals); + if (typeof accessToken !== 'string') return accessToken; + + const api = createApiClient({ fetch, accessToken }); + const { + data, + error: err, + response + } = await api.POST('/albums/youtube/{albumId}', { + params: { path: { albumId: params.albumId } } + }); + + if (response?.status === 409) { + return fail(409, { message: 'Ese álbum ya está en tu biblioteca.' }); + } + if (err || !data) { + return fail(502, { message: 'No se pudo guardar el álbum.' }); + } + + redirect(303, `/albums/${data.id}`); + } }; diff --git a/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.svelte b/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.svelte index efba78c..d414c1d 100644 --- a/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.svelte +++ b/web-player/src/routes/(app)/albums/youtube/[albumId]/+page.svelte @@ -1,13 +1,16 @@