Merge pull request #1245 from Materialious/update/1.12.4

Update/1.12.4
This commit is contained in:
Ward
2025-12-10 23:27:05 +00:00
committed by GitHub
17 changed files with 305 additions and 303 deletions
+1 -1
View File
@@ -69,7 +69,7 @@ I've commented out places what aren't relevant but might be in the future.-->
<td>MacOS (x64 & arm64)</td>
<td>
<a href="https://github.com/Materialious/Materialious/releases/latest/download/Materialious-darwin-universal.dmg">
<img width="220" alt="MacOS Download" src="https://reachify.io/wp-content/uploads/2018/09/mac-download-button-1.png">
<img width="220" alt="MacOS Download" src="https://www.filesdna.com/wp-content/uploads/2021/03/mac-download-button-1.png">
</a>
</td>
</tr>
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 175
versionName "1.12.3"
versionCode 176
versionName "1.12.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -72,7 +72,11 @@
<release version="1.12.3" date="2025-12-08">
<release version="1.12.4" date="2025-12-11">
<url>https://github.com/Materialious/Materialious/releases/tag/1.12.4</url>
</release>
<release version="1.12.3" date="2025-12-08">
<url>https://github.com/Materialious/Materialious/releases/tag/1.12.3</url>
</release>
<release version="1.12.2" date="2025-12-08">
+94 -36
View File
@@ -1,12 +1,12 @@
{
"name": "Materialious",
"version": "1.12.3",
"version": "1.12.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "Materialious",
"version": "1.12.3",
"version": "1.12.4",
"license": "MIT",
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
@@ -18,20 +18,20 @@
"electron-unhandled": "^4.0.1",
"electron-updater": "^6.3.4",
"electron-window-state": "^5.0.3",
"jsdom": "^27.2.0",
"jsdom": "^27.3.0",
"jsonfile": "^6.2.0"
},
"devDependencies": {
"electron": "^39.2.4",
"electron": "^39.2.6",
"electron-builder": "^26.0.12",
"electron-rebuild": "^3.2.9",
"typescript": "^5.9.3"
}
},
"node_modules/@acemir/cssom": {
"version": "0.9.24",
"resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.24.tgz",
"integrity": "sha512-5YjgMmAiT2rjJZU7XK1SNI7iqTy92DpaYVgG6x63FxkJ11UpYfLndHJATtinWJClAXiOlW9XWaUyAQf8pMrQPg==",
"version": "0.9.28",
"resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.28.tgz",
"integrity": "sha512-LuS6IVEivI75vKN8S04qRD+YySP0RmU/cV8UNukhQZvprxF+76Z43TNo/a08eCodaGhT1Us8etqS1ZRY9/Or0A==",
"license": "MIT"
},
"node_modules/@asamuzakjp/css-color": {
@@ -48,32 +48,32 @@
}
},
"node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
"version": "11.2.2",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz",
"integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==",
"license": "ISC",
"version": "11.2.4",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz",
"integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==",
"license": "BlueOak-1.0.0",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@asamuzakjp/dom-selector": {
"version": "6.7.4",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.4.tgz",
"integrity": "sha512-buQDjkm+wDPXd6c13534URWZqbz0RP5PAhXZ+LIoa5LgwInT9HVJvGIJivg75vi8I13CxDGdTnz+aY5YUJlIAA==",
"version": "6.7.6",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.6.tgz",
"integrity": "sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==",
"license": "MIT",
"dependencies": {
"@asamuzakjp/nwsapi": "^2.3.9",
"bidi-js": "^1.0.3",
"css-tree": "^3.1.0",
"is-potential-custom-element-name": "^1.0.1",
"lru-cache": "^11.2.2"
"lru-cache": "^11.2.4"
}
},
"node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": {
"version": "11.2.2",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz",
"integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==",
"license": "ISC",
"version": "11.2.4",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz",
"integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==",
"license": "BlueOak-1.0.0",
"engines": {
"node": "20 || >=22"
}
@@ -249,9 +249,9 @@
}
},
"node_modules/@csstools/css-syntax-patches-for-csstree": {
"version": "1.0.17",
"resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.17.tgz",
"integrity": "sha512-LCC++2h8pLUSPY+EsZmrrJ1EOUu+5iClpEiDhhdw3zRJpPbABML/N5lmRuBHjxtKm9VnRcsUzioyD0sekFMF0A==",
"version": "1.0.14",
"resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.14.tgz",
"integrity": "sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q==",
"funding": [
{
"type": "github",
@@ -265,6 +265,9 @@
"license": "MIT-0",
"engines": {
"node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/css-tokenizer": {
@@ -2250,13 +2253,13 @@
}
},
"node_modules/cssstyle": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.3.tgz",
"integrity": "sha512-OytmFH+13/QXONJcC75QNdMtKpceNk3u8ThBjyyYjkEcy/ekBwR1mMAuNvi3gdBPW3N5TlCzQ0WZw8H0lN/bDw==",
"version": "5.3.4",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.4.tgz",
"integrity": "sha512-KyOS/kJMEq5O9GdPnaf82noigg5X5DYn0kZPJTaAsCUaBizp6Xa1y9D4Qoqf/JazEXWuruErHgVXwjN5391ZJw==",
"license": "MIT",
"dependencies": {
"@asamuzakjp/css-color": "^4.0.3",
"@csstools/css-syntax-patches-for-csstree": "^1.0.14",
"@asamuzakjp/css-color": "^4.1.0",
"@csstools/css-syntax-patches-for-csstree": "1.0.14",
"css-tree": "^3.1.0"
},
"engines": {
@@ -2594,9 +2597,9 @@
}
},
"node_modules/electron": {
"version": "39.2.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-39.2.4.tgz",
"integrity": "sha512-KxPtwpFceQKSxRtUY39piHLYhJMMyHfOhc70e6zRnKGrbRdK6hzEqssth8IGjlKOdkeT4KCvIEngnNraYk39+g==",
"version": "39.2.6",
"resolved": "https://registry.npmjs.org/electron/-/electron-39.2.6.tgz",
"integrity": "sha512-dHBgTodWBZd+tL1Dt0PSh/CFLHeDkFCTKCTXu1dgPhlE9Z3k2zzlBQ9B2oW55CFsKanBDHiUomHJNw0XaSdQpA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -3955,14 +3958,14 @@
"license": "MIT"
},
"node_modules/jsdom": {
"version": "27.2.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.2.0.tgz",
"integrity": "sha512-454TI39PeRDW1LgpyLPyURtB4Zx1tklSr6+OFOipsxGUH1WMTvk6C65JQdrj455+DP2uJ1+veBEHTGFKWVLFoA==",
"version": "27.3.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.3.0.tgz",
"integrity": "sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==",
"license": "MIT",
"dependencies": {
"@acemir/cssom": "^0.9.23",
"@asamuzakjp/dom-selector": "^6.7.4",
"cssstyle": "^5.3.3",
"@acemir/cssom": "^0.9.28",
"@asamuzakjp/dom-selector": "^6.7.6",
"cssstyle": "^5.3.4",
"data-urls": "^6.0.0",
"decimal.js": "^10.6.0",
"html-encoding-sniffer": "^4.0.0",
@@ -4454,6 +4457,25 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/native-run": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.1.tgz",
@@ -4831,6 +4853,13 @@
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC",
"peer": true
},
"node_modules/plist": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
@@ -4845,6 +4874,35 @@
"node": ">=10.4.0"
}
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postject": {
"version": "1.0.0-alpha.6",
"resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz",
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.12.3",
"version": "1.12.4",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
@@ -31,11 +31,11 @@
"electron-unhandled": "^4.0.1",
"electron-updater": "^6.3.4",
"electron-window-state": "^5.0.3",
"jsdom": "^27.2.0",
"jsdom": "^27.3.0",
"jsonfile": "^6.2.0"
},
"devDependencies": {
"electron": "^39.2.4",
"electron": "^39.2.6",
"electron-builder": "^26.0.12",
"electron-rebuild": "^3.2.9",
"typescript": "^5.9.3"
@@ -44,4 +44,4 @@
"capacitor",
"electron"
]
}
}
+26 -26
View File
@@ -1,17 +1,17 @@
{
"name": "materialious",
"version": "1.12.3",
"version": "1.12.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "materialious",
"version": "1.12.3",
"version": "1.12.4",
"hasInstallScript": true,
"dependencies": {
"@capacitor-community/electron": "^5.0.1",
"@capacitor-community/safe-area": "^7.0.0-alpha.1",
"@capacitor/android": "^7.4.3",
"@capacitor/android": "^7.4.4",
"@capacitor/app": "^7.1.0",
"@capacitor/browser": "^7.0.0",
"@capacitor/clipboard": "^7.0.0",
@@ -21,7 +21,7 @@
"@capacitor/share": "^7.0.2",
"@macfja/serializer": "^1.1.4",
"@macfja/svelte-persistent-store": "^2.4.2",
"beercss": "^3.12.13",
"beercss": "^3.13.1",
"bgutils-js": "^3.2.0",
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
"dayjs": "^1.11.19",
@@ -30,7 +30,7 @@
"googlevideo": "^4.0.4",
"he": "^1.2.0",
"human-number": "^2.0.8",
"i18next": "^25.6.3",
"i18next": "^25.7.2",
"iso-3166": "^4.4.0",
"iso-639-1": "^3.1.5",
"material-dynamic-colors": "^1.1.1",
@@ -47,7 +47,7 @@
"@capacitor/cli": "^7.4.4",
"@sveltejs/adapter-auto": "^6.0.1",
"@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/kit": "^2.49.0",
"@sveltejs/kit": "^2.49.1",
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@types/event-source-polyfill": "^1.0.5",
"@types/he": "^1.2.3",
@@ -60,7 +60,7 @@
"patch-package": "^8.0.1",
"prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0",
"svelte": "^5.45.2",
"svelte": "^5.45.6",
"svelte-check": "^4.3.3",
"tslib": "^2.7.0",
"typescript": "^5.9.3",
@@ -1717,9 +1717,9 @@
}
},
"node_modules/@capacitor/android": {
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/@capacitor/android/-/android-7.4.3.tgz",
"integrity": "sha512-VpjvnOcmYGPLgvXRhe3CGLs62Cg7sxOyp77NddCr+Y06qqgnoaj6OGeBVTc2DZlqZ6bSmh15JvFu82pkvmdgfQ==",
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@capacitor/android/-/android-7.4.4.tgz",
"integrity": "sha512-y8knfV1JXNrd6XZZLZireGT+EBCN0lvOo+HZ/s7L8LkrPBu4nY5UZn0Wxz4yOezItEII9rqYJSHsS5fMJG9gdw==",
"license": "MIT",
"peerDependencies": {
"@capacitor/core": "^7.4.0"
@@ -3383,9 +3383,9 @@
}
},
"node_modules/@sveltejs/kit": {
"version": "2.49.0",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.49.0.tgz",
"integrity": "sha512-oH8tXw7EZnie8FdOWYrF7Yn4IKrqTFHhXvl8YxXxbKwTMcD/5NNCryUSEXRk2ZR4ojnub0P8rNrsVGHXWqIDtA==",
"version": "2.49.1",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.49.1.tgz",
"integrity": "sha512-vByReCTTdlNM80vva8alAQC80HcOiHLkd8XAxIiKghKSHcqeNfyhp3VsYAV8VSiPKu4Jc8wWCfsZNAIvd1uCqA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4451,9 +4451,9 @@
}
},
"node_modules/beercss": {
"version": "3.12.13",
"resolved": "https://registry.npmjs.org/beercss/-/beercss-3.12.13.tgz",
"integrity": "sha512-zsg15us8pSLTupIOzFFJqpJ7eJDLV6whsxT6GcRYGnYaF0ka45+HQ/u3+ldSUkCeyA5J24g6csEuMW8tqrI/0w==",
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/beercss/-/beercss-3.13.1.tgz",
"integrity": "sha512-729VrZYmaySNf8OXJ7iovXdToiqwiSuMNBABWOTMQxOBnwS78VnV7tRs1Ke0yK5mjij5WYwr6MLx4eSK0S7ThQ==",
"license": "MIT",
"dependencies": {
"material-dynamic-colors": "^1.1.2"
@@ -6287,9 +6287,9 @@
}
},
"node_modules/esrap": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.0.tgz",
"integrity": "sha512-WBmtxe7R9C5mvL4n2le8nMUe4mD5V9oiK2vJpQ9I3y20ENPUomPcphBXE8D1x/Bm84oN1V+lOfgXxtqmxTp3Xg==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.1.tgz",
"integrity": "sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -7349,9 +7349,9 @@
}
},
"node_modules/i18next": {
"version": "25.6.3",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.3.tgz",
"integrity": "sha512-AEQvoPDljhp67a1+NsnG/Wb1Nh6YoSvtrmeEd24sfGn3uujCtXCF3cXpr7ulhMywKNFF7p3TX1u2j7y+caLOJg==",
"version": "25.7.2",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.2.tgz",
"integrity": "sha512-58b4kmLpLv1buWUEwegMDUqZVR5J+rT+WTRFaBGL7lxDuJQQ0NrJFrq+eT2N94aYVR1k1Sr13QITNOL88tZCuw==",
"funding": [
{
"type": "individual",
@@ -11698,9 +11698,9 @@
}
},
"node_modules/svelte": {
"version": "5.45.2",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.45.2.tgz",
"integrity": "sha512-yyXdW2u3H0H/zxxWoGwJoQlRgaSJLp+Vhktv12iRw2WRDlKqUPT54Fi0K/PkXqrdkcQ98aBazpy0AH4BCBVfoA==",
"version": "5.45.6",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.45.6.tgz",
"integrity": "sha512-V3aVXthzPyPt1UB1wLEoXnEXpwPsvs7NHrR0xkCor8c11v71VqBj477MClqPZYyrcXrAH21sNGhOj9FJvSwXfQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -11713,7 +11713,7 @@
"clsx": "^2.1.1",
"devalue": "^5.5.0",
"esm-env": "^1.2.1",
"esrap": "^2.2.0",
"esrap": "^2.2.1",
"is-reference": "^3.0.3",
"locate-character": "^3.0.0",
"magic-string": "^0.30.11",
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.12.3",
"version": "1.12.4",
"private": true,
"scripts": {
"dev": "vite dev",
@@ -19,7 +19,7 @@
"@capacitor/cli": "^7.4.4",
"@sveltejs/adapter-auto": "^6.0.1",
"@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/kit": "^2.49.0",
"@sveltejs/kit": "^2.49.1",
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@types/event-source-polyfill": "^1.0.5",
"@types/he": "^1.2.3",
@@ -32,7 +32,7 @@
"patch-package": "^8.0.1",
"prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0",
"svelte": "^5.45.2",
"svelte": "^5.45.6",
"svelte-check": "^4.3.3",
"tslib": "^2.7.0",
"typescript": "^5.9.3",
@@ -43,7 +43,7 @@
"dependencies": {
"@capacitor-community/electron": "^5.0.1",
"@capacitor-community/safe-area": "^7.0.0-alpha.1",
"@capacitor/android": "^7.4.3",
"@capacitor/android": "^7.4.4",
"@capacitor/app": "^7.1.0",
"@capacitor/browser": "^7.0.0",
"@capacitor/clipboard": "^7.0.0",
@@ -53,7 +53,7 @@
"@capacitor/share": "^7.0.2",
"@macfja/serializer": "^1.1.4",
"@macfja/svelte-persistent-store": "^2.4.2",
"beercss": "^3.12.13",
"beercss": "^3.13.1",
"bgutils-js": "^3.2.0",
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
"dayjs": "^1.11.19",
@@ -62,7 +62,7 @@
"googlevideo": "^4.0.4",
"he": "^1.2.0",
"human-number": "^2.0.8",
"i18next": "^25.6.3",
"i18next": "^25.7.2",
"iso-3166": "^4.4.0",
"iso-639-1": "^3.1.5",
"material-dynamic-colors": "^1.1.1",
@@ -74,4 +74,4 @@
"svelte-infinite-loading": "^1.4.0",
"youtubei.js": "^16.0.1"
}
}
}
@@ -0,0 +1,110 @@
<script lang="ts">
import { resolve } from '$app/paths';
import { amSubscribed, deleteUnsubscribe, postSubscribe } from '$lib/api';
import type { Image } from '$lib/api/model';
import { getBestThumbnail, proxyGoogleImage } from '$lib/images';
import { truncate } from '$lib/misc';
import { authStore, interfaceLowBandwidthMode, isAndroidTvStore } from '$lib/store';
import { _ } from '$lib/i18n';
import { localDb } from '$lib/dexie';
import { onMount } from 'svelte';
let {
channel,
hideSubscribe = false
}: {
channel: { authorId: string; subCountText: string; authorThumbnails: Image[]; author: string };
hideSubscribe?: boolean;
} = $props();
let favoritedChannel = $state(false);
let subscribed = $state(false);
const favoriteChannelItem = localDb.favouriteChannels.filter((item) => {
return item.channelId === channel.authorId;
});
onMount(async () => {
amSubscribed(channel.authorId).then((subbed) => (subscribed = subbed));
favoritedChannel = (await favoriteChannelItem.count()) > 0;
});
async function toggleSubscribed() {
if (subscribed) {
await deleteUnsubscribe(channel.authorId);
} else {
await postSubscribe(channel.authorId);
}
subscribed = !subscribed;
}
async function toggleFavourited() {
if (favoritedChannel) {
await favoriteChannelItem.delete();
favoritedChannel = false;
} else {
await localDb.favouriteChannels.add({ channelId: channel.authorId, created: new Date() });
favoritedChannel = true;
}
}
</script>
<nav>
<a href={resolve(`/channel/[authorId]`, { authorId: channel.authorId })}>
<nav style="gap: 0.5em;">
{#if !$interfaceLowBandwidthMode}
<img
loading="lazy"
class="circle large"
src={proxyGoogleImage(getBestThumbnail(channel.authorThumbnails))}
alt="Channel profile"
/>
{/if}
<div>
<p style="margin: 0;" class="bold">
{$isAndroidTvStore ? channel.author : truncate(channel.author, 16)}
</p>
<p style="margin: 0;">{channel.subCountText}</p>
</div>
</nav>
</a>
{#if !hideSubscribe}
{#if $authStore}
<nav class="group split">
<button
onclick={toggleSubscribed}
class:inverse-surface={!subscribed}
class:border={subscribed}
>
{#if !subscribed}
{$_('subscribe')}
{:else}
{$_('unsubscribe')}
{/if}
</button>
{#if window.indexedDB && subscribed}
<button
class:inverse-surface={!favoritedChannel}
class:border={favoritedChannel}
onclick={toggleFavourited}
class="square"
>
<i>star</i>
<div class="tooltip">
{favoritedChannel ? $_('unfavouriteChannel') : $_('favouriteChannel')}
</div>
</button>
{/if}
</nav>
{:else}
<button class="inverse-surface" disabled>
{$_('subscribe')}
<div class="tooltip">
{$_('loginRequired')}
</div>
</button>
{/if}
{/if}
</nav>
@@ -308,6 +308,15 @@
// Continue regardless of error
}
player.addEventListener('loaded', () => {
restoreQualityPreference();
restoreDefaultLanguage();
if ($playerCCByDefault) {
toggleSubtitles();
}
});
if (!data.video.liveNow) {
if (watchProgressTimeout) {
clearInterval(watchProgressTimeout);
@@ -408,13 +417,6 @@
ui('#snackbar-alert');
}
restoreQualityPreference();
restoreDefaultLanguage();
if ($playerCCByDefault) {
toggleSubtitles();
}
if ($playerDefaultPlaybackSpeed && playerElement) {
playerElement.playbackRate = $playerDefaultPlaybackSpeed;
}
@@ -1,102 +0,0 @@
<script lang="ts">
import { resolve } from '$app/paths';
import { deleteUnsubscribe, postSubscribe } from '$lib/api';
import type { VideoPlay } from '$lib/api/model';
import { getBestThumbnail, proxyGoogleImage } from '$lib/images';
import { truncate } from '$lib/misc';
import { authStore, interfaceLowBandwidthMode, isAndroidTvStore } from '$lib/store';
import { _ } from '$lib/i18n';
import { localDb } from '$lib/dexie';
import { onMount } from 'svelte';
let {
video,
subscribed = $bindable(false),
hideSubscribe = false
}: { video: VideoPlay; subscribed?: boolean; hideSubscribe?: boolean } = $props();
let favoritedChannel = $state(false);
const favoriteChannelItem = localDb.favouriteChannels.filter((item) => {
return item.channelId === video.authorId;
});
onMount(async () => {
favoritedChannel = (await favoriteChannelItem.count()) > 0;
});
async function toggleSubscribed() {
if (subscribed) {
await deleteUnsubscribe(video.authorId);
} else {
await postSubscribe(video.authorId);
}
subscribed = !subscribed;
}
async function toggleFavourited() {
if (favoritedChannel) {
await favoriteChannelItem.delete();
favoritedChannel = false;
} else {
await localDb.favouriteChannels.add({ channelId: video.authorId, created: new Date() });
favoritedChannel = true;
}
}
</script>
<nav>
<a href={resolve(`/channel/[authorId]`, { authorId: video.authorId })}>
<nav style="gap: 0.5em;">
{#if !$interfaceLowBandwidthMode}
<img
loading="lazy"
class="circle large"
src={proxyGoogleImage(getBestThumbnail(video.authorThumbnails))}
alt="Channel profile"
/>
{/if}
<div>
<p style="margin: 0;" class="bold">
{$isAndroidTvStore ? video.author : truncate(video.author, 16)}
</p>
<p style="margin: 0;">{video.subCountText}</p>
</div>
</nav>
</a>
{#if !hideSubscribe}
{#if $authStore}
<button
onclick={toggleSubscribed}
class:inverse-surface={!subscribed}
class:border={subscribed}
>
{#if !subscribed}
{$_('subscribe')}
{:else}
{$_('unsubscribe')}
{/if}
</button>
{#if window.indexedDB}
<button
class:inverse-surface={!favoritedChannel}
class:border={favoritedChannel}
onclick={toggleFavourited}
>
<i>star</i>
<div class="tooltip">
{favoritedChannel ? $_('unfavouriteChannel') : $_('favouriteChannel')}
</div>
</button>
{/if}
{:else}
<button class="inverse-surface" disabled>
{$_('subscribe')}
<div class="tooltip">
{$_('loginRequired')}
</div>
</button>
{/if}
{/if}
</nav>
@@ -84,13 +84,13 @@
onclick={async () => loadReplies(comment.replies.continuation)}
class="transparent replies"
>
<i class="white-text">expand_more</i>
<span class="white-text">{comment.replies.replyCount} {replyText}</span>
<i>expand_more</i>
<span>{comment.replies.replyCount} {replyText}</span>
</button>
{:else if replies}
<button onclick={() => (replies = undefined)} class="transparent replies">
<i class="white-text">expand_less</i>
<span class="white-text">Hide {replyText}</span>
<i>expand_less</i>
<span>Hide {replyText}</span>
</button>
{/if}
</div>
+1 -3
View File
@@ -1,5 +1,4 @@
import {
amSubscribed,
getComments,
getDislikes,
getPersonalPlaylists,
@@ -79,8 +78,7 @@ export async function getWatchDetails(videoId: string, url: URL) {
streamed: {
personalPlaylists: personalPlaylists,
returnYTDislikes: returnYTDislikes,
comments: comments,
subscribed: amSubscribed(video.authorId)
comments: comments
}
};
}
+2 -2
View File
@@ -44,7 +44,7 @@
import { pwaInfo } from 'virtual:pwa-info';
import Mousetrap from 'mousetrap';
import { truncate } from '$lib/misc';
import Author from '$lib/components/watch/Author.svelte';
import Author from '$lib/components/Author.svelte';
let { children } = $props();
@@ -438,7 +438,7 @@
</nav>
<nav class="m l">
<Author video={$playerState.data.video} hideSubscribe={true} />
<Author channel={$playerState.data.video} hideSubscribe={true} />
<div class="max"></div>
<a
class="button border"
@@ -1,30 +1,25 @@
<script lang="ts">
import {
amSubscribed,
deleteUnsubscribe,
getChannelContent,
postSubscribe,
searchChannelContent,
type channelContentTypes,
type channelSortBy
} from '$lib/api';
import type { ChannelContentPlaylists, ChannelContentVideos } from '$lib/api/model';
import PageLoading from '$lib/components/PageLoading.svelte';
import { getBestThumbnail, proxyGoogleImage } from '$lib/images';
import { proxyGoogleImage } from '$lib/images';
import { cleanNumber } from '$lib/numbers';
import { authStore, interfaceLowBandwidthMode, isAndroidTvStore } from '$lib/store';
import { interfaceLowBandwidthMode, isAndroidTvStore } from '$lib/store';
import { Clipboard } from '@capacitor/clipboard';
import { Capacitor } from '@capacitor/core';
import { onMount } from 'svelte';
import { _ } from '$lib/i18n';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import { get } from 'svelte/store';
import ItemsList from '$lib/components/ItemsList.svelte';
import Author from '$lib/components/Author.svelte';
let { data } = $props();
let isSubscribed = $state(false);
let tab: channelContentTypes = $state('videos');
let sortBy: channelSortBy = $state('newest');
@@ -77,34 +72,12 @@
displayContent = await getChannelContent(data.channel.authorId, { type: tab });
}
let channelPfp: string | undefined = $state();
onMount(async () => {
displayContent = await getChannelContent(data.channel.authorId, {
type: 'videos',
sortBy: sortBy
});
if (!get(interfaceLowBandwidthMode)) {
const channelPfpResp = await fetch(
proxyGoogleImage(getBestThumbnail(data.channel.authorThumbnails))
);
channelPfp = URL.createObjectURL(await channelPfpResp.blob());
}
if (get(authStore)) {
isSubscribed = await amSubscribed(data.channel.authorId);
}
});
async function toggleSubscribed() {
if (isSubscribed) {
await deleteUnsubscribe(data.channel.authorId);
} else {
await postSubscribe(data.channel.authorId);
}
isSubscribed = !isSubscribed;
}
</script>
<div class="padding">
@@ -117,78 +90,43 @@
/>
{/if}
<div class="description">
{#if !$interfaceLowBandwidthMode}
<div class="m l">
{#if channelPfp}
<img
loading="lazy"
style="margin-right: 1em;"
class="circle extra"
src={channelPfp}
alt="Channel profile"
/>
{:else}
<progress style="padding: 15px;" class="circle"></progress>
{/if}
</div>
{/if}
<div>
<h2>{data.channel.author}</h2>
<p>{cleanNumber(data.channel.subCount)} {$_('subscribers')}</p>
<Author channel={{ ...data.channel, subCountText: cleanNumber(data.channel.subCount) }} />
<p style="width: 60vw;">{data.channel.description}</p>
</div>
<div class="grid no-padding">
<div class="s12 m12 l5">
<button
onclick={toggleSubscribed}
class:inverse-surface={!isSubscribed}
class:border={isSubscribed}
>
{#if !isSubscribed}
{$_('subscribe')}
{:else}
{$_('unsubscribe')}
{#if !$isAndroidTvStore}
<button class="border">
<i>share</i>
<span>{$_('player.share.title')}</span>
<menu class="no-wrap mobile">
{#if !Capacitor.isNativePlatform()}
<li
class="row"
role="presentation"
onclick={async () => {
await Clipboard.write({ string: location.href });
(document.activeElement as HTMLElement)?.blur();
}}
>
{$_('player.share.materialiousLink')}
</li>
{/if}
</button>
</div>
{#if !$isAndroidTvStore}
<div class="s12 m12 l5">
<button class="border">
<i>share</i>
<span>{$_('player.share.title')}</span>
<menu class="no-wrap mobile">
{#if !Capacitor.isNativePlatform()}
<li
class="row"
role="presentation"
onclick={async () => {
await Clipboard.write({ string: location.href });
(document.activeElement as HTMLElement)?.blur();
}}
>
{$_('player.share.materialiousLink')}
</li>
{/if}
<li
class="row"
role="presentation"
onclick={async () => {
await Clipboard.write({
string: `https://www.youtube.com/channel/${data.channel.authorId}`
});
(document.activeElement as HTMLElement)?.blur();
}}
>
{$_('player.share.youtubeLink')}
</li>
</menu>
</button>
</div>
{/if}
</div>
<li
class="row"
role="presentation"
onclick={async () => {
await Clipboard.write({
string: `https://www.youtube.com/channel/${data.channel.authorId}`
});
(document.activeElement as HTMLElement)?.blur();
}}
>
{$_('player.share.youtubeLink')}
</li>
</menu>
</button>
{/if}
</div>
<div class="tabs left-align scroll">
@@ -34,7 +34,7 @@
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { loadEntirePlaylist } from '$lib/playlist';
import Author from '$lib/components/watch/Author.svelte';
import Author from '$lib/components/Author.svelte';
import Description from '$lib/components/watch/Description.svelte';
import LikesDislikes from '$lib/components/watch/LikesDislikes.svelte';
import Comment from '$lib/components/watch/Comment.svelte';
@@ -52,9 +52,6 @@
comments = streamedComments;
});
let subscribed: boolean = $state(false);
data.streamed.subscribed.then((isSubbed) => (subscribed = isSubbed));
let personalPlaylists: PlaylistPage[] | null = $state(null);
data.streamed.personalPlaylists?.then((streamPlaylists) => (personalPlaylists = streamPlaylists));
@@ -400,7 +397,7 @@
<div class="grid no-padding">
<div class="s12 m12 l5" style="height: 100%;display: flex;align-items: center;">
<Author video={data.video} bind:subscribed />
<Author channel={data.video} />
</div>
<div class="s12 m12 l7 video-actions">
<div>
@@ -1,7 +1,7 @@
<script lang="ts">
import ContentColumn from '$lib/components/ContentColumn.svelte';
import Player from '$lib/components/Player.svelte';
import Author from '$lib/components/watch/Author.svelte';
import Author from '$lib/components/Author.svelte';
import Description from '$lib/components/watch/Description.svelte';
import LikesDislikes from '$lib/components/watch/LikesDislikes.svelte';
import { letterCase } from '$lib/letterCasing';
@@ -18,9 +18,6 @@
let showInfo = $state(false);
let playerCurrentTime: number = $state(0);
let subscribed: boolean = $state(false);
data.streamed.subscribed.then((isSubbed) => (subscribed = isSubbed));
onMount(() => {
if (playerElement) {
playerElement.addEventListener('timeupdate', () => {
@@ -121,7 +118,7 @@
{#if showInfo}
<article id="shown-info" transition:fade>
<h5>{letterCase(data.video.title)}</h5>
<Author bind:subscribed video={data.video} />
<Author channel={data.video} />
<LikesDislikes video={data.video} returnYTDislikes={data.streamed.returnYTDislikes} />
<article class="border">
<Description video={data.video} description={data.content.description} />
+1 -1
View File
@@ -3,7 +3,7 @@ import os
import re
from datetime import datetime
LATEST_VERSION = "1.12.3"
LATEST_VERSION = "1.12.4"
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")