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')}
-
+
);
}