Merge pull request #982 from Materialious/update/1.9.11

Update/1.9.11
This commit is contained in:
Ward
2025-06-19 18:27:41 +12:00
committed by GitHub
parent 51ae8aad74
commit 1067c6ee76
18 changed files with 130 additions and 57 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 127
versionName "1.9.10"
versionCode 128
versionName "1.9.11"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -2,6 +2,7 @@ package us.materialio.app;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebSettings;
import com.getcapacitor.BridgeActivity;
@@ -19,5 +20,8 @@ public class MainActivity extends BridgeActivity {
WebView webview = getBridge().getWebView();
webview.setOverScrollMode(WebView.OVER_SCROLL_NEVER);
webview.setVerticalScrollBarEnabled(false);
WebSettings settings = webview.getSettings();
settings.setMediaPlaybackRequiresUserGesture(false);
}
}
@@ -62,7 +62,11 @@
<release version="1.9.10" date="2025-6-19">
<release version="1.9.11" date="2025-6-19">
<url>https://github.com/Materialious/Materialious/releases/tag/1.9.11</url>
</release>
<release version="1.9.10" date="2025-6-19">
<url>https://github.com/Materialious/Materialious/releases/tag/1.9.10</url>
</release>
<release version="1.9.9" date="2025-6-19">
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "Materialious",
"version": "1.9.9",
"version": "1.9.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "Materialious",
"version": "1.9.9",
"version": "1.9.11",
"license": "MIT",
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.9.10",
"version": "1.9.11",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.9.10",
"version": "1.9.11",
"private": true,
"scripts": {
"dev": "vite dev",
+23 -6
View File
@@ -70,6 +70,7 @@
let watchProgressTimeout: NodeJS.Timeout;
let playerElementResizeObserver: ResizeObserver | undefined;
let showVideoRetry = $state(false);
let isAndroidTv = $state(false);
let player: shaka.Player;
let shakaUi: shaka.ui.Overlay;
@@ -191,7 +192,7 @@
if (
Capacitor.getPlatform() === 'android' &&
data.video.adaptiveFormats.length > 0 &&
!(await androidTv.isAndroidTv()).value
!isAndroidTv
) {
const videoFormats = data.video.adaptiveFormats.filter((format) =>
format.type.startsWith('video/')
@@ -404,6 +405,8 @@
return;
}
isAndroidTv = (await androidTv.isAndroidTv()).value;
HttpFetchPlugin.cacheManager.clearCache();
player = new shaka.Player();
@@ -575,9 +578,7 @@
setChapterMarkers();
if ((await androidTv.isAndroidTv()).value) {
shakaUi.getControls()?.toggleFullScreen();
if (isAndroidTv) {
Mousetrap.bind('enter', () => {
if (playerElement?.paused) {
playerElement?.play();
@@ -666,6 +667,8 @@
}
}
Mousetrap.unbind(['enter', 'left', 'right']);
if (watchProgressTimeout) {
clearTimeout(watchProgressTimeout);
}
@@ -699,6 +702,8 @@
<div
id="shaka-container"
class="player-theme"
class:contain-video={!isAndroidTv}
class:tv-contain-video={isAndroidTv}
data-shaka-player-container
class:hide={showVideoRetry}
>
@@ -709,7 +714,7 @@
poster={getBestThumbnail(data.video.videoThumbnails, 1251, 781)}
></video>
{#if isEmbed}
<div class="chip blur" style="position: absolute;top: 10px;left: 10px;font-size: 18px;">
<div class="chip blur embed" style="position: absolute;top: 10px;left: 10px;font-size: 18px;">
{data.video.title}
</div>
{/if}
@@ -742,7 +747,7 @@
{/if}
<style>
.player-theme {
.contain-video {
max-height: 80vh;
max-width: calc(80vh * 16 / 9);
overflow: hidden;
@@ -752,6 +757,18 @@
aspect-ratio: 16 / 9;
}
.tv-contain-video {
height: 100vh;
width: calc(100vh * 16 / 9);
max-width: 100vw;
max-height: 100vh;
overflow: hidden;
position: relative;
flex: 1;
background-color: black;
aspect-ratio: 16 / 9;
}
video {
position: absolute;
top: 50%;
@@ -109,7 +109,6 @@
await tick();
document.getElementById('search')?.focus();
}}
tabindex="0"
role="presentation"
>
<div
@@ -119,6 +118,7 @@
>
<i class="front" tabindex="-1">search</i>
<input
tabindex="0"
id="search-box"
placeholder={$_('searchPlaceholder')}
bind:value={search}
@@ -131,6 +131,7 @@
>arrow_back</i
>
<input
tabindex="0"
placeholder={$_('searchPlaceholder')}
type="text"
id="search"
@@ -16,8 +16,8 @@
>
<nav>
<div class="field label border max">
<input bind:value={synciousInstance} name="syncious-instance" type="text" />
<label for="syncious-instance">{$_('layout.instanceUrl')}</label>
<input tabindex="0" bind:value={synciousInstance} name="syncious-instance" type="text" />
<label tabindex="-1" for="syncious-instance">{$_('layout.instanceUrl')}</label>
</div>
<button class="square round">
<i>done</i>
@@ -29,7 +29,7 @@
<div class="max">
<p>{$_('enabled')}</p>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
bind:checked={$synciousStore}
onclick={() => synciousStore.set(!$synciousStore)}
@@ -43,7 +43,7 @@
<div class="max">
<p>{$_('layout.deArrow.titleOnly')}</p>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
bind:checked={$deArrowTitlesOnly}
onclick={() => deArrowTitlesOnly.set(!$deArrowTitlesOnly)}
@@ -57,7 +57,7 @@
<div class="max">
<p>{$_('enabled')}</p>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
bind:checked={$deArrowEnabledStore}
onclick={() => deArrowEnabledStore.set(!$deArrowEnabledStore)}
@@ -120,8 +120,8 @@
<form onsubmit={setInstance}>
<nav>
<div class="field label border max" class:invalid={invalidInstance}>
<input bind:value={invidiousInstance} name="invidious-instance" type="text" />
<label for="invidious-instance">{$_('layout.instanceUrl')}</label>
<input tabindex="0" bind:value={invidiousInstance} name="invidious-instance" type="text" />
<label tabindex="-1" for="invidious-instance">{$_('layout.instanceUrl')}</label>
{#if invalidInstance}
<span class="error">{$_('invalidInstance')}</span>
{/if}
@@ -177,7 +177,7 @@
<div class="max">
<div>{$_('layout.theme.AmoledTheme')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$interfaceAmoledTheme}
@@ -194,7 +194,7 @@
<div class="max">
<div>{$_('layout.searchHistory')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$interfaceSearchHistoryEnabled}
@@ -213,7 +213,7 @@
<div class="max">
<div>{$_('layout.lowBandwidthMode')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$interfaceLowBandwidthMode}
@@ -229,7 +229,7 @@
<div class="max">
<div>{$_('layout.searchSuggestions')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$interfaceSearchSuggestionsStore}
@@ -245,7 +245,7 @@
<div class="max">
<div>{$_('layout.expandDescription')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$interfaceAutoExpandDesc}
@@ -261,7 +261,7 @@
<div class="max">
<div>{$_('layout.expandChapters')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$interfaceAutoExpandChapters}
@@ -277,7 +277,7 @@
<div class="max">
<div>{$_('layout.expandComments')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$interfaceAutoExpandComments}
@@ -289,19 +289,29 @@
</div>
<div class="field label suffix border">
<select name="region" bind:value={region} onchange={() => interfaceRegionStore.set(region)}>
<select
tabindex="0"
name="region"
bind:value={region}
onchange={() => interfaceRegionStore.set(region)}
>
{#each iso31661 as region}
<option selected={$interfaceRegionStore === region.alpha2} value={region.alpha2}
>{region.alpha2} - {region.name}</option
>
{/each}
</select>
<label for="region">{$_('region')}</label>
<label tabindex="-1" for="region">{$_('region')}</label>
<i>arrow_drop_down</i>
</div>
<div class="field label suffix border">
<select name="case" bind:value={forceCase} onchange={() => interfaceForceCase.set(forceCase)}>
<select
tabindex="0"
name="case"
bind:value={forceCase}
onchange={() => interfaceForceCase.set(forceCase)}
>
<option selected={$interfaceForceCase === null} value={null}>Default</option>
{#each titleCases as caseType}
<option selected={$interfaceForceCase === caseType} value={caseType}
@@ -309,13 +319,14 @@
>
{/each}
</select>
<label for="case">{$_('letterCase')}</label>
<label tabindex="-1" for="case">{$_('letterCase')}</label>
<i>arrow_drop_down</i>
</div>
<div class="field label suffix border">
<select
name="defaultPage"
tabindex="0"
bind:value={defaultPage}
onchange={() => interfaceDefaultPage.set(defaultPage)}
>
@@ -326,7 +337,7 @@
{/if}
{/each}
</select>
<label for="defaultPage">{$_('defaultPage')}</label>
<label tabindex="-1" for="defaultPage">{$_('defaultPage')}</label>
<i>arrow_drop_down</i>
</div>
@@ -63,6 +63,7 @@
<div class="margin"></div>
<div class="field label suffix border">
<select
tabindex="0"
name="case"
bind:value={defaultLanguage}
onchange={() => playerDefaultLanguage.set(defaultLanguage)}
@@ -73,12 +74,13 @@
>
{/each}
</select>
<label for="case">{$_('player.defaultLanguage')}</label>
<label tabindex="-1" for="case">{$_('player.defaultLanguage')}</label>
<i>arrow_drop_down</i>
</div>
<div class="field label suffix border">
<select
tabindex="0"
name="quality"
id="quality"
bind:value={$playerDefaultQualityStore}
@@ -94,12 +96,13 @@
<option value="1440">1440p (2K)</option>
<option value="2160">2160p (4K UHD)</option>
</select>
<label for="quality">{$_('player.preferredQuality')}</label>
<label tabindex="-1" for="quality">{$_('player.preferredQuality')}</label>
<i>arrow_drop_down</i>
</div>
<div class="field label suffix border">
<select
tabindex="0"
name="quality"
id="quality"
bind:value={$playerDefaultPlaybackSpeed}
@@ -109,18 +112,23 @@
<option value={speed}>x{speed}</option>
{/each}
</select>
<label for="quality">{$_('layout.player.defaultPlaybackSpeed')}</label>
<label tabindex="-1" for="quality">{$_('layout.player.defaultPlaybackSpeed')}</label>
<i>arrow_drop_down</i>
</div>
{#if Capacitor.isNativePlatform()}
<div class="field suffix border label">
<select name="ytfallback" bind:value={localVideoFallback} onchange={onLocalVideoFallbackChange}>
<select
tabindex="0"
name="ytfallback"
bind:value={localVideoFallback}
onchange={onLocalVideoFallbackChange}
>
<option value="enabled">{$_('enabled')}</option>
<option value="always">{$_('layout.player.youtubeJsAlways')}</option>
<option value="disabled">{$_('disabled')}</option>
</select>
<label for="ytfallback">{$_('layout.player.localVideoFallback')}</label>
<label tabindex="-1" for="ytfallback">{$_('layout.player.localVideoFallback')}</label>
<i>arrow_drop_down</i>
</div>
{/if}
@@ -130,7 +138,7 @@
<div class="max">
<div>{$_('layout.player.autoPlay')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerAutoPlayStore}
@@ -146,7 +154,7 @@
<div class="max">
<div>{$_('layout.player.alwaysLoopVideo')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerAlwaysLoopStore}
@@ -163,7 +171,7 @@
<div class="max">
<div>{$_('layout.player.lockOrientation')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerAndroidLockOrientation}
@@ -181,7 +189,7 @@
<div class="max">
<div>{$_('layout.player.proxyVideos')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerProxyVideosStore}
@@ -198,7 +206,7 @@
<div class="max">
<div>{$_('layout.player.savePlaybackPosition')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerSavePlaybackPositionStore}
@@ -214,7 +222,7 @@
<div class="max">
<div>{$_('layout.player.theatreModeByDefault')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerTheatreModeByDefaultStore}
@@ -230,7 +238,7 @@
<div class="max">
<div>{$_('layout.player.autoPlayNextByDefault')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerAutoplayNextByDefaultStore}
@@ -246,7 +254,7 @@
<div class="max">
<div>{$_('layout.player.playerStatistics')}</div>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
bind:checked={$playerStatisticsByDefault}
@@ -16,8 +16,8 @@
>
<nav>
<div class="field label border max">
<input bind:value={returnYTInstance} name="returnyt-instance" type="text" />
<label for="returnyt-instance">{$_('layout.instanceUrl')}</label>
<input tabindex="0" bind:value={returnYTInstance} name="returnyt-instance" type="text" />
<label tabindex="-1" for="returnyt-instance">{$_('layout.instanceUrl')}</label>
</div>
<button class="square round">
<i>done</i>
@@ -29,7 +29,7 @@
<div class="max">
<p>{$_('enabled')}</p>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
bind:checked={$returnYtDislikesStore}
onclick={() => returnYtDislikesStore.set(!$returnYtDislikesStore)}
@@ -43,8 +43,13 @@
>
<nav>
<div class="field label border max">
<input bind:value={sponsorBlockInstance} name="sponsorblock-instance" type="text" />
<label for="sponsorblock-instance">{$_('layout.instanceUrl')}</label>
<input
tabindex="0"
bind:value={sponsorBlockInstance}
name="sponsorblock-instance"
type="text"
/>
<label tabindex="-1" for="sponsorblock-instance">{$_('layout.instanceUrl')}</label>
</div>
<button class="square round">
<i>done</i>
@@ -56,7 +61,7 @@
<div class="max">
<p>{$_('enabled')}</p>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
bind:checked={$sponsorBlockStore}
onclick={() => sponsorBlockStore.set(!$sponsorBlockStore)}
@@ -70,7 +75,7 @@
<div class="max">
<p>{$_('layout.sponsors.disableToast')}</p>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
bind:checked={$sponsorBlockDisplayToastStore}
onclick={() => sponsorBlockDisplayToastStore.set(!$sponsorBlockDisplayToastStore)}
@@ -104,7 +109,7 @@
<div class="max">
<p>{sponsor.name}</p>
</div>
<label class="switch">
<label class="switch" tabindex="0" role="switch">
<input
type="checkbox"
checked={sponsorCategoriesList.includes(sponsor.category)}
@@ -159,7 +159,7 @@
role="button"
onclick={async () => {
if ((await androidTv.isAndroidTv()).value) {
goto(watchUrl.toString());
goto(`${location.origin}/embed/${video.videoId}`);
}
}}
>
+5
View File
@@ -1,3 +1,8 @@
:focus {
outline: 4px solid var(--primary);
box-shadow: none !important;
}
.thumbnail-corner {
padding: 0.1em 0.4em;
}
+19 -1
View File
@@ -35,6 +35,7 @@
import { get } from 'svelte/store';
import { pwaInfo } from 'virtual:pwa-info';
import androidTv from '$lib/android/plugins/androidTv';
import Mousetrap from 'mousetrap';
let { children } = $props();
@@ -172,6 +173,16 @@
isAndroidTv = (await androidTv.isAndroidTv()).value;
if (isAndroidTv) {
const mainContent = document.getElementById('main-content') as HTMLElement;
Mousetrap.bind('down', () => {
if (!mainContent.contains(document.activeElement)) {
mainContent.focus();
return false;
}
});
}
document.addEventListener('click', linkClickOverwrite);
loadSettingsFromEnv();
@@ -265,6 +276,7 @@
onclick={() => goto($interfaceDefaultPage)}
style="cursor: pointer;"
class="m l"
tabindex="-1"
>
<Logo />
<h6 class="l">Materialious</h6>
@@ -351,7 +363,13 @@
{/if}
</dialog>
<main class="responsive max root" tabindex="0" role="region" class:root-not-tv={!isAndroidTv}>
<main
id="main-content"
class="responsive max root"
tabindex="0"
role="region"
class:root-not-tv={!isAndroidTv}
>
{#if isAndroidTv}
<div class="tabs">
{#each getPages() as navPage}
+1 -1
View File
@@ -3,7 +3,7 @@ import os
import re
from datetime import datetime
LATEST_VERSION = "1.9.10"
LATEST_VERSION = "1.9.11"
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")