From 858e0c8043f7e84dd0a3dfc2e04997129943cb22 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Tue, 8 Apr 2025 18:50:27 +1200 Subject: [PATCH 1/6] Update packages --- materialious/android/app/build.gradle | 4 ++-- materialious/electron/materialious.metainfo.xml | 6 +++++- materialious/electron/package-lock.json | 12 ++++++------ materialious/electron/package.json | 2 +- materialious/package-lock.json | 16 ++++++++-------- materialious/package.json | 4 ++-- update_versions.py | 2 +- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/materialious/android/app/build.gradle b/materialious/android/app/build.gradle index c80bf262..610795ae 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 101 - versionName "1.7.19" + versionCode 102 + versionName "1.7.20" 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 84790dc8..e47d00c0 100644 --- a/materialious/electron/materialious.metainfo.xml +++ b/materialious/electron/materialious.metainfo.xml @@ -62,7 +62,11 @@ - + + + https://github.com/Materialious/Materialious/releases/tag/1.7.20 + + https://github.com/Materialious/Materialious/releases/tag/1.7.19 diff --git a/materialious/electron/package-lock.json b/materialious/electron/package-lock.json index 371835f2..a35b9373 100644 --- a/materialious/electron/package-lock.json +++ b/materialious/electron/package-lock.json @@ -2506,9 +2506,9 @@ } }, "node_modules/electron": { - "version": "34.4.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-34.4.1.tgz", - "integrity": "sha512-iYzeLBdCrAR3i0RVSLa+mzuFZwH6HGxTGKsI+SS41sg2anZj4R5mHjOiHsxcZ50/ih47NJbuVRJgPIVlTF+USg==", + "version": "34.5.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-34.5.0.tgz", + "integrity": "sha512-GabFMG7r2P1NQf5DYp6mnCXo5CcatxXb8YQo54VTStql6weeEv7tsqvl3lAssGwDdd4iMc8QpTCFjErBSVRWeQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5751,9 +5751,9 @@ } }, "node_modules/typescript": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/materialious/electron/package.json b/materialious/electron/package.json index d7030157..06fc7dde 100644 --- a/materialious/electron/package.json +++ b/materialious/electron/package.json @@ -1,6 +1,6 @@ { "name": "Materialious", - "version": "1.7.19", + "version": "1.7.20", "description": "Modern material design for Invidious.", "author": { "name": "Ward Pearce", diff --git a/materialious/package-lock.json b/materialious/package-lock.json index 6b4efda7..51d76809 100644 --- a/materialious/package-lock.json +++ b/materialious/package-lock.json @@ -1,12 +1,12 @@ { "name": "materialious", - "version": "1.7.19", + "version": "1.7.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "materialious", - "version": "1.7.19", + "version": "1.7.20", "hasInstallScript": true, "dependencies": { "@capacitor-community/electron": "^5.0.1", @@ -3423,9 +3423,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.20.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.20.2.tgz", - "integrity": "sha512-Dv8TOAZC9vyfcAB9TMsvUEJsRbklRTeNfcYBPaeH6KnABJ99i3CvCB2eNx8fiiliIqe+9GIchBg4RodRH5p1BQ==", + "version": "2.20.4", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.20.4.tgz", + "integrity": "sha512-B3Y1mb1Qjt57zXLVch5tfqsK/ebHe6uYTcFSnGFNwRpId3+fplLgQK6Z2zhDVBezSsPuhDq6Pry+9PA88ocN6Q==", "dev": true, "license": "MIT", "dependencies": { @@ -12904,9 +12904,9 @@ } }, "node_modules/vite": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", - "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", + "integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/materialious/package.json b/materialious/package.json index a6073be6..5105baf4 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -1,6 +1,6 @@ { "name": "materialious", - "version": "1.7.19", + "version": "1.7.20", "private": true, "scripts": { "dev": "vite dev", @@ -72,4 +72,4 @@ "terser": "^5.34.1", "youtubei.js": "^13.3.0" } -} +} \ No newline at end of file diff --git a/update_versions.py b/update_versions.py index 57f5fcbe..5f6675ef 100644 --- a/update_versions.py +++ b/update_versions.py @@ -3,7 +3,7 @@ import os import re from datetime import datetime -LATEST_VERSION = "1.7.19" +LATEST_VERSION = "1.7.20" RELEASE_DATE = datetime.now().strftime("%Y-%-m-%d") # Format: YYYY-M-D WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "materialious") From e2988d5be99f2de7395a156301c30c9e683c2b1b Mon Sep 17 00:00:00 2001 From: WardPearce Date: Tue, 8 Apr 2025 19:54:36 +1200 Subject: [PATCH 2/6] Improved link handling --- .../android/app/capacitor.build.gradle | 1 - .../android/capacitor.settings.gradle | 3 -- materialious/electron/package-lock.json | 4 +- materialious/electron/src/setup.ts | 1 - materialious/package.json | 2 +- materialious/src/lib/components/Player.svelte | 2 +- materialious/src/lib/misc.ts | 5 -- materialious/src/lib/timestamps.ts | 52 ++++++++++++++++--- materialious/src/routes/(app)/+layout.svelte | 17 ++++++ .../routes/(app)/channel/[slug]/+page.svelte | 25 +++++---- .../src/routes/(app)/watch/[slug]/+page.ts | 2 +- .../routes/(no-layout)/embed/[slug]/+page.ts | 2 +- 12 files changed, 81 insertions(+), 35 deletions(-) diff --git a/materialious/android/app/capacitor.build.gradle b/materialious/android/app/capacitor.build.gradle index b9764570..6bea4029 100644 --- a/materialious/android/app/capacitor.build.gradle +++ b/materialious/android/app/capacitor.build.gradle @@ -14,7 +14,6 @@ dependencies { implementation project(':capacitor-clipboard') implementation project(':capacitor-screen-orientation') implementation project(':capacitor-status-bar') - implementation project(':capgo-inappbrowser') implementation project(':hugotomazi-capacitor-navigation-bar') implementation project(':capacitor-nodejs') diff --git a/materialious/android/capacitor.settings.gradle b/materialious/android/capacitor.settings.gradle index 2fd2c8fd..ef0cb561 100644 --- a/materialious/android/capacitor.settings.gradle +++ b/materialious/android/capacitor.settings.gradle @@ -17,9 +17,6 @@ project(':capacitor-screen-orientation').projectDir = new File('../node_modules/ include ':capacitor-status-bar' project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android') -include ':capgo-inappbrowser' -project(':capgo-inappbrowser').projectDir = new File('../node_modules/@capgo/inappbrowser/android') - include ':hugotomazi-capacitor-navigation-bar' project(':hugotomazi-capacitor-navigation-bar').projectDir = new File('../node_modules/@hugotomazi/capacitor-navigation-bar/android') diff --git a/materialious/electron/package-lock.json b/materialious/electron/package-lock.json index a35b9373..c4d30472 100644 --- a/materialious/electron/package-lock.json +++ b/materialious/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "Materialious", - "version": "1.7.19", + "version": "1.7.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Materialious", - "version": "1.7.19", + "version": "1.7.20", "license": "MIT", "dependencies": { "@capacitor-community/electron": "^5.0.0", diff --git a/materialious/electron/src/setup.ts b/materialious/electron/src/setup.ts index 49b8dfb3..b8b328c7 100644 --- a/materialious/electron/src/setup.ts +++ b/materialious/electron/src/setup.ts @@ -196,7 +196,6 @@ export class ElectronCapacitorApp { event.preventDefault(); } }); - // Link electron plugins into the system. setupCapacitorElectronPlugins(); diff --git a/materialious/package.json b/materialious/package.json index 5105baf4..13101be0 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -72,4 +72,4 @@ "terser": "^5.34.1", "youtubei.js": "^13.3.0" } -} \ No newline at end of file +} diff --git a/materialious/src/lib/components/Player.svelte b/materialious/src/lib/components/Player.svelte index d50d1848..b825589d 100644 --- a/materialious/src/lib/components/Player.svelte +++ b/materialious/src/lib/components/Player.svelte @@ -3,6 +3,7 @@ import '$lib/css/shaka-player-theme.css'; import { getBestThumbnail } from '$lib/images'; import { padTime, videoLength } from '$lib/time'; + import { type PhasedDescription } from '$lib/timestamps'; import { Capacitor } from '@capacitor/core'; import { ScreenOrientation, type ScreenOrientationResult } from '@capacitor/screen-orientation'; import { StatusBar, Style } from '@capacitor/status-bar'; @@ -19,7 +20,6 @@ import { get } from 'svelte/store'; import { deleteVideoProgress, getVideoProgress, saveVideoProgress } from '../api'; import type { VideoPlay } from '../api/model'; - import { type PhasedDescription } from '../misc'; import { authStore, instanceStore, diff --git a/materialious/src/lib/misc.ts b/materialious/src/lib/misc.ts index a4f00eba..f33c18c0 100644 --- a/materialious/src/lib/misc.ts +++ b/materialious/src/lib/misc.ts @@ -9,11 +9,6 @@ export function truncate(value: string, maxLength: number = 50): string { return value.length > maxLength ? `${value.substring(0, maxLength)}...` : value; } -export interface PhasedDescription { - description: string; - timestamps: { title: string; time: number; timePretty: string; }[]; -} - export function decodeHtmlCharCodes(str: string): string { const { decode } = he; return decode(str); diff --git a/materialious/src/lib/timestamps.ts b/materialious/src/lib/timestamps.ts index ed1c58fa..553fdabf 100644 --- a/materialious/src/lib/timestamps.ts +++ b/materialious/src/lib/timestamps.ts @@ -1,33 +1,69 @@ -import { type PhasedDescription, decodeHtmlCharCodes } from "./misc"; +import { decodeHtmlCharCodes } from "./misc"; import { convertToSeconds } from "./time"; -export function phaseDescription(content: string, usingYoutubeJs: boolean = false): PhasedDescription { +export interface PhasedDescription { + description: string; + timestamps: { title: string; time: number; timePretty: string; }[]; +} + +export function extractActualLink(url: string): string { + const urlParams = new URLSearchParams(url.split('?')[1]); + const actualLink = urlParams.get('q'); + if (actualLink) { + return decodeURIComponent(actualLink); + } + return url; +} + +export function processYoutubeLink(line: string): string { + // Regex to match the tag and extract the href (YouTube redirect link) + const urlRegex = /(\d+:\d+(?::\d+)?)<\/a>\s*(.+)/; - const timestampRegexYtJs = /&(?:\S*?&)?t=(\d+)\s*s.*?]*>([^<]*)<\/span>.*?>(.*?)<\/span>/; + const timestampRegexYtJs = new RegExp( + `href="https://www\\.youtube\\.com/watch\\?v=${videoId}(?:&t=(\\d+)s)?"[^>]*>\\s*]*>\\s*([^<]+)\\s*\\s*\\s*]*>\\s*([^<]+)\\s*`, + 'i' + ); let filteredLines: string[] = []; lines.forEach((line) => { const urlMatch = urlRegex.exec(line); // Use appropriate regex based on the `usingYoutubeJs` flag - const timestampMatch = (usingYoutubeJs ? timestampRegexYtJs : timestampRegexInvidious).exec(usingYoutubeJs ? line + '' : line); + const timestampMatch = (fallbackPatch === 'youtubejs' ? timestampRegexYtJs : timestampRegexInvidious).exec(fallbackPatch === 'youtubejs' ? line + '' : line); if (urlMatch !== null && timestampMatch === null) { // If line contains a URL but not a timestamp, modify the URL - const modifiedLine = line.replace( + const modifiedLine = processYoutubeLink(line).replace( / { ui(); + document.addEventListener('click', linkClickOverwrite); + scrollableRoot = document.querySelector('.root'); loadSettingsFromEnv(); @@ -183,6 +185,21 @@ } }); + function linkClickOverwrite(event: MouseEvent) { + // Handles opening links in browser for android. + + if (Capacitor.getPlatform() !== 'android') return; + + const link = (event.target as HTMLElement).closest('a'); + + if (link && link.href) { + if (link.href && link.href.startsWith('http') && link.target === '_blank') { + event.preventDefault(); + Browser.open({ url: link.href }); + } + } + } + let webManifestLink = $derived(pwaInfo ? pwaInfo.webManifest.linkTag : ''); diff --git a/materialious/src/routes/(app)/channel/[slug]/+page.svelte b/materialious/src/routes/(app)/channel/[slug]/+page.svelte index 71c951b4..7287370d 100644 --- a/materialious/src/routes/(app)/channel/[slug]/+page.svelte +++ b/materialious/src/routes/(app)/channel/[slug]/+page.svelte @@ -137,21 +137,24 @@ {$_('player.share.title')} {#if !Capacitor.isNativePlatform()} - { await Clipboard.write({ string: location.href }); - }}>{$_('player.share.materialiousLink')}{$_('player.share.materialiousLink')} + {/if} + + {#if true} + {/if} - { - await Clipboard.write({ - string: `https://www.youtube.com/channel/${data.channel.authorId}` - }); - }}>{$_('player.share.youtubeLink')} diff --git a/materialious/src/routes/(app)/watch/[slug]/+page.ts b/materialious/src/routes/(app)/watch/[slug]/+page.ts index 594305d7..80639185 100644 --- a/materialious/src/routes/(app)/watch/[slug]/+page.ts +++ b/materialious/src/routes/(app)/watch/[slug]/+page.ts @@ -52,7 +52,7 @@ export async function load({ params, url }) { return { video: video, - content: phaseDescription(video.descriptionHtml, video.fallbackPatch === 'youtubejs'), + content: phaseDescription(video.videoId, video.descriptionHtml, video.fallbackPatch), playlistId: url.searchParams.get('playlist'), streamed: { personalPlaylists: personalPlaylists, diff --git a/materialious/src/routes/(no-layout)/embed/[slug]/+page.ts b/materialious/src/routes/(no-layout)/embed/[slug]/+page.ts index b5d1f10c..dad2562f 100644 --- a/materialious/src/routes/(no-layout)/embed/[slug]/+page.ts +++ b/materialious/src/routes/(no-layout)/embed/[slug]/+page.ts @@ -1,6 +1,6 @@ import { getVideo } from '$lib/api/index'; -import type { PhasedDescription } from '$lib/misc'; import { playerProxyVideosStore } from '$lib/store'; +import type { PhasedDescription } from '$lib/timestamps'; import { error } from '@sveltejs/kit'; import { get } from 'svelte/store'; From ee2c01bccc1594c538a81e7ee381932f17aeeab3 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Tue, 8 Apr 2025 19:57:12 +1200 Subject: [PATCH 3/6] change time.ts to numbers.ts --- materialious/src/lib/components/ChannelThumbnail.svelte | 2 +- materialious/src/lib/components/Comment.svelte | 2 +- materialious/src/lib/components/HashtagThumbnail.svelte | 2 +- materialious/src/lib/components/Player.svelte | 2 +- materialious/src/lib/components/Thumbnail.svelte | 2 +- materialious/src/lib/components/Transcript.svelte | 2 +- materialious/src/lib/{time.ts => numbers.ts} | 0 materialious/src/lib/patches/youtubejs.ts | 2 +- materialious/src/lib/timestamps.ts | 2 +- materialious/src/routes/(app)/channel/[slug]/+page.svelte | 2 +- materialious/src/routes/(app)/playlist/[slug]/+page.svelte | 2 +- materialious/src/routes/(app)/watch/[slug]/+page.svelte | 2 +- 12 files changed, 11 insertions(+), 11 deletions(-) rename materialious/src/lib/{time.ts => numbers.ts} (100%) diff --git a/materialious/src/lib/components/ChannelThumbnail.svelte b/materialious/src/lib/components/ChannelThumbnail.svelte index bf765092..0d8addc1 100644 --- a/materialious/src/lib/components/ChannelThumbnail.svelte +++ b/materialious/src/lib/components/ChannelThumbnail.svelte @@ -1,6 +1,6 @@ -{#if !thumbnailHidden} -
-
{}} id="thumbnail-container" role="region"> - - {#if !$interfaceLowBandwidthMode} - {#if !thumbnail} -
- {:else} - Thumbnail for video - {/if} - {/if} - {#if progress} - - {/if} - {#if !('liveVideo' in video) || !video.liveVideo} - {#if video.lengthSeconds !== 0} - {#if !$interfaceLowBandwidthMode} -
-  {videoLength(video.lengthSeconds)}  -
- {:else} -

{videoLength(video.lengthSeconds)}

- {/if} - {/if} - {:else if video.lengthSeconds !== 0} -
- {$_('thumbnail.live')} -
+
+ - -
- {#if !sideways && !$interfaceLowBandwidthMode && $interfaceDisplayThumbnailAvatars} -
- {#if authorImg} - Author - {:else} - - {/if} -
{/if} -
- - {letterCase(truncate(video.title.trimEnd(), 80))} - - -
- {video.author} - {#if !('publishedText' in video) && 'viewCountText' in video} - - • {video.viewCountText} - {$_('views')} - - {/if} - - {#if 'publishedText' in video} -
- {cleanNumber(video.viewCount)} • {video.publishedText} + {#if progress} + + {/if} + {#if !('liveVideo' in video) || !video.liveVideo} + {#if video.lengthSeconds !== 0} + {#if !$interfaceLowBandwidthMode} +
+  {videoLength(video.lengthSeconds)} 
+ {:else} +

{videoLength(video.lengthSeconds)}

{/if} + {/if} + {:else if video.lengthSeconds !== 0} +
+ {$_('thumbnail.live')}
+ {:else} +

{$_('thumbnail.live')}

+ {/if} + +
+ +
+ {#if !sideways && !$interfaceLowBandwidthMode && $interfaceDisplayThumbnailAvatars} +
+ {#if authorImg} + Author + {:else} + + {/if} +
+ {/if} +
+ + {letterCase(truncate(video.title.trimEnd(), 80))} + + +
+ {video.author} + {#if !('publishedText' in video) && 'viewCountText' in video} + + • {video.viewCountText} + {$_('views')} + + {/if} + + {#if 'publishedText' in video} +
+ {cleanNumber(video.viewCount)} • {video.publishedText} +
+ {/if}
-{/if} - - - +