From 5e230aca7e5bea40beaa364b9878bebf829c26df Mon Sep 17 00:00:00 2001 From: WardPearce Date: Fri, 13 Feb 2026 02:57:32 +1300 Subject: [PATCH] Implemented Invidious import --- materialious/src/lib/api/index.ts | 15 +++-- .../src/lib/api/youtubejs/subscriptions.ts | 19 +++++-- .../src/lib/components/settings/Engine.svelte | 55 ++++++++++++++++++- materialious/src/lib/i18n/locales/en.json | 7 ++- materialious/src/lib/store.ts | 2 +- materialious/src/routes/(app)/+layout.svelte | 4 +- 6 files changed, 85 insertions(+), 17 deletions(-) diff --git a/materialious/src/lib/api/index.ts b/materialious/src/lib/api/index.ts index bc920a6c..8e0aa8f4 100644 --- a/materialious/src/lib/api/index.ts +++ b/materialious/src/lib/api/index.ts @@ -274,8 +274,11 @@ export async function notificationsMarkAsRead(fetchOptions: RequestInit = {}) { await fetchErrorHandle(await fetch(path, { ...buildAuthHeaders(), ...fetchOptions })); } -export async function getSubscriptions(fetchOptions: RequestInit = {}): Promise { - if (isYTBackend()) { +export async function getSubscriptions( + fetchOptions: RequestInit = {}, + bypassYTBackend: boolean = false +): Promise { + if (isYTBackend() && !bypassYTBackend) { return getSubscriptionsYTjs(); } const resp = await fetchErrorHandle( @@ -304,8 +307,12 @@ export async function amSubscribed( } } -export async function postSubscribe(authorId: string, fetchOptions: RequestInit = {}) { - if (isYTBackend()) { +export async function postSubscribe( + authorId: string, + fetchOptions: RequestInit = {}, + bypassYTBackend: boolean = false +) { + if (isYTBackend() && !bypassYTBackend) { return postSubscribeYTjs(authorId); } diff --git a/materialious/src/lib/api/youtubejs/subscriptions.ts b/materialious/src/lib/api/youtubejs/subscriptions.ts index 5b75f844..14fd99e7 100644 --- a/materialious/src/lib/api/youtubejs/subscriptions.ts +++ b/materialious/src/lib/api/youtubejs/subscriptions.ts @@ -24,13 +24,19 @@ export async function amSubscribedYTjs(authorId: string): Promise { return (await localDb.channelSubscriptions.where('channelId').equals(authorId).count()) > 0; } -export async function postSubscribeYTjs(authorId: string) { - const channel = await getChannelYTjs(authorId); +export async function postSubscribeYTjs( + authorId: string, + authorName: string | undefined = undefined +) { + if (!authorName) { + const channel = await getChannelYTjs(authorId); + authorName = channel.author; + } try { await localDb.channelSubscriptions.add({ channelId: authorId, - channelName: channel.author, + channelName: authorName, lastRSSFetch: new Date(0) }); } catch { @@ -147,16 +153,17 @@ export async function getFeedYTjs(): Promise { await Promise.all(toUpdatePromises); } - const videos = await localDb.subscriptionFeed.toArray(); + let videos = await localDb.subscriptionFeed.toArray(); videos.sort((a, b) => b.published - a.published); const cullAfter = get(engineCullYTStore); - if (videos.length > cullAfter) { const videosToDelete = videos.slice(cullAfter); const videoIdsToDelete = videosToDelete.map((video) => video.videoId); + await localDb.subscriptionFeed.where('videoId').anyOf(videoIdsToDelete).delete(); - await localDb.subscriptionFeed.where('id').anyOf(videoIdsToDelete).delete(); + // Don't display culled videos. + videos = videos.slice(0, cullAfter); } return { diff --git a/materialious/src/lib/components/settings/Engine.svelte b/materialious/src/lib/components/settings/Engine.svelte index 23f9a7c2..c2f8851a 100644 --- a/materialious/src/lib/components/settings/Engine.svelte +++ b/materialious/src/lib/components/settings/Engine.svelte @@ -1,9 +1,18 @@
@@ -40,7 +72,7 @@
{#if isYTBackend()} -

Feed

+
Feed
view_stream
+ + {#if $authStore && $instanceStore} +
{$_('layout.backendEngine.importExport')}
+
+ + + +
+ + + {/if} {:else} -

{$_('layout.backendEngine.fallbacks')}

+
{$_('layout.backendEngine.fallbacks')}
{#each engineFallbacks as fallback (fallback)}