Merge pull request #88 from WardPearce/update/localization
Started translation support
This commit is contained in:
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"i18n-ally.defaultNamespace": "",
|
||||
"i18n-ally.enabledFrameworks": [
|
||||
"svelte"
|
||||
],
|
||||
"i18n-ally.localesPaths": [
|
||||
"materialious/src/lib/i18n",
|
||||
"materialious/src/lib/i18n/locales"
|
||||
],
|
||||
"i18n-ally.extract.autoDetect": true
|
||||
}
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||

|
||||
|
||||
[Help translate Materialious!](https://fink.inlang.com/github.com/WardPearce/Materialious)
|
||||
|
||||
# Features
|
||||
- Watch sync parties!
|
||||
- Sponsorblock built-in.
|
||||
|
||||
Generated
+622
-10
@@ -14,6 +14,7 @@
|
||||
"media-icons": "^0.10.0",
|
||||
"peerjs": "^1.5.2",
|
||||
"sponsorblock-api": "^0.2.4",
|
||||
"svelte-i18n": "^4.0.0",
|
||||
"svelte-infinite-loading": "^1.3.8",
|
||||
"svelte-persisted-store": "^0.9.1",
|
||||
"vidstack": "^1.11.13"
|
||||
@@ -2504,6 +2505,50 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/ecma402-abstract": {
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz",
|
||||
"integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==",
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "0.5.4",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/fast-memoize": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
|
||||
"integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/icu-messageformat-parser": {
|
||||
"version": "2.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.6.tgz",
|
||||
"integrity": "sha512-etVau26po9+eewJKYoiBKP6743I1br0/Ie00Pb/S/PtmYfmjTcOn2YCh2yNkSZI12h6Rg+BOgQYborXk46BvkA==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.18.2",
|
||||
"@formatjs/icu-skeleton-parser": "1.8.0",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/icu-skeleton-parser": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.0.tgz",
|
||||
"integrity": "sha512-QWLAYvM0n8hv7Nq5BEs4LKIjevpVpbGLAJgOaYzg9wABEoX1j0JO1q2/jVkO6CVlq0dbsxZCngS5aXbysYueqA==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.18.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/intl-localematcher": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
@@ -3856,6 +3901,21 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-color": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz",
|
||||
"integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==",
|
||||
"dependencies": {
|
||||
"d": "^1.0.1",
|
||||
"es5-ext": "^0.10.64",
|
||||
"es6-iterator": "^2.0.3",
|
||||
"memoizee": "^0.4.15",
|
||||
"timers-ext": "^0.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/code-red": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz",
|
||||
@@ -4003,6 +4063,18 @@
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/d": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
|
||||
"integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
|
||||
"dependencies": {
|
||||
"es5-ext": "^0.10.64",
|
||||
"type": "^2.7.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/data-view-buffer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
|
||||
@@ -4084,7 +4156,6 @@
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -4353,12 +4424,60 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es5-ext": {
|
||||
"version": "0.10.64",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
|
||||
"integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"es6-iterator": "^2.0.3",
|
||||
"es6-symbol": "^3.1.3",
|
||||
"esniff": "^2.0.1",
|
||||
"next-tick": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/es6-iterator": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
||||
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
|
||||
"dependencies": {
|
||||
"d": "1",
|
||||
"es5-ext": "^0.10.35",
|
||||
"es6-symbol": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/es6-promise": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
|
||||
"integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/es6-symbol": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
|
||||
"integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
|
||||
"dependencies": {
|
||||
"d": "^1.0.2",
|
||||
"ext": "^1.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/es6-weak-map": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
|
||||
"integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
|
||||
"dependencies": {
|
||||
"d": "1",
|
||||
"es5-ext": "^0.10.46",
|
||||
"es6-iterator": "^2.0.3",
|
||||
"es6-symbol": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
|
||||
@@ -4592,6 +4711,20 @@
|
||||
"integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/esniff": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
|
||||
"integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
|
||||
"dependencies": {
|
||||
"d": "^1.0.1",
|
||||
"es5-ext": "^0.10.62",
|
||||
"event-emitter": "^0.3.5",
|
||||
"type": "^2.7.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/espree": {
|
||||
"version": "9.6.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
|
||||
@@ -4659,11 +4792,28 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/event-emitter": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
||||
"integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
|
||||
"dependencies": {
|
||||
"d": "1",
|
||||
"es5-ext": "~0.10.14"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
|
||||
},
|
||||
"node_modules/ext": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
|
||||
"integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
|
||||
"dependencies": {
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
@@ -5068,8 +5218,7 @@
|
||||
"node_modules/globalyzer": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
|
||||
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q=="
|
||||
},
|
||||
"node_modules/globby": {
|
||||
"version": "11.1.0",
|
||||
@@ -5094,8 +5243,7 @@
|
||||
"node_modules/globrex": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
|
||||
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
@@ -5302,6 +5450,17 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/intl-messageformat": {
|
||||
"version": "10.5.11",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.11.tgz",
|
||||
"integrity": "sha512-eYq5fkFBVxc7GIFDzpFQkDOZgNayNTQn4Oufe8jw6YY6OHVw70/4pA3FyCsQ0Gb2DnvEJEMmN2tOaXUGByM+kg==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.18.2",
|
||||
"@formatjs/fast-memoize": "2.2.0",
|
||||
"@formatjs/icu-messageformat-parser": "2.7.6",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-array-buffer": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
|
||||
@@ -5500,6 +5659,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-promise": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
|
||||
"integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
|
||||
},
|
||||
"node_modules/is-reference": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz",
|
||||
@@ -5910,6 +6074,14 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
|
||||
"integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
|
||||
"dependencies": {
|
||||
"es5-ext": "~0.10.2"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.8",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
|
||||
@@ -5953,6 +6125,21 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/memoizee": {
|
||||
"version": "0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
|
||||
"integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==",
|
||||
"dependencies": {
|
||||
"d": "^1.0.1",
|
||||
"es5-ext": "^0.10.53",
|
||||
"es6-weak-map": "^2.0.3",
|
||||
"event-emitter": "^0.3.5",
|
||||
"is-promise": "^2.2.2",
|
||||
"lru-queue": "^0.1.0",
|
||||
"next-tick": "^1.1.0",
|
||||
"timers-ext": "^0.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
@@ -6050,7 +6237,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@@ -6093,6 +6279,11 @@
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/next-tick": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
|
||||
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
|
||||
},
|
||||
"node_modules/node-gyp-build-optional-packages": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz",
|
||||
@@ -6783,7 +6974,6 @@
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
|
||||
"integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mri": "^1.1.0"
|
||||
},
|
||||
@@ -7329,6 +7519,416 @@
|
||||
"svelte": "^3.19.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-4.0.0.tgz",
|
||||
"integrity": "sha512-4vivjKZADUMRIhTs38JuBNy3unbnh9AFRxWFLxq62P4NHic+/BaIZZlAsvqsCdnp7IdJf5EoSiH6TNdItcjA6g==",
|
||||
"dependencies": {
|
||||
"cli-color": "^2.0.3",
|
||||
"deepmerge": "^4.2.2",
|
||||
"esbuild": "^0.19.2",
|
||||
"estree-walker": "^2",
|
||||
"intl-messageformat": "^10.5.3",
|
||||
"sade": "^1.8.1",
|
||||
"tiny-glob": "^0.2.9"
|
||||
},
|
||||
"bin": {
|
||||
"svelte-i18n": "dist/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^3 || ^4"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
|
||||
"integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/android-arm": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
|
||||
"integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/android-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
|
||||
"integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
|
||||
"integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
|
||||
"integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
|
||||
"integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
|
||||
"integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
|
||||
"integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
|
||||
"integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
|
||||
"integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/esbuild": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
|
||||
"integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.19.12",
|
||||
"@esbuild/android-arm": "0.19.12",
|
||||
"@esbuild/android-arm64": "0.19.12",
|
||||
"@esbuild/android-x64": "0.19.12",
|
||||
"@esbuild/darwin-arm64": "0.19.12",
|
||||
"@esbuild/darwin-x64": "0.19.12",
|
||||
"@esbuild/freebsd-arm64": "0.19.12",
|
||||
"@esbuild/freebsd-x64": "0.19.12",
|
||||
"@esbuild/linux-arm": "0.19.12",
|
||||
"@esbuild/linux-arm64": "0.19.12",
|
||||
"@esbuild/linux-ia32": "0.19.12",
|
||||
"@esbuild/linux-loong64": "0.19.12",
|
||||
"@esbuild/linux-mips64el": "0.19.12",
|
||||
"@esbuild/linux-ppc64": "0.19.12",
|
||||
"@esbuild/linux-riscv64": "0.19.12",
|
||||
"@esbuild/linux-s390x": "0.19.12",
|
||||
"@esbuild/linux-x64": "0.19.12",
|
||||
"@esbuild/netbsd-x64": "0.19.12",
|
||||
"@esbuild/openbsd-x64": "0.19.12",
|
||||
"@esbuild/sunos-x64": "0.19.12",
|
||||
"@esbuild/win32-arm64": "0.19.12",
|
||||
"@esbuild/win32-ia32": "0.19.12",
|
||||
"@esbuild/win32-x64": "0.19.12"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-i18n/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"node_modules/svelte-infinite-loading": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/svelte-infinite-loading/-/svelte-infinite-loading-1.3.8.tgz",
|
||||
@@ -7475,11 +8075,19 @@
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/timers-ext": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
|
||||
"integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
|
||||
"dependencies": {
|
||||
"es5-ext": "~0.10.46",
|
||||
"next-tick": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-glob": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
|
||||
"integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"globalyzer": "0.1.0",
|
||||
"globrex": "^0.1.2"
|
||||
@@ -7540,8 +8148,12 @@
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/type": {
|
||||
"version": "2.7.2",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
|
||||
"integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"media-icons": "^0.10.0",
|
||||
"peerjs": "^1.5.2",
|
||||
"sponsorblock-api": "^0.2.4",
|
||||
"svelte-i18n": "^4.0.0",
|
||||
"svelte-infinite-loading": "^1.3.8",
|
||||
"svelte-persisted-store": "^0.9.1",
|
||||
"vidstack": "^1.11.13"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import type { Channel } from './Api/model';
|
||||
import { cleanNumber, truncate } from './misc';
|
||||
|
||||
@@ -37,7 +38,8 @@
|
||||
</div>
|
||||
<h5 class="center-align">{truncate(channel.author, 14)}</h5>
|
||||
<h6 style="margin-top: 0;" class="center-align grey-text medium-text">
|
||||
{cleanNumber(channel.subCount)} subscribers
|
||||
{cleanNumber(channel.subCount)}
|
||||
{$_('subscribers')}
|
||||
</h6>
|
||||
<p>{channel.description}</p>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { getComments } from './Api';
|
||||
import { type Comment, type Comments } from './Api/model';
|
||||
import { numberWithCommas } from './misc';
|
||||
@@ -68,7 +69,7 @@
|
||||
class="transparent replies"
|
||||
>
|
||||
<i class="primary-text">expand_more</i>
|
||||
<span class="primary-text">{comment.replies.replyCount} replies</span>
|
||||
<span class="primary-text">{comment.replies.replyCount} {$_('replies')}</span>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { SponsorBlock, type Category } from 'sponsorblock-api';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import type { MediaTimeUpdateEvent, PlayerSrc } from 'vidstack';
|
||||
import type { MediaPlayerElement } from 'vidstack/elements';
|
||||
@@ -254,7 +255,7 @@
|
||||
|
||||
<div class="snackbar" id="sponsorblock-alert">
|
||||
<span
|
||||
>Skipping <span class="bold" style="text-transform: capitalize;">{categoryBeingSkipped}</span
|
||||
></span
|
||||
>{$_('skipping')}
|
||||
<span class="bold" style="text-transform: capitalize;">{categoryBeingSkipped}</span></span
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import type { Playlist } from './Api/model';
|
||||
import { truncate } from './misc';
|
||||
|
||||
@@ -48,7 +49,8 @@
|
||||
{/if}
|
||||
{/if}
|
||||
<div class="absolute right bottom small-margin black white-text small-text thumbnail-corner">
|
||||
{playlist.videoCount} videos
|
||||
{playlist.videoCount}
|
||||
{$_('videos')}
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { interfaceSearchSuggestions } from '../store';
|
||||
import { getSearchSuggestions } from './Api';
|
||||
|
||||
@@ -29,7 +30,7 @@
|
||||
<i class="front">search</i><input
|
||||
data-ui="search-suggestions"
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
placeholder={$_('searchPlaceholder')}
|
||||
bind:value={search}
|
||||
on:keyup={(target) => debouncedSearch(target)}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import {
|
||||
deArrowEnabled,
|
||||
@@ -145,7 +146,7 @@
|
||||
alt="Thumbnail for video"
|
||||
/>
|
||||
{:else}
|
||||
<p>Failed to load image</p>
|
||||
<p>{$_('thumbnail.failedToLoadImage')}</p>
|
||||
{/if}
|
||||
{#if progress}
|
||||
<progress
|
||||
@@ -163,7 +164,7 @@
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="absolute right bottom small-margin red white-text small-text thumbnail-corner">
|
||||
LIVE
|
||||
{$_('thumbnail.live')}
|
||||
</div>
|
||||
{/if}
|
||||
</a>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { browser } from '$app/environment';
|
||||
import { init, register } from 'svelte-i18n';
|
||||
|
||||
const defaultLocale = 'en';
|
||||
|
||||
register('en', () => import('./locales/en.json'));
|
||||
|
||||
init({
|
||||
fallbackLocale: defaultLocale,
|
||||
initialLocale: browser ? window.navigator.language : defaultLocale,
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"enabled": "Enabled",
|
||||
"copyUrl": "Copy URL",
|
||||
"loadMore": "Load more",
|
||||
"views": "views",
|
||||
"videos": "videos",
|
||||
"cancel": "Cancel",
|
||||
"create": "Create",
|
||||
"title": "Title",
|
||||
"searchPlaceholder": "Search...",
|
||||
"deleteAllHistory": "Delete all history",
|
||||
"skipping": "Skipping",
|
||||
"replies": "replies",
|
||||
"videoTabs": {
|
||||
"all": "All",
|
||||
"videos": "Videos",
|
||||
"playlists": "Playlists",
|
||||
"channels": "Channels",
|
||||
"shorts": "Shorts",
|
||||
"streams": "Streams"
|
||||
},
|
||||
"subscriptions": {
|
||||
"manageSubscriptions": "Manage subscriptions"
|
||||
},
|
||||
"playlist": {
|
||||
"createPlaylist": "Create playlist",
|
||||
"public": "Public",
|
||||
"unlisted": "Unlisted",
|
||||
"private": "Private"
|
||||
},
|
||||
"thumbnail": {
|
||||
"live": "LIVE",
|
||||
"failedToLoadImage": "Failed to load image"
|
||||
},
|
||||
"pages": {
|
||||
"home": "Home",
|
||||
"trending": "Trending",
|
||||
"subscriptions": "Subscriptions",
|
||||
"playlists": "Playlists",
|
||||
"history": "History"
|
||||
},
|
||||
"subscribers": "subscribers",
|
||||
"subscribe": "Subscribe",
|
||||
"unsubscribe": "Unsubscribe",
|
||||
"loginRequired": "Login required",
|
||||
"player": {
|
||||
"audioOnly": "Audio only",
|
||||
"theatreMode": "Theatre mode",
|
||||
"share": {
|
||||
"title": "Share",
|
||||
"materialiousLink": "Copy Materialious link",
|
||||
"invidiousRedirect": "Copy Invidious redirect link",
|
||||
"youtubeLink": "Copy Youtube link"
|
||||
},
|
||||
"download": "Download",
|
||||
"addToPlaylist": "Add to playlist",
|
||||
"noPlaylists": "No playlists",
|
||||
"unableToLoadComments": "Unable to load comments"
|
||||
},
|
||||
"layout": {
|
||||
"star": "Star us on Github!",
|
||||
"syncParty": "Sync party",
|
||||
"syncPartyWarning": "Please note your IP will be visible to users you invite.",
|
||||
"startSyncParty": "Start sync party",
|
||||
"endSyncParty": "End sync party",
|
||||
"notifications": "Notifications",
|
||||
"noNewNotifications": "No new notifications here",
|
||||
"settings": "Settings",
|
||||
"login": "Login",
|
||||
"logout": "Logout",
|
||||
"customize": "Customize",
|
||||
"theme": {
|
||||
"theme": "Theme",
|
||||
"darkMode": "Dark mode",
|
||||
"lightMode": "Light mode",
|
||||
"color": "Color"
|
||||
},
|
||||
"searchSuggestions": "Search suggestions",
|
||||
"dataPreferences": {
|
||||
"dataPreferences": "Data preferences",
|
||||
"content": "Looking to import/export subscriptions, change password or delete account? Click here and scroll to the bottom of the page."
|
||||
},
|
||||
"player": {
|
||||
"title": "Player",
|
||||
"autoPlay": "Autoplay video",
|
||||
"alwaysLoopVideo": "Always loop video",
|
||||
"proxyVideos": "Proxy videos",
|
||||
"savePlaybackPosition": "Save playback position",
|
||||
"listenByDefault": "Listen by default",
|
||||
"theatreModeByDefault": "Theatre mode by default",
|
||||
"autoPlayNextByDefault": "Autoplay next by default",
|
||||
"dash": "Dash"
|
||||
},
|
||||
"instanceUrl": "Instance URL",
|
||||
"sponsors": {
|
||||
"sponsor": "Sponsor",
|
||||
"unpaidSelfPromotion": "Unpaid/Self Promotion",
|
||||
"interactionReminder": "Interaction Reminder (Subscribe)",
|
||||
"intermissionIntroAnimation": "Intermission/Intro Animation",
|
||||
"credits": "Endcards/Credits",
|
||||
"preViewRecapHook": "Preview/Recap/Hook",
|
||||
"tangentJokes": "Filler Tangent/Jokes"
|
||||
},
|
||||
"deArrow": {
|
||||
"title": "DeArrow",
|
||||
"thumbnailInstanceUrl": "Thumbnail instance URL"
|
||||
},
|
||||
"bookmarklet": "Bookmarklet"
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
import type { DataConnection } from 'peerjs';
|
||||
import Peer from 'peerjs';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import { pwaInfo } from 'virtual:pwa-info';
|
||||
import {
|
||||
@@ -66,43 +67,43 @@
|
||||
{
|
||||
icon: 'home',
|
||||
href: '/',
|
||||
name: 'Home',
|
||||
name: $_('pages.home'),
|
||||
requiresAuth: false
|
||||
},
|
||||
{
|
||||
icon: 'whatshot',
|
||||
href: '/trending',
|
||||
name: 'Trending',
|
||||
name: $_('pages.trending'),
|
||||
requiresAuth: false
|
||||
},
|
||||
{
|
||||
icon: 'subscriptions',
|
||||
href: '/subscriptions',
|
||||
name: 'Subscriptions',
|
||||
name: $_('pages.subscriptions'),
|
||||
requiresAuth: true
|
||||
},
|
||||
{
|
||||
icon: 'video_library',
|
||||
href: '/playlists',
|
||||
name: 'Playlists',
|
||||
name: $_('pages.playlists'),
|
||||
requiresAuth: true
|
||||
},
|
||||
{
|
||||
icon: 'history',
|
||||
href: '/history',
|
||||
name: 'History',
|
||||
name: $_('pages.history'),
|
||||
requiresAuth: true
|
||||
}
|
||||
];
|
||||
|
||||
const sponsorCategories = [
|
||||
{ name: 'Sponsor', category: 'sponsor' },
|
||||
{ name: 'Unpaid/Self Promotion', category: 'selfpromo' },
|
||||
{ name: 'Interaction Reminder (Subscribe)', category: 'interaction' },
|
||||
{ name: 'Intermission/Intro Animation', category: 'intro' },
|
||||
{ name: 'Endcards/Credits', category: 'outro' },
|
||||
{ name: 'Preview/Recap/Hook', category: 'preview' },
|
||||
{ name: 'Filler Tangent/Jokes', category: 'filler' }
|
||||
{ name: $_('layout.sponsors.sponsor'), category: 'sponsor' },
|
||||
{ name: $_('layout.sponsors.unpaidSelfPromotion'), category: 'selfpromo' },
|
||||
{ name: $_('layout.sponsors.interactionReminder'), category: 'interaction' },
|
||||
{ name: $_('layout.sponsors.intermissionIntroAnimation'), category: 'intro' },
|
||||
{ name: $_('layout.sponsors.credits'), category: 'outro' },
|
||||
{ name: $_('layout.sponsors.preViewRecapHook'), category: 'preview' },
|
||||
{ name: $_('layout.sponsors.tangentJokes'), category: 'filler' }
|
||||
];
|
||||
|
||||
function changeVideoEvent(conn: DataConnection) {
|
||||
@@ -315,57 +316,57 @@
|
||||
class="button circle large transparent"
|
||||
>
|
||||
<i>code</i>
|
||||
<div class="tooltip bottom">Star us on Github!</div>
|
||||
<div class="tooltip bottom">{$_('layout.star')}</div>
|
||||
</a>
|
||||
<button data-ui="#sync-party" class="circle large transparent">
|
||||
<i class:primary-text={$syncPartyPeer}>group</i>
|
||||
<div class="tooltip bottom">Sync party</div>
|
||||
<div class="tooltip bottom">{$_('layout.syncParty')}</div>
|
||||
</button>
|
||||
{#if isLoggedIn}
|
||||
<button class="circle large transparent" data-ui="#dialog-notifications"
|
||||
><i>notifications</i>
|
||||
<div class="tooltip bottom">Notifications</div>
|
||||
<div class="tooltip bottom">{$_('layout.notifications')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
<button class="circle large transparent" data-ui="#dialog-settings">
|
||||
<i>settings</i>
|
||||
<div class="tooltip bottom">Settings</div>
|
||||
<div class="tooltip bottom">{$_('layout.settings')}</div>
|
||||
</button>
|
||||
|
||||
{#if !isLoggedIn}
|
||||
<button on:click={login} class="circle large transparent">
|
||||
<i>login</i>
|
||||
<div class="tooltip bottom">Login</div>
|
||||
<div class="tooltip bottom">{$_('layout.login')}</div>
|
||||
</button>
|
||||
{:else}
|
||||
<button on:click={logout} class="circle large transparent">
|
||||
<i>logout</i>
|
||||
<div class="tooltip bottom">Logout</div>
|
||||
<div class="tooltip bottom">{$_('layout.logout')}</div>
|
||||
</button>
|
||||
{/if}
|
||||
</nav>
|
||||
|
||||
<dialog class="right" id="dialog-settings">
|
||||
<nav>
|
||||
<h4 class="max">Settings</h4>
|
||||
<h4 class="max">{$_('layout.settings')}</h4>
|
||||
<button class="circle transparent" data-ui="#dialog-settings"><i>close</i></button>
|
||||
</nav>
|
||||
<p>Customize Materialious</p>
|
||||
<p>{$_('layout.customize')} Materialious</p>
|
||||
|
||||
<div class="settings">
|
||||
<h6>Theme</h6>
|
||||
<h6>{$_('layout.theme.theme')}</h6>
|
||||
<button on:click={toggleDarkMode} class="no-margin">
|
||||
{#if !$darkMode}
|
||||
<i>dark_mode</i>
|
||||
<span>Dark mode</span>
|
||||
<span>{$_('layout.theme.darkMode')}</span>
|
||||
{:else}
|
||||
<i>light_mode</i>
|
||||
<span>Light mode</span>
|
||||
<span>{$_('layout.theme.lightMode')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
<button>
|
||||
<i>palette</i>
|
||||
<span>Color</span>
|
||||
<span>{$_('layout.theme.color')}</span>
|
||||
<input on:change={setColor} type="color" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -375,7 +376,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Search suggestions</div>
|
||||
<div>{$_('layout.searchSuggestions')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -390,27 +391,25 @@
|
||||
</div>
|
||||
|
||||
<div class="settings">
|
||||
<h6>Data preferences</h6>
|
||||
<h6>{$_('layout.dataPreferences.dataPreferences')}</h6>
|
||||
<p style="width: 240px;">
|
||||
Looking to import/export subscriptions, change password or delete account?
|
||||
<a
|
||||
href={`${import.meta.env.VITE_DEFAULT_INVIDIOUS_INSTANCE}/preferences`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="link"
|
||||
>
|
||||
Go here
|
||||
{$_('layout.dataPreferences.content')}
|
||||
</a>
|
||||
and scroll to the bottom of the page.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="settings">
|
||||
<h6>Player</h6>
|
||||
<h6>{$_('layout.player.title')}</h6>
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Autoplay video</div>
|
||||
<div>{$_('layout.player.autoPlay')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -426,7 +425,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Always loop video</div>
|
||||
<div>{$_('layout.player.alwaysLoopVideo')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -442,7 +441,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Proxy videos</div>
|
||||
<div>{$_('layout.player.proxyVideos')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -458,7 +457,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Save playback position</div>
|
||||
<div>{$_('layout.player.savePlaybackPosition')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -474,7 +473,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Listen by default</div>
|
||||
<div>{$_('layout.player.listenByDefault')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -490,7 +489,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Theatre mode by default</div>
|
||||
<div>{$_('layout.player.theatreModeByDefault')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -506,7 +505,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Autoplay next by default</div>
|
||||
<div>{$_('layout.player.autoPlayNextByDefault')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -522,7 +521,7 @@
|
||||
<div class="field no-margin">
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<div>Dash</div>
|
||||
<div>{$_('layout.player.dash')}</div>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -543,7 +542,7 @@
|
||||
<nav>
|
||||
<div class="field label border">
|
||||
<input bind:value={returnYTInstance} name="returnyt-instance" type="text" />
|
||||
<label for="returnyt-instance">Instance URL</label>
|
||||
<label for="returnyt-instance">{$_('layout.instanceUrl')}</label>
|
||||
</div>
|
||||
<button class="square round">
|
||||
<i>done</i>
|
||||
@@ -553,7 +552,7 @@
|
||||
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<p>Enabled</p>
|
||||
<p>{$_('enabled')}</p>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -573,7 +572,7 @@
|
||||
<nav>
|
||||
<div class="field label border">
|
||||
<input bind:value={sponsorBlockInstance} name="sponsorblock-instance" type="text" />
|
||||
<label for="sponsorblock-instance">Instance URL</label>
|
||||
<label for="sponsorblock-instance">{$_('layout.instanceUrl')}</label>
|
||||
</div>
|
||||
<button class="square round">
|
||||
<i>done</i>
|
||||
@@ -583,7 +582,7 @@
|
||||
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<p>Enabled</p>
|
||||
<p>{$_('enabled')}</p>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -615,13 +614,13 @@
|
||||
</div>
|
||||
|
||||
<div class="settings">
|
||||
<h6>DeArrow</h6>
|
||||
<h6>{$_('layout.deArrow.title')}</h6>
|
||||
|
||||
<form on:submit|preventDefault={() => deArrowInstance.set(deArrowUrl)}>
|
||||
<nav>
|
||||
<div class="field label border">
|
||||
<input bind:value={deArrowUrl} name="dearrow-instance" type="text" />
|
||||
<label for="dearrow-instance">Instance URL</label>
|
||||
<label for="dearrow-instance">{$_('layout.instanceUrl')}</label>
|
||||
</div>
|
||||
<button class="square round">
|
||||
<i>done</i>
|
||||
@@ -633,7 +632,8 @@
|
||||
<nav>
|
||||
<div class="field label border">
|
||||
<input bind:value={deArrowThumbnailUrl} name="dearrow-thumbnail-instance" type="text" />
|
||||
<label for="dearrow-thumbnail-instance">Thumbnail instance URL</label>
|
||||
<label for="dearrow-thumbnail-instance">{$_('layout.deArrow.thumbnailInstanceUrl')}</label
|
||||
>
|
||||
</div>
|
||||
<button class="square round">
|
||||
<i>done</i>
|
||||
@@ -643,7 +643,7 @@
|
||||
|
||||
<nav class="no-padding">
|
||||
<div class="max">
|
||||
<p>Enabled</p>
|
||||
<p>{$_('enabled')}</p>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input
|
||||
@@ -657,22 +657,22 @@
|
||||
</div>
|
||||
|
||||
<div class="settings">
|
||||
<h6>Bookmarklet</h6>
|
||||
<h6>{$_('layout.bookmarklet')}</h6>
|
||||
<button
|
||||
class="no-margin"
|
||||
on:click={async () => await navigator.clipboard.writeText(bookmarkletSaveToUrl())}
|
||||
>Copy URL</button
|
||||
>{$_('copyUrl')}</button
|
||||
>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog class="right" id="dialog-notifications">
|
||||
<nav>
|
||||
<h5 class="max">Notifications</h5>
|
||||
<h5 class="max">{$_('layout.notifications')}</h5>
|
||||
<button class="circle transparent" data-ui="#dialog-notifications"><i>close</i></button>
|
||||
</nav>
|
||||
{#if notifications.length === 0}
|
||||
<p>No new notifications here</p>
|
||||
<p>{$_('layout.noNewNotifications')}</p>
|
||||
{:else}
|
||||
{#each notifications as notification}
|
||||
<article class="no-padding">
|
||||
@@ -710,8 +710,8 @@
|
||||
</dialog>
|
||||
|
||||
<dialog id="sync-party">
|
||||
<h6>Sync party</h6>
|
||||
<p>Please note your IP will be visible to users you invite.</p>
|
||||
<h6>{$_('layout.syncParty')}</h6>
|
||||
<p>{$_('layout.syncPartyWarning')}</p>
|
||||
{#if $syncPartyPeer}
|
||||
<nav>
|
||||
<div class="field label border">
|
||||
@@ -741,10 +741,10 @@
|
||||
on:click={startWatchSync}
|
||||
data-ui={`${$syncPartyPeer ? '#sync-party' : ''}`}
|
||||
>{#if $syncPartyPeer}
|
||||
End
|
||||
{$_('layout.endSyncParty')}
|
||||
{:else}
|
||||
Start
|
||||
{/if} sync party
|
||||
{$_('layout.startSyncParty')}
|
||||
{/if}
|
||||
</button>
|
||||
</dialog>
|
||||
|
||||
|
||||
@@ -1 +1,13 @@
|
||||
import { browser } from '$app/environment';
|
||||
import '$lib/i18n'; // Import to initialize. Important :)
|
||||
import { locale, waitLocale } from 'svelte-i18n';
|
||||
import type { LayoutLoad } from './$types';
|
||||
|
||||
export let ssr = false;
|
||||
|
||||
export const load: LayoutLoad = async () => {
|
||||
if (browser) {
|
||||
locale.set(window.navigator.language);
|
||||
}
|
||||
await waitLocale();
|
||||
};
|
||||
@@ -6,6 +6,7 @@
|
||||
import Thumbnail from '$lib/Thumbnail.svelte';
|
||||
import { cleanNumber } from '$lib/misc';
|
||||
import { onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
|
||||
import { get } from 'svelte/store';
|
||||
import { activePage, auth } from '../../../store';
|
||||
@@ -83,7 +84,7 @@
|
||||
/>
|
||||
<div>
|
||||
<h2>{data.channel.author}</h2>
|
||||
<p>{cleanNumber(data.channel.subCount)} subscribers</p>
|
||||
<p>{cleanNumber(data.channel.subCount)} {$_('subscribers')}</p>
|
||||
<p style="width: 60vw;">{data.channel.description}</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -92,9 +93,9 @@
|
||||
class:border={isSubscribed}
|
||||
>
|
||||
{#if !isSubscribed}
|
||||
Subscribe
|
||||
{$_('subscribe')}
|
||||
{:else}
|
||||
Unsubscribe
|
||||
{$_('unsubscribe')}
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
@@ -103,19 +104,19 @@
|
||||
{#if data.channel.tabs.includes('videos')}
|
||||
<a class:active={tab === 'videos'} on:click={() => changeTab('videos')} href={`#video`}>
|
||||
<i>movie</i>
|
||||
<span>Videos</span>
|
||||
<span>{$_('videoTabs.videos')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
{#if data.channel.tabs.includes('shorts')}
|
||||
<a class:active={tab === 'shorts'} on:click={() => changeTab('shorts')} href={`#short`}>
|
||||
<i>smartphone</i>
|
||||
<span>Shorts</span>
|
||||
<span>{$_('videoTabs.shorts')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
{#if data.channel.tabs.includes('streams')}
|
||||
<a class:active={tab === 'streams'} on:click={() => changeTab('streams')} href={`#stream`}>
|
||||
<i>stream</i>
|
||||
<span>Streams</span>
|
||||
<span>{$_('videoTabs.streams')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
{#if data.channel.tabs.includes('playlists')}
|
||||
@@ -125,7 +126,7 @@
|
||||
href={`#playlist`}
|
||||
>
|
||||
<i>playlist_add_check</i>
|
||||
<span>Playlists</span>
|
||||
<span>{$_('videoTabs.playlists')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import VideoList from '$lib/VideoList.svelte';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
|
||||
import { activePage } from '../../store';
|
||||
|
||||
@@ -62,7 +63,7 @@
|
||||
}}
|
||||
>
|
||||
<i>delete_sweep</i>
|
||||
<span>Delete all history</span>
|
||||
<span>{$_('deleteAllHistory')}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import VideoList from '$lib/VideoList.svelte';
|
||||
import { cleanNumber } from '$lib/misc.js';
|
||||
import { onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { activePage } from '../../../store';
|
||||
|
||||
export let data;
|
||||
@@ -36,7 +37,11 @@
|
||||
|
||||
<article>
|
||||
<h3>{data.playlist.title}</h3>
|
||||
<p>{cleanNumber(data.playlist.viewCount)} views • {data.playlist.videoCount} videos</p>
|
||||
<p>
|
||||
{cleanNumber(data.playlist.viewCount)}
|
||||
{$_('views')} • {data.playlist.videoCount}
|
||||
{$_('videos')}
|
||||
</p>
|
||||
<div class="divider" style="margin-bottom: 1em;"></div>
|
||||
<p style="white-space: pre-line;word-wrap: break-word;">{data.playlist.description}</p>
|
||||
</article>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { deletePersonalPlaylist, getPersonalPlaylists, postPersonalPlaylist } from '$lib/Api';
|
||||
import PlaylistThumbnail from '$lib/PlaylistThumbnail.svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { activePage } from '../../store';
|
||||
|
||||
export let data;
|
||||
@@ -53,7 +54,7 @@
|
||||
<article style="height: 100%;display: flex;align-items: center;justify-content: center;">
|
||||
<button data-ui="#create-playlist" class="round extra">
|
||||
<i>add_circle</i>
|
||||
<span>Create playlist</span>
|
||||
<span>{$_('playlist.createPlaylist')}</span>
|
||||
</button>
|
||||
</article>
|
||||
</div>
|
||||
@@ -64,27 +65,27 @@
|
||||
<form on:submit|preventDefault={createPlaylist}>
|
||||
<div class="field label border">
|
||||
<input bind:value={playlistTitle} required name="title" type="text" />
|
||||
<label for="title">Title</label>
|
||||
<label for="title">{$_('title')}</label>
|
||||
</div>
|
||||
<div class="field middle-align">
|
||||
<nav>
|
||||
<label class="radio">
|
||||
<input checked on:change={onPrivacyChange} value="public" type="radio" name="privacy" />
|
||||
<span>Public</span>
|
||||
<span>{$_('playlist.public')}</span>
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input on:change={onPrivacyChange} type="radio" value="unlisted" name="privacy" />
|
||||
<span>Unlisted</span>
|
||||
<span>{$_('playlist.unlisted')}</span>
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input on:change={onPrivacyChange} type="radio" value="private" name="privacy" />
|
||||
<span>Private</span>
|
||||
<span>{$_('playlist.private')}</span>
|
||||
</label>
|
||||
</nav>
|
||||
</div>
|
||||
<nav class="right-align">
|
||||
<button type="button" data-ui="#create-playlist">Cancel</button>
|
||||
<button type="submit">Create</button>
|
||||
<button type="button" data-ui="#create-playlist">{$_('cancel')}</button>
|
||||
<button type="submit">{$_('create')}</button>
|
||||
</nav>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import PageLoading from '$lib/PageLoading.svelte';
|
||||
import PlaylistThumbnail from '$lib/PlaylistThumbnail.svelte';
|
||||
import Thumbnail from '$lib/Thumbnail.svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
|
||||
import { activePage } from '../../../store';
|
||||
|
||||
@@ -46,7 +47,7 @@
|
||||
on:click={async () => changeType('all')}
|
||||
>
|
||||
<i>home</i>
|
||||
<span>All</span>
|
||||
<span>{$_('videoTabs.all')}</span>
|
||||
</a>
|
||||
<a
|
||||
class:active={data.searchType === 'video'}
|
||||
@@ -54,7 +55,7 @@
|
||||
on:click={async () => changeType('video')}
|
||||
>
|
||||
<i>movie</i>
|
||||
<span>Videos</span>
|
||||
<span>{$_('videoTabs.videos')}</span>
|
||||
</a>
|
||||
<a
|
||||
class:active={data.searchType === 'playlist'}
|
||||
@@ -62,7 +63,7 @@
|
||||
on:click={async () => changeType('playlist')}
|
||||
>
|
||||
<i>playlist_add_check</i>
|
||||
<span>Playlists</span>
|
||||
<span>{$_('videoTabs.playlists')}</span>
|
||||
</a>
|
||||
<a
|
||||
class:active={data.searchType === 'channel'}
|
||||
@@ -70,7 +71,7 @@
|
||||
on:click={async () => changeType('channel')}
|
||||
>
|
||||
<i>person</i>
|
||||
<span>Channels</span>
|
||||
<span>{$_('videoTabs.channels')}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getFeed } from '$lib/Api/index.js';
|
||||
import VideoList from '$lib/VideoList.svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
|
||||
import { activePage } from '../../store';
|
||||
|
||||
@@ -27,7 +28,7 @@
|
||||
<nav class="right-align">
|
||||
<a class="button" href="/subscriptions/manage">
|
||||
<i>subscriptions</i>
|
||||
<span>Manage subscriptions</span>
|
||||
<span>{$_('subscriptions.manageSubscriptions')}</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { deleteUnsubscribe } from '$lib/Api';
|
||||
import { truncate } from '$lib/misc';
|
||||
import Fuse from 'fuse.js';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { activePage } from '../../../store';
|
||||
|
||||
activePage.set(null);
|
||||
@@ -41,7 +42,7 @@
|
||||
bind:value={search}
|
||||
on:input={searchSubs}
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
placeholder={$_('searchPlaceholder')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import type { PlayerEvents } from '$lib/player';
|
||||
import type { DataConnection } from 'peerjs';
|
||||
import { onMount } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import type { MediaPlayerElement } from 'vidstack/elements';
|
||||
import {
|
||||
@@ -282,15 +283,17 @@
|
||||
class:border={data.subscribed}
|
||||
>
|
||||
{#if !data.subscribed}
|
||||
Subscribe
|
||||
{$_('subscribe')}
|
||||
{:else}
|
||||
Unsubscribe
|
||||
{$_('unsubscribe')}
|
||||
{/if}
|
||||
</button>
|
||||
{:else}
|
||||
<button class="inverse-surface" disabled>
|
||||
Subscribe
|
||||
<div class="tooltip">Login required</div>
|
||||
{$_('subscribe')}
|
||||
<div class="tooltip">
|
||||
{$_('loginRequired')}
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
</nav>
|
||||
@@ -312,15 +315,17 @@
|
||||
<div>
|
||||
<button on:click={() => (audioMode = !audioMode)} class:border={!audioMode}>
|
||||
<i>headphones</i>
|
||||
<div class="tooltip">Audio only</div>
|
||||
<div class="tooltip">{$_('player.audioOnly')}</div>
|
||||
</button>
|
||||
<button on:click={toggleTheatreMode} class="m l" class:border={!theatreMode}>
|
||||
<i>width_wide</i>
|
||||
<div class="tooltip">Theatre mode</div>
|
||||
<div class="tooltip">{$_('player.theatreMode')}</div>
|
||||
</button>
|
||||
<button class="border"
|
||||
><i>share</i>
|
||||
<div class="tooltip">Share</div>
|
||||
<div class="tooltip">
|
||||
{$_('player.share.title')}
|
||||
</div>
|
||||
<menu class="no-wrap">
|
||||
<a
|
||||
class="row"
|
||||
@@ -330,7 +335,7 @@
|
||||
`${import.meta.env.VITE_DEFAULT_FRONTEND_URL}/watch/${data.video.videoId}`
|
||||
)}
|
||||
>
|
||||
<div class="min">Copy Materialious link</div></a
|
||||
<div class="min">{$_('player.share.materialiousLink')}</div></a
|
||||
><a
|
||||
href="#copy"
|
||||
class="row"
|
||||
@@ -339,7 +344,7 @@
|
||||
`https://redirect.invidious.io/watch?v=${data.video.videoId}`
|
||||
)}
|
||||
>
|
||||
<div class="min">Copy Invidious redirect link</div></a
|
||||
<div class="min">{$_('player.share.invidiousRedirect')}</div></a
|
||||
><a
|
||||
class="row"
|
||||
href="#copy"
|
||||
@@ -348,14 +353,14 @@
|
||||
`https://www.youtube.com/watch?v=${data.video.videoId}`
|
||||
)}
|
||||
>
|
||||
<div class="min">Copy Youtube link</div></a
|
||||
<div class="min">{$_('player.share.youtubeLink')}</div></a
|
||||
></menu
|
||||
></button
|
||||
>
|
||||
{#if data.downloadOptions.length > 0}
|
||||
<button class="border"
|
||||
><i>download</i>
|
||||
<div class="tooltip">Download</div>
|
||||
<div class="tooltip">{$_('player.download')}</div>
|
||||
<menu class="no-wrap">
|
||||
{#each data.downloadOptions as download}
|
||||
<a class="row" href={download.url} target="_blank" rel="noopener noreferrer"
|
||||
@@ -368,7 +373,7 @@
|
||||
{#if data.personalPlaylists}
|
||||
<button class="border">
|
||||
<i>add</i>
|
||||
<div class="tooltip">Add to playlist</div>
|
||||
<div class="tooltip">{$_('player.addToPlaylist')}</div>
|
||||
<menu>
|
||||
{#each data.personalPlaylists as personalPlaylist}
|
||||
<a
|
||||
@@ -384,9 +389,9 @@
|
||||
<i>add</i>
|
||||
<div class="tooltip">
|
||||
{#if $auth}
|
||||
No playlists
|
||||
{$_('player.noPlaylists')}
|
||||
{:else}
|
||||
Login required
|
||||
{$_('loginRequired')}
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
@@ -435,10 +440,10 @@
|
||||
<Comment {comment} videoId={data.video.videoId}></Comment>
|
||||
{/each}
|
||||
{#if comments.continuation}
|
||||
<button on:click={loadMoreComments} class="margin">Load more</button>
|
||||
<button on:click={loadMoreComments} class="margin">{$_('loadMore')}</button>
|
||||
{/if}
|
||||
{:else}
|
||||
<h6>Unable to load comments</h6>
|
||||
<h6>{$_('player.unableToLoadComments')}</h6>
|
||||
{/if}
|
||||
</div>
|
||||
{#if !theatreMode}
|
||||
@@ -461,7 +466,11 @@
|
||||
>
|
||||
<article class="no-elevate" style="position: sticky; top: 0; z-index: 3;">
|
||||
<h6>{playlist.title}</h6>
|
||||
<p>{cleanNumber(playlist.viewCount)} views • {playlist.videoCount} videos</p>
|
||||
<p>
|
||||
{cleanNumber(playlist.viewCount)}
|
||||
{$_('views')} • {playlist.videoCount}
|
||||
{$_('videos')}
|
||||
</p>
|
||||
<p><a href={`/channel/${playlist.authorId}`}>{playlist.author}</a></p>
|
||||
<div class="divider"></div>
|
||||
</article>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"sourceLanguageTag": "en",
|
||||
"languageTags": [
|
||||
"en"
|
||||
],
|
||||
"modules": [
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/plugin-i18next@latest/dist/index.js"
|
||||
],
|
||||
"plugin.inlang.i18next": {
|
||||
"pathPattern": "./materialious/src/i18n/locales/{languageTag}.json"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user