mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-29 16:07:40 +01:00
Merge remote branch 'movie-web/dev'
This commit is contained in:
commit
7f2b343216
12 changed files with 245 additions and 60 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "sudo-flix",
|
"name": "sudo-flix",
|
||||||
"version": "4.6.1",
|
"version": "4.6.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://sudo-flix.lol",
|
"homepage": "https://sudo-flix.lol",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
"@formkit/auto-animate": "^0.8.1",
|
"@formkit/auto-animate": "^0.8.1",
|
||||||
"@headlessui/react": "^1.7.17",
|
"@headlessui/react": "^1.7.17",
|
||||||
"@ladjs/country-language": "^1.0.3",
|
"@ladjs/country-language": "^1.0.3",
|
||||||
"@movie-web/providers": "^2.2.2",
|
"@movie-web/providers": "^2.2.3",
|
||||||
"@noble/hashes": "^1.3.3",
|
"@noble/hashes": "^1.3.3",
|
||||||
"@plasmohq/messaging": "^0.6.1",
|
"@plasmohq/messaging": "^0.6.1",
|
||||||
"@react-spring/web": "^9.7.3",
|
"@react-spring/web": "^9.7.3",
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
"focus-trap-react": "^10.2.3",
|
"focus-trap-react": "^10.2.3",
|
||||||
"fscreen": "^1.2.0",
|
"fscreen": "^1.2.0",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"hls.js": "^1.4.14",
|
"hls.js": "^1.5.7",
|
||||||
"i18next": "^23.7.11",
|
"i18next": "^23.7.11",
|
||||||
"immer": "^10.0.3",
|
"immer": "^10.0.3",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
|
|
@ -22,8 +22,8 @@ dependencies:
|
||||||
specifier: ^1.0.3
|
specifier: ^1.0.3
|
||||||
version: 1.0.3
|
version: 1.0.3
|
||||||
'@movie-web/providers':
|
'@movie-web/providers':
|
||||||
specifier: ^2.2.2
|
specifier: ^2.2.3
|
||||||
version: 2.2.2
|
version: 2.2.3
|
||||||
'@noble/hashes':
|
'@noble/hashes':
|
||||||
specifier: ^1.3.3
|
specifier: ^1.3.3
|
||||||
version: 1.3.3
|
version: 1.3.3
|
||||||
|
@ -70,8 +70,8 @@ dependencies:
|
||||||
specifier: ^7.0.0
|
specifier: ^7.0.0
|
||||||
version: 7.0.0
|
version: 7.0.0
|
||||||
hls.js:
|
hls.js:
|
||||||
specifier: ^1.4.14
|
specifier: ^1.5.7
|
||||||
version: 1.4.14
|
version: 1.5.7
|
||||||
i18next:
|
i18next:
|
||||||
specifier: ^23.7.11
|
specifier: ^23.7.11
|
||||||
version: 23.7.11
|
version: 23.7.11
|
||||||
|
@ -277,7 +277,7 @@ devDependencies:
|
||||||
version: 0.5.9(prettier@3.1.1)
|
version: 0.5.9(prettier@3.1.1)
|
||||||
rollup-plugin-visualizer:
|
rollup-plugin-visualizer:
|
||||||
specifier: ^5.11.0
|
specifier: ^5.11.0
|
||||||
version: 5.11.0(@rollup/wasm-node@4.12.1)
|
version: 5.11.0(@rollup/wasm-node@4.13.0)
|
||||||
tailwind-scrollbar:
|
tailwind-scrollbar:
|
||||||
specifier: ^3.0.5
|
specifier: ^3.0.5
|
||||||
version: 3.0.5(tailwindcss@3.4.0)
|
version: 3.0.5(tailwindcss@3.4.0)
|
||||||
|
@ -1942,8 +1942,8 @@ packages:
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@movie-web/providers@2.2.2:
|
/@movie-web/providers@2.2.3:
|
||||||
resolution: {integrity: sha512-pTlErE5bdu+b68mUW2YAKOJKz2hwSx63auGAfTkGQ+0SHDMlCV9QQ8S8O9IoSsvdXps7/YlWJWOMX8pmKuYbPQ==}
|
resolution: {integrity: sha512-0axy02Zzlk7Tvtalc/Ebv9u5vzUPVWmQm0Ts5+6l6KPU41JUdLnFgmOl0yf0lbNeHRNSTx5SDlvWcYNL8rgpyA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
cheerio: 1.0.0-rc.12
|
cheerio: 1.0.0-rc.12
|
||||||
cookie: 0.6.0
|
cookie: 0.6.0
|
||||||
|
@ -2068,7 +2068,7 @@ packages:
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@rollup/plugin-babel@5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.12.1):
|
/@rollup/plugin-babel@5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.13.0):
|
||||||
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
|
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -2081,36 +2081,36 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.23.6
|
'@babel/core': 7.23.6
|
||||||
'@babel/helper-module-imports': 7.22.15
|
'@babel/helper-module-imports': 7.22.15
|
||||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.1)
|
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.13.0)
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.12.1):
|
/@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.13.0):
|
||||||
resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
|
resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
rollup: npm:@rollup/wasm-node
|
rollup: npm:@rollup/wasm-node
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.1)
|
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.13.0)
|
||||||
'@types/resolve': 1.17.1
|
'@types/resolve': 1.17.1
|
||||||
builtin-modules: 3.3.0
|
builtin-modules: 3.3.0
|
||||||
deepmerge: 4.3.1
|
deepmerge: 4.3.1
|
||||||
is-module: 1.0.0
|
is-module: 1.0.0
|
||||||
resolve: 1.22.4
|
resolve: 1.22.4
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.12.1):
|
/@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.13.0):
|
||||||
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
|
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
rollup: npm:@rollup/wasm-node
|
rollup: npm:@rollup/wasm-node
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.1)
|
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.13.0)
|
||||||
magic-string: 0.25.9
|
magic-string: 0.25.9
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.12.1):
|
/@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.13.0):
|
||||||
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
|
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
|
||||||
engines: {node: '>= 8.0.0'}
|
engines: {node: '>= 8.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -2119,11 +2119,11 @@ packages:
|
||||||
'@types/estree': 0.0.39
|
'@types/estree': 0.0.39
|
||||||
estree-walker: 1.0.1
|
estree-walker: 1.0.1
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@rollup/wasm-node@4.12.1:
|
/@rollup/wasm-node@4.13.0:
|
||||||
resolution: {integrity: sha512-5j3BVQEccCzCb8fkl++IbDgAsnlsKBPz049C4C//j5s3pFKxKGlybl63QApdJKl1fNLr7HIwQEJcBImQtA3ZHg==}
|
resolution: {integrity: sha512-oFX11wzU7RTaiW06WBtRpzIVN/oaG0I3XkevNO0brBklYnY9zpLhTfksN4b+TdBt6CfXV/KdVhdWLbb0fQIR7A==}
|
||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -4403,8 +4403,8 @@ packages:
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/hls.js@1.4.14:
|
/hls.js@1.5.7:
|
||||||
resolution: {integrity: sha512-UppQjyvPVclg+6t2KY/Rv03h0+bA5u6zwqVoz4LAC/L0fgYmIaCD7ZCrwe8WI1Gv01be1XL0QFsRbSdIHV/Wbw==}
|
resolution: {integrity: sha512-Hnyf7ojTBtXHeOW1/t6wCBJSiK1WpoKF9yg7juxldDx8u3iswrkPt2wbOA/1NiwU4j27DSIVoIEJRAhcdMef/A==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/hoist-non-react-statics@3.3.2:
|
/hoist-non-react-statics@3.3.2:
|
||||||
|
@ -5127,7 +5127,7 @@ packages:
|
||||||
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.6)
|
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.6)
|
||||||
'@babel/types': 7.23.6
|
'@babel/types': 7.23.6
|
||||||
kleur: 4.1.5
|
kleur: 4.1.5
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
unplugin: 1.5.1
|
unplugin: 1.5.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -6055,7 +6055,7 @@ packages:
|
||||||
glob: 7.2.3
|
glob: 7.2.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.12.1):
|
/rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.13.0):
|
||||||
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
|
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
|
||||||
deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
|
deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -6063,12 +6063,12 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.23.5
|
'@babel/code-frame': 7.23.5
|
||||||
jest-worker: 26.6.2
|
jest-worker: 26.6.2
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
serialize-javascript: 4.0.0
|
serialize-javascript: 4.0.0
|
||||||
terser: 5.19.3
|
terser: 5.19.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/rollup-plugin-visualizer@5.11.0(@rollup/wasm-node@4.12.1):
|
/rollup-plugin-visualizer@5.11.0(@rollup/wasm-node@4.13.0):
|
||||||
resolution: {integrity: sha512-exM0Ms2SN3AgTzMeW7y46neZQcyLY7eKwWAop1ZoRTCZwyrIRdMMJ6JjToAJbML77X/9N8ZEpmXG4Z/Clb9k8g==}
|
resolution: {integrity: sha512-exM0Ms2SN3AgTzMeW7y46neZQcyLY7eKwWAop1ZoRTCZwyrIRdMMJ6JjToAJbML77X/9N8ZEpmXG4Z/Clb9k8g==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -6080,7 +6080,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
open: 8.4.2
|
open: 8.4.2
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
source-map: 0.7.4
|
source-map: 0.7.4
|
||||||
yargs: 17.7.2
|
yargs: 17.7.2
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -7070,7 +7070,7 @@ packages:
|
||||||
'@types/node': 20.10.5
|
'@types/node': 20.10.5
|
||||||
esbuild: 0.19.10
|
esbuild: 0.19.10
|
||||||
postcss: 8.4.32
|
postcss: 8.4.32
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -7332,9 +7332,9 @@ packages:
|
||||||
'@babel/core': 7.23.6
|
'@babel/core': 7.23.6
|
||||||
'@babel/preset-env': 7.23.6(@babel/core@7.23.6)
|
'@babel/preset-env': 7.23.6(@babel/core@7.23.6)
|
||||||
'@babel/runtime': 7.23.6
|
'@babel/runtime': 7.23.6
|
||||||
'@rollup/plugin-babel': 5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.12.1)
|
'@rollup/plugin-babel': 5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.13.0)
|
||||||
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.12.1)
|
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.13.0)
|
||||||
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.12.1)
|
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.13.0)
|
||||||
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
||||||
ajv: 8.12.0
|
ajv: 8.12.0
|
||||||
common-tags: 1.8.2
|
common-tags: 1.8.2
|
||||||
|
@ -7343,8 +7343,8 @@ packages:
|
||||||
glob: 7.2.3
|
glob: 7.2.3
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
pretty-bytes: 5.6.0
|
pretty-bytes: 5.6.0
|
||||||
rollup: /@rollup/wasm-node@4.12.1
|
rollup: /@rollup/wasm-node@4.13.0
|
||||||
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.12.1)
|
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.13.0)
|
||||||
source-map: 0.8.0-beta.0
|
source-map: 0.8.0-beta.0
|
||||||
stringify-object: 3.3.0
|
stringify-object: 3.3.0
|
||||||
strip-comments: 2.0.1
|
strip-comments: 2.0.1
|
||||||
|
@ -7389,6 +7389,7 @@ packages:
|
||||||
|
|
||||||
/workbox-google-analytics@7.0.0:
|
/workbox-google-analytics@7.0.0:
|
||||||
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
|
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
|
||||||
|
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
|
||||||
dependencies:
|
dependencies:
|
||||||
workbox-background-sync: 7.0.0
|
workbox-background-sync: 7.0.0
|
||||||
workbox-core: 7.0.0
|
workbox-core: 7.0.0
|
||||||
|
|
|
@ -117,8 +117,7 @@
|
||||||
"loading": "Wczytywanie...",
|
"loading": "Wczytywanie...",
|
||||||
"noResults": "Nie mogliśmy niczego znaleźć!",
|
"noResults": "Nie mogliśmy niczego znaleźć!",
|
||||||
"placeholder": {
|
"placeholder": {
|
||||||
"default": "Co chciałbyś obejrzeć?",
|
"default": "Co chciałbyś obejrzeć?"
|
||||||
"extra": []
|
|
||||||
},
|
},
|
||||||
"sectionTitle": "Wyniki wyszukiwania"
|
"sectionTitle": "Wyniki wyszukiwania"
|
||||||
},
|
},
|
||||||
|
@ -131,11 +130,15 @@
|
||||||
},
|
},
|
||||||
"morning": {
|
"morning": {
|
||||||
"default": "Co chciałbyś obejrzeć dziś rano?",
|
"default": "Co chciałbyś obejrzeć dziś rano?",
|
||||||
"extra": ["Słyszałem że „Przed wschodem słońca” jest dobre"]
|
"extra": [
|
||||||
|
"Słyszałem że „Przed wschodem słońca” jest dobre"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"night": {
|
"night": {
|
||||||
"default": "Co chciałbyś obejrzeć dziś wieczorem?",
|
"default": "Co chciałbyś obejrzeć dziś wieczorem?",
|
||||||
"extra": ["Zmęczony? Słyszałem że „Egzorcysta” jest dobry."]
|
"extra": [
|
||||||
|
"Zmęczony? Słyszałem że „Egzorcysta” jest dobry."
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -176,7 +179,7 @@
|
||||||
"back": "Wstecz",
|
"back": "Wstecz",
|
||||||
"explainer": "Korzystając z rozszerzenia przeglądarki, możesz uzyskać najlepsze strumienie. Wystarczy prosta instalacja.",
|
"explainer": "Korzystając z rozszerzenia przeglądarki, możesz uzyskać najlepsze strumienie. Wystarczy prosta instalacja.",
|
||||||
"explainerIos": "Niestety, rozszerzenie przeglądarki nie jest obsługiwane w systemie iOS, naciśnij <bold>Wstecz</bold>, aby wybrać inną opcję.",
|
"explainerIos": "Niestety, rozszerzenie przeglądarki nie jest obsługiwane w systemie iOS, naciśnij <bold>Wstecz</bold>, aby wybrać inną opcję.",
|
||||||
"extensionHelp": "Jeżeli zainstalowałeś rozszerzenie, ale nie zostało ono wykryte. <bold>Otwórz rozszerzenie za pomocą menu rozszerzeń przeglądarki</bold> i postępuj zgodnie z instrukcjami wyświetlanymi na ekranie.",
|
"extensionHelp": "Jeżeli zainstalowałeś rozszerzenie, ale nie zostało ono wykryte, <bold>otwórz rozszerzenie za pomocą menu rozszerzeń przeglądarki</bold> i postępuj zgodnie z instrukcjami wyświetlanymi na ekranie.",
|
||||||
"linkChrome": "Zainstaluj rozszerzenie na Chrome",
|
"linkChrome": "Zainstaluj rozszerzenie na Chrome",
|
||||||
"linkFirefox": "Zainstaluj rozszerzenie na Firefox",
|
"linkFirefox": "Zainstaluj rozszerzenie na Firefox",
|
||||||
"notDetecting": "Zainstalowano na Chrome, ale się nie wyświetla? Spróbuj odświeżyć stronę!",
|
"notDetecting": "Zainstalowano na Chrome, ale się nie wyświetla? Spróbuj odświeżyć stronę!",
|
||||||
|
@ -207,7 +210,7 @@
|
||||||
"title": "Stwórzmy nowe proxy"
|
"title": "Stwórzmy nowe proxy"
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
"explainer": "Aby uzyskać najlepsze transmisje strumieniowe. Będziesz musiał wybrać metodę strumieniowania, której chcesz użyć.",
|
"explainer": "Aby uzyskać najlepsze transmisje strumieniowe, będziesz musiał wybrać metodę strumieniowania której chcesz użyć.",
|
||||||
"options": {
|
"options": {
|
||||||
"default": {
|
"default": {
|
||||||
"text": "Nie chcę dobrej jakości strumieni, <0 /> <1>użyj domyślnej konfiguracji</1>"
|
"text": "Nie chcę dobrej jakości strumieni, <0 /> <1>użyj domyślnej konfiguracji</1>"
|
||||||
|
@ -524,8 +527,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"subtitles": {
|
"subtitles": {
|
||||||
"backgroundLabel": "Krycie tła",
|
|
||||||
"backgroundBlurLabel": "Rozmycie tła",
|
"backgroundBlurLabel": "Rozmycie tła",
|
||||||
|
"backgroundLabel": "Krycie tła",
|
||||||
"colorLabel": "Kolor",
|
"colorLabel": "Kolor",
|
||||||
"previewQuote": "Nie wolno mi się bać. Strach zabija myślenie.",
|
"previewQuote": "Nie wolno mi się bać. Strach zabija myślenie.",
|
||||||
"textSizeLabel": "Rozmiar czcionki",
|
"textSizeLabel": "Rozmiar czcionki",
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
},
|
},
|
||||||
"host": "lawa ilo sina li <0>{{hostname}}</0> - ona li pona tawa sina la sina ken pali e lipu open",
|
"host": "lawa ilo sina li <0>{{hostname}}</0> - ona li pona tawa sina la sina ken pali e lipu open",
|
||||||
"no": "o weka",
|
"no": "o weka",
|
||||||
|
"noHost": "lawa ilo ni li open ala li nasin ala la, sina ken ala pali e lipu open",
|
||||||
|
"noHostTitle": "lawa ilo li open ala a!",
|
||||||
"title": "lawa ilo ni li pona tawa sina anu seme?",
|
"title": "lawa ilo ni li pona tawa sina anu seme?",
|
||||||
"yes": "lawa ilo ni li pona"
|
"yes": "lawa ilo ni li pona"
|
||||||
},
|
},
|
||||||
|
@ -79,7 +81,8 @@
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"legal": {
|
"legal": {
|
||||||
"disclaimer": "o sona e ni:"
|
"disclaimer": "o sona e ni:",
|
||||||
|
"disclaimerText": "ilo Muwi-We li mama ala e ijo sitelen. ona li toki taso tawa ilo ante. utala nasin li lon la o toki tawa ona pi ilo ante. sitelen ale li tan ala ilo Muwi-We"
|
||||||
},
|
},
|
||||||
"links": {
|
"links": {
|
||||||
"discord": "kulupu Siko",
|
"discord": "kulupu Siko",
|
||||||
|
@ -117,22 +120,33 @@
|
||||||
"noResults": "ijo li lon ala a!",
|
"noResults": "ijo li lon ala a!",
|
||||||
"placeholder": {
|
"placeholder": {
|
||||||
"default": "sina wile lukin e seme?",
|
"default": "sina wile lukin e seme?",
|
||||||
"extra": []
|
"extra": [
|
||||||
|
"sina wile alasa e seme?",
|
||||||
|
"sina wile lukin e seme?",
|
||||||
|
"sitelen nanpa wan sina li seme?",
|
||||||
|
"sitelen nanpa wan sina li seme?"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"sectionTitle": "mi lukin e ni:"
|
"sectionTitle": "mi lukin e ni:"
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"day": {
|
"day": {
|
||||||
"default": "tenpo suno ni la sina wile lukin e seme?",
|
"default": "tenpo suno ni la sina wile lukin e seme?",
|
||||||
"extra": ["sina pilin alasa la o lukin e sitelen Jurassic Park"]
|
"extra": [
|
||||||
|
"sina pilin alasa la o lukin e sitelen Jurassic Park"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"morning": {
|
"morning": {
|
||||||
"default": "tenpo sin ni la sina wile lukin e seme?",
|
"default": "tenpo sin ni la sina wile lukin e seme?",
|
||||||
"extra": ["ken la sitelen Before Sunrise li pona"]
|
"extra": [
|
||||||
|
"ken la sitelen Before Sunrise li pona"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"night": {
|
"night": {
|
||||||
"default": "tenpo pimeja ni la sina wile lukin e seme?",
|
"default": "tenpo pimeja ni la sina wile lukin e seme?",
|
||||||
"extra": ["sina pilin lape anu seme? o alasa lukin e sitelen Exorcist"]
|
"extra": [
|
||||||
|
"sina pilin lape anu seme? o alasa lukin e sitelen Exorcist"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -163,6 +177,9 @@
|
||||||
"title": "mi ken ala lukin e lipu ona"
|
"title": "mi ken ala lukin e lipu ona"
|
||||||
},
|
},
|
||||||
"onboarding": {
|
"onboarding": {
|
||||||
|
"defaultConfirm": {
|
||||||
|
"cancel": "ala"
|
||||||
|
},
|
||||||
"start": {
|
"start": {
|
||||||
"title": "o open e ilo Muwi-We"
|
"title": "o open e ilo Muwi-We"
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,3 +51,15 @@ export async function downloadCaption(
|
||||||
downloadCache.set(caption.url, output, expirySeconds);
|
downloadCache.set(caption.url, output, expirySeconds);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the WebVTT content. No different than a simple
|
||||||
|
* get request with a cache.
|
||||||
|
*/
|
||||||
|
export async function downloadWebVTT(url: string): Promise<string> {
|
||||||
|
const cached = downloadCache.get(url);
|
||||||
|
if (cached) return cached;
|
||||||
|
|
||||||
|
const data = await fetch(url).then((v) => v.text());
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
|
@ -122,9 +122,16 @@ export function CaptionsView({ id }: { id: string }) {
|
||||||
>(null);
|
>(null);
|
||||||
const { selectCaptionById, disable } = useCaptions();
|
const { selectCaptionById, disable } = useCaptions();
|
||||||
const captionList = usePlayerStore((s) => s.captionList);
|
const captionList = usePlayerStore((s) => s.captionList);
|
||||||
|
const getHlsCaptionList = usePlayerStore((s) => s.display?.getCaptionList);
|
||||||
|
|
||||||
|
const captions = useMemo(
|
||||||
|
() =>
|
||||||
|
captionList.length !== 0 ? captionList : getHlsCaptionList?.() ?? [],
|
||||||
|
[captionList, getHlsCaptionList],
|
||||||
|
);
|
||||||
|
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
const subtitleList = useSubtitleList(captionList, searchQuery);
|
const subtitleList = useSubtitleList(captions, searchQuery);
|
||||||
|
|
||||||
const [downloadReq, startDownload] = useAsyncFn(
|
const [downloadReq, startDownload] = useAsyncFn(
|
||||||
async (captionId: string) => {
|
async (captionId: string) => {
|
||||||
|
|
|
@ -67,6 +67,11 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
||||||
let preferenceQuality: SourceQuality | null = null;
|
let preferenceQuality: SourceQuality | null = null;
|
||||||
let lastVolume = 1;
|
let lastVolume = 1;
|
||||||
|
|
||||||
|
const languagePromises = new Map<
|
||||||
|
string,
|
||||||
|
(value: void | PromiseLike<void>) => void
|
||||||
|
>();
|
||||||
|
|
||||||
function reportLevels() {
|
function reportLevels() {
|
||||||
if (!hls) return;
|
if (!hls) return;
|
||||||
const levels = hls.levels;
|
const levels = hls.levels;
|
||||||
|
@ -133,6 +138,7 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
renderTextTracksNatively: false,
|
||||||
});
|
});
|
||||||
hls.on(Hls.Events.ERROR, (event, data) => {
|
hls.on(Hls.Events.ERROR, (event, data) => {
|
||||||
console.error("HLS error", data);
|
console.error("HLS error", data);
|
||||||
|
@ -173,6 +179,16 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
||||||
const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]);
|
const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]);
|
||||||
emit("changedquality", quality);
|
emit("changedquality", quality);
|
||||||
});
|
});
|
||||||
|
hls.on(Hls.Events.SUBTITLE_TRACK_LOADED, () => {
|
||||||
|
for (const [lang, resolve] of languagePromises) {
|
||||||
|
const track = hls?.subtitleTracks.find((t) => t.lang === lang);
|
||||||
|
if (track) {
|
||||||
|
resolve();
|
||||||
|
languagePromises.delete(lang);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hls.attachMedia(vid);
|
hls.attachMedia(vid);
|
||||||
|
@ -413,5 +429,40 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
||||||
setPlaybackRate(rate) {
|
setPlaybackRate(rate) {
|
||||||
if (videoElement) videoElement.playbackRate = rate;
|
if (videoElement) videoElement.playbackRate = rate;
|
||||||
},
|
},
|
||||||
|
getCaptionList() {
|
||||||
|
return (
|
||||||
|
hls?.subtitleTracks.map((track) => {
|
||||||
|
return {
|
||||||
|
id: track.id.toString(),
|
||||||
|
language: track.lang ?? "unknown",
|
||||||
|
url: track.url,
|
||||||
|
needsProxy: false,
|
||||||
|
hls: true,
|
||||||
|
};
|
||||||
|
}) ?? []
|
||||||
|
);
|
||||||
|
},
|
||||||
|
getSubtitleTracks() {
|
||||||
|
return hls?.subtitleTracks ?? [];
|
||||||
|
},
|
||||||
|
async setSubtitlePreference(lang) {
|
||||||
|
// default subtitles are already loaded by hls.js
|
||||||
|
const track = hls?.subtitleTracks.find((t) => t.lang === lang);
|
||||||
|
if (track?.details !== undefined) return Promise.resolve();
|
||||||
|
|
||||||
|
// need to wait a moment before hls loads the subtitles
|
||||||
|
const promise = new Promise<void>((resolve, reject) => {
|
||||||
|
languagePromises.set(lang, resolve);
|
||||||
|
|
||||||
|
// reject after some time, if hls.js fails to load the subtitles
|
||||||
|
// for any reason
|
||||||
|
setTimeout(() => {
|
||||||
|
reject();
|
||||||
|
languagePromises.delete(lang);
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
hls?.setSubtitleOption({ lang });
|
||||||
|
return promise;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,5 +274,14 @@ export function makeChromecastDisplayInterface(
|
||||||
playbackRate = rate;
|
playbackRate = rate;
|
||||||
setSource();
|
setSource();
|
||||||
},
|
},
|
||||||
|
getCaptionList() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
getSubtitleTracks() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
async setSubtitlePreference() {
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
import { MediaPlaylist } from "hls.js";
|
||||||
|
|
||||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
import { MWMediaType } from "@/backend/metadata/types/mw";
|
||||||
|
import { CaptionListItem } from "@/stores/player/slices/source";
|
||||||
import { LoadableSource, SourceQuality } from "@/stores/player/utils/qualities";
|
import { LoadableSource, SourceQuality } from "@/stores/player/utils/qualities";
|
||||||
import { Listener } from "@/utils/events";
|
import { Listener } from "@/utils/events";
|
||||||
|
|
||||||
|
@ -70,4 +73,7 @@ export interface DisplayInterface extends Listener<DisplayInterfaceEvents> {
|
||||||
setMeta(meta: DisplayMeta): void;
|
setMeta(meta: DisplayMeta): void;
|
||||||
setCaption(caption: DisplayCaption | null): void;
|
setCaption(caption: DisplayCaption | null): void;
|
||||||
getType(): DisplayType;
|
getType(): DisplayType;
|
||||||
|
getCaptionList(): CaptionListItem[];
|
||||||
|
getSubtitleTracks(): MediaPlaylist[];
|
||||||
|
setSubtitlePreference(lang: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
import { useCallback } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
|
import subsrt from "subsrt-ts";
|
||||||
|
|
||||||
import { downloadCaption } from "@/backend/helpers/subs";
|
import { downloadCaption, downloadWebVTT } from "@/backend/helpers/subs";
|
||||||
|
import { Caption } from "@/stores/player/slices/source";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
import { useSubtitleStore } from "@/stores/subtitles";
|
import { useSubtitleStore } from "@/stores/subtitles";
|
||||||
|
|
||||||
|
import {
|
||||||
|
filterDuplicateCaptionCues,
|
||||||
|
parseVttSubtitles,
|
||||||
|
} from "../utils/captions";
|
||||||
|
|
||||||
export function useCaptions() {
|
export function useCaptions() {
|
||||||
const setLanguage = useSubtitleStore((s) => s.setLanguage);
|
const setLanguage = useSubtitleStore((s) => s.setLanguage);
|
||||||
const enabled = useSubtitleStore((s) => s.enabled);
|
const enabled = useSubtitleStore((s) => s.enabled);
|
||||||
|
@ -12,32 +19,85 @@ export function useCaptions() {
|
||||||
);
|
);
|
||||||
const setCaption = usePlayerStore((s) => s.setCaption);
|
const setCaption = usePlayerStore((s) => s.setCaption);
|
||||||
const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage);
|
const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage);
|
||||||
|
|
||||||
const captionList = usePlayerStore((s) => s.captionList);
|
const captionList = usePlayerStore((s) => s.captionList);
|
||||||
|
const getHlsCaptionList = usePlayerStore((s) => s.display?.getCaptionList);
|
||||||
|
|
||||||
|
const getSubtitleTracks = usePlayerStore((s) => s.display?.getSubtitleTracks);
|
||||||
|
const setSubtitlePreference = usePlayerStore(
|
||||||
|
(s) => s.display?.setSubtitlePreference,
|
||||||
|
);
|
||||||
|
|
||||||
|
const captions = useMemo(
|
||||||
|
() =>
|
||||||
|
captionList.length !== 0 ? captionList : getHlsCaptionList?.() ?? [],
|
||||||
|
[captionList, getHlsCaptionList],
|
||||||
|
);
|
||||||
|
|
||||||
const selectCaptionById = useCallback(
|
const selectCaptionById = useCallback(
|
||||||
async (captionId: string) => {
|
async (captionId: string) => {
|
||||||
const caption = captionList.find((v) => v.id === captionId);
|
const caption = captions.find((v) => v.id === captionId);
|
||||||
if (!caption) return;
|
if (!caption) return;
|
||||||
const srtData = await downloadCaption(caption);
|
|
||||||
setCaption({
|
const captionToSet: Caption = {
|
||||||
id: caption.id,
|
id: caption.id,
|
||||||
language: caption.language,
|
language: caption.language,
|
||||||
srtData,
|
|
||||||
url: caption.url,
|
url: caption.url,
|
||||||
});
|
srtData: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!caption.hls) {
|
||||||
|
const srtData = await downloadCaption(caption);
|
||||||
|
captionToSet.srtData = srtData;
|
||||||
|
} else {
|
||||||
|
// request a language change to hls, so it can load the subtitles
|
||||||
|
await setSubtitlePreference?.(caption.language);
|
||||||
|
const track = getSubtitleTracks?.().find(
|
||||||
|
(t) => t.id.toString() === caption.id && t.details !== undefined,
|
||||||
|
);
|
||||||
|
if (!track) return;
|
||||||
|
|
||||||
|
const fragments =
|
||||||
|
track.details?.fragments?.filter(
|
||||||
|
(frag) => frag !== null && frag.url !== null,
|
||||||
|
) ?? [];
|
||||||
|
|
||||||
|
const vttCaptions = (
|
||||||
|
await Promise.all(
|
||||||
|
fragments.map(async (frag) => {
|
||||||
|
const vtt = await downloadWebVTT(frag.url);
|
||||||
|
return parseVttSubtitles(vtt);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
).flat();
|
||||||
|
|
||||||
|
const filtered = filterDuplicateCaptionCues(vttCaptions);
|
||||||
|
|
||||||
|
const srtData = subsrt.build(filtered, { format: "srt" });
|
||||||
|
captionToSet.srtData = srtData;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCaption(captionToSet);
|
||||||
resetSubtitleSpecificSettings();
|
resetSubtitleSpecificSettings();
|
||||||
setLanguage(caption.language);
|
setLanguage(caption.language);
|
||||||
},
|
},
|
||||||
[setLanguage, captionList, setCaption, resetSubtitleSpecificSettings],
|
[
|
||||||
|
setLanguage,
|
||||||
|
captions,
|
||||||
|
setCaption,
|
||||||
|
resetSubtitleSpecificSettings,
|
||||||
|
getSubtitleTracks,
|
||||||
|
setSubtitlePreference,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectLanguage = useCallback(
|
const selectLanguage = useCallback(
|
||||||
async (language: string) => {
|
async (language: string) => {
|
||||||
const caption = captionList.find((v) => v.language === language);
|
const caption = captions.find((v) => v.language === language);
|
||||||
if (!caption) return;
|
if (!caption) return;
|
||||||
return selectCaptionById(caption.id);
|
return selectCaptionById(caption.id);
|
||||||
},
|
},
|
||||||
[captionList, selectCaptionById],
|
[captions, selectCaptionById],
|
||||||
);
|
);
|
||||||
|
|
||||||
const disable = useCallback(async () => {
|
const disable = useCallback(async () => {
|
||||||
|
|
|
@ -50,12 +50,30 @@ export function convertSubtitlesToSrt(text: string): string {
|
||||||
return srt;
|
return srt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function filterDuplicateCaptionCues(cues: ContentCaption[]) {
|
||||||
|
return cues.reduce((acc: ContentCaption[], cap: ContentCaption) => {
|
||||||
|
const lastCap = acc[acc.length - 1];
|
||||||
|
const isSameAsLast =
|
||||||
|
lastCap?.start === cap.start &&
|
||||||
|
lastCap?.end === cap.end &&
|
||||||
|
lastCap?.content === cap.content;
|
||||||
|
if (lastCap === undefined || !isSameAsLast) {
|
||||||
|
acc.push(cap);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseVttSubtitles(vtt: string) {
|
||||||
|
return parse(vtt).filter((cue) => cue.type === "caption") as CaptionCueType[];
|
||||||
|
}
|
||||||
|
|
||||||
export function parseSubtitles(
|
export function parseSubtitles(
|
||||||
text: string,
|
text: string,
|
||||||
_language?: string,
|
_language?: string,
|
||||||
): CaptionCueType[] {
|
): CaptionCueType[] {
|
||||||
const vtt = convertSubtitlesToVtt(text);
|
const vtt = convertSubtitlesToVtt(text);
|
||||||
return parse(vtt).filter((cue) => cue.type === "caption") as CaptionCueType[];
|
return parseVttSubtitles(vtt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stringToBase64(input: string): string {
|
function stringToBase64(input: string): string {
|
||||||
|
|
|
@ -53,6 +53,7 @@ export interface CaptionListItem {
|
||||||
language: string;
|
language: string;
|
||||||
url: string;
|
url: string;
|
||||||
needsProxy: boolean;
|
needsProxy: boolean;
|
||||||
|
hls?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SourceSlice {
|
export interface SourceSlice {
|
||||||
|
|
Loading…
Reference in a new issue