From b1686daa246cf8db1848d78540e834a013a4554a Mon Sep 17 00:00:00 2001 From: WardPearce Date: Mon, 1 Apr 2024 11:41:58 +1300 Subject: [PATCH] Added playlist creation & adding support --- README.md | 1 - materialious/src/lib/Api/index.ts | 47 ++++- materialious/src/lib/PlaylistThumbnail.svelte | 20 +- materialious/src/routes/+layout.svelte | 1 + .../src/routes/playlist/[slug]/+page.svelte | 35 ++-- .../src/routes/playlists/+page.svelte | 90 ++++++++ materialious/src/routes/playlists/+page.ts | 7 + .../src/routes/watch/[slug]/+page.svelte | 196 ++++++++++-------- materialious/src/routes/watch/[slug]/+page.ts | 11 +- 9 files changed, 295 insertions(+), 113 deletions(-) create mode 100644 materialious/src/routes/playlists/+page.svelte create mode 100644 materialious/src/routes/playlists/+page.ts diff --git a/README.md b/README.md index 7f43ab56..0f959003 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ - PWA support. ## Todo -- Playlist support. - Docker building & publishing workflow. - Launching 'materialio.us'. - Locking down git branches & setup PR requirements. diff --git a/materialious/src/lib/Api/index.ts b/materialious/src/lib/Api/index.ts index 40e87197..7d351342 100644 --- a/materialious/src/lib/Api/index.ts +++ b/materialious/src/lib/Api/index.ts @@ -160,6 +160,51 @@ export async function postHistory(videoId: string) { } export async function getPlaylist(playlistId: string, page: number = 1): Promise { - const resp = await fetch(buildPath(`playlists/${playlistId}?page=${page}`)); + let resp; + + if (get(auth)) { + resp = await fetch(buildPath(`auth/playlists/${playlistId}?page=${page}`), buildAuthHeaders()); + } else { + resp = await fetch(buildPath(`playlists/${playlistId}?page=${page}`)); + } return await resp.json(); +} + +export async function getPersonalPlaylists(): Promise { + const resp = await fetch(buildPath('auth/playlists'), buildAuthHeaders()); + return await resp.json(); +} + +export async function deletePersonalPlaylist(playlistId: string) { + await fetch(buildPath(`auth/playlists/${playlistId}`), { + method: 'DELETE', + ...buildAuthHeaders() + }); +} + +export async function postPersonalPlaylist(title: string, privacy: 'public' | 'private' | 'unlisted') { + let headers: Record> = buildAuthHeaders(); + headers['headers']['Content-type'] = 'application/json'; + + await fetch(buildPath('auth/playlists'), { + method: 'POST', + body: JSON.stringify({ + title: title, + privacy: privacy + }), + ...headers + }); +} + +export async function addPlaylistVideo(playlistId: string, videoId: string) { + let headers: Record> = buildAuthHeaders(); + headers['headers']['Content-type'] = 'application/json'; + + await fetch(buildPath(`auth/playlists/${playlistId}/videos`), { + method: 'POST', + body: JSON.stringify({ + videoId: videoId + }), + ...headers + }); } \ No newline at end of file diff --git a/materialious/src/lib/PlaylistThumbnail.svelte b/materialious/src/lib/PlaylistThumbnail.svelte index a040f07c..ef3deb2a 100644 --- a/materialious/src/lib/PlaylistThumbnail.svelte +++ b/materialious/src/lib/PlaylistThumbnail.svelte @@ -35,15 +35,17 @@ style="width: 100%; overflow: hidden;min-height:100px;" class="wave" > - {#if loading} - - {:else} - Thumbnail for playlist + {#if playlist.videoCount > 0} + {#if loading} + + {:else} + Thumbnail for playlist + {/if} {/if}
{playlist.videoCount} videos diff --git a/materialious/src/routes/+layout.svelte b/materialious/src/routes/+layout.svelte index 47f3422a..427b0841 100644 --- a/materialious/src/routes/+layout.svelte +++ b/materialious/src/routes/+layout.svelte @@ -168,6 +168,7 @@ function logout() { auth.set(null); + goto('/'); } async function loadNotifications() { diff --git a/materialious/src/routes/playlist/[slug]/+page.svelte b/materialious/src/routes/playlist/[slug]/+page.svelte index 2fb24108..caec99a7 100644 --- a/materialious/src/routes/playlist/[slug]/+page.svelte +++ b/materialious/src/routes/playlist/[slug]/+page.svelte @@ -10,21 +10,26 @@ activePage.set(null); - let videos = data.playlist.videos.sort((a: PlaylistPageVideo, b: PlaylistPageVideo) => { - return a.index < b.index ? -1 : 1; - }); + let videos: PlaylistPageVideo[] | undefined; + if (data.playlist.videos) { + videos = data.playlist.videos.sort((a: PlaylistPageVideo, b: PlaylistPageVideo) => { + return a.index < b.index ? -1 : 1; + }); - onMount(async () => { - for (let page = 1; page++; ) { - const newVideos = (await getPlaylist(data.playlist.playlistId, page)).videos; - if (newVideos.length === 0) { - break; + onMount(async () => { + for (let page = 1; page++; ) { + const newVideos = (await getPlaylist(data.playlist.playlistId, page)).videos; + if (newVideos.length === 0) { + break; + } + videos = [...(videos as PlaylistPageVideo[]), ...newVideos].sort( + (a: PlaylistPageVideo, b: PlaylistPageVideo) => { + return a.index < b.index ? -1 : 1; + } + ); } - videos = [...videos, ...newVideos].sort((a: PlaylistPageVideo, b: PlaylistPageVideo) => { - return a.index < b.index ? -1 : 1; - }); - } - }); + }); + }
@@ -36,4 +41,6 @@

{data.playlist.description}

- +{#if videos} + +{/if} diff --git a/materialious/src/routes/playlists/+page.svelte b/materialious/src/routes/playlists/+page.svelte new file mode 100644 index 00000000..91f482ce --- /dev/null +++ b/materialious/src/routes/playlists/+page.svelte @@ -0,0 +1,90 @@ + + +
+
+
+ {#each data.playlists as playlist} +
+
+ + + +
+
+ {/each} +
+
+ +
+
+
+
+ + +
+
+ + +
+
+ +
+ +
+
diff --git a/materialious/src/routes/playlists/+page.ts b/materialious/src/routes/playlists/+page.ts new file mode 100644 index 00000000..27d45fd1 --- /dev/null +++ b/materialious/src/routes/playlists/+page.ts @@ -0,0 +1,7 @@ +import { getPersonalPlaylists } from "$lib/Api"; + +export async function load() { + return { + playlists: await getPersonalPlaylists() + }; +} \ No newline at end of file diff --git a/materialious/src/routes/watch/[slug]/+page.svelte b/materialious/src/routes/watch/[slug]/+page.svelte index b5a69ed3..0a95a79c 100644 --- a/materialious/src/routes/watch/[slug]/+page.svelte +++ b/materialious/src/routes/watch/[slug]/+page.svelte @@ -1,5 +1,12 @@