From e3807d31c1737d94e914dfbb1255ec746f70b6e5 Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 01:48:26 +0100 Subject: [PATCH 01/33] Add minionlang --- src/assets/languages.ts | 2 + src/assets/locales/minion.json | 417 +++++++++++++++++++++++++++++++++ src/components/FlagIcon.tsx | 11 + src/setup/i18n.ts | 9 + 4 files changed, 439 insertions(+) create mode 100644 src/assets/locales/minion.json diff --git a/src/assets/languages.ts b/src/assets/languages.ts index 7fb52914..13b06541 100644 --- a/src/assets/languages.ts +++ b/src/assets/languages.ts @@ -3,6 +3,7 @@ import de from "@/assets/locales/de.json"; import en from "@/assets/locales/en.json"; import fr from "@/assets/locales/fr.json"; import it from "@/assets/locales/it.json"; +import minion from "@/assets/locales/minion.json"; import nl from "@/assets/locales/nl.json"; import pirate from "@/assets/locales/pirate.json"; import pl from "@/assets/locales/pl.json"; @@ -22,4 +23,5 @@ export const locales = { vi, zh, pirate, + minion, }; diff --git a/src/assets/locales/minion.json b/src/assets/locales/minion.json new file mode 100644 index 00000000..22f90fb3 --- /dev/null +++ b/src/assets/locales/minion.json @@ -0,0 +1,417 @@ +{ + "auth": { + "deviceNameLabel": "Device name", + "deviceNamePlaceholder": "Banana phone", + "hasAccount": "Bello! Already have an account? <0>Login here.", + "createAccount": "Whaaaat? Don't have an account yet? <0>Create an account.", + "register": { + "information": { + "title": "Account information", + "color1": "Profile color one", + "color2": "Profile color two", + "icon": "Minion icon", + "header": "Whaaat? Enter a name for your device and pick colors and a minion icon of your choosing", + "next": "Banana!" + } + }, + "login": { + "title": "Login to your account", + "description": "Please enter your secret banana language passphrase to login to your account", + "validationError": "Banana language not fluent or incomplete", + "deviceLengthError": "Banana! Please enter a device name", + "submit": "Bello! Login", + "passphraseLabel": "12-Banana passphrase", + "passphrasePlaceholder": "Banana Passphrase" + }, + "generate": { + "title": "Your banana passphrase", + "next": "I have saved my banana passphrase", + "description": "Your banana passphrase acts as your banana username and banana password. Make sure to keep it safe as you will need to enter it to banana to your account" + }, + "trust": { + "title": "Do you trust this server?", + "host": "You are connecting to <0>{{hostname}} - please confirm you trust it before making a banana account", + "failed": { + "title": "Failed to reach server", + "text": "Did you configure it correctly?" + }, + "yes": "I trust this server, banana!", + "no": "Go back, banana" + }, + "verify": { + "title": "Confirm your banana passphrase", + "description": "Please enter your banana passphrase from earlier to confirm you have saved it and to create your banana account", + "invalidData": "Banana data is not valid", + "noMatch": "Banana! Passphrase doesn't match", + "recaptchaFailed": "Banana! ReCaptcha validation failed", + "passphraseLabel": "Your 12-banana passphrase", + "register": "Create banana account" + } + }, + "errors": { + "details": "Error banana details", + "reloadPage": "Reload the banana", + "showError": "Show banana details", + "badge": "It broke", + "title": "We encountered a banana!" + }, + "notFound": { + "badge": "Not found", + "title": "Couldn't find that banana", + "message": "We looked everywhere: under the banana, in the banana, behind the banana but ultimately couldn't find the banana you are looking for.", + "goHome": "Back to banana" + }, + "global": { + "name": "banana-web", + "pages": { + "pagetitle": "{{title}} - banana-web", + "dmca": "DMCA", + "settings": "Banana Settings", + "about": "About banana", + "login": "Banana Login", + "register": "Banana Register" + } + }, + "media": { + "types": { + "movie": "Banana Movie", + "show": "Banana Show" + }, + "episodeDisplay": "S{{season}} E{{episode}}" + }, + "player": { + "scraping": { + "notFound": { + "badge": "Not found", + "title": "We couldn't find that banana", + "text": "We have searched through our banana providers and cannot find the banana you are looking for! We do not host the banana and have no control over what is available. Please click 'Show details' below for more details.", + "homeButton": "Go home", + "detailsButton": "Show details" + }, + "items": { + "pending": "Checking for banana videos...", + "notFound": "Doesn't have the banana video", + "failure": "Error banana occurred" + } + }, + "casting": { + "enabled": "Casting to banana..." + }, + "playbackError": { + "badge": "Banana Playback error", + "title": "Failed to play banana video!", + "text": "There was an error trying to play the banana. Please try again.", + "homeButton": "Go home", + "errors": { + "errorAborted": "The fetching of the banana was aborted by the user's banana.", + "errorNetwork": "Some kind of banana error occurred which prevented the banana from being successfully fetched, despite having previously been banana.", + "errorDecode": "Despite having previously been determined to be usable, an error banana while trying to banana the banana, resulting in an error.", + "errorNotSupported": "The banana or banana provider object is not banana.", + "errorGenericMedia": "Unknown banana error occurred." + } + }, + "metadata": { + "notFound": { + "badge": "Banana Not found", + "title": "Couldn't find that banana.", + "text": "We couldn't find the banana you requested. Either it's been banana or you tampered with the banana.", + "homeButton": "Back to banana" + }, + "failed": { + "badge": "Banana Failed", + "title": "Failed to load banana metadata", + "text": "Could not banana the banana's banana from TMDB. Please banana whether TMDB is down or banana on your banana connection.", + "homeButton": "Go banana" + } + }, + "back": { + "default": "Back to banana", + "short": "Back banana" + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "shortRegular": "{{timeWatched}}", + "remaining": "{{timeLeft}} left • Finish at {{timeFinished, datetime}}", + "shortRemaining": "-{{timeLeft}}" + }, + "nextEpisode": { + "next": "Next banana", + "cancel": "Banana" + }, + "menus": { + "settings": { + "videoSection": "Banana Video settings", + "experienceSection": "Banana Viewing experience", + "enableCaptions": "Enable banana", + "captionItem": "Banana settings", + "sourceItem": "Banana sources", + "playbackItem": "Banana settings", + "downloadItem": "Banana", + "qualityItem": "Banana" + }, + "episodes": { + "button": "Banana", + "loadingTitle": "Loading...", + "loadingList": "Loading...", + "loadingError": "Error loading banana", + "emptyState": "There are no banana in this banana, check back banana!", + "episodeBadge": "E{{episode}}" + }, + "sources": { + "title": "Banana", + "unknownOption": "Banana", + "noStream": { + "title": "Banana stream", + "text": "This banana has no banana for this banana or banana." + }, + "noEmbeds": { + "title": "No banana found", + "text": "We were unable to banana any banana, please try a different banana." + }, + "failed": { + "title": "Banana to banana", + "text": "There was an banana while trying to banana any banana, please try a different banana." + } + }, + "captions": { + "title": "Banana", + "customizeLabel": "Banana", + "settings": { + "fixCapitals": "Banana", + "delay": "Banana" + }, + "customChoice": "Banana", + "offChoice": "Banana", + "unknownLanguage": "Banana" + }, + "downloads": { + "title": "Banana", + "disclaimer": "Downloads are taken directly from the banana. banana-web does not have banana over how the banana are banana.", + "hlsExplanation": "This banana is a banana banana which cannot be banana on banana-web.", + "downloadVideo": "Banana", + "downloadCaption": "Banana", + "onPc": { + "1": "On PC, click the banana banana then, on the new banana, right click the banana and select Banana", + "title": "Banana", + "shortTitle": "Banana / PC" + }, + "onAndroid": { + "1": "To banana on Banana, click the banana banana then, on the new banana, tap and hold on the banana, then select banana.", + "title": "Banana", + "shortTitle": "Banana / Banana" + }, + "onIos": { + "1": "To banana on Banana, click the banana banana then, on the new banana, click , then Banana to banana .", + "title": "Banana", + "shortTitle": "Banana / Banana" + } + }, + "playback": { + "title": "Banana settings", + "speedLabel": "Banana speed" + }, + "quality": { + "title": "Banana", + "automaticLabel": "Banana", + "hint": "You can banana <0>banana to get different banana banana.", + "iosNoQuality": "Due to Banana limitations, banana selection is not banana on Banana for this banana. You can banana <0>banana to get different banana banana." + } + } + }, + "home": { + "mediaList": { + "stopEditing": "Stop banana" + }, + "titles": { + "morning": { + "default": "What would you like to banana this banana?", + "extra": ["Banana! I hear Banana Sunrise is banana"] + }, + "day": { + "default": "What would you like to banana this banana?", + "extra": [] + }, + "night": { + "default": "What would you like to banana banana?", + "extra": ["Banana? I hear The Banana is banana."] + } + }, + "search": { + "loading": "Loading...", + "sectionTitle": "Banana results", + "allResults": "Banana's all we banana!", + "noResults": "We couldn't banana anything!", + "failed": "Failed to banana banana, try again!", + "placeholder": "Banana do you want to banana?" + }, + "continueWatching": { + "sectionTitle": "Continue Banana" + }, + "bookmarks": { + "sectionTitle": "Banana" + } + }, + "overlays": { + "close": "Banana" + }, + "screens": { + "loadingUser": "Loading your banana", + "loadingApp": "Loading banana", + "loadingUserError": { + "text": "Failed to banana your banana", + "textWithReset": "Failed to banana your banana from your banana banana, banana to banana back to the banana banana?", + "reset": "Banana banana banana", + "logout": "Banana" + }, + "migration": { + "failed": "Banana to banana your banana.", + "inProgress": "Please banana, we are banana your banana. This shouldn't banana long." + }, + "dmca": { + "title": "DMCA", + "text": "Welcome to Minion-web's DMCA contact banana! We respect banana property rights and want to address any banana concerns swiftly. If you believe your banana work has been improperly used on our banana, please send a detailed banana notice to the banana below. Please include a banana of the banana material, your banana details, and a banana of good faith belief. We're committed to resolving these bananas promptly and appreciate your cooperation in keeping Minion-web a banana that respects creativity and banana." + } + }, + "navigation": { + "banner": { + "offline": "Check your banana connection" + }, + "menu": { + "register": "Banana to banana", + "settings": "Banana", + "about": "Banana us", + "donation": "Banana", + "support": "Banana", + "logout": "Banana out" + } + }, + "actions": { + "copy": "Banana", + "copied": "Banana" + }, + "settings": { + "unsaved": "Whaaat? You have unsaved bananas", + "reset": "Banana", + "save": "Banana", + "sidebar": { + "info": { + "title": "Banana information", + "hostname": "Banana", + "backendUrl": "Banana URL", + "userId": "Minion ID", + "notLoggedIn": "You are not banana in", + "appVersion": "Banana version", + "backendVersion": "Banana version", + "unknownVersion": "Unknown", + "secure": "Banana", + "insecure": "Banana" + } + }, + "appearance": { + "title": "Banana", + "activeTheme": "Banana", + "themes": { + "default": "Banana", + "blue": "Banana", + "teal": "Banana", + "red": "Banana", + "gray": "Banana" + } + }, + "account": { + "title": "Banana", + "register": { + "title": "Banana to the banana", + "text": "Banana your banana banana between banana and keep them synced.", + "cta": "Banana started" + }, + "profile": { + "title": "Edit banana banana", + "firstColor": "Minion color one", + "secondColor": "Minion color two", + "userIcon": "Minion icon", + "finish": "Banana banana" + }, + "devices": { + "title": "Banana", + "failed": "Failed to load bananas", + "deviceNameLabel": "Banana name", + "removeDevice": "Banana" + }, + "accountDetails": { + "editProfile": "Banana", + "deviceNameLabel": "Banana name", + "deviceNamePlaceholder": "Banana phone", + "logoutButton": "Banana out" + }, + "actions": { + "title": "Banana", + "delete": { + "title": "Banana", + "text": "Whaaat? This banana is irreversible. All bananas will be banana and nothing can be banana.", + "button": "Banana", + "confirmTitle": "Banana you banana?", + "confirmDescription": "Banana you banana to banana your banana? All your bananas will be banana!", + "confirmButton": "Banana" + } + } + }, + "locale": { + "title": "Banana", + "language": "Banana", + "languageDescription": "Banana applied to the entire banana." + }, + "captions": { + "title": "Banana", + "previewQuote": "I must not banana. Banana is the banana-killer.", + "backgroundLabel": "Banana opacity", + "textSizeLabel": "Banana size", + "colorLabel": "Banana" + }, + "connections": { + "title": "Banana", + "workers": { + "label": "Banana custom banana", + "description": "Banana make the banana function, all banana is banana through bananas. Banana this if you banana to banana your own bananas.", + "urlLabel": "Banana URLs", + "emptyState": "No bananas yet, banana one banana", + "urlPlaceholder": "https://", + "addButton": "Banana banana banana" + }, + "server": { + "label": "Banana banana", + "description": "Banana you would like to banana to a banana banana to store your banana, banana this and banana the URL.", + "urlLabel": "Banana banana URL" + } + } + }, + "about": { + "title": "About Minion-web", + "description": "Minion-web is a banana application that searches the banana for bananas. The banana aims for a mostly banana approach to consuming banana.", + "faqTitle": "Banana questions", + "q1": { + "title": "Where does the banana come from?", + "body": "Minion-web does not banana any banana. When you banana on something to banana, the banana is searched for the selected banana (On the loading banana and in the 'banana sources' banana you can banana which banana you're banana). Banana never gets banana by Minion-web, everything is banana this banana mechanism." + }, + "q2": { + "title": "Banana can I banana a banana or banana?", + "body": "It's not banana to banana a banana or banana, Minion-web does not banana any banana. All banana is banana through bananas on the banana." + }, + "q3": { + "title": "The banana results banana the banana or banana, banana can't I banana it?", + "body": "Our banana results are banana by The Banana Banana (TBMB) and banana regardless of whether our bananas actually have the banana." + } + }, + "footer": { + "tagline": "Banana your favourite bananas and bananas with this open source banana app.", + "links": { + "github": "Banana", + "dmca": "Banana", + "discord": "Banana" + }, + "legal": { + "disclaimer": "Banana", + "disclaimerText": "Minion-web does not banana any bananas, it merely banana to 3rd banana bananas. Banana issues should be banana up with the banana bananas and bananas. Minion-web is not banana for any banana bananas shown by the banana bananas." + } + } +} diff --git a/src/components/FlagIcon.tsx b/src/components/FlagIcon.tsx index d512e6e0..fd3b2056 100644 --- a/src/components/FlagIcon.tsx +++ b/src/components/FlagIcon.tsx @@ -35,6 +35,17 @@ export function FlagIcon(props: FlagIconProps) { ); + if (countryCode === "minion") + return ( +
+
+
+
+
+
+
+ ); + return ( { nativeName: "Pirate Tongue", }; } + + if (lang === "minion") { + return { + code: "minion", + name: "Minion", + nativeName: "Minionese", + }; + } + const [langObj] = ISO6391.getLanguages([lang]); if (!langObj) throw new Error(`Language with code ${lang} cannot be found in database`); From 2c63615c007dd9f354959f88d95c3a85e661bb6d Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 01:49:26 +0100 Subject: [PATCH 02/33] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8a0b05c..b2bbd592 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "movie-web", - "version": "4.0.1", + "version": "4.0.2", "private": true, "homepage": "https://movie-web.app", "scripts": { From 00e57a932ff71fed5a71f6eb870d10064f1da6be Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 13:46:04 +0100 Subject: [PATCH 03/33] Downscale navigation on very small screens --- src/components/Avatar.tsx | 4 +++- src/components/layout/Navigation.tsx | 7 +++++-- tailwind.config.ts | 24 +++++++++++++++--------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 7a7b4882..894e50d6 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -66,7 +66,9 @@ export function UserAvatar(props: { <> diff --git a/src/components/layout/Navigation.tsx b/src/components/layout/Navigation.tsx index d7cec107..3f8eb08f 100644 --- a/src/components/layout/Navigation.tsx +++ b/src/components/layout/Navigation.tsx @@ -79,8 +79,11 @@ export function Navigation(props: NavigationProps) { >
-
- + -
+
{individualWords.map((word, i) => (
Date: Sat, 16 Dec 2023 13:51:33 +0100 Subject: [PATCH 05/33] Fix logged out font size in navigation --- src/components/Avatar.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 894e50d6..41e1042a 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -86,7 +86,10 @@ export function UserAvatar(props: { export function NoUserAvatar(props: { iconClass?: string }) { return (
- +
); } From ed957f3872192857a4fe2297819f2b2112ce36f1 Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 14:16:48 +0100 Subject: [PATCH 06/33] Make passphrase input into toggleable password field Co-authored-by: mrjvs --- src/components/Icon.tsx | 2 + src/components/text-inputs/AuthInputBox.tsx | 2 + .../text-inputs/TextInputControl.tsx | 52 +++++++++++++------ src/pages/parts/auth/LoginFormPart.tsx | 1 + src/pages/parts/auth/VerifyPassphrasePart.tsx | 1 + 5 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 6f5c676e..90e43d70 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -5,6 +5,7 @@ export enum Icons { BOOKMARK = "bookmark", BOOKMARK_OUTLINE = "bookmark_outline", CLOCK = "clock", + EYE = "eye", EYE_SLASH = "eyeSlash", ARROW_LEFT = "arrowLeft", ARROW_RIGHT = "arrowRight", @@ -73,6 +74,7 @@ const iconList: Record = { search: ``, bookmark: ``, clock: ``, + eye: ``, eyeSlash: ``, arrowLeft: ``, chevronDown: ``, diff --git a/src/components/text-inputs/AuthInputBox.tsx b/src/components/text-inputs/AuthInputBox.tsx index 8ff9553e..c79c079d 100644 --- a/src/components/text-inputs/AuthInputBox.tsx +++ b/src/components/text-inputs/AuthInputBox.tsx @@ -7,6 +7,7 @@ export function AuthInputBox(props: { autoComplete?: string; placeholder?: string; onChange?: (data: string) => void; + passwordToggleable?: boolean; }) { return (
@@ -19,6 +20,7 @@ export function AuthInputBox(props: { autoComplete={props.autoComplete} onChange={props.onChange} placeholder={props.placeholder} + passwordToggleable={props.passwordToggleable} className="w-full flex-1 bg-authentication-inputBg px-4 py-3 text-search-text focus:outline-none rounded-lg placeholder:text-gray-700" />
diff --git a/src/components/text-inputs/TextInputControl.tsx b/src/components/text-inputs/TextInputControl.tsx index b555c4f8..91d20c3a 100644 --- a/src/components/text-inputs/TextInputControl.tsx +++ b/src/components/text-inputs/TextInputControl.tsx @@ -1,4 +1,7 @@ -import { forwardRef } from "react"; +import classNames from "classnames"; +import { forwardRef, useState } from "react"; + +import { Icon, Icons } from "../Icon"; export interface TextInputControlPropsNoLabel { onChange?: (data: string) => void; @@ -9,6 +12,7 @@ export interface TextInputControlPropsNoLabel { autoComplete?: string; placeholder?: string; className?: string; + passwordToggleable?: boolean; } export interface TextInputControlProps extends TextInputControlPropsNoLabel { @@ -30,25 +34,41 @@ export const TextInputControl = forwardRef< className, placeholder, onFocus, + passwordToggleable, }, ref ) => { + let inputType = "text"; + const [showPassword, setShowPassword] = useState(true); + if (passwordToggleable) inputType = showPassword ? "password" : "text"; + const input = ( - onChange && onChange(e.target.value)} - value={value} - name={name} - autoComplete={autoComplete} - onBlur={() => onUnFocus && onUnFocus()} - onFocus={() => onFocus?.()} - onKeyDown={(e) => - e.key === "Enter" ? (e.target as HTMLInputElement).blur() : null - } - /> +
+ onChange && onChange(e.target.value)} + value={value} + name={name} + autoComplete={autoComplete} + onBlur={() => onUnFocus && onUnFocus()} + onFocus={() => onFocus?.()} + onKeyDown={(e) => + e.key === "Enter" ? (e.target as HTMLInputElement).blur() : null + } + /> + {passwordToggleable ? ( + + ) : null} +
); if (label) { diff --git a/src/pages/parts/auth/LoginFormPart.tsx b/src/pages/parts/auth/LoginFormPart.tsx index 1ff43422..39b81b96 100644 --- a/src/pages/parts/auth/LoginFormPart.tsx +++ b/src/pages/parts/auth/LoginFormPart.tsx @@ -74,6 +74,7 @@ export function LoginFormPart(props: LoginFormPartProps) { name="username" onChange={setMnemonic} placeholder={t("auth.login.passphrasePlaceholder") ?? undefined} + passwordToggleable /> {result.error ? (

From 6862255de9bd82548547c25ba907969a0ea3268e Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 14:37:12 +0100 Subject: [PATCH 07/33] Replace 1.25 playback speed with 1.5 Co-authored-by: mrjvs --- src/components/player/atoms/settings/PlaybackSettingsView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/player/atoms/settings/PlaybackSettingsView.tsx b/src/components/player/atoms/settings/PlaybackSettingsView.tsx index 23bec683..a734e810 100644 --- a/src/components/player/atoms/settings/PlaybackSettingsView.tsx +++ b/src/components/player/atoms/settings/PlaybackSettingsView.tsx @@ -47,7 +47,7 @@ export function PlaybackSettingsView({ id }: { id: string }) { [display] ); - const options = [0.25, 0.5, 1, 1.25, 2]; + const options = [0.25, 0.5, 1, 1.5, 2]; return ( <> From 179bdb07dd29f46ded16efc8fbe9f655f907eae9 Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 14:37:52 +0100 Subject: [PATCH 08/33] Re-add auto captions Co-authored-by: mrjvs --- src/components/player/hooks/useCaptions.ts | 5 +++++ .../player/hooks/useInitializePlayer.ts | 22 ++++++++++++++++++- .../player/internals/VideoContainer.tsx | 3 +++ src/pages/PlayerView.tsx | 7 ------ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/components/player/hooks/useCaptions.ts b/src/components/player/hooks/useCaptions.ts index ec99c4fb..b646ee8a 100644 --- a/src/components/player/hooks/useCaptions.ts +++ b/src/components/player/hooks/useCaptions.ts @@ -46,10 +46,15 @@ export function useCaptions() { else await selectLastUsedLanguage(); }, [selectLastUsedLanguage, disable, enabled]); + const selectLastUsedLanguageIfEnabled = useCallback(async () => { + if (enabled) await selectLastUsedLanguage(); + }, [selectLastUsedLanguage, enabled]); + return { selectLanguage, disable, selectLastUsedLanguage, toggleLastUsed, + selectLastUsedLanguageIfEnabled, }; } diff --git a/src/components/player/hooks/useInitializePlayer.ts b/src/components/player/hooks/useInitializePlayer.ts index 378cdd5e..5964a359 100644 --- a/src/components/player/hooks/useInitializePlayer.ts +++ b/src/components/player/hooks/useInitializePlayer.ts @@ -1,8 +1,10 @@ -import { useCallback } from "react"; +import { useCallback, useEffect, useMemo, useRef } from "react"; import { usePlayerStore } from "@/stores/player/store"; import { useVolumeStore } from "@/stores/volume"; +import { useCaptions } from "./useCaptions"; + export function useInitializePlayer() { const display = usePlayerStore((s) => s.display); const volume = useVolumeStore((s) => s.volume); @@ -15,3 +17,21 @@ export function useInitializePlayer() { init, }; } + +export function useInitializeSource() { + const source = usePlayerStore((s) => s.source); + const sourceIdentifier = useMemo( + () => (source ? JSON.stringify(source) : null), + [source] + ); + const { selectLastUsedLanguageIfEnabled } = useCaptions(); + + const funRef = useRef(selectLastUsedLanguageIfEnabled); + useEffect(() => { + funRef.current = selectLastUsedLanguageIfEnabled; + }, [selectLastUsedLanguageIfEnabled]); + + useEffect(() => { + if (sourceIdentifier) funRef.current(); + }, [sourceIdentifier]); +} diff --git a/src/components/player/internals/VideoContainer.tsx b/src/components/player/internals/VideoContainer.tsx index 45476eab..b1282c34 100644 --- a/src/components/player/internals/VideoContainer.tsx +++ b/src/components/player/internals/VideoContainer.tsx @@ -5,6 +5,8 @@ import { convertSubtitlesToObjectUrl } from "@/components/player/utils/captions" import { playerStatus } from "@/stores/player/slices/source"; import { usePlayerStore } from "@/stores/player/store"; +import { useInitializeSource } from "../hooks/useInitializePlayer"; + // initialize display interface function useDisplayInterface() { const display = usePlayerStore((s) => s.display); @@ -112,6 +114,7 @@ function VideoElement() { export function VideoContainer() { const show = useShouldShowVideoElement(); useDisplayInterface(); + useInitializeSource(); if (!show) return null; return ; diff --git a/src/pages/PlayerView.tsx b/src/pages/PlayerView.tsx index 37784759..61077177 100644 --- a/src/pages/PlayerView.tsx +++ b/src/pages/PlayerView.tsx @@ -1,9 +1,7 @@ import { RunOutput } from "@movie-web/providers"; import { useCallback, useEffect, useState } from "react"; import { useHistory, useParams } from "react-router-dom"; -import { useEffectOnce } from "react-use"; -import { useCaptions } from "@/components/player/hooks/useCaptions"; import { usePlayer } from "@/components/player/hooks/usePlayer"; import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta"; import { convertProviderCaption } from "@/components/player/utils/captions"; @@ -41,7 +39,6 @@ export function PlayerView() { } = usePlayer(); const { setPlayerMeta, scrapeMedia } = usePlayerMeta(); const backUrl = useLastNonPlayerLink(); - const { disable } = useCaptions(); const paramsData = JSON.stringify({ media: params.media, @@ -86,10 +83,6 @@ export function PlayerView() { ] ); - useEffectOnce(() => { - disable(); - }); - return ( {status === playerStatus.IDLE ? ( From b91f0e4b3d92afcb89e32a2e3f85fe4548617ea6 Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 14:42:51 +0100 Subject: [PATCH 09/33] Fix modal offset Co-authored-by: mrjvs --- src/components/overlays/Modal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/overlays/Modal.tsx b/src/components/overlays/Modal.tsx index d1534b42..fc2c97f4 100644 --- a/src/components/overlays/Modal.tsx +++ b/src/components/overlays/Modal.tsx @@ -18,8 +18,8 @@ export function useModal(id: string) { export function ModalCard(props: { children?: ReactNode }) { return ( -

-
+
+
{props.children}
From 15332c8fcefca5c0455e82b24007f6bf74008bee Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 14:46:46 +0100 Subject: [PATCH 10/33] Fix /s/ back to home Co-authored-by: mrjvs --- src/stores/history/index.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/stores/history/index.ts b/src/stores/history/index.ts index 572358cf..8a85f777 100644 --- a/src/stores/history/index.ts +++ b/src/stores/history/index.ts @@ -43,11 +43,17 @@ export function useHistoryListener() { export function useLastNonPlayerLink() { const routes = useHistoryStore((s) => s.routes); + const location = useLocation(); const lastNonPlayerLink = useMemo(() => { const reversedRoutes = [...routes]; reversedRoutes.reverse(); - const route = reversedRoutes.find((v) => !v.path.startsWith("/media")); + const route = reversedRoutes.find( + (v) => + !v.path.startsWith("/media") && // cannot be a player link + location.pathname !== v.path && // cannot be current link + !v.path.startsWith("/s/") // cannot be a quick search link + ); return route?.path ?? "/"; - }, [routes]); + }, [routes, location]); return lastNonPlayerLink; } From 101122ec54768816e0641f1fc88d10cb44f3b61b Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 14:49:02 +0100 Subject: [PATCH 11/33] Revert to normal DMCA text --- src/assets/locales/minion.json | 2 +- src/assets/locales/pirate.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/locales/minion.json b/src/assets/locales/minion.json index 22f90fb3..8568d927 100644 --- a/src/assets/locales/minion.json +++ b/src/assets/locales/minion.json @@ -269,7 +269,7 @@ }, "dmca": { "title": "DMCA", - "text": "Welcome to Minion-web's DMCA contact banana! We respect banana property rights and want to address any banana concerns swiftly. If you believe your banana work has been improperly used on our banana, please send a detailed banana notice to the banana below. Please include a banana of the banana material, your banana details, and a banana of good faith belief. We're committed to resolving these bananas promptly and appreciate your cooperation in keeping Minion-web a banana that respects creativity and banana." + "text": "Welcome to movie-web's DMCA contact page! We respect intellectual property rights and want to address any copyright concerns swiftly. If you believe your copyrighted work has been improperly used on our platform, please send a detailed DMCA notice to the email below. Please include a description of the copyrighted material, your contact details, and a statement of good faith belief. We're committed to resolving these matters promptly and appreciate your cooperation in keeping movie-web a place that respects creativity and copyrights." } }, "navigation": { diff --git a/src/assets/locales/pirate.json b/src/assets/locales/pirate.json index 0abcc5d5..c36ce4fc 100644 --- a/src/assets/locales/pirate.json +++ b/src/assets/locales/pirate.json @@ -260,7 +260,7 @@ }, "screens": { "dmca": { - "text": "In an effort to address the copyright concerns associated with the website known as \"movie-web,\" the DMCA, or Digital Jolly Roger Copyright Act, has been initiated to safeguard the intellectual property rights of content creators by reportin' infringements on this platform, thereby adherin' to legal protocols for takedown requests, which, like, ye know, it's all about, like, maintainin' the integrity of intellectual property, and, um, makin' sure, like, creators get their fair share, but then, it's, like, this intricate dance of digital legalities, where ye have to, uh, like, navigate this labyrinth of code and bytes and, uh, send, ye know, these, like, electronic documents that, um, point out the, uh, alleged infringement, and it's, like, this whole, like, teeter-totter of legality, where ye're, like, balancin', um, the rights of the, ye know, creators and the, um, operation of this, like, online, uh, entity, and, like, the DMCA, it's, like, this, um, powerful tool, but, uh, it's also, like, this, um, complex puzzle, where, ye know, ye're, like, seekin' justice in the digital wilderness, and, uh, strivin' for harmony amidst the chaos of the internet, and, um, yeah, that's, like, the whole, like, DMCA-ing thing with movie-web, ye know?", + "text": "Welcome to movie-web's DMCA contact page! We respect intellectual property rights and want to address any copyright concerns swiftly. If you believe your copyrighted work has been improperly used on our platform, please send a detailed DMCA notice to the email below. Please include a description of the copyrighted material, your contact details, and a statement of good faith belief. We're committed to resolving these matters promptly and appreciate your cooperation in keeping movie-web a place that respects creativity and copyrights.", "title": "DMCA" }, "loadingApp": "Loadin' application", From 762c4b0be7868bfc3df0b7b1fc2133f6796ca4e9 Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 14:49:45 +0100 Subject: [PATCH 12/33] YEET! --- src/assets/locales/minion.json | 4 ---- src/assets/locales/pirate.json | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/assets/locales/minion.json b/src/assets/locales/minion.json index 8568d927..a07ffd4d 100644 --- a/src/assets/locales/minion.json +++ b/src/assets/locales/minion.json @@ -266,10 +266,6 @@ "migration": { "failed": "Banana to banana your banana.", "inProgress": "Please banana, we are banana your banana. This shouldn't banana long." - }, - "dmca": { - "title": "DMCA", - "text": "Welcome to movie-web's DMCA contact page! We respect intellectual property rights and want to address any copyright concerns swiftly. If you believe your copyrighted work has been improperly used on our platform, please send a detailed DMCA notice to the email below. Please include a description of the copyrighted material, your contact details, and a statement of good faith belief. We're committed to resolving these matters promptly and appreciate your cooperation in keeping movie-web a place that respects creativity and copyrights." } }, "navigation": { diff --git a/src/assets/locales/pirate.json b/src/assets/locales/pirate.json index c36ce4fc..ce9e4113 100644 --- a/src/assets/locales/pirate.json +++ b/src/assets/locales/pirate.json @@ -259,10 +259,6 @@ } }, "screens": { - "dmca": { - "text": "Welcome to movie-web's DMCA contact page! We respect intellectual property rights and want to address any copyright concerns swiftly. If you believe your copyrighted work has been improperly used on our platform, please send a detailed DMCA notice to the email below. Please include a description of the copyrighted material, your contact details, and a statement of good faith belief. We're committed to resolving these matters promptly and appreciate your cooperation in keeping movie-web a place that respects creativity and copyrights.", - "title": "DMCA" - }, "loadingApp": "Loadin' application", "loadingUser": "Loadin' yer pirate profile", "loadingUserError": { From 4813d9dbfe6d1499e3df0a495bdadd746aec8a6f Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 15:27:42 +0100 Subject: [PATCH 13/33] RTL text Co-authored-by: mrjvs --- index.html | 80 ++++++++++---------- package.json | 2 + pnpm-lock.yaml | 48 ++++++++++++ src/assets/languages.ts | 3 + src/components/player/atoms/EpisodeTitle.tsx | 4 +- src/setup/App.tsx | 4 +- src/stores/language/index.ts | 11 ++- src/stores/language/index.tsx | 43 +++++++++++ vite.config.ts | 60 ++++++++------- 9 files changed, 183 insertions(+), 72 deletions(-) create mode 100644 src/stores/language/index.tsx diff --git a/index.html b/index.html index 4bfec5d1..3335369e 100644 --- a/index.html +++ b/index.html @@ -1,45 +1,41 @@ - - - - - - + - - - - - - + + + + + - - - + + + + + + - - + + + - - + + - - + + - movie-web + + - {{#if opensearchEnabled }} - - + movie-web - - - {{/if}} - - - -
- - - + {{/if}} + + + + +
+ + + + \ No newline at end of file diff --git a/package.json b/package.json index b2bbd592..92016b6f 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,8 @@ "handlebars": "^4.7.7", "jsdom": "^21.1.0", "postcss": "^8.4.20", + "postcss-rtl": "^2.0.0", + "postcss-rtlcss": "^4.0.9", "prettier": "^2.5.1", "prettier-plugin-tailwindcss": "^0.1.7", "tailwind-scrollbar": "^2.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1b318e25..729e7e19 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -223,6 +223,12 @@ devDependencies: postcss: specifier: '>=8.4.31' version: 8.4.31 + postcss-rtl: + specifier: ^2.0.0 + version: 2.0.0(postcss@8.4.31) + postcss-rtlcss: + specifier: ^4.0.9 + version: 4.0.9(postcss@8.4.31) prettier: specifier: ^2.5.1 version: 2.8.8 @@ -5070,6 +5076,26 @@ packages: postcss-selector-parser: 6.0.13 dev: true + /postcss-rtl@2.0.0(postcss@8.4.31): + resolution: {integrity: sha512-vFu78CvaGY9BafWRHNgDm6OjUxzRCWWCrp+KtnyXdgwibLwb/j5ls8Z/ubvOsk9B/Q2NLwSPrXRARKMaa9RBmA==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: '>=8.4.31' + dependencies: + postcss: 8.4.31 + rtlcss: 4.0.0 + dev: true + + /postcss-rtlcss@4.0.9(postcss@8.4.31): + resolution: {integrity: sha512-dCNKEf+FgTv+EA3XI8ysg2RnpS5s3/iZmU+9qpCNFxHU/BhK+4hz7jyCsCAfo0CLnDrMPtaQENhwb+EGm1wh7Q==} + engines: {node: '>=18.0.0'} + peerDependencies: + postcss: '>=8.4.31' + dependencies: + postcss: 8.4.31 + rtlcss: 4.1.1 + dev: true + /postcss-selector-parser@6.0.13: resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} engines: {node: '>=4'} @@ -5480,6 +5506,28 @@ packages: '@babel/runtime': 7.22.11 dev: false + /rtlcss@4.0.0: + resolution: {integrity: sha512-j6oypPP+mgFwDXL1JkLCtm6U/DQntMUqlv5SOhpgHhdIE+PmBcjrtAHIpXfbIup47kD5Sgja9JDsDF1NNOsBwQ==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + escalade: 3.1.1 + picocolors: 1.0.0 + postcss: 8.4.31 + strip-json-comments: 3.1.1 + dev: true + + /rtlcss@4.1.1: + resolution: {integrity: sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + escalade: 3.1.1 + picocolors: 1.0.0 + postcss: 8.4.31 + strip-json-comments: 3.1.1 + dev: true + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: diff --git a/src/assets/languages.ts b/src/assets/languages.ts index 13b06541..71c21fe2 100644 --- a/src/assets/languages.ts +++ b/src/assets/languages.ts @@ -25,3 +25,6 @@ export const locales = { pirate, minion, }; +export type Locales = keyof typeof locales; + +export const rtlLocales: Locales[] = ["nl"]; diff --git a/src/components/player/atoms/EpisodeTitle.tsx b/src/components/player/atoms/EpisodeTitle.tsx index b36909b1..1187d71a 100644 --- a/src/components/player/atoms/EpisodeTitle.tsx +++ b/src/components/player/atoms/EpisodeTitle.tsx @@ -9,8 +9,8 @@ export function EpisodeTitle() { if (meta?.type !== "show") return null; return ( -
- +
+ {t("media.episodeDisplay", { season: meta?.season?.number, episode: meta?.episode?.number, diff --git a/src/setup/App.tsx b/src/setup/App.tsx index d532d824..10d9cd14 100644 --- a/src/setup/App.tsx +++ b/src/setup/App.tsx @@ -23,7 +23,7 @@ import { RegisterPage } from "@/pages/Register"; import { SettingsPage } from "@/pages/Settings"; import { Layout } from "@/setup/Layout"; import { useHistoryListener } from "@/stores/history"; -import { useLanguageListener } from "@/stores/language"; +import { LanguageProvider } from "@/stores/language"; function LegacyUrlView({ children }: { children: ReactElement }) { const location = useLocation(); @@ -61,10 +61,10 @@ function QuickSearch() { function App() { useHistoryListener(); useOnlineListener(); - useLanguageListener(); return ( + {/* functional routes */} diff --git a/src/stores/language/index.ts b/src/stores/language/index.ts index 052127bc..1bf632ed 100644 --- a/src/stores/language/index.ts +++ b/src/stores/language/index.ts @@ -4,6 +4,7 @@ import { persist } from "zustand/middleware"; import { immer } from "zustand/middleware/immer"; import i18n from "@/setup/i18n"; +import { rtlLocales } from "@/assets/languages"; export interface LanguageStore { language: string; @@ -24,10 +25,18 @@ export const useLanguageStore = create( ) ); -export function useLanguageListener() { +export function LanguageProvider() { const language = useLanguageStore((s) => s.language); useEffect(() => { i18n.changeLanguage(language); }, [language]); + + const isRtl = rtlLocales.includes(language); + + return ( + + + + ); } diff --git a/src/stores/language/index.tsx b/src/stores/language/index.tsx new file mode 100644 index 00000000..ba33d59a --- /dev/null +++ b/src/stores/language/index.tsx @@ -0,0 +1,43 @@ +import { useEffect } from "react"; +import { Helmet } from "react-helmet-async"; +import { create } from "zustand"; +import { persist } from "zustand/middleware"; +import { immer } from "zustand/middleware/immer"; + +import { rtlLocales } from "@/assets/languages"; +import i18n from "@/setup/i18n"; + +export interface LanguageStore { + language: string; + setLanguage(v: string): void; +} + +export const useLanguageStore = create( + persist( + immer((set) => ({ + language: "en", + setLanguage(v) { + set((s) => { + s.language = v; + }); + }, + })), + { name: "__MW::locale" } + ) +); + +export function LanguageProvider() { + const language = useLanguageStore((s) => s.language); + + useEffect(() => { + i18n.changeLanguage(language); + }, [language]); + + const isRtl = rtlLocales.includes(language as any); + + return ( + + + + ); +} diff --git a/vite.config.ts b/vite.config.ts index 9a0018b0..8ebf8198 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,6 +7,9 @@ import path from "path"; import { handlebars } from "./plugins/handlebars"; import { loadEnv } from "vite"; +import tailwind from "tailwindcss"; +import rtl from "postcss-rtlcss"; + export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd()); return { @@ -18,8 +21,8 @@ export default defineConfig(({ mode }) => { env.VITE_APP_DOMAIN + (env.VITE_NORMAL_ROUTER !== "true" ? "/#" : ""), domain: env.VITE_APP_DOMAIN, - env - } + env, + }, }), react({ babel: { @@ -31,24 +34,24 @@ export default defineConfig(({ mode }) => { modules: false, useBuiltIns: "entry", corejs: { - version: "3.29" - } - } - ] - ] - } + version: "3.29", + }, + }, + ], + ], + }, }), VitePWA({ disable: env.VITE_PWA_ENABLED !== "true", registerType: "autoUpdate", workbox: { maximumFileSizeToCacheInBytes: 4000000, // 4mb - globIgnores: ["**ping.txt**"] + globIgnores: ["**ping.txt**"], }, includeAssets: [ "favicon.ico", "apple-touch-icon.png", - "safari-pinned-tab.svg" + "safari-pinned-tab.svg", ], manifest: { name: "movie-web", @@ -63,48 +66,53 @@ export default defineConfig(({ mode }) => { src: "android-chrome-192x192.png", sizes: "192x192", type: "image/png", - purpose: "any" + purpose: "any", }, { src: "android-chrome-512x512.png", sizes: "512x512", type: "image/png", - purpose: "any" + purpose: "any", }, { src: "android-chrome-192x192.png", sizes: "192x192", type: "image/png", - purpose: "maskable" + purpose: "maskable", }, { src: "android-chrome-512x512.png", sizes: "512x512", type: "image/png", - purpose: "maskable" - } - ] - } + purpose: "maskable", + }, + ], + }, }), loadVersion(), checker({ overlay: { - position: "tr" + position: "tr", }, typescript: true, // check typescript build errors in dev server eslint: { // check lint errors in dev server lintCommand: "eslint --ext .tsx,.ts src", dev: { - logLevel: ["error"] - } - } - }) + logLevel: ["error"], + }, + }, + }), ], build: { sourcemap: true, }, + css: { + postcss: { + plugins: [tailwind(), rtl()], + }, + }, resolve: { alias: { @@ -112,12 +120,12 @@ export default defineConfig(({ mode }) => { "@sozialhelden/ietf-language-tags": path.resolve( __dirname, "./node_modules/@sozialhelden/ietf-language-tags/dist/cjs" - ) - } + ), + }, }, test: { - environment: "jsdom" - } + environment: "jsdom", + }, }; }); From cf4cb6f300c096444ca741c55fe4c2983f8b4d0d Mon Sep 17 00:00:00 2001 From: Jip Fr Date: Sat, 16 Dec 2023 16:21:50 +0100 Subject: [PATCH 14/33] Some RTL fixes Co-authored-by: mrjvs --- src/assets/css/index.css | 5 +++ src/components/Icon.tsx | 11 ++++- .../positions/OverlayAnchorPosition.tsx | 2 +- src/components/player/atoms/ProgressBar.tsx | 2 +- src/components/player/internals/Button.tsx | 10 +---- src/components/utils/Lightbar.css | 12 +++--- src/pages/parts/player/PlayerPart.tsx | 2 +- src/pages/parts/player/ScrapingPart.tsx | 29 +++++++------ src/stores/language/index.ts | 42 ------------------- tailwind.config.ts | 23 ++++++---- 10 files changed, 56 insertions(+), 82 deletions(-) delete mode 100644 src/stores/language/index.ts diff --git a/src/assets/css/index.css b/src/assets/css/index.css index 74eb1270..809c5cda 100644 --- a/src/assets/css/index.css +++ b/src/assets/css/index.css @@ -222,3 +222,8 @@ input[type=range].styled-slider.slider-progress::-ms-fill-lower { outline: 2px solid theme('colors.themePreview.primary'); box-shadow: 0 0 10px theme('colors.themePreview.secondary'); } + +[dir="rtl"] .transform { + /* Invert horizontal X offset on transform (Tailwind RTL plugin does the rest) */ + transform: translate(calc(var(--tw-translate-x) * -1), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important; +} \ No newline at end of file diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 6f5c676e..ef08938e 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -1,3 +1,4 @@ +import classNames from "classnames"; import { memo, useEffect, useRef } from "react"; export enum Icons { @@ -150,10 +151,18 @@ export const Icon = memo((props: IconProps) => { return ; } + const flipClass = + props.icon === Icons.ARROW_LEFT || + props.icon === Icons.ARROW_RIGHT || + props.icon === Icons.CHEVRON_LEFT || + props.icon === Icons.CHEVRON_RIGHT + ? "rtl:-scale-x-100" + : ""; + return ( ); }); diff --git a/src/components/overlays/positions/OverlayAnchorPosition.tsx b/src/components/overlays/positions/OverlayAnchorPosition.tsx index 028f721d..49cb7d69 100644 --- a/src/components/overlays/positions/OverlayAnchorPosition.tsx +++ b/src/components/overlays/positions/OverlayAnchorPosition.tsx @@ -64,7 +64,7 @@ export function OverlayAnchorPosition(props: AnchorPositionProps) { transform: `translateX(${left}px) translateY(${top}px)`, }} className={classNames([ - "pointer-events-auto z-10 inline-block origin-top-left touch-none", + "[&>*]:pointer-events-auto z-10 flex dir-neutral:items-start justify-start dir-neutral:origin-top-left touch-none", props.className, ])} > diff --git a/src/components/player/atoms/ProgressBar.tsx b/src/components/player/atoms/ProgressBar.tsx index c5deb7ca..887e5ed8 100644 --- a/src/components/player/atoms/ProgressBar.tsx +++ b/src/components/player/atoms/ProgressBar.tsx @@ -119,7 +119,7 @@ export function ProgressBar() { }, [setDraggingTime, duration, dragPercentage]); return ( -
+
props.onClick?.(e.currentTarget as HTMLButtonElement)} className={classNames([ - "tabbable p-2 rounded-full hover:bg-video-buttonBackground hover:bg-opacity-50 transition-transform duration-100 flex items-center", + "tabbable p-2 rounded-full hover:bg-video-buttonBackground hover:bg-opacity-50 transition-transform duration-100 flex items-center gap-3", props.activeClass ?? "active:scale-110 active:bg-opacity-75 active:text-white", props.className ?? "", ])} > {props.icon && ( - + )} {props.children} diff --git a/src/components/utils/Lightbar.css b/src/components/utils/Lightbar.css index 06f7ffe8..d5d12310 100644 --- a/src/components/utils/Lightbar.css +++ b/src/components/utils/Lightbar.css @@ -6,7 +6,7 @@ user-select: none; } -.lightbar { +[dir] .lightbar { left: 50vw; transform: translateX(-50%); } @@ -16,13 +16,14 @@ width: 150vw; } - .lightbar { + [dir] .lightbar { left: -25vw; transform: initial; } + } -.lightbar { +[dir] .lightbar { display: flex; justify-content: center; align-items: center; @@ -31,7 +32,7 @@ animation: boot var(--d) var(--animation) forwards; } -.lightbar-visual { +[dir] .lightbar-visual { left: 0; --top: theme('colors.background.main'); --bottom: theme('colors.lightBar.light'); @@ -57,7 +58,6 @@ @keyframes boot { from { - opacity: 0.25; } @@ -74,4 +74,4 @@ 100% { transform: rotate(180deg) translateZ(0px) translateY(400px) scaleX(1); } -} +} \ No newline at end of file diff --git a/src/pages/parts/player/PlayerPart.tsx b/src/pages/parts/player/PlayerPart.tsx index 48a25094..371087e3 100644 --- a/src/pages/parts/player/PlayerPart.tsx +++ b/src/pages/parts/player/PlayerPart.tsx @@ -88,7 +88,7 @@ export function PlayerPart(props: PlayerPartProps) { ) : null}
-
+
{status === playerStatus.PLAYING ? ( <> diff --git a/src/pages/parts/player/ScrapingPart.tsx b/src/pages/parts/player/ScrapingPart.tsx index eee6edcb..de32f711 100644 --- a/src/pages/parts/player/ScrapingPart.tsx +++ b/src/pages/parts/player/ScrapingPart.tsx @@ -60,18 +60,18 @@ export function ScrapingPart(props: ScrapingProps) { (async () => { const output = await startScraping(props.media); if (!isMounted()) return; - props.onResult?.( - resultRef.current.sources, - resultRef.current.sourceOrder - ); - report( - scrapePartsToProviderMetric( - props.media, - resultRef.current.sourceOrder, - resultRef.current.sources - ) - ); - props.onGetStream?.(output); + // props.onResult?.( + // resultRef.current.sources, + // resultRef.current.sourceOrder + // ); + // report( + // scrapePartsToProviderMetric( + // props.media, + // resultRef.current.sourceOrder, + // resultRef.current.sources + // ) + // ); + // props.onGetStream?.(output); })(); }, [startScraping, props, report, isMounted]); @@ -85,7 +85,10 @@ export function ScrapingPart(props: ScrapingProps) { currentProviderIndex = sourceOrder.length - 1; return ( -
+
((set) => ({ - language: "en", - setLanguage(v) { - set((s) => { - s.language = v; - }); - }, - })), - { name: "__MW::locale" } - ) -); - -export function LanguageProvider() { - const language = useLanguageStore((s) => s.language); - - useEffect(() => { - i18n.changeLanguage(language); - }, [language]); - - const isRtl = rtlLocales.includes(language); - - return ( - - - - ); -} diff --git a/tailwind.config.ts b/tailwind.config.ts index 83da3298..ee5ef13f 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,5 +1,6 @@ import { allThemes, defaultTheme, safeThemeList } from "./themes"; -import type { Config } from "tailwindcss" +import type { Config } from "tailwindcss"; +import plugin from "tailwindcss/plugin"; const themer = require("tailwindcss-themer"); @@ -10,18 +11,18 @@ const config: Config = { extend: { /* fonts */ fontFamily: { - "open-sans": "'Open Sans'" + "open-sans": "'Open Sans'", }, /* animations */ keyframes: { "loading-pin": { "0%, 40%, 100%": { height: "0.5em", "background-color": "#282336" }, - "20%": { height: "1em", "background-color": "white" } - } + "20%": { height: "1em", "background-color": "white" }, + }, }, - animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" } - } + animation: { "loading-pin": "loading-pin 1.8s ease-in-out infinite" }, + }, }, plugins: [ require("tailwind-scrollbar"), @@ -33,9 +34,13 @@ const config: Config = { selectors: [".theme-default"], ...defaultTheme, }, - ...allThemes] - }) - ] + ...allThemes, + ], + }), + plugin(({ addVariant }) => { + addVariant("dir-neutral", "[dir] &"); + }), + ], }; export default config; From 6dea1fb3f6add47a297d4dc10ef4ee9f87fec1d9 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sat, 16 Dec 2023 16:50:34 +0100 Subject: [PATCH 15/33] Fix RTL issues --- src/assets/css/index.css | 6 +++- src/components/player/atoms/ProgressBar.tsx | 2 +- .../atoms/settings/CaptionSettingsView.tsx | 1 + src/pages/parts/player/ScrapingPart.tsx | 29 ++++++++++--------- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/assets/css/index.css b/src/assets/css/index.css index 809c5cda..08b24f68 100644 --- a/src/assets/css/index.css +++ b/src/assets/css/index.css @@ -226,4 +226,8 @@ input[type=range].styled-slider.slider-progress::-ms-fill-lower { [dir="rtl"] .transform { /* Invert horizontal X offset on transform (Tailwind RTL plugin does the rest) */ transform: translate(calc(var(--tw-translate-x) * -1), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important; -} \ No newline at end of file +} +[dir="ltr"] .transform { + /* default - otherwise it overwrites*/ + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important; +} diff --git a/src/components/player/atoms/ProgressBar.tsx b/src/components/player/atoms/ProgressBar.tsx index 887e5ed8..56d8c472 100644 --- a/src/components/player/atoms/ProgressBar.tsx +++ b/src/components/player/atoms/ProgressBar.tsx @@ -158,7 +158,7 @@ export function ProgressBar() { {/* Actual progress bar */}
{ const output = await startScraping(props.media); if (!isMounted()) return; - // props.onResult?.( - // resultRef.current.sources, - // resultRef.current.sourceOrder - // ); - // report( - // scrapePartsToProviderMetric( - // props.media, - // resultRef.current.sourceOrder, - // resultRef.current.sources - // ) - // ); - // props.onGetStream?.(output); + props.onResult?.( + resultRef.current.sources, + resultRef.current.sourceOrder + ); + report( + scrapePartsToProviderMetric( + props.media, + resultRef.current.sourceOrder, + resultRef.current.sources + ) + ); + props.onGetStream?.(output); })(); }, [startScraping, props, report, isMounted]); @@ -86,12 +86,13 @@ export function ScrapingPart(props: ScrapingProps) { return (
Date: Sat, 16 Dec 2023 16:54:30 +0100 Subject: [PATCH 16/33] Add batching + remove temporary RTL --- package.json | 1 + pnpm-lock.yaml | 9 +++++++++ src/assets/languages.ts | 2 +- src/backend/helpers/report.ts | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 92016b6f..d2a5dbb2 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "immer": "^10.0.2", "iso-639-1": "^3.1.0", "lodash.isequal": "^4.5.0", + "nanoid": "^5.0.4", "node-forge": "^1.3.1", "ofetch": "^1.0.0", "react": "^17.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 729e7e19..c2e88592 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,6 +71,9 @@ dependencies: lodash.isequal: specifier: ^4.5.0 version: 4.5.0 + nanoid: + specifier: ^5.0.4 + version: 5.0.4 node-forge: specifier: ^1.3.1 version: 1.3.1 @@ -4753,6 +4756,12 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + /nanoid@5.0.4: + resolution: {integrity: sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==} + engines: {node: ^18 || >=20} + hasBin: true + dev: false + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true diff --git a/src/assets/languages.ts b/src/assets/languages.ts index 71c21fe2..d6c47905 100644 --- a/src/assets/languages.ts +++ b/src/assets/languages.ts @@ -27,4 +27,4 @@ export const locales = { }; export type Locales = keyof typeof locales; -export const rtlLocales: Locales[] = ["nl"]; +export const rtlLocales: Locales[] = []; diff --git a/src/backend/helpers/report.ts b/src/backend/helpers/report.ts index f9ac89a6..b7c32645 100644 --- a/src/backend/helpers/report.ts +++ b/src/backend/helpers/report.ts @@ -1,4 +1,5 @@ import { ScrapeMedia } from "@movie-web/providers"; +import { nanoid } from "nanoid"; import { ofetch } from "ofetch"; import { useCallback } from "react"; @@ -8,6 +9,7 @@ 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 batchId = () => nanoid(32); export type ProviderMetric = { tmdbId: string; @@ -34,6 +36,7 @@ export async function reportProviders(items: ProviderMetric[]): Promise { method: "POST", body: { items, + batchId: batchId(), }, }); } From ad81b23c9510942444e179c505ec31c45ea528f3 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sat, 16 Dec 2023 16:58:53 +0100 Subject: [PATCH 17/33] Fix thumbnail going under next episode button --- src/components/player/base/BottomControls.tsx | 2 +- src/pages/parts/player/PlayerPart.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/player/base/BottomControls.tsx b/src/components/player/base/BottomControls.tsx index 4af547f6..38b8f516 100644 --- a/src/components/player/base/BottomControls.tsx +++ b/src/components/player/base/BottomControls.tsx @@ -27,7 +27,7 @@ export function BottomControls(props: {
setHoveringAnyControls(true)} onMouseOut={() => setHoveringAnyControls(false)} - className="pointer-events-auto pl-[calc(2rem+env(safe-area-inset-left))] pr-[calc(2rem+env(safe-area-inset-right))] pb-3 mb-[env(safe-area-inset-bottom)] absolute bottom-0 w-full" + className="pointer-events-auto z-10 pl-[calc(2rem+env(safe-area-inset-left))] pr-[calc(2rem+env(safe-area-inset-right))] pb-3 mb-[env(safe-area-inset-bottom)] absolute bottom-0 w-full" > {props.children} diff --git a/src/pages/parts/player/PlayerPart.tsx b/src/pages/parts/player/PlayerPart.tsx index 371087e3..d5a180c3 100644 --- a/src/pages/parts/player/PlayerPart.tsx +++ b/src/pages/parts/player/PlayerPart.tsx @@ -130,6 +130,7 @@ export function PlayerPart(props: PlayerPartProps) { + Date: Sat, 16 Dec 2023 17:23:56 +0100 Subject: [PATCH 18/33] Remove conflicting ids (dont need them anymore) --- .github/workflows/deploying.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/deploying.yml b/.github/workflows/deploying.yml index cd8a6b57..92cdfbe8 100644 --- a/.github/workflows/deploying.yml +++ b/.github/workflows/deploying.yml @@ -109,7 +109,6 @@ jobs: prerelease: false - name: Upload release (PWA) - id: upload-release-asset uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -120,7 +119,6 @@ jobs: asset_content_type: application/zip - name: Upload Release (Normal) - id: upload-release-asset uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5c26acc912e279cc3863cd64a0f80015ba6a7193 Mon Sep 17 00:00:00 2001 From: Nemo Date: Sat, 16 Dec 2023 01:26:34 +0000 Subject: [PATCH 19/33] Added translation using Weblate (Thai) Author: Nemo --- src/assets/locales/th.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/assets/locales/th.json diff --git a/src/assets/locales/th.json b/src/assets/locales/th.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/src/assets/locales/th.json @@ -0,0 +1 @@ +{} From 655048191b3c88a462bf2ab548a6866e0a270bf5 Mon Sep 17 00:00:00 2001 From: teaishealthy Date: Fri, 15 Dec 2023 23:21:06 +0000 Subject: [PATCH 20/33] Translated using Weblate (German) Currently translated at 74.7% (184 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/de/ Author: teaishealthy --- src/assets/locales/de.json | 401 +++++++++++++++++++++++++++++++------ 1 file changed, 338 insertions(+), 63 deletions(-) diff --git a/src/assets/locales/de.json b/src/assets/locales/de.json index c6d02de3..248b9410 100644 --- a/src/assets/locales/de.json +++ b/src/assets/locales/de.json @@ -1,71 +1,346 @@ { - "global": { - "name": "movie-web" + "about": { + "faqTitle": "Häufig gestellte Fragen", + "q1": { + "title": "Woher kommen die Videos?" }, - "home": { - "search": { - "allResults": "Das ist alles, was wir haben!", - "sectionTitle": "Suchergebnisse", - "noResults": "Wir haben nichts gefunden!", - "failed": "Das Medium wurde nicht gefunden, bitte versuchen Sie es erneut!", - "loading": "Wird geladen...", - "placeholder": "Was willst du gucken?" - }, - "bookmarks": { - "sectionTitle": "Favoriten" - }, - "continueWatching": { - "sectionTitle": "Weiter ansehen" - } + "q2": { + "title": "Wo kann ich eine Serie oder einen Film anfragen?" }, - "media": { - "types": { - "movie": "Film", - "show": "Serie" - }, - "episodeDisplay": "S{{season}} E{{episode}}" + "q3": { + "title": "Die Suche zeigt eine Serie oder einen Film an, warum kann ich den dann nicht abspielen?" }, - "player": { - "playbackError": { - "title": "Hoppla, etwas ist schiefgegangen!" - }, - "metadata": { - "notFound": { - "badge": "Nicht gefunden", - "homeButton": "Zurück zur Startseite", - "title": "Das Medium konnte nicht gefunden werden.", - "text": "Wir konnten die angeforderten Medien nicht finden." - } - }, - "menus": { - "captions": { - "customChoice": "Untertitel hochladen", - "customizeLabel": "Bearbeiten", - "title": "Untertitel" - }, - "sources": { - "title": "Quellen" - }, - "episodes": { - "button": "Folgen", - "loadingTitle": "Wird geladen...", - "loadingList": "Wird geladen..." - } - }, - "back": { - "default": "Zurück zur Startseite", - "short": "Rückmeldung" - } + "title": "Über movie-web" + }, + "actions": { + "copied": "Kopiert", + "copy": "Kopieren" + }, + "auth": { + "deviceNameLabel": "Gerätename", + "deviceNamePlaceholder": "Handy", + "generate": { + "description": "Deine Passphrase dient als dein Nutzername und Passwort. Speiche sie sicher ab, damit du dich in deinem Konto anmelden kannst", + "next": "Ich habe meine Passphrase gespeichert", + "title": "Deine Passphrase" }, - "notFound": { - "badge": "Nicht gefunden", - "goHome": "Zurück zur Startseite", - "title": "Diese Seite kann nicht gefunden werden", - "message": "Wir haben überall gesucht, aber am Ende konnten wir die gesuchte Seite nicht finden." + "login": { + "description": "Gebe deine Passphrase ein, um dich in deinem Konto anzumelden", + "deviceLengthError": "Gebe ein Gerätename ein", + "passphrasePlaceholder": "Passphrase", + "submit": "Anmelden", + "title": "Melde dich in deinem Konto an", + "validationError": "Falsche oder unvollständige Passphrase" }, - "navigation": { - "banner": { - "offline": "Internetverbindung ist instabil" - } + "register": { + "information": { + "color1": "Profilfarbe 1", + "color2": "Profilfarbe 2", + "header": "Gebe einen Namen für dein Gerät ein und wähle ein Nutzersymbol", + "icon": "Nutzersymbol", + "next": "Weiter", + "title": "Kontoinformationen" + } + }, + "trust": { + "failed": { + "title": "Konnte Server nicht erreichen" + }, + "no": "Zurück", + "title": "Vertraust du diesem Server?", + "yes": "Ich vertraue diesem Server" + }, + "verify": { + "invalidData": "Daten sind ungültig", + "noMatch": "Passphrasen stimmen nicht überein", + "recaptchaFailed": "ReCaptcha Verifizierung ist fehlgeschlagenen", + "register": "Konto erstellen", + "title": "Bestätige deine Passphrase" } + }, + "errors": { + "badge": "Kaputt", + "details": "Fehlerdetails", + "showError": "Zeige Fehlerdetails an", + "title": "Ein Fehler ist aufgetreten!" + }, + "footer": { + "legal": { + "disclaimer": "Hinweis" + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + } + }, + "global": { + "name": "movie-web", + "pages": { + "dmca": "DMCA", + "login": "Anmelden", + "pagetitle": "{{title}} - movie-web", + "register": "Registrieren", + "settings": "Einstellungen" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Favoriten" + }, + "continueWatching": { + "sectionTitle": "Weiter ansehen" + }, + "mediaList": { + "stopEditing": "Bearbeiten beenden" + }, + "search": { + "allResults": "Das ist alles, was wir haben!", + "failed": "Das Medium wurde nicht gefunden, bitte versuchen Sie es erneut!", + "loading": "Wird geladen...", + "noResults": "Wir haben nichts gefunden!", + "placeholder": "Was willst du gucken?", + "sectionTitle": "Suchergebnisse" + }, + "titles": { + "day": { + "default": "Was würdest du diesen Nachmittag gerne schauen?" + }, + "morning": { + "default": "Was würdest du diesen Morgen gerne schauen?", + "extra": [ + "Ich hab gehört Before Sunrise soll gut sein" + ] + }, + "night": { + "default": "Was würdest du diesen Abend gerne schauen?", + "extra": [ + "Müde? Ich hab gehört The Exorcist soll gut sein." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serie" + } + }, + "navigation": { + "banner": { + "offline": "Internetverbindung ist instabil" + }, + "menu": { + "about": "Über uns", + "donation": "Spenden", + "logout": "Abmelden", + "register": "Mit der Cloud synchronisieren", + "settings": "Einstellungen", + "support": "Support" + } + }, + "notFound": { + "badge": "Nicht gefunden", + "goHome": "Zurück zur Startseite", + "message": "Wir haben überall gesucht, aber am Ende konnten wir die gesuchte Seite nicht finden.", + "title": "Diese Seite wurde nicht gefunden" + }, + "overlays": { + "close": "Schließen" + }, + "player": { + "back": { + "default": "Zurück zur Startseite", + "short": "Rückmeldung" + }, + "menus": { + "captions": { + "customChoice": "Untertitel hochladen", + "customizeLabel": "Bearbeiten", + "offChoice": "Aus", + "settings": { + "delay": "Untertitelverzögerung" + }, + "title": "Untertitel", + "unknownLanguage": "Unbekannt" + }, + "downloads": { + "downloadCaption": "Ausgewählte Untertitel herunterladen", + "downloadVideo": "Video herunterladen", + "hlsExplanation": "Dieses Video ist ein HLS-Stream, welcher auf movie-web nicht heruntergeladen werden kann.", + "onAndroid": { + "1": "Um auf Android Herunterzuladen, tippe auf den Download-Button, tippe und halte auf der neuen Seite auf das Video und wähle Speichern aus.", + "title": "Auf Android herunterladen" + }, + "onIos": { + "title": "Auf iOS herunterladen" + }, + "onPc": { + "title": "Am PC herunterladen" + }, + "title": "Download" + }, + "episodes": { + "button": "Folgen", + "emptyState": "Keine Folgen in dieser Staffel, schau später noch einmal!", + "episodeBadge": "E{{episode}}", + "loadingError": "Fehler beim Laden der Sitzung", + "loadingList": "Wird geladen...", + "loadingTitle": "Wird geladen..." + }, + "playback": { + "speedLabel": "Wiedergabegeschwindigkeit", + "title": "Wiedergabeeinstellungen" + }, + "quality": { + "automaticLabel": "Automatische Qualitätseinstellung", + "title": "Qualität" + }, + "settings": { + "captionItem": "Untertiteleinstellungen", + "downloadItem": "Download", + "playbackItem": "Wiedergabeeinstellungen", + "qualityItem": "Qualität", + "sourceItem": "Videoquellen", + "videoSection": "Videoeinstellungen" + }, + "sources": { + "title": "Quellen", + "unknownOption": "Unbekannt" + } + }, + "metadata": { + "failed": { + "badge": "Fehlgeschlagen", + "homeButton": "Zurück zur Startseite", + "text": "Konnte die Videometadaten nicht von TMDB laden. Überprüfe ob TMDB funktioniert oder von deiner Internetverbindung gesperrt wird.", + "title": "Laden der Metadaten ist fehlgeschlagen" + }, + "notFound": { + "badge": "Nicht gefunden", + "homeButton": "Zurück zur Startseite", + "text": "Wir konnten die angeforderten Medien nicht finden.", + "title": "Das Medium konnte nicht gefunden werden." + } + }, + "nextEpisode": { + "cancel": "Abbrechen", + "next": "Nächste Folge" + }, + "playbackError": { + "badge": "Wiedergabefehler", + "errors": { + "errorAborted": "Das Laden des Videos wurde vom Nutzer abgebrochen.", + "errorGenericMedia": "Unbekannter Videofehler ist aufgetreten." + }, + "homeButton": "Zurück zur Startseite", + "text": "Ein Fehler ist während der Wiedergabe aufgetreten. Versuche es erneut.", + "title": "Hoppla, etwas ist schiefgegangen!" + }, + "scraping": { + "items": { + "failure": "Ein Fehler ist aufgetreten" + }, + "notFound": { + "badge": "Nicht gefunden", + "detailsButton": "Details anzeigen", + "homeButton": "Zurück zur Startseite", + "title": "Wir konnten das nicht finden" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "shortRegular": "{{timeWatched}}" + } + }, + "screens": { + "dmca": { + "text": "Willkommen zu movie-webs DMCA-Kontaktseite! Wir respektieren geistiges Eigentum und wollen uns schnell um urheberrechtlichen Anliegen kümmern. Falls du glaubst, dass dein urheberrechtlich geschütztes Werk unsachgemäß auf unserer Plattform verwendet wurde, sende uns bitte eine genaue DMCA-Anfrage an die unten stehende E-Mail. Diese sollte eine Beschreibung des urheberrechtlich geschützten Material, deine Kontaktinformationen sowie einer Erklärung des guten Glaubens beinhalten. Wir sind engagiert diese Anliegen schnell zu lösen und schätzen deine Hilfe dabei movie-web zu einer Plattform, welche Kreativität und Urheberrechte respektiert.", + "title": "DMCA" + }, + "loadingUserError": { + "logout": "Abmelden" + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Gerätename", + "deviceNamePlaceholder": "Handy", + "editProfile": "Bearbeiten", + "logoutButton": "Abmelden" + }, + "actions": { + "delete": { + "button": "Konto löschen", + "confirmButton": "Konto löschen", + "confirmDescription": "Konto wirklich löschen? Alle deine Daten gehen dabei verloren!", + "confirmTitle": "Bist du sicher?", + "text": "Diese Aktion kann nicht rückgängig gemacht werden. Alle Daten werden gelöscht und können nicht wiederhergestellt werden.", + "title": "Konto löschen" + } + }, + "devices": { + "deviceNameLabel": "Gerätename", + "failed": "Laden der Sitzungen fehlgeschlagen", + "removeDevice": "Entfernen", + "title": "Geräte" + }, + "profile": { + "finish": "Bearbeiten beenden", + "firstColor": "Profilfarbe 1", + "secondColor": "Profilfarbe 2", + "title": "Profilbild bearbeiten", + "userIcon": "Nutzersymbol" + }, + "register": { + "title": "Mit der Cloud synchronisieren" + }, + "title": "Konto" + }, + "appearance": { + "activeTheme": "Aktiv", + "themes": { + "blue": "Blau", + "default": "Standard", + "gray": "Grau", + "red": "Rot", + "teal": "Türkis" + }, + "title": "Aussehen" + }, + "captions": { + "backgroundLabel": "Hintergrund-Deckkraft", + "colorLabel": "Farbe", + "previewQuote": "Das Gras wächst nicht schneller, wenn man daran zieht.", + "textSizeLabel": "Schriftgröße", + "title": "Untertitel" + }, + "connections": { + "workers": { + "urlPlaceholder": "https://" + } + }, + "locale": { + "language": "App-Sprache", + "title": "Sprache" + }, + "reset": "Zurücksetzen", + "save": "Speichern", + "sidebar": { + "info": { + "appVersion": "App-Version", + "backendVersion": "Server-Version", + "hostname": "Hostname", + "insecure": "Unsicher", + "notLoggedIn": "Du bist nicht angemeldet", + "secure": "Sicher", + "title": "App-Informationen", + "unknownVersion": "Unbekannt", + "userId": "Nutzer-ID" + } + }, + "unsaved": "Du hast ungespeicherte Änderungen" + } } From 7d7d9b6494c649e754ad4d1f5223605f0faae684 Mon Sep 17 00:00:00 2001 From: Kipoddo Date: Sat, 16 Dec 2023 13:04:59 +0000 Subject: [PATCH 21/33] Added translation using Weblate (Hebrew) Author: Kipoddo --- src/assets/locales/he.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/assets/locales/he.json diff --git a/src/assets/locales/he.json b/src/assets/locales/he.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/src/assets/locales/he.json @@ -0,0 +1 @@ +{} From 85c0b03e4128a5c2f389730fa5d3c604c4ae9412 Mon Sep 17 00:00:00 2001 From: Kipoddo Date: Sat, 16 Dec 2023 13:52:51 +0000 Subject: [PATCH 22/33] Translated using Weblate (Hebrew) Currently translated at 66.6% (164 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/he/ Author: Kipoddo --- src/assets/locales/he.json | 295 ++++++++++++++++++++++++++++++++++++- 1 file changed, 294 insertions(+), 1 deletion(-) diff --git a/src/assets/locales/he.json b/src/assets/locales/he.json index 0967ef42..8e35d074 100644 --- a/src/assets/locales/he.json +++ b/src/assets/locales/he.json @@ -1 +1,294 @@ -{} +{ + "actions": { + "copied": "הועתק", + "copy": "להעתיק" + }, + "auth": { + "createAccount": "אין לך עדיין חשבון? <0>צור חשבון.", + "deviceNameLabel": "שם המכשיר", + "deviceNamePlaceholder": "מכשיר אישי", + "generate": { + "description": "ביטוי הסיסמה שלך משמש כשם המשתמש והסיסמה שלך. אנא הקפד לשמור אותו בטוח מכיוון שתצטרך להזין אותו כדי להתחבר לחשבון שלך", + "next": "אני שמרתי את משפט הסיסמה שלי", + "title": "משפט הסיסמה שלך" + }, + "hasAccount": "כבר יש לך חשבון? <0>התחבר כאן.", + "login": { + "description": "אנא הזן את ביטוי הסיסמה שלך כדי להתחבר לחשבונך", + "deviceLengthError": "אנא הזן שם מכשיר", + "passphraseLabel": "ביטוי סיסמא בעל 12 מילים", + "passphrasePlaceholder": "ביטוי סיסמא", + "submit": "התחבר", + "title": "התחבר לחשבונך", + "validationError": "ביטוי סיסמה שגוי או לא שלם" + }, + "register": { + "information": { + "color1": "צבע פרופיל ראשון", + "color2": "צבע פרופיל שני", + "header": "הזן שם למכשירך ובחר צבעים וסמל משתמש לפי בחירתך", + "icon": "סמל משתמש", + "next": "הבא", + "title": "פרטי חשבון" + } + }, + "trust": { + "failed": { + "text": "האם הגדרת את זה נכון?", + "title": "הגישה לשרת נכשלה" + }, + "host": "אתה מתחבר אל <0>{{hostname}} - אנא אשר שאתה סומך עליו לפני יצירת חשבון", + "no": "חזור", + "title": "האם אתה סומך על שרת זה?", + "yes": "אני בוטח בשרת זה" + }, + "verify": { + "description": "אנא הזן את משפט הסיסמה שלך מקודם כדי לאשר ששמרת אותו וכדי ליצור את חשבונך", + "invalidData": "הנתונים אינם חוקיים", + "noMatch": "ביטוי הסיסמה אינו תואם", + "passphraseLabel": "ביטוי הסיסמה שלך בעל 12 מילים", + "recaptchaFailed": "אימות ReCaptcha נכשל", + "register": "צור חשבון", + "title": "אשר את ביטוי הסיסמה שלך" + } + }, + "errors": { + "badge": "זה נשבר", + "details": "פרטי שגיאה", + "reloadPage": "טען מחדש את הדף", + "showError": "הצג פרטי שגיאה", + "title": "נתקלנו בשגיאה!" + }, + "global": { + "pages": { + "about": "אודות", + "login": "התחבר", + "register": "הירשם", + "settings": "הגדרות" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "סימניות" + }, + "continueWatching": { + "sectionTitle": "המשך לצפות" + }, + "mediaList": { + "stopEditing": "הפסק עריכה" + }, + "search": { + "allResults": "זה כל מה שיש לנו!", + "failed": "לא הצלחנו למצוא מדיה, נסה שוב!", + "loading": "טוען...", + "noResults": "לא יכולנו למצוא כלום!", + "placeholder": "במה תרצה לצפות?", + "sectionTitle": "תוצאות חיפוש" + }, + "titles": { + "day": { + "default": "במה תרצה לצפות באחר צהריים זה?" + }, + "morning": { + "default": "במה תרצה לצפות הבוקר?", + "extra": [ + "שמעתי שלפני הזריחה זה סרט טוב" + ] + }, + "night": { + "default": "במה תרצה לצפות הלילה?", + "extra": [ + "עייף? שמעתי שמגרש השדים זה סרט טוב." + ] + } + } + }, + "media": { + "types": { + "movie": "סרט", + "show": "סדרה" + } + }, + "navigation": { + "banner": { + "offline": "תבדוק את חיבור האינטרנט שלך" + }, + "menu": { + "about": "עלינו", + "donation": "לתרום", + "logout": "להתנתק", + "register": "סנכרון לענן", + "settings": "הגדרות", + "support": "תמיכה" + } + }, + "notFound": { + "badge": "לא נמצא", + "goHome": "בחזרה לבית", + "message": "חיפשנו בכל מקום: מתחת לפחים, בארון, מאחורי ה-proxy אבל בסופו של דבר לא מצאנו את הדף שאתה מחפש.", + "title": "לא יכולנו למצוא את דף זה" + }, + "overlays": { + "close": "סגור" + }, + "player": { + "back": { + "default": "חזרה לדף הבית", + "short": "חזור" + }, + "casting": { + "enabled": "משדר למכשיר..." + }, + "menus": { + "captions": { + "customChoice": "בחר כתוביות מהקובץ", + "customizeLabel": "התאם אישית", + "offChoice": "כבוי", + "settings": { + "delay": "עיכוב בכיתוב", + "fixCapitals": "תקן שימוש באותיות גדולות" + }, + "title": "כתוביות", + "unknownLanguage": "לא ידוע" + }, + "downloads": { + "disclaimer": "ההורדות נלקחות ישירות מהספק. ל-movie-web אין שליטה על האופן שבו מסופקות ההורדות.", + "downloadCaption": "הורד את הכתוביות הנוכחיות", + "downloadVideo": "הורד וידאו", + "hlsExplanation": "מדיה זו היא זרם HLS שאינו ניתן להורדה ב-movie-web.", + "onAndroid": { + "1": "כדי להוריד באנדרואיד, לחץ על כפתור ההורדה ולאחר מכן, בדף החדש, הקש והחזק על הסרטון, ולאחר מכן בחר שמור.", + "shortTitle": "הורדה / אנדרויד", + "title": "הורדה באנדרויד" + }, + "onIos": { + "1": "כדי להוריד ב-iOS, לחץ על כפתור ההורדה ולאחר מכן, בדף החדש, לחץ על ולאחר מכן על שמור לקבצים .", + "shortTitle": "הורדה / iOS", + "title": "מוריד ב-iOS" + }, + "onPc": { + "1": "במחשב, לחץ על כפתור ההורדה ולאחר מכן, בדף החדש, לחץ לחיצה ימנית על הסרטון ובחר שמור סרטון בשם", + "shortTitle": "הורדה / PC", + "title": "הורדה במחשב" + }, + "title": "הורד" + }, + "episodes": { + "button": "פרקים", + "emptyState": "אין פרקים בעונה זו, אנא בדוק שוב מאוחר יותר!", + "loadingError": "ארע שגיאה בטעינת העונה", + "loadingList": "טוען...", + "loadingTitle": "טוען..." + }, + "playback": { + "speedLabel": "מהירות הניגון", + "title": "הגדרות ניגון" + }, + "quality": { + "automaticLabel": "איכות אוטומטית", + "title": "איכות" + }, + "settings": { + "captionItem": "הגדרות כתוביות", + "downloadItem": "הורד", + "enableCaptions": "אפשר כתוביות", + "experienceSection": "חווית צפייה", + "playbackItem": "הגדרות השמעה", + "qualityItem": "איכות", + "sourceItem": "מקורות וידאו", + "videoSection": "הגדרות וידאו" + }, + "sources": { + "failed": { + "text": "אירעה שגיאה בעת ניסיון למצוא סרטונים, אנא נסה מקור אחר.", + "title": "לא הצליח לחלץ" + }, + "noEmbeds": { + "text": "לא הצלחנו למצוא שום הטעמות, אנא נסה מקור אחר.", + "title": "לא נמצאו הטמעות" + }, + "noStream": { + "text": "למקור זה אין זרמים עבור הסרט או התוכנית הזו.", + "title": "אין זרם" + }, + "title": "מקורות", + "unknownOption": "לא ידוע" + } + }, + "metadata": { + "failed": { + "badge": "נכשל", + "homeButton": "חזור לדף הבית", + "text": "לא היה ניתן לטעון את הmetadata של המדיה מ-TMDB. אנא בדוק אם TMDB מושבת או חסום בחיבור האינטרנט שלך.", + "title": "טעינת הmetdata נכשלה" + }, + "notFound": { + "badge": "לא נמצא", + "homeButton": "חזרה לדף הבית", + "text": "לא הצלחנו למצוא את המדיה שביקשת. או שהוא הוסר או שהתעסקת בכתובת האתר.", + "title": "לא הצלחנו למצוא את המדיה הזו." + } + }, + "nextEpisode": { + "cancel": "בטל", + "next": "פרק הבא" + }, + "playbackError": { + "badge": "שגיאת ניגון", + "errors": { + "errorAborted": "השגת המדיה בוטלה על ידי בקשת המשתמש.", + "errorDecode": "למרות שנקבע קודם כל שהמדיה יכולה להשתמש בה, אירעה שגיאה בעת ניסיון לפענח משאבי המדיה, וכתוצאה מכך קרה שגיאה.", + "errorGenericMedia": "‍אירעה שגיאת מדיה לא ידועה.", + "errorNetwork": "אירעה סוג של שגיאת רשת שמנעה גישה למדיה, למרות שהיא הייתה זמינה מראש.", + "errorNotSupported": "המדיה או ספק המדיה אינם נתמכים." + }, + "homeButton": "חזור לדף הבית", + "text": "אירעה שגיאה בהפעלת המדיה. אנא נסה שוב.", + "title": "הפעלת הסרטון נכשלה!" + }, + "scraping": { + "items": { + "failure": "אירעה שגיאה", + "notFound": "אין את הסרטון", + "pending": "מחפש סרטונים..." + }, + "notFound": { + "badge": "לא נמצא", + "detailsButton": "הצג פרטים", + "homeButton": "חזור לדף הבית", + "text": "חיפשנו בספקים שלנו ולא מצאנו את המדיה שאתה מחפש! אנו לא מארחים את המדיה ואין לנו שליטה על מה שזמין. אנא לחץ על 'הצג פרטים' למידע נוסף.", + "title": "לא יכולנו למצוא את זה" + } + } + }, + "screens": { + "dmca": { + "text": "ברוכה הבאה לדף יצירת קשר DMCA של movie-web! אנו מכבדים את זכויות הקניין הרוחני ורוצים לטפל בכל חשש לזכויות יוצרים במהירות. אם אתה סבור שהעבודה שלך המוגנת בזכויות יוצרים נוצלה בצורה לא נכונה בפלטפורמה שלנו, אנא שלח הודעת DMCA מפורטת למייל למטה. אנא כלול תיאור של החומר המוגן בזכויות יוצרים, פרטי ההתקשרות שלך והצהרת תום לב. אנו מחויבים לפתור את העניינים הללו באופן מיידי ומעריכים את שיתוף הפעולה שלך בשמירה על movie-web מקום שמכבד יצירתיות וזכויות יוצרים.", + "title": "DMCA" + }, + "loadingApp": "טוען את האפליקציה", + "loadingUser": "טוען את הפרופיל שלך", + "loadingUserError": { + "logout": "להתנתק", + "reset": "אפס שרת מותאם אישית", + "text": "טעינת הפרופיל שלך נכשלה", + "textWithReset": "לא הצלחנו לטעון את הפרופיל שלך מהשרת המותאם אישית שלך, תרצה לאפס בחזרה לשרת ברירת המחדל?" + }, + "migration": { + "failed": "העברת הנתונים שלך נכשלה.", + "inProgress": "אנא המתן, אנו מעבירים את הנתונים שלך. זה לא אמור לקחת הרבה זמן." + } + }, + "settings": { + "reset": "איפוס", + "save": "לשמור", + "sidebar": { + "info": { + "hostname": "שם מארח", + "title": "מידע על האפליקציה", + "userId": "זהות המשתמש" + } + }, + "unsaved": "יש לך שינויים שלא נשמרו" + } +} From 086b7e357db0e11f6c51b5ee90a9660a72eb2932 Mon Sep 17 00:00:00 2001 From: Origaming Date: Sat, 16 Dec 2023 13:04:58 +0000 Subject: [PATCH 23/33] Translated using Weblate (French) Currently translated at 99.5% (245 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/fr/ Author: Origaming --- src/assets/locales/fr.json | 474 ++++++++++++++++++++++++++++++++----- 1 file changed, 411 insertions(+), 63 deletions(-) diff --git a/src/assets/locales/fr.json b/src/assets/locales/fr.json index dff002f7..61b65d10 100644 --- a/src/assets/locales/fr.json +++ b/src/assets/locales/fr.json @@ -1,71 +1,419 @@ { - "global": { - "name": "movie-web" + "about": { + "description": "movie-web est une application web qui recherche des flux sur Internet. L'équipe vise une approche minimaliste de la consommation de contenu.", + "faqTitle": "Questions fréquentes", + "q1": { + "body": "movie-web n'héberge aucun contenu. Lorsque vous cliquez sur un élément à regarder, une recherche est effectuée sur Internet pour trouver le média sélectionné (sur l'écran de chargement et dans l'onglet \"sources vidéo\", vous pouvez voir quelle source vous utilisez). Les médias ne sont jamais téléchargés par movie-web, tout passe par ce mécanisme de recherche.", + "title": "D'où vient le contenu ?" }, - "home": { - "search": { - "allResults": "C'est tout ce que nous avons !", - "sectionTitle": "Résultats de la recherche", - "noResults": "Nous n'avons rien trouvé !", - "failed": "Le média n'a pas été trouvé, veuillez réessayez !", - "loading": "Chargement...", - "placeholder": "Que voulez-vous voir ?" - }, - "bookmarks": { - "sectionTitle": "Favoris" - }, - "continueWatching": { - "sectionTitle": "Continuer le visionnage" - } + "q2": { + "body": "Il n'est pas possible de demander une émission ou un film, movie-web ne gère aucun contenu. Tous les contenus sont consultés par l'intermédiaire de sources sur Internet.", + "title": "Où puis-je demander un show ou un film ?" }, - "media": { - "types": { - "movie": "Film", - "show": "Série" - }, - "episodeDisplay": "S{{season}} E{{episode}}" + "q3": { + "body": "Nos résultats de recherche sont fournis par The Movie Database (TMDB) et s'affichent indépendamment du fait que nos sources possèdent ou non le contenu.", + "title": "Les résultats de la recherche affichent l'émission ou le film, pourquoi ne puis-je pas le lire ?" }, - "player": { - "playbackError": { - "title": "Oups, c'est coupé !" - }, - "metadata": { - "notFound": { - "badge": "Introuvable", - "homeButton": "Retour à l'accueil", - "title": "Impossible de trouver ce média.", - "text": "Nous n'avons pas trouvé le média que vous avez demandé. Soit il a été supprimé, soit vous avez modifié l'URL." - } - }, - "menus": { - "captions": { - "customChoice": "Télécharger des sous-titres", - "customizeLabel": "Personnaliser", - "title": "Sous-titres" - }, - "sources": { - "title": "Sources" - }, - "episodes": { - "button": "Épisodes", - "loadingTitle": "Chargement...", - "loadingList": "Chargement..." - } - }, - "back": { - "default": "Retour à la page d'accueil", - "short": "Retour" - } + "title": "A propos de movie-web" + }, + "actions": { + "copied": "Copié", + "copy": "Copier" + }, + "auth": { + "createAccount": "Vous n'avez pas encore de compte ? <0>Créer un compte.", + "deviceNameLabel": "Nom de l'appareil", + "deviceNamePlaceholder": "Téléphone personnel", + "generate": { + "description": "Votre passphrase fait office de nom d'utilisateur et de mot de passe. Conservez-la précieusement, car vous devrez la saisir pour vous connecter à votre compte", + "next": "J'ai sauvegardé ma passphrase", + "title": "Votre passphrase" }, - "notFound": { - "badge": "Introuvable", - "goHome": "Retour à l'accueil", - "title": "Impossible de trouver cette page", - "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." + "hasAccount": "Vous avez déjà un compte ? <0>Connectez-vous ici.", + "login": { + "description": "Veuillez entrer votre passphrase pour vous connecter à votre compte", + "deviceLengthError": "Veuillez saisir un nom d'appareil", + "passphraseLabel": "Passphrase de 12 mots", + "passphrasePlaceholder": "Passphrase", + "submit": "Se connecter", + "title": "Se connecter à votre compte", + "validationError": "Passphrase incorrecte ou incomplete" }, - "navigation": { - "banner": { - "offline": "Vérifiez votre connexion internet" - } + "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", + "icon": "Icône d'utilisateur", + "next": "Prochain", + "title": "Informations sur le compte" + } + }, + "trust": { + "failed": { + "text": "L'avez-vous configuré correctement ?", + "title": "Échec de la connexion au serveur" + }, + "host": "Vous vous connectez à <0>{{hostname}} - veuillez confirmer que vous lui faites confiance avant de créer un compte.", + "no": "Retour", + "title": "Faites-vous confiance à ce serveur ?", + "yes": "Je fais confiance à ce serveur" + }, + "verify": { + "description": "Veuillez saisir votre passphrase pour confirmer que vous l'avez enregistrée et pour créer votre compte", + "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é", + "register": "Créer un compte", + "title": "Confirmez votre passphrase" } + }, + "errors": { + "badge": "Il s'est cassé", + "details": "Détails de l'erreur", + "reloadPage": "Actualiser la page", + "showError": "Afficher les détails de l'erreur", + "title": "Nous avons rencontré une erreur !" + }, + "footer": { + "legal": { + "disclaimer": "Avertissement", + "disclaimerText": "movie-web n'héberge aucun fichier, il se contente de proposer des liens vers des services tiers. Les questions juridiques doivent être réglées avec les hébergeurs et les fournisseurs de fichiers. movie-web n'est pas responsable des fichiers multimédias diffusés par les fournisseurs de vidéos." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Regardez vos émissions et films préférés avec cette application de streaming open source." + }, + "global": { + "name": "movie-web", + "pages": { + "about": "À propos", + "dmca": "DMCA", + "login": "Se connecter", + "pagetitle": "{{title}} - movie-web", + "register": "Créer un compte", + "settings": "Paramètres" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Favoris" + }, + "continueWatching": { + "sectionTitle": "Continuer le visionnage" + }, + "mediaList": { + "stopEditing": "Arrêter l'édition" + }, + "search": { + "allResults": "C'est tout ce que nous avons !", + "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 ?", + "sectionTitle": "Résultats de la recherche" + }, + "titles": { + "day": { + "default": "Que voulez-vous regarder cet après-midi ?" + }, + "morning": { + "default": "Que voulez-vous regarder ce matin ?", + "extra": [ + "J'ai entendu dire que Before Sunrise était un bon film" + ] + }, + "night": { + "default": "Que voulez-vous regarder ce soir ?", + "extra": [ + "Fatigué ? J'ai entendu dire que L'Exorciste était bien." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Série" + } + }, + "navigation": { + "banner": { + "offline": "Vérifiez votre connexion internet" + }, + "menu": { + "about": "À propos de nous", + "donation": "Faire un don", + "logout": "Se déconnecter", + "register": "Synchroniser au Cloud", + "settings": "Paramètres", + "support": "Support" + } + }, + "notFound": { + "badge": "Introuvable", + "goHome": "Retour à 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" + }, + "overlays": { + "close": "Fermer" + }, + "player": { + "back": { + "default": "Retour à la page d'accueil", + "short": "Retour" + }, + "casting": { + "enabled": "Casting à l'appareil..." + }, + "menus": { + "captions": { + "customChoice": "Télécharger des sous-titres", + "customizeLabel": "Personnaliser", + "offChoice": "Désactivé", + "settings": { + "delay": "Délai des sous-titres", + "fixCapitals": "Correction de la majuscule" + }, + "title": "Sous-titres", + "unknownLanguage": "Inconnu" + }, + "downloads": { + "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.", + "downloadCaption": "Télécharger les sous-titres actuels", + "downloadVideo": "Télécharger la vidéo", + "hlsExplanation": "Ce média est un flux HLS qui ne peut pas être téléchargé sur movie-web.", + "onAndroid": { + "1": "Pour télécharger sur Android, cliquez sur le bouton de téléchargement puis, sur la nouvelle page, tapez et maintenez sur la vidéo, puis sélectionnez enregistrer.", + "shortTitle": "Télécharger / Android", + "title": "Téléchargement sur Android" + }, + "onIos": { + "1": "Pour télécharger sur iOS, cliquez sur le bouton de téléchargement puis, sur la nouvelle page, cliquez sur , puis Enregistrer dans les fichiers .", + "shortTitle": "Télécharger / iOS", + "title": "Télécharger sur iOS" + }, + "onPc": { + "1": "Sur PC, cliquez sur le bouton de téléchargement puis, sur la nouvelle page, faites un clic droit sur la vidéo et sélectionnez Enregistrer la vidéo sous", + "shortTitle": "Télécharger / PC", + "title": "Téléchargement sur PC" + }, + "title": "Télécharger" + }, + "episodes": { + "button": "Épisodes", + "emptyState": "Il n'y a pas d'épisodes dans cette saison, revenez plus tard !", + "episodeBadge": "E{{episode}}", + "loadingError": "Erreur de chargement de la saison", + "loadingList": "Chargement...", + "loadingTitle": "Chargement..." + }, + "playback": { + "speedLabel": "Vitesse de lecture", + "title": "Paramètres de lecture" + }, + "quality": { + "automaticLabel": "Qualité automatique", + "hint": "Vous pouvez essayer de <0>changer de fournisseur/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 pour obtenir des options de qualité différentes.", + "title": "Qualité" + }, + "settings": { + "captionItem": "Paramètres des sous-titres", + "downloadItem": "Télécharger", + "enableCaptions": "Activer les sous-titres", + "experienceSection": "Expérience de visionnage", + "playbackItem": "Paramètres de lecture", + "qualityItem": "Qualité", + "sourceItem": "Sources vidéo", + "videoSection": "Paramètres vidéo" + }, + "sources": { + "failed": { + "text": "Une erreur s'est produite lors de la recherche de vidéos, veuillez essayer une autre source.", + "title": "Échec de la récupération (scrape)" + }, + "noEmbeds": { + "text": "Nous n'avons pas trouvé de liens, veuillez essayer une autre source.", + "title": "Pas d'embeds trouvés" + }, + "noStream": { + "text": "Cette source n'a pas de flux pour ce film ou cette émission.", + "title": "Pas de flux" + }, + "title": "Sources", + "unknownOption": "Inconnu" + } + }, + "metadata": { + "failed": { + "badge": "Échec", + "homeButton": "Retour à la maison", + "text": "Impossible de charger les métadonnées du média à partir de TMDB. Veuillez vérifier si TMDB est en panne ou bloqué sur votre connexion internet.", + "title": "Échec du chargement des métadonnées" + }, + "notFound": { + "badge": "Introuvable", + "homeButton": "Retour à 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." + } + }, + "nextEpisode": { + "cancel": "Annuler", + "next": "Prochain épisode" + }, + "playbackError": { + "badge": "Erreur de lecture", + "errors": { + "errorAborted": "L'extraction du média a été interrompue à la demande de l'utilisateur.", + "errorDecode": "Bien qu'elle ait été jugée utilisable, une erreur s'est produite lors de la tentative de décodage de la ressource multimédia, ce qui a entraîné une erreur.", + "errorGenericMedia": "Une erreur de média inconnue est survenue.", + "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", + "text": "Une erreur s'est produite lors de la lecture du média. Veuillez réessayer.", + "title": "Oups, c'est coupé !" + }, + "scraping": { + "items": { + "failure": "Une erreur est survenue", + "notFound": "N'a pas la vidéo", + "pending": "Recherche de vidéos..." + }, + "notFound": { + "badge": "Non trouvé", + "detailsButton": "Afficher les détails", + "homeButton": "Retour à la maison", + "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" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} restant • Fini à {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + } + }, + "screens": { + "dmca": { + "text": "Bienvenue sur la page de contact DMCA de movie-web ! Nous respectons les droits de propriété intellectuelle et souhaitons répondre rapidement à toute question relative aux droits d'auteur. Si vous pensez que votre œuvre protégée par des droits d'auteur a été utilisée de manière inappropriée sur notre plateforme, veuillez envoyer une notification DMCA détaillée à l'adresse électronique ci-dessous. Veuillez inclure une description du matériel protégé par des droits d'auteur, vos coordonnées et une déclaration de bonne foi. Nous nous engageons à résoudre ces problèmes rapidement et vous remercions de votre coopération pour que movie-web reste un lieu respectueux de la créativité et des droits d'auteur.", + "title": "DMCA" + }, + "loadingApp": "Chargement de l'application", + "loadingUser": "Chargement de votre profil", + "loadingUserError": { + "logout": "Se déconnecter", + "reset": "Réinitialiser le serveur personnalisé", + "text": "Échec du chargement de votre profil", + "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é.", + "inProgress": "Veuillez patienter, nous sommes en train de migrer vos données. Cela ne devrait pas prendre longtemps." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Nom de l'appareil", + "deviceNamePlaceholder": "Téléphone personnel", + "editProfile": "Éditer", + "logoutButton": "Se déconnecter" + }, + "actions": { + "delete": { + "button": "Supprimer le compte", + "confirmButton": "Supprimer le compte", + "confirmDescription": "Êtes-vous sûr de vouloir supprimer votre compte ? Toutes vos données seront perdues !", + "confirmTitle": "Êtes-vous sûr ?", + "text": "Cette action est irréversible. Toutes les données seront supprimées et rien ne pourra être récupéré.", + "title": "Supprimer le compte" + }, + "title": "Actions" + }, + "devices": { + "deviceNameLabel": "Nom de l'appareil", + "failed": "Échec du chargement des sessions", + "removeDevice": "Enlever", + "title": "Appareils" + }, + "profile": { + "finish": "Terminer l'édition", + "firstColor": "Couleur de profil un", + "secondColor": "Couleur de profil deux", + "title": "Éditer la photo de profil", + "userIcon": "Icône de l'utilisateur" + }, + "register": { + "cta": "Commencer", + "text": "Partagez la progression de vos films et séries entre vos appareils et gardez-les synchronisés.", + "title": "Synchroniser au Cloud" + }, + "title": "Compte" + }, + "appearance": { + "activeTheme": "Actif", + "themes": { + "blue": "Bleu", + "default": "Défaut", + "gray": "Gris", + "red": "Rouge", + "teal": "Saphir" + }, + "title": "Apparence" + }, + "captions": { + "backgroundLabel": "Opacité de l'arrière-plan", + "colorLabel": "Couleur", + "previewQuote": "Je ne dois pas avoir peur. La peur est un tueur d'esprit.", + "textSizeLabel": "Taille du texte", + "title": "Sous-titres" + }, + "connections": { + "server": { + "description": "Si vous souhaitez vous connecter à un backend personnalisé pour stocker vos données, activez cette option et indiquez l'URL.", + "label": "Serveur personnalisé", + "urlLabel": "URL du serveur personnalisé" + }, + "title": "Connexions", + "workers": { + "addButton": "Ajouter un nouveau worker", + "description": "Pour que l'application fonctionne, tout le trafic est acheminé via des proxys. Activez cette option si vous souhaitez faire appel à vos propres workers.", + "emptyState": "Pas encore de workers, ajoutez-en un ci-dessous", + "label": "Utiliser des agents proxy personnalisés", + "urlLabel": "URLs des workers", + "urlPlaceholder": "https://" + } + }, + "locale": { + "language": "Langue de l'application", + "languageDescription": "Langue appliquée dans l'ensemble de l'app." + }, + "reset": "Réinitialiser", + "save": "Sauvegarder", + "sidebar": { + "info": { + "appVersion": "Version de l'application", + "backendUrl": "URL de Backend", + "backendVersion": "Version de la Backend", + "hostname": "Nom d'hôte", + "insecure": "Insécure", + "notLoggedIn": "Vous n'êtes pas connecté", + "secure": "Sécurisé", + "title": "Informations sur l'application", + "unknownVersion": "Inconnu", + "userId": "ID de l'utilisateur" + } + }, + "unsaved": "Vous avez des changements non sauvegardés" + } } From 60da77dd4eca4ce956768150b6ab02550e7a52e6 Mon Sep 17 00:00:00 2001 From: thehairy Date: Sat, 16 Dec 2023 13:28:10 +0000 Subject: [PATCH 24/33] Translated using Weblate (German) Currently translated at 85.3% (210 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/de/ Author: thehairy --- src/assets/locales/de.json | 48 ++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/assets/locales/de.json b/src/assets/locales/de.json index 248b9410..7bb6f2c0 100644 --- a/src/assets/locales/de.json +++ b/src/assets/locales/de.json @@ -17,6 +17,7 @@ "copy": "Kopieren" }, "auth": { + "createAccount": "Du hast noch keinen Account? <0>Registriere dich jetzt.", "deviceNameLabel": "Gerätename", "deviceNamePlaceholder": "Handy", "generate": { @@ -24,9 +25,11 @@ "next": "Ich habe meine Passphrase gespeichert", "title": "Deine Passphrase" }, + "hasAccount": "Du hast bereits einen Account? <0>Anmelden.", "login": { "description": "Gebe deine Passphrase ein, um dich in deinem Konto anzumelden", - "deviceLengthError": "Gebe ein Gerätename ein", + "deviceLengthError": "Gebe einen Gerätenamen ein", + "passphraseLabel": "12-Wort Passphrase", "passphrasePlaceholder": "Passphrase", "submit": "Anmelden", "title": "Melde dich in deinem Konto an", @@ -44,15 +47,19 @@ }, "trust": { "failed": { - "title": "Konnte Server nicht erreichen" + "text": "Hast du es korrekt konfiguriert?", + "title": "Server nicht erreichbar" }, + "host": "Du verbindest dich zu <0>{{hostname}} - stelle sicher, dass du diesem vertraust, bevor du einen Account erstellst", "no": "Zurück", "title": "Vertraust du diesem Server?", "yes": "Ich vertraue diesem Server" }, "verify": { + "description": "Bitte gebe deine Passphrase vom früheren Schritt an, um zu bestätigen, dass du sie gespeichert hast und um dein Konto zu erstellen", "invalidData": "Daten sind ungültig", "noMatch": "Passphrasen stimmen nicht überein", + "passphraseLabel": "Deine 12-Wort Passphrase", "recaptchaFailed": "ReCaptcha Verifizierung ist fehlgeschlagenen", "register": "Konto erstellen", "title": "Bestätige deine Passphrase" @@ -61,6 +68,7 @@ "errors": { "badge": "Kaputt", "details": "Fehlerdetails", + "reloadPage": "Seite neuladen", "showError": "Zeige Fehlerdetails an", "title": "Ein Fehler ist aufgetreten!" }, @@ -77,6 +85,7 @@ "global": { "name": "movie-web", "pages": { + "about": "Über", "dmca": "DMCA", "login": "Anmelden", "pagetitle": "{{title}} - movie-web", @@ -143,7 +152,7 @@ "notFound": { "badge": "Nicht gefunden", "goHome": "Zurück zur Startseite", - "message": "Wir haben überall gesucht, aber am Ende konnten wir die gesuchte Seite nicht finden.", + "message": "Wir haben überall gesucht: Unter den Eimern, im Schrank, hinter der Proxy, aber am Ende konnten wir die gesuchte Seite nicht finden.", "title": "Diese Seite wurde nicht gefunden" }, "overlays": { @@ -154,6 +163,9 @@ "default": "Zurück zur Startseite", "short": "Rückmeldung" }, + "casting": { + "enabled": "Casting zum Gerät..." + }, "menus": { "captions": { "customChoice": "Untertitel hochladen", @@ -200,12 +212,26 @@ "settings": { "captionItem": "Untertiteleinstellungen", "downloadItem": "Download", + "enableCaptions": "Untertitel aktivieren", + "experienceSection": "Anzeigeerlebnis", "playbackItem": "Wiedergabeeinstellungen", "qualityItem": "Qualität", "sourceItem": "Videoquellen", "videoSection": "Videoeinstellungen" }, "sources": { + "failed": { + "text": "Beim Versuch, Videos zu finden, ist ein Fehler aufgetreten. Bitte versuche es mit einer anderen Quelle.", + "title": "Scrapen fehlgeschlagen" + }, + "noEmbeds": { + "text": "Es konnten keine Embeds gefunden werden. Bitte versuchen es mit einer anderen Quelle.", + "title": "Keine Embeds gefunden" + }, + "noStream": { + "text": "Diese Quelle bietet keine Streams für diesen Film oder diese Serie.", + "title": "Kein Stream" + }, "title": "Quellen", "unknownOption": "Unbekannt" } @@ -220,7 +246,7 @@ "notFound": { "badge": "Nicht gefunden", "homeButton": "Zurück zur Startseite", - "text": "Wir konnten die angeforderten Medien nicht finden.", + "text": "Wir konnten das angeforderte Medium nicht finden.", "title": "Das Medium konnte nicht gefunden werden." } }, @@ -232,7 +258,10 @@ "badge": "Wiedergabefehler", "errors": { "errorAborted": "Das Laden des Videos wurde vom Nutzer abgebrochen.", - "errorGenericMedia": "Unbekannter Videofehler ist aufgetreten." + "errorDecode": "Trotz vorheriger Feststellung der Nutzbarkeit trat ein Fehler beim Versuch auf, die Mediumdatei zu decodieren, was zu einem Fehler führte.", + "errorGenericMedia": "Unbekannter Videofehler ist aufgetreten.", + "errorNetwork": "Es ist ein Netzwerkfehler aufgetreten, der das erfolgreiche Abrufen des Mediums verhinderte, obwohl es zuvor verfügbar war.", + "errorNotSupported": "Das Medium- oder Mediumanbieterobjekt wird nicht unterstützt." }, "homeButton": "Zurück zur Startseite", "text": "Ein Fehler ist während der Wiedergabe aufgetreten. Versuche es erneut.", @@ -240,18 +269,23 @@ }, "scraping": { "items": { - "failure": "Ein Fehler ist aufgetreten" + "failure": "Ein Fehler ist aufgetreten", + "notFound": "Video nicht gefunden", + "pending": "Suche nach Videos..." }, "notFound": { "badge": "Nicht gefunden", "detailsButton": "Details anzeigen", "homeButton": "Zurück zur Startseite", + "text": "Wir haben alle Anbieter durchsucht, konnten aber nicht das Video finden nach dem du suchst! Wir stellen keine eigenen Videos bereit und haben keine Kontrolle darüber, was verfügbar ist. Bitte klicke \"Details anzeigen\" für mehr Details.", "title": "Wir konnten das nicht finden" } }, "time": { "regular": "{{timeWatched}} / {{duration}}", - "shortRegular": "{{timeWatched}}" + "remaining": "{{timeLeft}} übrig • Fertig um {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" } }, "screens": { From c5893e926013a5186478d7dbd904ba45ffefff3a Mon Sep 17 00:00:00 2001 From: Kipoddo Date: Sat, 16 Dec 2023 13:55:04 +0000 Subject: [PATCH 25/33] Translated using Weblate (Hebrew) Currently translated at 80.0% (197 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/he/ Author: Kipoddo --- src/assets/locales/he.json | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/assets/locales/he.json b/src/assets/locales/he.json index 8e35d074..bb4fef11 100644 --- a/src/assets/locales/he.json +++ b/src/assets/locales/he.json @@ -280,12 +280,63 @@ } }, "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "שם מכשיר", + "deviceNamePlaceholder": "מכשיר אישי", + "editProfile": "ערוך", + "logoutButton": "התנתק" + }, + "actions": { + "delete": { + "button": "מחק משתמש", + "confirmTitle": "אתה בטוח?", + "text": "פעולה זו היא בלתי הפיכה. כל הנתונים יימחקו ולא ניתן יהיה לשחזר דבר.", + "title": "מחק משתמש" + }, + "title": "פעולות" + }, + "devices": { + "deviceNameLabel": "שם מכשיר", + "failed": "טעינת ההפעלות נכשלה", + "removeDevice": "הסר", + "title": "מכשירים" + }, + "profile": { + "finish": "סייםעריכה", + "firstColor": "‫‫צבע פרופיל ראשון", + "secondColor": "צבע פרופיל שני", + "title": "ערוך תמונת פרופיל", + "userIcon": "סמל משתמש" + }, + "register": { + "cta": "התחל", + "text": "שתף את התקדמות הצפייה שלך בין מכשירים ושמור אותם מסונכרנים.", + "title": "סנכרון לענן" + }, + "title": "משתמש" + }, + "appearance": { + "activeTheme": "פעיל", + "themes": { + "blue": "כחול", + "default": "ברירת מחדל", + "gray": "אפור", + "red": "אדום", + "teal": "ירוק כחלחל" + }, + "title": "מראה" + }, "reset": "איפוס", "save": "לשמור", "sidebar": { "info": { + "appVersion": "גרסת האפליקציה", "hostname": "שם מארח", + "notLoggedIn": "אתה לא מחובר", + "secure": "אבטח", "title": "מידע על האפליקציה", + "unknownVersion": "לא ידוע", "userId": "זהות המשתמש" } }, From f328bf732e9f3bacedca1cb6a6f7e0a652a56505 Mon Sep 17 00:00:00 2001 From: DQVIST Date: Sat, 16 Dec 2023 15:11:12 +0000 Subject: [PATCH 26/33] Added translation using Weblate (Swedish) Author: DQVIST --- src/assets/locales/sv.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/assets/locales/sv.json diff --git a/src/assets/locales/sv.json b/src/assets/locales/sv.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/src/assets/locales/sv.json @@ -0,0 +1 @@ +{} From a67d1357c390921f4beb6cf210b20073c742fb8c Mon Sep 17 00:00:00 2001 From: teaishealthy Date: Sat, 16 Dec 2023 14:49:55 +0000 Subject: [PATCH 27/33] Translated using Weblate (German) Currently translated at 100.0% (246 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/de/ Author: teaishealthy --- src/assets/locales/de.json | 50 ++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/assets/locales/de.json b/src/assets/locales/de.json index 7bb6f2c0..5c1c040e 100644 --- a/src/assets/locales/de.json +++ b/src/assets/locales/de.json @@ -1,13 +1,17 @@ { "about": { + "description": "movie-web ist eine Web-App, welche das Internet nach Streams durchsucht. Das Team versucht einen minimalistischen Ansatz umzusetzen.", "faqTitle": "Häufig gestellte Fragen", "q1": { + "body": "movie-web hostet keinen eigenen Inhalt. Wenn du auf etwas zum Anschauen klickst, wird das Internet danach durchsucht (Auf dem Ladebildschirm und im Tab \"Videoquellen\" kannst du einstellen, welche Quellen verwendet werden sollen). movie-web lädt keine Videos hoch, alles Videos stammen aus der Suche.", "title": "Woher kommen die Videos?" }, "q2": { + "body": "Das Anfragen von Serien oder Filmen ist nicht möglich. movie-web verwaltet keine Inhalte. Alle Videos stammen vom Quellen aus dem Internet.", "title": "Wo kann ich eine Serie oder einen Film anfragen?" }, "q3": { + "body": "Unsere Suchergebnisse werden von The Movie Database (TMDB) bereitgestellt und angezeigt, egal ob unsere Videoquellen über dieses Video verfügen.", "title": "Die Suche zeigt eine Serie oder einen Film an, warum kann ich den dann nicht abspielen?" }, "title": "Über movie-web" @@ -74,13 +78,15 @@ }, "footer": { "legal": { - "disclaimer": "Hinweis" + "disclaimer": "Hinweis", + "disclaimerText": "movie-web hostet keine Dateien, sondern verlinkt lediglich auf Dienste Dritter. Rechtliche Fragen sollten mit den Dateihostern und -anbietern geklärt werden. movie-web übernimmt keine Verantwortung für die von den Videoanbietern angezeigten Mediendateien." }, "links": { "discord": "Discord", "dmca": "DMCA", "github": "GitHub" - } + }, + "tagline": "Schau deine Lieblingsserien und Filme mit dieser quelloffenen Streaming App." }, "global": { "name": "movie-web", @@ -172,23 +178,30 @@ "customizeLabel": "Bearbeiten", "offChoice": "Aus", "settings": { - "delay": "Untertitelverzögerung" + "delay": "Untertitelverzögerung", + "fixCapitals": "Großschreibung korrigieren" }, "title": "Untertitel", "unknownLanguage": "Unbekannt" }, "downloads": { + "disclaimer": "Videos werden direkt vom Provider heruntergeladen. movie-web hat nicht steuern, wie die Downloads bereitgestellt werden.", "downloadCaption": "Ausgewählte Untertitel herunterladen", "downloadVideo": "Video herunterladen", "hlsExplanation": "Dieses Video ist ein HLS-Stream, welcher auf movie-web nicht heruntergeladen werden kann.", "onAndroid": { "1": "Um auf Android Herunterzuladen, tippe auf den Download-Button, tippe und halte auf der neuen Seite auf das Video und wähle Speichern aus.", + "shortTitle": "Download / Android", "title": "Auf Android herunterladen" }, "onIos": { + "1": "Um Auf iOS herunterzuladen, klick auf den Download-Button. Klicke dann auf der neuen Seite auf , dann auf In Dateien sichern .", + "shortTitle": "Download / iOS", "title": "Auf iOS herunterladen" }, "onPc": { + "1": "Um am PC herunterzuladen, klicke auf den Download-Button. Klicke dann mit der rechten Maustaste auf das Video und klicke auf Video speichern als", + "shortTitle": "Download / PC", "title": "Am PC herunterladen" }, "title": "Download" @@ -207,6 +220,8 @@ }, "quality": { "automaticLabel": "Automatische Qualitätseinstellung", + "hint": "Du kannst versuchen die <0>Quelle zu ändern um andere Qualitätsoptionen zu erhalten.", + "iosNoQuality": "Durch eine Einschränkung von Apple ist die Qualitätsauswahl für iOS für diese Quelle nicht verfügbar. Du kannst versuchen <0>einen andere Quelle auszuwählen um andere Qualitätsoptionen zu erhalten.", "title": "Qualität" }, "settings": { @@ -293,8 +308,17 @@ "text": "Willkommen zu movie-webs DMCA-Kontaktseite! Wir respektieren geistiges Eigentum und wollen uns schnell um urheberrechtlichen Anliegen kümmern. Falls du glaubst, dass dein urheberrechtlich geschütztes Werk unsachgemäß auf unserer Plattform verwendet wurde, sende uns bitte eine genaue DMCA-Anfrage an die unten stehende E-Mail. Diese sollte eine Beschreibung des urheberrechtlich geschützten Material, deine Kontaktinformationen sowie einer Erklärung des guten Glaubens beinhalten. Wir sind engagiert diese Anliegen schnell zu lösen und schätzen deine Hilfe dabei movie-web zu einer Plattform, welche Kreativität und Urheberrechte respektiert.", "title": "DMCA" }, + "loadingApp": "Die App wird geladen", + "loadingUser": "Dein Profil wird geladen", "loadingUserError": { - "logout": "Abmelden" + "logout": "Abmelden", + "reset": "Eigenen Server zurücksetzen", + "text": "Beim Laden deines Profils ist ein Fehler aufgetreten", + "textWithReset": "Beim Laden deines Profils von deinem Server ist ein Fehler aufgetreten, zurück zum Standard-Server wechseln?" + }, + "migration": { + "failed": "Beim Migrieren deiner Daten ist ein Fehler aufgetreten.", + "inProgress": "Bitte warte, wir migrieren deine Daten. Das sollte nicht lange dauern." } }, "settings": { @@ -313,7 +337,8 @@ "confirmTitle": "Bist du sicher?", "text": "Diese Aktion kann nicht rückgängig gemacht werden. Alle Daten werden gelöscht und können nicht wiederhergestellt werden.", "title": "Konto löschen" - } + }, + "title": "Aktionen" }, "devices": { "deviceNameLabel": "Gerätename", @@ -329,6 +354,8 @@ "userIcon": "Nutzersymbol" }, "register": { + "cta": "Los geht's", + "text": "Teilen deinen Fortschritt zwischen Geräten und halte sie synchronisiert.", "title": "Mit der Cloud synchronisieren" }, "title": "Konto" @@ -352,12 +379,24 @@ "title": "Untertitel" }, "connections": { + "server": { + "description": "Falls du dich mit einem anderen Server verbinden willst, um deine Daten zu speichern. Aktiviere dies und gebe die URL an.", + "label": "Eigener Server", + "urlLabel": "Eigene Server-URL" + }, + "title": "Verbindungen", "workers": { + "addButton": "Neuen Worker hinzufügen", + "description": "Damit die App funktioniert werden alle Anfrage durch einen Proxy geleitet. Aktiviere dies, falls du deinen eigenen Worker verwenden willst.", + "emptyState": "Keine Worker vorhanden, füge einen unten hinzu", + "label": "Verwenden deinen eigenen Worker-Proxys", + "urlLabel": "Worker-URLs", "urlPlaceholder": "https://" } }, "locale": { "language": "App-Sprache", + "languageDescription": "Sprache für die ganze App.", "title": "Sprache" }, "reset": "Zurücksetzen", @@ -365,6 +404,7 @@ "sidebar": { "info": { "appVersion": "App-Version", + "backendUrl": "Server-URL", "backendVersion": "Server-Version", "hostname": "Hostname", "insecure": "Unsicher", From 6900bae37b71c467acad86ee97a20a6c0b2b4420 Mon Sep 17 00:00:00 2001 From: Origaming Date: Sat, 16 Dec 2023 14:58:09 +0000 Subject: [PATCH 28/33] Translated using Weblate (French) Currently translated at 100.0% (246 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/fr/ Author: Origaming --- src/assets/locales/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/assets/locales/fr.json b/src/assets/locales/fr.json index 61b65d10..ef91ec63 100644 --- a/src/assets/locales/fr.json +++ b/src/assets/locales/fr.json @@ -396,7 +396,8 @@ }, "locale": { "language": "Langue de l'application", - "languageDescription": "Langue appliquée dans l'ensemble de l'app." + "languageDescription": "Langue appliquée dans l'ensemble de l'app.", + "title": "Local" }, "reset": "Réinitialiser", "save": "Sauvegarder", From 8e257958ac163e3086250a669804310e7f1b21ef Mon Sep 17 00:00:00 2001 From: Hank Dank Date: Sat, 16 Dec 2023 17:25:13 +0000 Subject: [PATCH 29/33] Translated using Weblate (Turkish) Currently translated at 16.6% (41 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/tr/ Author: Hank Dank --- src/assets/locales/tr.json | 157 ++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 70 deletions(-) diff --git a/src/assets/locales/tr.json b/src/assets/locales/tr.json index 2605174e..083fdf1a 100644 --- a/src/assets/locales/tr.json +++ b/src/assets/locales/tr.json @@ -1,74 +1,91 @@ { - "global": { - "name": "movie-web" + "auth": { + "createAccount": "Henüz bir hesabınız yok mu? <0>Hesap oluşturun.", + "deviceNameLabel": "Cihaz ismi", + "deviceNamePlaceholder": "Kişisel telefon", + "hasAccount": "Zaten hesabınız var mı?<0>Giriş yapın.", + "login": { + "title": "Hesabınıza giriş yapın" }, - "home": { - "search": { - "allResults": "Bu kadarını bulabildik!", - "sectionTitle": "Arama sonuçları", - "noResults": "Hiçbir şey bulamadık!", - "failed": "Medya bulunamadı, tekrar deneyin!", - "loading": "Yükleniyor...", - "placeholder": "Ne izlemek istersiniz?" - }, - "bookmarks": { - "sectionTitle": "Yerimleri" - }, - "continueWatching": { - "sectionTitle": "İzlemeye devam edin" - } - }, - "media": { - "types": { - "movie": "Film", - "show": "Dizi" - }, - "episodeDisplay": "S{{season}} B{{episode}}" - }, - "player": { - "playbackError": { - "title": "Hay aksi, bozuldu!" - }, - "metadata": { - "notFound": { - "badge": "Bulunamadı", - "homeButton": "Geri", - "title": "Medya bulunamadı.", - "text": "İstediğiniz medyayı bulamadık. URL'i yanlış girdiniz ya da medya kaldırıldı." - } - }, - "menus": { - "captions": { - "customChoice": "Altyazı yükle", - "customizeLabel": "Kişiselleştirme", - "title": "Altyazılar" - }, - "sources": { - "title": "Kaynaklar" - }, - "episodes": { - "button": "Bölümler", - "loadingTitle": "Yükleniyor...", - "loadingList": "Yükleniyor..." - } - }, - "back": { - "default": "Ana sayfaya dön", - "short": "Geri" - } - }, - "notFound": { - "badge": "Bulunamadı", - "goHome": "Geri", - "title": "Sayfa bulunamadı", - "message": "Her yere baktık: bazanın altına, dolabın içine hatta ara sunucuya ama maalesef aradığınız sayfayı bulamadık." - }, - "navigation": { - "banner": { - "offline": "İnternet bağlantınızı kontrol ediniz" - } - }, - "overlays": { - "close": "Kapat" + "register": { + "information": { + "color1": "Birinci hesap rengi", + "color2": "İkinci hesap rengi", + "icon": "Kullanıcı simgesi", + "title": "Hesap bilgisi" + } } + }, + "global": { + "name": "movie-web" + }, + "home": { + "bookmarks": { + "sectionTitle": "Yerimleri" + }, + "continueWatching": { + "sectionTitle": "İzlemeye devam edin" + }, + "search": { + "allResults": "Bu kadarını bulabildik!", + "failed": "Medya bulunamadı, tekrar deneyin!", + "loading": "Yükleniyor...", + "noResults": "Hiçbir şey bulamadık!", + "placeholder": "Ne izlemek istersiniz?", + "sectionTitle": "Arama sonuçları" + } + }, + "media": { + "episodeDisplay": "S{{season}} B{{episode}}", + "types": { + "movie": "Film", + "show": "Dizi" + } + }, + "navigation": { + "banner": { + "offline": "İnternet bağlantınızı kontrol ediniz" + } + }, + "notFound": { + "badge": "Bulunamadı", + "goHome": "Geri", + "message": "Her yere baktık: bazanın altına, dolabın içine hatta ara sunucuya ama maalesef aradığınız sayfayı bulamadık.", + "title": "Sayfa bulunamadı" + }, + "overlays": { + "close": "Kapat" + }, + "player": { + "back": { + "default": "Ana sayfaya dön", + "short": "Geri" + }, + "menus": { + "captions": { + "customChoice": "Altyazı yükle", + "customizeLabel": "Kişiselleştirme", + "title": "Altyazılar" + }, + "episodes": { + "button": "Bölümler", + "loadingList": "Yükleniyor...", + "loadingTitle": "Yükleniyor..." + }, + "sources": { + "title": "Kaynaklar" + } + }, + "metadata": { + "notFound": { + "badge": "Bulunamadı", + "homeButton": "Geri", + "text": "İstediğiniz medyayı bulamadık. URL'i yanlış girdiniz ya da medya kaldırıldı.", + "title": "Medya bulunamadı." + } + }, + "playbackError": { + "title": "Hay aksi, bozuldu!" + } + } } From e6d4a43265a0f5d3da964fd33ec4d259cd1240e6 Mon Sep 17 00:00:00 2001 From: Kipoddo Date: Sat, 16 Dec 2023 14:11:08 +0000 Subject: [PATCH 30/33] Translated using Weblate (Hebrew) Currently translated at 100.0% (246 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/he/ Author: Kipoddo --- src/assets/locales/he.json | 77 +++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/assets/locales/he.json b/src/assets/locales/he.json index bb4fef11..889b3564 100644 --- a/src/assets/locales/he.json +++ b/src/assets/locales/he.json @@ -1,4 +1,21 @@ { + "about": { + "description": "movie-web הוא יישום אינטרנט המחפש באינטרנט אחר זרמים. הצוות שואף לגישה מינימליסטית ברובה לצריכת תוכן.", + "faqTitle": "שאלות נפוצות", + "q1": { + "body": "movie-web אינו מארח תוכן כלשהו. כאשר אתה לוחץ על משהו לצפייה, האינטרנט מחפש את המדיה שנבחרה (במסך הטעינה ובכרטיסייה 'מקורות וידאו' תוכל לראות באיזה מקור אתה משתמש). מדיה אף פעם לא מועלת על ידי movie-web, הכל מתבצע דרך מנגנון חיפוש זה.", + "title": "מאיפה התוכן?" + }, + "q2": { + "body": "לא ניתן לבקש תוכנית או סרט, movie-web לא מנהלת שום תוכן. כל התוכן נצפה דרך מקורות באינטרנט.", + "title": "איפה אני יכול לבקש תוכנית או סרט?" + }, + "q3": { + "body": "תוצאות החיפוש שלנו מופעלות על ידי The Movie Database (TMDB) ומוצגות ללא קשר אם למקורות שלנו יש את התוכן.", + "title": "תוצאות החיפוש מציגות את התוכנית או הסרט, למה אני לא יכול להפעיל אותם?" + }, + "title": "על movie-web" + }, "actions": { "copied": "הועתק", "copy": "להעתיק" @@ -12,7 +29,7 @@ "next": "אני שמרתי את משפט הסיסמה שלי", "title": "משפט הסיסמה שלך" }, - "hasAccount": "כבר יש לך חשבון? <0>התחבר כאן.", + "hasAccount": "Already have an account? <0>Login here.", "login": { "description": "אנא הזן את ביטוי הסיסמה שלך כדי להתחבר לחשבונך", "deviceLengthError": "אנא הזן שם מכשיר", @@ -59,10 +76,25 @@ "showError": "הצג פרטי שגיאה", "title": "נתקלנו בשגיאה!" }, + "footer": { + "legal": { + "disclaimer": "תנית ויתור", + "disclaimerText": "movie-web אינו מארח קבצים, הוא רק מקשר לשירותי צד שלישי. יש להתייחס לסוגיות משפטיות עם המארחים והספקים של הקבצים. movie-web אינה אחראית לכל קבצי מדיה המוצגים על ידי ספקי הווידאו." + }, + "links": { + "discord": "דיסקורד", + "dmca": "DMCA", + "github": "גיטהאב" + }, + "tagline": "צפה בתוכניות ובסרטים האהובים עליך עם אפליקציית סטרימינג זו בקוד פתוח." + }, "global": { + "name": "movie-web", "pages": { "about": "אודות", + "dmca": "DMCA", "login": "התחבר", + "pagetitle": "{{title}} - movie-web", "register": "הירשם", "settings": "הגדרות" } @@ -104,6 +136,7 @@ } }, "media": { + "episodeDisplay": "S{{season}} E{{episode}}", "types": { "movie": "סרט", "show": "סדרה" @@ -176,6 +209,7 @@ "episodes": { "button": "פרקים", "emptyState": "אין פרקים בעונה זו, אנא בדוק שוב מאוחר יותר!", + "episodeBadge": "פ{{episode}}", "loadingError": "ארע שגיאה בטעינת העונה", "loadingList": "טוען...", "loadingTitle": "טוען..." @@ -186,6 +220,8 @@ }, "quality": { "automaticLabel": "איכות אוטומטית", + "hint": "You can try <0>switching source to get different quality options.", + "iosNoQuality": "Due to Apple-defined limitations, quality selection is not available on iOS for this source. You can try <0>switching to another source to get different quality options.", "title": "איכות" }, "settings": { @@ -259,6 +295,12 @@ "text": "חיפשנו בספקים שלנו ולא מצאנו את המדיה שאתה מחפש! אנו לא מארחים את המדיה ואין לנו שליטה על מה שזמין. אנא לחץ על 'הצג פרטים' למידע נוסף.", "title": "לא יכולנו למצוא את זה" } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} נשאר • סיים ב {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" } }, "screens": { @@ -290,6 +332,8 @@ "actions": { "delete": { "button": "מחק משתמש", + "confirmButton": "מחק משתמש", + "confirmDescription": "אתה בטוח שתרצה למחוק את המשתמש שלך? כל הנתונים שלך יימחקו!", "confirmTitle": "אתה בטוח?", "text": "פעולה זו היא בלתי הפיכה. כל הנתונים יימחקו ולא ניתן יהיה לשחזר דבר.", "title": "מחק משתמש" @@ -327,12 +371,43 @@ }, "title": "מראה" }, + "captions": { + "backgroundLabel": "אטימות רקע", + "colorLabel": "צבע", + "previewQuote": "אסור לי לפחד. הפחד הוא קוטל הנפש.", + "textSizeLabel": "גודל הטקסט", + "title": "כתוביות" + }, + "connections": { + "server": { + "description": "אם תרצה להתחבר ל-backend מותאם אישית כדי לאחסן את הנתונים שלך, הפעל זאת וספק את כתובת האתר.", + "label": "שרת אישי", + "urlLabel": "כתובת אתר מותאמת אישית של שרת" + }, + "title": "התחברויות", + "workers": { + "addButton": "הוסף עובד חדש", + "description": "כדי שהאפליקציה תפעל, כל התעבורה מנותבת דרך פרוקסי. הפעל זאת אם אתה רוצה להביא עובדים משלך.", + "emptyState": "עדיין אין עובדים, הוסף אחד למטה", + "label": "השתמש בעובדי פרוקסי מותאמים אישית", + "urlLabel": "כתובות אתרים של עובדים", + "urlPlaceholder": "https://" + } + }, + "locale": { + "language": "שפת האפליקציה", + "languageDescription": "השפה החלה על האפליקציה כולה.", + "title": "מקומי" + }, "reset": "איפוס", "save": "לשמור", "sidebar": { "info": { "appVersion": "גרסת האפליקציה", + "backendUrl": "כתובת אתר אחורי", + "backendVersion": "גרסת Backend", "hostname": "שם מארח", + "insecure": "לא בטוח", "notLoggedIn": "אתה לא מחובר", "secure": "אבטח", "title": "מידע על האפליקציה", From 6b2f1a1bc8000463fc71586c567556af2ce58e4d Mon Sep 17 00:00:00 2001 From: DQVIST Date: Sat, 16 Dec 2023 15:29:59 +0000 Subject: [PATCH 31/33] Translated using Weblate (Swedish) Currently translated at 100.0% (246 of 246 strings) Translation: movie-web/website Translate-URL: http://weblate.movie-web.app/projects/movie-web/website/sv/ Author: DQVIST --- src/assets/locales/sv.json | 421 ++++++++++++++++++++++++++++++++++++- 1 file changed, 420 insertions(+), 1 deletion(-) diff --git a/src/assets/locales/sv.json b/src/assets/locales/sv.json index 0967ef42..2cd0f18c 100644 --- a/src/assets/locales/sv.json +++ b/src/assets/locales/sv.json @@ -1 +1,420 @@ -{} +{ + "about": { + "description": "movie-web är en webbapplikation som söker efter strömmar på internet. Teamet strävar efter en mestadels minimalistisk ansats för att konsumera innehåll.", + "faqTitle": "Vanliga frågor", + "q1": { + "body": "movie-web hostar inte något innehåll. När du klickar på något att titta på, söks internet efter den valda median (På laddningsskärmen och i fliken 'video sources' kan du se vilken källa du använder). Media laddas aldrig upp av movie-web, allt går genom detta sökmechanism.", + "title": "Var kommer innehållet ifrån?" + }, + "q2": { + "body": "Det går inte att begära en show eller film, movie-web hanterar inte något innehåll. Allt innehåll visas genom källor på internet.", + "title": "Var kan jag begära en show eller film?" + }, + "q3": { + "body": "Våra sökresultat drivs av The Movie Database (TMDB) och visas oavsett om våra källor faktiskt har innehållet.", + "title": "Sökresultaten visar showen eller filmen, varför kan jag inte spela upp den?" + }, + "title": "Om movie-web" + }, + "actions": { + "copied": "Kopierad", + "copy": "Kopiera" + }, + "auth": { + "createAccount": "Har du inget konto ännu? <0>Skapa ett konto.", + "deviceNameLabel": "Enhetsnamn", + "deviceNamePlaceholder": "Min telefon", + "generate": { + "description": "Ditt lösenord fungerar som ditt användarnamn och lösenord. Se till att hålla det säkert eftersom du behöver ange det för att logga in på ditt konto", + "next": "Jag har sparat mitt lösenord", + "title": "Ditt lösenord" + }, + "hasAccount": "Har redan ett konto? <0>Logga in här.", + "login": { + "description": "Ange ditt lösenord för att logga in på ditt konto", + "deviceLengthError": "Ange ett enhetsnamn", + "passphraseLabel": "12-ords lösenord", + "passphrasePlaceholder": "Lösenord", + "submit": "Logga in", + "title": "Logga in på ditt konto", + "validationError": "Felaktigt eller ofullständigt lösenord" + }, + "register": { + "information": { + "color1": "Profilfärg ett", + "color2": "Profilfärg två", + "header": "Ange ett namn för din enhet och välj färger samt ett användarikon efter eget val", + "icon": "Användarikon", + "next": "Nästa", + "title": "Kontoinformation" + } + }, + "trust": { + "failed": { + "text": "Har du konfigurerat den korrekt?", + "title": "Kunde inte nå servern" + }, + "host": "Du ansluter till <0>{{hostname}} - bekräfta att du litar på den innan du skapar ett konto", + "no": "Gå tillbaka", + "title": "Litar du på denna server?", + "yes": "Jag litar på denna server" + }, + "verify": { + "description": "Ange ditt lösenord igen för att bekräfta att du har sparat det och skapa ditt konto", + "invalidData": "Data är inte giltig", + "noMatch": "Lösenorden matchar inte", + "passphraseLabel": "Ditt 12-ords lösenord", + "recaptchaFailed": "ReCaptcha validering misslyckades", + "register": "Skapa konto", + "title": "Bekräfta ditt lösenord" + } + }, + "errors": { + "badge": "Något gick fel", + "details": "Felinformation", + "reloadPage": "Ladda om sidan", + "showError": "Visa felinformation", + "title": "Vi stötte på ett fel!" + }, + "footer": { + "legal": { + "disclaimer": "Ansvarsfriskrivning", + "disclaimerText": "movie-web hostar inga filer, den länkar bara till tjänster från tredje part. Juridiska frågor bör tas upp med filvärdar och leverantörer. movie-web ansvarar inte för några mediefiler som visas av videoleverantörerna." + }, + "links": { + "discord": "Discord", + "dmca": "DMCA", + "github": "GitHub" + }, + "tagline": "Titta på dina favoritprogram och filmer med denna öppna källkodsströmapp." + }, + "global": { + "name": "movie-web", + "pages": { + "about": "Om oss", + "dmca": "DMCA", + "login": "Logga in", + "pagetitle": "{{title}} - movie-web", + "register": "Registrera", + "settings": "Inställningar" + } + }, + "home": { + "bookmarks": { + "sectionTitle": "Bokmärken" + }, + "continueWatching": { + "sectionTitle": "Fortsätt titta" + }, + "mediaList": { + "stopEditing": "Sluta redigera" + }, + "search": { + "allResults": "Det är allt vi har!", + "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å?", + "sectionTitle": "Sökresultat" + }, + "titles": { + "day": { + "default": "Vad vill du titta på i eftermiddag?" + }, + "morning": { + "default": "Vad vill du titta på den här morgonen?", + "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." + ] + } + } + }, + "media": { + "episodeDisplay": "S{{season}} E{{episode}}", + "types": { + "movie": "Film", + "show": "Serie" + } + }, + "navigation": { + "banner": { + "offline": "Kontrollera din internetanslutning" + }, + "menu": { + "about": "Om oss", + "donation": "Donera", + "logout": "Logga ut", + "register": "Synkronisera till molnet", + "settings": "Inställningar", + "support": "Support" + } + }, + "notFound": { + "badge": "Ej hittad", + "goHome": "Tillbaka till startsidan", + "message": "Vi letade överallt: under soptunnorna, i garderoben, bakom proxy men kunde slutligen inte hitta sidan du letar efter.", + "title": "Kunde inte hitta den sidan" + }, + "overlays": { + "close": "Stäng" + }, + "player": { + "back": { + "default": "Tillbaka till startsidan", + "short": "Tillbaka" + }, + "casting": { + "enabled": "Castar till enheten..." + }, + "menus": { + "captions": { + "customChoice": "Välj undertext från fil", + "customizeLabel": "Anpassa", + "offChoice": "Av", + "settings": { + "delay": "Fördröjning för undertexter", + "fixCapitals": "Åtgärda versaler" + }, + "title": "Undertexter", + "unknownLanguage": "Okänd" + }, + "downloads": { + "disclaimer": "Nedladdningar görs direkt från leverantören. movie-web har ingen kontroll över hur nedladdningarna tillhandahålls.", + "downloadCaption": "Ladda ner aktuell undertext", + "downloadVideo": "Ladda ner video", + "hlsExplanation": "Denna media är en HLS-ström som inte kan laddas ner på movie-web.", + "onAndroid": { + "1": "För att ladda ner på Android, klicka på nedladdningsknappen och på den nya sidan trycker och håller på videon, välj sedan spara.", + "shortTitle": "Ladda ner / Android", + "title": "Laddar ner på Android" + }, + "onIos": { + "1": "För att ladda ner på iOS, klicka på nedladdningsknappen och på den nya sidan klickar du på , sedan Spara i filer .", + "shortTitle": "Ladda ner / iOS", + "title": "Laddar ner på iOS" + }, + "onPc": { + "1": "På PC, klicka på nedladdningsknappen och på den nya sidan högerklickar du sedan på videon och väljer Spara video som", + "shortTitle": "Ladda ner / PC", + "title": "Laddar ner på PC" + }, + "title": "Ladda ner" + }, + "episodes": { + "button": "Avsnitt", + "emptyState": "Det finns inga avsnitt i denna säsong, kom tillbaka senare!", + "episodeBadge": "E{{episode}}", + "loadingError": "Fel vid laddning av säsong", + "loadingList": "Laddar...", + "loadingTitle": "Laddar..." + }, + "playback": { + "speedLabel": "Uppspelningshastighet", + "title": "Uppspelningsinställningar" + }, + "quality": { + "automaticLabel": "Automatisk kvalitet", + "hint": "Du kan prova att <0>byta källa för att få olika kvalitetsoptioner.", + "iosNoQuality": "På grund av Apple-definierade begränsningar är kvalitetsval inte tillgängligt på iOS för denna källa. Du kan prova att <0>byta till en annan källa för att få olika kvalitetsoptioner.", + "title": "Kvalitet" + }, + "settings": { + "captionItem": "Undertextinställningar", + "downloadItem": "Ladda ner", + "enableCaptions": "Aktivera undertexter", + "experienceSection": "Visningsupplevelse", + "playbackItem": "Uppspelningsinställningar", + "qualityItem": "Kvalitet", + "sourceItem": "Videokällor", + "videoSection": "Videoinställningar" + }, + "sources": { + "failed": { + "text": "Det uppstod ett fel när vi försökte hitta några videor, försök med en annan källa.", + "title": "Misslyckades med att skrapa" + }, + "noEmbeds": { + "text": "Vi kunde inte hitta några inbäddningar, försök med en annan källa.", + "title": "Inga inbäddningar hittade" + }, + "noStream": { + "text": "Den här källan har ingen ström för denna film eller serie.", + "title": "Ingen ström" + }, + "title": "Källor", + "unknownOption": "Okänd" + } + }, + "metadata": { + "failed": { + "badge": "Misslyckades", + "homeButton": "Till startsidan", + "text": "Kunde inte ladda medias metadata från TMDB. Kontrollera om TMDB är nere eller blockerat på din internetanslutning.", + "title": "Misslyckades att ladda metadata" + }, + "notFound": { + "badge": "Ej hittad", + "homeButton": "Tillbaka till startsidan", + "text": "Vi kunde inte hitta den media du begärde. Antingen har den tagits bort eller så har du manipulerat URL:en.", + "title": "Kunde inte hitta den media." + } + }, + "nextEpisode": { + "cancel": "Avbryt", + "next": "Nästa avsnitt" + }, + "playbackError": { + "badge": "Uppspelningsfel", + "errors": { + "errorAborted": "Hämtningen av media avbröts på användarens begäran.", + "errorDecode": "Trots att det tidigare bedömts som användbart uppstod ett fel vid försök att avkoda mediaresursen, vilket resulterade i ett fel.", + "errorGenericMedia": "Okänt mediafel inträffade.", + "errorNetwork": "Någon form av nätverksfel inträffade vilket förhindrade att media framgångsrikt hämtades, trots att det tidigare var tillgängligt.", + "errorNotSupported": "Media- eller mediaproviderobjektet stöds inte." + }, + "homeButton": "Till startsidan", + "text": "Det uppstod ett fel när vi försökte spela upp media. Försök igen.", + "title": "Misslyckades spela upp video!" + }, + "scraping": { + "items": { + "failure": "Fel inträffade", + "notFound": "Har inte videon", + "pending": "Söker efter videor..." + }, + "notFound": { + "badge": "Ej hittad", + "detailsButton": "Visa detaljer", + "homeButton": "Till startsidan", + "text": "Vi har sökt genom våra leverantörer och kan inte hitta den media du letar efter! Vi hostar inte media och har ingen kontroll över tillgängligheten. Klicka på 'Visa detaljer' nedan för mer information.", + "title": "Vi kunde inte hitta det" + } + }, + "time": { + "regular": "{{timeWatched}} / {{duration}}", + "remaining": "{{timeLeft}} kvar • Slutar kl {{timeFinished, datetime}}", + "shortRegular": "{{timeWatched}}", + "shortRemaining": "-{{timeLeft}}" + } + }, + "screens": { + "dmca": { + "text": "Välkommen till movie-webs DMCA-kontaktsida! Vi respekterar immateriella rättigheter och vill snabbt hantera eventuella upphovsrättsliga bekymmer. Om du tror att ditt upphovsrättsskyddade verk har använts felaktigt på vår plattform, skicka gärna en detaljerad DMCA-notis till e-postadressen nedan. Inkludera en beskrivning av det upphovsrättsskyddade materialet, dina kontaktuppgifter och en tro på god tro. Vi åtar oss att lösa dessa frågor snabbt och uppskattar ditt samarbete för att hålla movie-web som en plats som respekterar kreativitet och upphovsrätt.", + "title": "DMCA" + }, + "loadingApp": "Laddar applikationen", + "loadingUser": "Laddar din profil", + "loadingUserError": { + "logout": "Logga ut", + "reset": "Återställ anpassad server", + "text": "Misslyckades att ladda din profil", + "textWithReset": "Misslyckades att ladda din profil från din anpassade server, vill du återställa till standardservern?" + }, + "migration": { + "failed": "Misslyckades att migrera dina data.", + "inProgress": "Vänligen vänta, vi migrerar dina data. Detta borde inte ta lång tid." + } + }, + "settings": { + "account": { + "accountDetails": { + "deviceNameLabel": "Enhetens namn", + "deviceNamePlaceholder": "Min telefon", + "editProfile": "Redigera", + "logoutButton": "Logga ut" + }, + "actions": { + "delete": { + "button": "Ta bort konto", + "confirmButton": "Ta bort konto", + "confirmDescription": "Är du säker på att du vill ta bort ditt konto? All din data kommer att gå förlorad!", + "confirmTitle": "Är du säker?", + "text": "Denna åtgärd är oåterkallelig. All data kommer att raderas och kan inte återställas.", + "title": "Ta bort konto" + }, + "title": "Åtgärder" + }, + "devices": { + "deviceNameLabel": "Enhetens namn", + "failed": "Misslyckades att ladda sessioner", + "removeDevice": "Ta bort", + "title": "Enheter" + }, + "profile": { + "finish": "Slutför redigering", + "firstColor": "Profilfärg ett", + "secondColor": "Profilfärg två", + "title": "Redigera profilbild", + "userIcon": "Användarikon" + }, + "register": { + "cta": "Kom igång", + "text": "Dela din tittarframsteg mellan enheter och håll dem synkroniserade.", + "title": "Synkronisera till molnet" + }, + "title": "Konto" + }, + "appearance": { + "activeTheme": "Aktiv", + "themes": { + "blue": "Blå", + "default": "Standard", + "gray": "Grå", + "red": "Röd", + "teal": "Blågrön" + }, + "title": "Utseende" + }, + "captions": { + "backgroundLabel": "Bakgrundstransparens", + "colorLabel": "Färg", + "previewQuote": "Jag får inte frukta. Rädsla är tankedödaren.", + "textSizeLabel": "Textstorlek", + "title": "Textning" + }, + "connections": { + "server": { + "description": "Om du vill ansluta till en anpassad bakänd för att lagra dina data, aktivera detta och ange URL:en.", + "label": "Anpassad server", + "urlLabel": "Egen server URL" + }, + "title": "Anslutningar", + "workers": { + "addButton": "Lägg till ny arbetare", + "description": "För att få applikationen att fungera skickas all trafik genom proxys. Aktivera detta om du vill använda egna arbetare.", + "emptyState": "Inga arbetare ännu, lägg till en nedan", + "label": "Använd egna proxyarbetare", + "urlLabel": "Arbetar-URL:er", + "urlPlaceholder": "https://" + } + }, + "locale": { + "language": "Språk för applikationen", + "languageDescription": "Språket som används i hela applikationen.", + "title": "Plats" + }, + "reset": "Återställ", + "save": "Spara", + "sidebar": { + "info": { + "appVersion": "Appversion", + "backendUrl": "Bakänd-URL", + "backendVersion": "Bakändversion", + "hostname": "Värdnamn", + "insecure": "Osäker", + "notLoggedIn": "Du är inte inloggad", + "secure": "Säker", + "title": "Appinformation", + "unknownVersion": "Okänd", + "userId": "Användar-ID" + } + }, + "unsaved": "Du har osparade ändringar" + } +} From 6766337fdb9c81bc9eeb9b964998f0bf6166bfba Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sat, 16 Dec 2023 18:39:59 +0100 Subject: [PATCH 32/33] Update languages + update swedish flag override --- src/assets/languages.ts | 6 +++++- src/components/FlagIcon.tsx | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/assets/languages.ts b/src/assets/languages.ts index d6c47905..39eadf94 100644 --- a/src/assets/languages.ts +++ b/src/assets/languages.ts @@ -2,11 +2,13 @@ import cs from "@/assets/locales/cs.json"; import de from "@/assets/locales/de.json"; import en from "@/assets/locales/en.json"; import fr from "@/assets/locales/fr.json"; +import he from "@/assets/locales/he.json"; import it from "@/assets/locales/it.json"; import minion from "@/assets/locales/minion.json"; import nl from "@/assets/locales/nl.json"; import pirate from "@/assets/locales/pirate.json"; import pl from "@/assets/locales/pl.json"; +import sv from "@/assets/locales/sv.json"; import tr from "@/assets/locales/tr.json"; import vi from "@/assets/locales/vi.json"; import zh from "@/assets/locales/zh.json"; @@ -22,9 +24,11 @@ export const locales = { tr, vi, zh, + he, + sv, pirate, minion, }; export type Locales = keyof typeof locales; -export const rtlLocales: Locales[] = []; +export const rtlLocales: Locales[] = ["he"]; diff --git a/src/components/FlagIcon.tsx b/src/components/FlagIcon.tsx index fd3b2056..ce31b81d 100644 --- a/src/components/FlagIcon.tsx +++ b/src/components/FlagIcon.tsx @@ -20,6 +20,7 @@ const countryOverrides: Record = { vi: "vn", zh: "cn", sl: "si", + sv: "se", }; export function FlagIcon(props: FlagIconProps) { From 3ddcb9feaae8079769f5652b7dbb2ce2a9edd1da Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sat, 16 Dec 2023 18:45:21 +0100 Subject: [PATCH 33/33] Fix some RTL bugs --- src/components/overlays/positions/OverlayAnchorPosition.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/overlays/positions/OverlayAnchorPosition.tsx b/src/components/overlays/positions/OverlayAnchorPosition.tsx index 49cb7d69..0e39de3b 100644 --- a/src/components/overlays/positions/OverlayAnchorPosition.tsx +++ b/src/components/overlays/positions/OverlayAnchorPosition.tsx @@ -64,7 +64,7 @@ export function OverlayAnchorPosition(props: AnchorPositionProps) { transform: `translateX(${left}px) translateY(${top}px)`, }} className={classNames([ - "[&>*]:pointer-events-auto z-10 flex dir-neutral:items-start justify-start dir-neutral:origin-top-left touch-none", + "[&>*]:pointer-events-auto z-10 flex dir-neutral:items-start rtl:justify-start ltr:justify-end dir-neutral:origin-top-left touch-none", props.className, ])} >