Compare commits

..

148 Commits
4.4.1 ... 4.6.0

Author SHA1 Message Date
William Oldham
59958487d2 Merge pull request #973 from movie-web/dev
Version 4.6
2024-03-10 23:19:06 +00:00
William Oldham
1fd3e37fa4 Merge branch 'master' into dev 2024-03-10 23:16:25 +00:00
William Oldham
d5ac1d5db2 Merge pull request #976 from gh-movie-web/weblate-movie-web-website
Translations update from movie-web weblate
2024-03-10 23:16:12 +00:00
admin
cfaf2130e4 Deleted translation using Weblate (Albanian)
Author: admin <admin@movie-web.app>
2024-03-10 23:14:11 +00:00
chaos
57a747099e Translated using Weblate (Estonian)
Currently translated at 100.0% (328 of 328 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/et/
Author: chaos <chaos@users.noreply.weblate.movie-web.app>
2024-03-10 23:09:21 +00:00
Jimin
3cab6ab3c3 Translated using Weblate (Korean)
Currently translated at 99.6% (326 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ko/
Author: Jimin <jiminlee102@gmail.com>
2024-03-10 23:09:21 +00:00
Alex
dd0b9f60c9 Translated using Weblate (Russian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ru/
Author: Alex <aslanych99@mail.ru>
2024-03-10 23:09:21 +00:00
Matias Bubello
5754215725 Translated using Weblate (Spanish)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/es/
Author: Matias Bubello <matt.bubello@gmail.com>
2024-03-10 23:09:21 +00:00
aryiu
7ffb904f9e Translated using Weblate (Valencian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ca@valencia/
Author: aryiu <aryiu@users.noreply.weblate.476328473.xyz>
2024-03-10 23:09:21 +00:00
chaos
90e1d3c369 Translated using Weblate (Estonian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/et/
Author: chaos <chaos@users.noreply.weblate.movie-web.app>
2024-03-10 23:09:21 +00:00
Juled Zaganjori
27297227e6 Added translation using Weblate (Albanian)
Author: Juled Zaganjori <zaganjorijuled@gmail.com>
2024-03-10 23:09:21 +00:00
William Oldham
9cb6147017 Bump version to 4.6 2024-03-10 23:09:09 +00:00
chaos
3d333dcb03 Merge pull request #993 from ssssobek/dev
Add blurred background option for subtitles
2024-03-11 01:05:50 +02:00
ssssobek
67af11fd85 Set the default background blur to 50% 2024-03-10 23:56:06 +01:00
ssssobek
ca180ab9ea Go back to using percentages instead of pixels 2024-03-10 23:10:25 +01:00
ssssobek
e09c04b57b Add blurred backgroud for subtitles 2024-03-10 20:14:48 +01:00
William Oldham
9409922efd Merge pull request #721 from qtchaos/mediasession
Implement MediaSession support
2024-03-07 15:54:57 +00:00
William Oldham
425c7beeea Merge branch 'dev' into mediasession 2024-03-07 15:52:35 +00:00
William Oldham
fcee7001ee Merge pull request #985 from zisra/x-button
Make x-button more visible
2024-03-06 17:06:40 +00:00
4a5d537679 Revert all color changes 2024-03-06 11:01:46 -06:00
a652be9a86 Fix 2024-03-06 10:59:29 -06:00
7159b76344 Add onboarding styles to default theme 2024-03-06 10:58:38 -06:00
b74a4cd4c6 Make x-button more visible 2024-03-06 10:56:06 -06:00
qtchaos
256f9f9df9 feat: add season/episode to the start of title 2024-03-05 00:33:31 +02:00
William Oldham
18e9bdbfc5 Merge branch 'dev' into mediasession 2024-03-04 21:42:40 +00:00
William Oldham
89bc201b73 Merge pull request #967 from MovieWebIPFS/patch-1
feat: allow setting 'base' via VITE_BASE_URL
2024-03-04 20:38:28 +00:00
MovieWebIPFS
de2e3e6aed feat: allow setting 'base' via VITE_BASE_URL
this sets the default to `/` which results in this patch not breaking behavior. This is being used to set base as a relative path to enable hosting movie-web at any non-root location
2024-03-04 20:36:39 +00:00
William Oldham
27aff99969 Merge pull request #975 from qtchaos/fix/button-navigate
When navigating to own pages, use `useNavigate()`
2024-03-03 23:20:51 +00:00
qtchaos
f33bc583ea fix: when navigating to own pages, use useNavigate() 2024-03-03 22:47:51 +02:00
William Oldham
bada1d12cf Add Catalan (Valencia) 2024-03-03 19:13:30 +00:00
William Oldham
cf3d9fdc21 Merge pull request #964 from gh-movie-web/weblate-movie-web-website
Translations update from movie-web weblate
2024-03-03 18:50:27 +00:00
Mehdi
8a973b1d89 Translated using Weblate (Persian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-03-03 18:48:11 +00:00
aryiu
078777f952 Translated using Weblate (Valencian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ca@valencia/
Author: aryiu <aryiu@users.noreply.weblate.movie-web.app>
2024-03-03 18:48:11 +00:00
aryiu
dc4ce9b91f Translated using Weblate (Catalan)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ca/
Author: aryiu <aryiu@users.noreply.weblate.movie-web.app>
2024-03-03 18:48:11 +00:00
Matic Bončina
56413183b6 Translated using Weblate (Slovenian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/sl/
Author: Matic Bončina <github@express.ninja>
2024-03-03 18:48:11 +00:00
aryiu
f89759e9b9 Translated using Weblate (Catalan)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ca/
Author: aryiu <aryiu@users.noreply.weblate.movie-web.app>
2024-03-03 18:48:11 +00:00
Fluhfi
9c03cef941 Translated using Weblate (Punjabi)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/pa/
Author: Fluhfi <aseemsharma2992@gmail.com>
2024-03-03 18:48:11 +00:00
Mehdi
49fe07b208 Translated using Weblate (Persian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-03-03 18:48:11 +00:00
aryiu
5e0b434ea7 Added translation using Weblate (Valencian)
Author: aryiu <aryiu@users.noreply.weblate.movie-web.app>
2024-03-03 18:48:11 +00:00
NidaleNieve
e24697f723 Translated using Weblate (Icelandic)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/is/
Author: NidaleNieve <nidale16@outlook.com>
2024-03-03 18:48:11 +00:00
Mehdi
00700408fb Translated using Weblate (Persian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-03-03 18:48:11 +00:00
Aayush Shah
2a3ae861cc Translated using Weblate (Hindi)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/hi/
Author: Aayush Shah <shahaayush999@gmail.com>
2024-03-03 18:48:11 +00:00
n1ck
2804b2addd Translated using Weblate (Spanish)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/es/
Author: n1ck <n1ck.lim@proton.me>
2024-03-03 18:48:11 +00:00
Aayush Shah
dcfbf6b266 Translated using Weblate (Nepali)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ne/
Author: Aayush Shah <shahaayush999@gmail.com>
2024-03-03 18:48:11 +00:00
Raymond Nee
7f859e0bfd Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/zh_Hans/
Author: Raymond Nee <monstorix@outlook.com>
2024-03-03 18:48:11 +00:00
blikje
05741ed632 Translated using Weblate (Dutch)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/nl/
Author: blikje <Blikje7up@gmail.com>
2024-03-03 18:48:11 +00:00
Jamie Poznanski
dc04390172 Translated using Weblate (Italian)
Currently translated at 100.0% (327 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/it/
Author: Jamie Poznanski <enby_jamie@users.noreply.weblate.movie-web.app>
2024-03-03 18:48:11 +00:00
EPScorp
228ac6fd6c Translated using Weblate (French)
Currently translated at 98.1% (321 of 327 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/fr/
Author: EPScorp <robotvolant168@gmail.com>
2024-03-03 18:48:11 +00:00
William Oldham
22cb2a259d Merge pull request #972 from movie-web/config-improvements
Config improvements
2024-03-03 18:48:05 +00:00
William Oldham
fa8548d3c2 Default config.js to not have TMDB set 2024-03-03 18:37:57 +00:00
William Oldham
404d3b885f Handle nullability of config fields 2024-03-03 18:37:43 +00:00
William Oldham
b560445659 Return null values where appr and handle the env being blank 2024-03-03 18:37:28 +00:00
William Oldham
e555354e17 If TMDB key is empty, don't attempt request 2024-03-03 18:36:12 +00:00
William Oldham
95a75f81b1 Merge pull request #961 from binaryoverload/dev
Add vercel config to properly support non-hash router
2024-03-01 19:30:11 +00:00
William Oldham
818e159586 Create vercel.json 2024-03-01 17:17:09 +00:00
William Oldham
a0067cb2f2 Merge pull request #955 from movie-web/dev
Version 4.5.1
2024-02-29 23:31:00 +00:00
William Oldham
9658c61cd0 Merge branch 'dev' of https://github.com/movie-web/movie-web into dev 2024-02-29 23:27:52 +00:00
William Oldham
34cb2bfb36 Bump version to 4.5.1 2024-02-29 23:27:50 +00:00
William Oldham
0f1aab605d Merge branch 'master' into dev 2024-02-29 23:19:07 +00:00
William Oldham
6388ebb8ef Update providers to 2.2.2 2024-02-29 23:18:15 +00:00
William Oldham
5e334246f4 Fix linting 2024-02-29 23:17:52 +00:00
William Oldham
10fa48ba04 Merge pull request #958 from movie-web/965-backend-https-default
Automatically prefix backend url with https:// if not provided
2024-02-29 22:01:49 +00:00
William Oldham
9fc3e9082f feat: automatically prefix backend url with https:// if not provided 2024-02-29 22:00:07 +00:00
William Oldham
d4463cbccd Merge pull request #907 from gh-movie-web/weblate-movie-web-website
Translations update from movie-web weblate
2024-02-29 18:55:40 +00:00
Mehdi
ffb468a450 Translated using Weblate (Persian)
Currently translated at 100.0% (325 of 325 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-02-29 18:51:21 +00:00
Matic Bončina
ceb0c1e35a Translated using Weblate (Slovenian)
Currently translated at 100.0% (325 of 325 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/sl/
Author: Matic Bončina <github@express.ninja>
2024-02-29 18:51:21 +00:00
Matic Boncina
96c5a3387d Translated using Weblate (Slovenian)
Currently translated at 100.0% (325 of 325 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/sl/
Author: Matic Boncina <476328473@express.ninja>
2024-02-29 18:51:21 +00:00
Aayush Shah
dec42deaef Translated using Weblate (Nepali)
Currently translated at 100.0% (325 of 325 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/ne/
Author: Aayush Shah <shahaayush999@gmail.com>
2024-02-29 18:51:21 +00:00
Jamie Poznanski
866142ac57 Translated using Weblate (Italian)
Currently translated at 100.0% (325 of 325 strings)

Translation: movie-web/website
Translate-URL: https://weblate.476328473.xyz/projects/movie-web/website/it/
Author: Jamie Poznanski <enby_jamie@users.noreply.weblate.movie-web.app>
2024-02-29 18:51:21 +00:00
Raymond Nee
204ec6421d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (325 of 325 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/zh_Hans/
Author: Raymond Nee <monstorix@outlook.com>
2024-02-29 18:51:21 +00:00
Weblate
3cbffb3981 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/
2024-02-29 18:51:21 +00:00
Mehdi
f0e3262a71 Translated using Weblate (Persian)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-02-29 18:51:21 +00:00
Ninguart
5aecb988de Translated using Weblate (Czech)
Currently translated at 98.4% (316 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/cs/
Author: Ninguart <ninguart@users.noreply.weblate.movie-web.app>
2024-02-29 18:51:21 +00:00
Vijay
e34995fa98 Translated using Weblate (Tamil)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/ta/
Author: Vijay <vcmvijay@gmail.com>
2024-02-29 18:51:21 +00:00
Mehdi
1c887b132d Translated using Weblate (Persian)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-02-29 18:51:21 +00:00
Vijay
76cd8847d3 Translated using Weblate (Tamil)
Currently translated at 23.0% (74 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/ta/
Author: Vijay <vcmvijay@gmail.com>
2024-02-29 18:51:21 +00:00
Jamie Poznanski
78d1c4f740 Translated using Weblate (Italian)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/it/
Author: Jamie Poznanski <enby_jamie@users.noreply.weblate.movie-web.app>
2024-02-29 18:51:21 +00:00
Mehdi
5ebff1276c Translated using Weblate (Persian)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-02-29 18:51:21 +00:00
Mehdi
e10463d60a Translated using Weblate (Persian)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/fa/
Author: Mehdi <pyrexrj@gmail.com>
2024-02-29 18:51:21 +00:00
Raymond Nee
65e6db761d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/zh_Hans/
Author: Raymond Nee <monstorix@outlook.com>
2024-02-29 18:51:21 +00:00
Stella Vanella
89929be12c Translated using Weblate (Vietnamese)
Currently translated at 34.2% (110 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/vi/
Author: Stella Vanella <stellavu2018@gmail.com>
2024-02-29 18:51:21 +00:00
aryiu
a3b2b741c8 Translated using Weblate (Catalan)
Currently translated at 87.5% (281 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/ca/
Author: aryiu <aryiu@users.noreply.weblate.movie-web.app>
2024-02-29 18:51:21 +00:00
Alex
d28c89eb83 Translated using Weblate (Russian)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/ru/
Author: Alex <aslanych99@mail.ru>
2024-02-29 18:51:21 +00:00
Tauan
2dc7affd94 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/pt_BR/
Author: Tauan <matheus-tauan@hotmail.com>
2024-02-29 18:51:21 +00:00
Alex
ad745eb532 Translated using Weblate (Spanish)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/es/
Author: Alex <alejandroreizq@duck.com>
2024-02-29 18:51:21 +00:00
Raymond Nee
fc4920699b Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/zh_Hans/
Author: Raymond Nee <monstorix@outlook.com>
2024-02-29 18:51:21 +00:00
Jamie Poznanski
c71c0f6ae7 Translated using Weblate (Italian)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/it/
Author: Jamie Poznanski <enby_jamie@users.noreply.weblate.movie-web.app>
2024-02-29 18:51:21 +00:00
Guillaume
5804838f5e Translated using Weblate (French)
Currently translated at 100.0% (321 of 321 strings)

Translation: movie-web/website
Translate-URL: https://weblate.movie-web.app/projects/movie-web/website/fr/
Author: Guillaume <guillaumepeeklo@gmail.com>
2024-02-29 18:51:21 +00:00
chaos
cbb699b767 Merge pull request #947 from movie-web/fix/#905
Extension: Prepare stream for all domains in a hls playlist
2024-02-28 16:58:36 +02:00
chaos
4ec89456ac Merge branch 'dev' into fix/#905 2024-02-28 16:50:46 +02:00
William Oldham
acec24b9b5 Merge pull request #949 from movie-web/feature/#944
Add dismissable banners
2024-02-28 11:31:32 +00:00
Jorrin
5a78e48dfe add dismissable banners 2024-02-28 00:48:49 +01:00
Jorrin
d20ab4be08 double map into one 2024-02-27 23:30:00 +01:00
Jorrin
7af58dd9e8 prepare stream for all domains in a hls playlist 2024-02-27 23:19:40 +01:00
William Oldham
8643b7c584 Merge pull request #946 from Audiosutras/dev
Update Dockerfile and add compose.yaml file
2024-02-27 20:10:20 +00:00
Audiosutras
7b1330f664 Update docker-compose.yaml
Co-authored-by: Timon Klinkert <83671398+DenuxPlays@users.noreply.github.com>
2024-02-27 15:05:22 -05:00
Christopher Dixon
916d15d2f0 add commented out build args to docker-compose.yaml 2024-02-27 15:02:45 -05:00
Christopher Dixon
d92a4de948 peer review feedback 2024-02-27 14:55:05 -05:00
Christopher Dixon
2cfa5acb35 update Dockerfile & add compose.yaml file 2024-02-27 14:38:48 -05:00
William Oldham
1acefd75fa Merge pull request #929 from movie-web/dev
Version 4.5.0
2024-02-26 21:39:25 +00:00
William Oldham
86a3136fd0 Bump version 2024-02-26 21:34:51 +00:00
William Oldham
7c4c02dd83 Fix theme preview 2024-02-26 21:27:45 +00:00
William Oldham
261ef5e6c5 Use quick links 2024-02-26 21:27:31 +00:00
William Oldham
843ec84936 Merge pull request #922 from marcoslor/868-add-appearance-preview
Add appearance preview
2024-02-26 21:13:06 +00:00
William Oldham
ba4713b130 Merge pull request #943 from qtchaos/scroll-volume
Allow users to change volume with scroll wheel
2024-02-26 20:56:30 +00:00
qtchaos
67c86a270e feat: make volume scrollable with your mouse 2024-02-26 22:39:32 +02:00
William Oldham
c1731fdbc9 Merge pull request #942 from qtchaos/google-analytics
Make Google Analytics configurable with VITE_GA_ID
2024-02-26 18:35:05 +00:00
qtchaos
0e72829dd7 feat: make Google Analytics configurable with VITE_GA_ID 2024-02-26 19:40:35 +02:00
William Oldham
02fceb7f8e Merge pull request #941 from qtchaos/fix-download
Fix media download button redirecting to incorrect URL on main tab
2024-02-26 15:09:35 +00:00
qtchaos
5321afe2cd chore: remove useNavigate import 2024-02-26 17:06:35 +02:00
qtchaos
e8d8c16d41 fix: use window.open instead of react-router on href within Button 2024-02-26 16:56:46 +02:00
William Oldham
d1c58041c4 Merge pull request #940 from qtchaos/remove-default-setup
Disable default setup option if no proxies are set, remove extension help once it succeeds
2024-02-26 12:12:03 +00:00
qtchaos
f93e9288b5 feat: remove default VITE_CORS_PROXY_URL 2024-02-26 14:06:33 +02:00
qtchaos
1df0ac000d feat: disable default setup option if no proxies set, remove extension help on OK 2024-02-26 13:48:45 +02:00
William Oldham
0a86c59cfb Merge pull request #939 from qtchaos/admin-update
Update the admin page to run workers in parallel
2024-02-25 22:20:15 +00:00
William Oldham
9e4241e464 Merge pull request #938 from qtchaos/remove-domain
Remove references to official domain
2024-02-25 22:19:14 +00:00
qtchaos
bf6424f75d feat: run worker tests in parallel with 5 sec cooldown 2024-02-25 22:04:47 +02:00
qtchaos
130b4f5cc3 feat: disable creating account when server is not set 2024-02-25 21:31:08 +02:00
qtchaos
fcf42a4e8a fix: change useBackendUrl to possibly be undefined, add checks to avoid useless requests to nonexistent backend 2024-02-24 02:08:01 +02:00
qtchaos
b18269b40e chore: Remove references to official domain 2024-02-23 16:26:17 +02:00
Marcos Rios
ac9d347a26 Remove nonsense ref 2024-02-22 23:55:07 -03:00
William Oldham
c6fe62ae8a Merge branch 'master' into dev 2024-02-21 19:09:16 +00:00
William Oldham
87c6be9a61 Merge pull request #915 from movie-web/fix/#904
route subtitles through extension if installed
2024-02-21 19:07:23 +00:00
William Oldham
f4514b283c Merge branch 'dev' into fix/#904 2024-02-21 19:05:29 +00:00
William Oldham
48a37112c6 Merge pull request #920 from vijaysingh2219/dev
Add dynamic and engaging search bar placeholders
2024-02-21 18:11:06 +00:00
William Oldham
ac119a42a0 Merge branch 'dev' into dev 2024-02-21 18:08:17 +00:00
William Oldham
12274db582 Merge pull request #928 from movie-web/fix/#927
Fix #927 and add build arg for Docker PWA
2024-02-21 18:04:50 +00:00
William Oldham
98d06a6051 Fix #927 and add build arg for Docker PWA 2024-02-21 17:54:01 +00:00
Vijay
446be58478 Fix ESLint warning in HeroPart.tsx 2024-02-20 16:18:36 +05:30
Vijay
60d5c5d05c Updated the extra search placeholder options
- Reduced the number of options for search placeholder
2024-02-20 15:29:44 +05:30
Vijay
b1741a3264 Updated 'placeholder' key structure across all locale files 2024-02-19 18:21:34 +05:30
Marcos Rios
3522f6c038 Fix theme preview not being reset after leaving settings 2024-02-18 17:10:16 -03:00
Marcos Rios
247362a4a9 Add preview theme functionality to SettingsPage 2024-02-18 17:10:16 -03:00
Vijay
f5c1d6eb86 Add dynamic and engaging search bar placeholders
Enhance search bar experience with 15 dynamic placeholders for the movie web app. Provides a mix of engaging questions and suggestions, promoting user interaction and a personalized feel. Shuffled for a random appearance, contributing to a more dynamic user experience.
2024-02-17 23:31:55 +05:30
Jorrin
121a71449f route subtitles through extension if installed 2024-02-15 14:17:57 +01:00
William Oldham
07b5c95607 Merge pull request #909 from movie-web/dev
Version 4.4.2: Fix extension compatibility
2024-02-14 10:20:59 +00:00
William Oldham
90d8d2428f Merge pull request #908 from movie-web/fix-extension-compat
Bump compatibility to caret-style for extension
2024-02-14 10:19:03 +00:00
William Oldham
6a13f0a737 Bump version 2024-02-14 09:27:18 +00:00
William Oldham
31dc7f4967 Bump compatibility to caret-style for extension 2024-02-14 09:20:06 +00:00
chaos
b129181b6c Merge branch 'dev' into mediasession 2024-02-09 15:52:31 +00:00
qtchaos
761e952ce2 fix: update if conditions to allow for updates after changing episodes 2024-02-09 17:51:47 +02:00
mrjvs
a2a3066bc7 Merge branch 'dev' into mediasession 2024-01-31 16:56:36 +01:00
chaos
224d823eb6 Merge branch 'dev' into mediasession 2024-01-11 22:25:07 +02:00
qtchaos
c6f359d4ea Remove unused import in MediaSession.ts 2024-01-06 19:31:05 +02:00
chaos
b952d0a4d0 Merge branch 'dev' into mediasession 2024-01-06 18:44:37 +02:00
qtchaos
fb68efa522 Rework MediaSession to be less bad 2024-01-06 18:43:42 +02:00
mrjvs
949cc216c7 Merge branch 'dev' into mediasession 2024-01-06 15:31:01 +01:00
qtchaos
00066ba788 somewhat ok mediasession implementation 2024-01-05 21:19:59 +02:00
104 changed files with 2435 additions and 524 deletions

View File

@@ -60,7 +60,7 @@ representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
codeofconduct@movie-web.app.
our [Discord](https://movie-web.github.io/links/discord).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the

View File

@@ -1,6 +1,6 @@
# Contributing Guidelines for movie-web
Thank you for investing your time in contributing to our project! Your contribution will be reflected on [movie-web.app](https://movie-web.app).
Thank you for investing your time in contributing to our project! Your contribution will be reflected on all of the community hosted instances that are on the latest version.
Please read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable.
@@ -33,7 +33,7 @@ There are two places where to request features or report bugs:
### Discord Server
If you do not have a GitHub account or want to discuss a feature or bug with us before making an issue, you can join our Discord server.
<a href="https://discord.movie-web.app"><img src="https://discord.com/api/guilds/871713465100816424/widget.png?style=banner2" alt="Discord Server"></a>
<a href="https://movie-web.github.io/links/discord"><img src="https://discord.com/api/guilds/871713465100816424/widget.png?style=banner2" alt="Discord Server"></a>
### GitHub Issues
To make a GitHub issue for movie-web, please visit the [new issue page](https://github.com/movie-web/movie-web/issues/new/choose) where you can pick either the "Bug Report" or "Feature Request" template.
@@ -85,7 +85,8 @@ Here are some tips to make sure that your pull requests are :pinched_fingers: fi
### Language Contributions
Language contributions help movie-web massively, allowing people worldwide to use our app!
We use weblate for crowdsourcing our translations. [Click here to go to our translation tool.](https://weblate.movie-web.app/projects/movie-web/website/)
We use Weblate for crowdsourcing our translations. [Click here to go to our translation tool.](https://movie-web.github.io/links/weblate)
1. First make sure you make an account. (click the link above)
2. Click the language you want to help translate, if it's not listed you can click the plus top left to add a new language.

9
.github/SECURITY.md vendored
View File

@@ -2,12 +2,9 @@
## Supported Versions
The movie-web maintainers only support the latest version of movie-web published at https://movie-web.app.
Support is not provided for any forks or mirrors of movie-web.
The latest version of movie-web is the only version that is supported, as it is the only version that is being actively developed.
## Reporting a Vulnerability
There are two ways you can contact the movie-web maintainers to report a vulnerability:
- Email [security@movie-web.app](mailto:security@movie-web.app)
- Report the vulnerability in the [movie-web Discord server](https://discord.movie-web.app)
You can contact the movie-web maintainers to report a vulnerability:
- Report the vulnerability in the [movie-web Discord server](https://movie-web.github.io/links/discord)

View File

@@ -8,6 +8,38 @@ COPY package.json ./
COPY pnpm-lock.yaml ./
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
ARG PWA_ENABLED="false"
ARG GA_ID
ARG APP_DOMAIN
ARG OPENSEARCH_ENABLED="false"
ARG TMDB_READ_API_KEY
ARG CORS_PROXY_URL
ARG DMCA_EMAIL
ARG NORMAL_ROUTER="false"
ARG BACKEND_URL
ARG HAS_ONBOARDING="false"
ARG ONBOARDING_CHROME_EXTENSION_INSTALL_LINK
ARG ONBOARDING_PROXY_INSTALL_LINK
ARG DISALLOWED_IDS
ARG CDN_REPLACEMENTS
ARG TURNSTILE_KEY
ENV VITE_PWA_ENABLED=${PWA_ENABLED}
ENV VITE_GA_ID=${GA_ID}
ENV VITE_APP_DOMAIN=${APP_DOMAIN}
ENV VITE_OPENSEARCH_ENABLED=${OPENSEARCH_ENABLED}
ENV VITE_TMDB_READ_API_KEY=${TMDB_READ_API_KEY}
ENV VITE_CORS_PROXY_URL=${CORS_PROXY_URL}
ENV VITE_DMCA_EMAIL=${DMCA_EMAIL}
ENV VITE_NORMAL_ROUTER=${NORMAL_ROUTER}
ENV VITE_BACKEND_URL=${BACKEND_URL}
ENV VITE_HAS_ONBOARDING=${HAS_ONBOARDING}
ENV VITE_ONBOARDING_CHROME_EXTENSION_INSTALL_LINK=${ONBOARDING_CHROME_EXTENSION_INSTALL_LINK}
ENV VITE_ONBOARDING_PROXY_INSTALL_LINK=${ONBOARDING_PROXY_INSTALL_LINK}
ENV VITE_DISALLOWED_IDS=${DISALLOWED_IDS}
ENV VITE_CDN_REPLACEMENTS=${CDN_REPLACEMENTS}
ENV VITE_TURNSTILE_KEY=${TURNSTILE_KEY}
COPY . ./
RUN pnpm run build

View File

@@ -4,13 +4,13 @@
<p align="center">
<img src="https://skillicons.dev/icons?i=react,vite,ts" />
<br/>
<a href="https://discord.movie-web.app"><kbd>🔵 discord</kbd></a> <a href="https://movie-web.app"><kbd>🟢 website</kbd></a>
<a href="https://movie-web.github.io/links/discord"><kbd>🔵 discord</kbd></a> <a href="https://movie-web.github.io/docs"><kbd>🟢 docs</kbd></a>
</p>
<br/><br/>
# ⚡What is movie-web?
movie-web is a web app for watching movies easily. Check it out at <a href="https://movie-web.app"><kbd>movie-web.app</kbd></a>.
movie-web is a web app for watching movies easily.
This service works by displaying video files from third-party providers inside an intuitive and aesthetic user interface.
@@ -57,7 +57,7 @@ pnpm build
A simple guide has been written to assist in hosting your own instance of movie-web. Check it out below
|[Selfhosting guide](https://docs.movie-web.app)|
|[Selfhosting guide](https://movie-web.github.io/docs)|
|---|
## 🤝 Thanks to all Contributors

26
docker-compose.yaml Normal file
View File

@@ -0,0 +1,26 @@
version: "3.8"
services:
movieweb:
build:
context: .
# args:
# PWA_ENABLED: "false"
# GA_ID: ""
# APP_DOMAIN: ""
# OPENSEARCH_ENABLED: "false"
# TMDB_READ_API_KEY: ""
# CORS_PROXY_URL: ""
# DMCA_EMAIL: ""
# NORMAL_ROUTER: "false"
# BACKEND_URL: ""
# HAS_ONBOARDING: "false"
# ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: ""
# ONBOARDING_PROXY_INSTALL_LINK: ""
# DISALLOWED_IDS: ""
# CDN_REPLACEMENTS: ""
# TURNSTILE_KEY: ""
ports:
- "80:80"
restart: unless-stopped

View File

@@ -1,8 +1,8 @@
{
"name": "movie-web",
"version": "4.4.1",
"version": "4.6.0",
"private": true,
"homepage": "https://movie-web.app",
"homepage": "https://github.com/movie-web/movie-web",
"scripts": {
"dev": "vite",
"build": "vite build",
@@ -29,7 +29,7 @@
"@formkit/auto-animate": "^0.8.1",
"@headlessui/react": "^1.7.17",
"@ladjs/country-language": "^1.0.3",
"@movie-web/providers": "^2.2.0",
"@movie-web/providers": "^2.2.2",
"@noble/hashes": "^1.3.3",
"@plasmohq/messaging": "^0.6.1",
"@react-spring/web": "^9.7.3",
@@ -123,7 +123,8 @@
"vite-plugin-package-version": "^1.1.0",
"vite-plugin-pwa": "^0.17.4",
"vite-plugin-static-copy": "^1.0.0",
"vitest": "^1.1.0"
"vitest": "^1.1.0",
"workbox-window": "^7.0.0"
},
"pnpm": {
"overrides": {

61
pnpm-lock.yaml generated
View File

@@ -22,8 +22,8 @@ dependencies:
specifier: ^1.0.3
version: 1.0.3
'@movie-web/providers':
specifier: ^2.2.0
version: 2.2.0
specifier: ^2.2.2
version: 2.2.2
'@noble/hashes':
specifier: ^1.3.3
version: 1.3.3
@@ -268,7 +268,7 @@ devDependencies:
version: 0.5.9(prettier@3.1.1)
rollup-plugin-visualizer:
specifier: ^5.11.0
version: 5.11.0(@rollup/wasm-node@4.10.0)
version: 5.11.0(@rollup/wasm-node@4.12.0)
tailwind-scrollbar:
specifier: ^3.0.5
version: 3.0.5(tailwindcss@3.4.0)
@@ -302,6 +302,9 @@ devDependencies:
vitest:
specifier: ^1.1.0
version: 1.1.0(@types/node@20.10.5)(jsdom@23.0.1)
workbox-window:
specifier: ^7.0.0
version: 7.0.0
packages:
@@ -1933,8 +1936,8 @@ packages:
engines: {node: '>= 14'}
dev: false
/@movie-web/providers@2.2.0:
resolution: {integrity: sha512-7rKUpLPklwOtS5P2CAeh0P3sPIuYvtkKIgm0kVMp+OsSpKd9IcuYm79bbDrA0MDi3IMGik1W6la9Mzy91+8uYQ==}
/@movie-web/providers@2.2.2:
resolution: {integrity: sha512-pTlErE5bdu+b68mUW2YAKOJKz2hwSx63auGAfTkGQ+0SHDMlCV9QQ8S8O9IoSsvdXps7/YlWJWOMX8pmKuYbPQ==}
dependencies:
cheerio: 1.0.0-rc.12
cookie: 0.6.0
@@ -2059,7 +2062,7 @@ packages:
engines: {node: '>=14.0.0'}
dev: false
/@rollup/plugin-babel@5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.10.0):
/@rollup/plugin-babel@5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.12.0):
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
engines: {node: '>= 10.0.0'}
peerDependencies:
@@ -2072,36 +2075,36 @@ packages:
dependencies:
'@babel/core': 7.23.6
'@babel/helper-module-imports': 7.22.15
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.10.0)
rollup: /@rollup/wasm-node@4.10.0
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.0)
rollup: /@rollup/wasm-node@4.12.0
dev: true
/@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.10.0):
/@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.12.0):
resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
engines: {node: '>= 10.0.0'}
peerDependencies:
rollup: npm:@rollup/wasm-node
dependencies:
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.10.0)
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.0)
'@types/resolve': 1.17.1
builtin-modules: 3.3.0
deepmerge: 4.3.1
is-module: 1.0.0
resolve: 1.22.4
rollup: /@rollup/wasm-node@4.10.0
rollup: /@rollup/wasm-node@4.12.0
dev: true
/@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.10.0):
/@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.12.0):
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
peerDependencies:
rollup: npm:@rollup/wasm-node
dependencies:
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.10.0)
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.0)
magic-string: 0.25.9
rollup: /@rollup/wasm-node@4.10.0
rollup: /@rollup/wasm-node@4.12.0
dev: true
/@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.10.0):
/@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.12.0):
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
engines: {node: '>= 8.0.0'}
peerDependencies:
@@ -2110,11 +2113,11 @@ packages:
'@types/estree': 0.0.39
estree-walker: 1.0.1
picomatch: 2.3.1
rollup: /@rollup/wasm-node@4.10.0
rollup: /@rollup/wasm-node@4.12.0
dev: true
/@rollup/wasm-node@4.10.0:
resolution: {integrity: sha512-wH/ih4T/iP2PUyTrkyioZqDoFY/gmu63LPLTOM5Q21gSB/D3Ejw3UBpUOMLt86fIbN3mV+wL45MyA71XAj1ytg==}
/@rollup/wasm-node@4.12.0:
resolution: {integrity: sha512-sqy3+YvV/uWX6bPZOR5PlEdH6xyMPXoelllRQ/uZ13tzy9f4pXZTbajnoWN8IHHXwTNKPiLzsePLiDEVmkxMNw==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
dependencies:
@@ -5098,7 +5101,7 @@ packages:
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.6)
'@babel/types': 7.23.6
kleur: 4.1.5
rollup: /@rollup/wasm-node@4.10.0
rollup: /@rollup/wasm-node@4.12.0
unplugin: 1.5.1
transitivePeerDependencies:
- supports-color
@@ -6026,7 +6029,7 @@ packages:
glob: 7.2.3
dev: true
/rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.10.0):
/rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.12.0):
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
peerDependencies:
@@ -6034,12 +6037,12 @@ packages:
dependencies:
'@babel/code-frame': 7.23.5
jest-worker: 26.6.2
rollup: /@rollup/wasm-node@4.10.0
rollup: /@rollup/wasm-node@4.12.0
serialize-javascript: 4.0.0
terser: 5.19.3
dev: true
/rollup-plugin-visualizer@5.11.0(@rollup/wasm-node@4.10.0):
/rollup-plugin-visualizer@5.11.0(@rollup/wasm-node@4.12.0):
resolution: {integrity: sha512-exM0Ms2SN3AgTzMeW7y46neZQcyLY7eKwWAop1ZoRTCZwyrIRdMMJ6JjToAJbML77X/9N8ZEpmXG4Z/Clb9k8g==}
engines: {node: '>=14'}
hasBin: true
@@ -6051,7 +6054,7 @@ packages:
dependencies:
open: 8.4.2
picomatch: 2.3.1
rollup: /@rollup/wasm-node@4.10.0
rollup: /@rollup/wasm-node@4.12.0
source-map: 0.7.4
yargs: 17.7.2
dev: true
@@ -7037,7 +7040,7 @@ packages:
'@types/node': 20.10.5
esbuild: 0.19.10
postcss: 8.4.32
rollup: /@rollup/wasm-node@4.10.0
rollup: /@rollup/wasm-node@4.12.0
optionalDependencies:
fsevents: 2.3.3
dev: true
@@ -7299,9 +7302,9 @@ packages:
'@babel/core': 7.23.6
'@babel/preset-env': 7.23.6(@babel/core@7.23.6)
'@babel/runtime': 7.23.6
'@rollup/plugin-babel': 5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.10.0)
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.10.0)
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.10.0)
'@rollup/plugin-babel': 5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.12.0)
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.12.0)
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.12.0)
'@surma/rollup-plugin-off-main-thread': 2.2.3
ajv: 8.12.0
common-tags: 1.8.2
@@ -7310,8 +7313,8 @@ packages:
glob: 7.2.3
lodash: 4.17.21
pretty-bytes: 5.6.0
rollup: /@rollup/wasm-node@4.10.0
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.10.0)
rollup: /@rollup/wasm-node@4.12.0
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.12.0)
source-map: 0.8.0-beta.0
stringify-object: 3.3.0
strip-comments: 2.0.1

View File

@@ -1,9 +1,10 @@
window.__CONFIG__ = {
// The URL for the CORS proxy, the URL must NOT end with a slash!
VITE_CORS_PROXY_URL: "CHANGEME",
// If not specified, the onboarding will not allow a "default setup". The user will have to use the extension or set up a proxy themselves
VITE_CORS_PROXY_URL: "",
// The READ API key to access TMDB
VITE_TMDB_READ_API_KEY: "CHANGEME",
VITE_TMDB_READ_API_KEY: "",
// The DMCA email displayed in the footer, null to hide the DMCA link
VITE_DMCA_EMAIL: null,
@@ -11,9 +12,9 @@ window.__CONFIG__ = {
// Whether to disable hash-based routing, leave this as false if you don't know what this is
VITE_NORMAL_ROUTER: false,
// The backend URL to communicate with, defaults to the movie-web hosted one at backend.movie-web.app
// The backend URL to communicate with
VITE_BACKEND_URL: null,
// A comma separated list of disallowed IDs in the case of a DMCA claim - in the format "series-<id>" and "movie-<id>"
VITE_DISALLOWED_IDS: ""
VITE_DISALLOWED_IDS: "",
};

View File

@@ -2,6 +2,7 @@ import ar from "@/assets/locales/ar.json";
import bg from "@/assets/locales/bg.json";
import bn from "@/assets/locales/bn.json";
import ca from "@/assets/locales/ca.json";
import caVl from "@/assets/locales/ca@valencia.json";
import cs from "@/assets/locales/cs.json";
import de from "@/assets/locales/de.json";
import el from "@/assets/locales/el.json";
@@ -46,6 +47,7 @@ import zh from "@/assets/locales/zh.json";
export const locales = {
en,
ca,
"ca-ES": caVl,
cs,
de,
fr,

View File

@@ -116,27 +116,24 @@
"failed": "تعذر العثور على الوسائط، حاول مجددا!",
"loading": "جار التحميل...",
"noResults": "لم نتمكن من العثور على أي شيء!",
"placeholder": "ماذا تريد أن تشاهد؟",
"placeholder": {
"default": "ماذا تريد أن تشاهد؟",
"extra": []
},
"sectionTitle": "نتائج البحث"
},
"titles": {
"day": {
"default": "ماذا تريد أن تشاهد في هذه الظهيرة؟",
"extra": [
"متشوق للمغامرة؟ قد يكون Jurassic Park خيارًا مثاليًا لك."
]
"extra": ["متشوق للمغامرة؟ قد يكون Jurassic Park خيارًا مثاليًا لك."]
},
"morning": {
"default": "ماذا تريد أن تشاهد في هذا الصباح؟",
"extra": [
"سمعت أن فلم \"Before Sunrise\" جيد"
]
"extra": ["سمعت أن فلم \"Before Sunrise\" جيد"]
},
"night": {
"default": "ماذا تريد أن تشاهد في هذه الليلة؟",
"extra": [
"مُرهَق؟ سمعت أن فيلم \"The Exorcist\" جيد."
]
"extra": ["مُرهَق؟ سمعت أن فيلم \"The Exorcist\" جيد."]
}
}
},

View File

@@ -115,7 +115,10 @@
"failed": "Неуспешно намиране на медия, опитайте отново!",
"loading": "Зареждане...",
"noResults": "Не успяхме да намерим нищо!",
"placeholder": "Какво искате да гледате?",
"placeholder": {
"default": "Какво искате да гледате?",
"extra": []
},
"sectionTitle": "Резултати от търсенето"
},
"titles": {
@@ -127,15 +130,11 @@
},
"morning": {
"default": "Какво бихте искали да гледате тази сутрин?",
"extra": [
"Чух, че Before Sunrise е добър"
]
"extra": ["Чух, че Before Sunrise е добър"]
},
"night": {
"default": "Какво бихте искали да гледате тази вечер?",
"extra": [
"Изморен? Чух, че Екзорсистът е добър."
]
"extra": ["Изморен? Чух, че Екзорсистът е добър."]
}
}
},

View File

@@ -115,27 +115,24 @@
"failed": "মিডিয়া খুঁজে পেতে ব্যর্থ, আবার চেষ্টা করুন!",
"loading": "লোড হচ্ছে..।",
"noResults": "আমরা কিছুই খুঁজে পাইনি!",
"placeholder": "আপনি কি দেখতে চান?",
"placeholder": {
"default": "আপনি কি দেখতে চান?",
"extra": []
},
"sectionTitle": "অনুসন্ধান ফলাফল"
},
"titles": {
"day": {
"default": "আপনি এই বিকেলে কি দেখতে চান?",
"extra": [
"দুঃসাহসিক বোধ করছেন? জুরাসিক পার্ক নিখুঁত পছন্দ হতে পারে।"
]
"extra": ["দুঃসাহসিক বোধ করছেন? জুরাসিক পার্ক নিখুঁত পছন্দ হতে পারে।"]
},
"morning": {
"default": "আপনি এই সকালে কি দেখতে চান?",
"extra": [
"শুনি সূর্যোদয়ের আগে ভালো"
]
"extra": ["শুনি সূর্যোদয়ের আগে ভালো"]
},
"night": {
"default": "আপনি আজ রাতে কি দেখতে চান?",
"extra": [
"ক্লান্ত? আমি শুনেছি দ্য এক্সরসিস্ট ভাল।"
]
"extra": ["ক্লান্ত? আমি শুনেছি দ্য এক্সরসিস্ট ভাল।"]
}
}
},

View File

@@ -3,7 +3,7 @@
"description": "movie-web és una aplicació web que cerca fluxos a internet. L'equip té com a objectiu un enfocament majoritàriament minimalista del consum de contingut.",
"faqTitle": "Preguntes freqüents",
"q1": {
"body": "movie-web no allotja cap contingut. Quan feu clic a alguna cosa per a mirar-la, es busca a Internet el contingut seleccionat (a la pantalla de càrrega i a la pestanya «Fonts de vídeo» podeu veure quina font utilitzeu). movie-web mai hi puja contingut, tot és a través d'aquest mecanisme de cerca.",
"body": "movie-web no allotja cap contingut. Quan feu clic a un contingut per a mirar-lo, es busca a Internet (a la pantalla de càrrega i a la pestanya «Fonts de vídeo» podeu veure quina font utilitzeu). movie-web mai hi puja contingut, tot és a través d'aquest mecanisme de cerca.",
"title": "D'on prové el contingut?"
},
"q2": {
@@ -57,6 +57,8 @@
},
"host": "Us esteu connectant a <0>{{hostname}}</0>. Confirmeu que hi confieu abans de crear un compte",
"no": "Torna",
"noHost": "El servidor no s'ha configurat, per tant, no es pot crear un compte",
"noHostTitle": "El servidor no està configurat!",
"title": "Confieu en aquest servidor?",
"yes": "Confie en aquest servidor"
},
@@ -95,6 +97,7 @@
"about": "Quant a",
"dmca": "DMCA",
"login": "Inicia sessió",
"onboarding": "Configura",
"pagetitle": "{{title}} - movie-web",
"register": "Registra",
"settings": "Configuració"
@@ -115,7 +118,15 @@
"failed": "No s'ha pogut trobar cap contingut, torneu-ho a provar!",
"loading": "S'està carregant…",
"noResults": "No hem pogut trobar res!",
"placeholder": "Què voleu mirar?",
"placeholder": {
"default": "Què voleu mirar?",
"extra": [
"Què voleu explorar?",
"Què hi ha a la vostra llista de seguiment?",
"Quina és la vostra pel·lícula preferida?",
"Quina és la vostra sèrie preferida?"
]
},
"sectionTitle": "Resultats de la cerca"
},
"titles": {
@@ -165,6 +176,69 @@
"message": "Hem mirat per tot arreu: davall de les papereres, a l'armari, darrere del servidor intermediari, però al remat no hem pogut trobar la pàgina que busqueu.",
"title": "No s'ha pogut trobar la pàgina"
},
"onboarding": {
"defaultConfirm": {
"cancel": "Cancel·la",
"confirm": "Usa la configuració per defecte",
"description": "La configuració per defecte no té els millors fluxos i pot ser insuportablement lenta.",
"title": "Segur?"
},
"extension": {
"back": "Torna",
"explainer": "Mitjançant l'extensió del navegador, podeu obtenir els millors fluxos que oferim. Amb només una simple instal·lació.",
"explainerIos": "Lamentablement, l'extensió del navegador no és compatible amb iOS, premeu <bold>Torna</bold> per a triar una altra opció.",
"extensionHelp": "Si heu instal·lat l'extensió, però no es detecta, <bold>obriu l'extensió al menú d'extensions del navegador</bold> i seguiu els passos en pantalla.",
"linkChrome": "Instal·la l'extensió de Chrome",
"linkFirefox": "Instal·la l'extensió de Firefox",
"notDetecting": "S'ha instal·lat a Chrome, però el lloc no el detecta? Proveu de recarregar la pàgina.",
"notDetectingAction": "Recarrega la pàgina",
"status": {
"disallowed": "L'extensió no està activada per a aquesta pàgina",
"disallowedAction": "Activa l'extensió",
"failed": "No s'ha pogut sol·licitar l'estat",
"loading": "Esperant que instal·leu l'extensió",
"outdated": "La versió de l'extensió és massa antiga",
"success": "L'extensió funciona com s'esperava!"
},
"submit": "Continua",
"title": "Comencem amb una extensió"
},
"proxy": {
"back": "Torna",
"explainer": "Amb el mètode del servidor intermediari, podeu obtenir fluxos d'alta qualitat fent un servidor intermediari propi.",
"input": {
"errorConnection": "No s'ha pogut connectar al servidor intermediari",
"errorInvalidUrl": "URL no vàlid",
"errorNotProxy": "S'esperava un servidor intermediari, però és un lloc web",
"label": "URL del servidor intermediari",
"placeholder": "https://"
},
"link": "Com fer un servidor intermediari",
"submit": "Envia el servidor intermediari",
"title": "Fem un nou servidor intermediari"
},
"start": {
"explainer": "Per a obtenir els millors fluxos possibles, haureu de triar quin mètode de transmissió voleu utilitzar.",
"options": {
"default": {
"text": "No vull fluxos de bona qualitat,<0 /> <1>utilitza la configuració per defecte</1>"
},
"extension": {
"action": "Instal·la l'extensió",
"description": "Instal·leu l'extensió del navegador i accediu a les millors fonts.",
"quality": "Millor qualitat",
"title": "Extensió del navegador"
},
"proxy": {
"action": "Configura el servidor intermediari",
"description": "Configureu un servidor intermediari en només 5 minuts i accediu a bones fonts.",
"quality": "Bona qualitat",
"title": "Servidor intermediari personalitzat"
}
},
"title": "Configurem el movie-web"
}
},
"overlays": {
"close": "Tanca"
},
@@ -178,10 +252,11 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Copia l'enllaç de la llista HLS",
"disclaimer": "Les baixades s'obtenen directament del proveïdor. movie-web no té control sobre com es proporcionen les baixades.",
"downloadSubtitle": "Baixa els subtítols actuals",
"downloadVideo": "Baixa el vídeo",
"hlsDisclaimer": "Les baixades s'obtenen directament del proveïdor. movie-web no té control sobre com es proporcionen les baixades. Tingueu en compte que esteu baixant una llista de reproducció HLS, destinada als usuaris familiaritzats amb la transmissió multimèdia avançada.",
"hlsDisclaimer": "Les baixades s'obtenen directament del proveïdor. movie-web no té control sobre com es proporcionen les baixades. <br /><br />Tingueu en compte que esteu baixant una llista de reproducció HLS, <bold>no es recomana baixar-la si no esteu familiaritzat amb formats de transmissió avançats</bold>. Proveu diferents fonts per a diferents formats.",
"onAndroid": {
"1": "Per a baixar-lo a Android, feu clic al botó de baixada i, a la pàgina nova, <bold>manteniu premut</bold> el vídeo i, a continuació, seleccioneu <bold>Desa</bold>.",
"shortTitle": "Baixa / Android",
@@ -262,6 +337,17 @@
"text": "No s'han pogut carregar les metadades de l'API, comproveu la connexió a Internet.",
"title": "No s'han pogut carregar les metadades de l'API"
},
"dmca": {
"badge": "Eliminat",
"text": "Aquest contingut ja no està disponible a causa d'un avís de retirada o d'una reclamació de drets d'autor.",
"title": "El contingut s'ha eliminat"
},
"extensionPermission": {
"badge": "Falta el permís",
"button": "Utilitza l'extensió",
"text": "Teniu l'extensió del navegador, però necessitem el vostre permís per a començar a utilitzar l'extensió.",
"title": "Configureu l'extensió"
},
"failed": {
"badge": "Ha fallat",
"homeButton": "Vés a l'inici",
@@ -393,16 +479,46 @@
"label": "Servidor personalitzat",
"urlLabel": "URL del servidor personalitzat"
},
"setup": {
"doSetup": "Configura",
"errorStatus": {
"description": "Sembla que heu de revisar un o més elements de la configuració.",
"title": "S'ha de revisar algun element"
},
"itemError": "Hi ha alguna cosa malament en la configuració. Torneu a fer la configuració per a solucionar-ho.",
"items": {
"default": "Configuració per defecte",
"extension": "Extensió",
"proxy": "Servidor personalitzat"
},
"redoSetup": "Reconfigura",
"successStatus": {
"description": "Tot està preparat perquè comenceu a mirar el vostre contingut preferit.",
"title": "Tot està configurat!"
},
"unsetStatus": {
"description": "Feu clic al botó de la dreta per a iniciar el procés de configuració.",
"title": "No heu fet la configuració"
}
},
"title": "Connexions",
"workers": {
"addButton": "Afig un «worker»",
"description": "Per fer funcionar l'aplicació, tot el trànsit s'encamina a través de servidors intermediaris. Activeu-ho si voleu portar els vostres propis «workers».<0>Instruccions.</0>",
"addButton": "Afegeix un «worker»",
"description": "Per fer funcionar l'aplicació, tot el trànsit s'encamina a través de servidors intermediaris. Activeu-ho si voleu portar els vostres propis «workers». <0>Instruccions.</0>",
"emptyState": "Encara no hi ha «workers», afegiu-ne un a continuació",
"label": "Utilitza «workers» intermediaris personalitzats",
"urlLabel": "URL dels «workers»",
"urlPlaceholder": "https://"
}
},
"preferences": {
"language": "Llengua de l'aplicació",
"languageDescription": "La llengua s'aplica a tota l'aplicació.",
"thumbnail": "Genera miniatures",
"thumbnailDescription": "Majoritàriament, els vídeos no tenen miniatures. Podeu activar aquesta opció per a generar-les sobre la marxa, però poden alentir el vídeo.",
"thumbnailLabel": "Genera miniatures",
"title": "Configuració"
},
"reset": "Restableix",
"save": "Desa",
"sidebar": {

View File

@@ -0,0 +1,547 @@
{
"about": {
"description": "movie-web és una aplicació web que cerca fluxos a internet. L'equip té com a objectiu un enfocament majoritàriament minimalista del consum de contingut.",
"faqTitle": "Preguntes freqüents",
"q1": {
"body": "movie-web no allotja cap contingut. Quan feu clic en un contingut per a mirar-lo, es busca a Internet (a la pantalla de càrrega i a la pestanya «Fonts de vídeo» podeu mirar quina font utilitzeu). movie-web mai puja contingut, tot és a través del mecanisme de cerca.",
"title": "D'on prové el contingut?"
},
"q2": {
"body": "No és possible sol·licitar un programa o una pel·lícula, movie-web no gestiona cap contingut. Tot el contingut es visualitza a través de fonts a internet.",
"title": "On puc sol·licitar un programa o una pel·lícula?"
},
"q3": {
"body": "Els resultats de cerca funcionen amb The Movie Database (TMDB) i es mostren independentment de si les nostres fonts realment tenen el contingut.",
"title": "Els resultats de la cerca mostren el programa o la pel·lícula, per què no puc reproduir-lo?"
},
"title": "Sobre movie-web"
},
"actions": {
"copied": "S'ha copiat",
"copy": "Copia"
},
"auth": {
"createAccount": "Encara no teniu un compte? <0>Creeu un compte.</0>",
"deviceNameLabel": "Nom del dispositiu",
"deviceNamePlaceholder": "Telèfon personal",
"generate": {
"description": "La frase de contrasenya actua com a nom d'usuari i contrasenya. Assegureu-vos de mantindre-la segura, ja que haureu d'introduir-la per a iniciar la sessió al vostre compte",
"next": "He desat la frase de contrasenya",
"passphraseFrameLabel": "Frase de contrasenya",
"title": "La vostra frase de contrasenya"
},
"hasAccount": "Ja teniu un compte? <0>Inicieu sessió ací.</0>",
"login": {
"description": "Introduïu la vostra frase de contrasenya per a iniciar sessió al vostre compte",
"deviceLengthError": "Introduïu un nom per al dispositiu",
"passphraseLabel": "Frase de contrasenya de 12 paraules",
"passphrasePlaceholder": "Frase de contrasenya",
"submit": "Inicia sessió",
"title": "Inicieu sessió al vostre compte",
"validationError": "Frase de contrasenya incorrecta o incompleta"
},
"register": {
"information": {
"color1": "Color de perfil 1",
"color2": "Color de perfil 2",
"header": "Introduïu un nom per al dispositiu i trieu els colors i la icona d'usuari que vulgueu",
"icon": "Icona d'usuari",
"next": "Següent",
"title": "Informació del compte"
}
},
"trust": {
"failed": {
"text": "L'heu configurada correctament?",
"title": "No s'ha pogut accedir al servidor"
},
"host": "Esteu connectant-vos a <0>{{hostname}}</0>. Confirmeu que hi confieu abans de crear un compte",
"no": "Torna",
"noHost": "El servidor no s'ha configurat, per tant, no es pot crear un compte",
"noHostTitle": "El servidor no està configurat!",
"title": "Confieu en este servidor?",
"yes": "Confie en este servidor"
},
"verify": {
"description": "Introduïu la vostra frase de contrasenya anterior per a confirmar que l'heu desat, i crear el compte",
"invalidData": "La data no és vàlida",
"noMatch": "La frase de contrasenya no coincideix",
"passphraseLabel": "Frase de contrasenya de 12 paraules",
"recaptchaFailed": "Ha fallat la validació de ReCaptcha",
"register": "Crea el compte",
"title": "Confirmeu la frase de contrasenya"
}
},
"errors": {
"badge": "S'ha trencat",
"details": "Detalls de l'error",
"reloadPage": "Recarrega la pàgina",
"showError": "Mostra els detalls de l'error",
"title": "Hem trobat un error!"
},
"footer": {
"legal": {
"disclaimer": "Avís d'exempció de responsabilitat",
"disclaimerText": "movie-web no allotja cap fitxer, només enllaça a serveis de tercers. Els problemes legals s'han d'abordar amb qui allotja i els proveïdors de fitxers. movie-web no es fa responsable del contingut mostrat pels proveïdors de vídeo."
},
"links": {
"discord": "Discord",
"dmca": "DMCA",
"github": "GitHub"
},
"tagline": "Mireu els vostres programes i pel·lícules preferits amb esta aplicació de codi obert de reproducció en temps real."
},
"global": {
"name": "movie-web",
"pages": {
"about": "Quant a",
"dmca": "DMCA",
"login": "Inicia sessió",
"onboarding": "Configura",
"pagetitle": "{{title}} - movie-web",
"register": "Registra",
"settings": "Configuració"
}
},
"home": {
"bookmarks": {
"sectionTitle": "Marcadors"
},
"continueWatching": {
"sectionTitle": "Continueu mirant"
},
"mediaList": {
"stopEditing": "Deixa d'editar"
},
"search": {
"allResults": "Això és tot el que tenim!",
"failed": "No s'ha pogut trobar cap contingut, torneu-ho a provar!",
"loading": "S'està carregant…",
"noResults": "No hem pogut trobar res!",
"placeholder": {
"default": "Què voleu mirar?",
"extra": [
"Què voleu explorar?",
"Què hi ha a la vostra llista de seguiment?",
"Quina és la vostra pel·lícula preferida?",
"Quina és la vostra sèrie preferida?"
]
},
"sectionTitle": "Resultats de la cerca"
},
"titles": {
"day": {
"default": "Què vos agradaria mirar esta vesprada?",
"extra": [
"Voleu aventura? Jurassic Park podria ser l'elecció perfecta."
]
},
"morning": {
"default": "Què vos agradaria mirar este matí?",
"extra": [
"He sentit que «Abans de l'alba» és bona"
]
},
"night": {
"default": "Què vos agradaria mirar esta nit?",
"extra": [
"Esteu cansat? He sentit que «L'exorcista» és bona."
]
}
}
},
"media": {
"episodeDisplay": "T{{season}} E{{episode}}",
"types": {
"movie": "Pel·lícula",
"show": "Sèrie/Programa"
}
},
"navigation": {
"banner": {
"offline": "Comproveu la connexió a internet"
},
"menu": {
"about": "Quant a nosaltres",
"donation": "Feu una donació",
"logout": "Tanca la sessió",
"register": "Sincronitza al núvol",
"settings": "Configuració",
"support": "Ajuda"
}
},
"notFound": {
"badge": "No s'ha trobat",
"goHome": "Torna a l'inici",
"message": "Hem mirat per tot arreu: davall de les papereres, a l'armari, darrere del servidor intermediari, però al remat no hem pogut trobar la pàgina que busqueu.",
"title": "No s'ha pogut trobar la pàgina"
},
"onboarding": {
"defaultConfirm": {
"cancel": "Cancel·la",
"confirm": "Usa la configuració per defecte",
"description": "La configuració per defecte no té els millors fluxos i pot ser insuportablement lenta.",
"title": "Segur?"
},
"extension": {
"back": "Torna",
"explainer": "Mitjançant l'extensió del navegador, podeu obtindre els millors fluxos que oferim. Amb només una simple instal·lació.",
"explainerIos": "Lamentablement, l'extensió del navegador no és compatible amb iOS, premeu <bold>Torna</bold> per a triar una altra opció.",
"extensionHelp": "Si heu instal·lat l'extensió, però no es detecta, <bold>obriu l'extensió al menú d'extensions del navegador</bold> i seguiu els passos en pantalla.",
"linkChrome": "Instal·la l'extensió de Chrome",
"linkFirefox": "Instal·la l'extensió de Firefox",
"notDetecting": "S'ha instal·lat a Chrome, però el lloc no el detecta? Proveu de recarregar la pàgina.",
"notDetectingAction": "Recarrega la pàgina",
"status": {
"disallowed": "L'extensió no està activada per a esta pàgina",
"disallowedAction": "Activa l'extensió",
"failed": "No s'ha pogut sol·licitar l'estat",
"loading": "Esperant que instal·leu l'extensió",
"outdated": "La versió de l'extensió és massa antiga",
"success": "L'extensió funciona com s'esperava!"
},
"submit": "Continua",
"title": "Comencem amb una extensió"
},
"proxy": {
"back": "Torna",
"explainer": "Amb el mètode del servidor intermediari, podeu obtindre fluxos d'alta qualitat fent un servidor intermediari propi.",
"input": {
"errorConnection": "No s'ha pogut connectar al servidor intermediari",
"errorInvalidUrl": "URL no vàlid",
"errorNotProxy": "S'esperava un servidor intermediari, però és un lloc web",
"label": "URL del servidor intermediari",
"placeholder": "https://"
},
"link": "Com fer un servidor intermediari",
"submit": "Envia el servidor intermediari",
"title": "Fem un nou servidor intermediari"
},
"start": {
"explainer": "Per a obtindre els millors fluxos possibles, haureu de triar quin mètode de transmissió voleu utilitzar.",
"options": {
"default": {
"text": "No vull fluxos de bona qualitat,<0 /> <1>utilitza la configuració per defecte</1>"
},
"extension": {
"action": "Instal·la l'extensió",
"description": "Instal·leu l'extensió del navegador i accediu a les millors fonts.",
"quality": "Millor qualitat",
"title": "Extensió del navegador"
},
"proxy": {
"action": "Configura el servidor intermediari",
"description": "Configureu un servidor intermediari en només 5 minuts i accediu a bones fonts.",
"quality": "Bona qualitat",
"title": "Servidor intermediari personalitzat"
}
},
"title": "Configurem el movie-web"
}
},
"overlays": {
"close": "Tanca"
},
"player": {
"back": {
"default": "Torna a l'inici",
"short": "Torna"
},
"casting": {
"enabled": "S'està emetent al dispositiu…"
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Copia l'enllaç de la llista HLS",
"disclaimer": "Les baixades s'obtenen directament del proveïdor. movie-web no té control sobre com es proporcionen les baixades.",
"downloadSubtitle": "Baixa els subtítols actuals",
"downloadVideo": "Baixa el vídeo",
"hlsDisclaimer": "Les baixades s'obtenen directament del proveïdor. movie-web no té control sobre com es proporcionen les baixades. <br /><br />Tingueu en compte que esteu baixant una llista de reproducció HLS, <bold>no es recomana baixar-la si no esteu familiaritzat amb formats de transmissió avançats</bold>. Proveu diferents fonts per a diferents formats.",
"onAndroid": {
"1": "Per a baixar-lo a Android, feu clic al botó de baixada i, a la pàgina nova, <bold>manteniu premut</bold> el vídeo i, a continuació, seleccioneu <bold>Desa</bold>.",
"shortTitle": "Baixa / Android",
"title": "Baixada a Android"
},
"onIos": {
"1": "Per a baixar a iOS, feu clic al botó de baixada i, a la pàgina nova, feu clic a <bold><ios_share /></bold> /> i, a continuació, <bold>Desa als Arxius <ios_files /></bold>.",
"shortTitle": "Baixa / iOS",
"title": "Baixada a iOS"
},
"onPc": {
"1": "En un PC, feu clic al botó de baixada i, a la pàgina nova, feu clic amb el botó dret al vídeo i seleccioneu <bold>Anomena i desa el vídeo</bold>",
"shortTitle": "Baixa / PC",
"title": "Baixada a un PC"
},
"title": "Baixa"
},
"episodes": {
"button": "Episodi",
"emptyState": "No hi ha episodis en esta temporada, torneu-ho a comprovar més tard!",
"episodeBadge": "E{{episode}}",
"loadingError": "Error en carregar la temporada",
"loadingList": "S'està carregant…",
"loadingTitle": "S'està carregant…",
"unairedEpisodes": "Un o més episodis d'esta temporada s'han desactivat perquè encara no s'han emés."
},
"playback": {
"speedLabel": "Velocitat de la reproducció",
"title": "Configuració de la reproducció"
},
"quality": {
"automaticLabel": "Qualitat automàtica",
"hint": "Podeu provar a <0>canviar la font</0> per a obtindre diferents opcions de qualitat.",
"iosNoQuality": "A causa de les limitacions definides per Apple, la selecció de qualitat no està disponible a iOS per a esta font. Podeu provar a <0>canviar a una altra font</0> per a obtindre diferents opcions de qualitat.",
"title": "Qualitat"
},
"settings": {
"downloadItem": "Baixa",
"enableSubtitles": "Activa els subtítols",
"experienceSection": "Experiència de visualització",
"playbackItem": "Configuració de la reproducció",
"qualityItem": "Qualitat",
"sourceItem": "Fonts de vídeo",
"subtitleItem": "Configuració dels subtítols",
"videoSection": "Configuració de vídeo"
},
"sources": {
"failed": {
"text": "S'ha produït un error en intentar trobar vídeos, proveu una font diferent.",
"title": "No s'ha pogut obtindre"
},
"noEmbeds": {
"text": "No hem pogut trobar cap incrustat, proveu una font diferent.",
"title": "No s'ha trobat cap incrustació"
},
"noStream": {
"text": "esta font no té fluxos per a esta pel·lícula o programa.",
"title": "Cap flux"
},
"title": "Fonts",
"unknownOption": "Desconeguda"
},
"subtitles": {
"customChoice": "Selecciona un fitxer de subtítols",
"customizeLabel": "Personalitza",
"offChoice": "Desactivats",
"settings": {
"backlink": "Subtítols personalitzats",
"delay": "Retard dels subtítols",
"fixCapitals": "Corregeix les majúscules/minúscules"
},
"title": "Subtítols",
"unknownLanguage": "Desconeguda"
}
},
"metadata": {
"api": {
"text": "No s'han pogut carregar les metadades de l'API, comproveu la connexió a Internet.",
"title": "No s'han pogut carregar les metadades de l'API"
},
"dmca": {
"badge": "Eliminat",
"text": "este contingut ja no està disponible a causa d'un avís de retirada o d'una reclamació de drets d'autor.",
"title": "El contingut s'ha eliminat"
},
"extensionPermission": {
"badge": "Falta el permís",
"button": "Utilitza l'extensió",
"text": "Teniu l'extensió del navegador, però necessitem el vostre permís per a començar a utilitzar l'extensió.",
"title": "Configureu l'extensió"
},
"failed": {
"badge": "Ha fallat",
"homeButton": "Vés a l'inici",
"text": "No s'han pogut carregar les metadades del contingut des de TMDB. Comproveu si TMDB no funciona o està bloquejat a la vostra connexió a Internet.",
"title": "Ha fallat la càrrega de les metadades"
},
"notFound": {
"badge": "No s'ha trobat",
"homeButton": "Torna a l'inici",
"text": "No hem pogut trobar el contingut sol·licitat. O bé s'ha eliminat o bé heu alterat l'URL.",
"title": "No s'ha trobat el contingut."
}
},
"nextEpisode": {
"cancel": "Cancel·la",
"next": "Episodi següent"
},
"playbackError": {
"badge": "Error en la reproducció",
"errors": {
"errorAborted": "S'ha interromput l'obtenció del contingut per petició de l'usuari.",
"errorDecode": "Tot i haver-se determinat prèviament que era utilitzable, s'ha produït un error en intentar descodificar el recurs multimèdia.",
"errorGenericMedia": "S'ha produït un error desconegut al contingut.",
"errorNetwork": "S'ha produït algun tipus d'error de xarxa que ha impedit que el contingut s'obtinga correctament, tot i haver estat disponibles prèviament.",
"errorNotSupported": "El contingut o el proveïdor del contingut no és compatible."
},
"homeButton": "Torna a l'inici",
"text": "S'ha produït un error en intentar reproduir el contingut. Torneu-ho a provar.",
"title": "No s'ha pogut reproduir el vídeo!"
},
"scraping": {
"items": {
"failure": "S'ha produït un error",
"notFound": "No té el vídeo",
"pending": "S'estan cercant vídeos…"
},
"notFound": {
"badge": "No s'ha trobat",
"detailsButton": "Mostra els detalls",
"homeButton": "Torna a l'inici",
"text": "Hem buscat a través dels nostres proveïdors i no trobem el contingut que busqueu! No allotgem contingut i no tenim control sobre què hi ha disponible. Feu clic a «Mostra els detalls» a continuació per a més informació.",
"title": "No s'ha pogut trobar"
}
},
"time": {
"regular": "{{timeWatched}} / {{duration}}",
"remaining": "{{timeLeft}} restants • Acaba a les {{timeFinished, datetime}}",
"shortRegular": "{{timeWatched}}",
"shortRemaining": "-{{timeLeft}}"
},
"turnstile": {
"description": "Verifiqueu que sou humà completant el Captcha de la dreta. Ho fem per a mantindre segura movie-web!",
"error": "No s'ha pogut verificar la humanitat. Torneu-ho a provar.",
"title": "Necessitem verificar que sou humà.",
"verifyingHumanity": "Verificant la vostra humanitat…"
}
},
"screens": {
"dmca": {
"text": "Vos donem la benvinguda a la pàgina de contacte DMCA de movie-web! Respectem els drets de propietat intel·lectual i volem resoldre qualsevol problema de drets d'autor ràpidament. Si creieu que la vostra obra protegida per drets d'autor s'ha utilitzat incorrectament a la nostra plataforma, envieu un avís detallat de la DMCA al correu electrònic següent. Incloeu una descripció del material protegit per drets d'autor, les vostres dades de contacte i una declaració de creença de bona fe. Ens comprometem a resoldre estes assumptes amb agilitat i agraïm la vostra col·laboració per a mantindre movie-web en un lloc que respecta la creativitat i els drets d'autor.",
"title": "DMCA"
},
"loadingApp": "S'està carregant l'aplicació",
"loadingUser": "S'està carregant el perfil",
"loadingUserError": {
"logout": "Tanca la sessió",
"reset": "Restableix el servidor personalitzat",
"text": "Ha fallat la càrrega del perfil",
"textWithReset": "Error en carregar el vostre perfil des del servidor personalitzat, voleu restablir el servidor per defecte?"
},
"migration": {
"failed": "La migració de les dades ha fallat.",
"inProgress": "Espereu, estem migrant les vostres dades. No hauria de tardar massa."
}
},
"settings": {
"account": {
"accountDetails": {
"deviceNameLabel": "Nom del dispositiu",
"deviceNamePlaceholder": "Telèfon personal",
"editProfile": "Edita",
"logoutButton": "Tanca la sessió"
},
"actions": {
"delete": {
"button": "Elimina el compte",
"confirmButton": "Elimina el compte",
"confirmDescription": "Segur que voleu eliminar el compte? Es perdran totes les dades!",
"confirmTitle": "Segur?",
"text": "Esta acció és irreversible. Totes les dades s'eliminaran i no es podrà recuperar res.",
"title": "Elimina el compte"
},
"title": "Accions"
},
"devices": {
"deviceNameLabel": "Nom del dispositiu",
"failed": "La càrrega de sessions ha fallat",
"removeDevice": "Elimina",
"title": "Dispositiu"
},
"profile": {
"finish": "Finalitza l'edició",
"firstColor": "Color de perfil 1",
"secondColor": "Color de perfil dos",
"title": "Edita la foto de perfil",
"userIcon": "Icona d'usuari"
},
"register": {
"cta": "Comença",
"text": "Compartiu el progrés de la visualització entre dispositius i manteniu-los sincronitzats.",
"title": "Sincronització amb el núvol"
},
"title": "Compte"
},
"appearance": {
"activeTheme": "Actiu",
"themes": {
"blue": "Blau",
"default": "Per defecte",
"gray": "Gris",
"red": "Vermell",
"teal": "Verd blavós"
},
"title": "Aparença"
},
"connections": {
"server": {
"description": "Si voleu connectar-vos a un rerefons personalitzat per a emmagatzemar les vostres dades, activeu-ho i proporcioneu l'URL. <0>Instruccions.</0>",
"label": "Servidor personalitzat",
"urlLabel": "URL del servidor personalitzat"
},
"setup": {
"doSetup": "Configura",
"errorStatus": {
"description": "Sembla que heu de revisar un o més elements de la configuració.",
"title": "S'ha de revisar algun element"
},
"itemError": "Hi ha alguna cosa malament en la configuració. Torneu a fer la configuració per a solucionar-ho.",
"items": {
"default": "Configuració per defecte",
"extension": "Extensió",
"proxy": "Servidor personalitzat"
},
"redoSetup": "Reconfigura",
"successStatus": {
"description": "Tot està preparat perquè comenceu a mirar el vostre contingut preferit.",
"title": "Tot està configurat!"
},
"unsetStatus": {
"description": "Feu clic al botó de la dreta per a iniciar el procés de configuració.",
"title": "No heu fet la configuració"
}
},
"title": "Connexions",
"workers": {
"addButton": "Afig un «worker»",
"description": "Per fer funcionar l'aplicació, tot el trànsit s'encamina a través de servidors intermediaris. Activeu-ho si voleu portar els vostres propis «workers». <0>Instruccions.</0>",
"emptyState": "Encara no hi ha «workers», afegiu-ne un a continuació",
"label": "Utilitza «workers» intermediaris personalitzats",
"urlLabel": "URL dels «workers»",
"urlPlaceholder": "https://"
}
},
"preferences": {
"language": "Llengua de l'aplicació",
"languageDescription": "La llengua s'aplica a tota l'aplicació.",
"thumbnail": "Genera miniatures",
"thumbnailDescription": "Majoritàriament, els vídeos no tenen miniatures. Podeu activar esta opció per a generar-les sobre la marxa, però poden alentir el vídeo.",
"thumbnailLabel": "Genera miniatures",
"title": "Configuració"
},
"reset": "Restableix",
"save": "Desa",
"sidebar": {
"info": {
"appVersion": "Versió de l'aplicació",
"backendUrl": "URL del rerefons",
"backendVersion": "Versió del rerefons",
"hostname": "Nom de l'amfitrió",
"insecure": "Insegur",
"notLoggedIn": "No heu iniciat sessió",
"secure": "Segur",
"title": "Informació de l'aplicació",
"unknownVersion": "Desconeguda",
"userId": "ID d'usuari"
}
},
"subtitles": {
"backgroundLabel": "Opacitat del fons",
"colorLabel": "Color",
"previewQuote": "No he de tindre por. La por és l'assassina de la ment.",
"textSizeLabel": "Grandària del text",
"title": "Subtítols"
},
"unsaved": "Hi ha canvis sense desar"
}
}

View File

@@ -116,27 +116,24 @@
"failed": "Nepodařilo se najít média, zkuste to znovu!",
"loading": "Načítání...",
"noResults": "Nemohli jsme nic najít!",
"placeholder": "Co si přejete sledovat?",
"placeholder": {
"default": "Co si přejete sledovat?",
"extra": []
},
"sectionTitle": "Výsledky vyhledávání"
},
"titles": {
"day": {
"default": "Na co byste se chtěli dnes odpoledne dívat?",
"extra": [
"Chceš zažít dobrodružství? Jurský Park je pro tebe."
]
"extra": ["Chceš zažít dobrodružství? Jurský Park je pro tebe."]
},
"morning": {
"default": "Na co byste se chtěli dnes ráno dívat?",
"extra": [
"Slyšel jsem, že Před úsvitem je super."
]
"extra": ["Slyšel jsem, že Před úsvitem je super."]
},
"night": {
"default": "Na co byste se chtěli dnes večer dívat?",
"extra": [
"Unaven? Slyšel jsem, že Vymítač ďábla je super."
]
"extra": ["Unaven? Slyšel jsem, že Vymítač ďábla je super."]
}
}
},
@@ -177,6 +174,8 @@
"back": "Zpět",
"explainer": "Pomocí rozšíření prohlížeče můžete získat nejlepší streamy, které nabízíme. S pouhou instalací.",
"extensionHelp": "Pokud jste rozšíření nainstalovali, ale nebylo zjištěno. <bold>Otevřete rozšíření pomocí nabídky rozšíření ve vašem prohlížeči</bold> a postupujte podle pokynů na obrazovce.",
"linkChrome": "Instalovat rozšíření pro Chrome",
"linkFirefox": "Instalovat rozšíření pro Firefox",
"status": {
"disallowed": "Rozšíření není pro tuto stránku povoleno",
"disallowedAction": "Povolit rozšíření",

View File

@@ -116,7 +116,10 @@
"failed": "Das Medium wurde nicht gefunden, bitte versuchen Sie es erneut!",
"loading": "Wird geladen...",
"noResults": "Wir haben nichts gefunden!",
"placeholder": "Was möchtest du schauen?",
"placeholder": {
"default": "Was möchtest du schauen?",
"extra": []
},
"sectionTitle": "Suchergebnisse"
},
"titles": {
@@ -128,15 +131,11 @@
},
"morning": {
"default": "Was würdest du diesen Morgen gerne schauen?",
"extra": [
"Before Sunrise soll gut sein"
]
"extra": ["Before Sunrise soll gut sein"]
},
"night": {
"default": "Was möchtest du diesen Abend gerne schauen?",
"extra": [
"Müde? Ich hab gehört The Exorcist soll gut sein."
]
"extra": ["Müde? Ich hab gehört The Exorcist soll gut sein."]
}
}
},

View File

@@ -115,7 +115,10 @@
"failed": "Απέτυχε η εύρεση πολυμέσων, δοκιμάστε ξανά!",
"loading": "Φόρτωση...",
"noResults": "Δεν μπορέσαμε να βρούμε τίποτα!",
"placeholder": "Τι θέλετε να παρακολουθήσετε;",
"placeholder": {
"default": "Τι θέλετε να παρακολουθήσετε;",
"extra": []
},
"sectionTitle": "Αποτελέσματα αναζήτησης"
},
"titles": {
@@ -127,15 +130,11 @@
},
"morning": {
"default": "Τι θα θέλατε να παρακολουθήσετε σήμερα το πρωί;",
"extra": [
"Έχω ακούσει ότι το Before Sunrise είναι καλό"
]
"extra": ["Έχω ακούσει ότι το Before Sunrise είναι καλό"]
},
"night": {
"default": "Τι θα θέλατε να παρακολουθήσετε απόψε;",
"extra": [
"Κούραση; Έχω ακούσει ότι ο Εξορκιστής είναι καλός."
]
"extra": ["Κούραση; Έχω ακούσει ότι ο Εξορκιστής είναι καλός."]
}
}
},

View File

@@ -55,6 +55,8 @@
"text": "Did you configure it correctly?",
"title": "Failed to reach server"
},
"noHostTitle": "Server not configured!",
"noHost": "The server has not been configured, therefore you cannot create an account",
"host": "You are connecting to <0>{{hostname}}</0> - please confirm you trust it before making an account",
"no": "Go back",
"title": "Do you trust this server?",
@@ -116,7 +118,15 @@
"failed": "Failed to find media, try again!",
"loading": "Loading...",
"noResults": "We couldn't find anything!",
"placeholder": "What do you want to watch?",
"placeholder": {
"default": "What do you want to watch?",
"extra": [
"What do you want to explore?",
"What's on your watchlist?",
"What's your favorite movie?",
"What's your favorite series?"
]
},
"sectionTitle": "Search results"
},
"titles": {
@@ -523,6 +533,7 @@
},
"subtitles": {
"backgroundLabel": "Background opacity",
"backgroundBlurLabel": "Background blur",
"colorLabel": "Color",
"previewQuote": "I must not fear. Fear is the mind-killer.",
"textSizeLabel": "Text size",

View File

@@ -12,7 +12,7 @@
},
"q3": {
"body": "Nuestros resultados de búsqueda están alimentados por The Movie Database (TMDB) y se muestran independientemente de si nuestras fuentes realmente tienen el contenido.",
"title": "Los resultados de búsqueda muestran la serie o película, ¿por qué no puedo reproducirla?"
"title": "Los resultados de búsqueda muestran la serie o película, ¿Por qué no puedo reproducirla?"
},
"title": "Acerca de movie-web"
},
@@ -57,6 +57,8 @@
},
"host": "Te estás conectando a <0>{{hostname}}</0> - por favor, confirma si confías en este antes de crear una cuenta",
"no": "Regresar",
"noHost": "El servidor no se ha configurado, por lo tanto, no puede crear una cuenta",
"noHostTitle": "¡El servidor no está configurado!",
"title": "¿Confías en este servidor?",
"yes": "Confío en este servidor"
},
@@ -116,7 +118,15 @@
"failed": "¡Error al encontrar contenido, inténtalo de nuevo!",
"loading": "Cargando...",
"noResults": "¡No pudimos encontrar nada!",
"placeholder": "¿Qué te gustaría ver?",
"placeholder": {
"default": "¿Qué te gustaría ver?",
"extra": [
"¿Qué quieres explorar?",
"¿Qué hay en tu lista de reproducción?",
"¿Cuál es tu película favorita?",
"¿Cuál es tu serie favorita?"
]
},
"sectionTitle": "Resultados de búsqueda"
},
"titles": {
@@ -171,7 +181,7 @@
"cancel": "Cancelar",
"confirm": "Usar configuración por defecto",
"description": "La configuración predeterminada no tiene las mejores transmisiones y puede ser insoportablemente lenta.",
"title": "Estás seguro?"
"title": "¿Estás seguro?"
},
"extension": {
"back": "Volver atrás",
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Copiar enlace de reproducción HLS",
"disclaimer": "Las descargas se realizan directamente desde el proveedor. movie-web no tiene control sobre cómo se proporcionan las descargas.",
"downloadSubtitle": "Descargar subtítulo actual",
"downloadVideo": "Descargar vídeo",
@@ -388,7 +399,7 @@
"shortRemaining": "-{{timeLeft}}"
},
"turnstile": {
"description": "Por favor, confirma que eres humano completando el Captcha. Esto es para mantener movie-web seguro!",
"description": "Por favor, confirma que eres humano completando el Captcha. ¡Esto es para mantener movie-web seguro!",
"error": "Ha habido un error al verificar tu humanidad. Por favor, prueba de nuevo.",
"title": "Necesitamos verificar que eres humano.",
"verifyingHumanity": "Verificando tu hunanidad…"
@@ -483,7 +494,7 @@
"redoSetup": "Rehacer configuración",
"successStatus": {
"description": "Todo lo necesario está en su sitio para que empieces a ver tu contenido favorito.",
"title": "Todo está configurado!"
"title": "¡Todo está configurado!"
},
"unsetStatus": {
"description": "Haga clic en el botón a la derecha para iniciar el proceso de configuración.",

View File

@@ -57,6 +57,8 @@
},
"host": "Ühendate <0>{{hostname}}</0> - enne konto tegemist kinnitage, et usaldate seda",
"no": "Tagasi",
"noHost": "Server ei ole konfigureeritud, seega ei saa kontot luua",
"noHostTitle": "Server ei ole konfigureeritud!",
"title": "Kas usaldate seda serverit?",
"yes": "Usaldan seda serverit"
},
@@ -116,7 +118,15 @@
"failed": "Meedia leidmine ebaõnnestus, proovige uuesti!",
"loading": "Laadimine....",
"noResults": "Me ei leidnud midagi!",
"placeholder": "Mida tahate vaadata?",
"placeholder": {
"default": "Mida tahate vaadata?",
"extra": [
"Mida soovite uurida?",
"Mis on teie nimekirjas?",
"Milline on teie lemmikfilm?",
"Milline on teie lemmiksari?"
]
},
"sectionTitle": "Otsingutulemused"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Kopeeri HLS esitusloendi link",
"disclaimer": "Allalaadimine toimub otse teenusepakkujalt. movie-web ei saa kontrollida, kuidas allalaadimine toimub.",
"downloadSubtitle": "Laadige alla praegune subtiiter",
"downloadVideo": "Lae alla video",
@@ -525,6 +536,7 @@
}
},
"subtitles": {
"backgroundBlurLabel": "Tausta hägusus",
"backgroundLabel": "Tausta läbipaistmatus",
"colorLabel": "Värv",
"previewQuote": "Ma ei tohi karta. Hirm on meelemõrvar.",

View File

@@ -8,11 +8,11 @@
},
"q2": {
"body": "از آنجایی که محتوا ها توسط مووی-وب مدیریت نمی‌شوند، امکان درخواست فیلم وجود ندارد. تمام محتوا از طریق منابع در اینترنت به شما نشان داده می‌شوند.",
"title": "از کجا میتوانم درخواست فیلم کنم؟"
"title": "از کجا میتونم درخواست فیلم کنم؟"
},
"q3": {
"body": "نتایج جستجوی ما توسط پایگاه داده فیلم (TMDB) تامین می‌شوند و نمایش داده می‌شوند، بدون اینکه مهم باشد که منابع ما واقعاً محتوا را داشته باشند یا خیر.",
"title": "نتایج جستجو وجود دارد، اما چرا فیلم پخش نمی‌شود؟"
"title": "جستجو همراه با نتیجه است، اما چرا فیلم پخش نمی‌شود؟"
},
"title": "درباره مووی-وب"
},
@@ -25,7 +25,7 @@
"deviceNameLabel": "نام دستگاه",
"deviceNamePlaceholder": "تلفن شخصی",
"generate": {
"description": "جمله امنیتی شما به عنوان نام کاربری و رمز عبور عمل می‌کند. آن را در جایی ذخیره کنید چون برای ورود به آن نیاز دارید",
"description": "عبارت عبور شما به عنوان نام کاربری و رمز عبور عمل می‌کند. آن را در جایی ذخیره کنید چون برای ورود به آن نیاز دارید",
"next": "عبارت عبور امنیتی خود را ذخیره کرده‌ام",
"passphraseFrameLabel": "عبارت عبور امنیتی",
"title": "عبارت عبور امنیتی شما"
@@ -34,7 +34,7 @@
"login": {
"description": "لطفاً عبارت عبور امنیتی خود را وارد کنید تا وارد حساب کاربری شوید",
"deviceLengthError": "لطفا نامی برای دستگاه انتخاب کنید",
"passphraseLabel": "جمله امنیتی 12 کلمه‌ای",
"passphraseLabel": "عبارت عبور 12 کلمه‌ای",
"passphrasePlaceholder": "عبارت عبور امنیتی",
"submit": "ورود",
"title": "ورود به حساب کاربری",
@@ -57,6 +57,8 @@
},
"host": "شما در حال اتصال به <0>{{hostname}}</0> هستید - لطفا قبل از ایجاد حساب کاربری خود از اعتماد به آن اطمینان حاصل کنید",
"no": "بازگشت",
"noHost": "سرور پیکربندی نشده، بنابرین نمیتوانید حسابی ایجاد کنید",
"noHostTitle": "سرور پیکر بندی نشده!",
"title": "آیا به این سرور اعتماد دارید؟",
"yes": "بله اعتماد دارم"
},
@@ -71,7 +73,7 @@
}
},
"errors": {
"badge": "مشکلی پیش آمده",
"badge": "مشکلی رخ داده",
"details": "جزئیات خطا",
"reloadPage": "صفحه را دوباره بارگذاری کنید",
"showError": "نمایش جزئیات خطا",
@@ -115,8 +117,16 @@
"allResults": "همه چیزی بود که داشتیم!",
"failed": "چیزی پیدا نشد، دوباره تلاش کنید!",
"loading": "در حال بارگذاری...",
"noResults": "چیزی پیدا نکردیم!",
"placeholder": "چه می‌خواهید تماشا کنید؟",
"noResults": "نتونستیم چیزی پیدا کنیم!",
"placeholder": {
"default": "چه می‌خواهید تماشا کنید؟",
"extra": [
"دنبال چی میگردی؟",
"چی تو لیست تماشات داری؟",
"فیلم مورد علاقت چیه؟",
"سریال مورد علاقت چیه؟"
]
},
"sectionTitle": "نتایج جستجو"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "لینک HLS لیست پخش را کپی کنید",
"disclaimer": "دانلود ها به طور مستقیم از ارائه دهنده گرفته می شوند. مووی-وب کنترلی بر نحوه ارائه دانلود ها ندارد.",
"downloadSubtitle": "دانلود زیرنویس فعلی",
"downloadVideo": "دانلود ویدیو",
@@ -464,7 +475,7 @@
},
"connections": {
"server": {
"description": "اگر میخواهید به یک بک-اند سفارشی برای ذخیره داده متصل شوید، با فعال و ارائه استفاده این لینک ادامه دهید. <0>دستورالعمل ها.</0>",
"description": "اگر میخواید به یک بک-اند سفارشی برای ذخیره داده متصل شوید، با فعال و ارائه استفاده این لینک ادامه دهید. <0>دستورالعمل ها.</0>",
"label": "سرور سفارشی",
"urlLabel": "لینک سرور سفارشی"
},
@@ -493,7 +504,7 @@
"title": "اتصالات",
"workers": {
"addButton": "اضافه کردن worker جدید",
"description": "برای ایجاد عملکرد برنامه، تمام ترافیک از طریق پروکسی ها هدایت می شود. اگر میخواهید این کار انجام دهید حتما از worker های خودتان استفاده کنید. <0>دستورالعمل ها.</0>",
"description": "برای ایجاد عملکرد برنامه، تمام ترافیک از طریق پروکسی ها هدایت می شود. اگر میخواید این کار انجام دهید حتما از worker های خودتان استفاده کنید. <0>دستورالعمل ها.</0>",
"emptyState": "هنوز هیچ worker ای وجود ندارد، یکی اضافه کنید",
"label": "استفاده از worker های پروکسی سفارشی",
"urlLabel": "لینک worker ها",

View File

@@ -116,7 +116,10 @@
"failed": "Mediaa ei löytynyt, yritä uudelleen!",
"loading": "Ladataan...",
"noResults": "Emme löytäneet mitään!",
"placeholder": "Mitä haluat katsoa?",
"placeholder": {
"default": "Mitä haluat katsoa?",
"extra": []
},
"sectionTitle": "Hakutulokset"
},
"titles": {
@@ -128,15 +131,11 @@
},
"morning": {
"default": "Mitä haluaisit katsoa tänä aamuna?",
"extra": [
"Kuulen, että Rakkautta ennen aamua (Before Sunrise) on hyvä"
]
"extra": ["Kuulen, että Rakkautta ennen aamua (Before Sunrise) on hyvä"]
},
"night": {
"default": "Mitä haluaisit katsoa tänä iltana?",
"extra": [
"Väsynyt? Kuulin, että Manaaja (The Exorcist) on hyvä."
]
"extra": ["Väsynyt? Kuulin, että Manaaja (The Exorcist) on hyvä."]
}
}
},

View File

@@ -7,12 +7,12 @@
"title": "D'où vient le contenu ?"
},
"q2": {
"body": "Il est impossible de solliciter une émission ou un film car movie-web ne gère aucun contenu. Les sources sur Internet sont utilisées pour consulter tous les contenus.",
"body": "Il est impossible de demander un film ou une série car movie-web ne gère aucun contenu. Le contenu est récupéré en explorant d'autres sites sur Internet.",
"title": "Où puis-je demander une série ou un film ?"
},
"q3": {
"body": "Que nos sources soient propriétaires du contenu ou non, The Movie Database (TMDB) fournit et affiche nos résultats de recherche.",
"title": "Les résultats de la recherche affichent l'émission ou le film, pourquoi ne puis-je pas le lire ?"
"body": "Nos résultats de recherche sont alimentés par The Movie Database (TMDB) et s'affichent indépendamment de la disponibilité réelle du contenu dans nos sources.",
"title": "Les résultats de la recherche affichent la série ou le film, pourquoi ne puis-je pas le lire ?"
},
"title": "À propos de movie-web"
},
@@ -27,27 +27,27 @@
"generate": {
"description": "Le nom d'utilisateur et le mot de passe sont obtenus à partir de votre passphrase. Vous devrez la saisir pour accéder à votre compte, alors gardez-la précieusement",
"next": "J'ai sauvegardé ma passphrase",
"passphraseFrameLabel": "Pass phrase",
"passphraseFrameLabel": "Passphrase",
"title": "Votre passphrase"
},
"hasAccount": "Avez-vous déjà un compte? <0>Connectez-vous ici.</0>",
"login": {
"description": "Veuillez fournir votre passphrase pour accéder à votre compte",
"description": "Veuillez saisir votre passphrase pour accéder à votre compte",
"deviceLengthError": "Veuillez saisir un nom d'appareil",
"passphraseLabel": "Passphrase de 12 mots",
"passphrasePlaceholder": "Phrase secrète",
"passphrasePlaceholder": "Passphrase",
"submit": "Se connecter",
"title": "Se connecter à votre compte",
"validationError": "Passphrase incorrecte ou incomplete"
"title": "Connectez-vous à votre compte",
"validationError": "Passphrase incorrecte ou incomplète"
},
"register": {
"information": {
"color1": "Couleur de profile un",
"color2": "Couleur de profile deux",
"header": "Entrez un nom pour votre appareil et choisissez une couleur de profile ainsi qu'une icône d'utilisateur de votre choix",
"color1": "Première couleur de profil",
"color2": "Seconde couleur de profil",
"header": "Veuillez entrer un nom pour votre appareil, choisir une couleur et une icône utilisateur de votre choix",
"icon": "Icône d'utilisateur",
"next": "Prochain",
"title": "Informations sur le compte"
"next": "Suivant",
"title": "Informations du compte"
}
},
"trust": {
@@ -55,7 +55,7 @@
"text": "L'avez-vous configuré correctement ?",
"title": "Échec de la connexion au serveur"
},
"host": "Vous vous connectez à <0>{{hostname}}</0> - veuillez confirmer que vous lui faites confiance avant de créer un compte",
"host": "Vous êtes en train de vous connecter à <0>{{hostname}}</0> - veuillez confirmer que vous lui faites confiance avant de créer un compte",
"no": "Retour",
"title": "Avez-vous confiance en ce serveur ?",
"yes": "Je fais confiance à ce serveur"
@@ -65,13 +65,13 @@
"invalidData": "Les données ne sont pas valides",
"noMatch": "La passphrase ne correspond pas",
"passphraseLabel": "Votre passphrase de 12 mots",
"recaptchaFailed": "La validation ReCaptcha a échoué",
"recaptchaFailed": "La validation ReCaptcha a échouée",
"register": "Créer un compte",
"title": "Confirmez votre passphrase"
"title": "Resaisissez votre passphrase"
}
},
"errors": {
"badge": "Il s'est cassé",
"badge": "Tout est cassé",
"details": "Détails de l'erreur",
"reloadPage": "Actualiser la page",
"showError": "Afficher les détails de l'erreur",
@@ -87,7 +87,7 @@
"dmca": "DMCA",
"github": "GitHub"
},
"tagline": "Cette application de streaming open source vous permet de regarder vos émissions et films préférés."
"tagline": "Regardez vos séries et films préférés avec cette application de streaming open source."
},
"global": {
"name": "movie-web",
@@ -95,7 +95,7 @@
"about": "À propos",
"dmca": "DMCA",
"login": "Se connecter",
"onboarding": "Setup",
"onboarding": "Mise en place",
"pagetitle": "{{title}} - movie-web",
"register": "Créer un compte",
"settings": "Paramètres"
@@ -106,7 +106,7 @@
"sectionTitle": "Favoris"
},
"continueWatching": {
"sectionTitle": "Continuer le visionnage"
"sectionTitle": "Reprendre la lecture"
},
"mediaList": {
"stopEditing": "Arrêter l'édition"
@@ -116,7 +116,9 @@
"failed": "Le média n'a pas été trouvé, veuillez réessayez!",
"loading": "Chargement...",
"noResults": "Nous n'avons rien trouvé!",
"placeholder": "Que voulez-vous voir?",
"placeholder": {
"default": "Que voulez-vous voir?"
},
"sectionTitle": "Résultats de la recherche"
},
"titles": {
@@ -162,21 +164,21 @@
},
"notFound": {
"badge": "Introuvable",
"goHome": "Retour à l'accueil",
"goHome": "Retourner à l'accueil",
"message": "Nous avons cherché partout : sous les poubelles, dans le placard, derrière le proxy, mais nous n'avons finalement pas trouvé la page que vous cherchez.",
"title": "Impossible de trouver cette page"
},
"onboarding": {
"defaultConfirm": {
"cancel": "Annuler",
"confirm": "Utiliser la configuration de départ",
"confirm": "Utiliser la configuration par défaut",
"description": "La configuration par défaut n'offre pas les meilleurs flux et peut être insupportablement lente.",
"title": "Es-tu sûr?"
"title": "Êtes-vous sûr ?"
},
"extension": {
"back": "Retour en arrière",
"back": "Revenir en arrière",
"explainer": "En utilisant l'extension de navigateur, vous pouvez obtenir les meilleurs flux que nous avons à offrir. Avec juste une simple installation.",
"explainerIos": "Malheureusement, l'extension web n'est pas prise en charge sur iOS, appuyez sur <bold> Retour en arrière </bold> pour choisir une autre option.",
"explainerIos": "Malheureusement, l'extension web n'est pas prise en charge sur iOS, appuyez sur <bold> Revenir en arrière </bold> pour choisir une autre option.",
"extensionHelp": "Si vous avez installé l'extension mais qu'elle n'est pas détectée, <bold>ouvrez l'extension via le menu des extensions de votre navigateur</bold> et suivez les étapes à l'écran.",
"linkChrome": "Installer l'extension Chrome",
"linkFirefox": "Installer l'extension Firefox",
@@ -186,7 +188,7 @@
"disallowed": "L'extension n'est pas activée pour cette page",
"disallowedAction": "Activer l'extension",
"failed": "Échec de la demande de statut",
"loading": "En attendant que vous installiez l'extension",
"loading": "En attente que vous installiez l'extension",
"outdated": "Version d'extension trop ancienne",
"success": "L'extension fonctionne comme prévu!"
},
@@ -194,7 +196,7 @@
"title": "Commençons par une extension"
},
"proxy": {
"back": "Retour en arrière",
"back": "Revenir en arrière",
"explainer": "Avec la méthode du proxy, vous pouvez obtenir des flux de bonne qualité en créant un proxy en libre-service.",
"input": {
"errorConnection": "Impossible de se connecter au proxy",
@@ -204,18 +206,18 @@
"placeholder": "https://"
},
"link": "Apprenez à créer un proxy",
"submit": "Soumettre le proxy",
"submit": "Valider le proxy",
"title": "Créons un nouveau proxy"
},
"start": {
"explainer": "Pour obtenir les meilleurs flux possibles, vous devrez choisir la méthode de streaming que vous souhaitez utiliser.",
"options": {
"default": {
"text": "Je ne veux pas de flux de bonne qualité,<0 /> <1>use the default setup</1>"
"text": "Je ne veux pas de flux de bonne qualité,<0 /> <1>Utiliser le flux par défaut</1>"
},
"extension": {
"action": "Installer l'extension",
"description": "Installez l'extension de navigateur et accédez aux meilleures sources.",
"description": "Installez l'extension pour navigateur et accédez aux meilleures sources.",
"quality": "Meilleur qualité",
"title": "Extension du navigateur"
},
@@ -226,7 +228,7 @@
"title": "Proxy personnalisé"
}
},
"title": "Commençons par vous configurer movie-web"
"title": "Commençons par configurer movie-web"
}
},
"overlays": {
@@ -234,14 +236,15 @@
},
"player": {
"back": {
"default": "Retour à la page d'accueil",
"default": "Revenir à la page d'accueil",
"short": "Retour"
},
"casting": {
"enabled": "Casting à l'appareil..."
"enabled": "Casting vers l'appareil..."
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Copier le lien de la playlist HLS",
"disclaimer": "Les téléchargements sont effectués directement par le fournisseur. movie-web n'a aucun contrôle sur la manière dont les téléchargements sont effectués.",
"downloadSubtitle": "Télécharger les sous-titres",
"downloadVideo": "Télécharger la vidéo",
@@ -265,9 +268,9 @@
},
"episodes": {
"button": "Épisodes",
"emptyState": "Il n'y a pas d'épisodes dans cette saison, revenez plus tard !",
"emptyState": "Cette saison ne contient aucun épisode, revenez plus tard !",
"episodeBadge": "E{{episode}}",
"loadingError": "Erreur de chargement de la saison",
"loadingError": "Erreur lors du chargement de la saison",
"loadingList": "Chargement...",
"loadingTitle": "Chargement...",
"unairedEpisodes": "Un ou plusieurs épisodes de cette saison ont été désactivés car ils n'ont pas encore été diffusés."
@@ -278,7 +281,7 @@
},
"quality": {
"automaticLabel": "Qualité automatique",
"hint": "Vous pouvez essayer de <0>changer de fournisseur</0> pour obtenir différentes options de qualité.",
"hint": "Vous pouvez essayer de <0>changer de source</0> pour obtenir différentes options de qualité.",
"iosNoQuality": "En raison des limitations définies par Apple, la sélection de la qualité n'est pas disponible sur iOS pour cette source. Vous pouvez essayer <0>de passer à une autre source</0> pour obtenir des options de qualité différentes.",
"title": "Qualité"
},
@@ -302,7 +305,7 @@
"title": "Pas d'embeds trouvés"
},
"noStream": {
"text": "Cette source n'a pas de flux pour ce film ou cette émission.",
"text": "Cette source n'a pas de flux pour ce film ou cette série.",
"title": "Pas de flux"
},
"title": "Sources",
@@ -345,7 +348,7 @@
},
"notFound": {
"badge": "Introuvable",
"homeButton": "Retour à l'accueil",
"homeButton": "Revenir à l'accueil",
"text": "Nous n'avons pas trouvé le média que vous avez demandé. Soit il a été supprimé, soit vous avez modifié l'URL.",
"title": "Impossible de trouver ce média."
}
@@ -363,7 +366,7 @@
"errorNetwork": "Une erreur de réseau s'est produite qui a empêché la récupération du média, bien qu'il ait été disponible auparavant.",
"errorNotSupported": "L'objet du media ou de la source du média n'est pas supporté."
},
"homeButton": "Retour à la maison",
"homeButton": "Revenir à l'accueil",
"text": "Une erreur s'est produite lors de la lecture du média. Veuillez réessayer.",
"title": "Oups, c'est coupé !"
},
@@ -376,7 +379,7 @@
"notFound": {
"badge": "Non trouvé",
"detailsButton": "Afficher les détails",
"homeButton": "Retour à la maison",
"homeButton": "Revenir à l'accueil",
"text": "Nous avons cherché parmi nos sources et n'avons pas trouvé les médias que vous recherchez ! Nous n'hébergeons pas les médias et n'avons aucun contrôle sur ce qui est disponible. Veuillez cliquer sur \"Afficher les détails\" ci-dessous pour plus d'informations.",
"title": "Nous n'avons pas trouvé cela"
}
@@ -408,7 +411,7 @@
"textWithReset": "Echec du chargement de votre profil à partir de votre serveur personnalisé, souhaitez-vous revenir au serveur par défaut ?"
},
"migration": {
"failed": "La migration de vos données a échoué.",
"failed": "La migration de vos données a échouée.",
"inProgress": "Veuillez patienter, nous sommes en train de migrer vos données. Cela ne devrait pas prendre longtemps."
}
},
@@ -434,18 +437,18 @@
"devices": {
"deviceNameLabel": "Nom de l'appareil",
"failed": "Échec du chargement des sessions",
"removeDevice": "Enlever",
"removeDevice": "Supprimer",
"title": "Appareils"
},
"profile": {
"finish": "Terminer l'édition",
"firstColor": "Couleur de profil un",
"secondColor": "Couleur de profil deux",
"title": "Éditer la photo de profil",
"firstColor": "Première couleur de profil",
"secondColor": "Seconde couleur de profil",
"title": "Modifier la photo de profil",
"userIcon": "Icône de l'utilisateur"
},
"register": {
"cta": "Commencer",
"cta": "Démarrer",
"text": "Partagez la progression de vos films et séries entre vos appareils et gardez-les synchronisés.",
"title": "Synchroniser au Cloud"
},
@@ -469,12 +472,12 @@
"urlLabel": "URL du serveur personnalisé"
},
"setup": {
"doSetup": "Faire la configuration",
"doSetup": "Configurer",
"errorStatus": {
"description": "Il semble qu'un ou plusieurs éléments de cette configuration nécessitent votre attention.",
"title": "Quelque chose nécessite votre attention"
},
"itemError": "Ce paramètre présente un problème. Résolvez le problème en redémarrant la configuration.",
"itemError": "Ce paramètre présente un problème. Résolvez le problème en recommençant la configuration.",
"items": {
"default": "Configuration par défaut",
"extension": "Extension",
@@ -487,7 +490,7 @@
},
"unsetStatus": {
"description": "Pour commencer le processus de configuration, veuillez cliquer sur le bouton à droite.",
"title": "Vous n'avez pas fait la configuration"
"title": "Vous n'avez pas encore effectué la configuration"
}
},
"title": "Connexions",
@@ -514,9 +517,9 @@
"info": {
"appVersion": "Version de l'application",
"backendUrl": "URL de Backend",
"backendVersion": "Version de la Backend",
"backendVersion": "Version du Backend",
"hostname": "Nom d'hôte",
"insecure": "Insécure",
"insecure": "Non sécurisé",
"notLoggedIn": "Vous n'êtes pas connecté",
"secure": "Sécurisé",
"title": "Informations sur l'application",

View File

@@ -116,7 +116,10 @@
"failed": "Error ao encontrar contido... intentao de novo!",
"loading": "Cargando...",
"noResults": "Non atopamos nada!",
"placeholder": "Que che gustaría ver?",
"placeholder": {
"default": "Que che gustaría ver?",
"extra": []
},
"sectionTitle": "Resultados da busca"
},
"titles": {
@@ -128,15 +131,11 @@
},
"morning": {
"default": "Que che gustaría ver esta mañá?",
"extra": [
"Escoitei que “Antes del amanecer” é boa"
]
"extra": ["Escoitei que “Antes del amanecer” é boa"]
},
"night": {
"default": "Que che gustaría ver esta noite?",
"extra": [
"Canso? Escoitei que “El Exorcista” é boa."
]
"extra": ["Canso? Escoitei que “El Exorcista” é boa."]
}
}
},

View File

@@ -116,21 +116,20 @@
"failed": "મીડિયા શોધવામાં નિષ્ફળ, ફરી પ્રયાસ કરો!",
"loading": "લોડ થાય છે...",
"noResults": "અમે કંઈપણ શોધી શક્યા નથી!",
"placeholder": "તમે શું જોવા માંગો છો?",
"placeholder": {
"default": "તમે શું જોવા માંગો છો?",
"extra": []
},
"sectionTitle": "શોધ પરિણામો"
},
"titles": {
"day": {
"default": "તમે આ બપોરે શું જોવા માંગો છો?",
"extra": [
"સાહસિક લાગે છે? જુરાસિક પાર્ક યોગ્ય પસંદગી હોઈ શકે છે."
]
"extra": ["સાહસિક લાગે છે? જુરાસિક પાર્ક યોગ્ય પસંદગી હોઈ શકે છે."]
},
"morning": {
"default": "તમે આ સવારે શું જોવા માંગો છો?",
"extra": [
"હું સાંભળું છું કે Before Sunrise સારું છે"
]
"extra": ["હું સાંભળું છું કે Before Sunrise સારું છે"]
},
"night": {
"default": "તમે આજે રાત્રે શું જોવા માંગો છો?",

View File

@@ -116,27 +116,24 @@
"failed": "לא הצלחנו למצוא מדיה, נסה שוב!",
"loading": "טוען...",
"noResults": "לא יכולנו למצוא כלום!",
"placeholder": "במה תרצה לצפות?",
"placeholder": {
"default": "במה תרצה לצפות?",
"extra": []
},
"sectionTitle": "תוצאות חיפוש"
},
"titles": {
"day": {
"default": "במה תרצה לצפות באחר צהריים זה?",
"extra": [
"מרגיש הרפתקני? פארק היורה עשוי להיות הבחירה המושלמת."
]
"extra": ["מרגיש הרפתקני? פארק היורה עשוי להיות הבחירה המושלמת."]
},
"morning": {
"default": "במה תרצה לצפות הבוקר?",
"extra": [
"שמעתי שלפני הזריחה זה סרט טוב"
]
"extra": ["שמעתי שלפני הזריחה זה סרט טוב"]
},
"night": {
"default": "במה תרצה לצפות הלילה?",
"extra": [
"רוצה לישון? הפיג'מות היא בחירה מצויינת."
]
"extra": ["רוצה לישון? הפיג'מות היא בחירה מצויינת."]
}
}
},

View File

@@ -57,6 +57,8 @@
},
"host": "आप <0>{{hostname}}</0> से कनेक्ट हो रहे हैं - खाता बनाने से पहले कृपया पुष्टि करें कि आप इस पर भरोसा करते हैं",
"no": "पीछे जाये",
"noHost": "सर्वर कॉन्फ़िगर नहीं किया गया है, इसलिए आप खाता नहीं बना सकते",
"noHostTitle": "सर्वर कॉन्फ़िगर नहीं है!",
"title": "क्या आपको इस सर्वर पर भरोसा है?",
"yes": "मुझे इस सर्वर पर भरोसा है"
},
@@ -116,7 +118,15 @@
"failed": "मीडिया ढूंढने में विफल, पुनः प्रयास करें!",
"loading": "लोड हो रहा है..।",
"noResults": "हमें कुछ नहीं मिला!",
"placeholder": "क्या देखना चाहते हो?",
"placeholder": {
"default": "क्या देखना चाहते हो?",
"extra": [
"आप क्या अन्वेषण करना चाहते हैं?",
"आपकी वॉचलिस्ट में क्या है?",
"आपकी पसंदीदा फिल्म कौनसी है?",
"आपकी पसंदीदा सीरीज़ कौन सी है?"
]
},
"sectionTitle": "खोज के परिणाम"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "HLS प्लेलिस्ट लिंक कॉपी करें",
"disclaimer": "डाउनलोड सीधे प्रदाता से लिए जाते हैं। मूवी-वेब का इस पर नियंत्रण नहीं है कि डाउनलोड कैसे प्रदान किए जाते हैं।",
"downloadSubtitle": "वर्तमान उपशीर्षक डाउनलोड करें",
"downloadVideo": "वीडियो डाउनलोड करें",

View File

@@ -115,7 +115,10 @@
"failed": "Gagal menemukan media, coba lagi!",
"loading": "Memuat...",
"noResults": "Kami tidak dapat menemukan apapun!",
"placeholder": "Apa yang ingin anda tonton?",
"placeholder": {
"default": "Apa yang ingin anda tonton?",
"extra": []
},
"sectionTitle": "Hasil pencarian"
},
"titles": {
@@ -127,15 +130,11 @@
},
"morning": {
"default": "Apa yang ingin anda tonton pagi ini?",
"extra": [
"Kayaknya film Before Sunrise bagus deh"
]
"extra": ["Kayaknya film Before Sunrise bagus deh"]
},
"night": {
"default": "Apa yang ingin anda tonton malam ini?",
"extra": [
"Capek? Katanya The Exocist rekomended."
]
"extra": ["Capek? Katanya The Exocist rekomended."]
}
}
},

View File

@@ -1,9 +1,9 @@
{
"about": {
"description": "movie-web er vefforrit sem leitar á netinu að straumum. Markmið liðsins er naumhyggju nálgun á að horfa á efni.",
"description": "movie-web er vefforrit sem leitar á netinu að streymum. Markmið liðsins er naumhyggju nálgun á að horfa á efni.",
"faqTitle": "Algengar spurningar",
"q1": {
"body": "movie-web hýsir ekki neitt efni. Þegar þú ýtir á eitthvað til að horfa á, leitað er á netinu fyrir það efni (Þú getur séð hvaða heimild við erum að nota á hleðslu skjánum og í 'myndbands heimildir' flipanum). Skrár eru aldrei settar in af movie-web, allt er í gegnum leitarvél.",
"body": "movie-web hýsir ekki neitt efni. Þegar þú ýtir á eitthvað til að horfa á, er leitað á netinu fyrir það efni (Þú getur séð hvaða heimild við erum að nota á hleðslu skjánum og í 'myndbands heimildir' flipanum). Skrár eru aldrei settar inn af movie-web, allt er í gegnum leitarvél.",
"title": "Hvaðan kemur efnið?"
},
"q2": {
@@ -11,7 +11,7 @@
"title": "Hvar get ég beðið um þætti eða myndir?"
},
"q3": {
"body": "Okkar leitar niðurstöður eru knúnar af The Movie Database (TMDB) og eru sýndar þótt að okkar heimildir hafa ekki efnið.",
"body": "Leitarniðurstöður okkar eru knúnar af The Movie Database (TMDB) og eru sýndar þótt að heimildir okkar hafa ekki efnið.",
"title": "Leitarniðurstöðurnar sýna þættina eða myndina, af hverju get ég ekki spilað það?"
},
"title": "Um movie-web"
@@ -57,6 +57,8 @@
},
"host": "Þú ert að tengjast við <0>{{hostname}}</0> - vinsamlegast staðfestu að þú treystir því áður en þú býrð til reikning",
"no": "Fara til baka",
"noHost": "Netjónninn hefur ekki verið stilltur, þess vegna getur þú ekki búið til reikning",
"noHostTitle": "Netþjónn ekki stilltur!",
"title": "Treystir þú þessum netþjóni?",
"yes": "Ég treysti þessum netþjóni"
},
@@ -82,13 +84,21 @@
"disclaimer": "Fyrirvari",
"disclaimerText": "movie-web hýsir engar skrár, það tengist eingöngu þjónustu þriðja aðila. Lagleg atriði ættu að vera rædd við skráarhýsinga og veitanda. movie-web er ekki ábyrg fyrir neinum skrám sýndar af myndbands veitöndum."
},
"links": {
"discord": "Discord",
"dmca": "DMCA",
"github": "GitHub"
},
"tagline": "Horfðu á uppáhalds þætti og myndirnar þínar með þessu opna hugbúnaða forriti."
},
"global": {
"name": "movie-web",
"pages": {
"about": "Um",
"dmca": "DMCA",
"login": "Skrá inn",
"onboarding": "Setja upp",
"pagetitle": "{{title}} - movie-web",
"register": "Skrá",
"settings": "Stillingar"
}
@@ -108,7 +118,15 @@
"failed": "Mostókst að finna miðil, reyndu aftur!",
"loading": "Hlaðið...",
"noResults": "Við gátum ekki fundið neitt!",
"placeholder": "Hvað viltu horfa á?",
"placeholder": {
"default": "Hvað viltu horfa á?",
"extra": [
"Hvað viltu kanna?",
"Hvað er á áhorfslistanum þínum?",
"Hvað er uppáhalds bíómyndin þín?",
"Hvað er uppáhalds þáttaröðin þín?"
]
},
"sectionTitle": "Leitar niðurstöður"
},
"titles": {
@@ -192,7 +210,8 @@
"errorConnection": "Gat ekki tengst umboð",
"errorInvalidUrl": "Ekki gildur hlekkur",
"errorNotProxy": "Bjóst við umboði en fékk heimasíðu",
"label": "Umboðs hlekkur"
"label": "Umboðs hlekkur",
"placeholder": "https://"
},
"link": "Lærðu hvernig þú býrð til umboð",
"submit": "Staðfesta umboð",
@@ -233,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Afrita HLS spilalista hlekk",
"disclaimer": "Niðurhalningar eru teknar beint frá heimildini. movie-web hefur engan kraft yfir hvernig niðurhalningarnar eru gefnar.",
"downloadSubtitle": "Hlaða niður nú verandi texta",
"downloadVideo": "Hlaða niður myndbandi",
@@ -373,7 +393,10 @@
}
},
"time": {
"remaining": "{{timeLeft}} er eftir • Þú klárar {{timeFinished, datetime}}"
"regular": "{{timeWatched}} / {{duration}}",
"remaining": "{{timeLeft}} er eftir • Þú klárar {{timeFinished, datetime}}",
"shortRegular": "{{timeWatched}}",
"shortRemaining": "-{{timeLeft}}"
},
"turnstile": {
"description": "Vinsamlegast sannreyndu að þú sért manneskja með því að klára Captcha-ið til hægri. Þetta er til þess að halda movie-web öruggu!",
@@ -384,7 +407,8 @@
},
"screens": {
"dmca": {
"text": "Velkomin á sambands síðu movie-web! Við virðum hugverkarétt og viljum ræða einhver höfundarréttar áhyggjur fljótt. Ef að þú trúir að höfundarréttur þíns verks hefur verið misnotaður á okkar síðu, vinsamlegast sentu ítarlega DMCA tilkynningu til netfangsing fyrir neðan þennan texta. Vinsamlegast láttu fylgja með lýsingu af höfundaréttavarna efninu, tengiliða upplýsingat þínar, og yfirlýsingu um góða trú. Við erum staðráðin í að leysa þessi mál tafarlaust og þökkum samstarf þitt við að halda movie-web stað sem virðir sköpunargáfu og höfundarrétt."
"text": "Velkomin á sambands síðu movie-web! Við virðum hugverkarétt og viljum ræða einhver höfundarréttar áhyggjur fljótt. Ef að þú trúir að höfundarréttur þíns verks hefur verið misnotaður á okkar síðu, vinsamlegast sentu ítarlega DMCA tilkynningu til netfangsing fyrir neðan þennan texta. Vinsamlegast láttu fylgja með lýsingu af höfundaréttavarna efninu, tengiliða upplýsingat þínar, og yfirlýsingu um góða trú. Við erum staðráðin í að leysa þessi mál tafarlaust og þökkum samstarf þitt við að halda movie-web stað sem virðir sköpunargáfu og höfundarrétt.",
"title": "DMCA"
},
"loadingApp": "Hlaðandi forriti",
"loadingUser": "Hlaðandi þínum reikningi",
@@ -483,7 +507,8 @@
"description": "Til að láta forritið virka, allri umboð er beint í gegnum umboð. Virktu þetta ef þú villt koma með þína eigin starfsmenn. <0>Leiðbeiningar.</0>",
"emptyState": "Engir starfsmenn komnir, bættu við einum fyir neðan þennan texta",
"label": "Notaðu sérsniðaða umboðs starfsmenn",
"urlLabel": "Starfsmanna hlekkir"
"urlLabel": "Starfsmanna hlekkir",
"urlPlaceholder": "https://"
}
},
"preferences": {

View File

@@ -1,6 +1,6 @@
{
"about": {
"description": "movie-web è un'applicazione web che cerca per gli stream sull'internet. Il team cerca di usare un approccio per lo più minimalista per usufruire del contenuto.",
"description": "movie-web è un'applicazione web che ricerca dei stream sull'internet. Il team cerca di usare un approccio prevalentemente minimalista per usufruire del contenuto.",
"faqTitle": "Domande comuni",
"q1": {
"body": "movie-web non ospita alcun contento. Quando clicci su qualcosa da guardare, movie-web cerca l'internet per media di vostra scelta (Sull schermata di caricamento e nell tab 'sorgenti video' si può vedere quale sorgente si sta utilizzando). I media non sono mai caricati da movie-web, tutto è attraverso questo meccanismo di ricerca.",
@@ -30,14 +30,14 @@
"passphraseFrameLabel": "Frase password",
"title": "La tua frase password"
},
"hasAccount": "Hai già un account? <0>Accedi </0>",
"hasAccount": "Hai già un account? <0>Accedi.</0>",
"login": {
"description": "Inserisci la tua frase password per accedere al proprio account",
"description": "Inserisci la tua frase password per accedere al vostro account",
"deviceLengthError": "Inserisci un nome per il dispositivo",
"passphraseLabel": "Frase password di 12 parole",
"passphrasePlaceholder": "Frase password",
"submit": "Accedi",
"title": "Accedi al proprio account",
"title": "Accedi al vostro account",
"validationError": "Frase password incompleta o sbagliata"
},
"register": {
@@ -57,11 +57,13 @@
},
"host": "Ti stai collegando a <0>{{hostname}}</0> - conferma la tua fiducia prima di creare un account",
"no": "Indietro",
"noHost": "Il server non è configurato, quindi non si può creare un account",
"noHostTitle": "Server non è configurato!",
"title": "Ti fidi di questo server?",
"yes": "Mi fido di questo server"
},
"verify": {
"description": "Inserisci il tuo frase password da prima per confermare che è salvato per creare il proprio account",
"description": "Inserisci il tuo frase password da prima per confermare che è salvato per creare un account",
"invalidData": "I dati non sono validi",
"noMatch": "Frase password non corrisponde",
"passphraseLabel": "La propria frase password di 12 parole",
@@ -116,7 +118,15 @@
"failed": "Impossibile trovare i media, riprova!",
"loading": "Caricamento...",
"noResults": "Non abbiamo trovato nulla!",
"placeholder": "Cosa vuoi guardare?",
"placeholder": {
"default": "Cosa vuoi guardare?",
"extra": [
"Cosa vorresti esplorare?",
"Cosa cè nella tua lista di guardare?",
"Cosè il vostro preferito film?",
"Cosè il vostro preferito serie?"
]
},
"sectionTitle": "Risultati della ricerca"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Copia link HLS playlist",
"disclaimer": "I download vengono effettuati direttamente dal provider. movie-web non ha il controllo sulle modalità di fornitura dei download.",
"downloadSubtitle": "Scarica sottotitolo attuale",
"downloadVideo": "Scarica video",
@@ -389,9 +400,9 @@
},
"turnstile": {
"description": "Verifica che siate umani completando il Captcha sulla destra. Questo serve a mantenere movie-web sicuro!",
"error": "Impossibile verificare il proprio umanità. Riprova.",
"error": "Impossibile verificare la vostra umanità. Riprova.",
"title": "Dobbiamo verificare che lei sia umano.",
"verifyingHumanity": "verificare il proprio umanità..."
"verifyingHumanity": "Verificare la vostra umanità..."
}
},
"screens": {
@@ -400,12 +411,12 @@
"title": "DMCA"
},
"loadingApp": "Caricamento dell'applicazione",
"loadingUser": "Caricamento del proprio profilo",
"loadingUser": "Caricamento del vostro profilo",
"loadingUserError": {
"logout": "Esci",
"reset": "Ripristino del server personalizzato",
"text": "Impossibile caricare il proprio profilo",
"textWithReset": "Impossibile caricare il proprio profile dal server personalizzato, vorresti ripristinare il server predefinito?"
"text": "Impossibile caricare il vostro profilo",
"textWithReset": "Impossibile caricare il vostro profile dal server personalizzato, vorresti ripristinare il server predefinito?"
},
"migration": {
"failed": "Impossible migrare i propri dati.",
@@ -424,7 +435,7 @@
"delete": {
"button": "Eliminare l'account",
"confirmButton": "Eliminare l'account",
"confirmDescription": "Sei sicuro che vuoi eliminare il proprio account? Tutti i dati propri andranno persi!",
"confirmDescription": "Sei sicuro che vuoi eliminare il vostro account? Tutti i dati andranno persi!",
"confirmTitle": "Sei sicuro?",
"text": "Questa azione è irreversibile. Tutti i propri dati verranno eliminati e non sarà possibile recuperare nulla.",
"title": "Eliminare l'account"

View File

@@ -76,7 +76,10 @@
"allResults": "それがすべてです!",
"loading": "読み込み中...",
"noResults": "見つかりませんでした!",
"placeholder": "どんな映画を見たい?",
"placeholder": {
"default": "どんな映画を見たい?",
"extra": []
},
"sectionTitle": "検索結果"
},
"titles": {

View File

@@ -57,6 +57,8 @@
},
"host": "<0>{{hostname}}</0>에 연결 중입니다 - 계정을 만들기 전에 신뢰하는지 확인해 주세요",
"no": "뒤로 가기",
"noHost": "서버가 구성되어 있지 않기 때문에 계정을 만들 수 없습니다",
"noHostTitle": "서버가 구성되지 않았습니다!",
"title": "이 서버를 신뢰하십니까?",
"yes": "네, 신뢰합니다"
},
@@ -116,7 +118,15 @@
"failed": "미디어 검색에 실패하였습니다, 다시 시도해주세요!",
"loading": "로딩...",
"noResults": "검색결과가 없습니다!",
"placeholder": "무엇을 보고 싶으신가요?",
"placeholder": {
"default": "무엇을 보고 싶으신가요?",
"extra": [
"무엇을 탐험하고 싶으신가요?",
null,
"당신이 가장 좋아하는 영화는?",
"당신이 가장 좋아하는 시리즈는?"
]
},
"sectionTitle": "검색 결과"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "HLS 플레이리스트 링크 복사하기",
"disclaimer": "다운로드는 제공업체에서 직접 가져옵니다. movie-web은 다운로드 제공 방식을 통제할 수 없습니다.",
"downloadSubtitle": "현재 자막 다운로드",
"downloadVideo": "영상 다운로드",

View File

@@ -114,7 +114,10 @@
"failed": "Neizdevās atrast multividi. Mēģiniet vēlreiz!",
"loading": "Lādejas...",
"noResults": "Mēs nevarējām neko atrast!",
"placeholder": "Ko tu gribi skatīties?",
"placeholder": {
"default": "Ko tu gribi skatīties?",
"extra": []
},
"sectionTitle": "Meklējuma rezultāti"
},
"titles": {
@@ -123,15 +126,11 @@
},
"morning": {
"default": "Ko tu gribētu šorīt noskatīties?",
"extra": [
"Es dzirdu, ka Pirms saullēkta ir labs"
]
"extra": ["Es dzirdu, ka Pirms saullēkta ir labs"]
},
"night": {
"default": "Ko tu gribētu šovakar skatīties?",
"extra": [
"Noguris? Es dzirdu, ka Exorcist ir labs."
]
"extra": ["Noguris? Es dzirdu, ka Exorcist ir labs."]
}
}
},

View File

@@ -115,7 +115,10 @@
"failed": "Failed to banana banana, try again!",
"loading": "Loading...",
"noResults": "We couldn't banana anything!",
"placeholder": "Banana do you want to banana?",
"placeholder": {
"default": "Banana do you want to banana?",
"extra": []
},
"sectionTitle": "Banana results"
},
"titles": {
@@ -127,15 +130,11 @@
},
"morning": {
"default": "What would you like to banana this banana?",
"extra": [
"Banana! I hear Banana Sunrise is banana"
]
"extra": ["Banana! I hear Banana Sunrise is banana"]
},
"night": {
"default": "What would you like to banana banana?",
"extra": [
"Banana? I hear The Banana is banana."
]
"extra": ["Banana? I hear The Banana is banana."]
}
}
},

View File

@@ -57,6 +57,8 @@
},
"host": "तपाइँ <0>{{hostname}}</0> मा कनेक्ट हुनुहुन्छ - कृपया खाता बनाउनु अघि तपाइँ यसलाई विश्वास गर्नुहुन्छ भनेर पुष्टि गर्नुहोस्",
"no": "पछाडी जाउ",
"noHost": "सर्भर कन्फिगर गरिएको छैन, त्यसैले तपाईंले खाता सिर्जना गर्न सक्नुहुन्न",
"noHostTitle": "सर्भर कन्फिगर गरिएको छैन!",
"title": "के तपाइँ यो सर्भरमा भरोसा गर्नुहुन्छ?",
"yes": "म यो सर्भरलाई भरोसा गर्छु"
},
@@ -79,6 +81,7 @@
},
"footer": {
"legal": {
"disclaimer": "अस्वीकरण",
"disclaimerText": "movie-webले कुनै पनि फाइलहरू होस्ट गर्दैन, यसले केवल तेस्रो पक्ष सेवाहरूमा लिङ्क गर्दछ। कानुनी मुद्दाहरू फाइल होस्ट र प्रदायकहरूसँग लिनु पर्छ। चलचित्र-वेब भिडियो प्रदायकहरू द्वारा देखाइएका कुनै पनि मिडिया फाइलहरूको लागि जिम्मेवार छैन।"
},
"links": {
@@ -115,7 +118,15 @@
"failed": "मिडिया फेला पार्न असफल भयो, फेरि प्रयास गर्नुहोस्!",
"loading": "लोड गर्दै...",
"noResults": "हामीले केहि फेला पार्न सकेनौं!",
"placeholder": "तपाईं के हेर्न चाहनुहुन्छ?",
"placeholder": {
"default": "तपाईं के हेर्न चाहनुहुन्छ?",
"extra": [
"तपाईं के खोज्न चाहनुहुन्छ?",
"तपाईको वाच लिस्टमा के छ?",
"तपाईलाई मन पर्ने चलचित्र कुन हो?",
"तपाईलाई मनपर्ने श्रृंखला कुन हो?"
]
},
"sectionTitle": "खोज परिणामहरू"
},
"titles": {
@@ -175,11 +186,11 @@
"extension": {
"back": "पछाडी जाउ",
"explainer": "ब्राउजर एक्सटेन्सन प्रयोग गरेर, तपाईंले हामीले प्रस्ताव गर्नु पर्ने उत्तम स्ट्रिमहरू प्राप्त गर्न सक्नुहुन्छ। केवल एक साधारण स्थापना संग।",
"explainerIos": "दुर्भाग्यवश, ब्राउजर एक्सटेन्सन IOS मा समर्थित छैन, अर्को विकल्प रोज्न <bold>Go back</bold> थिच्नुहोस्।",
"extensionHelp": "यदि तपाईंले एक्स्टेन्सन स्थापना गर्नुभएको छ तर यो पत्ता लागेको छैन <bold>तपाईंको ब्राउजर विस्तार मेनु मार्फत विस्तार खोल्नुहोस्</bold> र स्क्रिनमा चरणहरू पालना गर्नुहोस्।",
"explainerIos": "दुर्भाग्यवश, ब्राउजर एक्सटेन्सन iOS मा समर्थित छैन, अर्को विकल्प रोज्न <bold>Go back</bold> थिच्नुहोस्।",
"extensionHelp": "यदि तपाईंले एक्स्टेन्सन स्थापना गर्नुभएको छ तर यो पत्ता लागेको छैन, <bold>तपाईंको ब्राउजर विस्तार मेनु मार्फत विस्तार खोल्नुहोस्</bold> र स्क्रिनमा चरणहरू पालना गर्नुहोस्।",
"linkChrome": "क्रोम एक्सटेन्सन स्थापना गर्नुहोस्",
"linkFirefox": "फायरफक्स एक्सटेन्सन स्थापना गर्नुहोस्",
"notDetecting": "chrome मा स्थापित तर देखिदैन? पृष्ठ पुन: लोड गर्ने प्रयास गर्नुहोस्!",
"notDetecting": "Chrome मा स्थापित भयो तर देखिदैन? पृष्ठ पुन: लोड गर्ने प्रयास गर्नुहोस्!",
"notDetectingAction": "पृष्ठ पुन: लोड गर्नुहोस्",
"status": {
"disallowed": "यो पेजको लागि एक्सटेन्सन सक्षम गरिएको छैन",
@@ -207,7 +218,7 @@
"title": "एउटा नयाँ प्रोक्सी बनाऔं"
},
"start": {
"explainer": "सम्भावित उत्तम स्ट्रिमहरू प्राप्त गर्न, तपाईंले कुन स्ट्रिमिङ विधि प्रयोग गर्न चाहनुहुन्छ भनेर छनौट गर्न आवश्यक हुनेछ।",
"explainer": "सम्भावित उत्तम स्ट्रिमहरू प्राप्त गर्न, तपाईंले कुन स्ट्रिमिङ विधि प्रयोग गर्न चाहनुहुन्छ भनेर छनौट गर्न आवश्यक हुनेछ।",
"options": {
"default": {
"text": "मलाई राम्रो गुणस्तरका स्ट्रिमहरू चाहिँदैन,<0 /> <1>पूर्वनिर्धारित सेटअप प्रयोग गर्नुहोस्</1>"
@@ -241,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "HLS प्लेलिस्ट लिङ्क कपि गर्नुहोस्",
"disclaimer": "डाउनलोडहरू सीधा प्रदायकबाट लिइन्छ। movie-web ले डाउनलोडहरू कसरी प्रदान गरिन्छ भन्नेमा नियन्त्रण गर्दैन।",
"downloadSubtitle": "हालको उपशीर्षक डाउनलोड गर्नुहोस्",
"downloadVideo": "डाउनलोड भिडियो",

View File

@@ -57,6 +57,8 @@
},
"host": "Je gaat zo verbinden met <0>{{hostname}}</0>, check even of je deze link vertrouwt",
"no": "Vorige pagina",
"noHost": "De server is nog niet geconfigureerd, daarom kunt u geen account aanmaken",
"noHostTitle": "Server niet geconfigureerd!",
"title": "Vertrouw je deze server?",
"yes": "Ik vertrouw deze server"
},
@@ -116,7 +118,15 @@
"failed": "Het is niet gelukt de media te laden, probeer het nog eens!",
"loading": "Aan het zoeken...",
"noResults": "We konden helaas niets vinden!",
"placeholder": "Wat wil je graag kijken?",
"placeholder": {
"default": "Wat wil je graag kijken?",
"extra": [
"Wat wil je verkennen?",
"Wat staat er op jouw kijklijst?",
"Wat is jouw favoriete film?",
"Wat is jouw favoriete serie?"
]
},
"sectionTitle": "Zoekresultaten"
},
"titles": {
@@ -177,10 +187,10 @@
"back": "Terug",
"explainer": "Door gebruik te maken van de browserextensie kun je de beste streams krijgen. Met slechts een eenvoudige installatie.",
"explainerIos": "Helaas, de browserextensie is niet ondersteund op iOS. Druk op <bold>Terug</bold> om een andere optie te kiezen.",
"extensionHelp": "Als je de extensie hebt geïnstalleerd maar niet wordt gedetecteerd, <bold>Open dan de extensie via het extensies menu in je browser</bold> en volg de stappen op het scherm.",
"extensionHelp": "Als je de extensie hebt geïnstalleerd maar niet wordt gedetecteerd, <bold>open dan de extensie via het extensies menu in je browser</bold> en volg de stappen op het scherm.",
"linkChrome": "Installeer de Chrome-extensie",
"linkFirefox": "Installeer de Firefox-extensie",
"notDetecting": "Geïnstalleerd op Chrome maar wordt niet weergegeven? Probeer de pagina opnieuw te laden!",
"notDetecting": "Geïnstalleerd op Chrome, maar de site detecteert het niet? Probeer de pagina opnieuw te laden!",
"notDetectingAction": "Pagina opnieuw laden",
"status": {
"disallowed": "Extensie is niet ingeschakeld voor deze pagina",
@@ -208,7 +218,7 @@
"title": "Laten we een nieuwe proxy instellen"
},
"start": {
"explainer": "Om de beste mogelijke streams te krijgen, moet je kiezen welke streamingmethode je wilt gebruiken.",
"explainer": "Om de beste streams mogelijk te krijgen, moet je kiezen welke streammethode je wilt gebruiken.",
"options": {
"default": {
"text": "Ik wil geen streams van goede kwaliteit, <0 /> <1>Gebruik de standaardinstellingen.</1>"
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "HLS-afspeellijstlink kopiëren",
"disclaimer": "Downloads worden direct bij de bron opgehaald. movie-web heeft geen controle over het bestand dat je ontvangt.",
"downloadSubtitle": "Download huidige ondertiteling",
"downloadVideo": "Download filmpje",

View File

@@ -57,6 +57,8 @@
},
"host": "ਤੁਸੀਂ <0>{{hostname}}</0> ਨਾਲ ਜੁੜ ਰਹੇ ਹੋ - ਕਿਰਪਾ ਕਰਕੇ ਖਾਤਾ ਬਣਾਉਣ ਤੋਂ ਪਹਿਲਾਂ ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ ਤੁਸੀਂ ਇਸ 'ਤੇ ਭਰੋਸਾ ਕਰਦੇ ਹੋ",
"no": "ਵਾਪਸ ਜਾਓ",
"noHost": "ਸਰਵਰ ਕੌਂਫਿਗਰ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ, ਇਸਲਈ ਤੁਸੀਂ ਖਾਤਾ ਨਹੀਂ ਬਣਾ ਸਕਦੇ ਹੋ",
"noHostTitle": "ਸਰਵਰ ਕੌਂਫਿਗਰ ਨਹੀਂ ਕੀਤਾ ਗਿਆ!",
"title": "ਕੀ ਤੁਸੀਂ ਇਸ ਸਰਵਰ 'ਤੇ ਭਰੋਸਾ ਕਰਦੇ ਹੋ?",
"yes": "ਮੈਨੂੰ ਇਸ ਸਰਵਰ 'ਤੇ ਭਰੋਸਾ ਹੈ"
},
@@ -116,7 +118,15 @@
"failed": "ਮੀਡੀਆ ਲੱਭਣ ਵਿੱਚ ਅਸਫਲ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ!",
"loading": "ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...",
"noResults": "ਅਸੀਂ ਕੁਝ ਵੀ ਨਹੀਂ ਲੱਭ ਸਕੇ!",
"placeholder": "ਤੁਸੀਂ ਕੀ ਦੇਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"placeholder": {
"default": "ਤੁਸੀਂ ਕੀ ਦੇਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"extra": [
"ਤੁਸੀਂ ਕੀ ਪੜਚੋਲ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"ਤੁਹਾਡੀ ਨਿਗਰਾਨੀ ਸੂਚੀ ਵਿੱਚ ਕੀ ਹੈ?",
"ਤੁਹਾਡੀ ਮਨਪਸੰਦ ਫਿਲਮ ਕਿਹੜੀ ਹੈ?",
"ਤੁਹਾਡੀ ਮਨਪਸੰਦ ਲੜੀ ਕਿਹੜੀ ਹੈ?"
]
},
"sectionTitle": "ਖੋਜ ਨਤੀਜੇ"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "HLS ਪਲੇਲਿਸਟ ਲਿੰਕ ਕਾਪੀ ਕਰੋ",
"disclaimer": "ਡਾਊਨਲੋਡ ਸਿੱਧੇ ਪ੍ਰਦਾਤਾ ਤੋਂ ਲਏ ਜਾਂਦੇ ਹਨ. ਮੂਵੀ-ਵੈੱਬ ਦਾ ਇਸ 'ਤੇ ਕੰਟਰੋਲ ਨਹੀਂ ਹੈ ਕਿ ਡਾਊਨਲੋਡ ਕਿਵੇਂ ਪ੍ਰਦਾਨ ਕੀਤੇ ਜਾਂਦੇ ਹਨ.",
"downloadSubtitle": "ਮੌਜੂਦਾ ਉਪਸਿਰਲੇਖ ਡਾਊਨਲੋਡ ਕਰੋ",
"downloadVideo": "ਵੀਡੀਓ ਡਾਊਨਲੋਡ ਕਰੋ",

View File

@@ -116,7 +116,10 @@
"failed": "Arrrr failed to find media, try again!",
"loading": "Hold yer horses, me heartie!",
"noResults": "We couldn't find anythin', arrr!",
"placeholder": "What do ye want to watch?",
"placeholder": {
"default": "What do ye want to watch?",
"extra": []
},
"sectionTitle": "Searchin' results"
},
"titles": {

View File

@@ -116,7 +116,10 @@
"failed": "Nie udało się znaleźć mediów, Spróbuj ponownie!",
"loading": "Wczytywanie...",
"noResults": "Nie mogliśmy niczego znaleźć!",
"placeholder": "Co chciałbyś obejrzeć?",
"placeholder": {
"default": "Co chciałbyś obejrzeć?",
"extra": []
},
"sectionTitle": "Wyniki wyszukiwania"
},
"titles": {
@@ -128,15 +131,11 @@
},
"morning": {
"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": {
"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."]
}
}
},
@@ -526,6 +525,7 @@
},
"subtitles": {
"backgroundLabel": "Krycie tła",
"backgroundBlurLabel": "Rozmycie tła",
"colorLabel": "Kolor",
"previewQuote": "Nie wolno mi się bać. Strach zabija myślenie.",
"textSizeLabel": "Rozmiar czcionki",

View File

@@ -116,7 +116,10 @@
"failed": "Falha ao encontrar mídia, tente novamente!",
"loading": "Carregando...",
"noResults": "Não conseguimos encontrar nada!",
"placeholder": "O que você quer assistir?",
"placeholder": {
"default": "O que você quer assistir?",
"extra": []
},
"sectionTitle": "Resultados da pesquisa"
},
"titles": {
@@ -128,15 +131,11 @@
},
"morning": {
"default": "O que você gostaria de assistir esta manhã?",
"extra": [
"Ouvi dizer que Antes do Amanhecer é bom"
]
"extra": ["Ouvi dizer que Antes do Amanhecer é bom"]
},
"night": {
"default": "O que você gostaria de assistir esta noite?",
"extra": [
"Cansado? Ouvi dizer que O Exorcista é bom."
]
"extra": ["Cansado? Ouvi dizer que O Exorcista é bom."]
}
}
},
@@ -242,6 +241,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Copiar link da playlist HLS",
"disclaimer": "Os downloads são feitos diretamente do provedor. movie-web não tem controle sobre como os downloads são fornecidos.",
"downloadSubtitle": "Baixar legenda atual",
"downloadVideo": "Baixar vídeo",

View File

@@ -115,7 +115,10 @@
"failed": "Falha ao encontrar mídia, tente novamente!",
"loading": "A carregar...",
"noResults": "Não conseguimos encontrar nada!",
"placeholder": "O que deseja assistir?",
"placeholder": {
"default": "O que deseja assistir?",
"extra": []
},
"sectionTitle": "Resultados da pesquisa"
},
"titles": {
@@ -127,15 +130,11 @@
},
"morning": {
"default": "O que gostaria de assistir esta manhã?",
"extra": [
"Dizem que Antes do Amanhecer é bom"
]
"extra": ["Dizem que Antes do Amanhecer é bom"]
},
"night": {
"default": "O que gostaria de assistir esta noite?",
"extra": [
"Cansado? Dizem que O Exorcista é bom."
]
"extra": ["Cansado? Dizem que O Exorcista é bom."]
}
}
},

View File

@@ -114,7 +114,10 @@
"failed": "Găsire media eșuată, încearcă din nou!",
"loading": "Se încarcă...",
"noResults": "Nu am putut găsi nimic!",
"placeholder": "La ce dorești să te uiți?",
"placeholder": {
"default": "La ce dorești să te uiți?",
"extra": []
},
"sectionTitle": "Rezultate de căutare"
},
"titles": {
@@ -126,15 +129,11 @@
},
"morning": {
"default": "La ce dorești să te in uiți dimineață aceasta?",
"extra": [
"Aud că Before Sunrise este bun"
]
"extra": ["Aud că Before Sunrise este bun"]
},
"night": {
"default": "La ce dorești să te uiți în astă seară?",
"extra": [
"Obosit? Aud că The Exorcist is good."
]
"extra": ["Obosit? Aud că The Exorcist is good."]
}
}
},

View File

@@ -57,6 +57,8 @@
},
"host": "Вы подключаетесь к <0>{{hostname}}</0> - пожалуйста, подтвердите, что вы доверяете ему, прежде чем создавать учётную запись",
"no": "Вернуться назад",
"noHost": "Сервер не был настроен, поэтому вы не можете создать учётную запись",
"noHostTitle": "Сервер не настроен!",
"title": "Вы доверяете этому серверу?",
"yes": "Я доверяю этому серверу"
},
@@ -116,7 +118,15 @@
"failed": "Не удалось найти медиафайл, попробуйте снова!",
"loading": "Загрузка...",
"noResults": "Мы ничего не нашли!",
"placeholder": "Что вы хотите посмотреть?",
"placeholder": {
"default": "Что вы хотите посмотреть?",
"extra": [
"Что вы хотите исследовать?",
"Что в вашем списке?",
"Какой ваш любимый фильм?",
"Какой ваш любимый сериал?"
]
},
"sectionTitle": "Результаты поиска"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Скопировать ссылку на плейлист HLS",
"disclaimer": "Загрузки осуществляются непосредственно поставщиком. movie-web не контролирует способ предоставления загрузок.",
"downloadSubtitle": "Скачать текущие субтитры",
"downloadVideo": "Скачать видео",

View File

@@ -57,6 +57,8 @@
},
"host": "Povezujete se z <0>{{hostname}}</0> - pred ustvarjanjem računa potrdite, da mu zaupate",
"no": "Nazaj",
"noHost": "Strežnik ni nastavljen, zato ustvarjanje profila ni mogoče",
"noHostTitle": "Strežnik ni nastavljen!",
"title": "Ali zaupate temu strežniku?",
"yes": "Zaupam strežniku"
},
@@ -95,6 +97,7 @@
"about": "O projektu",
"dmca": "DMCA",
"login": "Prijava",
"onboarding": "Nastavitev",
"pagetitle": "{{title}} - movie-web",
"register": "Registriraj se",
"settings": "Nastavitve"
@@ -115,7 +118,15 @@
"failed": "Ni uspelo najti medija, prosim poskusite znova!",
"loading": "Nalaganje...",
"noResults": "Vsebin nismo našli!",
"placeholder": "Kaj si želite gledati?",
"placeholder": {
"default": "Kaj si želite gledati?",
"extra": [
"Kaj želiš raziskati danes?",
"Kateri fdilm/serijo si boš ogledal/a naslednje?",
"Kateri film ti je najljubši?",
"Katera je tvoja najljubša serija?"
]
},
"sectionTitle": "Rezultati iskanja"
},
"titles": {
@@ -165,6 +176,69 @@
"message": "Iskali smo povsod: pod preprogo, v omari, za \"proxyjem\", vendar na koncu nismo našli strani, ki jo iščete.",
"title": "Ni bilo mogoče najti te strani"
},
"onboarding": {
"defaultConfirm": {
"cancel": "Prekliči",
"confirm": "Upoeabi privzete nastavitve",
"description": "Privzeta nastavitev nima najboljših pretokov in je lahko neznosno počasna.",
"title": "Si prepričan?"
},
"extension": {
"back": "Nazaj",
"explainer": "Z razširitvijo brskalnika lahko dobite najboljše tokove, ki jih ponujamo. Namestitev je zelo preprosta!",
"explainerIos": "Na žalost razširitev brskalnika ni podprta v sistemu iOS, Pritisnite <bold>Najdi nazaj</bold> in izberite drugo možnost.",
"extensionHelp": "Če ste namestili razširitev, vendar ni zaznana, <bold>odprite razširitev v meniju razširitev brskalnika</bold> in sledite navodilom na zaslonu.",
"linkChrome": "Naloži Chrome razširitev",
"linkFirefox": "Naloži Firefox razširitev",
"notDetecting": "Nameščen v brskalniku Chrome, vendar ga spletno mesto ne zazna? Poskusite znova naložiti stran!",
"notDetectingAction": "Osveži stran",
"status": {
"disallowed": "Razširitev ni omogočena na tej strani",
"disallowedAction": "Omogoči razširitev",
"failed": "Ni uspelo zahtevati statusa",
"loading": "Čakamo, da namestite razširitev",
"outdated": "Verzija razširitve je prestara",
"success": "Razširitev deluje pravilno!"
},
"submit": "Nadaljuj",
"title": "Začnimo z razširitvijo"
},
"proxy": {
"back": "Nazaj",
"explainer": "Z metodo proxy lahko s samopostrežnim proxyjem pridobite zelo kakovostne prenose.",
"input": {
"errorConnection": "Povezava s proxyjem ni uspela",
"errorInvalidUrl": "Ni validen URL",
"errorNotProxy": "Pričakoval proxy, a dobil spletno stran",
"label": "URL proxyja",
"placeholder": "https://"
},
"link": "Kako postavim proxy",
"submit": "Oddaj proxy",
"title": "Naredimo nov proxy"
},
"start": {
"explainer": "Da bi dobili najboljše možne prenose, morate izbrati metodo pretakanja, ki jo želite uporabiti.",
"options": {
"default": {
"text": "Ne želim dobre kakovosti tokov,<0 /> <1>uporabite privzeto nastavitev</1>"
},
"extension": {
"action": "Naloži razširitev",
"description": "Namestite razširitev brskalnika in pridobite dostop do najboljših virov.",
"quality": "Najboljša kvaliteta",
"title": "Razširitev brskalnika"
},
"proxy": {
"action": "Nastavi proxy",
"description": "V samo 5 minutah nastavite proxy in pridobite dostop do odličnih virov.",
"quality": "Dobra kvaliteta",
"title": "Proxy po meri"
}
},
"title": "Pripravimo vas na namestitev s filmskim spletom"
}
},
"overlays": {
"close": "Zapri"
},
@@ -178,10 +252,11 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "Kopiranje povezave do seznama predvajanja HLS",
"disclaimer": "Prenosi se opravijo neposredno pri ponudniku vsebin. movie-web nima nadzora nad načinom zagotavljanja prenosov.",
"downloadSubtitle": "Prenesi trenutne podnapise",
"downloadVideo": "Prenesi video",
"hlsDisclaimer": "Prenosi se opravijo neposredno pri ponudniku vsebin. movie-web nima nadzora nad načinom zagotavljanja prenosov. Upoštevajte, da prenašate seznam predvajanja tipa \"HLS\"; ta je namenjen uporabnikom, ki poznajo napredno pretakanje večpredstavnostnih vsebin.",
"hlsDisclaimer": "Prenosi se opravijo neposredno pri ponudniku vsebin. movie-web nima nadzora nad načinom zagotavljanja prenosov. Upoštevajte, da prenašate seznam predvajanja tipa \"HLS\" namenjen uporabnikom, ki poznajo napredno pretakanje večpredstavnostnih vsebin.",
"onAndroid": {
"1": "Če želite prenesti v sistemu Android, kliknite gumb za prenos, nato na novi strani <bold>tipnite in držite</bold> videoposnetek ter izberite <bold>shrani</bold>.",
"shortTitle": "Prenesi / Android",
@@ -205,7 +280,8 @@
"episodeBadge": "E{{episode}}",
"loadingError": "Napaka pri nalaganju sezone",
"loadingList": "Nalaganje...",
"loadingTitle": "Nalaganje..."
"loadingTitle": "Nalaganje...",
"unairedEpisodes": "Ena ali več epizod v tej sezoni so onemogočene, ker še niso bile predvajane."
},
"playback": {
"speedLabel": "Hitrost predvajanja",
@@ -257,6 +333,21 @@
}
},
"metadata": {
"api": {
"text": "Metapodatkov API ni bilo mogoče naložiti, preverite internetno povezavo.",
"title": "Ni uspelo naložiti metapodatkov API"
},
"dmca": {
"badge": "Odstranjeno",
"text": "Ta medij ni več na voljo zaradi obvestila o odstranitvi ali zahtevka za avtorske pravice.",
"title": "Medij je bil odstranjen"
},
"extensionPermission": {
"badge": "Neveljavne pravice dostopa",
"button": "Uporabi razširitev",
"text": "Imate razširitev brskalnika, vendar potrebujemo vaše dovoljenje, da lahko začnemo uporabljati razširitev.",
"title": "Nastavi razširitev brskalnika"
},
"failed": {
"badge": "Neuspešno",
"homeButton": "Domov",
@@ -306,6 +397,12 @@
"remaining": "{{timeLeft}} do konca • Konča ob {{timeFinished, datetime}}",
"shortRegular": "{{timeWatched}}",
"shortRemaining": "-{{timeLeft}}"
},
"turnstile": {
"description": "Preverite, ali ste človek, tako da izpolnite Captcha na desni strani. S tem zagotavljamo varnost filmskega spleta!",
"error": "Ni uspelo preveriti vaše človeškosti. Poskusite znova.",
"title": "Preveriti moramo, ali ste človek.",
"verifyingHumanity": "Preverjanje vaše človeškosti..."
}
},
"screens": {
@@ -378,20 +475,50 @@
},
"connections": {
"server": {
"description": "Če se želite povezati z zaledjem po meri za hrambo podatkov, to omogočite in navedite URL naslov.",
"description": "Če se želite povezati z zaledjem po meri za hrambo podatkov, to omogočite in navedite URL naslov. <0>Navodila.</0>",
"label": "Strežnik po meri",
"urlLabel": "Naslov strežnika po meri (URL)"
},
"setup": {
"doSetup": "Naredi nastavitev",
"errorStatus": {
"description": "Zdi se, da je treba posvetiti pozornost enemu ali več elementom v tej nastavitvi.",
"title": "Nekaj potrebuje vašo pozornost"
},
"itemError": "S to nastavitvijo je nekaj narobe. Ponovno opravite nastavitev in jo popravite.",
"items": {
"default": "Privzet način",
"extension": "Razširitev",
"proxy": "Proxy po meri"
},
"redoSetup": "Ponovnio izvedi nastavljanje",
"successStatus": {
"description": "Vse stvari so pripravljene, da lahko začnete gledati svoje najljubše medije.",
"title": "Vse je nastavljeno!"
},
"unsetStatus": {
"description": "Kliknite gumb na desni strani, da začnete postopek namestitve.",
"title": "Niste opravili nastavitev"
}
},
"title": "Povezave",
"workers": {
"addButton": "Dodaj novega \"workerja\"",
"description": "Za delovanje aplikacije je ves promet usmerjen prek posredniških strežnikov. To nastavitev omogočite, če želite pripeljati lastne delavce.",
"description": "Za delovanje aplikacije je ves promet usmerjen prek posredniških strežnikov. To nastavitev omogočite, če želite pripeljati lastne delavce. <0>Navodila</0>",
"emptyState": "Niste dodali \"workerja\", dodajte ga spodaj",
"label": "Uporaba posrednikov po meri",
"urlLabel": "Naslov Workerja (URL)",
"urlPlaceholder": "https://"
}
},
"preferences": {
"language": "Jezik",
"languageDescription": "Jezik, ki se uporablja za celotno aplikacijo.",
"thumbnail": "Naloži predoglede",
"thumbnailDescription": "Videoposnetki večinoma nimajo predogledov. To nastavitev lahko omogočite in jih ustvarite sproti, vendar lahko zaradi tega videoposnetek postane počasnejši.",
"thumbnailLabel": "Naloži predoglede",
"title": "Nastavitve"
},
"reset": "Ponastavi",
"save": "Shrani",
"sidebar": {

View File

@@ -114,7 +114,10 @@
"failed": "Misslyckades med att hitta media, försök igen!",
"loading": "Laddar...",
"noResults": "Vi kunde inte hitta någonting!",
"placeholder": "Vad vill du titta på?",
"placeholder": {
"default": "Vad vill du titta på?",
"extra": []
},
"sectionTitle": "Sökresultat"
},
"titles": {
@@ -123,15 +126,11 @@
},
"morning": {
"default": "Vad vill du titta på den här morgonen?",
"extra": [
"Jag hör att Before Sunrise är bra"
]
"extra": ["Jag hör att Before Sunrise är bra"]
},
"night": {
"default": "Vad vill du titta på ikväll?",
"extra": [
"Trött? Jag hör att The Exorcist är bra."
]
"extra": ["Trött? Jag hör att The Exorcist är bra."]
}
}
},

View File

@@ -1,6 +1,19 @@
{
"about": {
"description": "movie-web என்பது இணையத்தில் ஸ்ட்ரீம்களைத் தேடும் ஒரு வலைப் பயன்பாடு ஆகும். உள்ளடக்கத்தை உட்கொள்வதற்கான ஒரு சிறிய அணுகுமுறையை குழு நோக்கமாகக் கொண்டுள்ளது.",
"faqTitle": "பொதுவான கேள்விகள்",
"q1": {
"body": "மூவி வெப் எந்தவொரு பதிவுகளையும் வழங்குவதில்லை. நீங்கள் ஒரு காட்சியை தேர்ந்தெடுத்து காண விரும்பும் போது அதற்கான பதிவை இணையத்தில் உள்ள பல்வேறு தளங்களில் இருந்து தேடி உங்களுக்கு வழங்குகிறது. பதிவுகள் ஒரு போதும் மூவி வெப் மூலம் பதிவேற்றப்படுவது இல்லை. நீங்கள் காணும் அனைத்து காட்சிகளும் தேடு பொறி முறையின் சிறப்பம்சத்தின் மூலமாகவே உங்களுக்கு வழங்கப்படுகிறது.",
"title": "பதிவு எங்கிருந்து வருகிறது?"
},
"q2": {
"body": "ஒரு திரைப்படம் அல்லது தொடரை உங்களால் நேரடியாக கோர முடியாது. மூவி வெப் எந்த ஒரு பதிவுகளையும் நிர்வகிப்பதில்லை. அணைத்து பதிவுகளும் இணையத்தில் உள்ள தளங்களின் வழியாகவே உங்களுக்கு அளிக்கப்படுகின்றது.",
"title": "ஒரு தொடர் அல்லது திரைப்படத்தை நான் எங்கே கோருவது?"
},
"q3": {
"body": "எங்கள் தேடல் முடிவுகள் The Movie Database (TMDB) தரவு தளம் மூலம் வழங்கப்படுகிறது. தேடல் முடிவுகள் தேடலுக்கான பதிவுகளை கட்டாயம் உள்ளடக்கி இருக்கும் என்பதை உறுதியாக கூற இயலாது.",
"title": "தேடல் முடிவுகள் திரைப்படம் அல்லது தொடரை காட்டுகிறது. ஆனால், ஏன் என்னால் அதை பார்க்க முடியவில்லை?"
},
"title": "movie-web பற்றி"
},
"actions": {
@@ -8,8 +21,8 @@
"copy": "நகல்"
},
"auth": {
"createAccount": "கணக்கு இல்லையா? <0>கணக்கை உருவாக்குங்கள்</0>",
"deviceNameLabel": "கருவியின் பெயர்",
"createAccount": "கணக்கு இல்லையா? <0>புதிய கணக்கை உருவாக்குங்கள்</0>",
"deviceNameLabel": "சாதனத்தின் பெயர்",
"deviceNamePlaceholder": "எனது கைபேசி",
"generate": {
"description": "தங்கள் கடவுச்சொற்றொடரே தங்களது பயனர் பெயர் மற்றும் கடவுச்சொல். கணக்கினுள் நுழைய அதனை பாதுகாப்பாக வைத்திருங்கள்",
@@ -17,51 +30,507 @@
"passphraseFrameLabel": "கடவுச்சொற்றொடர்",
"title": "உங்கள் கடவுச்சொற்றொடர்"
},
"hasAccount": "கணக்கு வைத்துள்ளீரா? <0>புகுபதிகை செய்க </0>",
"hasAccount": "ஏற்கனவே ஒரு கணக்கு ள்ளா? <0>இங்கே உள்நுழைக. </0>",
"login": {
"description": "உங்கள் கணக்கினுள் புகுபதிய கடவுச்சொற்றொடரை உள்ளிடுக",
"deviceLengthError": "கருவியின் பெயரை உள்ளிடுக",
"description": "உங்கள் கணக்கினுள் உள்நுழைய உங்கள் கடவுச்சொற்றொடரை உள்ளிடுக",
"deviceLengthError": "சாதனத்தின் பெயரை உள்ளிடவும்",
"passphraseLabel": "12-சொல் கடவுச்சொற்றொடர்",
"passphrasePlaceholder": "கடவுச்சொற்றொடர்",
"submit": "புகுபதிகை",
"title": "உங்கள் கணக்கினுள் புகுபதிய",
"title": "உங்கள் கணக்கில் உள்நுழைக",
"validationError": "தவறான அல்லது முழுமையற்ற கடவுச்சொற்றொடர்"
},
"register": {
"information": {
"icon": "பயனர் குறிப்படம்",
"color1": "Profile நிறம் ஒன்று",
"color2": "Profile நிறம் இரண்டு",
"header": "உங்கள் சாதனத்தின் பெயரை உள்ளிட்டு அதற்கான வண்ணம் மற்றும் ஐகானையும் தேர்ந்தெடுக்கவும்",
"icon": "பயனர் icon",
"next": "அடுத்து",
"title": "கணக்கு விவரம்"
}
},
"trust": {
"no": "பின்செல்"
"failed": {
"text": "நீங்கள் அதை சரியாக உள்ளமைத்தீர்களா?",
"title": "சர்வரை தொடர்பு கொள்ள முடியவில்லை"
},
"host": "நீங்கள் <0>{{hostname}}</0> உடன் இணைக்கப்படுகிறீர்கள். கணக்கை உருவாக்கும் முன் சரியான தகவல் தானா எனபதை உறுதி செய்து கொள்ளவும்",
"no": "பின்செல்",
"title": "நீங்கள் இந்த சர்வரை நம்புகிறீர்களா?",
"yes": "நான் இந்த சர்வரை நம்புகிறேன்"
},
"verify": {
"description": "உங்கள் கடவுச்சொற்றொடரைச் சேமித்துள்ளீர்கள் என்பதை உறுதிப்படுத்த உங்கள் கடவுச்சொற்றொடர்களை மீண்டும் இங்கே உள்ளீடு செய்து உங்கள் கணக்கை உருவாக்கிக் கொள்ளுங்கள்",
"invalidData": "தரவு செல்லுபடியாகாது",
"noMatch": "கடவுச்சொற்றொடர்கள் பொருந்தவில்லை",
"passphraseLabel": "உங்களின் 12-சொல் கடவுச்சொற்றொடர்",
"recaptchaFailed": "ReCaptcha சரிபார்ப்பு தோல்வியடைந்தது",
"register": "கணக்கை உருவாக்கு",
"title": "கடவுச்சொற்றொடரை உறுதி செய்க"
}
},
"errors": {
"badge": "சரியாக வேலை செய்யவில்லை",
"details": "பிழை விவரங்கள்",
"reloadPage": "இணையப் பக்கத்தை Reload செய்யவும்",
"showError": "பிழை விவரங்களைக் காட்டு",
"title": "நங்கள் ஒரு பிழையை எதிர் கொண்டு இருக்கிறோம்!"
},
"footer": {
"legal": {
"disclaimer": "பொறுப்பு துறப்பு",
"disclaimerText": "மூவி-வெப் எந்த பதிவுகளையும் தன்னகம் வைத்திருக்கவில்லை, இது மூன்றாம் தரப்பு பதிவுகளை வழங்குபவர்களை இணைக்கிறது. சட்ட சிக்கல்கள் ஏதேனும் இருப்பின் அது பதிவுகளை வழங்குபவரையே சாறும். வீடியோ வழங்குநர்கள் காண்பிக்கும் எந்த மீடியா பதிவுகளுக்கும் மூவி வெப் பொறுப்பாகாது."
},
"links": {
"discord": "Discord",
"dmca": "DMCA",
"github": "GitHub"
},
"tagline": "இந்த ஓப்பன் சோர்ஸ் (Open Source) இணைய தளம் மூலம் உங்களுக்குப் பிடித்த தொடர்களையும் திரைப்படங்களையும் பார்க்கலாம்."
},
"global": {
"name": "மூவி-வெப்",
"pages": {
"about": "தெரிந்து கொள்ள",
"dmca": "DMCA",
"login": "புகுபதிகை",
"onboarding": "அமை",
"pagetitle": "{{title}} - மூவி- வெப்",
"register": "பதிவு",
"settings": "அமைப்புகள்"
}
},
"home": {
"bookmarks": {
"sectionTitle": "குறிப்புகள்"
},
"continueWatching": {
"sectionTitle": "தொடர்ந்து பார்க்க"
},
"mediaList": {
"stopEditing": "திருத்துவதை நிறுத்து"
},
"search": {
"allResults": "மேலும் எங்களிடம் இல்லை!",
"failed": "மீடியாவைக் கண்டறிய முடியவில்லை, மீண்டும் முயலவும்!",
"loading": "Loading...",
"noResults": "எங்களால் எதையும் கண்டுபிடிக்க இயலவில்லை!",
"sectionTitle": "தேடல் முடிவுகள்"
},
"titles": {
"day": {
"default": "மதிய வணக்கம். தற்போது என்ன காண விரும்புகிறீர்கள்?",
"extra": [
"சாகசமாக உணர்கிறீர்களா? ஜுராசிக் பார்க் (Jurassic Park) சரியான தேர்வாக இருக்கலாம்."
]
},
"morning": {
"default": "காலை வணக்கம். தற்போது என்ன காண விரும்புகிறீர்கள்?",
"extra": [
"சூரிய உதயத்திற்கு முன் நல்லது என்று கேள்விப்படுகிறேன்"
]
},
"night": {
"default": "இன்றைய இரவு என்ன காண விரும்புகிறீர்கள்?",
"extra": [
"சோர்வாக உள்ளீர்களா? Exorcist திரைப்படம் காணுங்கள்."
]
}
}
},
"media": {
"episodeDisplay": "S{{season}} E{{episode}}",
"types": {
"movie": "திரைப்படம்",
"show": "காட்சி"
}
},
"navigation": {
"banner": {
"offline": "உங்கள் இணைய இணைப்பைச் சரிபார்க்கவும்"
},
"menu": {
"settings": "அமைப்புகள்"
"about": "எங்களை பற்றி",
"donation": "நன்கொடை",
"logout": "வெளியேறு",
"register": "இணைய கணக்கோடு ஒத்திசை (Sync to cloud)",
"settings": "அமைப்புகள்",
"support": "உதவி மையம்"
}
},
"notFound": {
"badge": "கிடைக்கவில்லை",
"goHome": "முகப்பிற்குச் செல்",
"message": "எங்களால் இயன்றவரை தேடினோம். ஆனால் உங்களுக்கான பக்கத்தை கண்டுபிடிக்க இயலவில்லை.",
"title": "உங்களுக்கான பக்கத்தை கண்டுபிடிக்க இயலவில்லை"
},
"onboarding": {
"defaultConfirm": {
"cancel": "ரத்து செய்",
"confirm": "இயல்புநிலை அமைப்பைப் பயன்படுத்தவும்",
"description": "இயல்புநிலை அமைப்பில் உள்ள தரவுகள் சிறந்த அனுபவத்தை வழங்க உகந்தவை அல்ல. மேலும், இவை மிகவும் மெதுவான இணைய வேகத்தையே கொண்டிருக்கும்.",
"title": "உறுதி செய்யலாமா?"
},
"extension": {
"back": "பின் செல்",
"explainer": "உலாவி நீட்டிப்பு (Browser Extension) வழி உங்களுக்கு சிறந்த காட்சிகளை எங்களால் வழங்க இயலும். மேலும், இந்த நிறுவல் மிகவும் எளிதான வழி முறையாகும்.",
"explainerIos": "துரதிர்ஷ்டவசமாக, உலாவி நீட்டிப்பு iOS இல் ஆதரிக்கப்படவில்லை, மற்றொரு விருப்பத்தைத் தேர்வுசெய்ய <bold>பின் செல்</bold> என்பதை அழுத்தவும்.",
"extensionHelp": "நீங்கள் நீட்டிப்பை நிறுவியிருந்தும் அது கண்டறியப்படவில்லை எனில், <bold>உங்கள் உலாவி நீட்டிப்பு மெனு மூலம் நீட்டிப்பைத் திறந்து</bold> திரையில் உள்ள படிகளைப் பின்பற்றவும்.",
"linkChrome": "Chrome நீட்டிப்பை நிறுவவும்",
"linkFirefox": "Firefox நீட்டிப்பை நிறுவவும்",
"notDetecting": "Chrome இல் நிறுவப்பட்டு விட்டது, ஆனால் தளம் அதைக் கண்டறியவில்லையா? பக்கத்தை மீண்டும் இயக்கி (Reload) முயற்சிக்கவும்!",
"notDetectingAction": "பக்கத்தை மீண்டும் இயக்கு",
"status": {
"disallowed": "இந்தப் பக்கத்திற்கு நீட்டிப்பு இயக்கப்படவில்லை",
"disallowedAction": "நீட்டிப்பை இயக்கு",
"failed": "தற்போதைய நிலையை அறிய இயலவில்லை",
"loading": "நீங்கள் நீட்டிப்பை நிறுவும் வரை காத்திருக்கிறது",
"outdated": "நீட்டிப்பு பதிப்பு மிகவும் பழையது",
"success": "நீட்டிப்பு எதிர்பார்த்தபடி செயல்படுகிறது!"
},
"submit": "தொடரவும்",
"title": "நீட்டிப்பு நிறுவலுடன் ஆரம்பிக்கலாம்"
},
"proxy": {
"back": "பின் செல்",
"explainer": "Proxy முறையில், உங்களின் தனிப்பட்ட Proxy யை உருவாக்குவதன் மூலம் சிறந்த தரமான ஸ்ட்ரீம்களைப் பெறலாம்.",
"input": {
"errorConnection": "Proxy உடன் இணைக்க முடியவில்லை",
"errorInvalidUrl": "சரியான URL அல்ல",
"errorNotProxy": "Proxy க்கு பதில் இணைய தளம் கிடைத்துள்ளது",
"label": "Proxy URL",
"placeholder": "https://"
},
"link": "Proxy எவ்வாறு உருவாக்குவது என்பதை அறிக",
"submit": "Proxy யை சமர்ப்பிக்க",
"title": "ஒரு புதிய Proxy யை உருவாக்குவோம்"
},
"start": {
"explainer": "சிறந்த ஸ்ட்ரீம்களைப் பெற, நீங்கள் எந்த ஸ்ட்ரீமிங் முறையைப் பயன்படுத்த விரும்புகிறீர்கள் என்பதை நீங்கள் தேர்வு செய்ய வேண்டும்.",
"options": {
"default": {
"text": "எனக்கு நல்ல தரமான ஸ்ட்ரீம்கள் வேண்டாம்,<0 /> <1>இயல்புநிலை அமைப்பைப் பயன்படுத்தவும்</1>"
},
"extension": {
"action": "நீட்டிப்பை நிறுவவும்",
"description": "உலாவி நீட்டிப்பை நிறுவி, சிறந்த தரவுகளை பெறுங்கள்.",
"quality": "சிறந்த தரம்",
"title": "உலாவி நீட்டிப்பு"
},
"proxy": {
"action": "Proxy யை அமைக்கவும்",
"description": "வெறும் 5 நிமிடங்களில் Proxy யை அமைத்து, சிறந்த தரவுகளை பெறுங்கள்.",
"quality": "நல்ல தரம்",
"title": "தனிப்பட்ட Proxy"
}
},
"title": "உங்களின் மூவி-வெப் அமைப்பை நிறுவலாம் வாருங்கள்"
}
},
"overlays": {
"close": "மூடு"
},
"player": {
"back": {
"default": "முகப்பிற்கு செல்",
"short": "பின் செல்"
},
"casting": {
"enabled": "சாதனத்தின் வழி திரையிடப்படுகிறது..."
},
"menus": {
"downloads": {
"copyHlsPlaylist": "HLS Playlist link யை காப்பி செய்யவும்",
"disclaimer": "பதிவிறக்கங்கள் வழங்குநரிடமிருந்து நேரடியாக வழங்கப்படுகின்றன. பதிவிறக்கங்கள் எவ்வாறு வழங்கப்படுகின்றன என்பதை மூவி-வெப் கட்டுப்படுத்தாது.",
"downloadSubtitle": "தற்போதைய வசனத்தைப் பதிவிறக்கவும்",
"downloadVideo": "Video வை பதிவிறக்கம் செய்",
"hlsDisclaimer": "பதிவிறக்கங்கள் வழங்குநரிடமிருந்து நேரடியாக எடுக்கப்படுகின்றன. பதிவிறக்கங்கள் எவ்வாறு வழங்கப்படுகின்றன என்பதை மூவி-வெப் கட்டுப்படுத்தவில்லை.<br /><br />நீங்கள் HLS Playlist யை பதிவிறக்குகிறீர்கள் என்பதை நினைவில் கொள்ளவும், <bold> Advanced streaming formats பற்றி நீங்கள் அறிந்து இருக்கவில்லையென்றால் பதிவிறக்கம் செய்ய உங்களை நாங்கள் பரிந்துரைக்கவில்லை. </bold>. வெவ்வேறு வடிவங்கள் அல்லது வெவ்வேறு ஆதாரங்களை முயற்சிக்கவும்.",
"onAndroid": {
"1": "Android இல் பதிவிறக்க, பதிவிறக்க பொத்தானைக் கிளிக் செய்து, புதிய பக்கத்தில், வீடியோ வின் மீது <bold>tap and hold</bold>கிளிக் செய்யவும், பின்னர் <bold>save</bold> என்பதைத் தேர்ந்தெடுக்கவும்.",
"shortTitle": "பதிவிறக்கம் / ஆண்ட்ராய்டு",
"title": "ஆண்ட்ராய்டு இல் பதிவிறங்குகிறது"
},
"onIos": {
"1": "iOS இல் பதிவிறக்க, பதிவிறக்க பொத்தானைக் கிளிக் செய்து, புதிய பக்கத்தில், <bold><ios_share /></bold> என்பதைக் கிளிக் செய்து பிறகு, <bold>Save to Files <ios_files /></bold> கிளிக் செய்யவும்.",
"shortTitle": "பதிவிறக்கு /iOS",
"title": "iOS இல் பதிவிறங்குகிறது"
},
"onPc": {
"1": "கணினியில், Download பொத்தானைக் கிளிக் செய்து வரும் புதிய பக்கத்தில், வீடியோவின் மீது சுட்டியின் வலது பக்கம் கிளிக் (Right Click) செய்து <bold>Save video as</bold> என்பதைத் தேர்ந்தெடுக்கவும்",
"shortTitle": "பதிவிறக்கு / PC",
"title": "கணினியில் பதிவிறங்குகிறது"
},
"title": "பதிவிறக்கு"
},
"episodes": {
"button": "அத்தியாயங்கள்",
"emptyState": "இந்த தொடரில் எந்தவொரு அத்தியாயங்களும் இல்லை. பிறகு பார்க்கவும்!",
"episodeBadge": "E{{episode}}",
"loadingError": "தொடரை திரையிட முடியவில்லை",
"loadingList": "திரையிடப்படுகிறது...",
"loadingTitle": "திரையிடப்படுகிறது...",
"unairedEpisodes": "இந்த Season இல் ஒன்று அல்லது அதற்கு மேற்பட்ட Episode கள் இன்னும் ஒளிபரப்பப்படாததால் அவை முடக்கப்பட்டுள்ளன."
},
"playback": {
"speedLabel": "காட்சி பின்னணி வேகம்",
"title": "காட்சி பின்னணி அமைப்புகள்"
},
"quality": {
"automaticLabel": "இயல்பான தரம்",
"hint": "வெவ்வேறு தர விருப்பங்களைப் பெற <0>switching source</0> தெரிவு செய்யலாம்.",
"iosNoQuality": "Apple நிறுவனத்தின் வரையறுக்கப்பட்ட வரம்புகள் காரணமாக, இந்த Source இன் தரமான தேர்வு iOS இயங்கு தளத்தில் வழங்க இயலவில்லை. வெவ்வேறு தர விருப்பங்களைப் பெற, <0>switching to another source</0> தெரிவு செய்யவும்.",
"title": "தரம்"
},
"settings": {
"downloadItem": "பதிவிறக்கம்",
"enableSubtitles": "வசனங்களை இயக்கு",
"experienceSection": "பார்க்கும் அனுபவம்",
"playbackItem": "காட்சி பின்னணி அமைப்புகள்",
"qualityItem": "தரம்",
"sourceItem": "வீடியோ ஆதாரங்கள்",
"subtitleItem": "வசன அமைப்புகள்",
"videoSection": "வீடியோ அமைப்புகள்"
},
"sources": {
"failed": {
"text": "வீடியோக்களை கண்டுபிடிக்க முயற்சிக்கும் போது பிழை ஏற்பட்டுள்ளது , வேறு ஆதாரங்களை முயற்சிக்கவும்.",
"title": "Scrape செய்ய முடியவில்லை"
},
"noEmbeds": {
"text": "எந்த உட்பொதிவுகளையும் (Embeds) எங்களால் கண்டுபிடிக்க இயலவில்லை, வேறு ஆதாரங்களை முயற்சிக்கவும்.",
"title": "உட்பொதிப்புகள் (Embeds) எதுவும் இல்லை"
},
"noStream": {
"text": "இந்த Source இல் திரைப்படம் அல்லது தொடருக்கான தரவுகள் இல்லை.",
"title": "தரவு கிடைக்கப்பெறவில்லை"
},
"title": "தரவு தளங்கள்",
"unknownOption": "தெரியவில்லை"
},
"subtitles": {
"customChoice": "File இல் இருந்து வசனத்தைத் தேர்ந்தெடுக்கவும்",
"customizeLabel": "தனிப்பயன்முறை",
"offChoice": "அனை",
"settings": {
"backlink": "தனிப்பட்ட வசன வரிகள்",
"delay": "வசன வரி தாமதம்",
"fixCapitals": "Capitals யை சரி செய்யவும்"
},
"title": "வசன வரிகள்",
"unknownLanguage": "தெரியவில்லை"
}
},
"metadata": {
"api": {
"text": "API தரவுகளை காண்பிக்க இயலவில்லை, உங்கள் இணைய இணைப்பைச் சரிபார்க்கவும்.",
"title": "API தரவுகளை காண்பிக்க இயலவில்லை"
},
"dmca": {
"badge": "அகற்றப்பட்டது",
"text": "Copyright Claim காரணமாக இந்த தரவு நீக்கப்பட்டது அல்லது காணக் கிடைக்காது.",
"title": "மீடியா நீக்கப்பட்டது"
},
"extensionPermission": {
"badge": "அனுமதி இல்லை",
"button": "நீட்டிப்பைப் பயன்படுத்தவும்",
"text": "உங்களிடம் உலாவி நீட்டிப்பு உள்ளது, ஆனால் நீட்டிப்பைப் பயன்படுத்தத் தொடங்க உங்கள் அனுமதி தேவை.",
"title": "நீட்டிப்பை உள்ளமைக்கவும்"
},
"failed": {
"badge": "தோல்வியடைந்தது",
"homeButton": "முகப்பிற்கு செல்",
"text": "TMDB இலிருந்து மீடியாவின் தரவுகளை ஏற்ற முடியவில்லை. உங்கள் இணைய இணைப்பில் TMDB செயலிழந்துள்ளதா அல்லது தடுக்கப்பட்டுள்ளதா என்பதைச் சரிபார்க்கவும்.",
"title": "மெட்டா டேட்டாவை ஏற்றுவதில் தோல்வி"
},
"notFound": {
"badge": "கிடைக்கவில்லை",
"homeButton": "முகப்பிற்கு செல்",
"text": "நீங்கள் கோரிய மீடியாவை எங்களால் கண்டுபிடிக்க இயலவில்லை. அது அகற்றப்பட்டிருக்கலாம் அல்லது நீங்கள் URL ஐ சேதப்படுத்தியிருக்கலாம்.",
"title": "மீடியாவைக் கண்டுபிடிக்க முடியவில்லை."
}
},
"nextEpisode": {
"cancel": "ரத்து செய்",
"next": "அடுத்த Episode"
},
"playbackError": {
"badge": "பின்னணி பிழை",
"errors": {
"errorAborted": "பயனரின் கோரிக்கையால் மீடியாவைப் பெறுவது நிறுத்தப்பட்டது.",
"errorDecode": "பயன்படுத்தக்கூடியது என்று முன்பே தீர்மானிக்கப்பட்டிருந்தாலும், மீடியாவை டிகோட் செய்ய முயற்சிக்கும்போது ஏற்பட்ட பிழை காரணமாக இந்த பிழை ஏற்பட்டுள்ளது.",
"errorGenericMedia": "அறியப்படாத மீடியா பிழை ஏற்பட்டுள்ளது.",
"errorNetwork": "மீடியா கிடைத்த போதிலும், சில நெட்ஒர்க் பிழையின் காரணமாக இந்த மீடியா இப்போது கிடைக்கப்பெறவில்லை.",
"errorNotSupported": "மீடியா அல்லது மீடியா வழங்குநர் பொருள் ஆதரிக்கப்படவில்லை."
},
"homeButton": "முகப்பிற்கு செல்",
"text": "மீடியாவை இயக்கும் முயற்சியில் பிழை ஏற்பட்டுள்ளது. தயவு செய்து மீண்டும் முயற்சிக்கவும்.",
"title": "வீடியோவை இயக்க முடியவில்லை!"
},
"scraping": {
"items": {
"failure": "பிழை ஏற்பட்டுள்ளது",
"notFound": "வீடியோ இல்லை",
"pending": "வீடியோக்களை எடுத்து கொண்டிருக்கிறது..."
},
"notFound": {
"badge": "கிடைக்கவில்லை",
"detailsButton": "விவரங்களை காட்டு",
"homeButton": "முகப்பிற்கு செல்",
"text": "எங்கள் வழங்குநர்கள் மூலம் நாங்கள் தேடினோம், நீங்கள் தேடும் மீடியாவைக் கண்டுபிடிக்க இயலவில்லை! நாங்கள் மீடியாவை host செய்யவில்லை, என்ன கிடைக்கும் என்பதில் எங்களுக்கு எந்த கட்டுப்பாடும் இல்லை. மேலும் விவரங்களுக்கு கீழே உள்ள 'விவரங்களைக் காட்டு' என்பதைக் கிளிக் செய்யவும்.",
"title": "அதை எங்களால் கண்டுபிடிக்க முடியவில்லை"
}
},
"time": {
"regular": "{{timeWatched}} / {{duration}}",
"remaining": "{{timeLeft}} மீதமுள்ள நேரம்• {{timeFinished, datetime}} அன்று முடிந்தது",
"shortRegular": "{{timeWatched}}",
"shortRemaining": "-{{timeLeft}}"
},
"turnstile": {
"description": "நீங்கள் மனிதர் தானா என்பதை உறுதி செய்யவும். இது எங்களை பாதுகாப்பாக வைத்திருக்க உதவும்!",
"error": "நீங்கள் மனிதர் என்பதை தான் சரிபார்க்க முடியவில்லை. தயவு செய்து மீண்டும் முயற்சிக்கவும்.",
"title": "நீங்கள் ஒரு மனிதர் என்பதை நாங்கள் உறுதி செய்ய வேண்டும்.",
"verifyingHumanity": "நீங்கள் மனிதர் தானா என்பதை உறுதி செய்கிறோம். காத்திருக்கவும்..."
}
},
"screens": {
"dmca": {
"text": "மூவி-வெப் DMCA தொடர்பு பக்கத்திற்கு வரவேற்கிறோம்! அறிவுசார் சொத்துரிமைகளை நாங்கள் மதிக்கிறோம் மற்றும் எந்தவொரு பதிப்புரிமைக் கவலைகளையும் விரைவாகத் தீர்க்க விரும்புகிறோம். உங்கள் பதிப்புரிமை பெற்ற வேலை எங்கள் தளத்தில் தவறாகப் பயன்படுத்தப்பட்டதாக நீங்கள் நம்பினால், கீழே உள்ள மின்னஞ்சலுக்கு விரிவான DMCA அறிவிப்பை அனுப்பவும். பதிப்புரிமை பெற்ற உள்ளடக்கத்தின் விளக்கம், உங்கள் தொடர்பு விவரங்கள் மற்றும் நல்ல நம்பிக்கையின் அறிக்கையைச் சேர்க்கவும். இந்த விஷயங்களை உடனடியாகத் தீர்ப்பதற்கு நாங்கள் கடமைப்பட்டுள்ளோம், மேலும் மூவி-வெப் படைப்பாற்றல் மற்றும் பதிப்புரிமைகளை மதிக்கும் இடமாக வைத்திருப்பதில் உங்கள் ஒத்துழைப்பைப் பாராட்டுகிறோம்.",
"title": "DMCA"
},
"loadingApp": "பயன்பாட்டை நிறுவுகிறது",
"loadingUser": "Profile லோட் செய்யப்படுகிறது",
"loadingUserError": {
"logout": "வெளியேறு",
"reset": "Custom server யை மீட்டமைக்கவும்",
"text": "Profile லோட் செய்ய முடியவில்லை",
"textWithReset": "உங்கள் Profile Custom Server இல் இருந்து லோட் செய்ய இயலவில்லை. மீண்டும் Default Server க்கு மாற்றியமைக்க விரும்புகிறீர்களா?"
},
"migration": {
"failed": "உங்கள் தரவுகளை புதுப்பிக்க இயலவில்லை.",
"inProgress": "தயவு செய்து காத்திருக்கவும், நாங்கள் உங்கள் தரவுகளை சேமித்து கொண்டு இருக்கிறோம். இதற்கு அதிக நேரம் தேவைப்படாது."
}
},
"settings": {
"account": {
"accountDetails": {
"deviceNameLabel": "சாதனத்தின் பெயர்",
"deviceNamePlaceholder": "தனிப்பட்ட போன்",
"editProfile": "எடிட்",
"logoutButton": "வெளியேறு"
},
"actions": {
"delete": {
"button": "கணக்கை நீக்குக",
"confirmButton": "கணக்கை நீக்குக",
"confirmDescription": "உங்கள் கணக்கை நிச்சயமாக நீக்க விரும்புகிறீர்களா? உங்கள் தரவுகள் அனைத்தும் நீக்கப்படும்!",
"confirmTitle": "நீங்கள் உறுதியா?",
"text": "இந்த நடவடிக்கை திரும்ப பெற முடியாதது. அனைத்து தரவுகளும் நீக்கப்படும் மற்றும் எதையும் மீட்டெடுக்க இயலாது.",
"title": "கணக்கை நீக்குக"
},
"title": "செயல்கள்"
},
"devices": {
"deviceNameLabel": "சாதனத்தின் பெயர்",
"failed": "சாதனத்தின் தரவுகளை காண்பிக்க இயலவில்லை",
"removeDevice": "நீக்கு",
"title": "சாதனங்கள்"
},
"profile": {
"finish": "எடிட்டிங் முடிக்கவும்",
"firstColor": "Profile நிறம் ஒன்று",
"secondColor": "Profile நிறம் இரண்டு",
"title": "Profile படத்தைத் திருத்தவும்",
"userIcon": "பயனர் icon"
},
"register": {
"cta": "தொடங்குங்கள்",
"text": "ஒன்றுக்கு மேற்பட்ட சாதனங்களுக்கு இடையே உங்களின் காட்சி நேரத்தை பகிர்ந்து அவற்றை ஒத்திசைத்து வைக்கவும்.",
"title": "Cloud இல் Sync செய்யவும்"
},
"title": "கணக்கு"
},
"appearance": {
"activeTheme": "செயலில் உள்ளது",
"themes": {
"blue": "நீலம்",
"default": "இயல்பு அமைப்பு",
"gray": "சாம்பல்",
"red": "சிவப்பு",
"teal": "அடர் பச்சை"
},
"title": "தோற்றம்"
},
"connections": {
"server": {
"description": "நீங்கள் உங்கள் தரவுகளை உங்களின் தனிப்பட்ட பின்தளம் (Backend) இல் சேமிக்க விரும்பினால் இதை தெரிவு செய்து URL யை உள்ளீடு செய்யவும்",
"label": "தனிப்பயன் சர்வர்",
"urlLabel": "தனிப்பட்ட சர்வரின் URL"
},
"setup": {
"doSetup": "அமைக்கவும்",
"errorStatus": {
"description": "இந்த அமைப்பில் உள்ள ஒன்று அல்லது அதற்கு மேற்பட்ட உருப்படிகளுக்கு உங்கள் கவனம் தேவை என்று தெரிகிறது.",
"title": "உங்களின் கவனம் இங்கு தேவைப்படுகிறது"
},
"itemError": "இந்த அமைப்பில் ஏதோ தவறு உள்ளது. அதை சரிசெய்ய மீண்டும் அமைவு வழியாக செல்லவும்.",
"items": {
"default": "இயல்புநிலை அமைப்பு",
"extension": "நீட்டிப்பு",
"proxy": "தனிப்பயன் Proxy"
},
"redoSetup": "அமைப்பை மீண்டும் செய்",
"successStatus": {
"description": "உங்களுக்குப் பிடித்த மீடியாவைப் பார்க்கத் தொடங்குவதற்கு அனைத்து விஷயங்களும் இங்கு உள்ளன.",
"title": "அணைத்தும் சரியாக உள்ளது!"
},
"unsetStatus": {
"description": "Setup Process யை தொடங்க வலதுபுறத்தில் உள்ள பொத்தானைக் கிளிக் செய்யவும்.",
"title": "நீங்கள் அமைப்பிற்குச் செல்லவில்லை"
}
},
"title": "இணைப்புகள்",
"workers": {
"addButton": "புதிய worker யை சேர்க்கவும்",
"description": "இந்த பயன்பாடு செயல்பட அனைத்து இணைய போக்குவரத்தும் இந்த proxies வழியாக அனுப்பப்பட உள்ளது. உங்களின் தனிப்பட்ட workers யை உபயோகிக்க இதை தெரிவு செய்யவும். <0>வழிமுறைகள்.</0>",
"emptyState": "எந்தவொரு workers ம் இல்லை. கீழே புதியதாக சேர்க்கவும்",
"label": "Custom proxy workers யை உபயோகப்படுத்த",
"urlLabel": "Worker URL கள்",
"urlPlaceholder": "https://"
}
},
"preferences": {
"language": "பயன்பாட்டின் மொழி",
"languageDescription": "பயன்பாடு முழுமைக்கும் மொழி பயன்படுத்தப்பட்டது.",
"thumbnail": "சிறுபடங்களை உருவாக்கவும்",
"thumbnailDescription": "பெரும்பாலான நேரங்களில், வீடியோக்களில் சிறுபடங்கள் இருக்காது. அவற்றை உருவாக்க இந்த அமைப்பை நீங்கள் இயக்கலாம். ஆனால் அவை உங்கள் வீடியோவை மெதுவாக்கும்.",
"thumbnailLabel": "சிறுபடங்களை உருவாக்கவும்",
"title": "விருப்பங்கள்"
},
"reset": "மீட்டமை",
"save": "சேமி",
"sidebar": {
"info": {
"appVersion": "பயன்பாட்டின் பதிப்பு",
"backendUrl": "பின்தள URL",
"backendVersion": "பின்தள பதிப்பு",
"hostname": "Hostname",
"insecure": "பாதுகாப்பற்றது",
"notLoggedIn": "நீங்கள் உள்நுழையவில்லை",
"secure": "பாதுகாப்பானது",
"title": "பயன்பாட்டின் தகவல்கள்",
"unknownVersion": "தெரியவில்லை",
"userId": "பயனர் ID"
}
},
"subtitles": {
"backgroundLabel": "பின்னணி ஒளிபுகாநிலை (Background opacity)",
"colorLabel": "நிறம்",
"previewQuote": "நான் பயப்படக்கூடாது. பயம் மனதைக் கொல்லும்.",
"textSizeLabel": "எழுத்து அளவு",
"title": "வசன வரிகள்"
},
"unsaved": "உங்களிடம் சேமிக்கப்படாத மாற்றங்கள் உள்ளன"
}
}

View File

@@ -115,7 +115,10 @@
"failed": "ไม่พบสื่อนี้ ลองอีกครั้ง!",
"loading": "กำลังโหลด..",
"noResults": "เราไม่พบอะไรเลย!",
"placeholder": "คุณอยากดูอะไรคะ?",
"placeholder": {
"default": "คุณอยากดูอะไรคะ?",
"extra": []
},
"sectionTitle": "ผลการค้นหา"
},
"titles": {
@@ -124,15 +127,11 @@
},
"morning": {
"default": "คุณอยากดูอะไรเช้านี้?",
"extra": [
"ฉันได้ยินมาว่าเรื่อง Before Sunrise สนุก"
]
"extra": ["ฉันได้ยินมาว่าเรื่อง Before Sunrise สนุก"]
},
"night": {
"default": "คุณอยากดูเรื่องอะไรในช่วงค่ำ?",
"extra": [
"เหนื่อยมั้ย? ฉันได้ยินมาว่า The Exorcist นั้นดี"
]
"extra": ["เหนื่อยมั้ย? ฉันได้ยินมาว่า The Exorcist นั้นดี"]
}
}
},

View File

@@ -115,27 +115,24 @@
"failed": "lukin li pakala a! o alasa sin",
"loading": "alasa...",
"noResults": "ijo li lon ala a!",
"placeholder": "sina wile lukin e seme?",
"placeholder": {
"default": "sina wile lukin e seme?",
"extra": []
},
"sectionTitle": "mi lukin e ni:"
},
"titles": {
"day": {
"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": {
"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": {
"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"]
}
}
},

View File

@@ -116,7 +116,10 @@
"failed": "Medya bulunamadı, tekrar deneyin!",
"loading": "Yükleniyor...",
"noResults": "Hiçbir şey bulamadık!",
"placeholder": "Ne izlemek istersiniz?",
"placeholder": {
"default": "Ne izlemek istersiniz?",
"extra": []
},
"sectionTitle": "Arama sonuçları"
},
"titles": {
@@ -128,15 +131,11 @@
},
"morning": {
"default": "Bu sabah ne izlemek istersiniz?",
"extra": [
"Before Sunrise'a iyi diyorlar"
]
"extra": ["Before Sunrise'a iyi diyorlar"]
},
"night": {
"default": "Bu akşam ne izlemek istersiniz?",
"extra": [
"Yoruldun mu? The Exorcist'e iyi diyorlar."
]
"extra": ["Yoruldun mu? The Exorcist'e iyi diyorlar."]
}
}
},

View File

@@ -116,7 +116,10 @@
"failed": "Не вдалося знайти медіафайли, повторіть спробу!",
"loading": "Завантаження...",
"noResults": "Ми не змогли знайти нічого!",
"placeholder": "Що ви хочете подивитися?",
"placeholder": {
"default": "Що ви хочете подивитися?",
"extra": []
},
"sectionTitle": "Результати пошуку"
},
"titles": {
@@ -128,15 +131,11 @@
},
"morning": {
"default": "Що б ви хотіли подивитися сьогодні вранці?",
"extra": [
"Я чув, що \"Перед сходом сонця\" гарний"
]
"extra": ["Я чув, що \"Перед сходом сонця\" гарний"]
},
"night": {
"default": "Що б ви хотіли подивитися сьогодні ввечері?",
"extra": [
"Втомився? Я чув, що \"Екзорцист\" хороший."
]
"extra": ["Втомився? Я чув, що \"Екзорцист\" хороший."]
}
}
},

View File

@@ -116,12 +116,30 @@
"failed": "Không thể tìm thấy nội dung, hãy thử lại!",
"loading": "Đang tải...",
"noResults": "Chúng tôi không thể tìm thấy gì!",
"placeholder": "Bạn muốn xem gì?",
"placeholder": {
"default": "Bạn muốn xem gì?",
"extra": []
},
"sectionTitle": "Kết quả tìm kiếm"
},
"titles": {
"day": {
"default": "Chiều nay bạn muốn coi gì?",
"extra": [
"Cảm thấy muốn phiêu lưu? Phim Công viên kỷ Jura có thể là sự lựa chọn hoàn hảo cho bạn."
]
},
"morning": {
"default": "Sáng nay bạn muốn coi gì?",
"extra": [
"Tôi nghe nói rằng bộ phim Before Sunrise hay đấy"
]
},
"night": {
"default": "Đêm nay bạn muốn coi gì?"
"default": "Đêm nay bạn muốn coi gì?",
"extra": [
"Cảm thấy mệt? Tôi nghe nói phim The Exorcist hay đấy."
]
}
}
},
@@ -140,6 +158,7 @@
"about": "Về chúng tôi",
"donation": "Ủng hộ",
"logout": "Đăng xuất",
"register": "Đồng bộ hóa với đám mây",
"settings": "Cài đặt",
"support": "Hỗ trợ"
}
@@ -158,7 +177,8 @@
"title": "Bạn có chắc không?"
},
"extension": {
"back": "Trở lại"
"back": "Trở lại",
"explainer": "Bạn có thể sử dụng các nguồn tốt nhất mà chúng tôi cung cấp bằng cách sử dụng tiện ích mở rộng trình duyệt. Đơn giản chỉ cần cài đặt."
}
},
"player": {

View File

@@ -116,27 +116,24 @@
"failed": "未能找到媒體,請重試!",
"loading": "載入中...",
"noResults": "我们找不到任何结果!",
"placeholder": "您想看什麼?",
"placeholder": {
"default": "您想看什麼?",
"extra": []
},
"sectionTitle": "搜索結果"
},
"titles": {
"day": {
"default": "您今天下午想看什麼?",
"extra": [
"想要來場冒險嗎?《侏羅紀公園》可能是完美選擇。"
]
"extra": ["想要來場冒險嗎?《侏羅紀公園》可能是完美選擇。"]
},
"morning": {
"default": "您今天早上想看什麼?",
"extra": [
"我聽說《情留半天》不錯"
]
"extra": ["我聽說《情留半天》不錯"]
},
"night": {
"default": "您今晚想看什麼?",
"extra": [
"疲倦了嗎?我聽說《驅魔人》不錯。"
]
"extra": ["疲倦了嗎?我聽說《驅魔人》不錯。"]
}
}
},

View File

@@ -57,6 +57,8 @@
},
"host": "您正在连接到 <0>{{hostname}}</0> - 在创建账户前,确保您信任它",
"no": "返回",
"noHost": "服务器尚未进行配置,因此您无法创建账户",
"noHostTitle": "未配置服务器!",
"title": "您是否信任这个服务器?",
"yes": "我信任这个服务器"
},
@@ -71,11 +73,11 @@
}
},
"errors": {
"badge": "它已损坏",
"badge": "坏",
"details": "错误细节",
"reloadPage": "刷新页面",
"showError": "显示错误细节",
"title": "我们遇到错误!"
"title": "我们遇到错误!"
},
"footer": {
"legal": {
@@ -116,7 +118,15 @@
"failed": "查找媒体失败,请重试!",
"loading": "载入中……",
"noResults": "我们找不到任何结果!",
"placeholder": "您想看些什么?",
"placeholder": {
"default": "您想看些什么?",
"extra": [
"您想探索些什么?",
"您的片单上都有啥?",
"您最喜欢的影片是什么?",
"您最喜欢的剧目是什么?"
]
},
"sectionTitle": "搜索结果"
},
"titles": {
@@ -242,6 +252,7 @@
},
"menus": {
"downloads": {
"copyHlsPlaylist": "复制 HLS 播放列表链接",
"disclaimer": "下载内容是直接从内容提供者获取的。movie-web 无法控制下载内容如何被提供。",
"downloadSubtitle": "下载当前字幕",
"downloadVideo": "下载视频",

View File

@@ -1,6 +1,6 @@
import { satisfies } from "semver";
const allowedExtensionRange = "~1.0.2";
const allowedExtensionRange = "^1.0.2";
export function isAllowedExtensionVersion(version: string): boolean {
return satisfies(version, allowedExtensionRange);

View File

@@ -6,6 +6,11 @@ import {
import { isAllowedExtensionVersion } from "@/backend/extension/compatibility";
import { ExtensionMakeRequestResponse } from "@/backend/extension/plasmo";
export const RULE_IDS = {
PREPARE_STREAM: 1,
SET_DOMAINS_HLS: 2,
};
// for some reason, about 500 ms is needed after
// page load before the extension starts responding properly
const isExtensionReady = new Promise<void>((resolve) => {

View File

@@ -1,6 +1,6 @@
import { Stream } from "@movie-web/providers";
import { setDomainRule } from "@/backend/extension/messaging";
import { RULE_IDS, setDomainRule } from "@/backend/extension/messaging";
function extractDomain(url: string): string | null {
try {
@@ -36,7 +36,7 @@ function buildHeadersFromStream(stream: Stream): Record<string, string> {
export async function prepareStream(stream: Stream) {
await setDomainRule({
ruleId: 1,
ruleId: RULE_IDS.PREPARE_STREAM,
targetDomains: extractDomainsFromStream(stream),
requestHeaders: buildHeadersFromStream(stream),
});

View File

@@ -5,13 +5,14 @@ import { useCallback } from "react";
import { isExtensionActiveCached } from "@/backend/extension/messaging";
import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape";
import { BACKEND_URL } from "@/setup/constants";
import { useAuthStore } from "@/stores/auth";
import { PlayerMeta } from "@/stores/player/slices/source";
// for anybody who cares - these are anonymous metrics.
// They are just used for figuring out if providers are broken or not
const metricsEndpoint = "https://backend.movie-web.app/metrics/providers";
const captchaMetricsEndpoint = "https://backend.movie-web.app/metrics/captcha";
const metricsEndpoint = `${BACKEND_URL}/metrics/providers`;
const captchaMetricsEndpoint = `${BACKEND_URL}/metrics/captcha`;
const batchId = () => nanoid(32);
export type ProviderMetric = {
@@ -44,6 +45,7 @@ function getStackTrace(error: Error, lines: number) {
}
export async function reportProviders(items: ProviderMetric[]): Promise<void> {
if (!BACKEND_URL) return;
return ofetch(metricsEndpoint, {
method: "POST",
body: {
@@ -156,6 +158,7 @@ export function useReportProviders() {
}
export function reportCaptchaSolve(success: boolean) {
if (!BACKEND_URL) return;
ofetch(captchaMetricsEndpoint, {
method: "POST",
body: {

View File

@@ -5,6 +5,11 @@ import { convertSubtitlesToSrt } from "@/components/player/utils/captions";
import { CaptionListItem } from "@/stores/player/slices/source";
import { SimpleCache } from "@/utils/cache";
import {
isExtensionActiveCached,
sendExtensionRequest,
} from "../extension/messaging";
export const subtitleTypeList = list().map((type) => `.${type}`);
const downloadCache = new SimpleCache<string, string>();
downloadCache.setCompare((a, b) => a === b);
@@ -21,7 +26,22 @@ export async function downloadCaption(
let data: string | undefined;
if (caption.needsProxy) {
data = await proxiedFetch<string>(caption.url, { responseType: "text" });
if (isExtensionActiveCached()) {
const extensionResponse = await sendExtensionRequest({
url: caption.url,
method: "GET",
});
if (
!extensionResponse?.success ||
typeof extensionResponse.response.body !== "string"
) {
throw new Error("failed to get caption data from extension");
}
data = extensionResponse.response.body;
} else {
data = await proxiedFetch<string>(caption.url, { responseType: "text" });
}
} else {
data = await fetch(caption.url).then((v) => v.text());
}

View File

@@ -144,12 +144,16 @@ export function decodeTMDBId(
const baseURL = "https://api.themoviedb.org/3";
const apiKey = conf().TMDB_READ_API_KEY;
const headers = {
accept: "application/json",
Authorization: `Bearer ${conf().TMDB_READ_API_KEY}`,
Authorization: `Bearer ${apiKey}`,
};
async function get<T>(url: string, params?: object): Promise<T> {
if (!apiKey) throw new Error("TMDB API key not set");
const res = await mwFetch<any>(encodeURI(url), {
headers,
baseURL,

View File

@@ -31,10 +31,16 @@ export function Button(props: Props) {
>,
) => {
if (loading) return;
if (href && !onClick) navigate(href);
else onClick?.(event);
if (href && !onClick) {
event.preventDefault();
if (!href.includes("http")) {
navigate(href);
} else {
window.open(href, "_blank", "noreferrer");
}
} else onClick?.(event);
},
[onClick, href, navigate, loading],
[loading, href, onClick, navigate],
);
let colorClasses = "bg-white hover:bg-gray-200 text-black";

View File

@@ -25,7 +25,7 @@ export function IconPatch(props: IconPatchProps) {
return (
<div className={props.className || undefined} onClick={props.onClick}>
<div
className={`flex items-center justify-center rounded-full border-2 border-transparent backdrop-blur-lg bg-pill-background bg-opacity-50 transition-[background-color,color,transform,border-color] duration-75 ${transparentClasses} ${clickableClasses} ${activeClasses} ${sizeClasses}`}
className={`flex items-center justify-center rounded-full border-2 border-transparent bg-pill-background bg-opacity-100 transition-[background-color,color,transform,border-color] duration-75 ${transparentClasses} ${clickableClasses} ${activeClasses} ${sizeClasses}`}
>
<Icon icon={props.icon} />
</div>

View File

@@ -47,8 +47,22 @@ export function Volume(props: Props) {
if (dragging) percentage = makePercentage(dragPercentage);
const percentageString = makePercentageString(percentage);
const handleWheel = useCallback(
(event: React.WheelEvent<HTMLDivElement>) => {
event.preventDefault();
let newVolume = volume - event.deltaY / 1000;
newVolume = Math.max(0, Math.min(newVolume, 1));
setVolume(newVolume);
},
[volume, setVolume],
);
return (
<div className={props.className} onMouseEnter={handleMouseEnter}>
<div
className={props.className}
onMouseEnter={handleMouseEnter}
onWheel={handleWheel}
>
<div className="pointer-events-auto flex cursor-pointer items-center py-0">
<div className="px-4 text-2xl text-white" onClick={handleClick}>
<Icon icon={percentage > 0 ? Icons.VOLUME : Icons.VOLUME_X} />

View File

@@ -262,6 +262,14 @@ export function CaptionSettingsView({ id }: { id: string }) {
value={styling.backgroundOpacity * 100}
textTransformer={(s) => `${s}%`}
/>
<CaptionSetting
label={t("settings.subtitles.backgroundBlurLabel")}
max={100}
min={0}
onChange={(v) => updateStyling({ backgroundBlur: v / 100 })}
value={styling.backgroundBlur * 100}
textTransformer={(s) => `${s}%`}
/>
<CaptionSetting
label={t("settings.subtitles.textSizeLabel")}
max={200}

View File

@@ -4,6 +4,7 @@ import { OverlayDisplay } from "@/components/overlays/OverlayDisplay";
import { CastingInternal } from "@/components/player/internals/CastingInternal";
import { HeadUpdater } from "@/components/player/internals/HeadUpdater";
import { KeyboardEvents } from "@/components/player/internals/KeyboardEvents";
import { MediaSession } from "@/components/player/internals/MediaSession";
import { MetaReporter } from "@/components/player/internals/MetaReporter";
import { ProgressSaver } from "@/components/player/internals/ProgressSaver";
import { ThumbnailScraper } from "@/components/player/internals/ThumbnailScraper";
@@ -91,6 +92,7 @@ export function Container(props: PlayerProps) {
<VideoContainer />
<ProgressSaver />
<KeyboardEvents />
<MediaSession />
<div className="relative h-screen overflow-hidden">
<VideoClickTarget showingControls={props.showingControls} />
<HeadUpdater />

View File

@@ -55,6 +55,10 @@ export function CaptionCue({
color: styling.color,
fontSize: `${(1.5 * styling.size).toFixed(2)}em`,
backgroundColor: `rgba(0,0,0,${styling.backgroundOpacity.toFixed(2)})`,
backdropFilter:
styling.backgroundBlur !== 0
? `blur(${Math.floor(styling.backgroundBlur * 64)}px)`
: "none",
}}
>
<span

View File

@@ -1,6 +1,11 @@
import fscreen from "fscreen";
import Hls, { Level } from "hls.js";
import {
RULE_IDS,
isExtensionActiveCached,
setDomainRule,
} from "@/backend/extension/messaging";
import {
DisplayInterface,
DisplayInterfaceEvents,
@@ -31,8 +36,8 @@ const levelConversionMap: Record<number, SourceQuality> = {
480: "480",
};
function hlsLevelToQuality(level: Level): SourceQuality | null {
return levelConversionMap[level.height] ?? null;
function hlsLevelToQuality(level?: Level): SourceQuality | null {
return levelConversionMap[level?.height ?? 0] ?? null;
}
function qualityToHlsLevel(quality: SourceQuality): number | null {
@@ -144,6 +149,24 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
if (!hls) return;
reportLevels();
setupQualityForHls();
if (isExtensionActiveCached()) {
hls.on(Hls.Events.LEVEL_LOADED, async (_, data) => {
const chunkUrlsDomains = data.details.fragments.map(
(v) => new URL(v.url).hostname,
);
const chunkUrls = [...new Set(chunkUrlsDomains)];
await setDomainRule({
ruleId: RULE_IDS.SET_DOMAINS_HLS,
targetDomains: chunkUrls,
requestHeaders: {
...src.preferredHeaders,
...src.headers,
},
});
});
}
});
hls.on(Hls.Events.LEVEL_SWITCHED, () => {
if (!hls) return;

View File

@@ -0,0 +1,182 @@
import { useCallback, useEffect, useRef } from "react";
import { usePlayerStore } from "@/stores/player/store";
import { usePlayerMeta } from "../hooks/usePlayerMeta";
export function MediaSession() {
const { setDirectMeta } = usePlayerMeta();
const setShouldStartFromBeginning = usePlayerStore(
(s) => s.setShouldStartFromBeginning,
);
const shouldUpdatePositionState = useRef(false);
const lastPlaybackPosition = useRef(0);
const data = usePlayerStore.getState();
const changeEpisode = useCallback(
(change: number) => {
const nextEp = data.meta?.episodes?.find(
(v) => v.number === (data.meta?.episode?.number ?? 0) + change,
);
if (!data.meta || !nextEp) return;
const metaCopy = { ...data.meta };
metaCopy.episode = nextEp;
setShouldStartFromBeginning(true);
setDirectMeta(metaCopy);
},
[data.meta, setDirectMeta, setShouldStartFromBeginning],
);
const updatePositionState = useCallback(
(position: number) => {
// If the updated position needs to be buffered, queue an update
if (position > data.progress.buffered) {
shouldUpdatePositionState.current = true;
}
if (position > data.progress.duration) return;
lastPlaybackPosition.current = data.progress.time;
navigator.mediaSession.setPositionState({
duration: data.progress.duration,
playbackRate: data.mediaPlaying.playbackRate,
position,
});
},
[
data.mediaPlaying.playbackRate,
data.progress.buffered,
data.progress.duration,
data.progress.time,
],
);
useEffect(() => {
if (!("mediaSession" in navigator)) return;
// If the media is paused, update the navigator
if (data.mediaPlaying.isPaused) {
navigator.mediaSession.playbackState = "paused";
} else {
navigator.mediaSession.playbackState = "playing";
}
}, [data.mediaPlaying.isPaused]);
useEffect(() => {
if (!("mediaSession" in navigator)) return;
updatePositionState(data.progress.time);
}, [data.progress.time, data.mediaPlaying.playbackRate, updatePositionState]);
useEffect(() => {
if (!("mediaSession" in navigator)) return;
// If not already updating the position state, and the media is loading, queue an update
if (!shouldUpdatePositionState.current && data.mediaPlaying.isLoading) {
shouldUpdatePositionState.current = true;
}
// If the user has skipped (or MediaSession desynced) by more than 5 seconds, queue an update
if (
Math.abs(data.progress.time - lastPlaybackPosition.current) >= 5 &&
!data.mediaPlaying.isLoading &&
!shouldUpdatePositionState.current
) {
shouldUpdatePositionState.current = true;
}
// If not loading and the position state is queued, update it
if (shouldUpdatePositionState.current && !data.mediaPlaying.isLoading) {
shouldUpdatePositionState.current = false;
updatePositionState(data.progress.time);
}
lastPlaybackPosition.current = data.progress.time;
}, [updatePositionState, data.progress.time, data.mediaPlaying.isLoading]);
useEffect(() => {
if (
!("mediaSession" in navigator) ||
(!data.mediaPlaying.isLoading &&
data.mediaPlaying.isPlaying &&
!data.display)
)
return;
let title: string | undefined;
let artist: string | undefined;
if (data.meta?.type === "movie") {
title = data.meta?.title;
} else if (data.meta?.type === "show") {
artist = data.meta?.title;
title = `S${data.meta?.season?.number} E${data.meta?.episode?.number}: ${data.meta?.episode?.title}`;
}
navigator.mediaSession.metadata = new MediaMetadata({
title,
artist,
artwork: [
{
src: data.meta?.poster ?? "",
sizes: "342x513",
type: "image/png",
},
],
});
navigator.mediaSession.setActionHandler("play", () => {
if (data.mediaPlaying.isLoading) return;
data.display?.play();
updatePositionState(data.progress.time);
});
navigator.mediaSession.setActionHandler("pause", () => {
if (data.mediaPlaying.isLoading) return;
data.display?.pause();
updatePositionState(data.progress.time);
});
navigator.mediaSession.setActionHandler("seekto", (e) => {
if (!e.seekTime) return;
data.display?.setTime(e.seekTime);
updatePositionState(e.seekTime);
});
if ((data.meta?.episode?.number ?? 1) !== 1) {
navigator.mediaSession.setActionHandler("previoustrack", () => {
changeEpisode(-1);
});
} else {
navigator.mediaSession.setActionHandler("previoustrack", null);
}
if (data.meta?.episode?.number !== data.meta?.episodes?.length) {
navigator.mediaSession.setActionHandler("nexttrack", () => {
changeEpisode(1);
});
} else {
navigator.mediaSession.setActionHandler("nexttrack", null);
}
}, [
changeEpisode,
updatePositionState,
data.mediaPlaying.hasPlayedOnce,
data.mediaPlaying.isLoading,
data.progress.duration,
data.progress.time,
data.meta?.episode?.number,
data.meta?.episodes?.length,
data.display,
data.mediaPlaying,
data.meta?.episode?.title,
data.meta?.title,
data.meta?.type,
data.meta?.poster,
data.meta?.season?.number,
]);
return null;
}

View File

@@ -28,6 +28,7 @@ export function convertRunoutputToSource(out: {
return {
type: "hls",
url: out.stream.playlist,
headers: out.stream.headers,
preferredHeaders: out.stream.preferredHeaders,
};
}
@@ -50,6 +51,7 @@ export function convertRunoutputToSource(out: {
return {
type: "file",
qualities,
headers: out.stream.headers,
preferredHeaders: out.stream.preferredHeaders,
};
}

View File

@@ -63,6 +63,7 @@ export function useAuth() {
const login = useCallback(
async (loginData: LoginData) => {
if (!backendUrl) return;
const keys = await keysFromMnemonic(loginData.mnemonic);
const publicKeyBase64Url = bytesToBase64Url(keys.publicKey);
const { challenge } = await getLoginChallengeToken(
@@ -87,7 +88,7 @@ export function useAuth() {
);
const logout = useCallback(async () => {
if (!currentAccount) return;
if (!currentAccount || !backendUrl) return;
try {
await removeSession(
backendUrl,
@@ -102,6 +103,7 @@ export function useAuth() {
const register = useCallback(
async (registerData: RegistrationData) => {
if (!backendUrl) return;
const { challenge } = await getRegisterChallengeToken(
backendUrl,
registerData.recaptchaToken,
@@ -134,6 +136,7 @@ export function useAuth() {
progressItems: Record<string, ProgressMediaItem>,
bookmarks: Record<string, BookmarkMediaItem>,
) => {
if (!backendUrl) return;
if (
Object.keys(progressItems).length === 0 &&
Object.keys(bookmarks).length === 0
@@ -159,6 +162,7 @@ export function useAuth() {
const restore = useCallback(
async (account: AccountWithToken) => {
if (!backendUrl) return;
let user: { user: UserResponse; session: SessionResponse };
try {
user = await getUser(backendUrl, account.token);

View File

@@ -1,7 +1,7 @@
import { conf } from "@/setup/config";
import { useAuthStore } from "@/stores/auth";
export function useBackendUrl() {
export function useBackendUrl(): string | null {
const backendUrl = useAuthStore((s) => s.backendUrl);
return backendUrl ?? conf().BACKEND_URL;
}

View File

@@ -9,6 +9,7 @@ import {
} from "react";
import { SubtitleStyling } from "@/stores/subtitles";
import { usePreviewThemeStore } from "@/stores/theme";
export function useDerived<T>(
initial: T,
@@ -56,6 +57,11 @@ export function useSettingsState(
const [backendUrlState, setBackendUrl, resetBackendUrl, backendUrlChanged] =
useDerived(backendUrl);
const [themeState, setTheme, resetTheme, themeChanged] = useDerived(theme);
const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme);
const resetPreviewTheme = useCallback(
() => setPreviewTheme(theme),
[setPreviewTheme, theme],
);
const [
appLanguageState,
setAppLanguage,
@@ -81,6 +87,7 @@ export function useSettingsState(
function reset() {
resetTheme();
resetPreviewTheme();
resetAppLanguage();
resetSubStyling();
resetProxyUrls();

View File

@@ -33,7 +33,7 @@ import { AccountWithToken, useAuthStore } from "@/stores/auth";
import { useLanguageStore } from "@/stores/language";
import { usePreferencesStore } from "@/stores/preferences";
import { useSubtitleStore } from "@/stores/subtitles";
import { useThemeStore } from "@/stores/theme";
import { usePreviewThemeStore, useThemeStore } from "@/stores/theme";
import { SubPageLayout } from "./layouts/SubPageLayout";
import { PreferencesPart } from "./parts/settings/PreferencesPart";
@@ -70,6 +70,7 @@ export function AccountSettings(props: {
const url = useBackendUrl();
const { account } = props;
const [sessionsResult, execSessions] = useAsyncFn(() => {
if (!url) return Promise.resolve([]);
return getSessions(url, account);
}, [account, url]);
useEffect(() => {
@@ -103,6 +104,8 @@ export function SettingsPage() {
const { t } = useTranslation();
const activeTheme = useThemeStore((s) => s.theme);
const setTheme = useThemeStore((s) => s.setTheme);
const previewTheme = usePreviewThemeStore((s) => s.previewTheme);
const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme);
const appLanguage = useLanguageStore((s) => s.language);
const setAppLanguage = useLanguageStore((s) => s.setLanguage);
@@ -143,8 +146,27 @@ export function SettingsPage() {
enableThumbnails,
);
useEffect(() => {
setPreviewTheme(activeTheme ?? "default");
}, [setPreviewTheme, activeTheme]);
useEffect(() => {
// Clear preview theme on unmount
return () => {
setPreviewTheme(null);
};
}, [setPreviewTheme]);
const setThemeWithPreview = useCallback(
(theme: string) => {
state.theme.set(theme === "default" ? null : theme);
setPreviewTheme(theme);
},
[state.theme, setPreviewTheme],
);
const saveChanges = useCallback(async () => {
if (account) {
if (account && backendUrl) {
if (
state.appLanguage.changed ||
state.theme.changed ||
@@ -186,7 +208,13 @@ export function SettingsPage() {
// when backend url gets changed, log the user out first
if (state.backendUrl.changed) {
await logout();
setBackendUrl(state.backendUrl.state);
let url = state.backendUrl.state;
if (url && !url.startsWith("http://") && !url.startsWith("https://")) {
url = `https://${url}`;
}
setBackendUrl(url);
}
}, [
state,
@@ -241,7 +269,11 @@ export function SettingsPage() {
/>
</div>
<div id="settings-appearance" className="mt-48">
<ThemePart active={state.theme.state} setTheme={state.theme.set} />
<ThemePart
active={previewTheme ?? "default"}
inUse={activeTheme ?? "default"}
setTheme={setThemeWithPreview}
/>
</div>
<div id="settings-captions" className="mt-48">
<CaptionsPart

View File

@@ -10,13 +10,13 @@ export function BlurEllipsis(props: { positionClass?: string }) {
<div
className={classNames(
props.positionClass ?? "fixed",
"top-0 -right-48 rotate-[32deg] w-[50rem] h-[15rem] rounded-[70rem] bg-background-accentA blur-[100px] pointer-events-none opacity-25",
"top-0 -right-48 rotate-[32deg] w-[50rem] h-[15rem] rounded-[70rem] bg-background-accentA blur-[100px] pointer-events-none opacity-25 transition-colors duration-75",
)}
/>
<div
className={classNames(
props.positionClass ?? "fixed",
"top-0 right-48 rotate-[32deg] w-[50rem] h-[15rem] rounded-[70rem] bg-background-accentB blur-[100px] pointer-events-none opacity-25",
"top-0 right-48 rotate-[32deg] w-[50rem] h-[15rem] rounded-[70rem] bg-background-accentB blur-[100px] pointer-events-none opacity-25 transition-colors duration-75",
)}
/>
</>

View File

@@ -13,6 +13,7 @@ import {
} from "@/pages/onboarding/onboardingHooks";
import { Card, CardContent, Link } from "@/pages/onboarding/utils";
import { PageTitle } from "@/pages/parts/util/PageTitle";
import { getProxyUrls } from "@/utils/proxyUrls";
function VerticalLine(props: { className?: string }) {
return (
@@ -27,6 +28,7 @@ export function OnboardingPage() {
const skipModal = useModal("skip");
const { completeAndRedirect } = useRedirectBack();
const { t } = useTranslation();
const noProxies = getProxyUrls().length === 0;
return (
<MinimalPageLayout>
@@ -85,32 +87,34 @@ export function OnboardingPage() {
</CardContent>
</Card>
</div>
<p className="text-center hidden md:block mt-12">
<Trans i18nKey="onboarding.start.options.default.text">
<br />
<a
onClick={skipModal.show}
type="button"
className="text-onboarding-link hover:opacity-75 cursor-pointer"
/>
</Trans>
</p>
<div className=" max-w-[300px] mx-auto md:hidden mt-12 ">
<Button
className="!text-type-text !bg-opacity-50"
theme="secondary"
onClick={skipModal.show}
>
<span>
{noProxies ? null : (
<>
<p className="text-center hidden md:block mt-12">
<Trans i18nKey="onboarding.start.options.default.text">
<span />
<span />
<br />
<a
onClick={skipModal.show}
type="button"
className="text-onboarding-link hover:opacity-75 cursor-pointer"
/>
</Trans>
</span>
</Button>
</div>
</p>
<div className=" max-w-[300px] mx-auto md:hidden mt-12 ">
<Button
className="!text-type-text !bg-opacity-50"
theme="secondary"
onClick={skipModal.show}
>
<span>
<Trans i18nKey="onboarding.start.options.default.text">
<span />
<span />
</Trans>
</span>
</Button>
</div>
</>
)}
</CenterContainer>
</MinimalPageLayout>
);

View File

@@ -115,7 +115,7 @@ export function ExtensionStatus(props: {
</div>
</Card>
{lastKnownStatus === "unknown" ? <RefreshBar /> : null}
{props.showHelp ? (
{props.showHelp && props.status !== "success" ? (
<Card className="mt-4">
<div className="flex items-center space-x-7">
<Icon icon={Icons.WARNING} className="text-type-danger text-2xl" />

View File

@@ -43,7 +43,7 @@ export function OnboardingProxyPage() {
throw new Error("onboarding.proxy.input.errorNotProxy");
setProxySet([url]);
if (account) {
if (account && backendUrl) {
await updateSettings(backendUrl, account, {
proxyUrls: [url],
});

View File

@@ -32,13 +32,21 @@ export function BackendTestPart() {
value: null,
});
if (!backendUrl) {
return setStatus({
hasTested: true,
success: false,
errorText: "Backend URL is not set",
value: null,
});
}
try {
const backendData = await getBackendMeta(backendUrl);
return setStatus({
hasTested: true,
success: true,
errorText:
"Failed to call backend, double check the URL key and your internet connection",
errorText: "",
value: backendData,
});
} catch (err) {
@@ -46,7 +54,7 @@ export function BackendTestPart() {
hasTested: true,
success: false,
errorText:
"Failed to call backend, double check the URL key and your internet connection",
"Failed to call backend, double check the URL, your internet connection, and ensure CORS is properly configured on your backend.",
value: null,
});
}

View File

@@ -25,11 +25,11 @@ export function TMDBTestPart() {
errorText: "",
});
if (tmdbApiKey.length === 0) {
if (!tmdbApiKey || tmdbApiKey.length === 0) {
return setStatus({
hasTested: true,
success: false,
errorText: "TMDB api key is not set",
errorText: "TMDB API key is not set",
});
}
const isJWT = tmdbApiKey.split(".").length > 2;
@@ -37,7 +37,7 @@ export function TMDBTestPart() {
return setStatus({
hasTested: true,
success: false,
errorText: "TMDB api key is not a read only key",
errorText: "TMDB API key is not a read only key",
});
}
@@ -48,7 +48,7 @@ export function TMDBTestPart() {
hasTested: true,
success: false,
errorText:
"Failed to call tmdb, double check api key and your internet connection",
"Failed to call TMDB, double check API key and your internet connection",
});
}
@@ -61,7 +61,7 @@ export function TMDBTestPart() {
return (
<>
<Heading2 className="mb-8 mt-12">TMDB tests</Heading2>
<Heading2 className="mb-8 mt-12">TMDB test</Heading2>
<Box>
<div className="flex items-center">
<div className="flex-1">

View File

@@ -52,14 +52,18 @@ export function WorkerTestPart() {
{ id: string; status: "error" | "success"; error?: Error }[]
>([]);
const [buttonDisabled, setButtonDisabled] = useState(false);
const [testState, runTests] = useAsyncFn(async () => {
setButtonDisabled(true);
function updateWorker(id: string, data: (typeof workerState)[number]) {
setWorkerState((s) => {
return [...s.filter((v) => v.id !== id), data];
});
}
setWorkerState([]);
for (const worker of workerList) {
const workerPromises = workerList.map(async (worker) => {
try {
if (worker.url.endsWith("/")) {
updateWorker(worker.id, {
@@ -67,7 +71,7 @@ export function WorkerTestPart() {
status: "error",
error: new Error("URL ends with slash"),
});
continue;
return;
}
await singularProxiedFetch(
worker.url,
@@ -85,7 +89,10 @@ export function WorkerTestPart() {
error: err as Error,
});
}
}
});
await Promise.all(workerPromises);
setTimeout(() => setButtonDisabled(false), 5000);
}, [workerList, setWorkerState]);
return (
@@ -112,7 +119,12 @@ export function WorkerTestPart() {
})}
<Divider />
<div className="flex justify-end">
<Button theme="purple" loading={testState.loading} onClick={runTests}>
<Button
theme="purple"
loading={testState.loading}
onClick={buttonDisabled ? undefined : runTests}
disabled={buttonDisabled}
>
Test workers
</Button>
</div>

View File

@@ -52,6 +52,9 @@ export function LoginFormPart(props: LoginFormPartProps) {
throw err;
}
if (!account)
throw new Error(t("auth.login.validationError") ?? undefined);
await importData(account, progressItems, bookmarkItems);
await restore(account);

View File

@@ -22,8 +22,12 @@ interface TrustBackendPartProps {
export function TrustBackendPart(props: TrustBackendPartProps) {
const navigate = useNavigate();
const backendUrl = useBackendUrl();
const hostname = useMemo(() => new URL(backendUrl).hostname, [backendUrl]);
const hostname = useMemo(
() => (backendUrl ? new URL(backendUrl).hostname : undefined),
[backendUrl],
);
const result = useAsync(() => {
if (!backendUrl) return Promise.resolve(null);
return getBackendMeta(backendUrl);
}, [backendUrl]);
const { t } = useTranslation();
@@ -50,38 +54,52 @@ export function TrustBackendPart(props: TrustBackendPartProps) {
return (
<LargeCard>
<LargeCardText
title={t("auth.trust.title")}
title={hostname ? t("auth.trust.title") : t("auth.trust.noHostTitle")}
icon={<Icon icon={Icons.CIRCLE_EXCLAMATION} />}
>
<Trans
i18nKey="auth.trust.host"
values={{
hostname,
}}
>
<span className="text-white" />
</Trans>
{hostname ? (
<Trans
i18nKey="auth.trust.host"
values={{
hostname,
}}
>
<span className="text-white" />
</Trans>
) : (
<p>{t("auth.trust.noHost")}</p>
)}
</LargeCardText>
<div className="border border-authentication-border rounded-xl px-4 py-8 flex flex-col items-center space-y-2 my-8">
{cardContent}
</div>
<LargeCardButtons>
<Button theme="secondary" onClick={() => navigate("/")}>
{t("auth.trust.no")}
</Button>
<Button
theme="purple"
onClick={() => result.value && props.onNext?.(result.value)}
>
{t("auth.trust.yes")}
</Button>
</LargeCardButtons>
<p className="text-center mt-6">
<Trans i18nKey="auth.hasAccount">
<MwLink to="/login">.</MwLink>
</Trans>
</p>
{hostname ? (
<>
<div className="border border-authentication-border rounded-xl px-4 py-8 flex flex-col items-center space-y-2 my-8">
{cardContent}
</div>
<LargeCardButtons>
<Button theme="secondary" onClick={() => navigate("/")}>
{t("auth.trust.no")}
</Button>
<Button
theme="purple"
onClick={() => result.value && props.onNext?.(result.value)}
>
{t("auth.trust.yes")}
</Button>
</LargeCardButtons>
<p className="text-center mt-6">
<Trans i18nKey="auth.hasAccount">
<MwLink to="/login">.</MwLink>
</Trans>
</p>
</>
) : (
<LargeCardButtons>
<Button theme="purple" onClick={() => navigate("/")}>
{t("auth.trust.no")}
</Button>
</LargeCardButtons>
)}
</LargeCard>
);
}

View File

@@ -47,6 +47,8 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
const [result, execute] = useAsyncFn(
async (inputMnemonic: string) => {
if (!backendUrl)
throw new Error(t("auth.verify.noBackendUrl") ?? undefined);
if (!props.mnemonic || !props.userData)
throw new Error(t("auth.verify.invalidData") ?? undefined);
@@ -68,6 +70,9 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
recaptchaToken,
});
if (!account)
throw new Error(t("auth.verify.registrationFailed") ?? undefined);
await importData(account, progressItems, bookmarkItems);
await updateSettings(backendUrl, account, {

View File

@@ -1,5 +1,4 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import Sticky from "react-sticky-el";
import { useWindowSize } from "react-use";
@@ -26,7 +25,6 @@ function getTimeOfDay(date: Date): "night" | "morning" | "day" {
export function HeroPart({ setIsSticky, searchParams }: HeroPartProps) {
const { t: randomT } = useRandomTranslation();
const { t } = useTranslation();
const [search, setSearch, setSearchUnFocus] = searchParams;
const [, setShowBg] = useState(false);
const bannerSize = useBannerSize();
@@ -54,7 +52,7 @@ export function HeroPart({ setIsSticky, searchParams }: HeroPartProps) {
const time = getTimeOfDay(new Date());
const title = randomT(`home.titles.${time}`);
const placeholder = randomT(`home.search.placeholder`);
const inputRef = useRef<HTMLInputElement>(null);
useSlashFocus(inputRef);
@@ -77,7 +75,7 @@ export function HeroPart({ setIsSticky, searchParams }: HeroPartProps) {
onChange={setSearch}
value={search}
onUnFocus={setSearchUnFocus}
placeholder={t("home.search.placeholder") ?? ""}
placeholder={placeholder ?? ""}
/>
</Sticky>
</div>

View File

@@ -18,7 +18,7 @@ export function AccountActionsPart() {
const deleteModal = useModal("account-delete");
const [deleteResult, deleteExec] = useAsyncFn(async () => {
if (!account) return;
if (!account || !url) return;
await deleteUser(url, account);
await logout();
deleteModal.hide();

View File

@@ -92,6 +92,16 @@ export function CaptionsPart(props: {
value={props.styling.backgroundOpacity * 100}
textTransformer={(s) => `${s}%`}
/>
<CaptionSetting
label={t("settings.subtitles.backgroundBlurLabel")}
max={100}
min={0}
onChange={(v) =>
props.setStyling({ ...props.styling, backgroundBlur: v / 100 })
}
value={props.styling.backgroundBlur * 100}
textTransformer={(s) => `${s}%`}
/>
<CaptionSetting
label={t("settings.subtitles.textSizeLabel")}
max={200}

View File

@@ -55,7 +55,7 @@ function ProxyEdit({ proxyUrls, setProxyUrls }: ProxyEditProps) {
</p>
<p className="max-w-[20rem] font-medium">
<Trans i18nKey="settings.connections.workers.description">
<MwLink to="https://docs.movie-web.app/proxy/deploy">
<MwLink to="https://movie-web.github.io/docs/proxy/deploy">
Proxy documentation
</MwLink>
</Trans>
@@ -125,7 +125,7 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {
</p>
<p className="max-w-[20rem] font-medium">
<Trans i18nKey="settings.connections.server.description">
<MwLink to="https://docs.movie-web.app/backend/deploy">
<MwLink to="https://movie-web.github.io/docs/backend/deploy">
Backend documentation
</MwLink>
</Trans>

View File

@@ -24,6 +24,7 @@ export function Device(props: {
const token = useAuthStore((s) => s.account?.token);
const [result, exec] = useAsyncFn(async () => {
if (!token) throw new Error("No token present");
if (!url) throw new Error("No backend set");
await removeSession(url, token, props.id);
props.onRemove?.();
}, [url, token, props.id]);

View File

@@ -14,9 +14,9 @@ import { useAuthStore } from "@/stores/auth";
const rem = 16;
function SecureBadge(props: { url: string }) {
function SecureBadge(props: { url: string | null }) {
const { t } = useTranslation();
const secure = props.url.startsWith("https://");
const secure = props.url ? props.url.startsWith("https://") : false;
return (
<div className="flex items-center gap-1 -mx-1 ml-3 px-1 rounded bg-largeCard-background font-bold">
<Icon icon={secure ? Icons.LOCK : Icons.UNLOCK} />
@@ -68,6 +68,7 @@ export function SidebarPart() {
const backendUrl = useBackendUrl();
const backendMeta = useAsync(async () => {
if (!backendUrl) return;
return getBackendMeta(backendUrl);
}, [backendUrl]);
@@ -159,7 +160,7 @@ export function SidebarPart() {
<SecureBadge url={backendUrl} />
</div>
<p className="text-white">
{backendUrl.replace(/https?:\/\//, "")}
{backendUrl?.replace(/https?:\/\//, "") ?? "—"}
</p>
</div>

View File

@@ -5,20 +5,29 @@ import { Icon, Icons } from "@/components/Icon";
import { Heading1 } from "@/components/utils/Text";
const availableThemes = [
{
id: "default",
selector: "theme-default",
key: "settings.appearance.themes.default",
},
{
id: "blue",
selector: "theme-blue",
key: "settings.appearance.themes.blue",
},
{
id: "teal",
selector: "theme-teal",
key: "settings.appearance.themes.teal",
},
{
id: "red",
selector: "theme-red",
key: "settings.appearance.themes.red",
},
{
id: "gray",
selector: "theme-gray",
key: "settings.appearance.themes.gray",
},
];
@@ -26,6 +35,7 @@ const availableThemes = [
function ThemePreview(props: {
selector?: string;
active?: boolean;
inUse?: boolean;
name: string;
onClick?: () => void;
}) {
@@ -105,7 +115,7 @@ function ThemePreview(props: {
<span
className={classNames(
"inline-block px-3 py-1 leading-tight text-sm transition-opacity duration-150 rounded-full bg-pill-activeBackground text-white/85",
props.active ? "opacity-100" : "opacity-0 pointer-events-none",
props.inUse ? "opacity-100" : "opacity-0 pointer-events-none",
)}
>
{t("settings.appearance.activeTheme")}
@@ -116,8 +126,9 @@ function ThemePreview(props: {
}
export function ThemePart(props: {
active: string | null;
setTheme: (theme: string | null) => void;
active: string;
inUse: string;
setTheme: (theme: string) => void;
}) {
const { t } = useTranslation();
@@ -125,17 +136,11 @@ export function ThemePart(props: {
<div>
<Heading1 border>{t("settings.appearance.title")}</Heading1>
<div className="grid grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-6 max-w-[700px]">
{/* default theme */}
<ThemePreview
name={t("settings.appearance.themes.default")}
selector="theme-default"
active={props.active === null}
onClick={() => props.setTheme(null)}
/>
{availableThemes.map((v) => (
<ThemePreview
selector={`theme-${v.id}`}
selector={v.selector}
active={props.active === v.id}
inUse={props.inUse === v.id}
name={t(v.key)}
key={v.id}
onClick={() => props.setTheme(v.id)}

View File

@@ -31,10 +31,10 @@ export interface RuntimeConfig {
DONATION_LINK: string;
DISCORD_LINK: string;
DMCA_EMAIL: string | null;
TMDB_READ_API_KEY: string;
TMDB_READ_API_KEY: string | null;
NORMAL_ROUTER: boolean;
PROXY_URLS: string[];
BACKEND_URL: string;
BACKEND_URL: string | null;
DISALLOWED_IDS: string[];
TURNSTILE_KEY: string | null;
CDN_REPLACEMENTS: Array<string[]>;
@@ -66,48 +66,48 @@ const env: Record<keyof Config, undefined | string> = {
HAS_ONBOARDING: import.meta.env.VITE_HAS_ONBOARDING,
};
// loads from different locations, in order: environment (VITE_{KEY}), window (public/config.js)
function getKeyValue(key: keyof Config): string | undefined {
let windowValue = (window as any)?.__CONFIG__?.[`VITE_${key}`];
if (
windowValue !== null &&
windowValue !== undefined &&
windowValue.length === 0
)
windowValue = undefined;
return env[key] ?? windowValue ?? undefined;
function coerceUndefined(value: string | null | undefined): string | undefined {
if (value == null) return undefined;
if (value.length === 0) return undefined;
return value;
}
function getKey(key: keyof Config, defaultString?: string): string {
return getKeyValue(key)?.toString() ?? defaultString ?? "";
// loads from different locations, in order: environment (VITE_{KEY}), window (public/config.js)
function getKeyValue(key: keyof Config): string | undefined {
const windowValue = (window as any)?.__CONFIG__?.[`VITE_${key}`];
return coerceUndefined(env[key]) ?? coerceUndefined(windowValue) ?? undefined;
}
function getKey(key: keyof Config): string | null;
function getKey(key: keyof Config, defaultString: string): string;
function getKey(key: keyof Config, defaultString?: string): string | null {
return getKeyValue(key)?.toString() ?? defaultString ?? null;
}
export function conf(): RuntimeConfig {
const dmcaEmail = getKey("DMCA_EMAIL");
const chromeExtension = getKey("ONBOARDING_CHROME_EXTENSION_INSTALL_LINK");
const firefoxExtension = getKey("ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK");
const proxyInstallLink = getKey("ONBOARDING_PROXY_INSTALL_LINK");
const turnstileKey = getKey("TURNSTILE_KEY");
return {
APP_VERSION,
GITHUB_LINK,
DONATION_LINK,
DISCORD_LINK,
DMCA_EMAIL: dmcaEmail.length > 0 ? dmcaEmail : null,
ONBOARDING_CHROME_EXTENSION_INSTALL_LINK:
chromeExtension.length > 0 ? chromeExtension : null,
ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK:
firefoxExtension.length > 0 ? firefoxExtension : null,
ONBOARDING_PROXY_INSTALL_LINK:
proxyInstallLink.length > 0 ? proxyInstallLink : null,
DMCA_EMAIL: getKey("DMCA_EMAIL"),
ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: getKey(
"ONBOARDING_CHROME_EXTENSION_INSTALL_LINK",
),
ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK: getKey(
"ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK",
),
ONBOARDING_PROXY_INSTALL_LINK: getKey("ONBOARDING_PROXY_INSTALL_LINK"),
BACKEND_URL: getKey("BACKEND_URL", BACKEND_URL),
TMDB_READ_API_KEY: getKey("TMDB_READ_API_KEY"),
PROXY_URLS: getKey("CORS_PROXY_URL")
PROXY_URLS: getKey("CORS_PROXY_URL", "")
.split(",")
.map((v) => v.trim()),
.map((v) => v.trim())
.filter((v) => v.length > 0),
NORMAL_ROUTER: getKey("NORMAL_ROUTER", "false") === "true",
HAS_ONBOARDING: getKey("HAS_ONBOARDING", "false") === "true",
TURNSTILE_KEY: turnstileKey.length > 0 ? turnstileKey : null,
TURNSTILE_KEY: getKey("TURNSTILE_KEY"),
DISALLOWED_IDS: getKey("DISALLOWED_IDS", "")
.split(",")
.map((v) => v.trim())

View File

@@ -1,6 +1,6 @@
export const APP_VERSION = import.meta.env.PACKAGE_VERSION;
export const DISCORD_LINK = "https://discord.movie-web.app";
export const DISCORD_LINK = "https://movie-web.github.io/links/discord";
export const GITHUB_LINK = "https://github.com/movie-web/movie-web";
export const DONATION_LINK = "https://ko-fi.com/movieweb";
export const GA_ID = "G-44YVXRL61C";
export const BACKEND_URL = "https://backend.movie-web.app";
export const GA_ID = import.meta.env.VITE_GA_ID;
export const BACKEND_URL = import.meta.env.VITE_BACKEND_URL;

View File

@@ -2,8 +2,10 @@ import ReactGA from "react-ga4";
import { GA_ID } from "@/setup/constants";
ReactGA.initialize([
{
trackingId: GA_ID,
},
]);
if (GA_ID) {
ReactGA.initialize([
{
trackingId: GA_ID,
},
]);
}

View File

@@ -10,6 +10,7 @@ export function Banner(props: {
id: string;
}) {
const [ref] = useRegisterBanner<HTMLDivElement>(props.id);
const hideBanner = useBannerStore((s) => s.hideBanner);
const styles = {
error: "bg-[#C93957] text-white",
};
@@ -29,6 +30,12 @@ export function Banner(props: {
<Icon icon={icons[props.type]} />
<div>{props.children}</div>
</div>
<span
className="absolute right-4 hover:cursor-pointer"
onClick={() => hideBanner(props.id, true)}
>
<Icon icon={Icons.X} />
</span>
</div>
</div>
);
@@ -38,6 +45,7 @@ export function BannerLocation(props: { location?: string }) {
const { t } = useTranslation();
const isOnline = useBannerStore((s) => s.isOnline);
const setLocation = useBannerStore((s) => s.setLocation);
const ignoredBannerIds = useBannerStore((s) => s.ignoredBannerIds);
const currentLocation = useBannerStore((s) => s.location);
const loc = props.location ?? null;
@@ -53,7 +61,7 @@ export function BannerLocation(props: { location?: string }) {
return (
<div>
{!isOnline ? (
{!isOnline && !ignoredBannerIds.includes("offline") ? (
<Banner id="offline" type="error">
{t("navigation.banner.offline")}
</Banner>

View File

@@ -13,9 +13,10 @@ interface BannerStore {
isOnline: boolean;
isTurnstile: boolean;
location: string | null;
ignoredBannerIds: string[];
updateHeight(id: string, height: number): void;
showBanner(id: string): void;
hideBanner(id: string): void;
hideBanner(id: string, force?: boolean): void;
setLocation(loc: string | null): void;
updateOnline(isOnline: boolean): void;
updateTurnstile(isTurnstile: boolean): void;
@@ -27,6 +28,7 @@ export const useBannerStore = create(
isOnline: true,
isTurnstile: false,
location: null,
ignoredBannerIds: [],
updateOnline(isOnline) {
set((s) => {
s.isOnline = isOnline;
@@ -45,14 +47,16 @@ export const useBannerStore = create(
showBanner(id) {
set((s) => {
if (s.banners.find((v) => v.id === id)) return;
if (s.ignoredBannerIds.includes(id)) return;
s.banners.push({
id,
height: 0,
});
});
},
hideBanner(id) {
hideBanner(id, force = false) {
set((s) => {
if (force) s.ignoredBannerIds.push(id);
s.banners = s.banners.filter((v) => v.id !== id);
});
},

View File

@@ -60,6 +60,7 @@ export function BookmarkSyncer() {
useEffect(() => {
const interval = setInterval(() => {
(async () => {
if (!url) return;
const state = useBookmarkStore.getState();
const user = useAuthStore.getState();
await syncBookmarks(

View File

@@ -14,6 +14,7 @@ export type SourceFileStream = {
export type LoadableSource = {
type: StreamType;
url: string;
headers?: Stream["headers"];
preferredHeaders?: Stream["preferredHeaders"];
};
@@ -21,11 +22,13 @@ export type SourceSliceSource =
| {
type: "file";
qualities: Partial<Record<SourceQuality, SourceFileStream>>;
headers?: Stream["headers"];
preferredHeaders?: Stream["preferredHeaders"];
}
| {
type: "hls";
url: string;
headers?: Stream["headers"];
preferredHeaders?: Stream["preferredHeaders"];
};

View File

@@ -62,6 +62,7 @@ export function ProgressSyncer() {
useEffect(() => {
const interval = setInterval(() => {
(async () => {
if (!url) return;
const state = useProgressStore.getState();
const user = useAuthStore.getState();
await syncProgress(

View File

@@ -16,6 +16,7 @@ export function SettingsSyncer() {
useEffect(() => {
const interval = setInterval(() => {
(async () => {
if (!url) return;
const state = useSubtitleStore.getState();
const user = useAuthStore.getState();
if (state.lastSync.lastSelectedLanguage === state.lastSelectedLanguage)

View File

@@ -17,6 +17,11 @@ export interface SubtitleStyling {
* background opacity, ranges between 0 and 1
*/
backgroundOpacity: number;
/**
* background blur, ranges between 0 and 1
*/
backgroundBlur: number;
}
export interface SubtitleStore {
@@ -51,6 +56,7 @@ export const useSubtitleStore = create(
color: "#ffffff",
backgroundOpacity: 0.5,
size: 1,
backgroundBlur: 0.5,
},
resetSubtitleSpecificSettings() {
set((s) => {
@@ -62,6 +68,8 @@ export const useSubtitleStore = create(
set((s) => {
if (newStyling.backgroundOpacity !== undefined)
s.styling.backgroundOpacity = newStyling.backgroundOpacity;
if (newStyling.backgroundBlur !== undefined)
s.styling.backgroundBlur = newStyling.backgroundBlur;
if (newStyling.color !== undefined)
s.styling.color = newStyling.color.toLowerCase();
if (newStyling.size !== undefined)

Some files were not shown because too many files have changed in this diff Show More