From 16418e4f714a06e6d85f8c3ca446db88ca36a17d Mon Sep 17 00:00:00 2001 From: WardPearce Date: Wed, 24 Apr 2024 18:36:01 +1200 Subject: [PATCH] Improved sync party --- README.md | 13 ++++++++++++- materialious/Dockerfile | 3 +++ materialious/replace_env_vars.sh | 5 ++++- materialious/src/lib/i18n/locales/en.json | 4 ++++ materialious/src/lib/misc.ts | 11 ++++++++++- materialious/src/routes/+layout.svelte | 22 +++++++++++++++++++--- 6 files changed, 52 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c847fb17..32551a8b 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ Please ensure you have followed the previous steps before doing this! version: "3" services: materialious: - image: wardpearce/materialious + image: wardpearce/materialious:latest restart: unless-stopped ports: - 3001:80 @@ -171,6 +171,17 @@ services: VITE_DEFAULT_DEARROW_THUMBNAIL_INSTANCE: "https://dearrow-thumb.ajay.app" ``` +## Step 4 (Optional): Self-host PeerJS +[Read the official guide.](https://github.com/peers/peerjs-server?tab=readme-ov-file#docker) + +Add these additional environment variables to Materialious. +```yaml +# Will differ depending on how you self-host peerjs. +VITE_DEFAULT_PEERJS_HOST: "peerjs.example.com" +VITE_DEFAULT_PEERJS_PATH: "/" +VITE_DEFAULT_PEERJS_PORT: 443 +``` + # Previews ## Mobile diff --git a/materialious/Dockerfile b/materialious/Dockerfile index d62181af..b9c123fc 100644 --- a/materialious/Dockerfile +++ b/materialious/Dockerfile @@ -15,6 +15,9 @@ RUN echo "VITE_DEFAULT_INVIDIOUS_INSTANCE=VITE_DEFAULT_INVIDIOUS_INSTANCE_PLACEH echo "VITE_DEFAULT_SPONSERBLOCK_INSTANCE=VITE_DEFAULT_SPONSERBLOCK_INSTANCE_PLACEHOLDER" >> .env && \ echo "VITE_DEFAULT_DEARROW_INSTANCE=VITE_DEFAULT_DEARROW_INSTANCE_PLACEHOLDER" >> .env && \ echo "VITE_DEFAULT_DEARROW_THUMBNAIL_INSTANCE=VITE_DEFAULT_DEARROW_THUMBNAIL_INSTANCE_PLACEHOLDER" >> .env && \ + echo "VITE_DEFAULT_PEERJS_HOST=VITE_DEFAULT_PEERJS_HOST_PLACEHOLDER" >> .env && \ + echo "VITE_DEFAULT_PEERJS_PATH=VITE_DEFAULT_PEERJS_PATH_PLACEHOLDER" >> .env && \ + echo "VITE_DEFAULT_PEERJS_PORT=VITE_DEFAULT_PEERJS_PORT_PLACEHOLDER" >> .env && \ echo "VITE_DEFAULT_RETURNYTDISLIKES_INSTANCE=VITE_DEFAULT_RETURNYTDISLIKES_INSTANCE_PLACEHOLDER" >> .env # Install dependencies and build the project diff --git a/materialious/replace_env_vars.sh b/materialious/replace_env_vars.sh index 87c6b0c4..5d5e419d 100644 --- a/materialious/replace_env_vars.sh +++ b/materialious/replace_env_vars.sh @@ -7,4 +7,7 @@ find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VI find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_FRONTEND_URL_PLACEHOLDER|'"$VITE_DEFAULT_FRONTEND_URL"'|g' {} + find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_SPONSERBLOCK_INSTANCE_PLACEHOLDER|'"$VITE_DEFAULT_SPONSERBLOCK_INSTANCE"'|g' {} + find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_DEARROW_THUMBNAIL_INSTANCE_PLACEHOLDER|'"$VITE_DEFAULT_DEARROW_THUMBNAIL_INSTANCE"'|g' {} + -find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_DEARROW_INSTANCE_PLACEHOLDER|'"$VITE_DEFAULT_DEARROW_INSTANCE"'|g' {} + \ No newline at end of file +find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_DEARROW_INSTANCE_PLACEHOLDER|'"$VITE_DEFAULT_DEARROW_INSTANCE"'|g' {} + +find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_PEERJS_HOST_PLACEHOLDER|'"$VITE_DEFAULT_PEERJS_HOST"'|g' {} + +find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_PEERJS_PATH_PLACEHOLDER|'"$VITE_DEFAULT_PEERJS_PATH"'|g' {} + +find "$ROOT_DIR" -type f \( -name "*.js" -o -name "*.html" \) -exec sed -i 's|VITE_DEFAULT_PEERJS_PORT_PLACEHOLDER|'"$VITE_DEFAULT_PEERJS_PORT"'|g' {} + diff --git a/materialious/src/lib/i18n/locales/en.json b/materialious/src/lib/i18n/locales/en.json index 8a773db4..596bf0e7 100644 --- a/materialious/src/lib/i18n/locales/en.json +++ b/materialious/src/lib/i18n/locales/en.json @@ -11,6 +11,10 @@ "deleteAllHistory": "Delete all history", "skipping": "Skipping", "replies": "replies", + "syncParty": { + "userJoined": "User joined your watch party.", + "userLeft": "User left your watch party." + }, "videoTabs": { "all": "All", "videos": "Videos", diff --git a/materialious/src/lib/misc.ts b/materialious/src/lib/misc.ts index 2e421f9d..e27d9dbb 100644 --- a/materialious/src/lib/misc.ts +++ b/materialious/src/lib/misc.ts @@ -1,6 +1,7 @@ import { pushState } from '$app/navigation'; import { page } from '$app/stores'; import humanNumber from 'human-number'; +import type { PeerOptions } from 'peerjs'; import { get } from 'svelte/store'; export function truncate(value: string, maxLength: number = 50): string { @@ -123,4 +124,12 @@ export function removeWindowQueryFlag(key: string) { const currentPage = get(page); currentPage.url.searchParams.delete(key); pushState(currentPage.url, currentPage.state); -} \ No newline at end of file +} + +export function peerJsOptions(): PeerOptions { + return { + host: import.meta.env.VITE_DEFAULT_PEERJS_HOST || '0.peerjs.com', + path: import.meta.env.VITE_DEFAULT_PEERJS_PATH || '/', + port: Number(import.meta.env.VITE_DEFAULT_PEERJS_PORT) || 443 + }; +} diff --git a/materialious/src/routes/+layout.svelte b/materialious/src/routes/+layout.svelte index 63d85b07..1b75c123 100644 --- a/materialious/src/routes/+layout.svelte +++ b/materialious/src/routes/+layout.svelte @@ -8,7 +8,7 @@ import Search from '$lib/Search.svelte'; import Thumbnail from '$lib/Thumbnail.svelte'; import { bookmarkletLoadFromUrl, bookmarkletSaveToUrl } from '$lib/bookmarklet'; - import { removeWindowQueryFlag, setWindowQueryFlag } from '$lib/misc'; + import { peerJsOptions, removeWindowQueryFlag, setWindowQueryFlag } from '$lib/misc'; import type { PlayerEvents } from '$lib/player'; import 'beercss'; import 'material-dynamic-colors'; @@ -132,11 +132,13 @@ const peerId = crypto.randomUUID(); setWindowQueryFlag('sync', peerId); - $syncPartyPeerStore = new Peer(peerId); + $syncPartyPeerStore = new Peer(peerId, peerJsOptions()); if ($syncPartyPeerStore) { $syncPartyPeerStore.on('connection', (conn) => { conn.on('open', () => { + ui('#sync-party-connection-join'); + if ($page.url.pathname.startsWith('/watch')) { const paths = $page.url.pathname.split('/'); if (paths.length > 2) { @@ -153,6 +155,10 @@ changeVideoEvent(conn); syncPartyConnectionsStore.set([...($syncPartyConnectionsStore || []), conn]); }); + + conn.on('close', () => { + ui('#sync-party-connection-left'); + }); }); } } @@ -248,7 +254,7 @@ const currentUrl = get(page).url; const syncId = currentUrl.searchParams.get('sync'); if (syncId) { - $syncPartyPeerStore = new Peer(crypto.randomUUID()); + $syncPartyPeerStore = new Peer(crypto.randomUUID(), peerJsOptions()); $syncPartyPeerStore.on('open', () => { if (!$syncPartyPeerStore) return; @@ -780,6 +786,16 @@ +
+ person_add + {$_('syncParty.userJoined')} +
+ +
+ person_remove + {$_('syncParty.userLeft')} +
+
{#if $navigating}