Update/1.12.0 (#1227)

* Explain why we need custom CORS headers.

* Translated using Weblate (German)

Currently translated at 100.0% (170 of 170 strings)

Translation: Materialious/Materialious
Translate-URL: https://toolate.othing.xyz/projects/materialious/materialious/de/

* Translated using Weblate (Alemannic)

Currently translated at 100.0% (170 of 170 strings)

Translation: Materialious/Materialious
Translate-URL: https://toolate.othing.xyz/projects/materialious/materialious/gsw/

* Bump svelte from 5.43.5 to 5.45.2 in /materialious

Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.43.5 to 5.45.2.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/svelte@5.45.2/packages/svelte)

---
updated-dependencies:
- dependency-name: svelte
  dependency-version: 5.45.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump vite from 7.2.4 to 7.2.6 in /materialious

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.2.4 to 7.2.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump @capacitor/core from 7.4.3 to 7.4.4 in /materialious

Bumps [@capacitor/core](https://github.com/ionic-team/capacitor) from 7.4.3 to 7.4.4.
- [Release notes](https://github.com/ionic-team/capacitor/releases)
- [Changelog](https://github.com/ionic-team/capacitor/blob/7.4.4/CHANGELOG.md)
- [Commits](https://github.com/ionic-team/capacitor/compare/7.4.3...7.4.4)

---
updated-dependencies:
- dependency-name: "@capacitor/core"
  dependency-version: 7.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump shaka-player from 4.16.10 to 4.16.11 in /materialious

Bumps [shaka-player](https://github.com/shaka-project/shaka-player) from 4.16.10 to 4.16.11.
- [Release notes](https://github.com/shaka-project/shaka-player/releases)
- [Changelog](https://github.com/shaka-project/shaka-player/blob/v4.16.11/CHANGELOG.md)
- [Commits](https://github.com/shaka-project/shaka-player/compare/v4.16.10...v4.16.11)

---
updated-dependencies:
- dependency-name: shaka-player
  dependency-version: 4.16.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump human-number from 2.0.7 to 2.0.8 in /materialious

Bumps [human-number](https://github.com/Kikobeats/human-number) from 2.0.7 to 2.0.8.
- [Release notes](https://github.com/Kikobeats/human-number/releases)
- [Changelog](https://github.com/Kikobeats/human-number/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Kikobeats/human-number/compare/v2.0.7...v2.0.8)

---
updated-dependencies:
- dependency-name: human-number
  dependency-version: 2.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump chokidar from 4.0.3 to 5.0.0 in /materialious/electron

Bumps [chokidar](https://github.com/paulmillr/chokidar) from 4.0.3 to 5.0.0.
- [Release notes](https://github.com/paulmillr/chokidar/releases)
- [Commits](https://github.com/paulmillr/chokidar/compare/4.0.3...5.0.0)

---
updated-dependencies:
- dependency-name: chokidar
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump electron from 39.2.3 to 39.2.4 in /materialious/electron

Bumps [electron](https://github.com/electron/electron) from 39.2.3 to 39.2.4.
- [Release notes](https://github.com/electron/electron/releases)
- [Commits](https://github.com/electron/electron/compare/v39.2.3...v39.2.4)

---
updated-dependencies:
- dependency-name: electron
  dependency-version: 39.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Translated using Weblate (German)

Currently translated at 100.0% (172 of 172 strings)

Translation: Materialious/Materialious
Translate-URL: https://toolate.othing.xyz/projects/materialious/materialious/de/

* Translated using Weblate (Alemannic)

Currently translated at 100.0% (172 of 172 strings)

Translation: Materialious/Materialious
Translate-URL: https://toolate.othing.xyz/projects/materialious/materialious/gsw/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (172 of 172 strings)

Translation: Materialious/Materialious
Translate-URL: https://toolate.othing.xyz/projects/materialious/materialious/hu/

* Add link to official RYD website

* Translated using Weblate (Latvian)

Currently translated at 73.2% (126 of 172 strings)

Translation: Materialious/Materialious
Translate-URL: https://toolate.othing.xyz/projects/materialious/materialious/lv/

* Bump version to 1.12.0

* Fix menu dropdown on theatre mode

* Fixe linting

* Update package-lock.json

* Update package-lock.json

* Update package-lock.json

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: mk-pmb <mk-pmb@users.noreply.github.com>
Co-authored-by: Lenny Angst <lenny@familie-angst.ch>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ghost of Sparta <makesocialfoss32@keemail.me>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <toolate.othing.xyz.coool@privatepasta.com>
This commit is contained in:
Ward
2025-12-06 01:27:28 +00:00
committed by GitHub
parent ae8565dfe5
commit 3bbc495d9b
45 changed files with 297 additions and 211 deletions
+20 -18
View File
@@ -1,24 +1,26 @@
name: Check web
on:
pull_request:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
web-check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./materialious
web-check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./materialious
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: latest
- name: Install modules
run: npm install
- name: Check linting
run: npm run check
- name: Attempt to build codebase
run: npm run build
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: latest
- name: Install modules
run: npm install
- name: Run svelte checks
run: npm run check
- name: Check linting
run: npm run eslint
- name: Attempt to build codebase
run: npm run build
+1 -1
View File
@@ -24,7 +24,7 @@
- Sync your watch progress between Invidious sessions.
- Watch sync parties.
- Sponsorblock built-in.
- Return YouTube dislikes built-in.
- [Return YouTube Dislike](https://github.com/Anarios/return-youtube-dislike) (RYD) built-in.
- [DeArrow](https://github.com/ajayyy/DeArrow) built-in (With local processing fallback).
- No ads.
- No tracking.
+11 -2
View File
@@ -1,5 +1,14 @@
# Setup
For security reasons regarding CORS, your hosted instance of Materialious must serve as the value for the `Access-Control-Allow-Origin` header on Invidious.
### CORS
To assure browsers they are allowed to access your Materialious instance
despite their default [same-origin policy][wp-sop], the instance's webserver
needs to send [cross-origin resource sharing (CORS)][wp-cors] headers in its
response to the browser's `OPTIONS` request. The `Access-Control-Allow-Origin`
header of that response must be set to the public origin URI of your instance.
[wp-sop]: https://en.wikipedia.org/wiki/Same-origin_policy
[wp-cors]: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Invidious doesn't provide a simple way to modify CORS, so this must be done with your reverse proxy.
@@ -169,7 +178,7 @@ services:
# URL to your proxied Companion instance
VITE_DEFAULT_COMPANION_INSTANCE: "https://companion.materialio.us"
# URL TO RYD
# URL TO RYD (Return YouTube Dislike / https://github.com/Anarios/return-youtube-dislike)
# Leave blank to disable completely.
VITE_DEFAULT_RETURNYTDISLIKES_INSTANCE: "https://returnyoutubedislikeapi.com"
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 171
versionName "1.11.10"
versionCode 172
versionName "1.12.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -68,7 +68,11 @@
</content_rating>
<releases>
<release version="1.11.10" date="2025-11-28">
<release version="1.12.0" date="2025-12-05">
<url>https://github.com/Materialious/Materialious/releases/tag/1.12.0</url>
</release>
<release version="1.11.10" date="2025-11-28">
<url>https://github.com/Materialious/Materialious/releases/tag/1.11.10</url>
</release>
<release version="1.11.9" date="2025-11-25">
+16 -16
View File
@@ -1,17 +1,17 @@
{
"name": "Materialious",
"version": "1.11.9",
"version": "1.12.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "Materialious",
"version": "1.11.9",
"version": "1.12.0",
"license": "MIT",
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
"bgutils-js": "^3.2.0",
"chokidar": "~4.0.3",
"chokidar": "~5.0.0",
"electron-is-dev": "~2.0.0",
"electron-serve": "~3.0.0",
"electron-unhandled": "^4.0.1",
@@ -21,7 +21,7 @@
"jsonfile": "^6.2.0"
},
"devDependencies": {
"electron": "^39.2.3",
"electron": "^39.2.4",
"electron-builder": "^26.0.12",
"electron-rebuild": "^3.2.9",
"typescript": "^5.9.3"
@@ -1902,15 +1902,15 @@
}
},
"node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 14.16.0"
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
@@ -2584,9 +2584,9 @@
}
},
"node_modules/electron": {
"version": "39.2.3",
"resolved": "https://registry.npmjs.org/electron/-/electron-39.2.3.tgz",
"integrity": "sha512-j7k7/bj3cNA29ty54FzEMRUoqirE+RBQPhPFP+XDuM93a1l2WcDPiYumxKWz+iKcXxBJLFdMIAlvtLTB/RfCkg==",
"version": "39.2.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-39.2.4.tgz",
"integrity": "sha512-KxPtwpFceQKSxRtUY39piHLYhJMMyHfOhc70e6zRnKGrbRdK6hzEqssth8IGjlKOdkeT4KCvIEngnNraYk39+g==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -4989,12 +4989,12 @@
}
},
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.11.10",
"version": "1.12.0",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
@@ -24,7 +24,7 @@
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
"bgutils-js": "^3.2.0",
"chokidar": "~4.0.3",
"chokidar": "~5.0.0",
"electron-is-dev": "~2.0.0",
"electron-serve": "~3.0.0",
"electron-unhandled": "^4.0.1",
@@ -34,7 +34,7 @@
"jsonfile": "^6.2.0"
},
"devDependencies": {
"electron": "^39.2.3",
"electron": "^39.2.4",
"electron-builder": "^26.0.12",
"electron-rebuild": "^3.2.9",
"typescript": "^5.9.3"
+9 -2
View File
@@ -57,7 +57,7 @@ export default ts.config(
'.DS_Store',
'node_modules',
'/build',
'/.svelte-kit',
'**/.svelte-kit/*',
'/package',
'.env',
'.env.*',
@@ -65,7 +65,14 @@ export default ts.config(
// Ignore files for PNPM, NPM and YARN
'pnpm-lock.yaml',
'package-lock.json',
'yarn.lock'
'yarn.lock',
// Ignore our nodejs android code
'**/nodejs-android/*',
// Ignore electron code from capacitorjs
'**/electron/*',
// Ignore build files
'**/build/*',
'**/android/app/src/main/assets/*'
]
}
);
+30 -30
View File
@@ -1,12 +1,12 @@
{
"name": "materialious",
"version": "1.11.9",
"version": "1.12.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "materialious",
"version": "1.11.9",
"version": "1.12.0",
"hasInstallScript": true,
"dependencies": {
"@capacitor-community/electron": "^5.0.1",
@@ -15,7 +15,7 @@
"@capacitor/app": "^7.1.0",
"@capacitor/browser": "^7.0.0",
"@capacitor/clipboard": "^7.0.0",
"@capacitor/core": "^7.4.3",
"@capacitor/core": "^7.4.4",
"@capacitor/preferences": "^7.0.2",
"@capacitor/screen-orientation": "^7.0.0",
"@capacitor/share": "^7.0.2",
@@ -28,7 +28,7 @@
"fuse.js": "^7.0.0",
"googlevideo": "^4.0.4",
"he": "^1.2.0",
"human-number": "^2.0.7",
"human-number": "^2.0.8",
"i18next": "^25.6.3",
"iso-3166": "^4.4.0",
"iso-639-1": "^3.1.5",
@@ -36,7 +36,7 @@
"media-captions": "^1.0.4",
"mousetrap": "^1.6.5",
"peerjs": "^1.5.5",
"shaka-player": "^4.16.9",
"shaka-player": "^4.16.11",
"sponsorblock-api": "^0.2.4",
"svelte-infinite-loading": "^1.4.0",
"youtubei.js": "^16.0.1"
@@ -59,12 +59,12 @@
"patch-package": "^8.0.1",
"prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0",
"svelte": "^5.43.5",
"svelte": "^5.45.2",
"svelte-check": "^4.3.3",
"tslib": "^2.7.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.47.0",
"vite": "^7.2.4"
"vite": "^7.2.6"
}
},
"node_modules/@babel/code-frame": {
@@ -2067,9 +2067,9 @@
}
},
"node_modules/@capacitor/core": {
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.3.tgz",
"integrity": "sha512-wCWr8fQ9Wxn0466vPg7nMn0tivbNVjNy1yL4GvDSIZuZx7UpU2HeVGNe9QjN/quEd+YLRFeKEBLBw619VqUiNg==",
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.4.tgz",
"integrity": "sha512-xzjxpr+d2zwTpCaN0k+C6wKSZzWFAb9OVEUtmO72ihjr/NEDoLvsGl4WLfjWPcCO2zOy0b2X52tfRWjECFUjtw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.1.0"
@@ -5664,10 +5664,9 @@
}
},
"node_modules/devalue": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.3.2.tgz",
"integrity": "sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==",
"dev": true,
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz",
"integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==",
"license": "MIT"
},
"node_modules/dezalgo": {
@@ -6281,9 +6280,9 @@
}
},
"node_modules/esrap": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.2.tgz",
"integrity": "sha512-DgvlIQeowRNyvLPWW4PT7Gu13WznY288Du086E751mwwbsgr29ytBiYeLzAGIo0qk3Ujob0SDk8TiSaM5WQzNg==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.0.tgz",
"integrity": "sha512-WBmtxe7R9C5mvL4n2le8nMUe4mD5V9oiK2vJpQ9I3y20ENPUomPcphBXE8D1x/Bm84oN1V+lOfgXxtqmxTp3Xg==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -7331,9 +7330,9 @@
}
},
"node_modules/human-number": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/human-number/-/human-number-2.0.7.tgz",
"integrity": "sha512-oRlIx8WSLqpGutVzCq72WipnfH1+OaSoxiPc5l2eMxjqgGow3K4jzCxAHkS93nPxFDa0vXUKaDrmdIAKLwBlHQ==",
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/human-number/-/human-number-2.0.8.tgz",
"integrity": "sha512-0OikVKOKQR86Plj4Oyszl4TNYu4a9dsKeZKaZw6uHw+7zCDXZ3E3ldG/3ZRddwRajYljdZsMKFcvrNNXHR6wVg==",
"license": "MIT",
"dependencies": {
"round-to": "~5.0.0"
@@ -10997,9 +10996,9 @@
}
},
"node_modules/shaka-player": {
"version": "4.16.10",
"resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.16.10.tgz",
"integrity": "sha512-FJJk3rbV6IQ/gmdB6EZ4q4VuCKXdWG1pf7dPuqfZi6lNWIvymT4YWE+Hv5qkBwJRtT0L/8p/EFJKMhwE4AMTMQ==",
"version": "4.16.11",
"resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.16.11.tgz",
"integrity": "sha512-e87a3KtI69duaAm1omY2HwN9hq72ZN0j6mc4aBQgTrfJIBG8hZAw34tEPo6oqGR3IBpK86ASTmtrdUXCzt6yjg==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
@@ -11692,9 +11691,9 @@
}
},
"node_modules/svelte": {
"version": "5.43.5",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.43.5.tgz",
"integrity": "sha512-HQoZArIewxQVNedseDsgMgnRSC4XOXczxXLF9rOJaPIJkg58INOPUiL8aEtzqZIXNSZJyw8NmqObwg/voajiHQ==",
"version": "5.45.2",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.45.2.tgz",
"integrity": "sha512-yyXdW2u3H0H/zxxWoGwJoQlRgaSJLp+Vhktv12iRw2WRDlKqUPT54Fi0K/PkXqrdkcQ98aBazpy0AH4BCBVfoA==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -11705,8 +11704,9 @@
"aria-query": "^5.3.1",
"axobject-query": "^4.1.0",
"clsx": "^2.1.1",
"devalue": "^5.5.0",
"esm-env": "^1.2.1",
"esrap": "^2.1.0",
"esrap": "^2.2.0",
"is-reference": "^3.0.3",
"locate-character": "^3.0.0",
"magic-string": "^0.30.11",
@@ -12500,9 +12500,9 @@
}
},
"node_modules/vite": {
"version": "7.2.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz",
"integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz",
"integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==",
"dev": true,
"license": "MIT",
"dependencies": {
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.11.10",
"version": "1.12.0",
"private": true,
"scripts": {
"dev": "vite dev",
@@ -32,12 +32,12 @@
"patch-package": "^8.0.1",
"prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0",
"svelte": "^5.43.5",
"svelte": "^5.45.2",
"svelte-check": "^4.3.3",
"tslib": "^2.7.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.47.0",
"vite": "^7.2.4"
"vite": "^7.2.6"
},
"type": "module",
"dependencies": {
@@ -47,7 +47,7 @@
"@capacitor/app": "^7.1.0",
"@capacitor/browser": "^7.0.0",
"@capacitor/clipboard": "^7.0.0",
"@capacitor/core": "^7.4.3",
"@capacitor/core": "^7.4.4",
"@capacitor/preferences": "^7.0.2",
"@capacitor/screen-orientation": "^7.0.0",
"@capacitor/share": "^7.0.2",
@@ -60,7 +60,7 @@
"fuse.js": "^7.0.0",
"googlevideo": "^4.0.4",
"he": "^1.2.0",
"human-number": "^2.0.7",
"human-number": "^2.0.8",
"i18next": "^25.6.3",
"iso-3166": "^4.4.0",
"iso-639-1": "^3.1.5",
@@ -68,7 +68,7 @@
"media-captions": "^1.0.4",
"mousetrap": "^1.6.5",
"peerjs": "^1.5.5",
"shaka-player": "^4.16.9",
"shaka-player": "^4.16.11",
"sponsorblock-api": "^0.2.4",
"svelte-infinite-loading": "^1.4.0",
"youtubei.js": "^16.0.1"
@@ -47,7 +47,7 @@ if (Capacitor.getPlatform() === 'android') {
if (needsProxying(args[1])) {
args[1] = corsProxyUrl + args[1];
}
/* @ts-ignore */
// @ts-expect-error args have any type
return originalXhrOpen.apply(this, args);
};
}
+3 -1
View File
@@ -52,7 +52,9 @@ export async function fetchErrorHandle(response: Response): Promise<Response> {
try {
const json = await response.json();
message = 'errorBacktrace' in json ? json.errorBacktrace : json.error;
} catch {}
} catch {
// Continue regardless of error
}
throw Error(message);
}
+1 -1
View File
@@ -248,7 +248,7 @@ export interface HashTag {
videoCount: number;
}
export interface Notification extends VideoBase {}
export type Notification = VideoBase;
export interface Feed {
notifications: Notification[];
+20 -7
View File
@@ -63,6 +63,7 @@
let snackBarAlert = $state('');
let originalOrigination: ScreenOrientationResult | undefined;
// eslint-disable-next-line no-undef
let watchProgressTimeout: NodeJS.Timeout;
let showVideoRetry = $state(false);
@@ -303,7 +304,9 @@
try {
document.getElementsByClassName('shaka-ad-info')[0].remove();
} catch {}
} catch {
// Continue regardless of error
}
if (!data.video.liveNow) {
if (watchProgressTimeout) {
@@ -525,7 +528,7 @@
console.error('Player error:', error);
});
player.getNetworkingEngine()?.registerResponseFilter((type, response, _) => {
player.getNetworkingEngine()?.registerResponseFilter((type, response) => {
if (
type !== shaka.net.NetworkingEngine.RequestType.SEGMENT ||
!response.uri.includes('/api/timedtext')
@@ -746,12 +749,16 @@
if (playerPos && Number(playerPos) > toSetTime) {
toSetTime = Number(playerPos);
}
} catch {}
} catch {
// Continue regardless of error
}
if ($synciousStore && $synciousInstanceStore && $authStore) {
try {
toSetTime = (await getVideoProgress(data.video.videoId))[0].time;
} catch {}
} catch {
// Continue regardless of error
}
}
return toSetTime;
@@ -769,7 +776,9 @@
) {
try {
localStorage.setItem(`v_${data.video.videoId}`, playerElement.currentTime.toString());
} catch {}
} catch {
// Continue regardless of error
}
if (synciousEnabled) {
saveVideoProgress(data.video.videoId, playerElement.currentTime);
@@ -777,7 +786,9 @@
} else {
try {
localStorage.removeItem(`v_${data.video.videoId}`);
} catch {}
} catch {
// Continue regardless of error
}
if (synciousEnabled) {
deleteVideoProgress(data.video.videoId);
@@ -799,7 +810,9 @@
try {
savePlayerPos();
} catch (error) {}
} catch {
// Continue regardless of error
}
Mousetrap.unbind(['left', 'right', 'space', 'c', 'f', 'shift+left', 'shift+right']);
@@ -24,6 +24,7 @@
let showSearchBox = $state(false);
// eslint-disable-next-line no-undef
let debounceTimer: NodeJS.Timeout;
function debouncedSearch(event: any) {
if (!searchSuggestions) return;
@@ -22,12 +22,14 @@
events.events.forEach((event) => {
if (event.type === 'change-video' && event.videoId) {
currentUrl.pathname = resolve(`/watch/[videoId]`, { videoId: event.videoId });
// eslint-disable-next-line svelte/no-navigation-without-resolve
goto(currentUrl);
} else if (event.type === 'goto' && event.path && event.path !== $page.url.pathname) {
if (blockedPages.includes(event.path.replace('/', ''))) {
ui('#sync-party-private-page');
} else {
currentUrl.pathname = event.path;
// eslint-disable-next-line svelte/no-navigation-without-resolve
goto(currentUrl);
}
}
@@ -96,7 +96,9 @@
break;
}
}
} catch {}
} catch {
// Continue regardless of error
}
}
const img = await insecureRequestImageHandler(imageSrc);
@@ -107,7 +109,9 @@
if (get(synciousStore) && get(synciousInstanceStore) && get(authStore)) {
try {
progress = (await queueSyncious(video.videoId))?.time?.toString() ?? undefined;
} catch {}
} catch {
// Continue regardless of error
}
}
});
@@ -156,6 +160,7 @@
<div class:sideways-root={sideways} tabindex="0" role="button">
<div id="thumbnail-container">
<!-- eslint-disable svelte/no-navigation-without-resolve -->
<a
tabindex="-1"
class="wave thumbnail"
@@ -48,10 +48,13 @@
isLoading = true;
transcript = null;
const resp = await fetch(`${!video.fallbackPatch ? new URL(get(instanceStore)).origin : ''}${url}`);
const resp = await fetch(
`${!video.fallbackPatch ? new URL(get(instanceStore)).origin : ''}${url}`
);
transcript = await parseText(await resp.text(), { strict: false });
// Group cues by Math.ceil(startTime)
// eslint-disable-next-line svelte/prefer-svelte-reactivity
const startTimeMap = new Map<number, VTTCue[]>();
for (const cue of transcript.cues) {
const roundedTime = Math.ceil(cue.startTime);
@@ -98,7 +101,7 @@
<div class="field label suffix border">
<select bind:value={url} onchange={loadTranscript} name="captions">
<option selected={true} value={null}>{$_('selectLang')}</option>
{#each video.captions as caption}
{#each video.captions as caption (caption)}
<option value={caption.url}>{caption.label}</option>
{/each}
</select>
@@ -131,7 +134,7 @@
{:else if transcript}
{#if transcript.cues.length > 0}
{#if transcriptCues.length > 0}
{#each transcriptCues as cue}
{#each transcriptCues as cue (cue)}
<div
class="transcript-line"
id={`transcript-line-${cue.startTime}`}
@@ -48,7 +48,7 @@
<h4>{$_('contributors')}</h4>
<div class="grid">
{#each ghContributors as contributor}
{#each ghContributors as contributor (contributor)}
{#if contributor.type === 'User'}
<div class="s12 m4 l4">
<article>
@@ -73,7 +73,7 @@
onchange={() => playerDefaultLanguage.set(defaultLanguage)}
>
<option selected={$playerDefaultLanguage === 'original'} value="original">Original</option>
{#each languageNames as language}
{#each languageNames as language (language)}
<option selected={$playerDefaultLanguage === language} value={language}
>{titleCase(language)}</option
>
@@ -113,7 +113,7 @@
bind:value={$playerDefaultPlaybackSpeed}
onchange={onSpeedChange}
>
{#each playbackRates as speed}
{#each playbackRates as speed (speed)}
<option value={speed}>x{speed}</option>
{/each}
</select>
@@ -304,7 +304,7 @@
<input
type="checkbox"
bind:checked={$playerStatisticsByDefault}
onclick={() => playerStatisticsByDefault.set(!playerStatisticsByDefault)}
onclick={() => playerStatisticsByDefault.set(!$playerStatisticsByDefault)}
role="switch"
/>
<span></span>
@@ -128,6 +128,7 @@
</a>
{/each}
{#if !$isAndroidTvStore}
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
<a href={`${$instanceStore}/preferences`} target="_blank" referrerpolicy="no-referrer">
<i>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
@@ -29,7 +29,9 @@
sort_by: 'top',
source: 'youtube'
});
} catch {}
} catch {
// Continue regardless of error
}
}
function commentTimestamps(html: string): string {
@@ -71,7 +73,9 @@
<span class="secondary-text">{comment.publishedText}</span>
</a>
<p class="no-margin">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html commentTimestamps(comment.contentHtml)}
<!-- Comment comes directly from YT so is already sanitized -->
</p>
<div class="comment-actions">
<p class="no-margin no-padding"><i>thumb_up</i> {numberWithCommas(comment.likeCount)}</p>
@@ -95,7 +99,7 @@
{/if}
{#if replies}
{#each replies.comments as reply}
{#each replies.comments as reply (reply)}
<CommentSelf comment={reply} {videoId} isSubComp={true} />
{/each}
{/if}
@@ -28,7 +28,9 @@
<div class="space"></div>
<div class="medium scroll">
<div style="white-space: pre-line; overflow-wrap: break-word;">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html description}
<!-- Description comes directly from YT so is already sanitized -->
</div>
{#if video.keywords && video.keywords.length > 0}
+5
View File
@@ -71,6 +71,11 @@ dialog {
justify-content: center;
}
menu {
left: auto;
right: 0;
}
@media screen and (max-width: 1000px) {
menu.mobile {
position: fixed !important;
+4 -2
View File
@@ -237,7 +237,9 @@ function setStores(toSet: Record<string, any>) {
let userOverwritten: boolean = false;
try {
userOverwritten = localStorage.getItem(store.name) !== null;
} catch {}
} catch {
// Continue regardless of error
}
const paramValue = toSet[store.name];
if (typeof paramValue !== 'undefined' && !userOverwritten) {
@@ -284,7 +286,7 @@ export function bookmarkletSaveToUrl(): string {
const url = new URL(location.origin);
persistedStores.forEach((store) => {
let value = get(store.store);
const value = get(store.store);
if (value !== null && value !== undefined) {
url.searchParams.set(store.name, value.toString());
}
+3 -1
View File
@@ -46,7 +46,9 @@ async function loadDayjsLocale(localeName: string) {
try {
const { default: locale } = await import(`dayjs/locale/${localeName}`);
dayjs.locale(locale);
} catch {}
} catch {
// Continue regardless of error
}
}
export async function initI18n(selectedLocale: string = getUserLocale()): Promise<void> {
+8 -3
View File
@@ -77,7 +77,8 @@
"materialiousLink": "Materialious-Link kopieren",
"invidiousRedirect": "Invidious-Weiterleitungslink kopieren",
"youtubeLink": "YouTube-Link kopieren",
"includeTimestamp": "Mit Zeitstempel"
"includeTimestamp": "Mit Zeitstempel",
"copiedSuccess": "In Zwischenablage kopiert"
},
"download": "Herunterladen",
"downloadSteps": {
@@ -178,7 +179,8 @@
"companionUrl": "Companion URL",
"expandChapters": "Kapitel standardmäßig ausklappen",
"displayThumbnailAvatars": "Vorschaubild-Avatare (Langsam)",
"about": "Über"
"about": "Über",
"androidNativeShare": "Natives Teilen nutzen"
},
"subscribe": "Abonnieren",
"recommendedVideos": "Vorgeschlagene Videos",
@@ -200,5 +202,8 @@
"duration": "Dauer",
"sortBy": "Sortieren nach",
"features": "Eigenschaften"
}
},
"newest": "Neuste",
"oldest": "Älteste",
"popular": "Populär"
}
+8 -3
View File
@@ -87,7 +87,8 @@
"displayThumbnailAvatars": "Vorschaubild-Avatar (Langsam)",
"expandDescription": "Beschriibig standardmässig erwiitere",
"disableAutoUpdate": "Automatischi Updates deaktiviere",
"about": "Über"
"about": "Über",
"androidNativeShare": "Nativs Teile bruche"
},
"videos": "Videos",
"cancel": "Abbreche",
@@ -160,7 +161,8 @@
"materialiousLink": "Materialious-Link kopiere",
"youtubeLink": "YouTube-Link kopiere",
"invidiousRedirect": "Invidious-Wiiterleitigslink kopiere",
"includeTimestamp": "Mit Ziitstempel"
"includeTimestamp": "Mit Ziitstempel",
"copiedSuccess": "I d Zwüscheablaag kopiert"
},
"download": "Abelade",
"downloadSteps": {
@@ -200,5 +202,8 @@
"duration": "Duur",
"sortBy": "Sortiere nach",
"features": "Eigeschafte"
}
},
"newest": "Neusti",
"oldest": "Ältisti",
"popular": "Populär"
}
+4 -2
View File
@@ -108,7 +108,8 @@
},
"logout": "Kijelentkezés",
"companionUrl": "Kiegészítő webcím",
"about": "Névjegy"
"about": "Névjegy",
"androidNativeShare": "Natív megosztás használata"
},
"enabled": "Engedélyezve",
"donate": "Adományozás",
@@ -122,7 +123,8 @@
"title": "Megosztás",
"materialiousLink": "Materialious-hivatkozás megosztása",
"youtubeLink": "Youtube-hivatkozás másolása",
"invidiousRedirect": "Invidious átirányítási hivatkozás másolása"
"invidiousRedirect": "Invidious átirányítási hivatkozás másolása",
"copiedSuccess": "Vágólapra másolva"
},
"audioOnly": "Csak hang",
"theatreMode": "Szélesvásznú mód",
+6 -3
View File
@@ -44,8 +44,8 @@
"theme": {
"theme": "Motīvs",
"color": "Krāsa",
"darkMode": "Tumšais režīms",
"lightMode": "Gaišais režīms",
"darkMode": "Tumšais motīvs",
"lightMode": "Gaišais motīvs",
"AmoledTheme": "AMOLED motīvs"
},
"player": {
@@ -55,7 +55,10 @@
"youtubeJsAlways": "Vienmēr izmantot",
"localVideoFallback": "Vietējais video ieguves rezerves variants",
"youtubeJsFallback": "Vietējais video apstrādes rezerves variants",
"alwaysLoopVideo": "Vienmēr atskaņot (malt) uz riņķi video"
"alwaysLoopVideo": "Vienmēr atskaņot (malt) uz riņķi video",
"miniPlayer": "Mini atskaņotājs",
"playerStatistics": "Rādīt atskaņotāja statistiku pēc noklusējuma",
"autoPlayNextByDefault": "Automātiski atskaņot nākamo video pēc noklusējuma"
},
"deArrow": {
"titleOnly": "Tikai virsrakstu",
+30 -29
View File
@@ -1,41 +1,42 @@
import { get } from "svelte/store";
import type { Image } from "./api/model";
import { instanceStore } from "./store";
import { get } from 'svelte/store';
import type { Image } from './api/model';
import { instanceStore } from './store';
export function getBestThumbnail(
images: Image[] | null,
maxWidthDimension: number = 480,
maxHeightDimension = 360
images: Image[] | null,
maxWidthDimension: number = 480,
maxHeightDimension = 360
): string {
if (images && images.length > 0) {
const imagesFiltered = images.filter(
(image) => image.width < maxWidthDimension && image.height < maxHeightDimension
);
if (images && images.length > 0) {
const imagesFiltered = images.filter(
(image) => image.width < maxWidthDimension && image.height < maxHeightDimension
);
if (imagesFiltered.length === 0) {
return images[0].url;
}
if (imagesFiltered.length === 0) {
return images[0].url;
}
imagesFiltered.sort((a, b) => {
return b.width * b.height - a.width * a.height;
});
imagesFiltered.sort((a, b) => {
return b.width * b.height - a.width * a.height;
});
return imagesFiltered[0].url;
} else {
return '';
}
return imagesFiltered[0].url;
} else {
return '';
}
}
export function proxyGoogleImage(source: string): string {
if (source.startsWith('//')) source = `https:${source}`;
if (source.startsWith('//')) source = `https:${source}`;
let path: string | undefined;
try {
path = new URL(source).pathname;
} catch { }
let path: string | undefined;
try {
path = new URL(source).pathname;
} catch {
// Continue regardless of error
}
if (typeof path === 'undefined') return '';
if (typeof path === 'undefined') return '';
return `${get(instanceStore)}/ggpht${path}`;
}
return `${get(instanceStore)}/ggpht${path}`;
}
+35 -41
View File
@@ -1,61 +1,55 @@
import { get } from "svelte/store";
import { interfaceForceCase } from "./store";
import { get } from 'svelte/store';
import { interfaceForceCase } from './store';
export type TitleCase = 'uppercase' | 'lowercase' | 'sentence case' | 'title case' | null;
export const titleCases: TitleCase[] = [
'lowercase',
'uppercase',
'title case',
'sentence case'
];
export const titleCases: TitleCase[] = ['lowercase', 'uppercase', 'title case', 'sentence case'];
export function letterCase(text: string, caseTypeOverwrite?: TitleCase): string {
const casing = caseTypeOverwrite ? caseTypeOverwrite : get(interfaceForceCase);
if (!casing) return text;
const casing = caseTypeOverwrite ? caseTypeOverwrite : get(interfaceForceCase);
if (!casing) return text;
switch (casing) {
case 'lowercase':
return text.toLowerCase();
case 'uppercase':
return text.toUpperCase();
case 'sentence case':
return sentenceCase(text);
default:
return titleCase(text);
}
switch (casing) {
case 'lowercase':
return text.toLowerCase();
case 'uppercase':
return text.toUpperCase();
case 'sentence case':
return sentenceCase(text);
default:
return titleCase(text);
}
}
export function sentenceCase(text: string): string {
let sentences: string[] = text.match(/[^.!?]*[.!?]*/g) || [];
const sentences: string[] = text.match(/[^.!?]*[.!?]*/g) || [];
let casedSentences: string[] = sentences.map(sentence => {
sentence = sentence.trim();
if (sentence.length === 0) return '';
return sentence.charAt(0).toUpperCase() + sentence.slice(1).toLowerCase();
});
const casedSentences: string[] = sentences.map((sentence) => {
sentence = sentence.trim();
if (sentence.length === 0) return '';
return sentence.charAt(0).toUpperCase() + sentence.slice(1).toLowerCase();
});
return casedSentences.join(' ');
return casedSentences.join(' ');
}
export function titleCase(text: string): string {
if (!text) return '';
if (!text) return '';
let words: string[] = text.split(/(\s+)/).filter(word => word.trim().length > 0);
const words: string[] = text.split(/(\s+)/).filter((word) => word.trim().length > 0);
let titleCasedWords: string[] = words.map(word => {
if (word.length === 0) return '';
const titleCasedWords: string[] = words.map((word) => {
if (word.length === 0) return '';
const firstChar = word.charAt(0);
const restOfWord = word.slice(1).toLowerCase();
const firstChar = word.charAt(0);
const restOfWord = word.slice(1).toLowerCase();
// Capitalize if the first character is a letter
if (/[a-zA-Z]/.test(firstChar)) {
return firstChar.toUpperCase() + restOfWord;
}
// Capitalize if the first character is a letter
if (/[a-zA-Z]/.test(firstChar)) {
return firstChar.toUpperCase() + restOfWord;
}
return word;
});
return word;
});
return titleCasedWords.join(' ');
return titleCasedWords.join(' ');
}
+9 -9
View File
@@ -1,10 +1,9 @@
import { pushState } from '$app/navigation';
import { resolve } from '$app/paths';
import { page } from '$app/stores';
import he from 'he';
import type Peer from 'peerjs';
import { get } from 'svelte/store';
import { instanceStore, interfaceAllowInsecureRequests, isAndroidTvStore } from './store';
import { interfaceAllowInsecureRequests, isAndroidTvStore } from './store';
import type {
Channel,
HashTag,
@@ -14,9 +13,10 @@ import type {
Video,
VideoBase
} from './api/model';
import { page } from '$app/state';
export function isVideoID(videoId: string): boolean {
var regExp = /^[a-zA-Z0-9_-]{11}$/;
const regExp = /^[a-zA-Z0-9_-]{11}$/;
return regExp.test(videoId);
}
@@ -34,15 +34,15 @@ export function unsafeRandomItem(array: any[]): any {
}
export function setWindowQueryFlag(key: string, value: string) {
const currentPage = get(page);
currentPage.url.searchParams.set(key, value);
pushState(currentPage.url, currentPage.state);
page.url.searchParams.set(key, value);
// eslint-disable-next-line svelte/no-navigation-without-resolve
pushState(page.url, page.state);
}
export function removeWindowQueryFlag(key: string) {
const currentPage = get(page);
currentPage.url.searchParams.delete(key);
pushState(currentPage.url, currentPage.state);
page.url.searchParams.delete(key);
// eslint-disable-next-line svelte/no-navigation-without-resolve
pushState(page.url, page.state);
}
let PeerInstance: typeof Peer;
+1 -1
View File
@@ -12,7 +12,7 @@ import { interfaceRegionStore, poTokenCacheStore } from '$lib/store';
import { Capacitor } from '@capacitor/core';
import { USER_AGENT } from 'bgutils-js';
import { get } from 'svelte/store';
import type { Types, Misc } from 'youtubei.js';
import type { Types } from 'youtubei.js';
import { Innertube, UniversalCache, Utils, YT, YTNodes, Platform } from 'youtubei.js';
Platform.shim.eval = async (
+1 -1
View File
@@ -8,7 +8,7 @@ import { darkModeStore, interfaceAmoledTheme } from './store';
export async function getDynamicTheme(mode?: string): Promise<Record<string, string>> {
const givenSettings = await ui('theme');
// @ts-ignore
// @ts-expect-error Works as expected
const themes: string = givenSettings[mode ? mode : (ui('mode') as string)];
const themeVars: Record<string, string> = {};
themes.split(';').forEach((keyVar) => {
+3 -1
View File
@@ -62,7 +62,9 @@ export async function getWatchDetails(videoId: string, url: URL) {
returnYTDislikes = get(returnYtDislikesStore)
? getDislikes(videoId, { priority: 'low' })
: null;
} catch {}
} catch {
// Continue regardless of error
}
}
const playlistId = url.searchParams.get('playlist');
+9 -4
View File
@@ -119,7 +119,9 @@
async function login() {
if (!$isAndroidTvStore) {
// eslint-disable-next-line svelte/prefer-svelte-reactivity
const path = new URL(`${get(instanceStore)}/authorize_token`);
// eslint-disable-next-line svelte/prefer-svelte-reactivity
const searchParams = new URLSearchParams({
scopes: ':feed,:subscriptions*,:playlists*,:history*,:notifications*'
});
@@ -207,7 +209,9 @@
const colorPalette = await colorTheme.getColorPalette();
themeHex = convertToHexColorCode(colorPalette.primary);
await ui('theme', themeHex);
} catch {}
} catch {
// Continue regardless of error
}
}
}
@@ -262,6 +266,7 @@
</script>
<svelte:head>
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html webManifestLink}
{#if Capacitor.getPlatform() === 'android' && !$isAndroidTvStore}
@@ -284,7 +289,7 @@
>
<Logo />
</header>
{#each getPages() as navPage}
{#each getPages() as navPage (navPage)}
{#if !navPage.requiresAuth || isLoggedIn}
<a href={resolve(navPage.href, {})} class:active={$page.url.href.endsWith(navPage.href)}
><i>{navPage.icon}</i>
@@ -361,7 +366,7 @@
</nav>
<nav class="bottom s">
{#each getPages() as navPage}
{#each getPages() as navPage (navPage)}
{#if !navPage.requiresAuth || isLoggedIn}
<a
class="round"
@@ -385,7 +390,7 @@
{#if notifications.length === 0}
<p>{$_('layout.noNewNotifications')}</p>
{:else}
{#each notifications as notification}
{#each notifications as notification (notification)}
<article class="no-padding border">
<Thumbnail video={notification}></Thumbnail>
</article>
@@ -102,11 +102,11 @@
</summary>
<article class="scroll medium">
<div class="grid">
{#each filters as filter}
{#each filters as filter (filter)}
<div class="s12 m2 l2">
<h6>{filter.title}</h6>
<ul class="list no-margin no-padding">
{#each filter.options as filterOption}
{#each filter.options as filterOption (filterOption)}
<li>
<button
class="small border"
@@ -2,7 +2,6 @@
import { getFeed } from '$lib/api/index';
import type { PlaylistPageVideo, Video, VideoBase } from '$lib/api/model';
import { feedCacheStore } from '$lib/store';
import { _ } from '$lib/i18n';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import ItemsList from '$lib/components/ItemsList.svelte';
@@ -28,7 +28,9 @@
subscriptions = subscriptions.filter((item) => {
return item.authorId !== authorId;
});
} catch {}
} catch {
// Continue regradless of error
}
}
</script>
@@ -18,6 +18,7 @@ export async function load({ url }) {
goToUrl.searchParams.set('time', timestamp);
}
// eslint-disable-next-line svelte/no-navigation-without-resolve
goto(goToUrl);
} else {
error(404);
@@ -26,7 +26,6 @@
playlistCacheStore,
playlistSettingsStore,
syncPartyConnectionsStore,
syncPartyPeerStore,
type PlayerState
} from '$lib/store';
import ui from 'beercss';
@@ -71,6 +70,7 @@
let playerCurrentTime: number = $state(0);
let premiereTime = $state('');
// eslint-disable-next-line no-undef
let premiereUpdateInterval: NodeJS.Timeout;
if (
@@ -302,7 +302,7 @@
playerElement.ended ||
playerElement.currentTime === 0 ||
playerElement.readyState <= 2 ||
!playerMiniplayerEnabled
!$playerMiniplayerEnabled
) {
playerState.set(undefined);
}
@@ -363,6 +363,7 @@
playertheatreModeIsActive.set(!$playertheatreModeIsActive);
}
// eslint-disable-next-line no-undef
let pauseTimeout: NodeJS.Timeout | undefined = $state();
function setPauseTimer() {
if (pauseTimeout) {
@@ -130,7 +130,7 @@
{#if data.content.timestamps.length > 0}
<h5 style="margin-bottom: 0;">{$_('player.chapters')}</h5>
<div class="grid">
{#each data.content.timestamps as timestamp}
{#each data.content.timestamps as timestamp (timestamp)}
<ContentColumn>
<article
role="presentation"
+3 -1
View File
@@ -28,7 +28,9 @@ export async function load({ url }) {
if (resolvedUrl.pageType === 'WEB_PAGE_TYPE_CHANNEL') {
goto(resolve(`/channel/[authorId]`, { authorId: resolvedUrl.ucid }));
}
} catch {}
} catch {
// continue regardless of error
}
}
const defaultPage = get(interfaceDefaultPage);
+1 -1
View File
@@ -3,7 +3,7 @@ import os
import re
from datetime import datetime
LATEST_VERSION = "1.11.10"
LATEST_VERSION = "1.12.0"
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")