@@ -7,8 +7,8 @@ android {
|
||||
applicationId "us.materialio.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 79
|
||||
versionName "1.6.28"
|
||||
versionCode 80
|
||||
versionName "1.6.29"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
|
||||
@@ -15,6 +15,7 @@ dependencies {
|
||||
implementation project(':capacitor-screen-orientation')
|
||||
implementation project(':capacitor-status-bar')
|
||||
implementation project(':capgo-inappbrowser')
|
||||
implementation project(':hugotomazi-capacitor-navigation-bar')
|
||||
implementation project(':mediagrid-capacitor-native-audio')
|
||||
implementation project(':capacitor-nodejs')
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacit
|
||||
include ':capgo-inappbrowser'
|
||||
project(':capgo-inappbrowser').projectDir = new File('../node_modules/@capgo/inappbrowser/android')
|
||||
|
||||
include ':hugotomazi-capacitor-navigation-bar'
|
||||
project(':hugotomazi-capacitor-navigation-bar').projectDir = new File('../node_modules/@hugotomazi/capacitor-navigation-bar/android')
|
||||
|
||||
include ':mediagrid-capacitor-native-audio'
|
||||
project(':mediagrid-capacitor-native-audio').projectDir = new File('../node_modules/@mediagrid/capacitor-native-audio/android')
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Materialious",
|
||||
"version": "1.6.28",
|
||||
"version": "1.6.29",
|
||||
"description": "Modern material design for Invidious.",
|
||||
"author": {
|
||||
"name": "Ward Pearce",
|
||||
|
||||
Generated
+12
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "materialious",
|
||||
"version": "1.6.27",
|
||||
"version": "1.6.28",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "materialious",
|
||||
"version": "1.6.27",
|
||||
"version": "1.6.28",
|
||||
"dependencies": {
|
||||
"@capacitor-community/electron": "^5.0.1",
|
||||
"@capacitor/android": "^6.1.2",
|
||||
@@ -19,6 +19,7 @@
|
||||
"@capacitor/status-bar": "^6.0.1",
|
||||
"@capgo/inappbrowser": "^6.6.8",
|
||||
"@ffmpeg/ffmpeg": "^0.12.10",
|
||||
"@hugotomazi/capacitor-navigation-bar": "^4.0.1",
|
||||
"@mediagrid/capacitor-native-audio": "^1.0.0",
|
||||
"beercss": "^3.8.0",
|
||||
"bgutils-js": "^3.1.1",
|
||||
@@ -2177,6 +2178,15 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@hugotomazi/capacitor-navigation-bar": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@hugotomazi/capacitor-navigation-bar/-/capacitor-navigation-bar-4.0.1.tgz",
|
||||
"integrity": "sha512-CtG9c2mxH1hxNvr8+PsoMhfKxoUkv17DQGqt82Y65gM4UARBe0Dp2fa8Eeo+ZzybJ1nRwSAiB4kEQ3nx5UpT1A==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@capacitor/core": "^4.0.1 || ^5.0.0 || ^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "materialious",
|
||||
"version": "1.6.28",
|
||||
"version": "1.6.29",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
@@ -53,6 +53,7 @@
|
||||
"@capacitor/status-bar": "^6.0.1",
|
||||
"@capgo/inappbrowser": "^6.6.8",
|
||||
"@ffmpeg/ffmpeg": "^0.12.10",
|
||||
"@hugotomazi/capacitor-navigation-bar": "^4.0.1",
|
||||
"@mediagrid/capacitor-native-audio": "^1.0.0",
|
||||
"beercss": "^3.8.0",
|
||||
"bgutils-js": "^3.1.1",
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
getBestThumbnail,
|
||||
proxyVideoUrl,
|
||||
pullBitratePreference,
|
||||
setStatusBarColor,
|
||||
videoLength,
|
||||
type PhasedDescription
|
||||
} from './misc';
|
||||
@@ -43,7 +42,7 @@
|
||||
synciousInstanceStore,
|
||||
synciousStore
|
||||
} from './store';
|
||||
import { getDynamicTheme } from './theme';
|
||||
import { getDynamicTheme, setStatusBarColor } from './theme';
|
||||
|
||||
export let data: { video: VideoPlay; content: PhasedDescription; playlistId: string | null };
|
||||
export let audioMode = false;
|
||||
@@ -365,6 +364,7 @@
|
||||
|
||||
if (get(playerAutoPlayStore)) {
|
||||
player.play();
|
||||
player.exitFullscreen();
|
||||
}
|
||||
await loadPlayerPos();
|
||||
});
|
||||
@@ -424,8 +424,6 @@
|
||||
}
|
||||
|
||||
if (Capacitor.getPlatform() === 'android') {
|
||||
let initialFullscreen = true;
|
||||
|
||||
const videoFormats = data.video.adaptiveFormats.filter((format) =>
|
||||
format.type.startsWith('video/')
|
||||
);
|
||||
@@ -433,14 +431,6 @@
|
||||
originalOrigination = await ScreenOrientation.orientation();
|
||||
|
||||
player.addEventListener('fullscreen-change', async (event: FullscreenChangeEvent) => {
|
||||
// A bit of a hack to fix Android automatically
|
||||
// fullscreening when opening a video.
|
||||
if (initialFullscreen) {
|
||||
player.exitFullscreen();
|
||||
initialFullscreen = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.detail) {
|
||||
// Ensure bar color is black while in fullscreen
|
||||
await StatusBar.setBackgroundColor({ color: '#000000' });
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import { ensureNoTrailingSlash, letterCase, titleCase, titleCases } from './misc';
|
||||
import { getPages } from './navPages';
|
||||
import {
|
||||
authStore,
|
||||
darkModeStore,
|
||||
@@ -21,6 +22,7 @@
|
||||
interfaceAmoledTheme,
|
||||
interfaceAutoExpandComments,
|
||||
interfaceAutoExpandDesc,
|
||||
interfaceDefaultPage,
|
||||
interfaceDisplayThumbnailAvatars,
|
||||
interfaceForceCase,
|
||||
interfaceLowBandwidthMode,
|
||||
@@ -66,6 +68,7 @@
|
||||
let region = get(interfaceRegionStore);
|
||||
let forceCase = get(interfaceForceCase);
|
||||
let defaultLanguage = get(playerDefaultLanguage);
|
||||
let defaultPage = get(interfaceDefaultPage);
|
||||
|
||||
const languageNames = ISO6391.getAllCodes().map((code) =>
|
||||
ISO6391.getName(code).toLocaleLowerCase()
|
||||
@@ -385,6 +388,24 @@
|
||||
<i>arrow_drop_down</i>
|
||||
</div>
|
||||
|
||||
<div class="field label suffix border">
|
||||
<select
|
||||
name="defaultPage"
|
||||
bind:value={defaultPage}
|
||||
on:change={() => interfaceDefaultPage.set(defaultPage)}
|
||||
>
|
||||
{#each getPages() as page}
|
||||
{#if !page.requiresAuth || get(authStore)}
|
||||
<option selected={$interfaceDefaultPage === page.href} value={page.href}
|
||||
>{page.name}</option
|
||||
>
|
||||
{/if}
|
||||
{/each}
|
||||
</select>
|
||||
<label for="defaultPage">{$_('defaultPage')}</label>
|
||||
<i>arrow_drop_down</i>
|
||||
</div>
|
||||
|
||||
{#if !Capacitor.isNativePlatform()}
|
||||
<div class="settings">
|
||||
<h6>{$_('layout.bookmarklet')}</h6>
|
||||
|
||||
@@ -51,5 +51,5 @@ if (Capacitor.getPlatform() === 'android') {
|
||||
return originalXhrOpen.apply(this, args);
|
||||
};
|
||||
|
||||
setTimeout(() => goto('/', { replaceState: true }), 300);
|
||||
setTimeout(() => goto('/', { replaceState: true }), 10);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
interfaceAmoledTheme,
|
||||
interfaceAutoExpandComments,
|
||||
interfaceAutoExpandDesc,
|
||||
interfaceDefaultPage,
|
||||
interfaceDisplayThumbnailAvatars,
|
||||
interfaceForceCase,
|
||||
interfaceLowBandwidthMode,
|
||||
@@ -207,6 +208,11 @@ const persistedStores: { name: string, store: Writable<any>, type: 'string' | 'b
|
||||
name: 'defaultLanguage',
|
||||
store: playerDefaultLanguage,
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'defaultPage',
|
||||
store: interfaceDefaultPage,
|
||||
type: 'string'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"letterCase": "Letter case for titles",
|
||||
"hideReplies": "Hide replies",
|
||||
"hideVideo": "Hide video",
|
||||
"defaultPage": "Default page",
|
||||
"syncParty": {
|
||||
"userJoined": "User joined your watch party.",
|
||||
"userLeft": "User left your watch party.",
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { pushState } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { StatusBar } from '@capacitor/status-bar';
|
||||
import he from 'he';
|
||||
import humanNumber from 'human-number';
|
||||
import type Peer from 'peerjs';
|
||||
import { get } from 'svelte/store';
|
||||
import type { Image } from './api/model';
|
||||
import { instanceStore, interfaceForceCase } from './store';
|
||||
import { getDynamicTheme } from './theme';
|
||||
|
||||
|
||||
export type TitleCase = 'uppercase' | 'lowercase' | 'sentence case' | 'title case' | null;
|
||||
@@ -291,11 +288,3 @@ export function ensureNoTrailingSlash(url: any): string {
|
||||
|
||||
return url.endsWith('/') ? url.slice(0, -1) : url;
|
||||
}
|
||||
|
||||
export async function setStatusBarColor() {
|
||||
if (Capacitor.getPlatform() === 'android') {
|
||||
await StatusBar.setBackgroundColor({
|
||||
color: (await getDynamicTheme())['--surface-container']
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
|
||||
// Must be a func do to how i18n is loaded
|
||||
export function getPages(): { icon: string, href: string, name: string, requiresAuth: boolean; }[] {
|
||||
return [
|
||||
{
|
||||
icon: 'home',
|
||||
href: '/',
|
||||
name: get(_)('pages.home'),
|
||||
requiresAuth: false
|
||||
},
|
||||
{
|
||||
icon: 'whatshot',
|
||||
href: '/trending',
|
||||
name: get(_)('pages.trending'),
|
||||
requiresAuth: false
|
||||
},
|
||||
{
|
||||
icon: 'subscriptions',
|
||||
href: '/subscriptions',
|
||||
name: get(_)('pages.subscriptions'),
|
||||
requiresAuth: true
|
||||
},
|
||||
{
|
||||
icon: 'video_library',
|
||||
href: '/playlists',
|
||||
name: get(_)('pages.playlists'),
|
||||
requiresAuth: true
|
||||
},
|
||||
{
|
||||
icon: 'history',
|
||||
href: '/history',
|
||||
name: get(_)('pages.history'),
|
||||
requiresAuth: true
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -159,11 +159,13 @@ export async function patchYoutubeJs(videoId: string): Promise<VideoPlay> {
|
||||
});
|
||||
}
|
||||
|
||||
console.log(video.primary_info);
|
||||
|
||||
return {
|
||||
type: 'video',
|
||||
title: video.primary_info.title?.toString() || '',
|
||||
viewCount: video.primary_info.view_count ? Number(video.primary_info.view_count?.toString()?.replace(/\D/g, '')) : 0,
|
||||
viewCountText: video.primary_info.view_count?.toString() || '',
|
||||
viewCount: Number(video.primary_info.view_count?.original_view_count || 0),
|
||||
viewCountText: video.primary_info.view_count?.original_view_count.toString() || '0',
|
||||
likeCount: video.basic_info.like_count || 0,
|
||||
dislikeCount: 0,
|
||||
allowRatings: false,
|
||||
|
||||
@@ -67,6 +67,7 @@ export const interfaceAutoExpandDesc: Writable<boolean> = persisted('autoExpandD
|
||||
export const interfaceAmoledTheme = persisted('amoledTheme', false);
|
||||
export const interfaceLowBandwidthMode = persisted('lowBandwidthMode', false);
|
||||
export const interfaceDisplayThumbnailAvatars = persisted('disableThumbnailAvatars', false);
|
||||
export const interfaceDefaultPage = persisted('defaultPage', '/');
|
||||
|
||||
export const sponsorBlockStore = persisted('sponsorBlock', true);
|
||||
export const sponsorBlockUrlStore: Writable<string | null | undefined> = persisted(
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { StatusBar, Style } from '@capacitor/status-bar';
|
||||
import { NavigationBar } from '@hugotomazi/capacitor-navigation-bar';
|
||||
import ui from 'beercss';
|
||||
import { get } from 'svelte/store';
|
||||
import { darkModeStore, interfaceAmoledTheme } from './store';
|
||||
@@ -15,6 +18,26 @@ export async function getDynamicTheme(mode?: string): Promise<Record<string, str
|
||||
return themeVars;
|
||||
}
|
||||
|
||||
export async function setStatusBarColor() {
|
||||
if (Capacitor.getPlatform() === 'android') {
|
||||
const surfaceColor = get(interfaceAmoledTheme) ? '#000000' : (await getDynamicTheme())['--surface-container'];
|
||||
|
||||
await StatusBar.setBackgroundColor({
|
||||
color: surfaceColor
|
||||
});
|
||||
|
||||
await NavigationBar.setColor({
|
||||
color: surfaceColor,
|
||||
darkButtons: !get(darkModeStore)
|
||||
});
|
||||
|
||||
if (get(darkModeStore)) {
|
||||
await StatusBar.setStyle({ style: Style.Dark });
|
||||
} else {
|
||||
await StatusBar.setStyle({ style: Style.Light });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function setAmoledTheme() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { afterNavigate, beforeNavigate, goto } from '$app/navigation';
|
||||
import { navigating } from '$app/stores';
|
||||
|
||||
import { navigating, page } from '$app/stores';
|
||||
import '$lib/android/http/androidRequests';
|
||||
import colorTheme, { convertToHexColorCode } from '$lib/android/plugins/colorTheme';
|
||||
import { getFeed } from '$lib/api/index';
|
||||
@@ -8,7 +9,7 @@
|
||||
import { bookmarkletLoadFromUrl, loadSettingsFromEnv } from '$lib/externalSettings';
|
||||
import Logo from '$lib/Logo.svelte';
|
||||
import MiniPlayer from '$lib/MiniPlayer.svelte';
|
||||
import { setStatusBarColor } from '$lib/misc';
|
||||
import { getPages } from '$lib/navPages';
|
||||
import PageLoading from '$lib/PageLoading.svelte';
|
||||
import Search from '$lib/Search.svelte';
|
||||
import Settings from '$lib/Settings.svelte';
|
||||
@@ -18,12 +19,13 @@
|
||||
darkModeStore,
|
||||
instanceStore,
|
||||
interfaceAmoledTheme,
|
||||
interfaceDefaultPage,
|
||||
showWarningStore,
|
||||
syncPartyPeerStore,
|
||||
themeColorStore
|
||||
} from '$lib/store';
|
||||
import SyncParty from '$lib/SyncParty.svelte';
|
||||
import { setAmoledTheme, setTheme } from '$lib/theme';
|
||||
import { setAmoledTheme, setStatusBarColor, setTheme } from '$lib/theme';
|
||||
import Thumbnail from '$lib/Thumbnail.svelte';
|
||||
import { App } from '@capacitor/app';
|
||||
import { Browser } from '@capacitor/browser';
|
||||
@@ -48,39 +50,6 @@
|
||||
|
||||
let notifications: Notification[] = [];
|
||||
|
||||
const pages = [
|
||||
{
|
||||
icon: 'home',
|
||||
href: '/',
|
||||
name: $_('pages.home'),
|
||||
requiresAuth: false
|
||||
},
|
||||
{
|
||||
icon: 'whatshot',
|
||||
href: '/trending',
|
||||
name: $_('pages.trending'),
|
||||
requiresAuth: false
|
||||
},
|
||||
{
|
||||
icon: 'subscriptions',
|
||||
href: '/subscriptions',
|
||||
name: $_('pages.subscriptions'),
|
||||
requiresAuth: true
|
||||
},
|
||||
{
|
||||
icon: 'video_library',
|
||||
href: '/playlists',
|
||||
name: $_('pages.playlists'),
|
||||
requiresAuth: true
|
||||
},
|
||||
{
|
||||
icon: 'history',
|
||||
href: '/history',
|
||||
name: $_('pages.history'),
|
||||
requiresAuth: true
|
||||
}
|
||||
];
|
||||
|
||||
interfaceAmoledTheme.subscribe(() => {
|
||||
setAmoledTheme();
|
||||
});
|
||||
@@ -178,6 +147,19 @@
|
||||
onMount(async () => {
|
||||
ui();
|
||||
|
||||
if (
|
||||
$interfaceDefaultPage &&
|
||||
$interfaceDefaultPage !== '/' &&
|
||||
$interfaceDefaultPage.startsWith('/') &&
|
||||
$page.url.pathname === '/'
|
||||
) {
|
||||
getPages().forEach((page) => {
|
||||
if (page.href === $interfaceDefaultPage && (!page.requiresAuth || $authStore)) {
|
||||
goto($interfaceDefaultPage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
scrollableRoot = document.querySelector('.root');
|
||||
|
||||
loadSettingsFromEnv();
|
||||
@@ -216,7 +198,7 @@
|
||||
|
||||
<nav class="left m l small">
|
||||
<header></header>
|
||||
{#each pages as page}
|
||||
{#each getPages() as page}
|
||||
{#if !page.requiresAuth || isLoggedIn}
|
||||
<a href={page.href} class:active={currentPage === page.name.toLowerCase()}
|
||||
><i>{page.icon}</i>
|
||||
@@ -297,7 +279,7 @@
|
||||
</nav>
|
||||
|
||||
<nav class="bottom s">
|
||||
{#each pages as page}
|
||||
{#each getPages() as page}
|
||||
{#if !page.requiresAuth || isLoggedIn}
|
||||
<a class="round" href={page.href} class:active={currentPage === page.name.toLowerCase()}
|
||||
><i>{page.icon}</i>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
|
||||
LATEST_VERSION = "1.6.28"
|
||||
LATEST_VERSION = "1.6.29"
|
||||
WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "materialious")
|
||||
|
||||
ROOT_PACKAGE = os.path.join(WORKING_DIR, "package.json")
|
||||
|
||||
Reference in New Issue
Block a user