From 03ffea333a2aa5650f751feb7330e0132fccaa8c Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Sat, 17 Dec 2022 08:54:27 +0000 Subject: [PATCH] i18nify views --- public/locales/en-GB/translation.json | 41 +++++++++++++++++++++++++++ public/locales/en/translation.json | 5 ---- src/components/layout/BrandPill.tsx | 10 ++++--- src/i18n.ts | 3 +- src/index.tsx | 6 ++-- src/providers/list/xemovie/index.ts | 3 +- src/views/MediaView.tsx | 8 ++++-- src/views/SearchView.tsx | 34 ++++++++++++++-------- src/views/notfound/NotFoundView.tsx | 28 ++++++++++-------- 9 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 public/locales/en-GB/translation.json delete mode 100644 public/locales/en/translation.json diff --git a/public/locales/en-GB/translation.json b/public/locales/en-GB/translation.json new file mode 100644 index 00000000..6a863e81 --- /dev/null +++ b/public/locales/en-GB/translation.json @@ -0,0 +1,41 @@ +{ + "global": { + "name": "movie-web" + }, + "search": { + "loading": "Fetching your favourite shows...", + "providersFailed": "{{fails}}/{{total}} providers failed!", + "allResults": "That's all we have!", + "noResults": "We couldn't find anything!", + "allFailed": "All providers have failed!", + "headingTitle": "Search results", + "headingLink": "Back to home", + "bookmarks": "Bookmarks", + "continueWatching": "Continue Watching", + "tagline": "Because watching legally is boring", + "title": "What do you want to watch?", + "placeholder": "What do you want to watch?" + }, + "media": { + "invalidUrl": "Your URL may be invalid", + "arrowText": "Go back" + }, + "notFound": { + "backArrow": "Back to home", + "media": { + "title": "Couldn't find that media", + "description": "We couldn't find the media you requested. Either it's been removed or you tampered with the URL" + }, + "provider": { + "title": "This provider has been disabled", + "description": "We had issues with the provider or it was too unstable to use, so we had to disable it." + }, + "page": { + "title": "Couldn't find that page", + "description": "We looked everywhere: under the bins, in the closet, behind the proxy but ultimately couldn't find the page you are looking for." + } + }, + "errorBoundary": { + "text": "The app encountered an error and wasn't able to recover, please report it to the" + } +} \ No newline at end of file diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json deleted file mode 100644 index 3c99b521..00000000 --- a/public/locales/en/translation.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "global": { - "name": "movie-web" - } -} \ No newline at end of file diff --git a/src/components/layout/BrandPill.tsx b/src/components/layout/BrandPill.tsx index 842cf8a3..3df0be76 100644 --- a/src/components/layout/BrandPill.tsx +++ b/src/components/layout/BrandPill.tsx @@ -1,16 +1,18 @@ import { Icon, Icons } from "@/components/Icon"; +import { useTranslation } from "react-i18next"; export function BrandPill(props: { clickable?: boolean }) { + const { t } = useTranslation(); + return (
- movie-web + {t('global.name')}
); } diff --git a/src/i18n.ts b/src/i18n.ts index 6a9f7a01..8ab960b1 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -17,8 +17,7 @@ i18n // init i18next // for all options read: https://www.i18next.com/overview/configuration-options .init({ - fallbackLng: 'en', - debug: true, + fallbackLng: 'en-GB', interpolation: { escapeValue: false, // not needed for react as it escapes by default diff --git a/src/index.tsx b/src/index.tsx index 25d3e800..4b233305 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { Suspense } from "react"; import ReactDOM from "react-dom"; import { HashRouter } from "react-router-dom"; import "./index.css"; @@ -10,7 +10,9 @@ ReactDOM.render( - + + + , diff --git a/src/providers/list/xemovie/index.ts b/src/providers/list/xemovie/index.ts index 3f6b585b..7f65f026 100644 --- a/src/providers/list/xemovie/index.ts +++ b/src/providers/list/xemovie/index.ts @@ -100,8 +100,7 @@ export const xemovieScraper: MWMediaProvider = { const data = JSON.parse( JSON.stringify( eval( - `(${ - script.textContent.replace("const data = ", "").split("};")[0] + `(${script.textContent.replace("const data = ", "").split("};")[0] }})` ) ) diff --git a/src/views/MediaView.tsx b/src/views/MediaView.tsx index 446d9515..1c121cd2 100644 --- a/src/views/MediaView.tsx +++ b/src/views/MediaView.tsx @@ -29,6 +29,7 @@ import { useBookmarkContext, } from "@/state/bookmark"; import { getWatchedFromPortable, useWatchedContext } from "@/state/watched"; +import { useTranslation } from "react-i18next"; import { NotFoundChecks } from "./notfound/NotFoundChecks"; interface StyledMediaViewProps { @@ -105,6 +106,8 @@ function StyledMediaFooter(props: StyledMediaFooterProps) { } function LoadingMediaFooter(props: { error?: boolean }) { + const { t } = useTranslation(); + return (
@@ -117,7 +120,7 @@ function LoadingMediaFooter(props: { error?: boolean }) { {props.error ? (
-

Your url may be invalid

+

{t('media.invalidUrl')}

) : ( @@ -183,6 +186,7 @@ function MediaViewContent(props: { portable: MWPortableMedia }) { } export function MediaView() { + const { t } = useTranslation(); const mediaPortable: MWPortableMedia | undefined = usePortableMedia(); const reactHistory = useHistory(); @@ -196,7 +200,7 @@ export function MediaView() { : reactHistory.push("/") } direction="left" - linkText="Go back" + linkText={t('media.arrowText')} /> diff --git a/src/views/SearchView.tsx b/src/views/SearchView.tsx index f832a2b2..5d7fa97b 100644 --- a/src/views/SearchView.tsx +++ b/src/views/SearchView.tsx @@ -18,9 +18,11 @@ import { getIfBookmarkedFromPortable, useBookmarkContext, } from "@/state/bookmark/context"; +import { useTranslation } from "react-i18next"; function SearchLoading() { - return ; + const { t } = useTranslation(); + return ; } function SearchSuffix(props: { @@ -28,6 +30,8 @@ function SearchSuffix(props: { total: number; resultsSize: number; }) { + const { t } = useTranslation(); + const allFailed: boolean = props.fails === props.total; const icon: Icons = allFailed ? Icons.WARNING : Icons.EYE_SLASH; @@ -43,13 +47,13 @@ function SearchSuffix(props: {
{props.fails > 0 ? (

- {props.fails}/{props.total} providers failed! + {t('search.providersFailed', { fails: props.fails, total: props.total })}

) : null} {props.resultsSize > 0 ? ( -

That's all we have!

+

{t('search.allResults')}

) : ( -

We couldn't find anything!

+

{t('search.noResults')}

)}
) : null} @@ -57,7 +61,7 @@ function SearchSuffix(props: { {/* Error result */} {allFailed ? (
-

All providers have failed!

+

{t('search.allFailed')}

) : null}
@@ -71,6 +75,8 @@ function SearchResultsView({ searchQuery: MWQuery; clear: () => void; }) { + const { t } = useTranslation(); + const [results, setResults] = useState(); const [runSearchQuery, loading, error, success] = useLoading( (query: MWQuery) => SearchProviders(query) @@ -91,9 +97,9 @@ function SearchResultsView({ {/* results */} {success && results?.results.length ? ( clear()} > {results.results.map((v) => ( @@ -124,6 +130,8 @@ function SearchResultsView({ } function ExtraItems() { + const { t } = useTranslation(); + const { getFilteredBookmarks } = useBookmarkContext(); const { getFilteredWatched } = useWatchedContext(); @@ -138,7 +146,7 @@ function ExtraItems() { return (
{bookmarks.length > 0 ? ( - + {bookmarks.map((v) => ( ) : null} {watchedItems.length > 0 ? ( - + {watchedItems.map((v) => ( (false); const [loading, setLoading] = useState(false); const [search, setSearch, setSearchUnFocus] = useSearchQuery(); @@ -195,14 +205,14 @@ export function SearchView() { {/* input section */}
- Because watching legally is boring - What movie do you want to watch? + {t('search.tagline')} + {t('search.title')}
diff --git a/src/views/notfound/NotFoundView.tsx b/src/views/notfound/NotFoundView.tsx index aee1481b..c797e281 100644 --- a/src/views/notfound/NotFoundView.tsx +++ b/src/views/notfound/NotFoundView.tsx @@ -4,6 +4,7 @@ import { Icons } from "@/components/Icon"; import { Navigation } from "@/components/layout/Navigation"; import { ArrowLink } from "@/components/text/ArrowLink"; import { Title } from "@/components/text/Title"; +import { useTranslation } from "react-i18next"; function NotFoundWrapper(props: { children?: ReactNode }) { return ( @@ -17,52 +18,55 @@ function NotFoundWrapper(props: { children?: ReactNode }) { } export function NotFoundMedia() { + const { t } = useTranslation(); + return (
- Couldn't find that media + {t('notFound.media.title')}

- We couldn't find the media you requested. Either it's been - removed or you tampered with the URL + {t('notFound.media.description')}

- +
); } export function NotFoundProvider() { + const { t } = useTranslation(); + return (
- This provider has been disabled + {t('notFound.provider.title')}

- We had issues with the provider or it was too unstable to use, so we had - to disable it. + {t('notFound.provider.description')}

- +
); } export function NotFoundPage() { + const { t } = useTranslation(); + return ( - Couldn't find that page + {t('notFound.page.title')}

- We looked everywhere: under the bins, in the closet, behind the proxy - but ultimately couldn't find the page you are looking for. + {t('notFound.page.description')}

- +
); }