Merge pull request #63 from WardPearce/update/sub-download-sync
Update/sub download sync
This commit is contained in:
Generated
+9
@@ -9,6 +9,7 @@
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"beercss": "^3.5.1",
|
||||
"fuse.js": "^7.0.0",
|
||||
"human-number": "^2.0.4",
|
||||
"media-icons": "^0.10.0",
|
||||
"peerjs": "^1.5.2",
|
||||
@@ -4913,6 +4914,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/fuse.js": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
|
||||
"integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"beercss": "^3.5.1",
|
||||
"fuse.js": "^7.0.0",
|
||||
"human-number": "^2.0.4",
|
||||
"media-icons": "^0.10.0",
|
||||
"peerjs": "^1.5.2",
|
||||
|
||||
@@ -664,6 +664,8 @@
|
||||
</dialog>
|
||||
|
||||
<dialog id="sync-party">
|
||||
<h6>Sync party</h6>
|
||||
<p>Please note your IP will be visible to users you invite.</p>
|
||||
{#if $syncPartyPeer}
|
||||
<nav>
|
||||
<div class="field label border">
|
||||
@@ -673,7 +675,7 @@
|
||||
value={`${import.meta.env.VITE_DEFAULT_FRONTEND_URL}?sync=${$syncPartyPeer.id}`}
|
||||
type="text"
|
||||
/>
|
||||
<label for="sync-share">Share URL</label>
|
||||
<label class="active" for="sync-share">Share URL</label>
|
||||
</div>
|
||||
<button
|
||||
on:click={async () => {
|
||||
@@ -688,7 +690,10 @@
|
||||
</nav>
|
||||
{/if}
|
||||
<div class="space"></div>
|
||||
<button on:click={startWatchSync} data-ui={`${$syncPartyPeer ? '#sync-party' : ''}`}
|
||||
<button
|
||||
class="no-margin"
|
||||
on:click={startWatchSync}
|
||||
data-ui={`${$syncPartyPeer ? '#sync-party' : ''}`}
|
||||
>{#if $syncPartyPeer}
|
||||
End
|
||||
{:else}
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="space"></div>
|
||||
<nav class="right-align">
|
||||
<a class="button" href="/subscriptions/manage">
|
||||
<i>subscriptions</i>
|
||||
<span>Manage subscriptions</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<VideoList bind:videos />
|
||||
|
||||
<InfiniteLoading on:infinite={loadMore} />
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import { deleteUnsubscribe } from '$lib/Api';
|
||||
import Fuse from 'fuse.js';
|
||||
import { activePage } from '../../../store';
|
||||
|
||||
activePage.set(null);
|
||||
|
||||
export let data;
|
||||
|
||||
let subscriptions = structuredClone(data.subscriptions);
|
||||
|
||||
let search: string;
|
||||
|
||||
const fuse = new Fuse(subscriptions, {
|
||||
keys: ['author']
|
||||
});
|
||||
|
||||
function searchSubs() {
|
||||
if (search === '') {
|
||||
subscriptions = structuredClone(data.subscriptions);
|
||||
} else {
|
||||
subscriptions = fuse.search(search).map((item) => item.item);
|
||||
}
|
||||
}
|
||||
|
||||
async function unsubscribe(authorId: string) {
|
||||
try {
|
||||
await deleteUnsubscribe(authorId);
|
||||
subscriptions = subscriptions.filter((item) => {
|
||||
return item.authorId !== authorId;
|
||||
});
|
||||
} catch {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="space"></div>
|
||||
|
||||
<div class="max field round suffix prefix small no-margin white black-text">
|
||||
<i class="front">search</i><input
|
||||
bind:value={search}
|
||||
on:input={searchSubs}
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#each subscriptions as sub}
|
||||
<article>
|
||||
<nav>
|
||||
<a href={`/channel/${sub.authorId}`} class="link"><h6>{sub.author}</h6></a>
|
||||
<div class="max"></div>
|
||||
<button on:click={async () => unsubscribe(sub.authorId)} class="inverse-surface">
|
||||
Unsubscribe
|
||||
</button>
|
||||
</nav>
|
||||
</article>
|
||||
{/each}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { getSubscriptions } from "$lib/Api";
|
||||
import { error } from "@sveltejs/kit";
|
||||
|
||||
export async function load() {
|
||||
let subscriptions;
|
||||
|
||||
try {
|
||||
subscriptions = await getSubscriptions();
|
||||
} catch (errorMessage: any) {
|
||||
error(500, errorMessage);
|
||||
}
|
||||
|
||||
return {
|
||||
subscriptions: subscriptions
|
||||
};
|
||||
}
|
||||
@@ -56,7 +56,11 @@
|
||||
} else if (event.type === 'play') {
|
||||
player.play();
|
||||
} else if (event.type === 'seek' && event.time) {
|
||||
player.currentTime = event.time;
|
||||
const timeDiff = player.currentTime - event.time;
|
||||
|
||||
if (timeDiff > 3 || timeDiff < 3) {
|
||||
player.currentTime = event.time;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -223,7 +227,7 @@
|
||||
<h5>{data.video.title}</h5>
|
||||
|
||||
<div class="grid no-padding">
|
||||
<div class="s12 m12 l4">
|
||||
<div class="s12 m12 l5">
|
||||
<nav>
|
||||
<a href={`/channel/${data.video.authorId}`}>
|
||||
<nav>
|
||||
@@ -258,9 +262,9 @@
|
||||
{/if}
|
||||
</nav>
|
||||
</div>
|
||||
<div class="s12 m12 l4 video-actions">
|
||||
<div class="s12 m12 l7 video-actions">
|
||||
{#if data.returnYTDislikes}
|
||||
<nav class="no-space no-margin" style="margin-right: .5em;">
|
||||
<nav class="no-space" style="margin-right: .5em;">
|
||||
<button style="cursor: default;" class="border left-round">
|
||||
<i class="small">thumb_up</i>
|
||||
<span>{cleanNumber(data.returnYTDislikes.likes)}</span>
|
||||
@@ -271,19 +275,11 @@
|
||||
</button>
|
||||
</nav>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="s12 m12 l4 video-actions">
|
||||
<button
|
||||
class="no-margin"
|
||||
on:click={() => (audioMode = !audioMode)}
|
||||
class:border={!audioMode}
|
||||
>
|
||||
<button on:click={() => (audioMode = !audioMode)} class:border={!audioMode}>
|
||||
<i>headphones</i>
|
||||
<span>Audio only </span>
|
||||
</button>
|
||||
<button class="border"
|
||||
><i>share</i> Share
|
||||
><i>share</i>
|
||||
<menu class="no-wrap">
|
||||
<a
|
||||
class="row"
|
||||
@@ -315,10 +311,21 @@
|
||||
></menu
|
||||
></button
|
||||
>
|
||||
{#if data.downloadOptions.length > 0}
|
||||
<button class="border"
|
||||
><i>download</i>
|
||||
<menu class="no-wrap">
|
||||
{#each data.downloadOptions as download}
|
||||
<a class="row" href={download.url} target="_blank" rel="noopener noreferrer"
|
||||
>{download.title}</a
|
||||
>
|
||||
{/each}
|
||||
</menu></button
|
||||
>
|
||||
{/if}
|
||||
{#if data.personalPlaylists}
|
||||
<button class="border no-margin">
|
||||
<button class="border">
|
||||
<i>add</i>
|
||||
<span>Playlist</span>
|
||||
<menu>
|
||||
{#each data.personalPlaylists as personalPlaylist}
|
||||
<a
|
||||
@@ -332,7 +339,6 @@
|
||||
{:else}
|
||||
<button disabled class="border no-margin">
|
||||
<i>add</i>
|
||||
<span>Playlist</span>
|
||||
<div class="tooltip">
|
||||
{#if $auth}
|
||||
No playlists
|
||||
@@ -457,6 +463,10 @@
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.video-actions button:not(.left-round):not(.right-round) {
|
||||
margin: 0.3em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
.video-actions {
|
||||
justify-content: flex-start;
|
||||
|
||||
@@ -13,6 +13,24 @@ export async function load({ params, url }) {
|
||||
error(500, errorMessage);
|
||||
}
|
||||
|
||||
let downloadOptions: { title: string; url: string; }[] = [];
|
||||
|
||||
if (!video.hlsUrl) {
|
||||
video.formatStreams.forEach(format => {
|
||||
downloadOptions.push({
|
||||
title: `${format.type.split(';')[0].trim()} - ${format.qualityLabel} (With audio)`,
|
||||
url: format.url
|
||||
});
|
||||
});
|
||||
|
||||
video.adaptiveFormats.forEach(format => {
|
||||
downloadOptions.push({
|
||||
title: `${format.type.split(';')[0].trim()} - ${format.qualityLabel || format.bitrate + ' bitrate'}`,
|
||||
url: format.url
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let personalPlaylists: PlaylistPage[] | null;
|
||||
|
||||
if (get(auth)) {
|
||||
@@ -47,6 +65,7 @@ export async function load({ params, url }) {
|
||||
subscribed: await amSubscribed(video.authorId),
|
||||
content: phaseDescription(video.descriptionHtml),
|
||||
playlistId: url.searchParams.get('playlist'),
|
||||
personalPlaylists: personalPlaylists
|
||||
personalPlaylists: personalPlaylists,
|
||||
downloadOptions: downloadOptions
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user