From 121a71449f229467c3524cdea7fdf7d7b66aefa1 Mon Sep 17 00:00:00 2001 From: Jorrin Date: Thu, 15 Feb 2024 14:17:57 +0100 Subject: [PATCH 01/22] route subtitles through extension if installed --- src/backend/helpers/subs.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/backend/helpers/subs.ts b/src/backend/helpers/subs.ts index 455f05a9..092de6a9 100644 --- a/src/backend/helpers/subs.ts +++ b/src/backend/helpers/subs.ts @@ -5,6 +5,11 @@ import { convertSubtitlesToSrt } from "@/components/player/utils/captions"; import { CaptionListItem } from "@/stores/player/slices/source"; import { SimpleCache } from "@/utils/cache"; +import { + isExtensionActiveCached, + sendExtensionRequest, +} from "../extension/messaging"; + export const subtitleTypeList = list().map((type) => `.${type}`); const downloadCache = new SimpleCache(); downloadCache.setCompare((a, b) => a === b); @@ -21,7 +26,22 @@ export async function downloadCaption( let data: string | undefined; if (caption.needsProxy) { - data = await proxiedFetch(caption.url, { responseType: "text" }); + if (isExtensionActiveCached()) { + const extensionResponse = await sendExtensionRequest({ + url: caption.url, + method: "GET", + }); + if ( + !extensionResponse?.success || + typeof extensionResponse.response.body !== "string" + ) { + throw new Error("failed to get caption data from extension"); + } + + data = extensionResponse.response.body; + } else { + data = await proxiedFetch(caption.url, { responseType: "text" }); + } } else { data = await fetch(caption.url).then((v) => v.text()); } From f5c1d6eb86a29b24b928162956c4309218f8836b Mon Sep 17 00:00:00 2001 From: Vijay <74645268+vijaysingh2219@users.noreply.github.com> Date: Sat, 17 Feb 2024 23:31:55 +0530 Subject: [PATCH 02/22] Add dynamic and engaging search bar placeholders Enhance search bar experience with 15 dynamic placeholders for the movie web app. Provides a mix of engaging questions and suggestions, promoting user interaction and a personalized feel. Shuffled for a random appearance, contributing to a more dynamic user experience. --- src/assets/locales/en.json | 21 ++++++++++++++++++++- src/pages/parts/home/HeroPart.tsx | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index 61b7e88b..bdb95c01 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -116,7 +116,26 @@ "failed": "Failed to find media, try again!", "loading": "Loading...", "noResults": "We couldn't find anything!", - "placeholder": "What do you want to watch?", + "placeholder": { + "default": "What do you want to watch?", + "extra": [ + "What's on your movie radar today?", + "What's your cinematic preference today?", + "What kind of entertainment are you seeking?", + "What's your ideal movie or series right now?", + "What do you want to explore in the film world?", + "What's on your watchlist for today?", + "What movie or series piques your interest?", + "What's your desired film experience at the moment?", + "What are you in the mood to watch?", + "Looking for a classic or something new?", + "Any specific mood you're in for your watch?", + "In the mood for a thrilling adventure or a cozy drama?", + "Searching for your favorite entertainment?", + "Interested in recent releases or timeless classics?", + "Prefer a short movie night or a binge-watching session?" + ] + }, "sectionTitle": "Search results" }, "titles": { diff --git a/src/pages/parts/home/HeroPart.tsx b/src/pages/parts/home/HeroPart.tsx index fab50f4d..bf39c099 100644 --- a/src/pages/parts/home/HeroPart.tsx +++ b/src/pages/parts/home/HeroPart.tsx @@ -54,7 +54,7 @@ export function HeroPart({ setIsSticky, searchParams }: HeroPartProps) { const time = getTimeOfDay(new Date()); const title = randomT(`home.titles.${time}`); - + const placeholder = randomT(`home.search.placeholder`); const inputRef = useRef(null); useSlashFocus(inputRef); @@ -77,7 +77,7 @@ export function HeroPart({ setIsSticky, searchParams }: HeroPartProps) { onChange={setSearch} value={search} onUnFocus={setSearchUnFocus} - placeholder={t("home.search.placeholder") ?? ""} + placeholder={placeholder ?? ""} /> From 247362a4a9fced65667728b9a37a860721419f5d Mon Sep 17 00:00:00 2001 From: Marcos Rios Date: Sun, 18 Feb 2024 01:23:53 -0300 Subject: [PATCH 03/22] Add preview theme functionality to SettingsPage --- src/pages/Settings.tsx | 20 +++++++++++++++++--- src/pages/layouts/SubPageLayout.tsx | 4 ++-- src/pages/parts/settings/ThemePart.tsx | 15 ++++++++------- src/stores/theme/index.tsx | 21 ++++++++++++++++++++- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 18b755ca..5744e90f 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -33,7 +33,7 @@ import { AccountWithToken, useAuthStore } from "@/stores/auth"; import { useLanguageStore } from "@/stores/language"; import { usePreferencesStore } from "@/stores/preferences"; import { useSubtitleStore } from "@/stores/subtitles"; -import { useThemeStore } from "@/stores/theme"; +import { usePreviewThemeStore, useThemeStore } from "@/stores/theme"; import { SubPageLayout } from "./layouts/SubPageLayout"; import { PreferencesPart } from "./parts/settings/PreferencesPart"; @@ -101,8 +101,10 @@ export function AccountSettings(props: { export function SettingsPage() { const { t } = useTranslation(); - const activeTheme = useThemeStore((s) => s.theme); + const activeTheme = useThemeStore((s) => s.theme) ?? "default"; const setTheme = useThemeStore((s) => s.setTheme); + const previewTheme = usePreviewThemeStore((s) => s.previewTheme) ?? "default"; + const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); const appLanguage = useLanguageStore((s) => s.language); const setAppLanguage = useLanguageStore((s) => s.setLanguage); @@ -143,6 +145,14 @@ export function SettingsPage() { enableThumbnails, ); + const setThemeWithPreview = useCallback( + (v: string | null) => { + state.theme.set(v === "default" ? null : v); + setPreviewTheme(v); + }, + [state.theme, setPreviewTheme], + ); + const saveChanges = useCallback(async () => { if (account) { if ( @@ -241,7 +251,11 @@ export function SettingsPage() { />
- +
diff --git a/src/pages/parts/settings/ThemePart.tsx b/src/pages/parts/settings/ThemePart.tsx index 264c5b40..f4972eaf 100644 --- a/src/pages/parts/settings/ThemePart.tsx +++ b/src/pages/parts/settings/ThemePart.tsx @@ -5,6 +5,10 @@ import { Icon, Icons } from "@/components/Icon"; import { Heading1 } from "@/components/utils/Text"; const availableThemes = [ + { + id: "default", + key: "settings.appearance.themes.default", + }, { id: "blue", key: "settings.appearance.themes.blue", @@ -26,6 +30,7 @@ const availableThemes = [ function ThemePreview(props: { selector?: string; active?: boolean; + inUse?: boolean; name: string; onClick?: () => void; }) { @@ -105,7 +110,7 @@ function ThemePreview(props: { {t("settings.appearance.activeTheme")} @@ -117,6 +122,7 @@ function ThemePreview(props: { export function ThemePart(props: { active: string | null; + inUse: string | null; setTheme: (theme: string | null) => void; }) { const { t } = useTranslation(); @@ -126,16 +132,11 @@ export function ThemePart(props: { {t("settings.appearance.title")}
{/* default theme */} - props.setTheme(null)} - /> {availableThemes.map((v) => ( props.setTheme(v.id)} diff --git a/src/stores/theme/index.tsx b/src/stores/theme/index.tsx index c43ec414..a644c626 100644 --- a/src/stores/theme/index.tsx +++ b/src/stores/theme/index.tsx @@ -25,12 +25,31 @@ export const useThemeStore = create( ), ); +export interface PreviewThemeStore { + previewTheme: string | null; + setPreviewTheme(v: string | null): void; +} + +export const usePreviewThemeStore = create( + immer((set) => ({ + previewTheme: null, + setPreviewTheme(v) { + set((s) => { + s.previewTheme = v; + }); + }, + })), +); + export function ThemeProvider(props: { children?: ReactNode; applyGlobal?: boolean; }) { + const previewTheme = usePreviewThemeStore((s) => s.previewTheme); const theme = useThemeStore((s) => s.theme); - const themeSelector = theme ? `theme-${theme}` : undefined; + + const themeToDisplay = previewTheme ?? theme; + const themeSelector = themeToDisplay ? `theme-${themeToDisplay}` : undefined; return (
From 3522f6c038fda8d31e6d74f22e6666b3474f7338 Mon Sep 17 00:00:00 2001 From: Marcos Rios Date: Sun, 18 Feb 2024 02:54:53 -0300 Subject: [PATCH 04/22] Fix theme preview not being reset after leaving settings --- src/hooks/useSettingsState.ts | 7 +++++++ src/pages/Settings.tsx | 13 ++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/hooks/useSettingsState.ts b/src/hooks/useSettingsState.ts index d0946deb..8e540a19 100644 --- a/src/hooks/useSettingsState.ts +++ b/src/hooks/useSettingsState.ts @@ -9,6 +9,7 @@ import { } from "react"; import { SubtitleStyling } from "@/stores/subtitles"; +import { usePreviewThemeStore } from "@/stores/theme"; export function useDerived( initial: T, @@ -56,6 +57,11 @@ export function useSettingsState( const [backendUrlState, setBackendUrl, resetBackendUrl, backendUrlChanged] = useDerived(backendUrl); const [themeState, setTheme, resetTheme, themeChanged] = useDerived(theme); + const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); + const resetPreviewTheme = useCallback( + () => setPreviewTheme(theme), + [setPreviewTheme, theme], + ); const [ appLanguageState, setAppLanguage, @@ -81,6 +87,7 @@ export function useSettingsState( function reset() { resetTheme(); + resetPreviewTheme(); resetAppLanguage(); resetSubStyling(); resetProxyUrls(); diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 5744e90f..d4ee5292 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -1,5 +1,5 @@ import classNames from "classnames"; -import { useCallback, useEffect, useMemo } from "react"; +import { useCallback, useEffect, useMemo, useRef } from "react"; import { useTranslation } from "react-i18next"; import { useAsyncFn } from "react-use"; @@ -105,6 +105,8 @@ export function SettingsPage() { const setTheme = useThemeStore((s) => s.setTheme); const previewTheme = usePreviewThemeStore((s) => s.previewTheme) ?? "default"; const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); + const activeThemeRef = useRef(activeTheme); + activeThemeRef.current = activeTheme; const appLanguage = useLanguageStore((s) => s.language); const setAppLanguage = useLanguageStore((s) => s.setLanguage); @@ -145,6 +147,15 @@ export function SettingsPage() { enableThumbnails, ); + useEffect( + () => () => { + setPreviewTheme( + activeThemeRef.current === "default" ? null : activeThemeRef.current, + ); + }, + [setPreviewTheme], + ); + const setThemeWithPreview = useCallback( (v: string | null) => { state.theme.set(v === "default" ? null : v); From b1741a32641d49a442bb06c4cbd9d0021b5fe933 Mon Sep 17 00:00:00 2001 From: Vijay <74645268+vijaysingh2219@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:21:34 +0530 Subject: [PATCH 05/22] Updated 'placeholder' key structure across all locale files --- src/assets/locales/ar.json | 17 +++++++---------- src/assets/locales/bg.json | 13 ++++++------- src/assets/locales/bn.json | 17 +++++++---------- src/assets/locales/ca.json | 13 ++++++------- src/assets/locales/cs.json | 17 +++++++---------- src/assets/locales/de.json | 13 ++++++------- src/assets/locales/el.json | 13 ++++++------- src/assets/locales/es.json | 13 ++++++------- src/assets/locales/et.json | 13 ++++++------- src/assets/locales/fa.json | 13 ++++++------- src/assets/locales/fi-FI.json | 13 ++++++------- src/assets/locales/fr.json | 9 +++++---- src/assets/locales/gl.json | 13 ++++++------- src/assets/locales/gu.json | 13 ++++++------- src/assets/locales/he.json | 17 +++++++---------- src/assets/locales/hi.json | 13 ++++++------- src/assets/locales/id.json | 13 ++++++------- src/assets/locales/is-IS.json | 13 ++++++------- src/assets/locales/it.json | 13 ++++++------- src/assets/locales/ja.json | 5 ++++- src/assets/locales/ko.json | 13 ++++++------- src/assets/locales/lv.json | 13 ++++++------- src/assets/locales/minion.json | 13 ++++++------- src/assets/locales/ne.json | 13 ++++++------- src/assets/locales/nl.json | 13 ++++++------- src/assets/locales/pa.json | 13 ++++++------- src/assets/locales/pirate.json | 5 ++++- src/assets/locales/pl.json | 13 ++++++------- src/assets/locales/pt-BR.json | 13 ++++++------- src/assets/locales/pt-PT.json | 13 ++++++------- src/assets/locales/ro.json | 13 ++++++------- src/assets/locales/ru.json | 9 +++++---- src/assets/locales/sl.json | 9 +++++---- src/assets/locales/sv.json | 13 ++++++------- src/assets/locales/th.json | 13 ++++++------- src/assets/locales/tok.json | 17 +++++++---------- src/assets/locales/tr.json | 13 ++++++------- src/assets/locales/uk.json | 13 ++++++------- src/assets/locales/vi.json | 5 ++++- src/assets/locales/zh-Hant.json | 17 +++++++---------- src/assets/locales/zh.json | 17 +++++++---------- 41 files changed, 244 insertions(+), 281 deletions(-) diff --git a/src/assets/locales/ar.json b/src/assets/locales/ar.json index 1f1b23f2..bae488b0 100644 --- a/src/assets/locales/ar.json +++ b/src/assets/locales/ar.json @@ -116,27 +116,24 @@ "failed": "تعذر العثور على الوسائط، حاول مجددا!", "loading": "جار التحميل...", "noResults": "لم نتمكن من العثور على أي شيء!", - "placeholder": "ماذا تريد أن تشاهد؟", + "placeholder": { + "default": "ماذا تريد أن تشاهد؟", + "extra": [] + }, "sectionTitle": "نتائج البحث" }, "titles": { "day": { "default": "ماذا تريد أن تشاهد في هذه الظهيرة؟", - "extra": [ - "متشوق للمغامرة؟ قد يكون Jurassic Park خيارًا مثاليًا لك." - ] + "extra": ["متشوق للمغامرة؟ قد يكون Jurassic Park خيارًا مثاليًا لك."] }, "morning": { "default": "ماذا تريد أن تشاهد في هذا الصباح؟", - "extra": [ - "سمعت أن فلم \"Before Sunrise\" جيد" - ] + "extra": ["سمعت أن فلم \"Before Sunrise\" جيد"] }, "night": { "default": "ماذا تريد أن تشاهد في هذه الليلة؟", - "extra": [ - "مُرهَق؟ سمعت أن فيلم \"The Exorcist\" جيد." - ] + "extra": ["مُرهَق؟ سمعت أن فيلم \"The Exorcist\" جيد."] } } }, diff --git a/src/assets/locales/bg.json b/src/assets/locales/bg.json index 63e112e2..7b5eb88f 100644 --- a/src/assets/locales/bg.json +++ b/src/assets/locales/bg.json @@ -115,7 +115,10 @@ "failed": "Неуспешно намиране на медия, опитайте отново!", "loading": "Зареждане...", "noResults": "Не успяхме да намерим нищо!", - "placeholder": "Какво искате да гледате?", + "placeholder": { + "default": "Какво искате да гледате?", + "extra": [] + }, "sectionTitle": "Резултати от търсенето" }, "titles": { @@ -127,15 +130,11 @@ }, "morning": { "default": "Какво бихте искали да гледате тази сутрин?", - "extra": [ - "Чух, че Before Sunrise е добър" - ] + "extra": ["Чух, че Before Sunrise е добър"] }, "night": { "default": "Какво бихте искали да гледате тази вечер?", - "extra": [ - "Изморен? Чух, че Екзорсистът е добър." - ] + "extra": ["Изморен? Чух, че Екзорсистът е добър."] } } }, diff --git a/src/assets/locales/bn.json b/src/assets/locales/bn.json index 728c3bbd..67dbf76e 100644 --- a/src/assets/locales/bn.json +++ b/src/assets/locales/bn.json @@ -115,27 +115,24 @@ "failed": "মিডিয়া খুঁজে পেতে ব্যর্থ, আবার চেষ্টা করুন!", "loading": "লোড হচ্ছে..।", "noResults": "আমরা কিছুই খুঁজে পাইনি!", - "placeholder": "আপনি কি দেখতে চান?", + "placeholder": { + "default": "আপনি কি দেখতে চান?", + "extra": [] + }, "sectionTitle": "অনুসন্ধান ফলাফল" }, "titles": { "day": { "default": "আপনি এই বিকেলে কি দেখতে চান?", - "extra": [ - "দুঃসাহসিক বোধ করছেন? জুরাসিক পার্ক নিখুঁত পছন্দ হতে পারে।" - ] + "extra": ["দুঃসাহসিক বোধ করছেন? জুরাসিক পার্ক নিখুঁত পছন্দ হতে পারে।"] }, "morning": { "default": "আপনি এই সকালে কি দেখতে চান?", - "extra": [ - "শুনি সূর্যোদয়ের আগে ভালো" - ] + "extra": ["শুনি সূর্যোদয়ের আগে ভালো"] }, "night": { "default": "আপনি আজ রাতে কি দেখতে চান?", - "extra": [ - "ক্লান্ত? আমি শুনেছি দ্য এক্সরসিস্ট ভাল।" - ] + "extra": ["ক্লান্ত? আমি শুনেছি দ্য এক্সরসিস্ট ভাল।"] } } }, diff --git a/src/assets/locales/ca.json b/src/assets/locales/ca.json index 0e2284d9..9b9c4d5b 100644 --- a/src/assets/locales/ca.json +++ b/src/assets/locales/ca.json @@ -115,7 +115,10 @@ "failed": "No s'ha pogut trobar cap contingut, torneu-ho a provar!", "loading": "S'està carregant…", "noResults": "No hem pogut trobar res!", - "placeholder": "Què voleu mirar?", + "placeholder": { + "default": "Què voleu mirar?", + "extra": [] + }, "sectionTitle": "Resultats de la cerca" }, "titles": { @@ -127,15 +130,11 @@ }, "morning": { "default": "Què us agradaria mirar aquest matí?", - "extra": [ - "He sentit que «Abans de l'alba» és bona" - ] + "extra": ["He sentit que «Abans de l'alba» és bona"] }, "night": { "default": "Què us agradaria mirar aquesta nit?", - "extra": [ - "Esteu cansat? He sentit que «L'exorcista» és bona." - ] + "extra": ["Esteu cansat? He sentit que «L'exorcista» és bona."] } } }, diff --git a/src/assets/locales/cs.json b/src/assets/locales/cs.json index 4478d656..eacf47d4 100644 --- a/src/assets/locales/cs.json +++ b/src/assets/locales/cs.json @@ -116,27 +116,24 @@ "failed": "Nepodařilo se najít média, zkuste to znovu!", "loading": "Načítání...", "noResults": "Nemohli jsme nic najít!", - "placeholder": "Co si přejete sledovat?", + "placeholder": { + "default": "Co si přejete sledovat?", + "extra": [] + }, "sectionTitle": "Výsledky vyhledávání" }, "titles": { "day": { "default": "Na co byste se chtěli dnes odpoledne dívat?", - "extra": [ - "Chceš zažít dobrodružství? Jurský Park je pro tebe." - ] + "extra": ["Chceš zažít dobrodružství? Jurský Park je pro tebe."] }, "morning": { "default": "Na co byste se chtěli dnes ráno dívat?", - "extra": [ - "Slyšel jsem, že Před úsvitem je super." - ] + "extra": ["Slyšel jsem, že Před úsvitem je super."] }, "night": { "default": "Na co byste se chtěli dnes večer dívat?", - "extra": [ - "Unaven? Slyšel jsem, že Vymítač ďábla je super." - ] + "extra": ["Unaven? Slyšel jsem, že Vymítač ďábla je super."] } } }, diff --git a/src/assets/locales/de.json b/src/assets/locales/de.json index 31dbe2f8..1d352faf 100644 --- a/src/assets/locales/de.json +++ b/src/assets/locales/de.json @@ -116,7 +116,10 @@ "failed": "Das Medium wurde nicht gefunden, bitte versuchen Sie es erneut!", "loading": "Wird geladen...", "noResults": "Wir haben nichts gefunden!", - "placeholder": "Was möchtest du schauen?", + "placeholder": { + "default": "Was möchtest du schauen?", + "extra": [] + }, "sectionTitle": "Suchergebnisse" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Was würdest du diesen Morgen gerne schauen?", - "extra": [ - "Before Sunrise soll gut sein" - ] + "extra": ["Before Sunrise soll gut sein"] }, "night": { "default": "Was möchtest du diesen Abend gerne schauen?", - "extra": [ - "Müde? Ich hab gehört The Exorcist soll gut sein." - ] + "extra": ["Müde? Ich hab gehört The Exorcist soll gut sein."] } } }, diff --git a/src/assets/locales/el.json b/src/assets/locales/el.json index 426897fb..00c400ce 100644 --- a/src/assets/locales/el.json +++ b/src/assets/locales/el.json @@ -115,7 +115,10 @@ "failed": "Απέτυχε η εύρεση πολυμέσων, δοκιμάστε ξανά!", "loading": "Φόρτωση...", "noResults": "Δεν μπορέσαμε να βρούμε τίποτα!", - "placeholder": "Τι θέλετε να παρακολουθήσετε;", + "placeholder": { + "default": "Τι θέλετε να παρακολουθήσετε;", + "extra": [] + }, "sectionTitle": "Αποτελέσματα αναζήτησης" }, "titles": { @@ -127,15 +130,11 @@ }, "morning": { "default": "Τι θα θέλατε να παρακολουθήσετε σήμερα το πρωί;", - "extra": [ - "Έχω ακούσει ότι το Before Sunrise είναι καλό" - ] + "extra": ["Έχω ακούσει ότι το Before Sunrise είναι καλό"] }, "night": { "default": "Τι θα θέλατε να παρακολουθήσετε απόψε;", - "extra": [ - "Κούραση; Έχω ακούσει ότι ο Εξορκιστής είναι καλός." - ] + "extra": ["Κούραση; Έχω ακούσει ότι ο Εξορκιστής είναι καλός."] } } }, diff --git a/src/assets/locales/es.json b/src/assets/locales/es.json index 1170f970..bf9bea49 100644 --- a/src/assets/locales/es.json +++ b/src/assets/locales/es.json @@ -116,7 +116,10 @@ "failed": "¡Error al encontrar contenido, inténtalo de nuevo!", "loading": "Cargando...", "noResults": "¡No pudimos encontrar nada!", - "placeholder": "¿Qué te gustaría ver?", + "placeholder": { + "default": "¿Qué te gustaría ver?", + "extra": [] + }, "sectionTitle": "Resultados de búsqueda" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "¿Qué te gustaría ver esta mañana?", - "extra": [ - "Escuché que “Antes del amanecer” es buena" - ] + "extra": ["Escuché que “Antes del amanecer” es buena"] }, "night": { "default": "¿Qué te gustaría ver esta noche?", - "extra": [ - "¿Cansado? Escuché que “El Exorcista” es buena." - ] + "extra": ["¿Cansado? Escuché que “El Exorcista” es buena."] } } }, diff --git a/src/assets/locales/et.json b/src/assets/locales/et.json index 0bf06f29..8819ce15 100644 --- a/src/assets/locales/et.json +++ b/src/assets/locales/et.json @@ -116,7 +116,10 @@ "failed": "Meedia leidmine ebaõnnestus, proovige uuesti!", "loading": "Laadimine....", "noResults": "Me ei leidnud midagi!", - "placeholder": "Mida tahate vaadata?", + "placeholder": { + "default": "Mida tahate vaadata?", + "extra": [] + }, "sectionTitle": "Otsingutulemused" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Mida te soovite täna hommikul vaadata?", - "extra": [ - "Ma kuulsin, et Before Sunrise on hea" - ] + "extra": ["Ma kuulsin, et Before Sunrise on hea"] }, "night": { "default": "Mida te soovite täna õhtul vaadata?", - "extra": [ - "Väsinud? Olen kuulnud, et The Exorcist on hea." - ] + "extra": ["Väsinud? Olen kuulnud, et The Exorcist on hea."] } } }, diff --git a/src/assets/locales/fa.json b/src/assets/locales/fa.json index 0a16d98d..4ffb5da8 100644 --- a/src/assets/locales/fa.json +++ b/src/assets/locales/fa.json @@ -116,7 +116,10 @@ "failed": "چیزی پیدا نشد، دوباره تلاش کنید!", "loading": "در حال بارگذاری...", "noResults": "چیزی پیدا نکردیم!", - "placeholder": "چه می‌خواهید تماشا کنید؟", + "placeholder": { + "default": "چه می‌خواهید تماشا کنید؟", + "extra": [] + }, "sectionTitle": "نتایج جستجو" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "دوست دارید امروز صبح چه چیزی تماشا کنید؟", - "extra": [ - "شنیدم فیلم \"پیش از طلوع\" عالیه" - ] + "extra": ["شنیدم فیلم \"پیش از طلوع\" عالیه"] }, "night": { "default": "دوست دارید امشب چه چیزی تماشا کنید؟", - "extra": [ - "خسته اید؟ شنیده ام که \"جن گیر\" فیلم خوبی است." - ] + "extra": ["خسته اید؟ شنیده ام که \"جن گیر\" فیلم خوبی است."] } } }, diff --git a/src/assets/locales/fi-FI.json b/src/assets/locales/fi-FI.json index 069a3ab3..be38bb71 100644 --- a/src/assets/locales/fi-FI.json +++ b/src/assets/locales/fi-FI.json @@ -116,7 +116,10 @@ "failed": "Mediaa ei löytynyt, yritä uudelleen!", "loading": "Ladataan...", "noResults": "Emme löytäneet mitään!", - "placeholder": "Mitä haluat katsoa?", + "placeholder": { + "default": "Mitä haluat katsoa?", + "extra": [] + }, "sectionTitle": "Hakutulokset" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Mitä haluaisit katsoa tänä aamuna?", - "extra": [ - "Kuulen, että Rakkautta ennen aamua (Before Sunrise) on hyvä" - ] + "extra": ["Kuulen, että Rakkautta ennen aamua (Before Sunrise) on hyvä"] }, "night": { "default": "Mitä haluaisit katsoa tänä iltana?", - "extra": [ - "Väsynyt? Kuulin, että Manaaja (The Exorcist) on hyvä." - ] + "extra": ["Väsynyt? Kuulin, että Manaaja (The Exorcist) on hyvä."] } } }, diff --git a/src/assets/locales/fr.json b/src/assets/locales/fr.json index 59fa2a66..20c51659 100644 --- a/src/assets/locales/fr.json +++ b/src/assets/locales/fr.json @@ -116,7 +116,10 @@ "failed": "Le média n'a pas été trouvé, veuillez réessayez !", "loading": "Chargement...", "noResults": "Nous n'avons rien trouvé !", - "placeholder": "Que voulez-vous voir ?", + "placeholder": { + "default": "Que voulez-vous voir ?", + "extra": [] + }, "sectionTitle": "Résultats de la recherche" }, "titles": { @@ -128,9 +131,7 @@ }, "morning": { "default": "Que voulez-vous regarder ce matin ?", - "extra": [ - "Les films, c'est comme les voyages : ça nous ouvre l'esprit" - ] + "extra": ["Les films, c'est comme les voyages : ça nous ouvre l'esprit"] }, "night": { "default": "Que voulez-vous regarder ce soir ?", diff --git a/src/assets/locales/gl.json b/src/assets/locales/gl.json index b87c7559..854d1261 100644 --- a/src/assets/locales/gl.json +++ b/src/assets/locales/gl.json @@ -116,7 +116,10 @@ "failed": "Error ao encontrar contido... intentao de novo!", "loading": "Cargando...", "noResults": "Non atopamos nada!", - "placeholder": "Que che gustaría ver?", + "placeholder": { + "default": "Que che gustaría ver?", + "extra": [] + }, "sectionTitle": "Resultados da busca" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Que che gustaría ver esta mañá?", - "extra": [ - "Escoitei que “Antes del amanecer” é boa" - ] + "extra": ["Escoitei que “Antes del amanecer” é boa"] }, "night": { "default": "Que che gustaría ver esta noite?", - "extra": [ - "Canso? Escoitei que “El Exorcista” é boa." - ] + "extra": ["Canso? Escoitei que “El Exorcista” é boa."] } } }, diff --git a/src/assets/locales/gu.json b/src/assets/locales/gu.json index 9eb5478d..1ddfcef2 100644 --- a/src/assets/locales/gu.json +++ b/src/assets/locales/gu.json @@ -116,21 +116,20 @@ "failed": "મીડિયા શોધવામાં નિષ્ફળ, ફરી પ્રયાસ કરો!", "loading": "લોડ થાય છે...", "noResults": "અમે કંઈપણ શોધી શક્યા નથી!", - "placeholder": "તમે શું જોવા માંગો છો?", + "placeholder": { + "default": "તમે શું જોવા માંગો છો?", + "extra": [] + }, "sectionTitle": "શોધ પરિણામો" }, "titles": { "day": { "default": "તમે આ બપોરે શું જોવા માંગો છો?", - "extra": [ - "સાહસિક લાગે છે? જુરાસિક પાર્ક યોગ્ય પસંદગી હોઈ શકે છે." - ] + "extra": ["સાહસિક લાગે છે? જુરાસિક પાર્ક યોગ્ય પસંદગી હોઈ શકે છે."] }, "morning": { "default": "તમે આ સવારે શું જોવા માંગો છો?", - "extra": [ - "હું સાંભળું છું કે Before Sunrise સારું છે" - ] + "extra": ["હું સાંભળું છું કે Before Sunrise સારું છે"] }, "night": { "default": "તમે આજે રાત્રે શું જોવા માંગો છો?", diff --git a/src/assets/locales/he.json b/src/assets/locales/he.json index aad7cae4..468558c5 100644 --- a/src/assets/locales/he.json +++ b/src/assets/locales/he.json @@ -116,27 +116,24 @@ "failed": "לא הצלחנו למצוא מדיה, נסה שוב!", "loading": "טוען...", "noResults": "לא יכולנו למצוא כלום!", - "placeholder": "במה תרצה לצפות?", + "placeholder": { + "default": "במה תרצה לצפות?", + "extra": [] + }, "sectionTitle": "תוצאות חיפוש" }, "titles": { "day": { "default": "במה תרצה לצפות באחר צהריים זה?", - "extra": [ - "מרגיש הרפתקני? פארק היורה עשוי להיות הבחירה המושלמת." - ] + "extra": ["מרגיש הרפתקני? פארק היורה עשוי להיות הבחירה המושלמת."] }, "morning": { "default": "במה תרצה לצפות הבוקר?", - "extra": [ - "שמעתי שלפני הזריחה זה סרט טוב" - ] + "extra": ["שמעתי שלפני הזריחה זה סרט טוב"] }, "night": { "default": "במה תרצה לצפות הלילה?", - "extra": [ - "רוצה לישון? הפיג'מות היא בחירה מצויינת." - ] + "extra": ["רוצה לישון? הפיג'מות היא בחירה מצויינת."] } } }, diff --git a/src/assets/locales/hi.json b/src/assets/locales/hi.json index 671f5bac..7f1dfe00 100644 --- a/src/assets/locales/hi.json +++ b/src/assets/locales/hi.json @@ -116,7 +116,10 @@ "failed": "मीडिया ढूंढने में विफल, पुनः प्रयास करें!", "loading": "लोड हो रहा है..।", "noResults": "हमें कुछ नहीं मिला!", - "placeholder": "क्या देखना चाहते हो?", + "placeholder": { + "default": "क्या देखना चाहते हो?", + "extra": [] + }, "sectionTitle": "खोज के परिणाम" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "आप आज सुबह को क्या देखना चाहेंगे?", - "extra": [ - "मैंने सुना है सूर्योदय से पहले ठीक है" - ] + "extra": ["मैंने सुना है सूर्योदय से पहले ठीक है"] }, "night": { "default": "आप आज रात को क्या देखना चाहेंगे?", - "extra": [ - "थके हुए हो? मैंने सुना एक्सोरसिस्ट अच्छी मूवी है।" - ] + "extra": ["थके हुए हो? मैंने सुना एक्सोरसिस्ट अच्छी मूवी है।"] } } }, diff --git a/src/assets/locales/id.json b/src/assets/locales/id.json index 15a91bfe..de2153ca 100644 --- a/src/assets/locales/id.json +++ b/src/assets/locales/id.json @@ -115,7 +115,10 @@ "failed": "Gagal menemukan media, coba lagi!", "loading": "Memuat...", "noResults": "Kami tidak dapat menemukan apapun!", - "placeholder": "Apa yang ingin anda tonton?", + "placeholder": { + "default": "Apa yang ingin anda tonton?", + "extra": [] + }, "sectionTitle": "Hasil pencarian" }, "titles": { @@ -127,15 +130,11 @@ }, "morning": { "default": "Apa yang ingin anda tonton pagi ini?", - "extra": [ - "Kayaknya film Before Sunrise bagus deh" - ] + "extra": ["Kayaknya film Before Sunrise bagus deh"] }, "night": { "default": "Apa yang ingin anda tonton malam ini?", - "extra": [ - "Capek? Katanya The Exocist rekomended." - ] + "extra": ["Capek? Katanya The Exocist rekomended."] } } }, diff --git a/src/assets/locales/is-IS.json b/src/assets/locales/is-IS.json index 1b4906a4..d76ad65f 100644 --- a/src/assets/locales/is-IS.json +++ b/src/assets/locales/is-IS.json @@ -108,7 +108,10 @@ "failed": "Mostókst að finna miðil, reyndu aftur!", "loading": "Hlaðið...", "noResults": "Við gátum ekki fundið neitt!", - "placeholder": "Hvað viltu horfa á?", + "placeholder": { + "default": "Hvað viltu horfa á?", + "extra": [] + }, "sectionTitle": "Leitar niðurstöður" }, "titles": { @@ -120,15 +123,11 @@ }, "morning": { "default": "Hvað myndirðu vilja horfa á þessum morgni?", - "extra": [ - "Ég heyrði að Before Sunrise sé góð" - ] + "extra": ["Ég heyrði að Before Sunrise sé góð"] }, "night": { "default": "Hvað myndirðu vilja horfa á í nótt?", - "extra": [ - "Þreytt? Ég heyrði að The Exorcist sé góð." - ] + "extra": ["Þreytt? Ég heyrði að The Exorcist sé góð."] } } }, diff --git a/src/assets/locales/it.json b/src/assets/locales/it.json index 8e6cdd35..966afac4 100644 --- a/src/assets/locales/it.json +++ b/src/assets/locales/it.json @@ -116,7 +116,10 @@ "failed": "Impossibile trovare i media, riprova!", "loading": "Caricamento...", "noResults": "Non abbiamo trovato nulla!", - "placeholder": "Cosa vuoi guardare?", + "placeholder": { + "default": "Cosa vuoi guardare?", + "extra": [] + }, "sectionTitle": "Risultati della ricerca" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Cosa vorresti guardare questa mattina?", - "extra": [ - "Ho sentito che «Prima Dell'alba» è buono" - ] + "extra": ["Ho sentito che «Prima Dell'alba» è buono"] }, "night": { "default": "Cosa vorresti guardare questa sera?", - "extra": [ - "Stanco? Ho sentito che L'esorciccio è buono." - ] + "extra": ["Stanco? Ho sentito che L'esorciccio è buono."] } } }, diff --git a/src/assets/locales/ja.json b/src/assets/locales/ja.json index fb202dc7..3d45db90 100644 --- a/src/assets/locales/ja.json +++ b/src/assets/locales/ja.json @@ -76,7 +76,10 @@ "allResults": "それがすべてです!", "loading": "読み込み中...", "noResults": "見つかりませんでした!", - "placeholder": "どんな映画を見たい?", + "placeholder": { + "default": "どんな映画を見たい?", + "extra": [] + }, "sectionTitle": "検索結果" }, "titles": { diff --git a/src/assets/locales/ko.json b/src/assets/locales/ko.json index 9866d3c5..f4b48fb1 100644 --- a/src/assets/locales/ko.json +++ b/src/assets/locales/ko.json @@ -116,7 +116,10 @@ "failed": "미디어 검색에 실패하였습니다, 다시 시도해주세요!", "loading": "로딩...", "noResults": "검색결과가 없습니다!", - "placeholder": "무엇을 보고 싶으신가요?", + "placeholder": { + "default": "무엇을 보고 싶으신가요?", + "extra": [] + }, "sectionTitle": "검색 결과" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "오늘 아침에 무엇을 보고 싶으신가요?", - "extra": [ - "Before Sunrise가 좋다고 들었어요" - ] + "extra": ["Before Sunrise가 좋다고 들었어요"] }, "night": { "default": "오늘 밤에 무엇을 보고 싶으신가요?", - "extra": [ - "피곤하신가요? The Exorcist가 좋다고 들었어요." - ] + "extra": ["피곤하신가요? The Exorcist가 좋다고 들었어요."] } } }, diff --git a/src/assets/locales/lv.json b/src/assets/locales/lv.json index 0d5b3c99..e2f7088a 100644 --- a/src/assets/locales/lv.json +++ b/src/assets/locales/lv.json @@ -114,7 +114,10 @@ "failed": "Neizdevās atrast multividi. Mēģiniet vēlreiz!", "loading": "Lādejas...", "noResults": "Mēs nevarējām neko atrast!", - "placeholder": "Ko tu gribi skatīties?", + "placeholder": { + "default": "Ko tu gribi skatīties?", + "extra": [] + }, "sectionTitle": "Meklējuma rezultāti" }, "titles": { @@ -123,15 +126,11 @@ }, "morning": { "default": "Ko tu gribētu šorīt noskatīties?", - "extra": [ - "Es dzirdu, ka Pirms saullēkta ir labs" - ] + "extra": ["Es dzirdu, ka Pirms saullēkta ir labs"] }, "night": { "default": "Ko tu gribētu šovakar skatīties?", - "extra": [ - "Noguris? Es dzirdu, ka Exorcist ir labs." - ] + "extra": ["Noguris? Es dzirdu, ka Exorcist ir labs."] } } }, diff --git a/src/assets/locales/minion.json b/src/assets/locales/minion.json index 22ca5c95..ed620f8a 100644 --- a/src/assets/locales/minion.json +++ b/src/assets/locales/minion.json @@ -115,7 +115,10 @@ "failed": "Failed to banana banana, try again!", "loading": "Loading...", "noResults": "We couldn't banana anything!", - "placeholder": "Banana do you want to banana?", + "placeholder": { + "default": "Banana do you want to banana?", + "extra": [] + }, "sectionTitle": "Banana results" }, "titles": { @@ -127,15 +130,11 @@ }, "morning": { "default": "What would you like to banana this banana?", - "extra": [ - "Banana! I hear Banana Sunrise is banana" - ] + "extra": ["Banana! I hear Banana Sunrise is banana"] }, "night": { "default": "What would you like to banana banana?", - "extra": [ - "Banana? I hear The Banana is banana." - ] + "extra": ["Banana? I hear The Banana is banana."] } } }, diff --git a/src/assets/locales/ne.json b/src/assets/locales/ne.json index a2954d9a..4b342f61 100644 --- a/src/assets/locales/ne.json +++ b/src/assets/locales/ne.json @@ -115,7 +115,10 @@ "failed": "मिडिया फेला पार्न असफल भयो, फेरि प्रयास गर्नुहोस्!", "loading": "लोड गर्दै...", "noResults": "हामीले केहि फेला पार्न सकेनौं!", - "placeholder": "तपाईं के हेर्न चाहनुहुन्छ?", + "placeholder": { + "default": "तपाईं के हेर्न चाहनुहुन्छ?", + "extra": [] + }, "sectionTitle": "खोज परिणामहरू" }, "titles": { @@ -127,15 +130,11 @@ }, "morning": { "default": "तपाई आज बिहान के हेर्न चाहनुहुन्छ?", - "extra": [ - "Before Sunrise राम्रो छ भन्ने सुन्छु" - ] + "extra": ["Before Sunrise राम्रो छ भन्ने सुन्छु"] }, "night": { "default": "तपाईं आज राती के हेर्न चाहनुहुन्छ?", - "extra": [ - "थकित? मैले सुनेको छु The Exorcist राम्रो छ।" - ] + "extra": ["थकित? मैले सुनेको छु The Exorcist राम्रो छ।"] } } }, diff --git a/src/assets/locales/nl.json b/src/assets/locales/nl.json index 20ef4503..5b1f2750 100644 --- a/src/assets/locales/nl.json +++ b/src/assets/locales/nl.json @@ -116,7 +116,10 @@ "failed": "Het is niet gelukt de media te laden, probeer het nog eens!", "loading": "Aan het zoeken...", "noResults": "We konden helaas niets vinden!", - "placeholder": "Wat wil je graag kijken?", + "placeholder": { + "default": "Wat wil je graag kijken?", + "extra": [] + }, "sectionTitle": "Zoekresultaten" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Waar wil je deze ochtend naar kijken?", - "extra": [ - "Ik hoor dat Before Sunrise goed is" - ] + "extra": ["Ik hoor dat Before Sunrise goed is"] }, "night": { "default": "Wat wil je vanavond bekijken?", - "extra": [ - "Moe? Ik hoor dat The Exorcist goed is." - ] + "extra": ["Moe? Ik hoor dat The Exorcist goed is."] } } }, diff --git a/src/assets/locales/pa.json b/src/assets/locales/pa.json index 978dce15..ebc8887d 100644 --- a/src/assets/locales/pa.json +++ b/src/assets/locales/pa.json @@ -116,7 +116,10 @@ "failed": "ਮੀਡੀਆ ਲੱਭਣ ਵਿੱਚ ਅਸਫਲ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ!", "loading": "ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...", "noResults": "ਅਸੀਂ ਕੁਝ ਵੀ ਨਹੀਂ ਲੱਭ ਸਕੇ!", - "placeholder": "ਤੁਸੀਂ ਕੀ ਦੇਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?", + "placeholder": { + "default": "ਤੁਸੀਂ ਕੀ ਦੇਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?", + "extra": [] + }, "sectionTitle": "ਖੋਜ ਨਤੀਜੇ" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "ਤੁਸੀਂ ਅੱਜ ਸਵੇਰੇ ਕੀ ਦੇਖਣਾ ਚਾਹੋਗੇ?", - "extra": [ - "ਮੈਂ ਸੁਣਦਾ ਹਾਂ ਕਿ ਸੂਰਜ ਚੜ੍ਹਨ ਤੋਂ ਪਹਿਲਾਂ ਚੰਗਾ ਹੁੰਦਾ ਹੈ" - ] + "extra": ["ਮੈਂ ਸੁਣਦਾ ਹਾਂ ਕਿ ਸੂਰਜ ਚੜ੍ਹਨ ਤੋਂ ਪਹਿਲਾਂ ਚੰਗਾ ਹੁੰਦਾ ਹੈ"] }, "night": { "default": "ਤੁਸੀਂ ਅੱਜ ਰਾਤ ਕੀ ਦੇਖਣਾ ਚਾਹੋਗੇ?", - "extra": [ - "ਥੱਕ ਗਏ? ਮੈਂ ਸੁਣਿਆ ਹੈ ਕਿ Exorcist ਚੰਗਾ ਹੈ." - ] + "extra": ["ਥੱਕ ਗਏ? ਮੈਂ ਸੁਣਿਆ ਹੈ ਕਿ Exorcist ਚੰਗਾ ਹੈ."] } } }, diff --git a/src/assets/locales/pirate.json b/src/assets/locales/pirate.json index ac6d1c74..05f384a8 100644 --- a/src/assets/locales/pirate.json +++ b/src/assets/locales/pirate.json @@ -116,7 +116,10 @@ "failed": "Arrrr failed to find media, try again!", "loading": "Hold yer horses, me heartie!", "noResults": "We couldn't find anythin', arrr!", - "placeholder": "What do ye want to watch?", + "placeholder": { + "default": "What do ye want to watch?", + "extra": [] + }, "sectionTitle": "Searchin' results" }, "titles": { diff --git a/src/assets/locales/pl.json b/src/assets/locales/pl.json index b84e17e7..a653e4f9 100644 --- a/src/assets/locales/pl.json +++ b/src/assets/locales/pl.json @@ -116,7 +116,10 @@ "failed": "Nie udało się znaleźć mediów, Spróbuj ponownie!", "loading": "Wczytywanie...", "noResults": "Nie mogliśmy niczego znaleźć!", - "placeholder": "Co chciałbyś obejrzeć?", + "placeholder": { + "default": "Co chciałbyś obejrzeć?", + "extra": [] + }, "sectionTitle": "Wyniki wyszukiwania" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Co chciałbyś obejrzeć dziś rano?", - "extra": [ - "Słyszałem że „Przed wschodem słońca” jest dobre" - ] + "extra": ["Słyszałem że „Przed wschodem słońca” jest dobre"] }, "night": { "default": "Co chciałbyś obejrzeć dziś wieczorem?", - "extra": [ - "Zmęczony? Słyszałem że „Egzorcysta” jest dobry." - ] + "extra": ["Zmęczony? Słyszałem że „Egzorcysta” jest dobry."] } } }, diff --git a/src/assets/locales/pt-BR.json b/src/assets/locales/pt-BR.json index d846c829..a732d231 100644 --- a/src/assets/locales/pt-BR.json +++ b/src/assets/locales/pt-BR.json @@ -116,7 +116,10 @@ "failed": "Falha ao encontrar mídia, tente novamente!", "loading": "Carregando...", "noResults": "Não conseguimos encontrar nada!", - "placeholder": "O que você quer assistir?", + "placeholder": { + "default": "O que você quer assistir?", + "extra": [] + }, "sectionTitle": "Resultados da pesquisa" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "O que você gostaria de assistir esta manhã?", - "extra": [ - "Ouvi dizer que Antes do Amanhecer é bom" - ] + "extra": ["Ouvi dizer que Antes do Amanhecer é bom"] }, "night": { "default": "O que você gostaria de assistir esta noite?", - "extra": [ - "Cansado? Ouvi dizer que O Exorcista é bom." - ] + "extra": ["Cansado? Ouvi dizer que O Exorcista é bom."] } } }, diff --git a/src/assets/locales/pt-PT.json b/src/assets/locales/pt-PT.json index 612415d6..22dd4234 100644 --- a/src/assets/locales/pt-PT.json +++ b/src/assets/locales/pt-PT.json @@ -115,7 +115,10 @@ "failed": "Falha ao encontrar mídia, tente novamente!", "loading": "A carregar...", "noResults": "Não conseguimos encontrar nada!", - "placeholder": "O que deseja assistir?", + "placeholder": { + "default": "O que deseja assistir?", + "extra": [] + }, "sectionTitle": "Resultados da pesquisa" }, "titles": { @@ -127,15 +130,11 @@ }, "morning": { "default": "O que gostaria de assistir esta manhã?", - "extra": [ - "Dizem que Antes do Amanhecer é bom" - ] + "extra": ["Dizem que Antes do Amanhecer é bom"] }, "night": { "default": "O que gostaria de assistir esta noite?", - "extra": [ - "Cansado? Dizem que O Exorcista é bom." - ] + "extra": ["Cansado? Dizem que O Exorcista é bom."] } } }, diff --git a/src/assets/locales/ro.json b/src/assets/locales/ro.json index 04849ce6..9a0ba2d9 100644 --- a/src/assets/locales/ro.json +++ b/src/assets/locales/ro.json @@ -114,7 +114,10 @@ "failed": "Găsire media eșuată, încearcă din nou!", "loading": "Se încarcă...", "noResults": "Nu am putut găsi nimic!", - "placeholder": "La ce dorești să te uiți?", + "placeholder": { + "default": "La ce dorești să te uiți?", + "extra": [] + }, "sectionTitle": "Rezultate de căutare" }, "titles": { @@ -126,15 +129,11 @@ }, "morning": { "default": "La ce dorești să te in uiți dimineață aceasta?", - "extra": [ - "Aud că Before Sunrise este bun" - ] + "extra": ["Aud că Before Sunrise este bun"] }, "night": { "default": "La ce dorești să te uiți în astă seară?", - "extra": [ - "Obosit? Aud că The Exorcist is good." - ] + "extra": ["Obosit? Aud că The Exorcist is good."] } } }, diff --git a/src/assets/locales/ru.json b/src/assets/locales/ru.json index bac2ae8d..668ab561 100644 --- a/src/assets/locales/ru.json +++ b/src/assets/locales/ru.json @@ -116,7 +116,10 @@ "failed": "Не удалось найти медиафайл, попробуйте снова!", "loading": "Загрузка...", "noResults": "Мы ничего не нашли!", - "placeholder": "Что вы хотите посмотреть?", + "placeholder": { + "default": "Что вы хотите посмотреть?", + "extra": [] + }, "sectionTitle": "Результаты поиска" }, "titles": { @@ -128,9 +131,7 @@ }, "morning": { "default": "Что бы вы хотели посмотреть этим утром?", - "extra": [ - "Слышали, что «Перед рассветом» – отличный фильм" - ] + "extra": ["Слышали, что «Перед рассветом» – отличный фильм"] }, "night": { "default": "Что бы вы хотели посмотреть этим вечером?", diff --git a/src/assets/locales/sl.json b/src/assets/locales/sl.json index ef51e2b7..ee374b4a 100644 --- a/src/assets/locales/sl.json +++ b/src/assets/locales/sl.json @@ -115,7 +115,10 @@ "failed": "Ni uspelo najti medija, prosim poskusite znova!", "loading": "Nalaganje...", "noResults": "Vsebin nismo našli!", - "placeholder": "Kaj si želite gledati?", + "placeholder": { + "default": "Kaj si želite gledati?", + "extra": [] + }, "sectionTitle": "Rezultati iskanja" }, "titles": { @@ -127,9 +130,7 @@ }, "morning": { "default": "Kateri film ali serijo bi si želeli ogledati ob tem jutru?", - "extra": [ - "Slišala sem, da je film \"Pred sončnim vzhodom\" odličen" - ] + "extra": ["Slišala sem, da je film \"Pred sončnim vzhodom\" odličen"] }, "night": { "default": "Kateri film ali serijo bi si želeli ogledati nocoj?", diff --git a/src/assets/locales/sv.json b/src/assets/locales/sv.json index 94263b93..ac35a4bf 100644 --- a/src/assets/locales/sv.json +++ b/src/assets/locales/sv.json @@ -114,7 +114,10 @@ "failed": "Misslyckades med att hitta media, försök igen!", "loading": "Laddar...", "noResults": "Vi kunde inte hitta någonting!", - "placeholder": "Vad vill du titta på?", + "placeholder": { + "default": "Vad vill du titta på?", + "extra": [] + }, "sectionTitle": "Sökresultat" }, "titles": { @@ -123,15 +126,11 @@ }, "morning": { "default": "Vad vill du titta på den här morgonen?", - "extra": [ - "Jag hör att Before Sunrise är bra" - ] + "extra": ["Jag hör att Before Sunrise är bra"] }, "night": { "default": "Vad vill du titta på ikväll?", - "extra": [ - "Trött? Jag hör att The Exorcist är bra." - ] + "extra": ["Trött? Jag hör att The Exorcist är bra."] } } }, diff --git a/src/assets/locales/th.json b/src/assets/locales/th.json index 2ff9cac9..2e130daa 100644 --- a/src/assets/locales/th.json +++ b/src/assets/locales/th.json @@ -115,7 +115,10 @@ "failed": "ไม่พบสื่อนี้ ลองอีกครั้ง!", "loading": "กำลังโหลด..", "noResults": "เราไม่พบอะไรเลย!", - "placeholder": "คุณอยากดูอะไรคะ?", + "placeholder": { + "default": "คุณอยากดูอะไรคะ?", + "extra": [] + }, "sectionTitle": "ผลการค้นหา" }, "titles": { @@ -124,15 +127,11 @@ }, "morning": { "default": "คุณอยากดูอะไรเช้านี้?", - "extra": [ - "ฉันได้ยินมาว่าเรื่อง Before Sunrise สนุก" - ] + "extra": ["ฉันได้ยินมาว่าเรื่อง Before Sunrise สนุก"] }, "night": { "default": "คุณอยากดูเรื่องอะไรในช่วงค่ำ?", - "extra": [ - "เหนื่อยมั้ย? ฉันได้ยินมาว่า The Exorcist นั้นดี" - ] + "extra": ["เหนื่อยมั้ย? ฉันได้ยินมาว่า The Exorcist นั้นดี"] } } }, diff --git a/src/assets/locales/tok.json b/src/assets/locales/tok.json index 189b3ff0..7856144e 100644 --- a/src/assets/locales/tok.json +++ b/src/assets/locales/tok.json @@ -115,27 +115,24 @@ "failed": "lukin li pakala a! o alasa sin", "loading": "alasa...", "noResults": "ijo li lon ala a!", - "placeholder": "sina wile lukin e seme?", + "placeholder": { + "default": "sina wile lukin e seme?", + "extra": [] + }, "sectionTitle": "mi lukin e ni:" }, "titles": { "day": { "default": "tenpo suno ni la sina wile lukin e seme?", - "extra": [ - "sina pilin alasa la o lukin e sitelen Jurassic Park" - ] + "extra": ["sina pilin alasa la o lukin e sitelen Jurassic Park"] }, "morning": { "default": "tenpo sin ni la sina wile lukin e seme?", - "extra": [ - "ken la sitelen Before Sunrise li pona" - ] + "extra": ["ken la sitelen Before Sunrise li pona"] }, "night": { "default": "tenpo pimeja ni la sina wile lukin e seme?", - "extra": [ - "sina pilin lape anu seme? o alasa lukin e sitelen Exorcist" - ] + "extra": ["sina pilin lape anu seme? o alasa lukin e sitelen Exorcist"] } } }, diff --git a/src/assets/locales/tr.json b/src/assets/locales/tr.json index f26aa6a0..5d8a24b3 100644 --- a/src/assets/locales/tr.json +++ b/src/assets/locales/tr.json @@ -116,7 +116,10 @@ "failed": "Medya bulunamadı, tekrar deneyin!", "loading": "Yükleniyor...", "noResults": "Hiçbir şey bulamadık!", - "placeholder": "Ne izlemek istersiniz?", + "placeholder": { + "default": "Ne izlemek istersiniz?", + "extra": [] + }, "sectionTitle": "Arama sonuçları" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Bu sabah ne izlemek istersiniz?", - "extra": [ - "Before Sunrise'a iyi diyorlar" - ] + "extra": ["Before Sunrise'a iyi diyorlar"] }, "night": { "default": "Bu akşam ne izlemek istersiniz?", - "extra": [ - "Yoruldun mu? The Exorcist'e iyi diyorlar." - ] + "extra": ["Yoruldun mu? The Exorcist'e iyi diyorlar."] } } }, diff --git a/src/assets/locales/uk.json b/src/assets/locales/uk.json index e6142426..5b568aa6 100644 --- a/src/assets/locales/uk.json +++ b/src/assets/locales/uk.json @@ -116,7 +116,10 @@ "failed": "Не вдалося знайти медіафайли, повторіть спробу!", "loading": "Завантаження...", "noResults": "Ми не змогли знайти нічого!", - "placeholder": "Що ви хочете подивитися?", + "placeholder": { + "default": "Що ви хочете подивитися?", + "extra": [] + }, "sectionTitle": "Результати пошуку" }, "titles": { @@ -128,15 +131,11 @@ }, "morning": { "default": "Що б ви хотіли подивитися сьогодні вранці?", - "extra": [ - "Я чув, що \"Перед сходом сонця\" гарний" - ] + "extra": ["Я чув, що \"Перед сходом сонця\" гарний"] }, "night": { "default": "Що б ви хотіли подивитися сьогодні ввечері?", - "extra": [ - "Втомився? Я чув, що \"Екзорцист\" хороший." - ] + "extra": ["Втомився? Я чув, що \"Екзорцист\" хороший."] } } }, diff --git a/src/assets/locales/vi.json b/src/assets/locales/vi.json index ab553b01..12bca47f 100644 --- a/src/assets/locales/vi.json +++ b/src/assets/locales/vi.json @@ -116,7 +116,10 @@ "failed": "Không thể tìm thấy nội dung, hãy thử lại!", "loading": "Đang tải...", "noResults": "Chúng tôi không thể tìm thấy gì!", - "placeholder": "Bạn muốn xem gì?", + "placeholder": { + "default": "Bạn muốn xem gì?", + "extra": [] + }, "sectionTitle": "Kết quả tìm kiếm" }, "titles": { diff --git a/src/assets/locales/zh-Hant.json b/src/assets/locales/zh-Hant.json index a273328f..1d140961 100644 --- a/src/assets/locales/zh-Hant.json +++ b/src/assets/locales/zh-Hant.json @@ -116,27 +116,24 @@ "failed": "未能找到媒體,請重試!", "loading": "載入中...", "noResults": "我们找不到任何结果!", - "placeholder": "您想看什麼?", + "placeholder": { + "default": "您想看什麼?", + "extra": [] + }, "sectionTitle": "搜索結果" }, "titles": { "day": { "default": "您今天下午想看什麼?", - "extra": [ - "想要來場冒險嗎?《侏羅紀公園》可能是完美選擇。" - ] + "extra": ["想要來場冒險嗎?《侏羅紀公園》可能是完美選擇。"] }, "morning": { "default": "您今天早上想看什麼?", - "extra": [ - "我聽說《情留半天》不錯" - ] + "extra": ["我聽說《情留半天》不錯"] }, "night": { "default": "您今晚想看什麼?", - "extra": [ - "疲倦了嗎?我聽說《驅魔人》不錯。" - ] + "extra": ["疲倦了嗎?我聽說《驅魔人》不錯。"] } } }, diff --git a/src/assets/locales/zh.json b/src/assets/locales/zh.json index b2b13da6..81717569 100644 --- a/src/assets/locales/zh.json +++ b/src/assets/locales/zh.json @@ -116,27 +116,24 @@ "failed": "查找媒体失败,请重试!", "loading": "载入中……", "noResults": "我们找不到任何结果!", - "placeholder": "您想看些什么?", + "placeholder": { + "default": "您想看些什么?", + "extra": [] + }, "sectionTitle": "搜索结果" }, "titles": { "day": { "default": "您今天下午想看什么?", - "extra": [ - "想要来场冒险?《侏罗纪公园》可能是最佳选项。" - ] + "extra": ["想要来场冒险?《侏罗纪公园》可能是最佳选项。"] }, "morning": { "default": "您今早想看什么?", - "extra": [ - "我听说《爱在黎明破晓前》不错" - ] + "extra": ["我听说《爱在黎明破晓前》不错"] }, "night": { "default": "您今晚想看什么?", - "extra": [ - "累了?我听说《驱魔人》不错。" - ] + "extra": ["累了?我听说《驱魔人》不错。"] } } }, From 60d5c5d05cc53a7856be289f9f38bfde2f1b786a Mon Sep 17 00:00:00 2001 From: Vijay <74645268+vijaysingh2219@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:29:44 +0530 Subject: [PATCH 06/22] Updated the extra search placeholder options - Reduced the number of options for search placeholder --- src/assets/locales/en.json | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index bdb95c01..c6a43875 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -119,21 +119,10 @@ "placeholder": { "default": "What do you want to watch?", "extra": [ - "What's on your movie radar today?", - "What's your cinematic preference today?", - "What kind of entertainment are you seeking?", - "What's your ideal movie or series right now?", - "What do you want to explore in the film world?", - "What's on your watchlist for today?", - "What movie or series piques your interest?", - "What's your desired film experience at the moment?", - "What are you in the mood to watch?", - "Looking for a classic or something new?", - "Any specific mood you're in for your watch?", - "In the mood for a thrilling adventure or a cozy drama?", - "Searching for your favorite entertainment?", - "Interested in recent releases or timeless classics?", - "Prefer a short movie night or a binge-watching session?" + "What do you want to explore?", + "What's on your watchlist?", + "What's your favorite movie?", + "What's your favorite series?" ] }, "sectionTitle": "Search results" From 446be5847831320be4182e49520bbb14379ac218 Mon Sep 17 00:00:00 2001 From: Vijay <74645268+vijaysingh2219@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:18:36 +0530 Subject: [PATCH 07/22] Fix ESLint warning in HeroPart.tsx --- src/pages/parts/home/HeroPart.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/parts/home/HeroPart.tsx b/src/pages/parts/home/HeroPart.tsx index bf39c099..9fdea893 100644 --- a/src/pages/parts/home/HeroPart.tsx +++ b/src/pages/parts/home/HeroPart.tsx @@ -1,5 +1,4 @@ import { useCallback, useEffect, useRef, useState } from "react"; -import { useTranslation } from "react-i18next"; import Sticky from "react-sticky-el"; import { useWindowSize } from "react-use"; @@ -26,7 +25,6 @@ function getTimeOfDay(date: Date): "night" | "morning" | "day" { export function HeroPart({ setIsSticky, searchParams }: HeroPartProps) { const { t: randomT } = useRandomTranslation(); - const { t } = useTranslation(); const [search, setSearch, setSearchUnFocus] = searchParams; const [, setShowBg] = useState(false); const bannerSize = useBannerSize(); From 98d06a6051a7b21c5adfb13623d80c40584db50c Mon Sep 17 00:00:00 2001 From: William Oldham Date: Wed, 21 Feb 2024 17:54:01 +0000 Subject: [PATCH 08/22] Fix #927 and add build arg for Docker PWA --- Dockerfile | 4 ++++ package.json | 3 ++- pnpm-lock.yaml | 53 ++++++++++++++++++++++++++------------------------ 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Dockerfile b/Dockerfile index cc9b84be..5923db79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,10 @@ COPY package.json ./ COPY pnpm-lock.yaml ./ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +ARG PWA_ENABLED="false" + +ENV VITE_PWA_ENABLED=${PWA_ENABLED} + COPY . ./ RUN pnpm run build diff --git a/package.json b/package.json index b4cac548..810a689b 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,8 @@ "vite-plugin-package-version": "^1.1.0", "vite-plugin-pwa": "^0.17.4", "vite-plugin-static-copy": "^1.0.0", - "vitest": "^1.1.0" + "vitest": "^1.1.0", + "workbox-window": "^7.0.0" }, "pnpm": { "overrides": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd97c001..2ded1fb4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -268,7 +268,7 @@ devDependencies: version: 0.5.9(prettier@3.1.1) rollup-plugin-visualizer: specifier: ^5.11.0 - version: 5.11.0(@rollup/wasm-node@4.10.0) + version: 5.11.0(@rollup/wasm-node@4.12.0) tailwind-scrollbar: specifier: ^3.0.5 version: 3.0.5(tailwindcss@3.4.0) @@ -302,6 +302,9 @@ devDependencies: vitest: specifier: ^1.1.0 version: 1.1.0(@types/node@20.10.5)(jsdom@23.0.1) + workbox-window: + specifier: ^7.0.0 + version: 7.0.0 packages: @@ -2059,7 +2062,7 @@ packages: engines: {node: '>=14.0.0'} dev: false - /@rollup/plugin-babel@5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.10.0): + /@rollup/plugin-babel@5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.12.0): resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} peerDependencies: @@ -2072,36 +2075,36 @@ packages: dependencies: '@babel/core': 7.23.6 '@babel/helper-module-imports': 7.22.15 - '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.10.0) - rollup: /@rollup/wasm-node@4.10.0 + '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.0) + rollup: /@rollup/wasm-node@4.12.0 dev: true - /@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.10.0): + /@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.12.0): resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} engines: {node: '>= 10.0.0'} peerDependencies: rollup: npm:@rollup/wasm-node dependencies: - '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.10.0) + '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.0) '@types/resolve': 1.17.1 builtin-modules: 3.3.0 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.4 - rollup: /@rollup/wasm-node@4.10.0 + rollup: /@rollup/wasm-node@4.12.0 dev: true - /@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.10.0): + /@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.12.0): resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} peerDependencies: rollup: npm:@rollup/wasm-node dependencies: - '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.10.0) + '@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.12.0) magic-string: 0.25.9 - rollup: /@rollup/wasm-node@4.10.0 + rollup: /@rollup/wasm-node@4.12.0 dev: true - /@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.10.0): + /@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.12.0): resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} peerDependencies: @@ -2110,11 +2113,11 @@ packages: '@types/estree': 0.0.39 estree-walker: 1.0.1 picomatch: 2.3.1 - rollup: /@rollup/wasm-node@4.10.0 + rollup: /@rollup/wasm-node@4.12.0 dev: true - /@rollup/wasm-node@4.10.0: - resolution: {integrity: sha512-wH/ih4T/iP2PUyTrkyioZqDoFY/gmu63LPLTOM5Q21gSB/D3Ejw3UBpUOMLt86fIbN3mV+wL45MyA71XAj1ytg==} + /@rollup/wasm-node@4.12.0: + resolution: {integrity: sha512-sqy3+YvV/uWX6bPZOR5PlEdH6xyMPXoelllRQ/uZ13tzy9f4pXZTbajnoWN8IHHXwTNKPiLzsePLiDEVmkxMNw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true dependencies: @@ -5098,7 +5101,7 @@ packages: '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.6) '@babel/types': 7.23.6 kleur: 4.1.5 - rollup: /@rollup/wasm-node@4.10.0 + rollup: /@rollup/wasm-node@4.12.0 unplugin: 1.5.1 transitivePeerDependencies: - supports-color @@ -6026,7 +6029,7 @@ packages: glob: 7.2.3 dev: true - /rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.10.0): + /rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.12.0): resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser peerDependencies: @@ -6034,12 +6037,12 @@ packages: dependencies: '@babel/code-frame': 7.23.5 jest-worker: 26.6.2 - rollup: /@rollup/wasm-node@4.10.0 + rollup: /@rollup/wasm-node@4.12.0 serialize-javascript: 4.0.0 terser: 5.19.3 dev: true - /rollup-plugin-visualizer@5.11.0(@rollup/wasm-node@4.10.0): + /rollup-plugin-visualizer@5.11.0(@rollup/wasm-node@4.12.0): resolution: {integrity: sha512-exM0Ms2SN3AgTzMeW7y46neZQcyLY7eKwWAop1ZoRTCZwyrIRdMMJ6JjToAJbML77X/9N8ZEpmXG4Z/Clb9k8g==} engines: {node: '>=14'} hasBin: true @@ -6051,7 +6054,7 @@ packages: dependencies: open: 8.4.2 picomatch: 2.3.1 - rollup: /@rollup/wasm-node@4.10.0 + rollup: /@rollup/wasm-node@4.12.0 source-map: 0.7.4 yargs: 17.7.2 dev: true @@ -7037,7 +7040,7 @@ packages: '@types/node': 20.10.5 esbuild: 0.19.10 postcss: 8.4.32 - rollup: /@rollup/wasm-node@4.10.0 + rollup: /@rollup/wasm-node@4.12.0 optionalDependencies: fsevents: 2.3.3 dev: true @@ -7299,9 +7302,9 @@ packages: '@babel/core': 7.23.6 '@babel/preset-env': 7.23.6(@babel/core@7.23.6) '@babel/runtime': 7.23.6 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.10.0) - '@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.10.0) - '@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.10.0) + '@rollup/plugin-babel': 5.3.1(@babel/core@7.23.6)(@rollup/wasm-node@4.12.0) + '@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.12.0) + '@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.12.0) '@surma/rollup-plugin-off-main-thread': 2.2.3 ajv: 8.12.0 common-tags: 1.8.2 @@ -7310,8 +7313,8 @@ packages: glob: 7.2.3 lodash: 4.17.21 pretty-bytes: 5.6.0 - rollup: /@rollup/wasm-node@4.10.0 - rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.10.0) + rollup: /@rollup/wasm-node@4.12.0 + rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.12.0) source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 From ac9d347a26fc4df55dbb04ddf6d6d5ec89889543 Mon Sep 17 00:00:00 2001 From: Marcos Rios Date: Thu, 22 Feb 2024 23:55:07 -0300 Subject: [PATCH 09/22] Remove nonsense ref --- src/pages/Settings.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index d4ee5292..d56e4815 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -105,8 +105,6 @@ export function SettingsPage() { const setTheme = useThemeStore((s) => s.setTheme); const previewTheme = usePreviewThemeStore((s) => s.previewTheme) ?? "default"; const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); - const activeThemeRef = useRef(activeTheme); - activeThemeRef.current = activeTheme; const appLanguage = useLanguageStore((s) => s.language); const setAppLanguage = useLanguageStore((s) => s.setLanguage); @@ -147,11 +145,10 @@ export function SettingsPage() { enableThumbnails, ); + // Reset the preview theme when the settings page is unmounted useEffect( () => () => { - setPreviewTheme( - activeThemeRef.current === "default" ? null : activeThemeRef.current, - ); + setPreviewTheme(null); }, [setPreviewTheme], ); From b18269b40ef8a54a1f04b00f37eda17e1cc71fe8 Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:26:17 +0200 Subject: [PATCH 10/22] chore: Remove references to official domain --- .github/CODE_OF_CONDUCT.md | 2 +- .github/CONTRIBUTING.md | 6 +++--- .github/SECURITY.md | 9 +++------ README.md | 6 +++--- package.json | 2 +- public/config.js | 2 +- src/backend/accounts/progress.ts | 2 ++ src/backend/helpers/report.ts | 7 +++++-- src/pages/parts/settings/ConnectionsPart.tsx | 4 ++-- src/setup/constants.ts | 4 ++-- 10 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 412c4af2..c45aba90 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -codeofconduct@movie-web.app. +our [Discord](https://discord.gg/gQYB6fGArX). All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 926899a8..a9883859 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing Guidelines for movie-web -Thank you for investing your time in contributing to our project! Your contribution will be reflected on [movie-web.app](https://movie-web.app). +Thank you for investing your time in contributing to our project! Your contribution will be reflected on all of the community hosted instances that are on the latest version. Please read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable. @@ -33,7 +33,7 @@ There are two places where to request features or report bugs: ### Discord Server If you do not have a GitHub account or want to discuss a feature or bug with us before making an issue, you can join our Discord server. -Discord Server +Discord Server ### GitHub Issues To make a GitHub issue for movie-web, please visit the [new issue page](https://github.com/movie-web/movie-web/issues/new/choose) where you can pick either the "Bug Report" or "Feature Request" template. @@ -85,7 +85,7 @@ Here are some tips to make sure that your pull requests are :pinched_fingers: fi ### Language Contributions Language contributions help movie-web massively, allowing people worldwide to use our app! -We use weblate for crowdsourcing our translations. [Click here to go to our translation tool.](https://weblate.movie-web.app/projects/movie-web/website/) +We use weblate for crowdsourcing our translations. 1. First make sure you make an account. (click the link above) 2. Click the language you want to help translate, if it's not listed you can click the plus top left to add a new language. diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 83bf16ae..b092f774 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -2,12 +2,9 @@ ## Supported Versions -The movie-web maintainers only support the latest version of movie-web published at https://movie-web.app. - -Support is not provided for any forks or mirrors of movie-web. +The latest version of movie-web is the only version that is supported, as it is the only version that is being actively developed. ## Reporting a Vulnerability -There are two ways you can contact the movie-web maintainers to report a vulnerability: - - Email [security@movie-web.app](mailto:security@movie-web.app) - - Report the vulnerability in the [movie-web Discord server](https://discord.movie-web.app) +You can contact the movie-web maintainers to report a vulnerability: + - Report the vulnerability in the [movie-web Discord server](https://discord.gg/gQYB6fGArX) diff --git a/README.md b/README.md index 7f4662a2..7a2470a9 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@


- 🔵 discord 🟢 website + 🔵 discord 🟢 docs



# ⚡What is movie-web? -movie-web is a web app for watching movies easily. Check it out at movie-web.app. +movie-web is a web app for watching movies easily. This service works by displaying video files from third-party providers inside an intuitive and aesthetic user interface. @@ -57,7 +57,7 @@ pnpm build A simple guide has been written to assist in hosting your own instance of movie-web. Check it out below -|[Selfhosting guide](https://docs.movie-web.app)| +|[Selfhosting guide](https://movie-web.github.io/docs)| |---| ## 🤝 Thanks to all Contributors diff --git a/package.json b/package.json index 810a689b..3d6724b3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "movie-web", "version": "4.4.2", "private": true, - "homepage": "https://movie-web.app", + "homepage": "https://github.com/movie-web/movie-web", "scripts": { "dev": "vite", "build": "vite build", diff --git a/public/config.js b/public/config.js index 68a9ca3f..011e8630 100644 --- a/public/config.js +++ b/public/config.js @@ -11,7 +11,7 @@ window.__CONFIG__ = { // Whether to disable hash-based routing, leave this as false if you don't know what this is VITE_NORMAL_ROUTER: false, - // The backend URL to communicate with, defaults to the movie-web hosted one at backend.movie-web.app + // The backend URL to communicate with VITE_BACKEND_URL: null, // A comma separated list of disallowed IDs in the case of a DMCA claim - in the format "series-" and "movie-" diff --git a/src/backend/accounts/progress.ts b/src/backend/accounts/progress.ts index 511d1c5d..6b522079 100644 --- a/src/backend/accounts/progress.ts +++ b/src/backend/accounts/progress.ts @@ -2,6 +2,7 @@ import { ofetch } from "ofetch"; import { getAuthHeaders } from "@/backend/accounts/auth"; import { ProgressResponse } from "@/backend/accounts/user"; +import { BACKEND_URL } from "@/setup/constants"; import { AccountWithToken } from "@/stores/auth"; import { ProgressMediaItem, ProgressUpdateItem } from "@/stores/progress"; @@ -103,6 +104,7 @@ export async function removeProgress( episodeId?: string, seasonId?: string, ) { + if (!BACKEND_URL) return; await ofetch(`/users/${account.userId}/progress/${id}`, { method: "DELETE", headers: getAuthHeaders(account.token), diff --git a/src/backend/helpers/report.ts b/src/backend/helpers/report.ts index 4822a867..4aa19f0e 100644 --- a/src/backend/helpers/report.ts +++ b/src/backend/helpers/report.ts @@ -5,13 +5,14 @@ import { useCallback } from "react"; import { isExtensionActiveCached } from "@/backend/extension/messaging"; import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape"; +import { BACKEND_URL } from "@/setup/constants"; import { useAuthStore } from "@/stores/auth"; import { PlayerMeta } from "@/stores/player/slices/source"; // for anybody who cares - these are anonymous metrics. // They are just used for figuring out if providers are broken or not -const metricsEndpoint = "https://backend.movie-web.app/metrics/providers"; -const captchaMetricsEndpoint = "https://backend.movie-web.app/metrics/captcha"; +const metricsEndpoint = `${BACKEND_URL}/metrics/providers`; +const captchaMetricsEndpoint = `${BACKEND_URL}/metrics/captcha`; const batchId = () => nanoid(32); export type ProviderMetric = { @@ -44,6 +45,7 @@ function getStackTrace(error: Error, lines: number) { } export async function reportProviders(items: ProviderMetric[]): Promise { + if (!BACKEND_URL) return; return ofetch(metricsEndpoint, { method: "POST", body: { @@ -156,6 +158,7 @@ export function useReportProviders() { } export function reportCaptchaSolve(success: boolean) { + if (!BACKEND_URL) return; ofetch(captchaMetricsEndpoint, { method: "POST", body: { diff --git a/src/pages/parts/settings/ConnectionsPart.tsx b/src/pages/parts/settings/ConnectionsPart.tsx index 9b693e9f..990c5de0 100644 --- a/src/pages/parts/settings/ConnectionsPart.tsx +++ b/src/pages/parts/settings/ConnectionsPart.tsx @@ -55,7 +55,7 @@ function ProxyEdit({ proxyUrls, setProxyUrls }: ProxyEditProps) {

- + Proxy documentation @@ -125,7 +125,7 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {

- + Backend documentation diff --git a/src/setup/constants.ts b/src/setup/constants.ts index 27a9792b..def7c48f 100644 --- a/src/setup/constants.ts +++ b/src/setup/constants.ts @@ -1,6 +1,6 @@ export const APP_VERSION = import.meta.env.PACKAGE_VERSION; -export const DISCORD_LINK = "https://discord.movie-web.app"; +export const DISCORD_LINK = "https://discord.gg/gQYB6fGArX"; export const GITHUB_LINK = "https://github.com/movie-web/movie-web"; export const DONATION_LINK = "https://ko-fi.com/movieweb"; export const GA_ID = "G-44YVXRL61C"; -export const BACKEND_URL = "https://backend.movie-web.app"; +export const BACKEND_URL = import.meta.env.VITE_BACKEND_URL; From fcf42a4e8ad76d4790f32d1d375a81ba930d91b6 Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Sat, 24 Feb 2024 02:08:01 +0200 Subject: [PATCH 11/22] fix: change useBackendUrl to possibly be undefined, add checks to avoid useless requests to nonexistent backend --- src/backend/accounts/progress.ts | 2 -- src/hooks/auth/useAuth.ts | 6 +++++- src/hooks/auth/useBackendUrl.ts | 2 +- src/pages/Settings.tsx | 3 ++- src/pages/onboarding/OnboardingProxy.tsx | 2 +- src/pages/parts/admin/BackendTestPart.tsx | 14 +++++++++++--- src/pages/parts/auth/LoginFormPart.tsx | 3 +++ src/pages/parts/auth/TrustBackendPart.tsx | 6 +++++- src/pages/parts/auth/VerifyPassphrasePart.tsx | 5 +++++ src/pages/parts/settings/AccountActionsPart.tsx | 2 +- src/pages/parts/settings/DeviceListPart.tsx | 1 + src/pages/parts/settings/SidebarPart.tsx | 7 ++++--- src/stores/bookmarks/BookmarkSyncer.tsx | 1 + src/stores/progress/ProgressSyncer.tsx | 1 + src/stores/subtitles/SettingsSyncer.tsx | 1 + 15 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/backend/accounts/progress.ts b/src/backend/accounts/progress.ts index 6b522079..511d1c5d 100644 --- a/src/backend/accounts/progress.ts +++ b/src/backend/accounts/progress.ts @@ -2,7 +2,6 @@ import { ofetch } from "ofetch"; import { getAuthHeaders } from "@/backend/accounts/auth"; import { ProgressResponse } from "@/backend/accounts/user"; -import { BACKEND_URL } from "@/setup/constants"; import { AccountWithToken } from "@/stores/auth"; import { ProgressMediaItem, ProgressUpdateItem } from "@/stores/progress"; @@ -104,7 +103,6 @@ export async function removeProgress( episodeId?: string, seasonId?: string, ) { - if (!BACKEND_URL) return; await ofetch(`/users/${account.userId}/progress/${id}`, { method: "DELETE", headers: getAuthHeaders(account.token), diff --git a/src/hooks/auth/useAuth.ts b/src/hooks/auth/useAuth.ts index f608d148..3ce49163 100644 --- a/src/hooks/auth/useAuth.ts +++ b/src/hooks/auth/useAuth.ts @@ -63,6 +63,7 @@ export function useAuth() { const login = useCallback( async (loginData: LoginData) => { + if (!backendUrl) return; const keys = await keysFromMnemonic(loginData.mnemonic); const publicKeyBase64Url = bytesToBase64Url(keys.publicKey); const { challenge } = await getLoginChallengeToken( @@ -87,7 +88,7 @@ export function useAuth() { ); const logout = useCallback(async () => { - if (!currentAccount) return; + if (!currentAccount || !backendUrl) return; try { await removeSession( backendUrl, @@ -102,6 +103,7 @@ export function useAuth() { const register = useCallback( async (registerData: RegistrationData) => { + if (!backendUrl) return; const { challenge } = await getRegisterChallengeToken( backendUrl, registerData.recaptchaToken, @@ -134,6 +136,7 @@ export function useAuth() { progressItems: Record, bookmarks: Record, ) => { + if (!backendUrl) return; if ( Object.keys(progressItems).length === 0 && Object.keys(bookmarks).length === 0 @@ -159,6 +162,7 @@ export function useAuth() { const restore = useCallback( async (account: AccountWithToken) => { + if (!backendUrl) return; let user: { user: UserResponse; session: SessionResponse }; try { user = await getUser(backendUrl, account.token); diff --git a/src/hooks/auth/useBackendUrl.ts b/src/hooks/auth/useBackendUrl.ts index e417ed06..64545227 100644 --- a/src/hooks/auth/useBackendUrl.ts +++ b/src/hooks/auth/useBackendUrl.ts @@ -1,7 +1,7 @@ import { conf } from "@/setup/config"; import { useAuthStore } from "@/stores/auth"; -export function useBackendUrl() { +export function useBackendUrl(): string | undefined { const backendUrl = useAuthStore((s) => s.backendUrl); return backendUrl ?? conf().BACKEND_URL; } diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 18b755ca..cebf1ddd 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -70,6 +70,7 @@ export function AccountSettings(props: { const url = useBackendUrl(); const { account } = props; const [sessionsResult, execSessions] = useAsyncFn(() => { + if (!url) return Promise.resolve([]); return getSessions(url, account); }, [account, url]); useEffect(() => { @@ -144,7 +145,7 @@ export function SettingsPage() { ); const saveChanges = useCallback(async () => { - if (account) { + if (account && backendUrl) { if ( state.appLanguage.changed || state.theme.changed || diff --git a/src/pages/onboarding/OnboardingProxy.tsx b/src/pages/onboarding/OnboardingProxy.tsx index e67c0769..00584eef 100644 --- a/src/pages/onboarding/OnboardingProxy.tsx +++ b/src/pages/onboarding/OnboardingProxy.tsx @@ -43,7 +43,7 @@ export function OnboardingProxyPage() { throw new Error("onboarding.proxy.input.errorNotProxy"); setProxySet([url]); - if (account) { + if (account && backendUrl) { await updateSettings(backendUrl, account, { proxyUrls: [url], }); diff --git a/src/pages/parts/admin/BackendTestPart.tsx b/src/pages/parts/admin/BackendTestPart.tsx index 449e9643..aadd9397 100644 --- a/src/pages/parts/admin/BackendTestPart.tsx +++ b/src/pages/parts/admin/BackendTestPart.tsx @@ -32,13 +32,21 @@ export function BackendTestPart() { value: null, }); + if (!backendUrl) { + return setStatus({ + hasTested: true, + success: false, + errorText: "Backend URL is not set", + value: null, + }); + } + try { const backendData = await getBackendMeta(backendUrl); return setStatus({ hasTested: true, success: true, - errorText: - "Failed to call backend, double check the URL key and your internet connection", + errorText: "", value: backendData, }); } catch (err) { @@ -46,7 +54,7 @@ export function BackendTestPart() { hasTested: true, success: false, errorText: - "Failed to call backend, double check the URL key and your internet connection", + "Failed to call backend, double check the URL, your internet connection, and ensure CORS is properly configured on your backend.", value: null, }); } diff --git a/src/pages/parts/auth/LoginFormPart.tsx b/src/pages/parts/auth/LoginFormPart.tsx index e4bed3ec..ac63fad2 100644 --- a/src/pages/parts/auth/LoginFormPart.tsx +++ b/src/pages/parts/auth/LoginFormPart.tsx @@ -52,6 +52,9 @@ export function LoginFormPart(props: LoginFormPartProps) { throw err; } + if (!account) + throw new Error(t("auth.login.validationError") ?? undefined); + await importData(account, progressItems, bookmarkItems); await restore(account); diff --git a/src/pages/parts/auth/TrustBackendPart.tsx b/src/pages/parts/auth/TrustBackendPart.tsx index 3fa818ef..0d71e403 100644 --- a/src/pages/parts/auth/TrustBackendPart.tsx +++ b/src/pages/parts/auth/TrustBackendPart.tsx @@ -22,8 +22,12 @@ interface TrustBackendPartProps { export function TrustBackendPart(props: TrustBackendPartProps) { const navigate = useNavigate(); const backendUrl = useBackendUrl(); - const hostname = useMemo(() => new URL(backendUrl).hostname, [backendUrl]); + const hostname = useMemo( + () => (backendUrl ? new URL(backendUrl).hostname : ""), + [backendUrl], + ); const result = useAsync(() => { + if (!backendUrl) return Promise.resolve(null); return getBackendMeta(backendUrl); }, [backendUrl]); const { t } = useTranslation(); diff --git a/src/pages/parts/auth/VerifyPassphrasePart.tsx b/src/pages/parts/auth/VerifyPassphrasePart.tsx index 2f040ccb..1d6ea62a 100644 --- a/src/pages/parts/auth/VerifyPassphrasePart.tsx +++ b/src/pages/parts/auth/VerifyPassphrasePart.tsx @@ -47,6 +47,8 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) { const [result, execute] = useAsyncFn( async (inputMnemonic: string) => { + if (!backendUrl) + throw new Error(t("auth.verify.noBackendUrl") ?? undefined); if (!props.mnemonic || !props.userData) throw new Error(t("auth.verify.invalidData") ?? undefined); @@ -68,6 +70,9 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) { recaptchaToken, }); + if (!account) + throw new Error(t("auth.verify.registrationFailed") ?? undefined); + await importData(account, progressItems, bookmarkItems); await updateSettings(backendUrl, account, { diff --git a/src/pages/parts/settings/AccountActionsPart.tsx b/src/pages/parts/settings/AccountActionsPart.tsx index e19aa9e9..f1e50dbf 100644 --- a/src/pages/parts/settings/AccountActionsPart.tsx +++ b/src/pages/parts/settings/AccountActionsPart.tsx @@ -18,7 +18,7 @@ export function AccountActionsPart() { const deleteModal = useModal("account-delete"); const [deleteResult, deleteExec] = useAsyncFn(async () => { - if (!account) return; + if (!account || !url) return; await deleteUser(url, account); await logout(); deleteModal.hide(); diff --git a/src/pages/parts/settings/DeviceListPart.tsx b/src/pages/parts/settings/DeviceListPart.tsx index afaea589..c7326059 100644 --- a/src/pages/parts/settings/DeviceListPart.tsx +++ b/src/pages/parts/settings/DeviceListPart.tsx @@ -24,6 +24,7 @@ export function Device(props: { const token = useAuthStore((s) => s.account?.token); const [result, exec] = useAsyncFn(async () => { if (!token) throw new Error("No token present"); + if (!url) throw new Error("No backend set"); await removeSession(url, token, props.id); props.onRemove?.(); }, [url, token, props.id]); diff --git a/src/pages/parts/settings/SidebarPart.tsx b/src/pages/parts/settings/SidebarPart.tsx index 47469a5e..13db06fe 100644 --- a/src/pages/parts/settings/SidebarPart.tsx +++ b/src/pages/parts/settings/SidebarPart.tsx @@ -14,9 +14,9 @@ import { useAuthStore } from "@/stores/auth"; const rem = 16; -function SecureBadge(props: { url: string }) { +function SecureBadge(props: { url: string | undefined }) { const { t } = useTranslation(); - const secure = props.url.startsWith("https://"); + const secure = props.url ? props.url.startsWith("https://") : false; return (

@@ -68,6 +68,7 @@ export function SidebarPart() { const backendUrl = useBackendUrl(); const backendMeta = useAsync(async () => { + if (!backendUrl) return; return getBackendMeta(backendUrl); }, [backendUrl]); @@ -159,7 +160,7 @@ export function SidebarPart() {

- {backendUrl.replace(/https?:\/\//, "")} + {backendUrl?.replace(/https?:\/\//, "") ?? "—"}

diff --git a/src/stores/bookmarks/BookmarkSyncer.tsx b/src/stores/bookmarks/BookmarkSyncer.tsx index 1f3b705d..7d4d0bc0 100644 --- a/src/stores/bookmarks/BookmarkSyncer.tsx +++ b/src/stores/bookmarks/BookmarkSyncer.tsx @@ -60,6 +60,7 @@ export function BookmarkSyncer() { useEffect(() => { const interval = setInterval(() => { (async () => { + if (!url) return; const state = useBookmarkStore.getState(); const user = useAuthStore.getState(); await syncBookmarks( diff --git a/src/stores/progress/ProgressSyncer.tsx b/src/stores/progress/ProgressSyncer.tsx index c9b4eb58..67aae877 100644 --- a/src/stores/progress/ProgressSyncer.tsx +++ b/src/stores/progress/ProgressSyncer.tsx @@ -62,6 +62,7 @@ export function ProgressSyncer() { useEffect(() => { const interval = setInterval(() => { (async () => { + if (!url) return; const state = useProgressStore.getState(); const user = useAuthStore.getState(); await syncProgress( diff --git a/src/stores/subtitles/SettingsSyncer.tsx b/src/stores/subtitles/SettingsSyncer.tsx index 48b25bbe..ca3c0817 100644 --- a/src/stores/subtitles/SettingsSyncer.tsx +++ b/src/stores/subtitles/SettingsSyncer.tsx @@ -16,6 +16,7 @@ export function SettingsSyncer() { useEffect(() => { const interval = setInterval(() => { (async () => { + if (!url) return; const state = useSubtitleStore.getState(); const user = useAuthStore.getState(); if (state.lastSync.lastSelectedLanguage === state.lastSelectedLanguage) From 130b4f5cc39478dd90e10f24c5fb0f0ce90420bc Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Sun, 25 Feb 2024 21:31:08 +0200 Subject: [PATCH 12/22] feat: disable creating account when server is not set --- src/assets/locales/en.json | 2 + src/pages/parts/auth/TrustBackendPart.tsx | 72 ++++++++++++++--------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index c6a43875..55922380 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -55,6 +55,8 @@ "text": "Did you configure it correctly?", "title": "Failed to reach server" }, + "noHostTitle": "Server not configured!", + "noHost": "The server has not been configured, therefore you cannot create an account", "host": "You are connecting to <0>{{hostname}} - please confirm you trust it before making an account", "no": "Go back", "title": "Do you trust this server?", diff --git a/src/pages/parts/auth/TrustBackendPart.tsx b/src/pages/parts/auth/TrustBackendPart.tsx index 0d71e403..16c16c66 100644 --- a/src/pages/parts/auth/TrustBackendPart.tsx +++ b/src/pages/parts/auth/TrustBackendPart.tsx @@ -23,7 +23,7 @@ export function TrustBackendPart(props: TrustBackendPartProps) { const navigate = useNavigate(); const backendUrl = useBackendUrl(); const hostname = useMemo( - () => (backendUrl ? new URL(backendUrl).hostname : ""), + () => (backendUrl ? new URL(backendUrl).hostname : undefined), [backendUrl], ); const result = useAsync(() => { @@ -54,38 +54,52 @@ export function TrustBackendPart(props: TrustBackendPartProps) { return ( } > - - - + {hostname ? ( + + + + ) : ( +

{t("auth.trust.noHost")}

+ )}
-
- {cardContent} -
- - - - -

- - . - -

+ {hostname ? ( + <> +
+ {cardContent} +
+ + + + +

+ + . + +

+ + ) : ( + + + + )}
); } From bf6424f75d5ec77fc541846bf42bd9dd4a17b241 Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:04:47 +0200 Subject: [PATCH 13/22] feat: run worker tests in parallel with 5 sec cooldown --- src/pages/parts/admin/TMDBTestPart.tsx | 8 ++++---- src/pages/parts/admin/WorkerTestPart.tsx | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/pages/parts/admin/TMDBTestPart.tsx b/src/pages/parts/admin/TMDBTestPart.tsx index 00198946..a7f8fa50 100644 --- a/src/pages/parts/admin/TMDBTestPart.tsx +++ b/src/pages/parts/admin/TMDBTestPart.tsx @@ -29,7 +29,7 @@ export function TMDBTestPart() { return setStatus({ hasTested: true, success: false, - errorText: "TMDB api key is not set", + errorText: "TMDB API key is not set", }); } const isJWT = tmdbApiKey.split(".").length > 2; @@ -37,7 +37,7 @@ export function TMDBTestPart() { return setStatus({ hasTested: true, success: false, - errorText: "TMDB api key is not a read only key", + errorText: "TMDB API key is not a read only key", }); } @@ -48,7 +48,7 @@ export function TMDBTestPart() { hasTested: true, success: false, errorText: - "Failed to call tmdb, double check api key and your internet connection", + "Failed to call TMDB, double check API key and your internet connection", }); } @@ -61,7 +61,7 @@ export function TMDBTestPart() { return ( <> - TMDB tests + TMDB test
diff --git a/src/pages/parts/admin/WorkerTestPart.tsx b/src/pages/parts/admin/WorkerTestPart.tsx index e2dd6780..5f8b9853 100644 --- a/src/pages/parts/admin/WorkerTestPart.tsx +++ b/src/pages/parts/admin/WorkerTestPart.tsx @@ -52,14 +52,18 @@ export function WorkerTestPart() { { id: string; status: "error" | "success"; error?: Error }[] >([]); + const [buttonDisabled, setButtonDisabled] = useState(false); + const [testState, runTests] = useAsyncFn(async () => { + setButtonDisabled(true); function updateWorker(id: string, data: (typeof workerState)[number]) { setWorkerState((s) => { return [...s.filter((v) => v.id !== id), data]; }); } setWorkerState([]); - for (const worker of workerList) { + + const workerPromises = workerList.map(async (worker) => { try { if (worker.url.endsWith("/")) { updateWorker(worker.id, { @@ -67,7 +71,7 @@ export function WorkerTestPart() { status: "error", error: new Error("URL ends with slash"), }); - continue; + return; } await singularProxiedFetch( worker.url, @@ -85,7 +89,10 @@ export function WorkerTestPart() { error: err as Error, }); } - } + }); + + await Promise.all(workerPromises); + setTimeout(() => setButtonDisabled(false), 5000); }, [workerList, setWorkerState]); return ( @@ -112,7 +119,12 @@ export function WorkerTestPart() { })}
-
From 1df0ac000d3e0a17d4ad7700742c938edbbb636e Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Mon, 26 Feb 2024 13:48:45 +0200 Subject: [PATCH 14/22] feat: disable default setup option if no proxies set, remove extension help on OK --- src/pages/onboarding/Onboarding.tsx | 52 +++++++++++--------- src/pages/onboarding/OnboardingExtension.tsx | 2 +- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/pages/onboarding/Onboarding.tsx b/src/pages/onboarding/Onboarding.tsx index 8ba0ba19..01ff209f 100644 --- a/src/pages/onboarding/Onboarding.tsx +++ b/src/pages/onboarding/Onboarding.tsx @@ -13,6 +13,7 @@ import { } from "@/pages/onboarding/onboardingHooks"; import { Card, CardContent, Link } from "@/pages/onboarding/utils"; import { PageTitle } from "@/pages/parts/util/PageTitle"; +import { getProxyUrls } from "@/utils/proxyUrls"; function VerticalLine(props: { className?: string }) { return ( @@ -27,6 +28,7 @@ export function OnboardingPage() { const skipModal = useModal("skip"); const { completeAndRedirect } = useRedirectBack(); const { t } = useTranslation(); + const noProxies = getProxyUrls().length === 0; return ( @@ -85,32 +87,34 @@ export function OnboardingPage() {
- -

- -
- -
-

- - +

+
+ +
+ + )} ); diff --git a/src/pages/onboarding/OnboardingExtension.tsx b/src/pages/onboarding/OnboardingExtension.tsx index a0fa035d..db351dda 100644 --- a/src/pages/onboarding/OnboardingExtension.tsx +++ b/src/pages/onboarding/OnboardingExtension.tsx @@ -115,7 +115,7 @@ export function ExtensionStatus(props: {
{lastKnownStatus === "unknown" ? : null} - {props.showHelp ? ( + {props.showHelp && props.status !== "success" ? (
From f93e9288b54f63f05c8ac1993c202585173235a8 Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Mon, 26 Feb 2024 14:06:33 +0200 Subject: [PATCH 15/22] feat: remove default VITE_CORS_PROXY_URL --- public/config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/config.js b/public/config.js index 011e8630..a0681d06 100644 --- a/public/config.js +++ b/public/config.js @@ -1,6 +1,7 @@ window.__CONFIG__ = { // The URL for the CORS proxy, the URL must NOT end with a slash! - VITE_CORS_PROXY_URL: "CHANGEME", + // If not specified, the onboarding will not allow a "default setup". The user will have to use the extension or set up a proxy themselves + VITE_CORS_PROXY_URL: "", // The READ API key to access TMDB VITE_TMDB_READ_API_KEY: "CHANGEME", From e8d8c16d418b64db466352be1cdf48a958b38f7b Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:56:46 +0200 Subject: [PATCH 16/22] fix: use window.open instead of react-router on href within Button --- src/components/buttons/Button.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/buttons/Button.tsx b/src/components/buttons/Button.tsx index 1c1a2b61..cee00528 100644 --- a/src/components/buttons/Button.tsx +++ b/src/components/buttons/Button.tsx @@ -21,7 +21,6 @@ interface Props { } export function Button(props: Props) { - const navigate = useNavigate(); const { onClick, href, loading } = props; const cb = useCallback( ( @@ -31,10 +30,12 @@ export function Button(props: Props) { >, ) => { if (loading) return; - if (href && !onClick) navigate(href); - else onClick?.(event); + if (href && !onClick) { + event.preventDefault(); + window.open(href, "_blank", "noreferrer"); + } else onClick?.(event); }, - [onClick, href, navigate, loading], + [onClick, href, loading], ); let colorClasses = "bg-white hover:bg-gray-200 text-black"; From 5321afe2cdbdf9dce643f3d64c23bb45e6162f6f Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:06:35 +0200 Subject: [PATCH 17/22] chore: remove useNavigate import --- src/components/buttons/Button.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/buttons/Button.tsx b/src/components/buttons/Button.tsx index cee00528..f5c81b8d 100644 --- a/src/components/buttons/Button.tsx +++ b/src/components/buttons/Button.tsx @@ -1,6 +1,5 @@ import classNames from "classnames"; import { ReactNode, useCallback } from "react"; -import { useNavigate } from "react-router-dom"; import { Icon, Icons } from "@/components/Icon"; import { Spinner } from "@/components/layout/Spinner"; From 0e72829dd76da6d99734d3ffb0e7c31fcdae05da Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Mon, 26 Feb 2024 19:40:35 +0200 Subject: [PATCH 18/22] feat: make Google Analytics configurable with VITE_GA_ID --- src/setup/constants.ts | 2 +- src/setup/ga.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/setup/constants.ts b/src/setup/constants.ts index def7c48f..a92cc880 100644 --- a/src/setup/constants.ts +++ b/src/setup/constants.ts @@ -2,5 +2,5 @@ export const APP_VERSION = import.meta.env.PACKAGE_VERSION; export const DISCORD_LINK = "https://discord.gg/gQYB6fGArX"; export const GITHUB_LINK = "https://github.com/movie-web/movie-web"; export const DONATION_LINK = "https://ko-fi.com/movieweb"; -export const GA_ID = "G-44YVXRL61C"; +export const GA_ID = import.meta.env.VITE_GA_ID; export const BACKEND_URL = import.meta.env.VITE_BACKEND_URL; diff --git a/src/setup/ga.ts b/src/setup/ga.ts index 1fbf488b..9b900c0d 100644 --- a/src/setup/ga.ts +++ b/src/setup/ga.ts @@ -2,8 +2,10 @@ import ReactGA from "react-ga4"; import { GA_ID } from "@/setup/constants"; -ReactGA.initialize([ - { - trackingId: GA_ID, - }, -]); +if (GA_ID) { + ReactGA.initialize([ + { + trackingId: GA_ID, + }, + ]); +} From 67c86a270e1eab14d86c46b84cf73291fc242cc8 Mon Sep 17 00:00:00 2001 From: qtchaos <72168435+qtchaos@users.noreply.github.com> Date: Mon, 26 Feb 2024 22:39:32 +0200 Subject: [PATCH 19/22] feat: make volume scrollable with your mouse --- src/components/player/atoms/Volume.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/components/player/atoms/Volume.tsx b/src/components/player/atoms/Volume.tsx index 35e9dff2..b2ea4cf4 100644 --- a/src/components/player/atoms/Volume.tsx +++ b/src/components/player/atoms/Volume.tsx @@ -47,8 +47,22 @@ export function Volume(props: Props) { if (dragging) percentage = makePercentage(dragPercentage); const percentageString = makePercentageString(percentage); + const handleWheel = useCallback( + (event: React.WheelEvent) => { + event.preventDefault(); + let newVolume = volume - event.deltaY / 1000; + newVolume = Math.max(0, Math.min(newVolume, 1)); + setVolume(newVolume); + }, + [volume, setVolume], + ); + return ( -
+
0 ? Icons.VOLUME : Icons.VOLUME_X} /> From 261ef5e6c57133806b07d75e6189bdf6c099b4bf Mon Sep 17 00:00:00 2001 From: William Oldham Date: Mon, 26 Feb 2024 21:27:31 +0000 Subject: [PATCH 20/22] Use quick links --- .github/CODE_OF_CONDUCT.md | 2 +- .github/CONTRIBUTING.md | 5 +++-- .github/SECURITY.md | 2 +- README.md | 2 +- src/setup/constants.ts | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index c45aba90..fddc74e2 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -our [Discord](https://discord.gg/gQYB6fGArX). +our [Discord](https://movie-web.github.io/links/discord). All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a9883859..1d1587f0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -33,7 +33,7 @@ There are two places where to request features or report bugs: ### Discord Server If you do not have a GitHub account or want to discuss a feature or bug with us before making an issue, you can join our Discord server. -Discord Server +Discord Server ### GitHub Issues To make a GitHub issue for movie-web, please visit the [new issue page](https://github.com/movie-web/movie-web/issues/new/choose) where you can pick either the "Bug Report" or "Feature Request" template. @@ -85,7 +85,8 @@ Here are some tips to make sure that your pull requests are :pinched_fingers: fi ### Language Contributions Language contributions help movie-web massively, allowing people worldwide to use our app! -We use weblate for crowdsourcing our translations. +We use Weblate for crowdsourcing our translations. [Click here to go to our translation tool.](https://movie-web.github.io/links/weblate) + 1. First make sure you make an account. (click the link above) 2. Click the language you want to help translate, if it's not listed you can click the plus top left to add a new language. diff --git a/.github/SECURITY.md b/.github/SECURITY.md index b092f774..2e85d3a2 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -7,4 +7,4 @@ The latest version of movie-web is the only version that is supported, as it is ## Reporting a Vulnerability You can contact the movie-web maintainers to report a vulnerability: - - Report the vulnerability in the [movie-web Discord server](https://discord.gg/gQYB6fGArX) + - Report the vulnerability in the [movie-web Discord server](https://movie-web.github.io/links/discord) diff --git a/README.md b/README.md index 7a2470a9..29afdbcd 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@


- 🔵 discord 🟢 docs + 🔵 discord 🟢 docs



diff --git a/src/setup/constants.ts b/src/setup/constants.ts index a92cc880..935987e9 100644 --- a/src/setup/constants.ts +++ b/src/setup/constants.ts @@ -1,5 +1,5 @@ export const APP_VERSION = import.meta.env.PACKAGE_VERSION; -export const DISCORD_LINK = "https://discord.gg/gQYB6fGArX"; +export const DISCORD_LINK = "https://movie-web.github.io/links/discord"; export const GITHUB_LINK = "https://github.com/movie-web/movie-web"; export const DONATION_LINK = "https://ko-fi.com/movieweb"; export const GA_ID = import.meta.env.VITE_GA_ID; From 7c4c02dd835d6466268e63e9b0f1ebd2f6e6522e Mon Sep 17 00:00:00 2001 From: William Oldham Date: Mon, 26 Feb 2024 21:27:45 +0000 Subject: [PATCH 21/22] Fix theme preview --- src/pages/Settings.tsx | 29 ++++++++++++++------------ src/pages/parts/settings/ThemePart.tsx | 14 ++++++++----- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index a2efcc2f..5fe8843b 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -102,9 +102,9 @@ export function AccountSettings(props: { export function SettingsPage() { const { t } = useTranslation(); - const activeTheme = useThemeStore((s) => s.theme) ?? "default"; + const activeTheme = useThemeStore((s) => s.theme); const setTheme = useThemeStore((s) => s.setTheme); - const previewTheme = usePreviewThemeStore((s) => s.previewTheme) ?? "default"; + const previewTheme = usePreviewThemeStore((s) => s.previewTheme); const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme); const appLanguage = useLanguageStore((s) => s.language); @@ -146,18 +146,21 @@ export function SettingsPage() { enableThumbnails, ); - // Reset the preview theme when the settings page is unmounted - useEffect( - () => () => { + useEffect(() => { + setPreviewTheme(activeTheme ?? "default"); + }, [setPreviewTheme, activeTheme]); + + useEffect(() => { + // Clear preview theme on unmount + return () => { setPreviewTheme(null); - }, - [setPreviewTheme], - ); + }; + }, [setPreviewTheme]); const setThemeWithPreview = useCallback( - (v: string | null) => { - state.theme.set(v === "default" ? null : v); - setPreviewTheme(v); + (theme: string) => { + state.theme.set(theme === "default" ? null : theme); + setPreviewTheme(theme); }, [state.theme, setPreviewTheme], ); @@ -261,8 +264,8 @@ export function SettingsPage() {
diff --git a/src/pages/parts/settings/ThemePart.tsx b/src/pages/parts/settings/ThemePart.tsx index f4972eaf..b5600181 100644 --- a/src/pages/parts/settings/ThemePart.tsx +++ b/src/pages/parts/settings/ThemePart.tsx @@ -7,22 +7,27 @@ import { Heading1 } from "@/components/utils/Text"; const availableThemes = [ { id: "default", + selector: "theme-default", key: "settings.appearance.themes.default", }, { id: "blue", + selector: "theme-blue", key: "settings.appearance.themes.blue", }, { id: "teal", + selector: "theme-teal", key: "settings.appearance.themes.teal", }, { id: "red", + selector: "theme-red", key: "settings.appearance.themes.red", }, { id: "gray", + selector: "theme-gray", key: "settings.appearance.themes.gray", }, ]; @@ -121,9 +126,9 @@ function ThemePreview(props: { } export function ThemePart(props: { - active: string | null; - inUse: string | null; - setTheme: (theme: string | null) => void; + active: string; + inUse: string; + setTheme: (theme: string) => void; }) { const { t } = useTranslation(); @@ -131,10 +136,9 @@ export function ThemePart(props: {
{t("settings.appearance.title")}
- {/* default theme */} {availableThemes.map((v) => ( Date: Mon, 26 Feb 2024 21:34:51 +0000 Subject: [PATCH 22/22] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3d6724b3..8031308c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "movie-web", - "version": "4.4.2", + "version": "4.5.0", "private": true, "homepage": "https://github.com/movie-web/movie-web", "scripts": {