Merge pull request #985 from Materialious/update/1.9.13

Minor Android TV fixes
This commit is contained in:
Ward
2025-06-19 22:32:00 +12:00
committed by GitHub
14 changed files with 73 additions and 56 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 129
versionName "1.9.12"
versionCode 130
versionName "1.9.13"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -64,7 +64,11 @@
<release version="1.9.12" date="2025-6-19">
<release version="1.9.13" date="2025-6-19">
<url>https://github.com/Materialious/Materialious/releases/tag/1.9.13</url>
</release>
<release version="1.9.12" date="2025-6-19">
<url>https://github.com/Materialious/Materialious/releases/tag/1.9.12</url>
</release>
<release version="1.9.11" date="2025-6-19">
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "Materialious",
"version": "1.9.11",
"version": "1.9.12",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "Materialious",
"version": "1.9.11",
"version": "1.9.12",
"license": "MIT",
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.9.12",
"version": "1.9.13",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.9.12",
"version": "1.9.13",
"private": true,
"scripts": {
"dev": "vite dev",
@@ -1,5 +1,5 @@
<script lang="ts">
import androidTv from '$lib/android/plugins/androidTv';
import { isAndroidTvStore } from '$lib/store';
import { onMount } from 'svelte';
let { children } = $props();
@@ -9,7 +9,7 @@
let mediumCol = $state('6');
async function checkWidth() {
if ((await androidTv.isAndroidTv()).value) {
if ($isAndroidTvStore) {
mediumCol = '3';
} else if (innerWidth <= 1750) {
largeCol = '4';
@@ -7,9 +7,9 @@
import {
interfaceSearchHistoryEnabled,
interfaceSearchSuggestionsStore,
isAndroidTvStore,
searchHistoryStore
} from '../store';
import androidTv from '$lib/android/plugins/androidTv';
const dispatch = createEventDispatcher();
@@ -22,8 +22,6 @@
let showSearchBox = $state(false);
let isAndroidTv = $state(false);
let debounceTimer: NodeJS.Timeout;
function debouncedSearch(event: any) {
if (!searchSuggestions) return;
@@ -92,7 +90,6 @@
}
onMount(async () => {
isAndroidTv = (await androidTv.isAndroidTv()).value;
Mousetrap.bind(['ctrl+k', 'command+k'], () => {
document.getElementById('search-box')?.focus();
showSearchBox = !showSearchBox;
@@ -113,8 +110,8 @@
>
<div
class="field prefix fill no-margin rounded"
class:search={!isAndroidTv}
class:search-tv={isAndroidTv}
class:search={!$isAndroidTvStore}
class:search-tv={$isAndroidTvStore}
>
<i class="front" tabindex="-1">search</i>
<input
@@ -8,6 +8,7 @@
import Player from './Player.svelte';
import Ryd from './RYD.svelte';
import SponsorBlock from './SponsorBlock.svelte';
import { isAndroidTvStore } from '$lib/store';
let activeTab:
| 'interface'
@@ -42,7 +43,7 @@
</nav>
<div>
<nav class="tabbed small" tabindex="0" role="region">
<nav tabindex="0" class="tabbed small" style="outline: none" role="region">
<a class:active={activeTab === 'interface'} onclick={() => (activeTab = 'interface')}>
<i>grid_view</i>
<span>{$_('layout.interface')}</span>
@@ -51,7 +52,7 @@
<i>smart_display</i>
<span>{$_('layout.player.title')}</span>
</a>
<a class:active={activeTab === 'ryd'} onclick={() => (activeTab = 'ryd')}>
<a tabindex="0" class:active={activeTab === 'ryd'} onclick={() => (activeTab = 'ryd')}>
<i>thumb_down</i>
<span>RYD</span>
</a>
@@ -67,22 +68,28 @@
<i>keyboard_double_arrow_down</i>
<span>{$_('layout.deArrow.title')}</span>
</a>
<a class:active={activeTab === 'data'} onclick={() => (activeTab = 'data')}>
<i>save</i>
<span>{$_('layout.dataPreferences.dataPreferences')}</span>
</a>
<a href="https://github.com/sponsors/WardPearce" target="_blank" referrerpolicy="no-referrer">
<i>favorite</i>
<span>{$_('donate')}</span>
</a>
<a
href="https://github.com/Materialious/Materialious"
target="_blank"
referrerpolicy="no-referrer"
>
<i>code</i>
<span>GitHub</span>
</a>
{#if !$isAndroidTvStore}
<a class:active={activeTab === 'data'} onclick={() => (activeTab = 'data')}>
<i>save</i>
<span>{$_('layout.dataPreferences.dataPreferences')}</span>
</a>
<a
href="https://github.com/sponsors/WardPearce"
target="_blank"
referrerpolicy="no-referrer"
>
<i>favorite</i>
<span>{$_('donate')}</span>
</a>
<a
href="https://github.com/Materialious/Materialious"
target="_blank"
referrerpolicy="no-referrer"
>
<i>code</i>
<span>GitHub</span>
</a>
{/if}
</nav>
<div class="page padding" class:active={activeTab === 'interface'}>
<Interface />
@@ -13,6 +13,7 @@
authStore,
deArrowEnabledStore,
interfaceLowBandwidthMode,
isAndroidTvStore,
playerSavePlaybackPositionStore,
syncPartyConnectionsStore,
syncPartyPeerStore,
@@ -20,7 +21,6 @@
synciousStore
} from '../store';
import { goto } from '$app/navigation';
import androidTv from '$lib/android/plugins/androidTv';
interface Props {
video: VideoBase | Video | Notification | PlaylistPageVideo;
@@ -137,6 +137,10 @@
}
function calcThumbnailPlaceholderHeight() {
if ($isAndroidTvStore) {
placeholderHeight = innerWidth / 3;
return;
}
if (!sideways) {
if (innerWidth < 1000) {
if (innerWidth < 600) {
@@ -158,7 +162,7 @@
tabindex="0"
role="button"
onclick={async () => {
if ((await androidTv.isAndroidTv()).value) {
if ($isAndroidTvStore) {
goto(`${location.origin}/embed/${video.videoId}`);
}
}}
-5
View File
@@ -1,8 +1,3 @@
:focus {
outline: 4px solid var(--primary);
box-shadow: none !important;
}
.thumbnail-corner {
padding: 0.1em 0.4em;
}
+2
View File
@@ -130,3 +130,5 @@ export const searchCacheStore: Writable<{
[searchTypeAndQuery: string]: (Channel | Video | Playlist | HashTag)[];
}> = writable({});
export const feedLastItemId: Writable<string | undefined> = writable(undefined);
export const isAndroidTvStore: Writable<boolean> = writable(false);
+20 -9
View File
@@ -20,6 +20,7 @@
instanceStore,
interfaceAmoledTheme,
interfaceDefaultPage,
isAndroidTvStore,
syncPartyPeerStore,
themeColorStore
} from '$lib/store';
@@ -31,7 +32,7 @@
import ui from 'beercss';
import 'material-dynamic-colors';
import { onMount } from 'svelte';
import { _ } from '$lib/i18n';
import { _, initI18n } from '$lib/i18n';
import { get } from 'svelte/store';
import { pwaInfo } from 'virtual:pwa-info';
import androidTv from '$lib/android/plugins/androidTv';
@@ -41,8 +42,6 @@
let mobileSearchShow = $state(false);
let isAndroidTv = $state(false);
let isLoggedIn = $state(false);
authStore.subscribe((value) => {
isLoggedIn = value !== null;
@@ -97,7 +96,7 @@
});
async function login() {
if (!isAndroidTv) {
if (!$isAndroidTvStore) {
const path = new URL(`${get(instanceStore)}/authorize_token`);
const searchParams = new URLSearchParams({
scopes: ':feed,:subscriptions*,:playlists*,:history*,:notifications*'
@@ -122,6 +121,9 @@
let rawPassword: string = $state('');
async function usernamePasswordLogin(event: Event) {
event.preventDefault();
if (!$isAndroidTvStore) return;
loginError = false;
const body = new FormData();
@@ -171,9 +173,9 @@
onMount(async () => {
ui();
isAndroidTv = (await androidTv.isAndroidTv()).value;
$isAndroidTvStore = (await androidTv.isAndroidTv()).value;
if (isAndroidTv) {
if ($isAndroidTvStore) {
const topContent = document.getElementById('top-content') as HTMLElement;
Mousetrap.bind('down', () => {
if (topContent.contains(document.activeElement)) {
@@ -231,9 +233,18 @@
<svelte:head>
{@html webManifestLink}
{#if $isAndroidTvStore}
<style>
:focus {
outline: 4px solid var(--primary);
box-shadow: none !important;
}
</style>
{/if}
</svelte:head>
{#if !isAndroidTv}
{#if !$isAndroidTvStore}
<nav class="left m l small">
<header></header>
{#each getPages() as navPage}
@@ -368,9 +379,9 @@
class="responsive max root"
tabindex="0"
role="region"
class:root-not-tv={!isAndroidTv}
class:root-not-tv={!$isAndroidTvStore}
>
{#if isAndroidTv}
{#if $isAndroidTvStore}
<div class="tabs">
{#each getPages() as navPage}
{#if !navPage.requiresAuth || isLoggedIn}
@@ -4,17 +4,15 @@
import VideoList from '$lib/components/VideoList.svelte';
import { unsafeRandomItem } from '$lib/misc';
import { cleanNumber } from '$lib/numbers';
import { playlistSettingsStore } from '$lib/store';
import { isAndroidTvStore, playlistSettingsStore } from '$lib/store';
import { Clipboard } from '@capacitor/clipboard';
import { Capacitor } from '@capacitor/core';
import { onMount } from 'svelte';
import { _ } from '$lib/i18n';
import androidTv from '$lib/android/plugins/androidTv.js';
let { data } = $props();
let videos: PlaylistPageVideo[] | undefined = $state();
let isAndroidTv: boolean = $state(false);
if (data.playlist.videos.length > 0) {
videos = data.playlist.videos
@@ -26,7 +24,6 @@
});
onMount(async () => {
isAndroidTv = (await androidTv.isAndroidTv()).value;
for (let page = 1; page++; ) {
const newVideos = (await getPlaylist(data.playlist.playlistId, page)).videos;
if (newVideos.length === 0) {
@@ -51,7 +48,7 @@
{#if videos}
<nav>
<a
href={!isAndroidTv
href={!$isAndroidTvStore
? `/watch/${videos[0].videoId}?playlist=${data.playlist.playlistId}`
: `/embed/${videos[0].videoId}?playlist=${data.playlist.playlistId}`}
class="button circle extra no-margin"
@@ -63,7 +60,7 @@
</a>
<a
href={!isAndroidTv
href={!$isAndroidTvStore
? `/watch/${unsafeRandomItem(videos).videoId}?playlist=${data.playlist.playlistId}`
: `/embed/${unsafeRandomItem(videos).videoId}?playlist=${data.playlist.playlistId}`}
onclick={() =>
+1 -1
View File
@@ -3,7 +3,7 @@ import os
import re
from datetime import datetime
LATEST_VERSION = "1.9.12"
LATEST_VERSION = "1.9.13"
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")