Merge pull request #1304 from Materialious/update/1.13.2

Update/1.13.2
This commit is contained in:
Ward
2026-01-16 11:41:49 +00:00
committed by GitHub
23 changed files with 1125 additions and 506 deletions
@@ -6,7 +6,7 @@ Es lässt dich Videos durchstöbern und anschauen, Wiedergabelisten verwalten un
<li>Unterstützung für Invidious Companion</li>
<li>Invidious API Extended Integration</li>
<li>YouTube.js-Fallback für Desktop & Android, falls Invidious beim Laden von Videos fehlschlägt</li>
<li>Unterstützung zur Deaktivierung der Zertifikatsüberprüfung für Homelab-Nutzer</li>
<li>Unterstützung zur Deaktivierung der Zertifikatsüberprüfung für Homelab-Setups</li>
<li>Synchronisiere deinen Wiedergabefortschritt zwischen Invidious-Sitzungen</li>
<li>Schaue gemeinsam in Synchronisationsgruppen</li>
<li>Sponsorblock miteingebaut</li>
@@ -15,7 +15,7 @@ Es lässt dich Videos durchstöbern und anschauen, Wiedergabelisten verwalten un
<li>Keine Werbung</li>
<li>Kein Tracking</li>
<li>Hell- und Dunkel-Themes</li>
<li>Benutzerdefinierte Farb-Themes</li>
<li>Individuelle Farb-Themes</li>
<li>Integriert mit Invidious Abonnements, Wiedergabeverlauf & mehr</li>
<li>Livestream-Unterstützung</li>
<li>Dash-Unterstützung</li>
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 185
versionName "1.13.1"
versionCode 186
versionName "1.13.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -82,7 +82,11 @@
<release version="1.13.1" date="2026-1-06">
<release version="1.13.2" date="2026-1-16">
<url>https://github.com/Materialious/Materialious/releases/tag/1.13.2</url>
</release>
<release version="1.13.1" date="2026-1-06">
<url>https://github.com/Materialious/Materialious/releases/tag/1.13.1</url>
</release>
<release version="1.13.0" date="2026-1-03">
+616 -265
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.13.1",
"version": "1.13.2",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
@@ -24,7 +24,6 @@
"dependencies": {
"@capacitor-community/electron": "^5.0.0",
"bgutils-js": "^3.2.0",
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
"chokidar": "~5.0.0",
"electron-is-dev": "~2.0.0",
"electron-serve": "~3.0.0",
@@ -1,6 +1,4 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const CapacitorNodejs = require('../../../node_modules/capacitor-nodejs/electron/dist/plugin.js');
module.exports = {
CapacitorNodejs,
}
+2
View File
@@ -190,6 +190,8 @@ export class ElectronCapacitorApp {
globalShortcut.register('Control+Shift+I', () => {
this.MainWindow.webContents.toggleDevTools();
});
this.MainWindow.webContents.toggleDevTools();
// Security
this.MainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url);
+263 -138
View File
@@ -1,12 +1,12 @@
{
"name": "materialious",
"version": "1.13.0",
"version": "1.13.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "materialious",
"version": "1.13.0",
"version": "1.13.2",
"hasInstallScript": true,
"dependencies": {
"@capacitor-community/electron": "^5.0.1",
@@ -24,6 +24,7 @@
"@macfja/svelte-persistent-store": "^2.4.2",
"beercss": "^3.13.1",
"bgutils-js": "^3.2.0",
"buffer": "^6.0.3",
"capacitor-music-controls-plugin": "^6.1.0",
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
"dayjs": "^1.11.19",
@@ -42,7 +43,8 @@
"shaka-player": "^4.16.11",
"sponsorblock-api": "^0.2.4",
"svelte-infinite-loading": "^1.4.0",
"youtubei.js": "^16.0.1"
"youtubei.js": "^16.0.1",
"zod": "^4.3.5"
},
"devDependencies": {
"@capacitor/assets": "^3.0.5",
@@ -2641,9 +2643,9 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
"integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3733,9 +3735,9 @@
}
},
"node_modules/@sveltejs/kit": {
"version": "2.49.2",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.49.2.tgz",
"integrity": "sha512-Vp3zX/qlwerQmHMP6x0Ry1oY7eKKRcOWGc2P59srOp4zcqyn+etJyQpELgOi4+ZSUgteX8Y387NuwruLgGXLUQ==",
"version": "2.49.5",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.49.5.tgz",
"integrity": "sha512-dCYqelr2RVnWUuxc+Dk/dB/SjV/8JBndp1UovCyCZdIQezd8TRwFLNZctYkzgHxRJtaNvseCSRsuuHPeUgIN/A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3744,7 +3746,7 @@
"@types/cookie": "^0.6.0",
"acorn": "^8.14.1",
"cookie": "^0.6.0",
"devalue": "^5.3.2",
"devalue": "^5.6.2",
"esm-env": "^1.2.2",
"kleur": "^4.1.5",
"magic-string": "^0.30.5",
@@ -3763,25 +3765,29 @@
"@opentelemetry/api": "^1.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0",
"svelte": "^4.0.0 || ^5.0.0-next.0",
"typescript": "^5.3.3",
"vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0"
},
"peerDependenciesMeta": {
"@opentelemetry/api": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/@sveltejs/vite-plugin-svelte": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz",
"integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==",
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.4.tgz",
"integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sveltejs/vite-plugin-svelte-inspector": "^5.0.0",
"debug": "^4.4.1",
"deepmerge": "^4.3.1",
"magic-string": "^0.30.17",
"magic-string": "^0.30.21",
"obug": "^2.1.0",
"vitefu": "^1.1.1"
},
"engines": {
@@ -3835,31 +3841,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@sveltejs/vite-plugin-svelte/node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@sveltejs/vite-plugin-svelte/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@trapezedev/gradle-parse": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@trapezedev/gradle-parse/-/gradle-parse-7.1.3.tgz",
@@ -4132,20 +4113,20 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.1.tgz",
"integrity": "sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.0.tgz",
"integrity": "sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.50.1",
"@typescript-eslint/type-utils": "8.50.1",
"@typescript-eslint/utils": "8.50.1",
"@typescript-eslint/visitor-keys": "8.50.1",
"ignore": "^7.0.0",
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.53.0",
"@typescript-eslint/type-utils": "8.53.0",
"@typescript-eslint/utils": "8.53.0",
"@typescript-eslint/visitor-keys": "8.53.0",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.1.0"
"ts-api-utils": "^2.4.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4155,7 +4136,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.50.1",
"@typescript-eslint/parser": "^8.53.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
@@ -4171,17 +4152,17 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.1.tgz",
"integrity": "sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.0.tgz",
"integrity": "sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.50.1",
"@typescript-eslint/types": "8.50.1",
"@typescript-eslint/typescript-estree": "8.50.1",
"@typescript-eslint/visitor-keys": "8.50.1",
"debug": "^4.3.4"
"@typescript-eslint/scope-manager": "8.53.0",
"@typescript-eslint/types": "8.53.0",
"@typescript-eslint/typescript-estree": "8.53.0",
"@typescript-eslint/visitor-keys": "8.53.0",
"debug": "^4.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4195,16 +4176,41 @@
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.1.tgz",
"integrity": "sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==",
"node_modules/@typescript-eslint/parser/node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.50.1",
"@typescript-eslint/types": "^8.50.1",
"debug": "^4.3.4"
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/parser/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.0.tgz",
"integrity": "sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.53.0",
"@typescript-eslint/types": "^8.53.0",
"debug": "^4.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4217,15 +4223,40 @@
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.1.tgz",
"integrity": "sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==",
"node_modules/@typescript-eslint/project-service/node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.50.1",
"@typescript-eslint/visitor-keys": "8.50.1"
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/project-service/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.0.tgz",
"integrity": "sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.53.0",
"@typescript-eslint/visitor-keys": "8.53.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4236,9 +4267,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.1.tgz",
"integrity": "sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.0.tgz",
"integrity": "sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4253,17 +4284,17 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.1.tgz",
"integrity": "sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.0.tgz",
"integrity": "sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.50.1",
"@typescript-eslint/typescript-estree": "8.50.1",
"@typescript-eslint/utils": "8.50.1",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
"@typescript-eslint/types": "8.53.0",
"@typescript-eslint/typescript-estree": "8.53.0",
"@typescript-eslint/utils": "8.53.0",
"debug": "^4.4.3",
"ts-api-utils": "^2.4.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4277,10 +4308,35 @@
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/types": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.1.tgz",
"integrity": "sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.0.tgz",
"integrity": "sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4292,21 +4348,21 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.1.tgz",
"integrity": "sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.0.tgz",
"integrity": "sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.50.1",
"@typescript-eslint/tsconfig-utils": "8.50.1",
"@typescript-eslint/types": "8.50.1",
"@typescript-eslint/visitor-keys": "8.50.1",
"debug": "^4.3.4",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"@typescript-eslint/project-service": "8.53.0",
"@typescript-eslint/tsconfig-utils": "8.53.0",
"@typescript-eslint/types": "8.53.0",
"@typescript-eslint/visitor-keys": "8.53.0",
"debug": "^4.4.3",
"minimatch": "^9.0.5",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.1.0"
"ts-api-utils": "^2.4.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4329,6 +4385,24 @@
"balanced-match": "^1.0.0"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -4345,17 +4419,24 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/utils": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.1.tgz",
"integrity": "sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.0.tgz",
"integrity": "sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.50.1",
"@typescript-eslint/types": "8.50.1",
"@typescript-eslint/typescript-estree": "8.50.1"
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.53.0",
"@typescript-eslint/types": "8.53.0",
"@typescript-eslint/typescript-estree": "8.53.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4370,13 +4451,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.1.tgz",
"integrity": "sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.0.tgz",
"integrity": "sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.50.1",
"@typescript-eslint/types": "8.53.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -4951,6 +5032,30 @@
"readable-stream": "^3.4.0"
}
},
"node_modules/bl/node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -5045,9 +5150,9 @@
}
},
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
@@ -5065,7 +5170,7 @@
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
"ieee754": "^1.2.1"
}
},
"node_modules/buffer-crc32": {
@@ -6133,9 +6238,9 @@
}
},
"node_modules/devalue": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.1.tgz",
"integrity": "sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==",
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz",
"integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==",
"license": "MIT"
},
"node_modules/dexie": {
@@ -6644,9 +6749,9 @@
}
},
"node_modules/eslint-plugin-svelte": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.13.1.tgz",
"integrity": "sha512-Ng+kV/qGS8P/isbNYVE3sJORtubB+yLEcYICMkUWNaDTb0SwZni/JhAYXh/Dz/q2eThUwWY0VMPZ//KYD1n3eQ==",
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.14.0.tgz",
"integrity": "sha512-Isw0GvaMm0yHxAj71edAdGFh28ufYs+6rk2KlbbZphnqZAzrH3Se3t12IFh2H9+1F/jlDhBBL4oiOJmLqmYX0g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7842,9 +7947,9 @@
}
},
"node_modules/i18next": {
"version": "25.7.3",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.3.tgz",
"integrity": "sha512-2XaT+HpYGuc2uTExq9TVRhLsso+Dxym6PWaKpn36wfBmTI779OQ7iP/XaZHzrnGyzU4SHpFrTYLKfVyBfAhVNA==",
"version": "25.7.4",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.4.tgz",
"integrity": "sha512-hRkpEblXXcXSNbw8mBNq9042OEetgyB/ahc/X17uV/khPwzV+uB8RHceHh3qavyrkPJvmXFKXME2Sy1E0KjAfw==",
"funding": [
{
"type": "individual",
@@ -9687,6 +9792,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/obug": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
"integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
"dev": true,
"funding": [
"https://github.com/sponsors/sxzz",
"https://opencollective.com/debug"
],
"license": "MIT"
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -11440,9 +11556,9 @@
}
},
"node_modules/shaka-player": {
"version": "4.16.12",
"resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.16.12.tgz",
"integrity": "sha512-bUne2YBbpMId8tU9kPSeZWSJHKbt2t5XyH3all6OsReRrfFYP9apOgohInbaDXNd0T/S8hUgWQT+wqLKH41XJg==",
"version": "4.16.13",
"resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-4.16.13.tgz",
"integrity": "sha512-2K6g1EBGXht3QnUqF/LKiGuVrvr+nx2AF2Y7DGicSOTUoTXY7YQW8CFXT1ha+ldQfkTuihQkju5NCEzY/KKuIw==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
@@ -12135,9 +12251,9 @@
}
},
"node_modules/svelte": {
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.46.1.tgz",
"integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==",
"version": "5.46.4",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.46.4.tgz",
"integrity": "sha512-VJwdXrmv9L8L7ZasJeWcCjoIuMRVbhuxbss0fpVnR8yorMmjNDwcjIH08vS6wmSzzzgAG5CADQ1JuXPS2nwt9w==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -12148,7 +12264,7 @@
"aria-query": "^5.3.1",
"axobject-query": "^4.1.0",
"clsx": "^2.1.1",
"devalue": "^5.5.0",
"devalue": "^5.6.2",
"esm-env": "^1.2.1",
"esrap": "^2.2.1",
"is-reference": "^3.0.3",
@@ -12519,9 +12635,9 @@
}
},
"node_modules/ts-api-utils": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.2.0.tgz",
"integrity": "sha512-L6f5oQRAoLU1RwXz0Ab9mxsE7LtxeVB6AIR1lpkZMsOyg/JXeaxBaXa/FVCBZyNr9S9I4wkHrlZTklX+im+WMw==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12723,16 +12839,16 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.50.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.50.1.tgz",
"integrity": "sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.0.tgz",
"integrity": "sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.50.1",
"@typescript-eslint/parser": "8.50.1",
"@typescript-eslint/typescript-estree": "8.50.1",
"@typescript-eslint/utils": "8.50.1"
"@typescript-eslint/eslint-plugin": "8.53.0",
"@typescript-eslint/parser": "8.53.0",
"@typescript-eslint/typescript-estree": "8.53.0",
"@typescript-eslint/utils": "8.53.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -14035,6 +14151,15 @@
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
"license": "MIT"
},
"node_modules/zod": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz",
"integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}
+5 -3
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.13.1",
"version": "1.13.2",
"private": true,
"scripts": {
"dev": "npm run patch:github && vite dev",
@@ -57,6 +57,7 @@
"@macfja/svelte-persistent-store": "^2.4.2",
"beercss": "^3.13.1",
"bgutils-js": "^3.2.0",
"buffer": "^6.0.3",
"capacitor-music-controls-plugin": "^6.1.0",
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
"dayjs": "^1.11.19",
@@ -75,6 +76,7 @@
"shaka-player": "^4.16.11",
"sponsorblock-api": "^0.2.4",
"svelte-infinite-loading": "^1.4.0",
"youtubei.js": "^16.0.1"
"youtubei.js": "^16.0.1",
"zod": "^4.3.5"
}
}
}
@@ -1000,9 +1000,10 @@
if (playerAndroidUITimeout) {
clearTimeout(playerAndroidUITimeout);
showControls = true;
}
showControls = true;
playerAndroidUITimeout = setTimeout(() => {
showControls = false;
}, 3000);
@@ -1,13 +1,12 @@
<script lang="ts">
import { resolve } from '$app/paths';
import { instanceStore, interfaceAndroidUseNativeShare } from '$lib/store';
import { Share } from '@capacitor/share';
import { instanceStore } from '$lib/store';
import ui from 'beercss';
import { Clipboard } from '@capacitor/clipboard';
import { Capacitor } from '@capacitor/core';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import type { Notification, PlaylistPageVideo, Video, VideoBase } from '../api/model';
import { shareURL } from '$lib/misc';
interface Props {
video: VideoBase | Video | Notification | PlaylistPageVideo;
@@ -17,19 +16,12 @@
let { video, currentTime = $bindable() }: Props = $props();
let includeTimestamp: boolean = $state(false);
async function shareUrl(url: string, param: string = 't') {
async function shareVideo(url: string, param: string = 't') {
if (includeTimestamp) url += `?${param}=${Math.floor(currentTime ?? 0)}`;
if (
(await Share.canShare()) &&
Capacitor.getPlatform() !== 'electron' &&
$interfaceAndroidUseNativeShare
) {
await Share.share({ url: url, dialogTitle: video.title });
} else {
await Clipboard.write({ string: url });
ui('#share-success');
}
await shareURL(url);
ui('#share-success');
}
</script>
@@ -50,9 +42,9 @@
role="presentation"
onclick={async () => {
if (Capacitor.isNativePlatform()) {
shareUrl(`${get(instanceStore)}/watch/${video.videoId}`);
shareVideo(`${get(instanceStore)}/watch/${video.videoId}`);
} else {
shareUrl(
shareVideo(
`${location.origin}${resolve('/watch/[videoId]', { videoId: video.videoId })}`,
'time'
);
@@ -66,7 +58,7 @@
class="row"
role="presentation"
onclick={async () => {
shareUrl(`https://redirect.invidious.io/watch?v=${video.videoId}`);
shareVideo(`https://redirect.invidious.io/watch?v=${video.videoId}`);
}}
>
<div class="min">{$_('player.share.invidiousRedirect')}</div>
@@ -76,7 +68,7 @@
class="row"
role="presentation"
onclick={async () => {
shareUrl(`https://www.youtube.com/watch?v=${video.videoId}`);
shareVideo(`https://www.youtube.com/watch?v=${video.videoId}`);
}}
>
<div class="min">{$_('player.share.youtubeLink')}</div>
@@ -2,15 +2,34 @@
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { page } from '$app/stores';
import { peerJs, removeWindowQueryFlag, setWindowQueryFlag } from '$lib/misc';
import {
determinePeerJsInstance,
peerJs,
removeWindowQueryFlag,
setWindowQueryFlag,
shareURL
} from '$lib/misc';
import type { PlayerEvents } from '$lib/player';
import { Clipboard } from '@capacitor/clipboard';
import ui from 'beercss';
import type { DataConnection } from 'peerjs';
import { onDestroy, onMount } from 'svelte';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { syncPartyConnectionsStore, syncPartyPeerStore } from '../store';
import z from 'zod';
import { Buffer } from 'buffer';
import { Capacitor } from '@capacitor/core';
const SyncInfo = z.object({
host: z.string(),
path: z.string(),
port: z.number(),
syncId: z.string()
});
let syncPartyManualInput: string = $state('');
const syncOrigin = Capacitor.isNativePlatform() ? 'https://sync.materialio.us' : location.origin;
function changeVideoEvent(conn: DataConnection) {
conn.on('data', (data) => {
@@ -37,6 +56,16 @@
});
}
function createShareBase64(): string {
return Buffer.from(
JSON.stringify({
...determinePeerJsInstance(),
syncId: $syncPartyPeerStore?.id
}),
'utf-8'
).toString('base64');
}
async function startWatchSync() {
if ($syncPartyPeerStore) {
$syncPartyPeerStore.destroy();
@@ -89,24 +118,36 @@
}
});
async function joinSyncParty(syncInfo: string) {
const parseInfo = SyncInfo.safeParse(
JSON.parse(Buffer.from(syncInfo, 'base64').toString('utf-8'))
);
if (parseInfo.error) {
return;
}
$syncPartyPeerStore = await peerJs(crypto.randomUUID(), parseInfo.data);
$syncPartyPeerStore.on('open', () => {
if (!$syncPartyPeerStore) return;
const conn = $syncPartyPeerStore.connect(parseInfo.data.syncId);
syncPartyConnectionsStore.set([...($syncPartyConnectionsStore || []), conn]);
changeVideoEvent(conn);
});
$syncPartyPeerStore.on('disconnected', () => {
syncPartyPeerStore.set(null);
syncPartyConnectionsStore.set(null);
});
}
onMount(async () => {
const currentUrl = get(page).url;
const syncId = currentUrl.searchParams.get('sync');
if (syncId) {
$syncPartyPeerStore = await peerJs(crypto.randomUUID());
$syncPartyPeerStore.on('open', () => {
if (!$syncPartyPeerStore) return;
const conn = $syncPartyPeerStore.connect(syncId);
syncPartyConnectionsStore.set([...($syncPartyConnectionsStore || []), conn]);
changeVideoEvent(conn);
});
$syncPartyPeerStore.on('disconnected', () => {
syncPartyPeerStore.set(null);
syncPartyConnectionsStore.set(null);
});
const syncInfo = currentUrl.searchParams.get('sync');
if (syncInfo) {
await joinSyncParty(syncInfo);
}
});
@@ -118,25 +159,23 @@
});
</script>
<dialog id="sync-party">
<h6>{$_('layout.syncParty')}</h6>
<p>{$_('layout.syncPartyWarning')}</p>
<dialog id="sync-party" class="padding">
<h6 class="no-margin">{$_('layout.syncParty')}</h6>
<p class="no-margin">{$_('layout.syncPartyWarning')}</p>
{#if $syncPartyPeerStore}
<nav>
<div class="field label border max">
<input
name="sync-share"
readonly
value={`${location.origin}${resolve(`/?sync=${$syncPartyPeerStore?.id}`, {})}`}
value={`${syncOrigin}${resolve(`/?sync=${createShareBase64()}`, {})}`}
type="text"
/>
<label class="active" for="sync-share">Share URL</label>
<label class="active" for="sync-share">{$_('layout.shareURL')}</label>
</div>
<button
onclick={async () => {
await Clipboard.write({
string: `${location.origin}${resolve(`/?sync=${$syncPartyPeerStore?.id}`, {})}`
});
await shareURL(`${syncOrigin}${resolve(`/?sync=${createShareBase64()}`, {})}`);
}}
class="square round"
>
@@ -145,6 +184,7 @@
</nav>
{/if}
<div class="space"></div>
<button
class="no-margin"
onclick={startWatchSync}
@@ -155,6 +195,29 @@
{$_('layout.startSyncParty')}
{/if}
</button>
{#if !$syncPartyPeerStore}
<div class="space"></div>
<hr />
<div class="space"></div>
<h6 class="no-margin">{$_('layout.joinSyncParty')}</h6>
<form
onsubmit={async (event) => {
event.preventDefault();
try {
await joinSyncParty(new URL(syncPartyManualInput).searchParams.get('sync') || '');
} catch {
// Continue regardless of error
}
}}
>
<div class="field label border max">
<input bind:value={syncPartyManualInput} type="text" name="sync-input" />
<label for="sync-input">{$_('layout.shareURL')}</label>
</div>
</form>
{/if}
</dialog>
<div class="snackbar" id="sync-party-connection-join">
@@ -4,7 +4,7 @@
let ghContributors: { login: string; avatar_url: string; type: 'Bot' | 'User' }[] = $state([]);
onMount(() => {
fetch(`${document.location.origin}/localApi/ghContributors.json`, {
fetch('/localApi/ghContributors.json', {
priority: 'low'
}).then(async (resp) => {
if (!resp.ok) {
+14 -8
View File
@@ -27,9 +27,9 @@
"hideReplies": "Antworten verstecken",
"hideVideo": "Video verstecken",
"syncParty": {
"userJoined": "Ein Benutzer ist deiner Wiedergabegruppe beigetreten.",
"userLeft": "Ein Benutzer hat deine Wiedergabegruppe verlassen.",
"userOnPrivatePage": "Der Benutzer sieht sich gerade eine private Seite an, die Synchronisierung wird in Kürze fortgesetzt."
"userJoined": "Eine Person ist deiner Wiedergabegruppe beigetreten.",
"userLeft": "Eine Person hat deine Wiedergabegruppe verlassen.",
"userOnPrivatePage": "Die Person sieht sich gerade eine private Seite an, die Synchronisierung wird in Kürze fortgesetzt."
},
"videoTabs": {
"all": "Alle",
@@ -115,10 +115,10 @@
}
},
"layout": {
"interface": "Benutzeroberfläche",
"interface": "Bedienoberfläche",
"star": "Sternchen auf GitHub vergeben!",
"syncParty": "Synchronisationsgruppe",
"syncPartyWarning": "Bitte beachte, dass deine IP für die von dir eingeladenen Benutzer sichtbar ist.",
"syncPartyWarning": "Bitte beachte, dass deine IP für die von dir eingeladenen Personen sichtbar ist.",
"startSyncParty": "Synchronisationsgruppe starten",
"endSyncParty": "Synchronisationsgruppe stoppen",
"notifications": "Benachrichtigungen",
@@ -163,7 +163,8 @@
"defaultPlaybackSpeed": "Standardmäßige Wiedergabegeschwindigkeit",
"ccByDefault": "Untertitel standardmäßig an",
"localVideoFallback": "Lokaler Video-Fallback",
"playerStatistics": "Player-Statistiken standardmäßig anzeigen"
"playerStatistics": "Player-Statistiken standardmäßig anzeigen",
"networkChangePause": "Bei Netzwerkwechsel pausieren"
},
"bookmarklet": "Lesezeichen",
"instanceUrl": "URL der Instanz",
@@ -177,7 +178,10 @@
"intermissionIntroAnimation": "Unterbrechung/Einstiegsanimation",
"credits": "Abspann",
"preViewRecapHook": "Vorschau/Rückblick/Hook",
"tangentJokes": "Füllende Abweichler/Witze"
"tangentJokes": "Füllende Abweichler/Witze",
"automatic": "Automatisch überspringen",
"manual": "Manuell überspringen",
"timeline": "Nur Zeitleiste"
},
"deArrow": {
"title": "DeArrow",
@@ -217,5 +221,7 @@
"oldest": "Älteste",
"popular": "Populär",
"favouriteChannel": "Kanal favorisieren",
"unfavouriteChannel": "Kanal entfavorisieren"
"unfavouriteChannel": "Kanal entfavorisieren",
"skip": "Überspringen",
"upcomingSegment": "Kommend "
}
@@ -146,6 +146,8 @@
"syncPartyWarning": "Please note your IP will be visible to users you invite.",
"startSyncParty": "Start sync party",
"endSyncParty": "End sync party",
"joinSyncParty": "Enter sync party URL",
"shareURL": "Share URL",
"notifications": "Notifications",
"noNewNotifications": "No new notifications here",
"settings": "Settings",
+14 -8
View File
@@ -33,7 +33,8 @@
"youtubeJsAlways": "Immer nutze",
"lockOrientation": "Uusrichtig as Siiteverhältnis bunde",
"defaultPlaybackSpeed": "Standardmässigi Widergabegschwindigkeit",
"playerStatistics": "Player-Statistike standardmässig aazeige"
"playerStatistics": "Player-Statistike standardmässig aazeige",
"networkChangePause": "Bi Netzwerchwechsel pausiere"
},
"sponsors": {
"intermissionIntroAnimation": "Unterbrechig/Iistigsanimation",
@@ -45,9 +46,12 @@
"interactionReminder": "Interaktionsufforderig (Abonniere)",
"credits": "Abspann",
"preViewRecapHook": "Vorschau/Rückblick/Hook",
"tangentJokes": "Füllendi Abwiichler/Witz"
"tangentJokes": "Füllendi Abwiichler/Witz",
"automatic": "Automatisch überspringe",
"manual": "Manuell überspringe",
"timeline": "Nur Ziitleischte"
},
"interface": "Benutzeroberflächi",
"interface": "Bedienoberflächi",
"star": "Sternli uf GitHub vergeh!",
"syncParty": "Synchronisationsgruppe",
"startSyncParty": "Synchronisationsgruppe starte",
@@ -83,7 +87,7 @@
"thumbnailInstanceUrl": "URL vo de Vorschaubilder-Instanz",
"titleOnly": "Nur Titel"
},
"syncPartyWarning": "Bitte denk dra, dass dini IP für die vo dir iigladne Benutzer sichtbar isch.",
"syncPartyWarning": "Bitte denk dra, dass dini IP für die vo dir iigladne Persone sichtbar isch.",
"displayThumbnailAvatars": "Vorschaubild-Avatar (Langsam)",
"expandDescription": "Beschriibig standardmässig erwiitere",
"disableAutoUpdate": "Automatischi Updates deaktiviere",
@@ -114,9 +118,9 @@
"hideVideo": "Video verstecke",
"defaultPage": "Standardsiite",
"syncParty": {
"userJoined": "En Benutzer isch dinere Widergabegruppe biiträte.",
"userLeft": "En Benutzer het dini Widergabegruppe verlah.",
"userOnPrivatePage": "De Benutzer luegt sich grad e privati Siite a, d Synchronisierig wird grad wieder fortgsetzt."
"userJoined": "E Person isch dinere Widergabegruppe biiträte.",
"userLeft": "E Person het dini Widergabegruppe verlah.",
"userOnPrivatePage": "D Person luegt sich grad e privati Siite a, d Synchronisierig wird grad wieder fortgsetzt."
},
"videoTabs": {
"all": "Alli",
@@ -217,5 +221,7 @@
"oldest": "Ältisti",
"popular": "Populär",
"favouriteChannel": "Kanal favorisiere",
"unfavouriteChannel": "Kanal entfavorisiere"
"unfavouriteChannel": "Kanal entfavorisiere",
"skip": "Überspringe",
"upcomingSegment": "Kommend "
}
+9 -3
View File
@@ -44,7 +44,10 @@
"intermissionIntroAnimation": "Szünet/bevezető animáció",
"credits": "Végképernyő/köszönet",
"preViewRecapHook": "Bevezető/összegzés/figyelemfelketés",
"tangentJokes": "Kitöltő mellékvágányok/poénok"
"tangentJokes": "Kitöltő mellékvágányok/poénok",
"automatic": "Automatikus átugrás",
"manual": "Kézi ugrás",
"timeline": "Csak idővonal"
},
"syncPartyWarning": "Vegye figyelembe, hogy IP-címe látható lesz az Ön által meghívott felhasználók számára.",
"expandDescription": "Leírás kibontása alapértelmezetten",
@@ -96,7 +99,8 @@
"savePlaybackPosition": "Lejátszási pozíció mentése",
"localVideoFallback": "Helyi videó visszatérés",
"theatreModeByDefault": "Szélesvásznú mód alapértelmezetten",
"youtubeJsFallback": "Helyi videó visszatérés feldolgozása"
"youtubeJsFallback": "Helyi videó visszatérés feldolgozása",
"networkChangePause": "Szünet a hálózati változáskor"
},
"bookmarklet": "Bookmarklet",
"instanceUrl": "Példány webcíme",
@@ -217,5 +221,7 @@
"oldest": "Legrégebbi",
"popular": "Népszerű",
"favouriteChannel": "Csatorna kedvelése",
"unfavouriteChannel": "Csatorna eltávolítása a kedvencekből"
"unfavouriteChannel": "Csatorna eltávolítása a kedvencekből",
"skip": "Kihagyás",
"upcomingSegment": "Közelgő "
}
+27 -6
View File
@@ -7,7 +7,8 @@
"invidiousRedirect": "Kopēt Invidious servera (instances) saiti",
"title": "Dalīties",
"youtubeLink": "Kopēt YouTube saiti",
"includeTimestamp": "Iekļaut atskaņošanas laiku"
"includeTimestamp": "Iekļaut atskaņošanas laiku",
"copiedSuccess": "Kopēta starpliktuvē"
},
"download": "Lejupielādēt",
"downloadSteps": {
@@ -31,7 +32,15 @@
"retryText": "Neizdevās ielādēt video. Kā vēlaties turpināt?",
"youtubeJsLoading": "Neizdevās ielādēt video, mēģina atkārtoti ielādēt ar vietējo video ieguves rezerves variantu.",
"enableYoutubejsPerm": "Vienmēr izmantot vietējo video ieguves rezerves variantu",
"preferredQuality": "Vēlamā kvalitāte"
"preferredQuality": "Vēlamā kvalitāte",
"premiere": "Video būs pieejams",
"controls": {
"quality": "Kvalitāte",
"playbackSpeed": "Atskaņošanas ātrums",
"on": "Ieslēgt",
"off": "Izslēgt",
"language": "Valoda"
}
},
"videos": "video",
"layout": {
@@ -58,7 +67,12 @@
"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"
"autoPlayNextByDefault": "Automātiski atskaņot nākamo video pēc noklusējuma",
"ccByDefault": "Iespējot subtitrus pēc noklusējuma",
"backgroundPlay": "Atskaņot audio fonā",
"dash": "Izmantot DASH",
"silenceSkipper": "Izlaist klusuma brīžus (eksperimentāla)",
"defaultPlaybackSpeed": "Noklusējuma atskaņošanas ātrums"
},
"deArrow": {
"titleOnly": "Tikai virsrakstu",
@@ -68,7 +82,8 @@
"Catagories": "Kategorijas",
"unpaidSelfPromotion": "Neapmaksāts/pašreklāma",
"sponsor": "Sponsors",
"disableToast": "Atspējot uznirstošos logus"
"disableToast": "Atspējot uznirstošos logus",
"automatic": "Automātiski izlaist"
},
"bookmarklet": "Grāmatzīmes sīklietotne",
"dataPreferences": {
@@ -161,9 +176,15 @@
"filters": "Filtrēt pēc",
"type": "Tips",
"uploadDate": "Augšupielādes datums",
"duration": "Ilgums"
"duration": "Ilgums",
"sortBy": "Kārtot pēc"
},
"comments": "komentāri",
"login": "Autorizēties",
"transcript": "Transkripcija"
"transcript": "Transkripcija",
"popularPageDisabled": "Administratori atspējojuši \"Populārs\" lapu",
"skip": "Izlaist",
"reply": "atbilde",
"contributors": "Dalībnieki, līdzautori, kas devuši savu artavu",
"loadMore": "Ielādēt vēl"
}
+10 -1
View File
@@ -1,4 +1,13 @@
{
"enabled": "啟用",
"disabled": "停用"
"disabled": "停用",
"player": {
"controls": {
"language": "語言"
}
},
"layout": {
"interface": "介面",
"syncPartyWarning": "被邀請的使用者將會看到您的IP位址。"
}
}
+39 -7
View File
@@ -3,7 +3,11 @@ import { resolve } from '$app/paths';
import he from 'he';
import type Peer from 'peerjs';
import { get } from 'svelte/store';
import { interfaceAllowInsecureRequests, isAndroidTvStore } from './store';
import {
interfaceAllowInsecureRequests,
interfaceAndroidUseNativeShare,
isAndroidTvStore
} from './store';
import type {
Channel,
HashTag,
@@ -14,6 +18,9 @@ import type {
VideoBase
} from './api/model';
import { page } from '$app/state';
import { Capacitor } from '@capacitor/core';
import { Share } from '@capacitor/share';
import { Clipboard } from '@capacitor/clipboard';
export function isVideoID(videoId: string): boolean {
const regExp = /^[a-zA-Z0-9_-]{11}$/;
@@ -46,16 +53,41 @@ export function removeWindowQueryFlag(key: string) {
}
let PeerInstance: typeof Peer;
export async function peerJs(peerId: string): Promise<Peer> {
export interface PeerInstance {
host: string;
path: string;
port: number;
}
export function determinePeerJsInstance(): PeerInstance {
return {
host: import.meta.env.VITE_DEFAULT_PEERJS_HOST || '0.peerjs.com',
path: import.meta.env.VITE_DEFAULT_PEERJS_PATH || '/',
port: import.meta.env.VITE_DEFAULT_PEERJS_PORT || 443
};
}
export async function peerJs(
id: string,
instance: PeerInstance = determinePeerJsInstance()
): Promise<Peer> {
// https://github.com/peers/peerjs/issues/819
if (typeof PeerInstance === 'undefined') {
PeerInstance = (await import('peerjs')).Peer;
}
return new PeerInstance(peerId, {
host: import.meta.env.VITE_DEFAULT_PEERJS_HOST || '0.peerjs.com',
path: import.meta.env.VITE_DEFAULT_PEERJS_PATH || '/',
port: import.meta.env.VITE_DEFAULT_PEERJS_PORT || 443
});
return new PeerInstance(id, instance);
}
export async function shareURL(url: string) {
if (
Capacitor.getPlatform() === 'android' &&
(await Share.canShare()).value &&
get(interfaceAndroidUseNativeShare)
) {
await Share.share({ url: url });
} else {
await Clipboard.write({ string: url });
}
}
export function ensureNoTrailingSlash(url: any): string {
+10 -10
View File
@@ -253,10 +253,12 @@
>
<Logo />
</header>
<a href={resolve('/search', {})} class:active={$page.url.href.endsWith('/search')}>
<i>search</i>
<div>{$_('searchPlaceholder')}</div>
</a>
{#if $isAndroidTvStore}
<a href={resolve('/search', {})} class:active={$page.url.href.endsWith('/search')}>
<i>search</i>
<div>{$_('searchPlaceholder')}</div>
</a>
{/if}
{#each getPages() as navPage (navPage)}
{#if !navPage.requiresAuth || isLoggedIn}
<a href={resolve(navPage.href, {})} class:active={$page.url.href.endsWith(navPage.href)}
@@ -321,12 +323,10 @@
<Search on:searchCancelled={() => (mobileSearchShow = false)} />
</div>
{:else}
{#if !Capacitor.isNativePlatform()}
<button data-ui="#sync-party" class="circle large transparent">
<i class:primary-text={$syncPartyPeerStore}>group</i>
<div class="tooltip bottom">{$_('layout.syncParty')}</div>
</button>
{/if}
<button data-ui="#sync-party" class="circle large transparent">
<i class:primary-text={$syncPartyPeerStore}>group</i>
<div class="tooltip bottom">{$_('layout.syncParty')}</div>
</button>
{#if isLoggedIn}
<button class="circle large transparent" onclick={() => ui('#dialog-notifications')}
><i>notifications</i>
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -3,7 +3,7 @@ import os
import re
from datetime import datetime
LATEST_VERSION = "1.13.1"
LATEST_VERSION = "1.13.2"
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")