diff --git a/components/AudioTrackSelector.tsx b/components/AudioTrackSelector.tsx index 75fd659c..8302624e 100644 --- a/components/AudioTrackSelector.tsx +++ b/components/AudioTrackSelector.tsx @@ -3,6 +3,7 @@ import { useMemo } from "react"; import { TouchableOpacity, View } from "react-native"; import * as DropdownMenu from "zeego/dropdown-menu"; import { Text } from "./common/Text"; +import { useTranslation } from "react-i18next"; interface Props extends React.ComponentProps { source?: MediaSourceInfo; @@ -26,6 +27,8 @@ export const AudioTrackSelector: React.FC = ({ [audioStreams, selected] ); + const { t } = useTranslation(); + return ( = ({ - Audio + {t("series.audio")} {selectedAudioSteam?.DisplayTitle} diff --git a/components/BitrateSelector.tsx b/components/BitrateSelector.tsx index 0f1bd28b..ccb62f20 100644 --- a/components/BitrateSelector.tsx +++ b/components/BitrateSelector.tsx @@ -2,6 +2,7 @@ import { TouchableOpacity, View } from "react-native"; import * as DropdownMenu from "zeego/dropdown-menu"; import { Text } from "./common/Text"; import { useMemo } from "react"; +import { useTranslation } from "react-i18next"; export type Bitrate = { key: string; @@ -59,6 +60,8 @@ export const BitrateSelector: React.FC = ({ ); }, []); + const { t } = useTranslation(); + return ( = ({ - Quality + {t("series.quality")} {BITRATES.find((b) => b.value === selected?.value)?.key} diff --git a/components/ItemTechnicalDetails.tsx b/components/ItemTechnicalDetails.tsx index 0c472192..bb10784b 100644 --- a/components/ItemTechnicalDetails.tsx +++ b/components/ItemTechnicalDetails.tsx @@ -15,6 +15,7 @@ import { BottomSheetScrollView, } from "@gorhom/bottom-sheet"; import { Button } from "./Button"; +import { useTranslation } from "react-i18next"; interface Props { source?: MediaSourceInfo; @@ -22,15 +23,16 @@ interface Props { export const ItemTechnicalDetails: React.FC = ({ source, ...props }) => { const bottomSheetModalRef = useRef(null); + const { t } = useTranslation(); return ( - Video + {t("series.video")} bottomSheetModalRef.current?.present()}> - More details + {t("series.more_details")} = ({ source, ...props }) => { - Video + {t("series.video")} - Audio + {t("series.audio")} = ({ source, ...props }) => { - Subtitles + {t("series.subtitles")} = ({ }) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); + const { t } = useTranslation(); const { data: actor } = useQuery({ queryKey: ["actor", actorId], @@ -76,7 +78,7 @@ export const MoreMoviesWithActor: React.FC = ({ return ( - More with {actor?.Name} + {t("series.more_with", {name: actor?.Name})} = ({ ...props }) => { const [limit, setLimit] = useState(characterLimit); + const { t } = useTranslation(); if (!text) return null; return ( - Overview + {t("series.overview")} setLimit((prev) => diff --git a/components/SimilarItems.tsx b/components/SimilarItems.tsx index 46815b6d..f275ddfc 100644 --- a/components/SimilarItems.tsx +++ b/components/SimilarItems.tsx @@ -12,6 +12,7 @@ import { ItemCardText } from "./ItemCardText"; import { Loader } from "./Loader"; import { HorizontalScroll } from "./common/HorrizontalScroll"; import { TouchableItemRouter } from "./common/TouchableItemRouter"; +import { useTranslation } from "react-i18next"; interface SimilarItemsProps extends ViewProps { itemId?: string | null; @@ -23,6 +24,7 @@ export const SimilarItems: React.FC = ({ }) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); + const { t } = useTranslation(); const { data: similarItems, isLoading } = useQuery({ queryKey: ["similarItems", itemId], @@ -47,12 +49,12 @@ export const SimilarItems: React.FC = ({ return ( - Similar items + {t("series.similar_items")} ( { source?: MediaSourceInfo; @@ -37,6 +38,8 @@ export const SubtitleTrackSelector: React.FC = ({ if (subtitleStreams.length === 0) return null; + const { t } = useTranslation(); + return ( = ({ - Subtitle + {t("series.subtitles")} {selectedSubtitleSteam diff --git a/components/series/CastAndCrew.tsx b/components/series/CastAndCrew.tsx index 2b312f0e..6b8da475 100644 --- a/components/series/CastAndCrew.tsx +++ b/components/series/CastAndCrew.tsx @@ -12,6 +12,7 @@ import { HorizontalScroll } from "../common/HorrizontalScroll"; import { Text } from "../common/Text"; import Poster from "../posters/Poster"; import { itemRouter } from "../common/TouchableItemRouter"; +import { useTranslation } from "react-i18next"; interface Props extends ViewProps { item?: BaseItemDto | null; @@ -21,6 +22,7 @@ interface Props extends ViewProps { export const CastAndCrew: React.FC = ({ item, loading, ...props }) => { const [api] = useAtom(apiAtom); const segments = useSegments(); + const { t } = useTranslation(); const from = segments[2]; const destinctPeople = useMemo(() => { @@ -40,7 +42,7 @@ export const CastAndCrew: React.FC = ({ item, loading, ...props }) => { return ( - Cast & Crew + {t("series.cast_and_crew")} i.Id.toString()} diff --git a/components/series/CurrentSeries.tsx b/components/series/CurrentSeries.tsx index e573929a..cf2eba11 100644 --- a/components/series/CurrentSeries.tsx +++ b/components/series/CurrentSeries.tsx @@ -8,6 +8,7 @@ import Poster from "../posters/Poster"; import { HorizontalScroll } from "../common/HorrizontalScroll"; import { Text } from "../common/Text"; import { getPrimaryImageUrlById } from "@/utils/jellyfin/image/getPrimaryImageUrlById"; +import { useTranslation } from "react-i18next"; interface Props extends ViewProps { item?: BaseItemDto | null; @@ -15,10 +16,11 @@ interface Props extends ViewProps { export const CurrentSeries: React.FC = ({ item, ...props }) => { const [api] = useAtom(apiAtom); + const { t } = useTranslation(); return ( - Series + {t("series.series")} - Seasons + {t("series.seasons")} {!allSeasonsAvailable && ( @@ -210,7 +210,7 @@ const JellyseerrSeasons: React.FC<{ )} ListHeaderComponent={() => ( - Seasons + {t("series.seasons")} {!allSeasonsAvailable && ( diff --git a/components/series/NextUp.tsx b/components/series/NextUp.tsx index 95834b9d..40a1adf5 100644 --- a/components/series/NextUp.tsx +++ b/components/series/NextUp.tsx @@ -12,10 +12,12 @@ import ContinueWatchingPoster from "../ContinueWatchingPoster"; import { ItemCardText } from "../ItemCardText"; import { TouchableItemRouter } from "../common/TouchableItemRouter"; import { FlashList } from "@shopify/flash-list"; +import { useTranslation } from "react-i18next"; export const NextUp: React.FC<{ seriesId: string }> = ({ seriesId }) => { const [user] = useAtom(userAtom); const [api] = useAtom(apiAtom); + const { t } = useTranslation(); const { data: items } = useQuery({ queryKey: ["nextUp", seriesId], @@ -37,14 +39,14 @@ export const NextUp: React.FC<{ seriesId: string }> = ({ seriesId }) => { if (!items?.length) return ( - Next up - No items to display + {t("series.next_up")} + {t("series.no_items_to_display")} ); return ( - Next up + {t("series.next_up")} = ({ - Season {seasonIndex} + {t("series.season")} {seasonIndex} @@ -104,7 +105,7 @@ export const SeasonDropdown: React.FC = ({ collisionPadding={8} sideOffset={8} > - Seasons + {t("series.seasons")} {seasons?.sort(sortByIndex).map((season: any) => ( = ({ item, initialSeasonIndex }) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); const [seasonIndexState, setSeasonIndexState] = useAtom(seasonIndexAtom); + const { t } = useTranslation(); const seasonIndex = useMemo( () => seasonIndexState[item.Id ?? ""], @@ -210,7 +211,7 @@ export const SeasonPicker: React.FC = ({ item, initialSeasonIndex }) => { {(episodes?.length || 0) === 0 ? ( - No episodes for this season + {t("series.no_episodes_for_this_seasonz")} ) : null} diff --git a/components/settings/AudioToggles.tsx b/components/settings/AudioToggles.tsx index 366b57fe..6bcdbb36 100644 --- a/components/settings/AudioToggles.tsx +++ b/components/settings/AudioToggles.tsx @@ -68,7 +68,7 @@ export const AudioToggles: React.FC = ({ ...props }) => { }); }} > - None + t("home.settings.audio.none") {cultures?.map((l) => ( = ({ ...props }) => { }); }} > - None + {t("home.settings.subtitles.none")} {cultures?.map((l) => (