Merge pull request #975 from Materialious/update/1.9.7

Update/1.9.7
This commit is contained in:
Ward
2025-06-15 19:26:29 +12:00
committed by GitHub
parent d71ec9c910
commit d4e25689a9
12 changed files with 126 additions and 29 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 123
versionName "1.9.6"
versionCode 124
versionName "1.9.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -58,7 +58,11 @@
<release version="1.9.6" date="2025-6-14">
<release version="1.9.7" date="2025-6-15">
<url>https://github.com/Materialious/Materialious/releases/tag/1.9.7</url>
</release>
<release version="1.9.6" date="2025-6-14">
<url>https://github.com/Materialious/Materialious/releases/tag/1.9.6</url>
</release>
<release version="1.9.5" date="2025-6-09">
+15 -2
View File
@@ -1,16 +1,17 @@
{
"name": "Materialious",
"version": "1.9.6",
"version": "1.9.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "Materialious",
"version": "1.9.6",
"version": "1.9.7",
"license": "MIT",
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
"bgutils-js": "^3.2.0",
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.8/capacitor-nodejs.tgz",
"chokidar": "~4.0.3",
"electron-is-dev": "~2.0.0",
"electron-serve": "~1.1.0",
@@ -1797,6 +1798,18 @@
"node": ">= 0.4"
}
},
"node_modules/capacitor-nodejs": {
"version": "1.0.0-beta.8",
"resolved": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.8/capacitor-nodejs.tgz",
"integrity": "sha512-VAMCTBqz+sA3762kFhSyzXS0unm0EpsVSHLmDYsTYPTiXXZaFcGk27vfXakRyyXJexAUG2Y5rZka5BvH6EmeZw==",
"license": "MIT",
"engines": {
"node": ">=20.10"
},
"peerDependencies": {
"@capacitor/core": "^6.0.0"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.9.6",
"version": "1.9.7",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
@@ -24,6 +24,7 @@
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
"bgutils-js": "^3.2.0",
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.8/capacitor-nodejs.tgz",
"chokidar": "~4.0.3",
"electron-is-dev": "~2.0.0",
"electron-serve": "~1.1.0",
@@ -1,4 +1,6 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const CapacitorNodejs = require('../../../node_modules/capacitor-nodejs/electron/dist/plugin.js');
module.exports = {
CapacitorNodejs,
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.9.6",
"version": "1.9.7",
"private": true,
"scripts": {
"dev": "vite dev",
+13 -2
View File
@@ -44,6 +44,7 @@
import { injectSABR } from '$lib/sabr';
import { patchYoutubeJs } from '$lib/patches/youtubejs';
import { playbackRates } from '$lib/const';
import { EndTimeElement } from '$lib/shaka-elements/endTime';
interface Props {
data: { video: VideoPlay; content: PhasedDescription; playlistId: string | null };
@@ -387,13 +388,19 @@
playerElement
);
shaka.ui.Controls.registerElement('end_time', {
create: (parent: HTMLElement, controls: shaka.ui.Controls) => {
return new EndTimeElement(parent, controls);
}
});
shakaUi.configure({
controlPanelElements: [
'play_pause',
Capacitor.getPlatform() === 'android' ? '' : 'volume',
'spacer',
'chapter',
'time_and_duration',
data.video.liveNow || data.video.lengthSeconds < 240 ? '' : 'end_time',
'captions',
'overflow_menu',
'fullscreen'
@@ -401,7 +408,6 @@
overflowMenuButtons: [
'cast',
'airplay',
'captions',
'quality',
'playback_rate',
'loop',
@@ -655,6 +661,11 @@
id="player"
poster={getBestThumbnail(data.video.videoThumbnails, 1251, 781)}
></video>
{#if isEmbed}
<div class="chip blur" style="position: absolute;top: 10px;left: 10px;font-size: 18px;">
{data.video.title}
</div>
{/if}
</div>
{#if showVideoRetry}
@@ -0,0 +1,41 @@
import shaka from 'shaka-player/dist/shaka-player.ui';
export class EndTimeElement extends shaka.ui.Element {
public video: HTMLMediaElement;
protected button: HTMLButtonElement;
constructor(parent: HTMLElement, controls: shaka.ui.Controls) {
super(parent, controls);
this.video = (this.player as shaka.Player).getMediaElement() as HTMLMediaElement;
this.button = document.createElement('button');
this.button.classList.add('shaka-current-time');
this.button.disabled = true;
(this.parent as HTMLElement).appendChild(this.button);
this.updateTime = this.updateTime.bind(this);
(this.eventManager as shaka.util.EventManager).listen(
this.video,
'timeupdate',
this.updateTime
);
}
private updateTime(): void {
const duration = this.video.duration;
const currentTime = this.video.currentTime;
if (isNaN(duration) || isNaN(currentTime)) return;
const remainingTime: number = duration - currentTime;
const end: Date = new Date(Date.now() + remainingTime * 1000);
const formatted: string = end.toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit',
hour12: true
});
this.button.textContent = `Ends at ${formatted}`;
}
}
@@ -70,6 +70,10 @@
videoId = url.pathname.split('/')[1];
}
if (videoId === 'shorts') {
videoId = url.pathname.split('/')[2];
}
if (!videoId) {
return;
}
@@ -72,6 +72,8 @@
let playerCurrentTime: number = $state(0);
let currentChapterStartTime: number = $state(0);
function expandSummery(id: string) {
const element = document.getElementById(id);
if (element) {
@@ -243,6 +245,15 @@
playerElement.addEventListener('timeupdate', () => {
if (!playerElement) return;
playerCurrentTime = playerElement.currentTime;
if (data.content.timestamps) {
for (const timestamp of data.content.timestamps) {
if (timestamp.time >= playerCurrentTime && timestamp.endTime <= playerCurrentTime) {
currentChapterStartTime = timestamp.time;
break;
}
}
}
});
playerElement.addEventListener('ended', async () => {
@@ -409,6 +420,15 @@
ui('#pause-timer');
}
function goToChapter() {
const chaptersScrollable = document.getElementById('chapters');
const currentTimestamp = document.getElementById(`timestamp-${currentChapterStartTime}`);
if (!chaptersScrollable || !currentTimestamp) return;
chaptersScrollable.scrollTop = currentTimestamp.offsetTop - chaptersScrollable.offsetTop - 550;
}
</script>
<svelte:head>
@@ -599,7 +619,7 @@
{#if data.content.timestamps.length > 0}
<article>
<details>
<summary id="chapter-section" class="bold none">
<summary id="chapter-section" class="bold none" onclick={goToChapter}>
<nav>
<div class="max">
<p>{$_('player.chapters')}</p>
@@ -608,11 +628,12 @@
</nav>
</summary>
<div class="space"></div>
<div class="chapter-list">
<div class="chapter-list" id="chapters">
<ul class="list">
{#each data.content.timestamps as timestamp}
<li
role="presentation"
id={`timestamp-${timestamp.time}`}
onclick={() => {
if (playerElement) playerElement.currentTime = timestamp.time;
}}
@@ -788,7 +809,8 @@
<style>
.chapter-list {
max-height: 300px;
overflow-x: scroll;
overflow-y: scroll;
overflow-x: hidden;
}
.video-actions {
@@ -1,23 +1,22 @@
import { getVideo } from '$lib/api/index';
import { playerProxyVideosStore } from '$lib/store';
import type { PhasedDescription } from '$lib/timestamps';
import { error } from '@sveltejs/kit';
import { get } from 'svelte/store';
export async function load({ params }) {
let video;
try {
video = await getVideo(params.slug, get(playerProxyVideosStore));
} catch (errorMessage: any) {
error(500, errorMessage);
}
let video;
try {
video = await getVideo(params.slug, get(playerProxyVideosStore));
} catch (errorMessage: any) {
error(500, errorMessage);
}
return {
video: video,
content: {
description: '',
timestamps: []
} as PhasedDescription,
playlistId: null
};
}
return {
video: video,
content: {
description: '',
timestamps: []
},
playlistId: null
};
}
+1 -1
View File
@@ -3,7 +3,7 @@ import os
import re
from datetime import datetime
LATEST_VERSION = "1.9.6"
LATEST_VERSION = "1.9.7"
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")