@@ -7,8 +7,8 @@ android {
|
||||
applicationId "us.materialio.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 226
|
||||
versionName "1.16.8"
|
||||
versionCode 227
|
||||
versionName "1.16.9"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
|
||||
@@ -91,7 +91,11 @@
|
||||
|
||||
|
||||
|
||||
<release version="1.16.8" date="2026-3-03">
|
||||
|
||||
<release version="1.16.9" date="2026-3-05">
|
||||
<url>https://github.com/Materialious/Materialious/releases/tag/1.16.9</url>
|
||||
</release>
|
||||
<release version="1.16.8" date="2026-3-03">
|
||||
<url>https://github.com/Materialious/Materialious/releases/tag/1.16.8</url>
|
||||
</release>
|
||||
<release version="1.16.7" date="2026-3-02">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Materialious",
|
||||
"version": "1.16.8",
|
||||
"version": "1.16.9",
|
||||
"description": "Modern material design for YouTube and Invidious.",
|
||||
"author": {
|
||||
"name": "Ward Pearce",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "materialious",
|
||||
"version": "1.16.8",
|
||||
"version": "1.16.9",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run patch:github && vite dev",
|
||||
@@ -99,4 +99,4 @@
|
||||
"youtubei.js": "^16.0.1",
|
||||
"zod": "^4.3.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,13 @@
|
||||
import { onMount } from 'svelte';
|
||||
import Thumbnail from '$lib/components/thumbnail/VideoThumbnail.svelte';
|
||||
import { extractUniqueId, type FeedItems } from '$lib/feed';
|
||||
import { timeout } from '$lib/misc';
|
||||
import { isMobile, timeout } from '$lib/misc';
|
||||
import ChannelThumbnail from '$lib/components/thumbnail/ChannelThumbnail.svelte';
|
||||
import PlaylistThumbnail from '$lib/components/thumbnail/PlaylistThumbnail.svelte';
|
||||
import HashtagThumbnail from '$lib/components/thumbnail/HashtagThumbnail.svelte';
|
||||
import NoResults from '$lib/components/NoResults.svelte';
|
||||
import { SpatialMenu } from 'melt/builders';
|
||||
import { mergeAttrs } from 'melt';
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { isItemFiltered } from '$lib/filtering/index';
|
||||
|
||||
interface Props {
|
||||
@@ -77,10 +76,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={classes}
|
||||
class:item-container={Capacitor.getPlatform() !== 'android' && !$isAndroidTvStore}
|
||||
>
|
||||
<div class={classes} class:item-container={!isMobile() && !$isAndroidTvStore}>
|
||||
{#if items.length === 0}
|
||||
<NoResults />
|
||||
{/if}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
let contentFilters = $state($filterContentListStore);
|
||||
|
||||
filterContentListStore.subscribe((updatedFilterList) => (contentFilters = updatedFilterList));
|
||||
|
||||
async function loadFilterList(event: Event) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -75,6 +77,8 @@
|
||||
});
|
||||
|
||||
filterContentListStore.set(contentFilters);
|
||||
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}
|
||||
|
||||
function removeFilter(filter: z.infer<typeof zFilterGroup>) {
|
||||
@@ -83,6 +87,7 @@
|
||||
contentFilters = contentFilters.filter((item) => item !== filter);
|
||||
|
||||
filterContentListStore.set(contentFilters);
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -169,6 +174,7 @@
|
||||
onclick={() => {
|
||||
filter.conditions = filter.conditions.filter((item) => condition !== item);
|
||||
filterContentListStore.set(contentFilters);
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}}
|
||||
class="surface-container-highest"
|
||||
>
|
||||
@@ -181,6 +187,7 @@
|
||||
onchange={(event: Event & { currentTarget: HTMLSelectElement }) => {
|
||||
condition.field = event.currentTarget.value;
|
||||
filterContentListStore.set(contentFilters);
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}}
|
||||
name="field"
|
||||
>
|
||||
@@ -201,6 +208,7 @@
|
||||
typeof zFilterOperatorEnum
|
||||
>;
|
||||
filterContentListStore.set(contentFilters);
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}}
|
||||
name="operator"
|
||||
>
|
||||
@@ -220,6 +228,7 @@
|
||||
onchange={(event: Event & { currentTarget: HTMLSelectElement }) => {
|
||||
condition.value = event.currentTarget.value;
|
||||
filterContentListStore.set(contentFilters);
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}}
|
||||
name="boolean-options"
|
||||
>
|
||||
@@ -238,6 +247,7 @@
|
||||
onchange={(event: Event & { currentTarget: HTMLSelectElement }) => {
|
||||
condition.value = event.currentTarget.value;
|
||||
filterContentListStore.set(contentFilters);
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}}
|
||||
name="array-options"
|
||||
>
|
||||
@@ -262,6 +272,7 @@
|
||||
? Number(event.currentTarget.value)
|
||||
: event.currentTarget.value;
|
||||
filterContentListStore.set(contentFilters);
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}}
|
||||
name="value"
|
||||
type={schema[filter.type][condition.field] === 'string' ? 'text' : 'number'}
|
||||
@@ -282,6 +293,7 @@
|
||||
field: 'author',
|
||||
value: ''
|
||||
});
|
||||
filterContentUrlAutoUpdateStore.set(false);
|
||||
}}
|
||||
class="surface-container-highest"
|
||||
>
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
onclick={onVideoSelected}
|
||||
>
|
||||
<div class="thumbnail-image">
|
||||
<div class:crop={thumbnailHTMLElement ? thumbnailHTMLElement.height > 300 : false}>
|
||||
<div class:crop={thumbnailHTMLElement ? thumbnailHTMLElement.naturalHeight > 300 : false}>
|
||||
<img
|
||||
class="responsive"
|
||||
class:watched={progress !== undefined}
|
||||
|
||||
@@ -21,17 +21,21 @@ export async function syncSettingsToBackend() {
|
||||
getKeyValue(store.name).then((currentKeyValue) => {
|
||||
if (currentKeyValue !== null || allowNullOverwrite.includes(store.name)) {
|
||||
const currentKeyValueParsed = parseWithSchema(store.schema, currentKeyValue);
|
||||
if (currentKeyValueParsed !== null && currentKeyValueParsed !== undefined) {
|
||||
if (
|
||||
(currentKeyValueParsed !== null && currentKeyValueParsed !== undefined) ||
|
||||
allowNullOverwrite.includes(store.name)
|
||||
) {
|
||||
store.store.set(currentKeyValueParsed);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let initalLoad = true;
|
||||
let initialLoad = true;
|
||||
store.store.subscribe((value) => {
|
||||
if (!get(rawMasterKeyStore)) return;
|
||||
if (initalLoad) {
|
||||
initalLoad = false;
|
||||
|
||||
if (initialLoad && !allowNullOverwrite.includes(store.name)) {
|
||||
initialLoad = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,9 @@ export async function load({ url }) {
|
||||
const filterUrl = get(filterContentUrlStore);
|
||||
if (filterUrl) {
|
||||
try {
|
||||
loadContentFilterFromURL(filterUrl);
|
||||
loadContentFilterFromURL(filterUrl).then((filterList) =>
|
||||
filterContentListStore.set(filterList)
|
||||
);
|
||||
} catch {
|
||||
// Continue regardless of error
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -3,7 +3,7 @@ import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
LATEST_VERSION = "1.16.8"
|
||||
LATEST_VERSION = "1.16.9"
|
||||
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