Merge pull request #108 from WardPearce/fix/history-playlist

Fixed playlist history
This commit is contained in:
Ward
2024-04-12 00:52:59 +12:00
committed by GitHub
13 changed files with 109 additions and 31 deletions
+11 -2
View File
@@ -186,9 +186,9 @@ export async function deleteUnsubscribe(authorId: string) {
);
}
export async function getHistory(page: number = 1): Promise<string[]> {
export async function getHistory(page: number = 1, maxResults: number = 20): Promise<string[]> {
const resp = await fetchErrorHandle(
await fetch(buildPath(`auth/history?page=${page}`), buildAuthHeaders())
await fetch(buildPath(`auth/history?page=${page}&max_results=${maxResults}`), buildAuthHeaders())
);
return await resp.json();
}
@@ -276,6 +276,15 @@ export async function addPlaylistVideo(playlistId: string, videoId: string) {
);
}
export async function removePlaylistVideo(playlistId: string, indexId: string) {
await fetchErrorHandle(
await fetch(buildPath(`auth/playlists/${playlistId}/videos/${indexId}`), {
method: 'DELETE',
...buildAuthHeaders()
})
);
}
export async function getDeArrow(videoId: string): Promise<DeArrow> {
const resp = await fetchErrorHandle(
await fetch(`${get(deArrowInstance)}/api/branding?videoID=${videoId}`)
+1
View File
@@ -180,6 +180,7 @@ export interface Playlist {
export interface PlaylistPageVideo extends PlaylistVideo {
author: string;
index: number;
indexId: string;
authorId: string;
viewCount: number;
}
+48 -19
View File
@@ -23,28 +23,57 @@
suggestionsForSearch = (await getSearchSuggestions(event.target.value)).suggestions;
}, 250);
};
function handleSubmit() {
goto(`/search/${encodeURIComponent(search)}`);
}
</script>
<form on:submit|preventDefault={() => goto(`/search/${encodeURIComponent(search)}`)}>
<div class="max field round suffix prefix small no-margin white black-text">
<i class="front">search</i><input
data-ui="search-suggestions"
type="text"
placeholder={$_('searchPlaceholder')}
bind:value={search}
on:keyup={(target) => debouncedSearch(target)}
/>
{#if searchSuggestions}
<menu
class="no-wrap"
style="width: 100%;"
id="search-suggestions"
data-ui="#search-suggestions"
>
<form on:submit|preventDefault={handleSubmit}>
<div class="field prefix round fill no-margin search">
<i class="front">search</i>
<input bind:value={search} on:click={() => document.getElementById('search')?.focus()} />
<menu class="min">
<div class="field large prefix suffix no-margin fixed">
<i class="front">arrow_back</i>
<input
placeholder={$_('searchPlaceholder')}
type="text"
id="search"
required
bind:value={search}
on:keyup={(event) => {
if (event.key === 'Enter') {
handleSubmit();
} else {
debouncedSearch(event);
}
}}
/>
<i class="front" on:click={() => (search = '')}>close</i>
</div>
{#if searchSuggestions}
{#each suggestionsForSearch as suggestion}
<a href={`/search/${encodeURIComponent(suggestion)}`}>{suggestion}</a>
<a
on:click={() => (search = suggestion)}
class="row"
href={`/search/${encodeURIComponent(suggestion)}`}
>
<div>{suggestion}</div>
</a>
{/each}
</menu>
{/if}
{/if}
</menu>
</div>
</form>
<style>
.search {
width: 500px;
}
@media screen and (max-width: 1140px) {
.search {
width: 100%;
}
}
</style>
+11 -3
View File
@@ -18,13 +18,19 @@
async function loadPageHistory() {
try {
const videoIds = await getHistory(currentPage);
const videoIds = await getHistory(currentPage, 20);
let promises = [];
for (const videoId of videoIds) {
promises.push(getVideo(videoId));
promises.push(
getVideo(videoId).catch(() => {
return null;
})
);
}
const loadedHistory = await Promise.all(promises);
const loadedHistory = (await Promise.all(promises)).filter((item) => {
return item !== null;
}) as VideoPlay[];
history = [...history, ...loadedHistory];
} catch (errorMessage: any) {
error(500, errorMessage);
@@ -34,6 +40,8 @@
async function loadMore(event: InfiniteEvent) {
const pastHistoryLen = Number(history.length);
currentPage++;
await loadPageHistory();
if (pastHistoryLen === history.length) {
@@ -69,7 +69,7 @@
</p>
<div class="divider" style="margin-bottom: 1em;"></div>
<article class="medium scroll no-padding no-elevate no-round">
<article style="max-height: 200px;" class="scroll no-padding no-elevate no-round">
<p style="white-space: pre-line;word-wrap: break-word;">{data.playlist.description}</p>
</article>
</article>
@@ -6,7 +6,8 @@
getComments,
getPersonalPlaylists,
getPlaylist,
postSubscribe
postSubscribe,
removePlaylistVideo
} from '$lib/Api/index.js';
import type { PlaylistPage, PlaylistPageVideo } from '$lib/Api/model.js';
import Comment from '$lib/Comment.svelte';
@@ -294,8 +295,28 @@
}
}
async function addVideoToPlaylist(playlistId: string) {
await addPlaylistVideo(playlistId, data.video.videoId);
async function toggleVideoToPlaylist(playlistId: string) {
if (!data.personalPlaylists) return;
const selectedPlaylist = data.personalPlaylists.filter((item) => {
return item.playlistId === playlistId;
});
if (selectedPlaylist.length === 0) {
return;
}
const videosToDelete = selectedPlaylist[0].videos.filter((item) => {
return item.videoId === data.video.videoId;
});
if (videosToDelete.length > 0) {
videosToDelete.forEach(async (toDelete) => {
await removePlaylistVideo(playlistId, toDelete.indexId);
});
} else {
await addPlaylistVideo(playlistId, data.video.videoId);
}
data.personalPlaylists = await getPersonalPlaylists();
}
@@ -462,12 +483,22 @@
<button class="border">
<i>add</i>
<div class="tooltip">{$_('player.addToPlaylist')}</div>
<menu>
<menu class="no-wrap">
{#each data.personalPlaylists as personalPlaylist}
<a
href="#add"
on:click={async () => await addVideoToPlaylist(personalPlaylist.playlistId)}
>{personalPlaylist.title}
on:click={async () => await toggleVideoToPlaylist(personalPlaylist.playlistId)}
>
<nav>
<span class="max">{personalPlaylist.title}</span>
{#if personalPlaylist.videos.filter((item) => {
return item.videoId === data.video.videoId;
}).length > 0}
<i>close</i>
{:else}
<i>add</i>
{/if}
</nav>
</a>
{/each}
</menu>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 684 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 7.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 706 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB