From 5905f56e8470d9f643fc32ad1cd1229514fe7533 Mon Sep 17 00:00:00 2001 From: XShine555 Date: Tue, 14 Jul 2026 13:26:08 +0200 Subject: [PATCH] feat(frontend): show recently played from listening history on home --- frontend/src/lib/api/schema.d.ts | 92 +++++++++++++++++++++++++++++ frontend/src/routes/+page.server.ts | 12 +++- frontend/src/routes/+page.svelte | 39 +++++++++--- 3 files changed, 132 insertions(+), 11 deletions(-) diff --git a/frontend/src/lib/api/schema.d.ts b/frontend/src/lib/api/schema.d.ts index 2de12ba..084525f 100644 --- a/frontend/src/lib/api/schema.d.ts +++ b/frontend/src/lib/api/schema.d.ts @@ -161,6 +161,23 @@ export interface paths { patch?: never; trace?: never; }; + "/tracks/{id}/cover": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get A Track Cover Image. */ + get: operations["GetTrackCover"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/tracks/{id}/stream": { parameters: { query?: never; @@ -264,6 +281,23 @@ export interface paths { patch?: never; trace?: never; }; + "/users/{id}/listening-history": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get A User'S Listening History. */ + get: operations["GetListeningHistory"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; } export type webhooks = Record; export interface components { @@ -908,6 +942,35 @@ export interface operations { }; }; }; + GetTrackCover: { + parameters: { + query?: { + size?: string; + }; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; GetTrackStream: { parameters: { query?: never; @@ -1158,4 +1221,33 @@ export interface operations { }; }; }; + GetListeningHistory: { + parameters: { + query?: never; + header?: never; + path: { + id: number | string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["TrackApplicationResponse"][]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; } diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts index d6fa3c2..088fb30 100644 --- a/frontend/src/routes/+page.server.ts +++ b/frontend/src/routes/+page.server.ts @@ -12,8 +12,15 @@ export const load: PageServerLoad = async ({ locals, fetch }) => { params: { path: { userId: locals.user.sub }, query: { pageNumber: 1, pageSize: 8 } } }) : Promise.resolve({ data: undefined }); + const recentlyPlayedPromise = locals.user + ? api.GET('/users/{id}/listening-history', { params: { path: { id: locals.user.sub } } }) + : Promise.resolve({ data: undefined }); - const [latest, playlists] = await Promise.all([latestPromise, playlistsPromise]); + const [latest, playlists, recentlyPlayed] = await Promise.all([ + latestPromise, + playlistsPromise, + recentlyPlayedPromise + ]); const playlistItems = playlists.data?.items ?? []; const covers = await Promise.all( @@ -28,6 +35,7 @@ export const load: PageServerLoad = async ({ locals, fetch }) => { return { latest: latest.data?.items ?? [], playlists: playlistItems, - trackIds: Object.fromEntries(covers) as Record + trackIds: Object.fromEntries(covers) as Record, + recentlyPlayed: recentlyPlayed.data ?? [] }; }; diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 6e26884..8c7c7b7 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -11,6 +11,22 @@ const latest = $derived(data.latest); const playlists = $derived(data.playlists); const trackIds = $derived(data.trackIds); + const recentlyPlayed = $derived.by(() => { + const seen = new Set(); + const merged: { id: string; title: string }[] = []; + for (const t of player.recentlyPlayed) { + const id = String(t.id); + if (seen.has(id)) continue; + seen.add(id); + merged.push({ id, title: t.title }); + } + for (const t of data.recentlyPlayed) { + if (seen.has(t.id)) continue; + seen.add(t.id); + merged.push({ id: t.id, title: t.title }); + } + return merged.slice(0, 15); + }); const greeting = (() => { const h = new Date().getHours(); @@ -41,6 +57,12 @@ if (player.current.id === track.id) player.toggle(); else player.playQueue(latest, index); } + + function playRecent(index: number) { + const track = recentlyPlayed[index]; + if (player.current.id === track.id) player.toggle(); + else player.playQueue(recentlyPlayed, index); + } @@ -61,19 +83,19 @@ -{#if player.recentlyPlayed.length > 0} -
+{#if recentlyPlayed.length > 0} +

Escuchado recientemente

- {#each player.recentlyPlayed as track (track.id)} + {#each recentlyPlayed as track, i (track.id)} {/each} @@ -92,7 +113,7 @@
{/if} -
+

Novedades

{#if latest.length > 0}
@@ -142,8 +163,8 @@ {/if}
-
-

Tus listas

+
+

Mis listas

{#if playlists.length > 0}
{#each playlists as playlist, i (playlist.id)}