Merge pull request #651 from Materialious/update/1.6.10

Update/1.6.10
This commit is contained in:
Ward
2024-10-17 15:27:25 +13:00
committed by GitHub
19 changed files with 308 additions and 139 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 60
versionName "1.6.9"
versionCode 61
versionName "1.6.10"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -12,6 +12,8 @@ dependencies {
implementation project(':capacitor-app')
implementation project(':capacitor-browser')
implementation project(':capacitor-clipboard')
implementation project(':capacitor-screen-orientation')
implementation project(':capacitor-status-bar')
implementation project(':capgo-inappbrowser')
implementation project(':mediagrid-capacitor-native-audio')
implementation project(':capacitor-nodejs')
@@ -11,6 +11,12 @@ project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/
include ':capacitor-clipboard'
project(':capacitor-clipboard').projectDir = new File('../node_modules/@capacitor/clipboard/android')
include ':capacitor-screen-orientation'
project(':capacitor-screen-orientation').projectDir = new File('../node_modules/@capacitor/screen-orientation/android')
include ':capacitor-status-bar'
project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android')
include ':capgo-inappbrowser'
project(':capgo-inappbrowser').projectDir = new File('../node_modules/@capgo/inappbrowser/android')
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.6.9",
"version": "1.6.10",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
+45 -19
View File
@@ -1,12 +1,12 @@
{
"name": "materialious",
"version": "1.6.9",
"version": "1.6.10",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "materialious",
"version": "1.6.9",
"version": "1.6.10",
"dependencies": {
"@capacitor-community/electron": "^5.0.1",
"@capacitor/android": "6.1.2",
@@ -15,6 +15,8 @@
"@capacitor/cli": "6.1.2",
"@capacitor/clipboard": "^6.0.1",
"@capacitor/core": "^6.1.2",
"@capacitor/screen-orientation": "^6.0.2",
"@capacitor/status-bar": "^6.0.1",
"@capgo/inappbrowser": "^6.6.8",
"@ffmpeg/ffmpeg": "^0.12.10",
"@mediagrid/capacitor-native-audio": "^1.0.0",
@@ -2190,6 +2192,24 @@
"tslib": "^2.1.0"
}
},
"node_modules/@capacitor/screen-orientation": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@capacitor/screen-orientation/-/screen-orientation-6.0.2.tgz",
"integrity": "sha512-CF+RFUIUYrvztlX+voHwvONdAbf/F9xuJWfMDnxjiGliu+oPTNLLTWxAFPmoyi3sVJcNoeQ+qwWzUfXa7ag59Q==",
"license": "MIT",
"peerDependencies": {
"@capacitor/core": "^6.0.0"
}
},
"node_modules/@capacitor/status-bar": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-6.0.1.tgz",
"integrity": "sha512-Usd9hZZQVAqy+jJfL7jRcYI7dcsxN09Na1yttwdl+F1bk3Ztoukk7CGPDm5VgKUSs53ihQBOy1+sczCACxhNiw==",
"license": "MIT",
"peerDependencies": {
"@capacitor/core": "^6.0.0"
}
},
"node_modules/@capgo/inappbrowser": {
"version": "6.6.8",
"resolved": "https://registry.npmjs.org/@capgo/inappbrowser/-/inappbrowser-6.6.8.tgz",
@@ -2794,10 +2814,11 @@
}
},
"node_modules/@polka/url": {
"version": "1.0.0-next.25",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz",
"integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==",
"dev": true
"version": "1.0.0-next.28",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
"integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
"dev": true,
"license": "MIT"
},
"node_modules/@prettier/plugin-xml": {
"version": "2.2.0",
@@ -3141,15 +3162,16 @@
}
},
"node_modules/@sveltejs/kit": {
"version": "2.5.27",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.27.tgz",
"integrity": "sha512-CcbRTzl+65oWljAASL6UlxM4x3NWwd0fjq5fQOfP243vs50myFQ8lil0fr3Im6HeeQqYUCtnv8HjO8REWVPjTw==",
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.1.tgz",
"integrity": "sha512-TBVnkwgYQT3EafGQK6Eyh5FlLEBlRhCmqPTwcdOs+QdnyUc3eCAxRWtXlFxIWtmk6pqv11zdng8qTpThdTogew==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.6.0",
"cookie": "^0.6.0",
"devalue": "^5.0.0",
"devalue": "^5.1.0",
"esm-env": "^1.0.0",
"import-meta-resolve": "^4.1.0",
"kleur": "^4.1.5",
@@ -3157,7 +3179,7 @@
"mrmime": "^2.0.0",
"sade": "^1.8.1",
"set-cookie-parser": "^2.6.0",
"sirv": "^2.0.4",
"sirv": "^3.0.0",
"tiny-glob": "^0.2.9"
},
"bin": {
@@ -5614,10 +5636,11 @@
}
},
"node_modules/devalue": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz",
"integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==",
"dev": true
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz",
"integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==",
"dev": true,
"license": "MIT"
},
"node_modules/dezalgo": {
"version": "1.0.4",
@@ -8866,6 +8889,7 @@
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
"integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
}
@@ -13569,17 +13593,18 @@
}
},
"node_modules/sirv": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
"integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz",
"integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@polka/url": "^1.0.0-next.24",
"mrmime": "^2.0.0",
"totalist": "^3.0.0"
},
"engines": {
"node": ">= 10"
"node": ">=18"
}
},
"node_modules/sisteransi": {
@@ -14807,6 +14832,7 @@
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
+4 -2
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.6.9",
"version": "1.6.10",
"private": true,
"scripts": {
"dev": "vite dev",
@@ -50,6 +50,8 @@
"@capacitor/cli": "6.1.2",
"@capacitor/clipboard": "^6.0.1",
"@capacitor/core": "^6.1.2",
"@capacitor/screen-orientation": "^6.0.2",
"@capacitor/status-bar": "^6.0.1",
"@capgo/inappbrowser": "^6.6.8",
"@ffmpeg/ffmpeg": "^0.12.10",
"@mediagrid/capacitor-native-audio": "^1.0.0",
@@ -74,4 +76,4 @@
"vidstack": "^1.12.9",
"youtubei.js": "^10.5.0"
}
}
}
+23
View File
@@ -0,0 +1,23 @@
<script lang="ts">
import { onMount } from 'svelte';
let largeCol = '2';
function checkWidth() {
if (innerWidth <= 1750) {
largeCol = '4';
} else {
largeCol = '2';
}
}
onMount(() => {
checkWidth();
addEventListener('resize', () => checkWidth());
});
</script>
<div class="s12 m6 l{largeCol}">
<slot />
</div>
+73 -47
View File
@@ -3,13 +3,15 @@
import { page } from '$app/stores';
import { Capacitor } from '@capacitor/core';
import { ScreenOrientation } from '@capacitor/screen-orientation';
import { StatusBar } from '@capacitor/status-bar';
import { AudioPlayer } from '@mediagrid/capacitor-native-audio';
import type { Page } from '@sveltejs/kit';
import { SponsorBlock, type Category, type Segment } from 'sponsorblock-api';
import { onDestroy, onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { get } from 'svelte/store';
import type { MediaTimeUpdateEvent, PlayerSrc } from 'vidstack';
import type { FullscreenChangeEvent, MediaTimeUpdateEvent, PlayerSrc } from 'vidstack';
import type { MediaPlayerElement } from 'vidstack/elements';
import { deleteVideoProgress, getVideoProgress, saveVideoProgress } from './Api';
import type { VideoPlay } from './Api/model';
@@ -26,6 +28,7 @@
miniPlayerSrcStore,
playerAlwaysLoopStore,
playerAndroidBgPlayer,
playerAndroidLockOrientation,
playerAutoPlayStore,
playerProxyVideosStore,
playerSavePlaybackPositionStore,
@@ -195,7 +198,7 @@
kind: 'captions',
language: caption.language_code,
// Need if captions are generated when youtube.js is being used.
src: caption.url.startsWith('blob:')
src: caption.url.startsWith('http')
? caption.url
: `${get(instanceStore)}${caption.url}`
});
@@ -344,57 +347,80 @@
await loadPlayerPos();
});
if (
Capacitor.getPlatform() === 'android' &&
get(playerAndroidBgPlayer) &&
data.video.adaptiveFormats.length > 0
) {
const highestBitrateAudio = data.video.adaptiveFormats
.filter((format) => format.type.startsWith('audio/'))
.reduce((prev, current) => {
return parseInt(prev.bitrate) > parseInt(current.bitrate) ? prev : current;
});
if (Capacitor.getPlatform() === 'android' && data.video.adaptiveFormats.length > 0) {
if (get(playerAndroidBgPlayer)) {
const highestBitrateAudio = data.video.adaptiveFormats
.filter((format) => format.type.startsWith('audio/'))
.reduce((prev, current) => {
return parseInt(prev.bitrate) > parseInt(current.bitrate) ? prev : current;
});
const audioId = { audioId: data.video.videoId };
const audioId = { audioId: data.video.videoId };
let isPlayingInBackground = false;
let isPlayingInBackground = false;
await AudioPlayer.create({
...audioId,
audioSource: !data.video.fallbackPatch
? proxyVideoUrl(highestBitrateAudio.url)
: highestBitrateAudio.url,
friendlyTitle: data.video.title,
useForNotification: true,
loop: player.loop,
isBackgroundMusic: false
});
AudioPlayer.onAppGainsFocus(audioId, async () => {
if (!isPlayingInBackground) return;
isPlayingInBackground = false;
await AudioPlayer.pause(audioId);
const audioPlayerTime = await AudioPlayer.getCurrentTime(audioId);
player.currentTime = Math.round(audioPlayerTime.currentTime);
await player.play();
});
AudioPlayer.onAppLosesFocus(audioId, async () => {
if (player.paused) return;
isPlayingInBackground = true;
await AudioPlayer.play(audioId);
await AudioPlayer.seek({
await AudioPlayer.create({
...audioId,
timeInSeconds: Math.round(player.currentTime)
audioSource: !data.video.fallbackPatch
? proxyVideoUrl(highestBitrateAudio.url)
: highestBitrateAudio.url,
friendlyTitle: data.video.title,
useForNotification: true,
loop: player.loop,
isBackgroundMusic: false
});
});
await AudioPlayer.initialize(audioId);
AudioPlayer.onAppGainsFocus(audioId, async () => {
if (!isPlayingInBackground) return;
isPlayingInBackground = false;
await AudioPlayer.pause(audioId);
const audioPlayerTime = await AudioPlayer.getCurrentTime(audioId);
player.currentTime = Math.round(audioPlayerTime.currentTime);
await player.play();
});
AudioPlayer.onAppLosesFocus(audioId, async () => {
if (player.paused) return;
isPlayingInBackground = true;
await AudioPlayer.play(audioId);
await AudioPlayer.seek({
...audioId,
timeInSeconds: Math.round(player.currentTime)
});
});
await AudioPlayer.initialize(audioId);
}
if (get(playerAndroidLockOrientation)) {
const videoFormats = data.video.adaptiveFormats.filter((format) =>
format.type.startsWith('video/')
);
const originalOrigination = await ScreenOrientation.orientation();
player.addEventListener('fullscreen-change', async (event: FullscreenChangeEvent) => {
if (event.detail && videoFormats[0].resolution) {
const widthHeight = videoFormats[0].resolution.split('x');
if (widthHeight.length !== 2) return;
if (Number(widthHeight[0]) > Number(widthHeight[1])) {
await StatusBar.setOverlaysWebView({ overlay: true });
await ScreenOrientation.lock({ orientation: 'landscape' });
} else {
await ScreenOrientation.lock({ orientation: 'portrait' });
}
} else {
await StatusBar.setOverlaysWebView({ overlay: false });
await ScreenOrientation.lock({ orientation: originalOrigination.type });
}
});
}
}
} else {
playerIsLive = true;
+38
View File
@@ -17,6 +17,7 @@
deArrowThumbnailInstanceStore,
deArrowTitlesOnly,
instanceStore,
interfaceAmoledTheme,
interfaceAutoExpandComments,
interfaceAutoExpandDesc,
interfaceForceCase,
@@ -25,6 +26,7 @@
interfaceSearchSuggestionsStore,
playerAlwaysLoopStore,
playerAndroidBgPlayer,
playerAndroidLockOrientation,
playerAutoPlayStore,
playerAutoplayNextByDefaultStore,
playerListenByDefaultStore,
@@ -46,6 +48,7 @@
synciousStore,
themeColorStore
} from './store';
import { setAmoledTheme } from './theme';
let sponsorCategoriesList: string[] = [];
sponsorBlockCategoriesStore.subscribe((value) => (sponsorCategoriesList = value));
@@ -82,6 +85,7 @@
const target = color.target;
const hex = (target as { value: string }).value;
await ui('theme', hex);
setAmoledTheme();
themeColorStore.set(hex);
}
@@ -190,6 +194,24 @@
<div class="margin"></div>
{#if $darkModeStore}
<div class="field no-margin">
<nav class="no-padding">
<div class="max">
<div>{$_('layout.theme.AmoledTheme')}</div>
</div>
<label class="switch">
<input
type="checkbox"
bind:checked={$interfaceAmoledTheme}
on:click={() => interfaceAmoledTheme.set(!$interfaceAmoledTheme)}
/>
<span></span>
</label>
</nav>
</div>
{/if}
{#if Capacitor.isNativePlatform()}
<form
on:submit|preventDefault={() => {
@@ -386,6 +408,22 @@
</label>
</nav>
</div>
<div class="field no-margin">
<nav class="no-padding">
<div class="max">
<div>{$_('layout.player.lockOrientation')}</div>
</div>
<label class="switch">
<input
type="checkbox"
bind:checked={$playerAndroidLockOrientation}
on:click={() => playerAndroidLockOrientation.set(!$playerAndroidLockOrientation)}
/>
<span></span>
</label>
</nav>
</div>
{/if}
{#if Capacitor.isNativePlatform()}
+3 -17
View File
@@ -1,9 +1,9 @@
<script lang="ts">
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { get } from 'svelte/store';
import { removePlaylistVideo } from './Api';
import type { Notification, PlaylistPageVideo, Video, VideoBase } from './Api/model';
import ContentColumn from './ContentColumn.svelte';
import Thumbnail from './Thumbnail.svelte';
import { authStore } from './store';
@@ -20,20 +20,6 @@
await removePlaylistVideo(playlistId, indexId);
hiddenVideos = [...hiddenVideos, videoId];
}
function checkWidth() {
if (innerWidth <= 1750) {
largeCol = '4';
} else {
largeCol = '2';
}
}
onMount(() => {
checkWidth();
addEventListener('resize', () => checkWidth());
});
</script>
<div class="page right active">
@@ -41,7 +27,7 @@
<div class="grid">
{#each videos as video}
{#if !hiddenVideos.includes(video.videoId)}
<div class="s12 m6 l{largeCol}">
<ContentColumn>
<article class="no-padding" style="height: 100%;">
<Thumbnail
on:videoHidden={() => (hiddenVideos = [...hiddenVideos, video.videoId])}
@@ -60,7 +46,7 @@
</div>
{/if}
</article>
</div>
</ContentColumn>
{/if}
{/each}
</div>
+3 -1
View File
@@ -103,6 +103,7 @@
"theme": "Theme",
"darkMode": "Dark mode",
"lightMode": "Light mode",
"AmoledTheme": "Amoled theme",
"color": "Color"
},
"searchSuggestions": "Search suggestions",
@@ -127,7 +128,8 @@
"dash": "Dash",
"silenceSkipper": "Silence skipper (Experimental)",
"youtubeJsFallback": "Local video processing fallback",
"youtubeJsAlways": "Always use local video processing"
"youtubeJsAlways": "Always use local video processing",
"lockOrientation": "Orientation locked to aspect ratio"
},
"bookmarklet": "Bookmarklet",
"instanceUrl": "Instance URL",
+32 -4
View File
@@ -1,4 +1,4 @@
import type { Image, Thumbnail, VideoBase, VideoPlay } from '$lib/Api/model';
import type { AdaptiveFormats, Captions, Image, Thumbnail, VideoBase, VideoPlay } from '$lib/Api/model';
import { numberWithCommas } from '$lib/misc';
import { interfaceRegionStore, poTokenCacheStore } from '$lib/store';
import { Capacitor } from '@capacitor/core';
@@ -85,6 +85,8 @@ export async function patchYoutubeJs(videoId: string): Promise<VideoPlay> {
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');
}
@@ -104,7 +106,8 @@ export async function patchYoutubeJs(videoId: string): Promise<VideoPlay> {
let authorThumbnails: Image[];
if (video.basic_info.channel_id) {
authorThumbnails = (await youtube.getChannel(video.basic_info.channel_id)).metadata.avatar as Image[];
const channel = await youtube.getChannel(video.basic_info.channel_id);
authorThumbnails = channel.metadata.avatar as Image[];
} else {
authorThumbnails = [];
}
@@ -122,6 +125,31 @@ export async function patchYoutubeJs(videoId: string): Promise<VideoPlay> {
});
});
let captions: Captions[] = [];
video.captions?.caption_tracks?.forEach(caption => {
captions.push({
label: caption.name.toString(),
language_code: caption.language_code,
url: caption.base_url
});
});
let adaptiveFormats: AdaptiveFormats[] = [];
video.streaming_data?.adaptive_formats.forEach(format => {
adaptiveFormats.push({
index: format.index_range?.start.toString() || '',
bitrate: format.bitrate.toString(),
init: format.init_range?.start.toString() || '',
url: format.url || '',
itag: format.itag.toString(),
type: format.mime_type,
clen: '',
lmt: '',
projectionType: 0,
resolution: format.width ? `${format.width}x${format.height}` : undefined
});
});
return {
type: 'video',
title: video.primary_info.title ? video.primary_info.title.toString() : '',
@@ -136,11 +164,11 @@ export async function patchYoutubeJs(videoId: string): Promise<VideoPlay> {
genre: video.basic_info.category || '',
genreUrl: '',
dashUrl: dashUri,
adaptiveFormats: [],
adaptiveFormats: adaptiveFormats,
formatStreams: [],
recommendedVideos: recommendedVideos,
authorThumbnails: authorThumbnails,
captions: [],
captions: captions,
authorId: video.basic_info.channel_id || '',
authorUrl: `/channel/${video.basic_info.channel_id}`,
authorVerified: false,
+3
View File
@@ -41,6 +41,7 @@ export const playerMiniPlayerStore = persisted('miniPlayer', true);
export const playerYouTubeJsFallback = persisted('youTubeJsFallback', true);
export const playerYouTubeJsAlways = persisted('youTubeJsAlways', false);
export const playerAndroidBgPlayer = persisted('androidBgPlayer', true);
export const playerAndroidLockOrientation = persisted('androidLockOrientation', true);
export const returnYtDislikesStore = persisted('returnYtDislikes', false);
export const returnYTDislikesInstanceStore: Writable<string | null | undefined> = persisted(
@@ -60,6 +61,8 @@ export const interfacePreviewVideoOnHoverStore = persisted('previewVideoOnHover'
export const interfaceForceCase: Writable<TitleCase> = persisted('forceCase', null);
export const interfaceAutoExpandComments: Writable<boolean> = persisted('autoExpandComments', true);
export const interfaceAutoExpandDesc: Writable<boolean> = persisted('autoExpandDesc', false);
export const interfaceAmoledTheme = persisted('amoledTheme', false);
export const sponsorBlockStore = persisted('sponsorBlock', true);
export const sponsorBlockUrlStore: Writable<string | null | undefined> = persisted(
+45
View File
@@ -1,4 +1,6 @@
import ui from 'beercss';
import { get } from 'svelte/store';
import { darkModeStore, interfaceAmoledTheme } from './store';
export async function getDynamicTheme(mode?: string): Promise<Record<string, string>> {
const givenSettings = (await ui('theme'));
@@ -12,3 +14,46 @@ export async function getDynamicTheme(mode?: string): Promise<Record<string, str
});
return themeVars;
}
export function setAmoledTheme() {
const isAmoled = get(interfaceAmoledTheme);
const isDark = get(darkModeStore);
if (isAmoled && isDark) {
const rootVars = [
'--surface-container',
'--surface',
'--surface-container-lowest',
'--surface-container-low',
'--surface-container-high',
'--surface-container-highest'
];
rootVars.forEach((varName) => {
document.body.style.setProperty(varName, '#000');
});
} else {
setTheme();
}
}
export function setTheme() {
const isDark = get(darkModeStore);
if (isDark === null) {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
darkModeStore.set(true);
ui('mode', 'dark');
} else {
darkModeStore.set(false);
ui('mode', 'light');
}
} else {
if (isDark) {
ui('mode', 'dark');
} else {
ui('mode', 'light');
}
}
}
+12 -24
View File
@@ -17,9 +17,11 @@
authStore,
darkModeStore,
instanceStore,
interfaceAmoledTheme,
syncPartyPeerStore,
themeColorStore
} from '$lib/store';
import { setAmoledTheme, setTheme } from '$lib/theme';
import { App } from '@capacitor/app';
import { Browser } from '@capacitor/browser';
import { Capacitor } from '@capacitor/core';
@@ -76,12 +78,13 @@
}
];
darkModeStore.subscribe((isDark) => {
if (isDark) {
ui('mode', 'dark');
} else {
ui('mode', 'light');
}
interfaceAmoledTheme.subscribe(() => {
setAmoledTheme();
});
darkModeStore.subscribe(() => {
setTheme();
setAmoledTheme();
});
App.addListener('appUrlOpen', (data) => {
@@ -147,29 +150,14 @@
// So user preferences overwrite instance preferences.
bookmarkletLoadFromUrl();
const isDark = get(darkModeStore);
if (isDark === null) {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
darkModeStore.set(true);
ui('mode', 'dark');
} else {
darkModeStore.set(false);
ui('mode', 'light');
}
} else {
if (isDark) {
ui('mode', 'dark');
} else {
ui('mode', 'light');
}
}
const themeHex = get(themeColorStore);
if (themeHex) {
await ui('theme', themeHex);
}
setTheme();
setAmoledTheme();
if (isLoggedIn) {
loadNotifications().catch(() => authStore.set(null));
}
@@ -1,9 +1,10 @@
<script lang="ts">
import { amSubscribed, deleteUnsubscribe, getChannelContent, postSubscribe } from '$lib/Api';
import type { ChannelContentPlaylists, ChannelContentVideos } from '$lib/Api/model';
import ContentColumn from '$lib/ContentColumn.svelte';
import PageLoading from '$lib/PageLoading.svelte';
import PlaylistThumbnail from '$lib/PlaylistThumbnail.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
import VideoList from '$lib/VideoList.svelte';
import { cleanNumber, getBestThumbnail, proxyGoogleImage } from '$lib/misc';
import { activePageStore, authStore } from '$lib/store';
import { Clipboard } from '@capacitor/clipboard';
@@ -184,28 +185,22 @@
</div>
{#if displayContent}
<div class="page right active">
<div class="space"></div>
<div class="grid">
{#if 'videos' in displayContent}
{#each displayContent.videos as video}
<div class="s12 m6 l2">
<article class="no-padding" style="height: 100%;">
<Thumbnail {video} />
</article>
</div>
{/each}
{:else}
{#if 'videos' in displayContent}
<VideoList videos={displayContent.videos} />
{:else}
<div class="page right active">
<div class="space"></div>
<div class="grid">
{#each displayContent.playlists as playlist}
<div class="s12 m6 l2">
<ContentColumn>
<article class="no-padding" style="height: 100%;">
<PlaylistThumbnail {playlist} />
</article>
</div>
</ContentColumn>
{/each}
{/if}
</div>
</div>
</div>
{/if}
<InfiniteLoading on:infinite={loadMore} />
{:else}
@@ -1,6 +1,7 @@
<script lang="ts">
import { getSearch } from '$lib/Api';
import ChannelThumbnail from '$lib/ChannelThumbnail.svelte';
import ContentColumn from '$lib/ContentColumn.svelte';
import PageLoading from '$lib/PageLoading.svelte';
import PlaylistThumbnail from '$lib/PlaylistThumbnail.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
@@ -79,7 +80,7 @@
<div class="space"></div>
<div class="grid">
{#each data.search as item}
<div class="s12 m6 l2">
<ContentColumn>
{#key item}
<article class="no-padding" style="height: 100%;">
{#if item.type === 'video'}
@@ -91,7 +92,7 @@
{/if}
</article>
{/key}
</div>
</ContentColumn>
{/each}
</div>
</div>
@@ -698,8 +698,6 @@
</div>
</details>
</article>
{:else}
<h6>{$_('player.unableToLoadComments')}</h6>
{/if}
</div>
{#if !theatreMode}
+1 -1
View File
@@ -5,7 +5,7 @@ import json
import os
import re
LATEST_VERSION = "1.6.9"
LATEST_VERSION = "1.6.10"
WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "materialious")
ROOT_PACKAGE = os.path.join(WORKING_DIR, "package.json")