diff --git a/materialious/android/app/build.gradle b/materialious/android/app/build.gradle index ac28be9f..82c7dff7 100644 --- a/materialious/android/app/build.gradle +++ b/materialious/android/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "us.materialio.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 207 - versionName "1.14.3" + versionCode 208 + versionName "1.14.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/materialious/electron/materialious.metainfo.xml b/materialious/electron/materialious.metainfo.xml index 34d744eb..dd4c57c1 100644 --- a/materialious/electron/materialious.metainfo.xml +++ b/materialious/electron/materialious.metainfo.xml @@ -72,7 +72,11 @@ - + + + https://github.com/Materialious/Materialious/releases/tag/1.14.4 + + https://github.com/Materialious/Materialious/releases/tag/1.14.3 diff --git a/materialious/electron/package-lock.json b/materialious/electron/package-lock.json index c4f81a2e..a8fb768a 100644 --- a/materialious/electron/package-lock.json +++ b/materialious/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "Materialious", - "version": "1.14.3", + "version": "1.14.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Materialious", - "version": "1.14.3", + "version": "1.14.4", "license": "MIT", "dependencies": { "@capacitor-community/electron": "^5.0.0", diff --git a/materialious/electron/package.json b/materialious/electron/package.json index c2e7e210..434fc421 100644 --- a/materialious/electron/package.json +++ b/materialious/electron/package.json @@ -1,6 +1,6 @@ { "name": "Materialious", - "version": "1.14.3", + "version": "1.14.4", "description": "Modern material design for YouTube and Invidious.", "author": { "name": "Ward Pearce", diff --git a/materialious/package.json b/materialious/package.json index 568033b4..0a7e67b3 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -1,6 +1,6 @@ { "name": "materialious", - "version": "1.14.3", + "version": "1.14.4", "private": true, "scripts": { "dev": "npm run patch:github && vite dev", diff --git a/materialious/src/lib/api/index.ts b/materialious/src/lib/api/index.ts index 8e0aa8f4..d7414cd1 100644 --- a/materialious/src/lib/api/index.ts +++ b/materialious/src/lib/api/index.ts @@ -252,7 +252,7 @@ export async function getFeed( fetchOptions: RequestInit = {} ): Promise { if (isYTBackend()) { - return getFeedYTjs(); + return getFeedYTjs(maxResults, page); } const path = buildPath('auth/feed'); diff --git a/materialious/src/lib/api/youtubejs/channel.ts b/materialious/src/lib/api/youtubejs/channel.ts index b0156378..fd77bc6a 100644 --- a/materialious/src/lib/api/youtubejs/channel.ts +++ b/materialious/src/lib/api/youtubejs/channel.ts @@ -18,10 +18,15 @@ export async function getChannelYTjs(channelId: string): Promise { const authorId = innerResults.metadata.url?.split('/')[4] ?? ''; let authorBanners: Image[] = []; - if (innerResults.header?.is(YTNodes.PageHeaderView)) { - authorBanners = innerResults.header.banner?.image ?? []; + if ( + innerResults.header?.is(YTNodes.PageHeader) && + innerResults.header.content?.is(YTNodes.PageHeaderView) + ) { + authorBanners = innerResults.header.content.banner?.image ?? []; } + const description = innerResults.metadata.description ?? ''; + return { type: 'channel', allowedRegions: innerResults.metadata.available_countries ?? [], @@ -38,8 +43,8 @@ export async function getChannelYTjs(channelId: string): Promise { authorUrl: `/channel/${authorId}`, subCount: 0, autoGenerated: false, - description: '', - descriptionHml: '' + description, + descriptionHml: description }; } @@ -91,7 +96,6 @@ function fetchChannelContentVideosWithContinuation( } async function fetchChannelContentWithContinuation( - channelId: string, innerResults: YT.Channel | YT.ChannelListContinuation, author: string ): Promise { @@ -131,5 +135,5 @@ export async function getChannelContentYTjs( innerResults = await channel.getLiveStreams(); } - return fetchChannelContentWithContinuation(channelId, innerResults, author); + return fetchChannelContentWithContinuation(innerResults, author); } diff --git a/materialious/src/lib/api/youtubejs/subscriptions.ts b/materialious/src/lib/api/youtubejs/subscriptions.ts index 14fd99e7..807765d7 100644 --- a/materialious/src/lib/api/youtubejs/subscriptions.ts +++ b/materialious/src/lib/api/youtubejs/subscriptions.ts @@ -5,7 +5,11 @@ import { relativeTimestamp } from '$lib/time'; import { get } from 'svelte/store'; import type { Feed, Subscription, Thumbnail } from '../model'; import { getChannelYTjs } from './channel'; -import { engineCooldownYTStore, engineCullYTStore } from '$lib/store'; +import { + engineCooldownYTStore, + engineCullYTStore, + engineMaxConcurrentChannelsStore +} from '$lib/store'; export async function getSubscriptionsYTjs(): Promise { const subscriptions: Subscription[] = []; @@ -134,19 +138,28 @@ export async function parseChannelRSS(channelId: string): Promise { } } -export async function getFeedYTjs(): Promise { +export async function getFeedYTjs(maxResults: number, page: number): Promise { const channelSubscriptions = await localDb.channelSubscriptions.toArray(); const toUpdatePromises: Promise[] = []; const now = new Date(); + + let totalChannelsToParse = 0; for (const channel of channelSubscriptions) { const lastRSSFetch = new Date(channel.lastRSSFetch); const timeDifference = now.getTime() - lastRSSFetch.getTime(); const cooldownTime = get(engineCooldownYTStore) * 60 * 60 * 1000; + if (timeDifference > cooldownTime) { - toUpdatePromises.push(parseChannelRSS(channel.channelId)); + if (totalChannelsToParse < get(engineMaxConcurrentChannelsStore)) { + toUpdatePromises.push(parseChannelRSS(channel.channelId)); + } else { + parseChannelRSS(channel.channelId); + } } + + totalChannelsToParse++; } if (toUpdatePromises) { @@ -166,8 +179,11 @@ export async function getFeedYTjs(): Promise { videos = videos.slice(0, cullAfter); } + const start = (page - 1) * maxResults; + const end = start + maxResults; + return { notifications: [], - videos: videos + videos: videos.slice(start, end) }; } diff --git a/materialious/src/lib/api/youtubejs/video.ts b/materialious/src/lib/api/youtubejs/video.ts index 548577e1..6f447a06 100644 --- a/materialious/src/lib/api/youtubejs/video.ts +++ b/materialious/src/lib/api/youtubejs/video.ts @@ -84,10 +84,13 @@ export async function getVideoYTjs(videoId: string): Promise { // Unsupported format fix // https://github.com/LuanRT/googlevideo/issues/42 - if (video.streaming_data) + if (video.streaming_data) { video.streaming_data.adaptive_formats = video.streaming_data.adaptive_formats.filter( (format) => format.xtags !== 'CgcKAnZiEgEx' ); + } else { + throw new Error('Video did not provide streaming data.'); + } const adaptiveFormats: AdaptiveFormats[] = []; video.streaming_data?.adaptive_formats.forEach((format) => { diff --git a/materialious/src/lib/components/Search.svelte b/materialious/src/lib/components/Search.svelte index 01bcc615..7a551fee 100644 --- a/materialious/src/lib/components/Search.svelte +++ b/materialious/src/lib/components/Search.svelte @@ -1,5 +1,4 @@