diff --git a/materialious/android/app/build.gradle b/materialious/android/app/build.gradle index 146b7a2c..7151b4a6 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 64 - versionName "1.6.13" + versionCode 65 + versionName "1.6.14" 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/package.json b/materialious/electron/package.json index 7f0c34a4..14306748 100644 --- a/materialious/electron/package.json +++ b/materialious/electron/package.json @@ -1,6 +1,6 @@ { "name": "Materialious", - "version": "1.6.13", + "version": "1.6.14", "description": "Modern material design for Invidious.", "author": { "name": "Ward Pearce", diff --git a/materialious/package-lock.json b/materialious/package-lock.json index f6c19504..ffa1832e 100644 --- a/materialious/package-lock.json +++ b/materialious/package-lock.json @@ -1,12 +1,12 @@ { "name": "materialious", - "version": "1.6.10", + "version": "1.6.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "materialious", - "version": "1.6.10", + "version": "1.6.14", "dependencies": { "@capacitor-community/electron": "^5.0.1", "@capacitor/android": "6.1.2", diff --git a/materialious/package.json b/materialious/package.json index a8ddd43a..7edc8db0 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -1,6 +1,6 @@ { "name": "materialious", - "version": "1.6.13", + "version": "1.6.14", "private": true, "scripts": { "dev": "vite dev", @@ -76,4 +76,4 @@ "vidstack": "^1.12.9", "youtubei.js": "^10.5.0" } -} \ No newline at end of file +} diff --git a/materialious/src/lib/Player.svelte b/materialious/src/lib/Player.svelte index b32de43f..32343b10 100644 --- a/materialious/src/lib/Player.svelte +++ b/materialious/src/lib/Player.svelte @@ -381,7 +381,11 @@ const audioPlayerTime = await AudioPlayer.getCurrentTime(audioId); - player.currentTime = Math.round(audioPlayerTime.currentTime); + const audioPlayerTimeRounded = Math.round(audioPlayerTime.currentTime); + if (audioPlayerTimeRounded > player.currentTime) { + player.currentTime = audioPlayerTimeRounded; + } + await player.play(); }); diff --git a/materialious/src/lib/i18n/locales/en.json b/materialious/src/lib/i18n/locales/en.json index d136f407..23ecc371 100644 --- a/materialious/src/lib/i18n/locales/en.json +++ b/materialious/src/lib/i18n/locales/en.json @@ -8,7 +8,7 @@ "cancel": "Cancel", "create": "Create", "title": "Title", - "searchPlaceholder": "Search (ctrl + k)", + "searchPlaceholder": "Search", "delete": "Delete", "donate": "Donate", "deleteAllHistory": "Delete all history", @@ -65,6 +65,8 @@ "player": { "audioOnly": "Audio only", "theatreMode": "Theatre mode", + "pauseTimer": "Pause timer", + "pauseVideoIn": "Pause video in ", "share": { "title": "Share", "materialiousLink": "Copy Materialious link", diff --git a/materialious/src/lib/misc.ts b/materialious/src/lib/misc.ts index 23002461..c1aecfe0 100644 --- a/materialious/src/lib/misc.ts +++ b/materialious/src/lib/misc.ts @@ -160,6 +160,25 @@ function convertToSeconds(time: string): number { return seconds; } +export function humanizeSeconds(totalSeconds: number): string { + const secondsInMinute = 60; + const secondsInHour = 3600; + + const hours = Math.floor(totalSeconds / secondsInHour); + const minutes = Math.floor((totalSeconds % secondsInHour) / secondsInMinute); + + const parts: string[] = []; + + if (hours > 0) { + parts.push(`${hours} hour${hours > 1 ? 's' : ''}`); + } + if (minutes > 0) { + parts.push(`${minutes} minute${minutes > 1 ? 's' : ''}`); + } + + return parts.join(', '); +} + export function proxyVideoUrl(source: string): string { const rawSrc = new URL(source); rawSrc.host = get(instanceStore).replace('http://', '').replace( diff --git a/materialious/src/lib/patches/youtubejs.ts b/materialious/src/lib/patches/youtubejs.ts index eedfb662..0271bf30 100644 --- a/materialious/src/lib/patches/youtubejs.ts +++ b/materialious/src/lib/patches/youtubejs.ts @@ -85,8 +85,6 @@ export async function patchYoutubeJs(videoId: string): Promise { const video = await youtube.getInfo(videoId); - console.log(video); - if (!video.primary_info || !video.secondary_info) { throw new Error('Unable to pull video info from youtube.js'); } diff --git a/materialious/src/routes/(app)/watch/[slug]/+page.svelte b/materialious/src/routes/(app)/watch/[slug]/+page.svelte index 2bfca96d..80457f8e 100644 --- a/materialious/src/routes/(app)/watch/[slug]/+page.svelte +++ b/materialious/src/routes/(app)/watch/[slug]/+page.svelte @@ -11,13 +11,10 @@ } from '$lib/Api/index.js'; import type { Comments, PlaylistPage, PlaylistPageVideo } from '$lib/Api/model.js'; import Comment from '$lib/Comment.svelte'; - import Player from '$lib/Player.svelte'; - import ShareVideo from '$lib/ShareVideo.svelte'; - import Thumbnail from '$lib/Thumbnail.svelte'; - import Transcript from '$lib/Transcript.svelte'; import { cleanNumber, getBestThumbnail, + humanizeSeconds, letterCase, numberWithCommas, proxyGoogleImage, @@ -25,6 +22,8 @@ unsafeRandomItem } from '$lib/misc'; import type { PlayerEvents } from '$lib/player'; + import Player from '$lib/Player.svelte'; + import ShareVideo from '$lib/ShareVideo.svelte'; import { activePageStore, authStore, @@ -40,7 +39,10 @@ syncPartyConnectionsStore, syncPartyPeerStore } from '$lib/store'; + import Thumbnail from '$lib/Thumbnail.svelte'; + import Transcript from '$lib/Transcript.svelte'; import { mergeMediaFromDASH } from '$lib/videoDownload'; + import ui from 'beercss'; import type { DataConnection } from 'peerjs'; import { type Segment } from 'sponsorblock-api'; import { onDestroy, onMount } from 'svelte'; @@ -78,6 +80,8 @@ let segments: Segment[] = []; + let pauseTimerSeconds: number = -1; + let showTranscript = false; playlistSettingsStore.subscribe((playlistSetting) => { @@ -296,6 +300,10 @@ // Reset title when page left. document.title = 'Materialious'; + if (pauseTimeout) { + clearTimeout(pauseTimeout); + } + if ( get(playerMiniPlayerStore) && !player.paused && @@ -393,10 +401,24 @@ subscribed = !subscribed; } - async function toggleTheatreMode() { + function toggleTheatreMode() { theatreMode = !theatreMode; } + let pauseTimeout: NodeJS.Timeout; + function setPauseTimer() { + if (pauseTimeout) { + clearTimeout(pauseTimeout); + } + pauseTimeout = setTimeout(() => { + player.pause(); + pauseTimerSeconds = 0; + clearTimeout(pauseTimeout); + }, pauseTimerSeconds * 1000); + + ui('#pause-timer'); + } + let downloadStage: string | undefined; let downloadProgress: number = 0; @@ -553,6 +575,21 @@ width_wide
{$_('player.theatreMode')}
+ {#if data.video.lengthSeconds > 60 && !data.video.hlsUrl} + + {/if} + + + +