Jellyseerr

This commit is contained in:
Simon Caron
2025-01-13 00:03:41 -05:00
parent 90f20f6e46
commit cd8aba32d8
10 changed files with 106 additions and 35 deletions

View File

@@ -32,7 +32,7 @@ import { MediaSourceSelector } from "./MediaSourceSelector";
import ProgressCircle from "./ProgressCircle";
import { RoundButton } from "./RoundButton";
import { SubtitleTrackSelector } from "./SubtitleTrackSelector";
import { useTranslation } from "react-i18next";
import { t } from "i18next";
interface DownloadProps extends ViewProps {
items: BaseItemDto[];
@@ -56,7 +56,7 @@ export const DownloadItems: React.FC<DownloadProps> = ({
const [user] = useAtom(userAtom);
const [queue, setQueue] = useAtom(queueAtom);
const [settings] = useSettings();
const { t } = useTranslation();
const { processes, startBackgroundDownload, downloadedFiles } = useDownload();
const { startRemuxing } = useRemuxHlsToMp4();
@@ -393,7 +393,9 @@ export const DownloadSingleItem: React.FC<{
return (
<DownloadItems
size={size}
title="Download Episode"
title={item.Type == "Episode"
? t("item_card.download.download_episode")
: t("item_card.download.download_movie")}
subtitle={item.Name!}
items={[item]}
MissingDownloadIconComponent={() => (

View File

@@ -5,15 +5,17 @@ import React from "react";
import { FlashList } from "@shopify/flash-list";
import { Text } from "@/components/common/Text";
import PersonPoster from "@/components/jellyseerr/PersonPoster";
import { useTranslation } from "react-i18next";
const CastSlide: React.FC<
{ details?: MovieDetails | TvDetails } & ViewProps
> = ({ details, ...props }) => {
const { t } = useTranslation();
return (
details?.credits?.cast &&
details?.credits?.cast?.length > 0 && (
<View {...props}>
<Text className="text-lg font-bold mb-2 px-4">Cast</Text>
<Text className="text-lg font-bold mb-2 px-4">{t("jellyseerr.cast")}</Text>
<FlashList
horizontal
showsHorizontalScrollIndicator={false}

View File

@@ -9,6 +9,7 @@ import { TmdbRelease } from "@/utils/jellyseerr/server/api/themoviedb/interfaces
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
import CountryFlag from "react-native-country-flag";
import { ANIME_KEYWORD_ID } from "@/utils/jellyseerr/server/api/themoviedb/constants";
import { useTranslation } from "react-i18next";
interface Release {
certification: string;
@@ -50,6 +51,7 @@ const DetailFacts: React.FC<
{ details?: MovieDetails | TvDetails } & ViewProps
> = ({ details, className, ...props }) => {
const { jellyseerrUser } = useJellyseerr();
const { t } = useTranslation();
const locale = useMemo(() => {
return jellyseerrUser?.settings?.locale || "en";
@@ -144,21 +146,21 @@ const DetailFacts: React.FC<
return (
details && (
<View className="p-4">
<Text className="text-lg font-bold">Details</Text>
<Text className="text-lg font-bold">{t("jellyseerr.details")}</Text>
<View
className={`${className} flex flex-col justify-center divide-y-2 divide-neutral-800`}
{...props}
>
<Fact title="Status" fact={details?.status} />
<Fact title={t("jellyseerr.status")} fact={details?.status} />
<Fact
title="Original Title"
title={t("jellyseerr.original_title")}
fact={(details as TvDetails)?.originalName}
/>
{details.keywords.some(
(keyword) => keyword.id === ANIME_KEYWORD_ID
) && <Fact title="Series Type" fact="Anime" />}
) && <Fact title={t("jellyseerr.series_type")} fact="Anime" />}
<Facts
title="Release Dates"
title={t("jellyseerr.release_dates")}
facts={filteredReleases?.map?.((r: Release, idx) => (
<View key={idx} className="flex flex-row space-x-2 items-center">
{r.type === 3 ? (
@@ -184,13 +186,13 @@ const DetailFacts: React.FC<
</View>
))}
/>
<Fact title="First Air Date" fact={firstAirDate} />
<Fact title="Next Air Date" fact={nextAirDate} />
<Fact title="Revenue" fact={revenue} />
<Fact title="Budget" fact={budget} />
<Fact title="Original Language" fact={spokenLanguage} />
<Fact title={t("jellyseerr.first_air_date")} fact={firstAirDate} />
<Fact title={t("jellyseerr.next_air_date")} fact={nextAirDate} />
<Fact title={t("jellyseerr.revenue")} fact={revenue} />
<Fact title={t("jellyseerr.budget")} fact={budget} />
<Fact title={t("jellyseerr.original_language")} fact={spokenLanguage} />
<Facts
title="Production Country"
title={t("jellyseerr.production_country")}
facts={details?.productionCountries?.map((n, idx) => (
<View key={idx} className="flex flex-row items-center space-x-2">
<CountryFlag isoCode={n.iso_3166_1} size={10} />
@@ -199,14 +201,14 @@ const DetailFacts: React.FC<
))}
/>
<Facts
title="Studios"
title={t("jellyseerr.studios")}
facts={uniqBy(details?.productionCompanies, "name")?.map(
(n) => n.name
)}
/>
<Facts title="Network" facts={networks?.map((n) => n.name)} />
<Facts title={t("jellyseerr.network")}facts={networks?.map((n) => n.name)} />
<Facts
title="Currently Streaming on"
title={t("jellyseerr.currently_streaming_on")}
facts={streamingProviders?.map((s) => s.name)}
/>
</View>

View File

@@ -10,6 +10,7 @@ import {MediaRequestBody} from "@/utils/jellyseerr/server/interfaces/api/request
import {BottomSheetModalMethods} from "@gorhom/bottom-sheet/lib/typescript/types";
import {Button} from "@/components/Button";
import {Text} from "@/components/common/Text";
import { useTranslation } from "react-i18next";
interface Props {
id: number;
@@ -36,6 +37,8 @@ const RequestModal = forwardRef<BottomSheetModalMethods, Props & Omit<ViewProps,
userId: jellyseerrUser?.id
});
const { t } = useTranslation();
const [modalRequestProps, setModalRequestProps] = useState<MediaRequestBody>();
const {data: serviceSettings} = useQuery({
@@ -103,7 +106,7 @@ const RequestModal = forwardRef<BottomSheetModalMethods, Props & Omit<ViewProps,
);
const seasonTitle = useMemo(
() => modalRequestProps?.seasons?.length ? `Season (${modalRequestProps?.seasons})` : undefined,
() => modalRequestProps?.seasons?.length ? t("jellyseerr.season_x", {seasons: modalRequestProps?.seasons}) : undefined,
[modalRequestProps?.seasons]
);
@@ -148,7 +151,7 @@ const RequestModal = forwardRef<BottomSheetModalMethods, Props & Omit<ViewProps,
return <BottomSheetView>
<View className="flex flex-col space-y-4 px-4 pb-8 pt-2">
<View>
<Text className="font-bold text-2xl text-neutral-100">Advanced</Text>
<Text className="font-bold text-2xl text-neutral-100">{t("jellyseerr.advanced")}</Text>
{seasonTitle &&
<Text className="text-neutral-300">{seasonTitle}</Text>
}
@@ -161,27 +164,27 @@ const RequestModal = forwardRef<BottomSheetModalMethods, Props & Omit<ViewProps,
titleExtractor={(item) => item.name}
placeholderText={defaultProfile.name}
keyExtractor={(item) => item.id.toString()}
label={"Quality Profile"}
label={t("jellyseerr.quality_profile")}
onSelected={(item) =>
item && setRequestOverrides((prev) => ({
...prev,
profileId: item?.id
}))
}
title={"Quality Profile"}
title={t("jellyseerr.quality_profile")}
/>
<Dropdown
data={defaultServiceDetails.rootFolders}
titleExtractor={pathTitleExtractor}
placeholderText={defaultFolder ? pathTitleExtractor(defaultFolder) : ""}
keyExtractor={(item) => item.id.toString()}
label={"Root Folder"}
label={t("jellyseerr.root_folder")}
onSelected={(item) =>
item && setRequestOverrides((prev) => ({
...prev,
rootFolder: item.path
}))}
title={"Root Folder"}
title={t("jellyseerr.root_folder")}
/>
<Dropdown
multi={true}
@@ -189,28 +192,28 @@ const RequestModal = forwardRef<BottomSheetModalMethods, Props & Omit<ViewProps,
titleExtractor={(item) => item.label}
placeholderText={defaultTags.map(t => t.label).join(",")}
keyExtractor={(item) => item.id.toString()}
label={"Tags"}
label={t("jellyseerr.tags")}
onSelected={(...item) =>
item && setRequestOverrides((prev) => ({
...prev,
tags: item.map(i => i.id)
}))
}
title={"Tags"}
title={t("jellyseerr.tags")}
/>
<Dropdown
data={users}
titleExtractor={(item) => item.displayName}
placeholderText={jellyseerrUser!!.displayName}
keyExtractor={(item) => item.id.toString() || ""}
label={"Request As"}
label={t("jellyseerr.request_as")}
onSelected={(item) =>
item && setRequestOverrides((prev) => ({
...prev,
userId: item?.id
}))
}
title={"Request As"}
title={t("jellyseerr.request_as")}
/>
</>
)
@@ -221,7 +224,7 @@ const RequestModal = forwardRef<BottomSheetModalMethods, Props & Omit<ViewProps,
onPress={request}
color="purple"
>
Request
{t("jellyseerr.request_button")}
</Button>
</View>
</BottomSheetView>

View File

@@ -256,8 +256,8 @@ const JellyseerrSeasons: React.FC<{
<Tags
textClass=""
tags={[
`Season ${season.seasonNumber}`,
`${season.episodeCount} Episodes`,
t("jellyseerr.season_number", {season_number: season.seasonNumber}),
t("jellyseerr.number_episodes", {episode_number: season.episodeCount}),
]}
/>
{[0].map(() => {