@@ -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">
|
||||
|
||||
Generated
+2
-2
@@ -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,6 +1,6 @@
|
||||
{
|
||||
"name": "Materialious",
|
||||
"version": "1.9.10",
|
||||
"version": "1.9.11",
|
||||
"description": "Modern material design for Invidious.",
|
||||
"author": {
|
||||
"name": "Ward Pearce",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "materialious",
|
||||
"version": "1.9.10",
|
||||
"version": "1.9.11",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
:focus {
|
||||
outline: 4px solid var(--primary);
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.thumbnail-corner {
|
||||
padding: 0.1em 0.4em;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user