diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 2111dd2e..1037334b 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -3,7 +3,7 @@
## Project Overview
Streamyfin is a cross-platform Jellyfin video streaming client built with Expo (React Native).
-It supports mobile (iOS/Android) and TV platforms, integrates with Jellyfin and Jellyseerr APIs,
+It supports mobile (iOS/Android) and TV platforms, integrates with Jellyfin and Seerr APIs,
and provides seamless media streaming with offline capabilities and Chromecast support.
## Main Technologies
diff --git a/README.md b/README.md
index 44a8863c..26f8e2fa 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
-
+
diff --git a/app/(auth)/(tabs)/(home)/_layout.tsx b/app/(auth)/(tabs)/(home)/_layout.tsx
index a7e059ed..761e868c 100644
--- a/app/(auth)/(tabs)/(home)/_layout.tsx
+++ b/app/(auth)/(tabs)/(home)/_layout.tsx
@@ -222,9 +222,9 @@ export default function IndexLayout() {
}}
/>
-
+
);
diff --git a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/company/[companyId].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/company/[companyId].tsx
similarity index 75%
rename from app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/company/[companyId].tsx
rename to app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/company/[companyId].tsx
index fdcd786c..359ebfd1 100644
--- a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/company/[companyId].tsx
+++ b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/company/[companyId].tsx
@@ -3,9 +3,9 @@ import { Image } from "expo-image";
import { useLocalSearchParams } from "expo-router";
import { uniqBy } from "lodash";
import { useMemo } from "react";
-import ParallaxSlideShow from "@/components/jellyseerr/ParallaxSlideShow";
-import JellyseerrPoster from "@/components/posters/JellyseerrPoster";
-import { Endpoints, useJellyseerr } from "@/hooks/useJellyseerr";
+import SeerrPoster from "@/components/posters/SeerrPoster";
+import ParallaxSlideShow from "@/components/seerr/ParallaxSlideShow";
+import { Endpoints, useSeerr } from "@/hooks/useSeerr";
import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover";
import {
type MovieResult,
@@ -13,9 +13,9 @@ import {
} from "@/utils/jellyseerr/server/models/Search";
import { COMPANY_LOGO_IMAGE_FILTER } from "@/utils/jellyseerr/src/components/Discover/NetworkSlider";
-export default function page() {
+export default function CompanyPage() {
const local = useLocalSearchParams();
- const { jellyseerrApi, isJellyseerrMovieOrTvResult } = useJellyseerr();
+ const { seerrApi, isSeerrMovieOrTvResult } = useSeerr();
const { companyId, image, type } = local as unknown as {
companyId: string;
@@ -25,12 +25,12 @@ export default function page() {
};
const { data, fetchNextPage, hasNextPage, isLoading } = useInfiniteQuery({
- queryKey: ["jellyseerr", "company", type, companyId],
+ queryKey: ["seerr", "company", type, companyId],
queryFn: async ({ pageParam }) => {
const params: any = {
page: Number(pageParam),
};
- return jellyseerrApi?.discover(
+ return seerrApi?.discover(
`${
Number(type) === DiscoverSliderType.NETWORKS
? Endpoints.DISCOVER_TV_NETWORK
@@ -39,7 +39,7 @@ export default function page() {
params,
);
},
- enabled: !!jellyseerrApi && !!companyId,
+ enabled: !!seerrApi && !!companyId,
initialPageParam: 1,
getNextPageParam: (lastPage, pages) =>
(lastPage?.page || pages?.findLast((p) => p?.results.length)?.page || 1) +
@@ -53,8 +53,7 @@ export default function page() {
data?.pages
?.filter((p) => p?.results.length)
.flatMap(
- (p) =>
- p?.results.filter((r) => isJellyseerrMovieOrTvResult(r)) ?? [],
+ (p) => p?.results.filter((r) => isSeerrMovieOrTvResult(r)) ?? [],
),
"id",
) ?? [],
@@ -63,15 +62,15 @@ export default function page() {
const backdrops = useMemo(
() =>
- jellyseerrApi
+ seerrApi
? flatData.map((r) =>
- jellyseerrApi.imageProxy(
+ seerrApi.imageProxy(
(r as TvResult | MovieResult).backdropPath,
"w1920_and_h800_multi_faces",
),
)
: [],
- [jellyseerrApi, flatData],
+ [seerrApi, flatData],
);
return (
@@ -92,7 +91,7 @@ export default function page() {
key={companyId}
className='bottom-1 w-1/2'
source={{
- uri: jellyseerrApi?.imageProxy(image, COMPANY_LOGO_IMAGE_FILTER),
+ uri: seerrApi?.imageProxy(image, COMPANY_LOGO_IMAGE_FILTER),
}}
cachePolicy={"memory-disk"}
contentFit='contain'
@@ -101,7 +100,7 @@ export default function page() {
}}
/>
}
- renderItem={(item, _index) => }
+ renderItem={(item, _index) => }
/>
);
}
diff --git a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/genre/[genreId].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/genre/[genreId].tsx
similarity index 67%
rename from app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/genre/[genreId].tsx
rename to app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/genre/[genreId].tsx
index 7ea00808..a61cff40 100644
--- a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/genre/[genreId].tsx
+++ b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/genre/[genreId].tsx
@@ -3,15 +3,15 @@ import { useLocalSearchParams } from "expo-router";
import { uniqBy } from "lodash";
import { useMemo } from "react";
import { Text } from "@/components/common/Text";
-import { textShadowStyle } from "@/components/jellyseerr/discover/GenericSlideCard";
-import ParallaxSlideShow from "@/components/jellyseerr/ParallaxSlideShow";
-import JellyseerrPoster from "@/components/posters/JellyseerrPoster";
-import { Endpoints, useJellyseerr } from "@/hooks/useJellyseerr";
+import SeerrPoster from "@/components/posters/SeerrPoster";
+import { textShadowStyle } from "@/components/seerr/discover/GenericSlideCard";
+import ParallaxSlideShow from "@/components/seerr/ParallaxSlideShow";
+import { Endpoints, useSeerr } from "@/hooks/useSeerr";
import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover";
-export default function page() {
+export default function GenrePage() {
const local = useLocalSearchParams();
- const { jellyseerrApi, isJellyseerrMovieOrTvResult } = useJellyseerr();
+ const { seerrApi, isSeerrMovieOrTvResult } = useSeerr();
const { genreId, name, type } = local as unknown as {
genreId: string;
@@ -20,21 +20,21 @@ export default function page() {
};
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
- queryKey: ["jellyseerr", "company", type, genreId],
+ queryKey: ["seerr", "company", type, genreId],
queryFn: async ({ pageParam }) => {
const params: any = {
page: Number(pageParam),
genre: genreId,
};
- return jellyseerrApi?.discover(
+ return seerrApi?.discover(
type === DiscoverSliderType.MOVIE_GENRES
? Endpoints.DISCOVER_MOVIES
: Endpoints.DISCOVER_TV,
params,
);
},
- enabled: !!jellyseerrApi && !!genreId,
+ enabled: !!seerrApi && !!genreId,
initialPageParam: 1,
getNextPageParam: (lastPage, pages) =>
(lastPage?.page || pages?.findLast((p) => p?.results.length)?.page || 1) +
@@ -48,8 +48,7 @@ export default function page() {
data?.pages
?.filter((p) => p?.results.length)
.flatMap(
- (p) =>
- p?.results.filter((r) => isJellyseerrMovieOrTvResult(r)) ?? [],
+ (p) => p?.results.filter((r) => isSeerrMovieOrTvResult(r)) ?? [],
),
"id",
) ?? [],
@@ -58,15 +57,12 @@ export default function page() {
const backdrops = useMemo(
() =>
- jellyseerrApi
+ seerrApi
? flatData.map((r) =>
- jellyseerrApi.imageProxy(
- r.backdropPath,
- "w1920_and_h800_multi_faces",
- ),
+ seerrApi.imageProxy(r.backdropPath, "w1920_and_h800_multi_faces"),
)
: [],
- [jellyseerrApi, flatData],
+ [seerrApi, flatData],
);
return (
@@ -91,7 +87,7 @@ export default function page() {
{name}
}
- renderItem={(item, _index) => }
+ renderItem={(item, _index) => }
/>
);
}
diff --git a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/page.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/page.tsx
similarity index 87%
rename from app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/page.tsx
rename to app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/page.tsx
index 2f0af594..901f5032 100644
--- a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/page.tsx
+++ b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/page.tsx
@@ -18,18 +18,18 @@ import { toast } from "sonner-native";
import { Button } from "@/components/Button";
import { Text } from "@/components/common/Text";
import { GenreTags } from "@/components/GenreTags";
-import Cast from "@/components/jellyseerr/Cast";
-import DetailFacts from "@/components/jellyseerr/DetailFacts";
-import RequestModal from "@/components/jellyseerr/RequestModal";
import { OverviewText } from "@/components/OverviewText";
import { ParallaxScrollView } from "@/components/ParallaxPage";
import { PlatformDropdown } from "@/components/PlatformDropdown";
-import { JellyserrRatings } from "@/components/Ratings";
-import JellyseerrSeasons from "@/components/series/JellyseerrSeasons";
+import { SeerrRatings } from "@/components/Ratings";
+import Cast from "@/components/seerr/Cast";
+import DetailFacts from "@/components/seerr/DetailFacts";
+import RequestModal from "@/components/seerr/RequestModal";
+import SeerrSeasons from "@/components/series/SeerrSeasons";
import { ItemActions } from "@/components/series/SeriesActions";
import useRouter from "@/hooks/useAppRouter";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
-import { useJellyseerrCanRequest } from "@/utils/_jellyseerr/useJellyseerrCanRequest";
+import { useSeerr } from "@/hooks/useSeerr";
+import { useSeerrCanRequest } from "@/utils/_seerr/useSeerrCanRequest";
import { ANIME_KEYWORD_ID } from "@/utils/jellyseerr/server/api/themoviedb/constants";
import {
type IssueType,
@@ -68,7 +68,7 @@ const Page: React.FC = () => {
} & Partial;
const navigation = useNavigation();
- const { jellyseerrApi, jellyseerrUser, requestMedia } = useJellyseerr();
+ const { seerrApi, seerrUser, requestMedia } = useSeerr();
const [issueType, setIssueType] = useState();
const [issueMessage, setIssueMessage] = useState();
@@ -83,8 +83,8 @@ const Page: React.FC = () => {
isLoading,
refetch,
} = useQuery({
- enabled: !!jellyseerrApi && !!result && !!result.id,
- queryKey: ["jellyseerr", "detail", mediaType, result.id],
+ enabled: !!seerrApi && !!result && !!result.id,
+ queryKey: ["seerr", "detail", mediaType, result.id],
staleTime: 0,
refetchOnMount: true,
refetchOnReconnect: true,
@@ -93,21 +93,18 @@ const Page: React.FC = () => {
refetchInterval: 0,
queryFn: async () => {
return mediaType === MediaType.MOVIE
- ? jellyseerrApi?.movieDetails(result.id!)
- : jellyseerrApi?.tvDetails(result.id!);
+ ? seerrApi?.movieDetails(result.id!)
+ : seerrApi?.tvDetails(result.id!);
},
});
const [canRequest, hasAdvancedRequestPermission] =
- useJellyseerrCanRequest(details);
+ useSeerrCanRequest(details);
const canManageRequests = useMemo(() => {
- if (!jellyseerrUser) return false;
- return hasPermission(
- Permission.MANAGE_REQUESTS,
- jellyseerrUser.permissions,
- );
- }, [jellyseerrUser]);
+ if (!seerrUser) return false;
+ return hasPermission(Permission.MANAGE_REQUESTS, seerrUser.permissions);
+ }, [seerrUser]);
const pendingRequest = useMemo(() => {
return details?.mediaInfo?.requests?.find(
@@ -119,27 +116,27 @@ const Page: React.FC = () => {
if (!pendingRequest?.id) return;
try {
- await jellyseerrApi?.approveRequest(pendingRequest.id);
- toast.success(t("jellyseerr.toasts.request_approved"));
+ await seerrApi?.approveRequest(pendingRequest.id);
+ toast.success(t("seerr.toasts.request_approved"));
refetch();
} catch (error) {
- toast.error(t("jellyseerr.toasts.failed_to_approve_request"));
+ toast.error(t("seerr.toasts.failed_to_approve_request"));
console.error("Failed to approve request:", error);
}
- }, [jellyseerrApi, pendingRequest, refetch, t]);
+ }, [seerrApi, pendingRequest, refetch, t]);
const handleDeclineRequest = useCallback(async () => {
if (!pendingRequest?.id) return;
try {
- await jellyseerrApi?.declineRequest(pendingRequest.id);
- toast.success(t("jellyseerr.toasts.request_declined"));
+ await seerrApi?.declineRequest(pendingRequest.id);
+ toast.success(t("seerr.toasts.request_declined"));
refetch();
} catch (error) {
- toast.error(t("jellyseerr.toasts.failed_to_decline_request"));
+ toast.error(t("seerr.toasts.failed_to_decline_request"));
console.error("Failed to decline request:", error);
}
- }, [jellyseerrApi, pendingRequest, refetch, t]);
+ }, [seerrApi, pendingRequest, refetch, t]);
const renderBackdrop = useCallback(
(props: BottomSheetBackdropProps) => (
@@ -154,7 +151,7 @@ const Page: React.FC = () => {
const submitIssue = useCallback(() => {
if (result.id && issueType && issueMessage && details) {
- jellyseerrApi
+ seerrApi
?.submitIssue(details.mediaInfo.id, Number(issueType), issueMessage)
.then(() => {
setIssueType(undefined);
@@ -162,7 +159,7 @@ const Page: React.FC = () => {
bottomSheetModalRef?.current?.close();
});
}
- }, [jellyseerrApi, details, result, issueType, issueMessage]);
+ }, [seerrApi, details, result, issueType, issueMessage]);
const handleIssueModalDismiss = useCallback(() => {
setIssueTypeDropdownOpen(false);
@@ -214,7 +211,7 @@ const Page: React.FC = () => {
const issueTypeOptionGroups = useMemo(
() => [
{
- title: t("jellyseerr.types"),
+ title: t("seerr.types"),
options: Object.entries(IssueTypeName)
.reverse()
.map(([key, value]) => ({
@@ -265,7 +262,7 @@ const Page: React.FC = () => {
height: "100%",
}}
source={{
- uri: jellyseerrApi?.imageProxy(
+ uri: seerrApi?.imageProxy(
result.backdropPath,
"w1920_and_h800_multi_faces",
),
@@ -295,7 +292,7 @@ const Page: React.FC = () => {
- {
/>
) : canRequest ? (
- {t("jellyseerr.request_button")}
+ {t("seerr.request_button")}
) : (
details?.mediaInfo?.jellyfinMediaId && (
@@ -353,7 +350,7 @@ const Page: React.FC = () => {
}}
>
- {t("jellyseerr.report_issue_button")}
+ {t("seerr.report_issue_button")}
)}
@@ -389,12 +386,12 @@ const Page: React.FC = () => {
- {t("jellyseerr.requested_by", {
+ {t("seerr.requested_by", {
user:
pendingRequest.requestedBy?.displayName ||
pendingRequest.requestedBy?.username ||
pendingRequest.requestedBy?.jellyfinUsername ||
- t("jellyseerr.unknown_user"),
+ t("seerr.unknown_user"),
})}
@@ -415,7 +412,7 @@ const Page: React.FC = () => {
borderStyle: "solid",
}}
>
- {t("jellyseerr.approve")}
+ {t("seerr.approve")}
{
borderStyle: "solid",
}}
>
- {t("jellyseerr.decline")}
+ {t("seerr.decline")}
@@ -442,7 +439,7 @@ const Page: React.FC = () => {
{mediaType === MediaType.TV && (
- {
- {t("jellyseerr.whats_wrong")}
+ {t("seerr.whats_wrong")}
- {t("jellyseerr.issue_type")}
+ {t("seerr.issue_type")}
{
{issueType
? IssueTypeName[issueType]
- : t("jellyseerr.select_an_issue")}
+ : t("seerr.select_an_issue")}
}
- title={t("jellyseerr.types")}
+ title={t("seerr.types")}
open={issueTypeDropdownOpen}
onOpenChange={setIssueTypeDropdownOpen}
/>
@@ -522,7 +519,7 @@ const Page: React.FC = () => {
maxLength={254}
style={{ color: "white" }}
clearButtonMode='always'
- placeholder={t("jellyseerr.describe_the_issue")}
+ placeholder={t("seerr.describe_the_issue")}
placeholderTextColor='#9CA3AF'
// Issue with multiline + Textinput inside a portal
// https://github.com/callstack/react-native-paper/issues/1668
@@ -532,7 +529,7 @@ const Page: React.FC = () => {
- {t("jellyseerr.submit_button")}
+ {t("seerr.submit_button")}
diff --git a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/person/[personId].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/person/[personId].tsx
similarity index 70%
rename from app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/person/[personId].tsx
rename to app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/person/[personId].tsx
index a29e1280..41b5ef8f 100644
--- a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/jellyseerr/person/[personId].tsx
+++ b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/seerr/person/[personId].tsx
@@ -5,31 +5,27 @@ import { orderBy, uniqBy } from "lodash";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Text } from "@/components/common/Text";
-import ParallaxSlideShow from "@/components/jellyseerr/ParallaxSlideShow";
import { OverviewText } from "@/components/OverviewText";
-import JellyseerrPoster from "@/components/posters/JellyseerrPoster";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import SeerrPoster from "@/components/posters/SeerrPoster";
+import ParallaxSlideShow from "@/components/seerr/ParallaxSlideShow";
+import { useSeerr } from "@/hooks/useSeerr";
import type { PersonCreditCast } from "@/utils/jellyseerr/server/models/Person";
-export default function page() {
+export default function PersonPage() {
const local = useLocalSearchParams();
const { t } = useTranslation();
- const {
- jellyseerrApi,
- jellyseerrRegion: region,
- jellyseerrLocale: locale,
- } = useJellyseerr();
+ const { seerrApi, seerrRegion: region, seerrLocale: locale } = useSeerr();
const { personId } = local as { personId: string };
const { data } = useQuery({
- queryKey: ["jellyseerr", "person", personId],
+ queryKey: ["seerr", "person", personId],
queryFn: async () => ({
- details: await jellyseerrApi?.personDetails(personId),
- combinedCredits: await jellyseerrApi?.personCombinedCredits(personId),
+ details: await seerrApi?.personDetails(personId),
+ combinedCredits: await seerrApi?.personCombinedCredits(personId),
}),
- enabled: !!jellyseerrApi && !!personId,
+ enabled: !!seerrApi && !!personId,
});
const castedRoles: PersonCreditCast[] = useMemo(
@@ -46,22 +42,19 @@ export default function page() {
);
const backdrops = useMemo(
() =>
- jellyseerrApi
+ seerrApi
? castedRoles.map((c) =>
- jellyseerrApi.imageProxy(
- c.backdropPath,
- "w1920_and_h800_multi_faces",
- ),
+ seerrApi.imageProxy(c.backdropPath, "w1920_and_h800_multi_faces"),
)
: [],
- [jellyseerrApi, data?.combinedCredits],
+ [seerrApi, data?.combinedCredits],
);
return (
item.id.toString()}
logo={
{data?.details?.name}
- {t("jellyseerr.born")}{" "}
+ {t("seerr.born")}{" "}
{data?.details?.birthday &&
new Date(data.details.birthday).toLocaleDateString(
`${locale}-${region}`,
@@ -103,7 +96,7 @@ export default function page() {
MainContent={() => (
)}
- renderItem={(item, _index) => }
+ renderItem={(item, _index) => }
/>
);
}
diff --git a/app/(auth)/(tabs)/(search)/_layout.tsx b/app/(auth)/(tabs)/(search)/_layout.tsx
index f4d34978..b008c04d 100644
--- a/app/(auth)/(tabs)/(search)/_layout.tsx
+++ b/app/(auth)/(tabs)/(search)/_layout.tsx
@@ -33,17 +33,17 @@ export default function SearchLayout() {
headerShadowVisible: false,
}}
/>
-
+
diff --git a/app/(auth)/(tabs)/(search)/index.tsx b/app/(auth)/(tabs)/(search)/index.tsx
index 751b1df1..cff07dd4 100644
--- a/app/(auth)/(tabs)/(search)/index.tsx
+++ b/app/(auth)/(tabs)/(search)/index.tsx
@@ -26,18 +26,18 @@ import { Input } from "@/components/common/Input";
import { Text } from "@/components/common/Text";
import { TouchableItemRouter } from "@/components/common/TouchableItemRouter";
import { ItemCardText } from "@/components/ItemCardText";
-import {
- JellyseerrSearchSort,
- JellyserrIndexPage,
-} from "@/components/jellyseerr/JellyseerrIndexPage";
import MoviePoster from "@/components/posters/MoviePoster";
import SeriesPoster from "@/components/posters/SeriesPoster";
import { DiscoverFilters } from "@/components/search/DiscoverFilters";
import { LoadingSkeleton } from "@/components/search/LoadingSkeleton";
import { SearchItemWrapper } from "@/components/search/SearchItemWrapper";
import { SearchTabButtons } from "@/components/search/SearchTabButtons";
+import {
+ SeerrIndexPage,
+ SeerrSearchSort,
+} from "@/components/seerr/SeerrIndexPage";
import useRouter from "@/hooks/useAppRouter";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import { useSeerr } from "@/hooks/useSeerr";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
import { eventBus } from "@/utils/eventBus";
@@ -55,7 +55,7 @@ const exampleSearches = [
"The Mandalorian",
];
-export default function search() {
+export default function SearchPage() {
const params = useLocalSearchParams();
const insets = useSafeAreaInsets();
const router = useRouter();
@@ -93,16 +93,11 @@ export default function search() {
const [api] = useAtom(apiAtom);
const { settings } = useSettings();
- const { jellyseerrApi } = useJellyseerr();
- const [jellyseerrOrderBy, setJellyseerrOrderBy] =
- useState(
- JellyseerrSearchSort[
- JellyseerrSearchSort.DEFAULT
- ] as unknown as JellyseerrSearchSort,
- );
- const [jellyseerrSortOrder, setJellyseerrSortOrder] = useState<
- "asc" | "desc"
- >("desc");
+ const { seerrApi } = useSeerr();
+ const [seerrOrderBy, setSeerrOrderBy] = useState(
+ SeerrSearchSort[SeerrSearchSort.DEFAULT] as unknown as SeerrSearchSort,
+ );
+ const [seerrSortOrder, setSeerrSortOrder] = useState<"asc" | "desc">("desc");
const searchEngine = useMemo(() => {
return settings?.searchEngine || "Jellyfin";
@@ -474,7 +469,7 @@ export default function search() {
className='flex flex-col'
style={{ paddingTop: Platform.OS === "android" ? 10 : 0 }}
>
- {jellyseerrApi && (
+ {seerrApi && (
)}
@@ -754,10 +749,10 @@ export default function search() {
/>
) : (
-
)}
diff --git a/assets/icons/jellyseerr-logo.svg b/assets/icons/seerr-logo.svg
similarity index 100%
rename from assets/icons/jellyseerr-logo.svg
rename to assets/icons/seerr-logo.svg
diff --git a/assets/images/jellyseerr.PNG b/assets/images/seerr.PNG
similarity index 100%
rename from assets/images/jellyseerr.PNG
rename to assets/images/seerr.PNG
diff --git a/components/IntroSheet.tsx b/components/IntroSheet.tsx
index ea1a23a2..7317b7e8 100644
--- a/components/IntroSheet.tsx
+++ b/components/IntroSheet.tsx
@@ -89,16 +89,16 @@ export const IntroSheet = forwardRef((_, ref) => {
- Jellyseerr
+ Seerr
- {t("home.intro.jellyseerr_feature_description")}
+ {t("home.intro.seerr_feature_description")}
diff --git a/components/Ratings.tsx b/components/Ratings.tsx
index 5741233f..e091c64c 100644
--- a/components/Ratings.tsx
+++ b/components/Ratings.tsx
@@ -4,7 +4,7 @@ import { useQuery } from "@tanstack/react-query";
import { Image } from "expo-image";
import { useMemo } from "react";
import { View, type ViewProps } from "react-native";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import { useSeerr } from "@/hooks/useSeerr";
import { MediaType } from "@/utils/jellyseerr/server/constants/media";
import type { MovieDetails } from "@/utils/jellyseerr/server/models/Movie";
import type {
@@ -55,23 +55,23 @@ export const Ratings: React.FC = ({ item, ...props }) => {
);
};
-export const JellyserrRatings: React.FC<{
+export const SeerrRatings: React.FC<{
result: MovieResult | TvResult | TvDetails | MovieDetails;
}> = ({ result }) => {
- const { jellyseerrApi, getMediaType } = useJellyseerr();
+ const { seerrApi, getMediaType } = useSeerr();
const mediaType = useMemo(() => getMediaType(result), [result]);
const { data, isLoading } = useQuery({
- queryKey: ["jellyseerr", result.id, mediaType, "ratings"],
+ queryKey: ["seerr", result.id, mediaType, "ratings"],
queryFn: async () => {
return mediaType === MediaType.MOVIE
- ? jellyseerrApi?.movieRatings(result.id)
- : jellyseerrApi?.tvRatings(result.id);
+ ? seerrApi?.movieRatings(result.id)
+ : seerrApi?.tvRatings(result.id);
},
staleTime: (5).minutesToMilliseconds(),
retry: false,
- enabled: !!jellyseerrApi,
+ enabled: !!seerrApi,
});
return (
diff --git a/components/common/JellyseerrItemRouter.tsx b/components/common/SeerrItemRouter.tsx
similarity index 92%
rename from components/common/JellyseerrItemRouter.tsx
rename to components/common/SeerrItemRouter.tsx
index f6878bc5..184ef490 100644
--- a/components/common/JellyseerrItemRouter.tsx
+++ b/components/common/SeerrItemRouter.tsx
@@ -21,7 +21,7 @@ interface Props extends TouchableOpacityProps {
mediaType: MediaType;
}
-export const TouchableJellyseerrRouter: React.FC> = ({
+export const TouchableSeerrRouter: React.FC> = ({
result,
mediaTitle,
releaseYear,
@@ -43,7 +43,7 @@ export const TouchableJellyseerrRouter: React.FC> = ({
if (!result) return;
router.push({
- pathname: `/(auth)/(tabs)/${from}/jellyseerr/page`,
+ pathname: `/(auth)/(tabs)/${from}/seerr/page`,
// @ts-expect-error
params: {
...result,
diff --git a/components/music/MusicAlbumCard.tsx b/components/music/MusicAlbumCard.tsx
index 1a747c8e..11e78610 100644
--- a/components/music/MusicAlbumCard.tsx
+++ b/components/music/MusicAlbumCard.tsx
@@ -23,10 +23,7 @@ export const MusicAlbumCard: React.FC = ({ album, width = 130 }) => {
);
const handlePress = useCallback(() => {
- router.push({
- pathname: "/music/album/[albumId]",
- params: { albumId: album.Id! },
- });
+ router.push(`/music/album/${album.Id}`);
}, [router, album.Id]);
return (
diff --git a/components/music/MusicAlbumRowCard.tsx b/components/music/MusicAlbumRowCard.tsx
index 6612a392..e794a793 100644
--- a/components/music/MusicAlbumRowCard.tsx
+++ b/components/music/MusicAlbumRowCard.tsx
@@ -24,10 +24,7 @@ export const MusicAlbumRowCard: React.FC = ({ album }) => {
);
const handlePress = useCallback(() => {
- router.push({
- pathname: "/music/album/[albumId]",
- params: { albumId: album.Id! },
- });
+ router.push(`/music/album/${album.Id}`);
}, [router, album.Id]);
return (
diff --git a/components/music/MusicArtistCard.tsx b/components/music/MusicArtistCard.tsx
index c98e3fce..a9bfc61b 100644
--- a/components/music/MusicArtistCard.tsx
+++ b/components/music/MusicArtistCard.tsx
@@ -25,10 +25,7 @@ export const MusicArtistCard: React.FC = ({ artist }) => {
);
const handlePress = useCallback(() => {
- router.push({
- pathname: "/music/artist/[artistId]",
- params: { artistId: artist.Id! },
- });
+ router.push(`/music/artist/${artist.Id}`);
}, [router, artist.Id]);
return (
diff --git a/components/music/MusicPlaylistCard.tsx b/components/music/MusicPlaylistCard.tsx
index 93caf7a4..50671715 100644
--- a/components/music/MusicPlaylistCard.tsx
+++ b/components/music/MusicPlaylistCard.tsx
@@ -61,10 +61,7 @@ export const MusicPlaylistCard: React.FC = ({ playlist }) => {
const hasDownloads = downloadStatus.downloaded > 0;
const handlePress = useCallback(() => {
- router.push({
- pathname: "/music/playlist/[playlistId]",
- params: { playlistId: playlist.Id! },
- });
+ router.push(`/music/playlist/${playlist.Id}`);
}, [router, playlist.Id]);
return (
diff --git a/components/music/TrackOptionsSheet.tsx b/components/music/TrackOptionsSheet.tsx
index a0b78472..b5de1379 100644
--- a/components/music/TrackOptionsSheet.tsx
+++ b/components/music/TrackOptionsSheet.tsx
@@ -197,10 +197,7 @@ export const TrackOptionsSheet: React.FC = ({
const artistId = track?.ArtistItems?.[0]?.Id;
if (artistId) {
setOpen(false);
- router.push({
- pathname: "/music/artist/[artistId]",
- params: { artistId },
- });
+ router.push(`/music/artist/${artistId}`);
}
}, [track?.ArtistItems, router, setOpen]);
@@ -208,10 +205,7 @@ export const TrackOptionsSheet: React.FC = ({
const albumId = track?.AlbumId || track?.ParentId;
if (albumId) {
setOpen(false);
- router.push({
- pathname: "/music/album/[albumId]",
- params: { albumId },
- });
+ router.push(`/music/album/${albumId}`);
}
}, [track?.AlbumId, track?.ParentId, router, setOpen]);
diff --git a/components/posters/JellyseerrPoster.tsx b/components/posters/SeerrPoster.tsx
similarity index 84%
rename from components/posters/JellyseerrPoster.tsx
rename to components/posters/SeerrPoster.tsx
index d7b1fcdb..399ac386 100644
--- a/components/posters/JellyseerrPoster.tsx
+++ b/components/posters/SeerrPoster.tsx
@@ -7,15 +7,15 @@ import Animated, {
useSharedValue,
withTiming,
} from "react-native-reanimated";
-import { TouchableJellyseerrRouter } from "@/components/common/JellyseerrItemRouter";
+import { TouchableSeerrRouter } from "@/components/common/SeerrItemRouter";
import { Text } from "@/components/common/Text";
import { Tag, Tags } from "@/components/GenreTags";
-import { textShadowStyle } from "@/components/jellyseerr/discover/GenericSlideCard";
-import JellyseerrMediaIcon from "@/components/jellyseerr/JellyseerrMediaIcon";
-import JellyseerrStatusIcon from "@/components/jellyseerr/JellyseerrStatusIcon";
+import { textShadowStyle } from "@/components/seerr/discover/GenericSlideCard";
+import SeerrMediaIcon from "@/components/seerr/SeerrMediaIcon";
+import SeerrStatusIcon from "@/components/seerr/SeerrStatusIcon";
import { Colors } from "@/constants/Colors";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
-import { useJellyseerrCanRequest } from "@/utils/_jellyseerr/useJellyseerrCanRequest";
+import { useSeerr } from "@/hooks/useSeerr";
+import { useSeerrCanRequest } from "@/utils/_seerr/useSeerrCanRequest";
import { MediaStatus } from "@/utils/jellyseerr/server/constants/media";
import type MediaRequest from "@/utils/jellyseerr/server/entity/MediaRequest";
import type { DownloadingItem } from "@/utils/jellyseerr/server/lib/downloadtracker";
@@ -34,13 +34,13 @@ interface Props extends ViewProps {
mediaRequest?: MediaRequest;
}
-const JellyseerrPoster: React.FC = ({
+const SeerrPoster: React.FC = ({
item,
horizontal,
showDownloadInfo,
mediaRequest,
}) => {
- const { jellyseerrApi, getTitle, getYear, getMediaType } = useJellyseerr();
+ const { seerrApi, getTitle, getYear, getMediaType } = useSeerr();
const loadingOpacity = useSharedValue(1);
const imageOpacity = useSharedValue(0);
const { t } = useTranslation();
@@ -56,16 +56,13 @@ const JellyseerrPoster: React.FC = ({
const backdropSrc = useMemo(
() =>
- jellyseerrApi?.imageProxy(
- item?.backdropPath,
- "w1920_and_h800_multi_faces",
- ),
- [item, jellyseerrApi, horizontal],
+ seerrApi?.imageProxy(item?.backdropPath, "w1920_and_h800_multi_faces"),
+ [item, seerrApi, horizontal],
);
const posterSrc = useMemo(
- () => jellyseerrApi?.imageProxy(item?.posterPath, "w300_and_h450_face"),
- [item, jellyseerrApi, horizontal],
+ () => seerrApi?.imageProxy(item?.posterPath, "w300_and_h450_face"),
+ [item, seerrApi, horizontal],
);
const title = useMemo(() => getTitle(item), [item]);
@@ -75,7 +72,7 @@ const JellyseerrPoster: React.FC = ({
const size = useMemo(() => (horizontal ? "h-28" : "w-28"), [horizontal]);
const ratio = useMemo(() => (horizontal ? "15/10" : "10/15"), [horizontal]);
- const [canRequest] = useJellyseerrCanRequest(item);
+ const [canRequest] = useSeerrCanRequest(item);
const is4k = useMemo(() => mediaRequest?.is4k === true, [mediaRequest]);
@@ -109,7 +106,7 @@ const JellyseerrPoster: React.FC = ({
second,
third,
fourth,
- t("home.settings.plugins.jellyseerr.plus_n_more", { n: rest.length }),
+ t("home.settings.plugins.seerr.plus_n_more", { n: rest.length }),
];
}
return seasons;
@@ -121,7 +118,7 @@ const JellyseerrPoster: React.FC = ({
}, [mediaRequest, is4k]);
return (
- = ({
)}
>
)}
-
-
@@ -201,8 +198,8 @@ const JellyseerrPoster: React.FC = ({
{releaseYear || ""}
-
+
);
};
-export default JellyseerrPoster;
+export default SeerrPoster;
diff --git a/components/search/DiscoverFilters.tsx b/components/search/DiscoverFilters.tsx
index 2e844c88..7a3a2a60 100644
--- a/components/search/DiscoverFilters.tsx
+++ b/components/search/DiscoverFilters.tsx
@@ -1,19 +1,19 @@
import { Button, ContextMenu, Host, Picker } from "@expo/ui/swift-ui";
import { Platform, View } from "react-native";
import { FilterButton } from "@/components/filters/FilterButton";
-import { JellyseerrSearchSort } from "@/components/jellyseerr/JellyseerrIndexPage";
+import { SeerrSearchSort } from "@/components/seerr/SeerrIndexPage";
interface DiscoverFiltersProps {
searchFilterId: string;
orderFilterId: string;
- jellyseerrOrderBy: JellyseerrSearchSort;
- setJellyseerrOrderBy: (value: JellyseerrSearchSort) => void;
- jellyseerrSortOrder: "asc" | "desc";
- setJellyseerrSortOrder: (value: "asc" | "desc") => void;
+ seerrOrderBy: SeerrSearchSort;
+ setSeerrOrderBy: (value: SeerrSearchSort) => void;
+ seerrSortOrder: "asc" | "desc";
+ setSeerrSortOrder: (value: "asc" | "desc") => void;
t: (key: string) => string;
}
-const sortOptions = Object.keys(JellyseerrSearchSort).filter((v) =>
+const sortOptions = Object.keys(SeerrSearchSort).filter((v) =>
Number.isNaN(Number(v)),
);
@@ -22,10 +22,10 @@ const orderOptions = ["asc", "desc"] as const;
export const DiscoverFilters: React.FC = ({
searchFilterId,
orderFilterId,
- jellyseerrOrderBy,
- setJellyseerrOrderBy,
- jellyseerrSortOrder,
- setJellyseerrSortOrder,
+ seerrOrderBy,
+ setSeerrOrderBy,
+ seerrSortOrder,
+ setSeerrSortOrder,
t,
}) => {
if (Platform.OS === "ios") {
@@ -52,16 +52,16 @@ export const DiscoverFilters: React.FC = ({
- t(`home.settings.plugins.jellyseerr.order_by.${item}`),
+ t(`home.settings.plugins.seerr.order_by.${item}`),
)}
variant='menu'
selectedIndex={sortOptions.indexOf(
- jellyseerrOrderBy as unknown as string,
+ seerrOrderBy as unknown as string,
)}
onOptionSelected={(event: any) => {
const index = event.nativeEvent.index;
- setJellyseerrOrderBy(
- sortOptions[index] as unknown as JellyseerrSearchSort,
+ setSeerrOrderBy(
+ sortOptions[index] as unknown as SeerrSearchSort,
);
}}
/>
@@ -69,10 +69,10 @@ export const DiscoverFilters: React.FC = ({
label={t("library.filters.sort_order")}
options={orderOptions.map((item) => t(`library.filters.${item}`))}
variant='menu'
- selectedIndex={orderOptions.indexOf(jellyseerrSortOrder)}
+ selectedIndex={orderOptions.indexOf(seerrSortOrder)}
onOptionSelected={(event: any) => {
const index = event.nativeEvent.index;
- setJellyseerrSortOrder(orderOptions[index]);
+ setSeerrSortOrder(orderOptions[index]);
}}
/>
@@ -86,17 +86,15 @@ export const DiscoverFilters: React.FC = ({
- Object.keys(JellyseerrSearchSort).filter((v) =>
- Number.isNaN(Number(v)),
- )
+ Object.keys(SeerrSearchSort).filter((v) => Number.isNaN(Number(v)))
}
- set={(value) => setJellyseerrOrderBy(value[0])}
- values={[jellyseerrOrderBy]}
+ set={(value) => setSeerrOrderBy(value[0])}
+ values={[seerrOrderBy]}
title={t("library.filters.sort_by")}
renderItemLabel={(item) =>
- t(`home.settings.plugins.jellyseerr.order_by.${item}`)
+ t(`home.settings.plugins.seerr.order_by.${item}`)
}
disableSearch={true}
/>
@@ -104,8 +102,8 @@ export const DiscoverFilters: React.FC = ({
id={orderFilterId}
queryKey='jellysearr_search'
queryFn={async () => ["asc", "desc"]}
- set={(value) => setJellyseerrSortOrder(value[0])}
- values={[jellyseerrSortOrder]}
+ set={(value) => setSeerrSortOrder(value[0])}
+ values={[seerrSortOrder]}
title={t("library.filters.sort_order")}
renderItemLabel={(item) => t(`library.filters.${item}`)}
disableSearch={true}
diff --git a/components/jellyseerr/Cast.tsx b/components/seerr/Cast.tsx
similarity index 88%
rename from components/jellyseerr/Cast.tsx
rename to components/seerr/Cast.tsx
index 99440bd8..9063ac65 100644
--- a/components/jellyseerr/Cast.tsx
+++ b/components/seerr/Cast.tsx
@@ -3,7 +3,7 @@ import type React from "react";
import { useTranslation } from "react-i18next";
import { View, type ViewProps } from "react-native";
import { Text } from "@/components/common/Text";
-import PersonPoster from "@/components/jellyseerr/PersonPoster";
+import PersonPoster from "@/components/seerr/PersonPoster";
import type { MovieDetails } from "@/utils/jellyseerr/server/models/Movie";
import type { TvDetails } from "@/utils/jellyseerr/server/models/Tv";
@@ -15,9 +15,7 @@ const CastSlide: React.FC<
details?.credits?.cast &&
details?.credits?.cast?.length > 0 && (
-
- {t("jellyseerr.cast")}
-
+ {t("seerr.cast")}
= ({
const DetailFacts: React.FC<
{ details?: MovieDetails | TvDetails } & ViewProps
> = ({ details, className, ...props }) => {
- const { jellyseerrRegion: region, jellyseerrLocale: locale } =
- useJellyseerr();
+ const { seerrRegion: region, seerrLocale: locale } = useSeerr();
const { t } = useTranslation();
const releases = useMemo(
@@ -138,21 +137,21 @@ const DetailFacts: React.FC<
return (
details && (
- {t("jellyseerr.details")}
+ {t("seerr.details")}
-
+
{details.keywords.some(
(keyword) => keyword.id === ANIME_KEYWORD_ID,
- ) && }
+ ) && }
(
{r.type === 3 ? (
@@ -178,16 +177,13 @@ const DetailFacts: React.FC<
))}
/>
-
-
-
-
-
+
+
+
+
+
(
@@ -196,17 +192,17 @@ const DetailFacts: React.FC<
))}
/>
n.name,
)}
/>
n.name)}
/>
s.name)}
/>
diff --git a/components/jellyseerr/GridSkeleton.tsx b/components/seerr/GridSkeleton.tsx
similarity index 100%
rename from components/jellyseerr/GridSkeleton.tsx
rename to components/seerr/GridSkeleton.tsx
diff --git a/components/jellyseerr/ParallaxSlideShow.tsx b/components/seerr/ParallaxSlideShow.tsx
similarity index 100%
rename from components/jellyseerr/ParallaxSlideShow.tsx
rename to components/seerr/ParallaxSlideShow.tsx
diff --git a/components/jellyseerr/PersonPoster.tsx b/components/seerr/PersonPoster.tsx
similarity index 78%
rename from components/jellyseerr/PersonPoster.tsx
rename to components/seerr/PersonPoster.tsx
index e926b093..821cf52c 100644
--- a/components/jellyseerr/PersonPoster.tsx
+++ b/components/seerr/PersonPoster.tsx
@@ -4,7 +4,7 @@ import { TouchableOpacity, View, type ViewProps } from "react-native";
import { Text } from "@/components/common/Text";
import Poster from "@/components/posters/Poster";
import useRouter from "@/hooks/useAppRouter";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import { useSeerr } from "@/hooks/useSeerr";
interface Props {
id: string;
@@ -20,7 +20,7 @@ const PersonPoster: React.FC = ({
subName,
...props
}) => {
- const { jellyseerrApi } = useJellyseerr();
+ const { seerrApi } = useSeerr();
const router = useRouter();
const segments = useSegments();
const from = (segments as string[])[2] || "(home)";
@@ -28,14 +28,12 @@ const PersonPoster: React.FC = ({
if (from === "(home)" || from === "(search)" || from === "(libraries)")
return (
- router.push(`/(auth)/(tabs)/${from}/jellyseerr/person/${id}`)
- }
+ onPress={() => router.push(`/(auth)/(tabs)/${from}/seerr/person/${id}`)}
>
{name}
{subName && {subName} }
diff --git a/components/jellyseerr/RequestModal.tsx b/components/seerr/RequestModal.tsx
similarity index 89%
rename from components/jellyseerr/RequestModal.tsx
rename to components/seerr/RequestModal.tsx
index 5bc44177..97e04619 100644
--- a/components/jellyseerr/RequestModal.tsx
+++ b/components/seerr/RequestModal.tsx
@@ -12,7 +12,7 @@ import { View, type ViewProps } from "react-native";
import { Button } from "@/components/Button";
import { Text } from "@/components/common/Text";
import { PlatformDropdown } from "@/components/PlatformDropdown";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import { useSeerr } from "@/hooks/useSeerr";
import type {
QualityProfile,
RootFolder,
@@ -41,11 +41,11 @@ const RequestModal = forwardRef<
{ id, title, requestBody, type, isAnime = false, onRequested, onDismiss },
ref,
) => {
- const { jellyseerrApi, jellyseerrUser, requestMedia } = useJellyseerr();
+ const { seerrApi, seerrUser, requestMedia } = useSeerr();
const [requestOverrides, setRequestOverrides] = useState({
mediaId: Number(id),
mediaType: type,
- userId: jellyseerrUser?.id,
+ userId: seerrUser?.id,
});
const [qualityProfileOpen, setQualityProfileOpen] = useState(false);
@@ -65,18 +65,17 @@ const RequestModal = forwardRef<
}, [onDismiss]);
const { data: serviceSettings } = useQuery({
- queryKey: ["jellyseerr", "request", type, "service"],
+ queryKey: ["seerr", "request", type, "service"],
queryFn: async () =>
- jellyseerrApi?.service(type === "movie" ? "radarr" : "sonarr"),
- enabled: !!jellyseerrApi && !!jellyseerrUser,
+ seerrApi?.service(type === "movie" ? "radarr" : "sonarr"),
+ enabled: !!seerrApi && !!seerrUser,
refetchOnMount: "always",
});
const { data: users } = useQuery({
- queryKey: ["jellyseerr", "users"],
- queryFn: async () =>
- jellyseerrApi?.user({ take: 1000, sort: "displayname" }),
- enabled: !!jellyseerrApi && !!jellyseerrUser,
+ queryKey: ["seerr", "users"],
+ queryFn: async () => seerrApi?.user({ take: 1000, sort: "displayname" }),
+ enabled: !!seerrApi && !!seerrUser,
refetchOnMount: "always",
});
@@ -87,7 +86,7 @@ const RequestModal = forwardRef<
const { data: defaultServiceDetails } = useQuery({
queryKey: [
- "jellyseerr",
+ "seerr",
"request",
type,
"service",
@@ -99,12 +98,12 @@ const RequestModal = forwardRef<
...prev,
serverId: defaultService?.id,
}));
- return jellyseerrApi?.serviceDetails(
+ return seerrApi?.serviceDetails(
type === "movie" ? "radarr" : "sonarr",
defaultService!.id,
);
},
- enabled: !!jellyseerrApi && !!jellyseerrUser && !!defaultService,
+ enabled: !!seerrApi && !!seerrUser && !!defaultService,
refetchOnMount: "always",
});
@@ -148,9 +147,9 @@ const RequestModal = forwardRef<
return undefined;
}
if (requestBody.seasons.length > 1) {
- return t("jellyseerr.season_all");
+ return t("seerr.season_all");
}
- return t("jellyseerr.season_number", {
+ return t("seerr.season_number", {
season_number: requestBody.seasons[0],
});
}, [requestBody?.seasons]);
@@ -245,8 +244,7 @@ const RequestModal = forwardRef<
type: "radio" as const,
label: user.displayName,
value: user.id.toString(),
- selected:
- (requestOverrides.userId || jellyseerrUser?.id) === user.id,
+ selected: (requestOverrides.userId || seerrUser?.id) === user.id,
onPress: () =>
setRequestOverrides((prev) => ({
...prev,
@@ -255,7 +253,7 @@ const RequestModal = forwardRef<
})) || [],
},
],
- [users, jellyseerrUser, requestOverrides.userId],
+ [users, seerrUser, requestOverrides.userId],
);
const request = useCallback(() => {
@@ -268,7 +266,7 @@ const RequestModal = forwardRef<
...requestOverrides,
};
- writeDebugLog("Sending Jellyseerr advanced request", body);
+ writeDebugLog("Sending Seerr advanced request", body);
requestMedia(
seasonTitle ? `${title}, ${seasonTitle}` : title,
@@ -308,7 +306,7 @@ const RequestModal = forwardRef<
- {t("jellyseerr.advanced")}
+ {t("seerr.advanced")}
{seasonTitle && (
{seasonTitle}
@@ -319,7 +317,7 @@ const RequestModal = forwardRef<
<>
- {t("jellyseerr.quality_profile")}
+ {t("seerr.quality_profile")}
}
- title={t("jellyseerr.quality_profile")}
+ title={t("seerr.quality_profile")}
open={qualityProfileOpen}
onOpenChange={setQualityProfileOpen}
/>
@@ -343,7 +341,7 @@ const RequestModal = forwardRef<
- {t("jellyseerr.root_folder")}
+ {t("seerr.root_folder")}
}
- title={t("jellyseerr.root_folder")}
+ title={t("seerr.root_folder")}
open={rootFolderOpen}
onOpenChange={setRootFolderOpen}
/>
@@ -376,7 +374,7 @@ const RequestModal = forwardRef<
- {t("jellyseerr.tags")}
+ {t("seerr.tags")}
}
- title={t("jellyseerr.tags")}
+ title={t("seerr.tags")}
open={tagsOpen}
onOpenChange={setTagsOpen}
/>
@@ -403,7 +401,7 @@ const RequestModal = forwardRef<
- {t("jellyseerr.request_as")}
+ {t("seerr.request_as")}
u.id ===
- (requestOverrides.userId || jellyseerrUser?.id),
- )?.displayName || jellyseerrUser!.displayName}
+ (requestOverrides.userId || seerrUser?.id),
+ )?.displayName || seerrUser!.displayName}
}
- title={t("jellyseerr.request_as")}
+ title={t("seerr.request_as")}
open={usersOpen}
onOpenChange={setUsersOpen}
/>
@@ -427,7 +425,7 @@ const RequestModal = forwardRef<
)}
- {t("jellyseerr.request_button")}
+ {t("seerr.request_button")}
diff --git a/components/jellyseerr/JellyseerrIndexPage.tsx b/components/seerr/SeerrIndexPage.tsx
similarity index 65%
rename from components/jellyseerr/JellyseerrIndexPage.tsx
rename to components/seerr/SeerrIndexPage.tsx
index 42fd223b..6ef54fa6 100644
--- a/components/jellyseerr/JellyseerrIndexPage.tsx
+++ b/components/seerr/SeerrIndexPage.tsx
@@ -8,8 +8,8 @@ import {
useSharedValue,
withTiming,
} from "react-native-reanimated";
-import Discover from "@/components/jellyseerr/discover/Discover";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import Discover from "@/components/seerr/discover/Discover";
+import { useSeerr } from "@/hooks/useSeerr";
import { MediaType } from "@/utils/jellyseerr/server/constants/media";
import type {
MovieResult,
@@ -18,57 +18,57 @@ import type {
} from "@/utils/jellyseerr/server/models/Search";
import { useReactNavigationQuery } from "@/utils/useReactNavigationQuery";
import { Text } from "../common/Text";
-import JellyseerrPoster from "../posters/JellyseerrPoster";
+import SeerrPoster from "../posters/SeerrPoster";
import { LoadingSkeleton } from "../search/LoadingSkeleton";
import { SearchItemWrapper } from "../search/SearchItemWrapper";
import PersonPoster from "./PersonPoster";
interface Props extends ViewProps {
searchQuery: string;
- sortType?: JellyseerrSearchSort;
+ sortType?: SeerrSearchSort;
order?: "asc" | "desc";
}
-export enum JellyseerrSearchSort {
+export enum SeerrSearchSort {
DEFAULT = 0,
VOTE_COUNT_AND_AVERAGE = 1,
POPULARITY = 2,
}
-export const JellyserrIndexPage: React.FC = ({
+export const SeerrIndexPage: React.FC = ({
searchQuery,
sortType,
order,
}) => {
- const { jellyseerrApi } = useJellyseerr();
+ const { seerrApi } = useSeerr();
const opacity = useSharedValue(1);
const { t } = useTranslation();
const {
- data: jellyseerrDiscoverSettings,
+ data: seerrDiscoverSettings,
isFetching: f1,
isLoading: l1,
} = useReactNavigationQuery({
- queryKey: ["search", "jellyseerr", "discoverSettings", searchQuery],
- queryFn: async () => jellyseerrApi?.discoverSettings(),
- enabled: !!jellyseerrApi && searchQuery.length === 0,
+ queryKey: ["search", "seerr", "discoverSettings", searchQuery],
+ queryFn: async () => seerrApi?.discoverSettings(),
+ enabled: !!seerrApi && searchQuery.length === 0,
});
const {
- data: jellyseerrResults,
+ data: seerrResults,
isFetching: f2,
isLoading: l2,
} = useReactNavigationQuery({
- queryKey: ["search", "jellyseerr", "results", searchQuery],
+ queryKey: ["search", "seerr", "results", searchQuery],
queryFn: async () => {
const params = {
query: new URLSearchParams(searchQuery || "").toString(),
};
return await Promise.all([
- jellyseerrApi?.search({ ...params, page: 1 }),
- jellyseerrApi?.search({ ...params, page: 2 }),
- jellyseerrApi?.search({ ...params, page: 3 }),
- jellyseerrApi?.search({ ...params, page: 4 }),
+ seerrApi?.search({ ...params, page: 1 }),
+ seerrApi?.search({ ...params, page: 2 }),
+ seerrApi?.search({ ...params, page: 3 }),
+ seerrApi?.search({ ...params, page: 4 }),
]).then((all) =>
uniqBy(
all.flatMap((v) => v?.results || []),
@@ -76,7 +76,7 @@ export const JellyserrIndexPage: React.FC = ({
),
);
},
- enabled: !!jellyseerrApi && searchQuery.length > 0,
+ enabled: !!seerrApi && searchQuery.length > 0,
});
useAnimatedReaction(
@@ -92,20 +92,20 @@ export const JellyserrIndexPage: React.FC = ({
const sortingType = useMemo(() => {
if (!sortType) return;
- switch (Number(JellyseerrSearchSort[sortType])) {
- case JellyseerrSearchSort.VOTE_COUNT_AND_AVERAGE:
+ switch (Number(SeerrSearchSort[sortType])) {
+ case SeerrSearchSort.VOTE_COUNT_AND_AVERAGE:
return ["voteCount", "voteAverage"];
- case JellyseerrSearchSort.POPULARITY:
+ case SeerrSearchSort.POPULARITY:
return ["voteCount", "popularity"];
default:
return undefined;
}
}, [sortType, order]);
- const jellyseerrMovieResults = useMemo(
+ const seerrMovieResults = useMemo(
() =>
orderBy(
- jellyseerrResults?.filter(
+ seerrResults?.filter(
(r) => r.mediaType === MediaType.MOVIE,
) as MovieResult[],
sortingType || [
@@ -113,41 +113,37 @@ export const JellyserrIndexPage: React.FC = ({
],
order || "desc",
),
- [jellyseerrResults, sortingType, order],
+ [seerrResults, sortingType, order],
);
- const jellyseerrTvResults = useMemo(
+ const seerrTvResults = useMemo(
() =>
orderBy(
- jellyseerrResults?.filter(
- (r) => r.mediaType === MediaType.TV,
- ) as TvResult[],
+ seerrResults?.filter((r) => r.mediaType === MediaType.TV) as TvResult[],
sortingType || [
(t) => t.name.toLowerCase() === searchQuery.toLowerCase(),
],
order || "desc",
),
- [jellyseerrResults, sortingType, order],
+ [seerrResults, sortingType, order],
);
- const jellyseerrPersonResults = useMemo(
+ const seerrPersonResults = useMemo(
() =>
orderBy(
- jellyseerrResults?.filter(
- (r) => r.mediaType === "person",
- ) as PersonResult[],
+ seerrResults?.filter((r) => r.mediaType === "person") as PersonResult[],
sortingType || [
(p) => p.name.toLowerCase() === searchQuery.toLowerCase(),
],
order || "desc",
),
- [jellyseerrResults, sortingType, order],
+ [seerrResults, sortingType, order],
);
if (!searchQuery.length)
return (
-
+
);
@@ -155,9 +151,9 @@ export const JellyserrIndexPage: React.FC = ({
- {!jellyseerrMovieResults?.length &&
- !jellyseerrTvResults?.length &&
- !jellyseerrPersonResults?.length &&
+ {!seerrMovieResults?.length &&
+ !seerrTvResults?.length &&
+ !seerrPersonResults?.length &&
!f1 &&
!f2 &&
!l1 &&
@@ -175,21 +171,21 @@ export const JellyserrIndexPage: React.FC = ({
(
-
+
)}
/>
(
-
+
)}
/>
(
= ({ mediaType, className, ...props }) => {
+const SeerrMediaIcon: React.FC<{ mediaType: "tv" | "movie" } & ViewProps> = ({
+ mediaType,
+ className,
+ ...props
+}) => {
const style = useMemo(
() =>
mediaType === MediaType.MOVIE
@@ -29,4 +31,4 @@ const JellyseerrMediaIcon: React.FC<
);
};
-export default JellyseerrMediaIcon;
+export default SeerrMediaIcon;
diff --git a/components/jellyseerr/JellyseerrStatusIcon.tsx b/components/seerr/SeerrStatusIcon.tsx
similarity index 96%
rename from components/jellyseerr/JellyseerrStatusIcon.tsx
rename to components/seerr/SeerrStatusIcon.tsx
index e9b37af5..414fea62 100644
--- a/components/jellyseerr/JellyseerrStatusIcon.tsx
+++ b/components/seerr/SeerrStatusIcon.tsx
@@ -9,7 +9,7 @@ interface Props {
onPress?: () => void;
}
-const JellyseerrStatusIcon: React.FC = ({
+const SeerrStatusIcon: React.FC = ({
mediaStatus,
showRequestIcon,
onPress,
@@ -74,4 +74,4 @@ const JellyseerrStatusIcon: React.FC = ({
);
};
-export default JellyseerrStatusIcon;
+export default SeerrStatusIcon;
diff --git a/components/jellyseerr/discover/CompanySlide.tsx b/components/seerr/discover/CompanySlide.tsx
similarity index 74%
rename from components/jellyseerr/discover/CompanySlide.tsx
rename to components/seerr/discover/CompanySlide.tsx
index abba1d31..58e614fa 100644
--- a/components/jellyseerr/discover/CompanySlide.tsx
+++ b/components/seerr/discover/CompanySlide.tsx
@@ -2,10 +2,10 @@ import { useSegments } from "expo-router";
import type React from "react";
import { useCallback } from "react";
import { TouchableOpacity, type ViewProps } from "react-native";
-import GenericSlideCard from "@/components/jellyseerr/discover/GenericSlideCard";
-import Slide, { type SlideProps } from "@/components/jellyseerr/discover/Slide";
+import GenericSlideCard from "@/components/seerr/discover/GenericSlideCard";
+import Slide, { type SlideProps } from "@/components/seerr/discover/Slide";
import useRouter from "@/hooks/useAppRouter";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import { useSeerr } from "@/hooks/useSeerr";
import {
COMPANY_LOGO_IMAGE_FILTER,
type Network,
@@ -16,14 +16,14 @@ const CompanySlide: React.FC<
{ data: Network[] | Studio[] } & SlideProps & ViewProps
> = ({ slide, data, ...props }) => {
const segments = useSegments();
- const { jellyseerrApi } = useJellyseerr();
+ const { seerrApi } = useSeerr();
const router = useRouter();
const from = (segments as string[])[2] || "(home)";
const navigate = useCallback(
({ id, image, name }: Network | Studio) =>
router.push({
- pathname: `/(auth)/(tabs)/${from}/jellyseerr/company/${id}` as any,
+ pathname: `/(auth)/(tabs)/${from}/seerr/company/${id}` as any,
params: { id, image, name, type: slide.type },
}),
[slide],
@@ -40,10 +40,7 @@ const CompanySlide: React.FC<
)}
diff --git a/components/jellyseerr/discover/Discover.tsx b/components/seerr/discover/Discover.tsx
similarity index 87%
rename from components/jellyseerr/discover/Discover.tsx
rename to components/seerr/discover/Discover.tsx
index 67e5bf3c..7a926eec 100644
--- a/components/jellyseerr/discover/Discover.tsx
+++ b/components/seerr/discover/Discover.tsx
@@ -2,10 +2,10 @@ import { sortBy } from "lodash";
import type React from "react";
import { useMemo } from "react";
import { View } from "react-native";
-import CompanySlide from "@/components/jellyseerr/discover/CompanySlide";
-import GenreSlide from "@/components/jellyseerr/discover/GenreSlide";
-import MovieTvSlide from "@/components/jellyseerr/discover/MovieTvSlide";
-import RecentRequestsSlide from "@/components/jellyseerr/discover/RecentRequestsSlide";
+import CompanySlide from "@/components/seerr/discover/CompanySlide";
+import GenreSlide from "@/components/seerr/discover/GenreSlide";
+import MovieTvSlide from "@/components/seerr/discover/MovieTvSlide";
+import RecentRequestsSlide from "@/components/seerr/discover/RecentRequestsSlide";
import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover";
import type DiscoverSlider from "@/utils/jellyseerr/server/entity/DiscoverSlider";
import { networks } from "@/utils/jellyseerr/src/components/Discover/NetworkSlider";
diff --git a/components/jellyseerr/discover/GenericSlideCard.tsx b/components/seerr/discover/GenericSlideCard.tsx
similarity index 100%
rename from components/jellyseerr/discover/GenericSlideCard.tsx
rename to components/seerr/discover/GenericSlideCard.tsx
diff --git a/components/jellyseerr/discover/GenreSlide.tsx b/components/seerr/discover/GenreSlide.tsx
similarity index 78%
rename from components/jellyseerr/discover/GenreSlide.tsx
rename to components/seerr/discover/GenreSlide.tsx
index 31248540..e65534d0 100644
--- a/components/jellyseerr/discover/GenreSlide.tsx
+++ b/components/seerr/discover/GenreSlide.tsx
@@ -3,39 +3,39 @@ import { useSegments } from "expo-router";
import type React from "react";
import { useCallback } from "react";
import { TouchableOpacity, type ViewProps } from "react-native";
-import GenericSlideCard from "@/components/jellyseerr/discover/GenericSlideCard";
-import Slide, { type SlideProps } from "@/components/jellyseerr/discover/Slide";
+import GenericSlideCard from "@/components/seerr/discover/GenericSlideCard";
+import Slide, { type SlideProps } from "@/components/seerr/discover/Slide";
import useRouter from "@/hooks/useAppRouter";
-import { Endpoints, useJellyseerr } from "@/hooks/useJellyseerr";
+import { Endpoints, useSeerr } from "@/hooks/useSeerr";
import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover";
import type { GenreSliderItem } from "@/utils/jellyseerr/server/interfaces/api/discoverInterfaces";
import { genreColorMap } from "@/utils/jellyseerr/src/components/Discover/constants";
const GenreSlide: React.FC = ({ slide, ...props }) => {
const segments = useSegments();
- const { jellyseerrApi } = useJellyseerr();
+ const { seerrApi } = useSeerr();
const router = useRouter();
const from = (segments as string[])[2] || "(home)";
const navigate = useCallback(
(genre: GenreSliderItem) =>
router.push({
- pathname: `/(auth)/(tabs)/${from}/jellyseerr/genre/${genre.id}` as any,
+ pathname: `/(auth)/(tabs)/${from}/seerr/genre/${genre.id}` as any,
params: { type: slide.type, name: genre.name },
}),
[slide],
);
const { data } = useQuery({
- queryKey: ["jellyseerr", "discover", slide.type, slide.id],
+ queryKey: ["seerr", "discover", slide.type, slide.id],
queryFn: async () => {
- return jellyseerrApi?.getGenreSliders(
+ return seerrApi?.getGenreSliders(
slide.type === DiscoverSliderType.MOVIE_GENRES
? Endpoints.MOVIE
: Endpoints.TV,
);
},
- enabled: !!jellyseerrApi,
+ enabled: !!seerrApi,
});
return (
@@ -53,7 +53,7 @@ const GenreSlide: React.FC = ({ slide, ...props }) => {
title={item.name}
colors={["transparent", "transparent"]}
contentFit={"cover"}
- url={jellyseerrApi?.imageProxy(
+ url={seerrApi?.imageProxy(
item.backdrops?.[0],
`w780_filter(duotone,${
genreColorMap[item.id] ?? genreColorMap[0]
diff --git a/components/jellyseerr/discover/MovieTvSlide.tsx b/components/seerr/discover/MovieTvSlide.tsx
similarity index 76%
rename from components/jellyseerr/discover/MovieTvSlide.tsx
rename to components/seerr/discover/MovieTvSlide.tsx
index a82f48a3..6291bab1 100644
--- a/components/jellyseerr/discover/MovieTvSlide.tsx
+++ b/components/seerr/discover/MovieTvSlide.tsx
@@ -3,23 +3,19 @@ import { uniqBy } from "lodash";
import type React from "react";
import { useMemo } from "react";
import type { ViewProps } from "react-native";
-import Slide, { type SlideProps } from "@/components/jellyseerr/discover/Slide";
-import JellyseerrPoster from "@/components/posters/JellyseerrPoster";
-import {
- type DiscoverEndpoint,
- Endpoints,
- useJellyseerr,
-} from "@/hooks/useJellyseerr";
+import SeerrPoster from "@/components/posters/SeerrPoster";
+import Slide, { type SlideProps } from "@/components/seerr/discover/Slide";
+import { type DiscoverEndpoint, Endpoints, useSeerr } from "@/hooks/useSeerr";
import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover";
const MovieTvSlide: React.FC = ({
slide,
...props
}) => {
- const { jellyseerrApi, isJellyseerrMovieOrTvResult } = useJellyseerr();
+ const { seerrApi, isSeerrMovieOrTvResult } = useSeerr();
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
- queryKey: ["jellyseerr", "discover", slide.id],
+ queryKey: ["seerr", "discover", slide.id],
queryFn: async ({ pageParam }) => {
let endpoint: DiscoverEndpoint | undefined;
let params: any = {
@@ -50,13 +46,13 @@ const MovieTvSlide: React.FC = ({
break;
}
- return endpoint ? jellyseerrApi?.discover(endpoint, params) : null;
+ return endpoint ? seerrApi?.discover(endpoint, params) : null;
},
initialPageParam: 1,
getNextPageParam: (lastPage, pages) =>
(lastPage?.page || pages?.findLast((p) => p?.results.length)?.page || 1) +
1,
- enabled: !!jellyseerrApi,
+ enabled: !!seerrApi,
staleTime: 0,
});
@@ -65,9 +61,7 @@ const MovieTvSlide: React.FC = ({
uniqBy(
data?.pages
?.filter((p) => p?.results.length)
- .flatMap((p) =>
- p?.results.filter((r) => isJellyseerrMovieOrTvResult(r)),
- ),
+ .flatMap((p) => p?.results.filter((r) => isSeerrMovieOrTvResult(r))),
"id",
),
[data],
@@ -84,7 +78,7 @@ const MovieTvSlide: React.FC = ({
onEndReached={() => {
if (hasNextPage) fetchNextPage();
}}
- renderItem={(item) => }
+ renderItem={(item) => }
/>
)
);
diff --git a/components/jellyseerr/discover/RecentRequestsSlide.tsx b/components/seerr/discover/RecentRequestsSlide.tsx
similarity index 70%
rename from components/jellyseerr/discover/RecentRequestsSlide.tsx
rename to components/seerr/discover/RecentRequestsSlide.tsx
index 71b5fc21..12cdef40 100644
--- a/components/jellyseerr/discover/RecentRequestsSlide.tsx
+++ b/components/seerr/discover/RecentRequestsSlide.tsx
@@ -1,9 +1,9 @@
import { useQuery } from "@tanstack/react-query";
import type React from "react";
import type { ViewProps } from "react-native";
-import Slide, { type SlideProps } from "@/components/jellyseerr/discover/Slide";
-import JellyseerrPoster from "@/components/posters/JellyseerrPoster";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import SeerrPoster from "@/components/posters/SeerrPoster";
+import Slide, { type SlideProps } from "@/components/seerr/discover/Slide";
+import { useSeerr } from "@/hooks/useSeerr";
import { MediaType } from "@/utils/jellyseerr/server/constants/media";
import type MediaRequest from "@/utils/jellyseerr/server/entity/MediaRequest";
import type { NonFunctionProperties } from "@/utils/jellyseerr/server/interfaces/api/common";
@@ -16,36 +16,36 @@ type ExtendedMediaRequest = NonFunctionProperties & {
const RequestCard: React.FC<{ request: ExtendedMediaRequest }> = ({
request,
}) => {
- const { jellyseerrApi } = useJellyseerr();
+ const { seerrApi } = useSeerr();
const { data: details } = useQuery({
queryKey: [
- "jellyseerr",
+ "seerr",
"detail",
request.media.mediaType,
request.media.tmdbId,
],
queryFn: async () => {
return request.media.mediaType === MediaType.MOVIE
- ? jellyseerrApi?.movieDetails(request.media.tmdbId)
- : jellyseerrApi?.tvDetails(request.media.tmdbId);
+ ? seerrApi?.movieDetails(request.media.tmdbId)
+ : seerrApi?.tvDetails(request.media.tmdbId);
},
- enabled: !!jellyseerrApi,
+ enabled: !!seerrApi,
refetchOnMount: true,
staleTime: 0,
});
const { data: refreshedRequest } = useQuery({
- queryKey: ["jellyseerr", "requests", request.media.mediaType, request.id],
- queryFn: async () => jellyseerrApi?.getRequest(request.id),
- enabled: !!jellyseerrApi,
+ queryKey: ["seerr", "requests", request.media.mediaType, request.id],
+ queryFn: async () => seerrApi?.getRequest(request.id),
+ enabled: !!seerrApi,
refetchOnMount: true,
refetchInterval: 5000,
staleTime: 0,
});
return (
- = ({
slide,
...props
}) => {
- const { jellyseerrApi } = useJellyseerr();
+ const { seerrApi } = useSeerr();
const { data: requests } = useQuery({
- queryKey: ["jellyseerr", "recent_requests"],
- queryFn: async () => jellyseerrApi?.requests(),
- enabled: !!jellyseerrApi,
+ queryKey: ["seerr", "recent_requests"],
+ queryFn: async () => seerrApi?.requests(),
+ enabled: !!seerrApi,
refetchOnMount: true,
staleTime: 0,
});
diff --git a/components/jellyseerr/discover/Slide.tsx b/components/seerr/discover/Slide.tsx
similarity index 100%
rename from components/jellyseerr/discover/Slide.tsx
rename to components/seerr/discover/Slide.tsx
diff --git a/components/series/JellyseerrSeasons.tsx b/components/series/SeerrSeasons.tsx
similarity index 88%
rename from components/series/JellyseerrSeasons.tsx
rename to components/series/SeerrSeasons.tsx
index 3b130683..ff1f0b6d 100644
--- a/components/series/JellyseerrSeasons.tsx
+++ b/components/series/SeerrSeasons.tsx
@@ -14,11 +14,11 @@ import { Alert, TouchableOpacity, View } from "react-native";
import { HorizontalScroll } from "@/components/common/HorizontalScroll";
import { Text } from "@/components/common/Text";
import { Tags } from "@/components/GenreTags";
-import { dateOpts } from "@/components/jellyseerr/DetailFacts";
-import { textShadowStyle } from "@/components/jellyseerr/discover/GenericSlideCard";
-import JellyseerrStatusIcon from "@/components/jellyseerr/JellyseerrStatusIcon";
import { RoundButton } from "@/components/RoundButton";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import { dateOpts } from "@/components/seerr/DetailFacts";
+import { textShadowStyle } from "@/components/seerr/discover/GenericSlideCard";
+import SeerrStatusIcon from "@/components/seerr/SeerrStatusIcon";
+import { useSeerr } from "@/hooks/useSeerr";
import {
MediaStatus,
MediaType,
@@ -30,15 +30,15 @@ import type { MovieDetails } from "@/utils/jellyseerr/server/models/Movie";
import type { TvDetails } from "@/utils/jellyseerr/server/models/Tv";
import { Loader } from "../Loader";
-const JellyseerrSeasonEpisodes: React.FC<{
+const SeerrSeasonEpisodes: React.FC<{
details: TvDetails;
seasonNumber: number;
}> = ({ details, seasonNumber }) => {
- const { jellyseerrApi } = useJellyseerr();
+ const { seerrApi } = useSeerr();
const { data: seasonWithEpisodes, isLoading } = useQuery({
- queryKey: ["jellyseerr", details.id, "season", seasonNumber],
- queryFn: async () => jellyseerrApi?.tvSeason(details.id, seasonNumber),
+ queryKey: ["seerr", details.id, "season", seasonNumber],
+ queryFn: async () => seerrApi?.tvSeason(details.id, seasonNumber),
enabled: details.seasons.filter((s) => s.seasonNumber !== 0).length > 0,
});
@@ -57,11 +57,7 @@ const JellyseerrSeasonEpisodes: React.FC<{
};
const RenderItem = ({ item }: any) => {
- const {
- jellyseerrApi,
- jellyseerrRegion: region,
- jellyseerrLocale: locale,
- } = useJellyseerr();
+ const { seerrApi, seerrRegion: region, seerrLocale: locale } = useSeerr();
const [imageError, setImageError] = useState(false);
const upcomingAirDate = useMemo(() => {
@@ -83,7 +79,7 @@ const RenderItem = ({ item }: any) => {
key={item.id}
id={item.id}
source={{
- uri: jellyseerrApi?.imageProxy(item.stillPath),
+ uri: seerrApi?.imageProxy(item.stillPath),
}}
cachePolicy={"memory-disk"}
contentFit='cover'
@@ -131,7 +127,7 @@ const RenderItem = ({ item }: any) => {
);
};
-const JellyseerrSeasons: React.FC<{
+const SeerrSeasons: React.FC<{
isLoading: boolean;
details?: TvDetails;
hasAdvancedRequest?: boolean;
@@ -148,7 +144,7 @@ const JellyseerrSeasons: React.FC<{
hasAdvancedRequest,
onAdvancedRequest,
}) => {
- const { jellyseerrApi, requestMedia } = useJellyseerr();
+ const { seerrApi, requestMedia } = useSeerr();
const [seasonStates, setSeasonStates] = useState<{ [key: number]: boolean }>(
{},
);
@@ -181,7 +177,7 @@ const JellyseerrSeasons: React.FC<{
);
const requestAll = useCallback(() => {
- if (details && jellyseerrApi) {
+ if (details && seerrApi) {
const body: MediaRequestBody = {
mediaId: details.id,
mediaType: MediaType.TV,
@@ -198,7 +194,7 @@ const JellyseerrSeasons: React.FC<{
requestMedia(details.name, body, refetch);
}
}, [
- jellyseerrApi,
+ seerrApi,
seasons,
details,
hasAdvancedRequest,
@@ -210,15 +206,15 @@ const JellyseerrSeasons: React.FC<{
const promptRequestAll = useCallback(
() =>
Alert.alert(
- t("jellyseerr.confirm"),
- t("jellyseerr.are_you_sure_you_want_to_request_all_seasons"),
+ t("seerr.confirm"),
+ t("seerr.are_you_sure_you_want_to_request_all_seasons"),
[
{
- text: t("jellyseerr.cancel"),
+ text: t("seerr.cancel"),
style: "cancel",
},
{
- text: t("jellyseerr.yes"),
+ text: t("seerr.yes"),
onPress: requestAll,
},
],
@@ -301,10 +297,10 @@ const JellyseerrSeasons: React.FC<{
{
const canRequest = season.status === MediaStatus.UNKNOWN;
return (
-
requestSeason(canRequest, season.seasonNumber)
@@ -326,7 +322,7 @@ const JellyseerrSeasons: React.FC<{
{seasonStates?.[season.seasonNumber] && (
- {
- const { jellyseerrUser, setJellyseerrUser, clearAllJellyseerData } =
- useJellyseerr();
-
- const { t } = useTranslation();
-
- const [user] = useAtom(userAtom);
- const { settings, updateSettings } = useSettings();
-
- const [jellyseerrPassword, setJellyseerrPassword] = useState<
- string | undefined
- >(undefined);
-
- const [jellyseerrServerUrl, setjellyseerrServerUrl] = useState<
- string | undefined
- >(settings?.jellyseerrServerUrl || undefined);
-
- const loginToJellyseerrMutation = useMutation({
- mutationFn: async () => {
- if (!jellyseerrServerUrl && !settings?.jellyseerrServerUrl)
- throw new Error("Missing server url");
- if (!user?.Name)
- throw new Error("Missing required information for login");
- const jellyseerrTempApi = new JellyseerrApi(
- jellyseerrServerUrl || settings.jellyseerrServerUrl || "",
- );
- const testResult = await jellyseerrTempApi.test();
- if (!testResult.isValid) throw new Error("Invalid server url");
- return jellyseerrTempApi.login(user.Name, jellyseerrPassword || "");
- },
- onSuccess: (user) => {
- setJellyseerrUser(user);
- updateSettings({ jellyseerrServerUrl });
- },
- onError: () => {
- toast.error(t("jellyseerr.failed_to_login"));
- },
- onSettled: () => {
- setJellyseerrPassword(undefined);
- },
- });
-
- const clearData = () => {
- clearAllJellyseerData().finally(() => {
- setJellyseerrUser(undefined);
- setJellyseerrPassword(undefined);
- setjellyseerrServerUrl(undefined);
- });
- };
-
- return (
-
-
- {jellyseerrUser ? (
- <>
-
-
-
-
-
-
-
-
-
-
- {t(
- "home.settings.plugins.jellyseerr.reset_jellyseerr_config_button",
- )}
-
-
- >
- ) : (
-
-
- {t("home.settings.plugins.jellyseerr.jellyseerr_warning")}
-
-
- {t("home.settings.plugins.jellyseerr.server_url")}
-
-
-
- {t("home.settings.plugins.jellyseerr.server_url_hint")}
-
-
-
-
-
- {t("home.settings.plugins.jellyseerr.password")}
-
-
- loginToJellyseerrMutation.mutate()}
- >
- {t("home.settings.plugins.jellyseerr.login_button")}
-
-
-
- )}
-
-
- );
-};
diff --git a/components/settings/PluginSettings.tsx b/components/settings/PluginSettings.tsx
index 1b21cf98..e6a6d310 100644
--- a/components/settings/PluginSettings.tsx
+++ b/components/settings/PluginSettings.tsx
@@ -19,7 +19,7 @@ export const PluginSettings = () => {
className='mb-4'
>
router.push("/settings/plugins/jellyseerr/page")}
+ onPress={() => router.push("/settings/plugins/seerr/page")}
title={"Seerr"}
showArrow
/>
diff --git a/components/settings/Seerr.tsx b/components/settings/Seerr.tsx
new file mode 100644
index 00000000..1ad87e7f
--- /dev/null
+++ b/components/settings/Seerr.tsx
@@ -0,0 +1,174 @@
+import { useMutation } from "@tanstack/react-query";
+import { useAtom } from "jotai";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { View } from "react-native";
+import { toast } from "sonner-native";
+import { SeerrApi, useSeerr } from "@/hooks/useSeerr";
+import { userAtom } from "@/providers/JellyfinProvider";
+import { useSettings } from "@/utils/atoms/settings";
+import { Button } from "../Button";
+import { Input } from "../common/Input";
+import { Text } from "../common/Text";
+import { ListGroup } from "../list/ListGroup";
+import { ListItem } from "../list/ListItem";
+
+export const SeerrSettings = () => {
+ const { seerrUser, setSeerrUser, clearAllSeerrData } = useSeerr();
+
+ const { t } = useTranslation();
+
+ const [user] = useAtom(userAtom);
+ const { settings, updateSettings } = useSettings();
+
+ const [seerrPassword, setSeerrPassword] = useState(
+ undefined,
+ );
+
+ const [seerrServerUrl, setSeerrServerUrl] = useState(
+ settings?.seerrServerUrl || undefined,
+ );
+
+ const loginToSeerrMutation = useMutation({
+ mutationFn: async () => {
+ if (!seerrServerUrl && !settings?.seerrServerUrl)
+ throw new Error("Missing server url");
+ if (!user?.Name)
+ throw new Error("Missing required information for login");
+ const seerrTempApi = new SeerrApi(
+ seerrServerUrl || settings.seerrServerUrl || "",
+ );
+ const testResult = await seerrTempApi.test();
+ if (!testResult.isValid) throw new Error("Invalid server url");
+ return seerrTempApi.login(user.Name, seerrPassword || "");
+ },
+ onSuccess: (user) => {
+ setSeerrUser(user);
+ updateSettings({ seerrServerUrl });
+ },
+ onError: () => {
+ toast.error(t("seerr.failed_to_login"));
+ },
+ onSettled: () => {
+ setSeerrPassword(undefined);
+ },
+ });
+
+ const clearData = () => {
+ clearAllSeerrData().finally(() => {
+ setSeerrUser(undefined);
+ setSeerrPassword(undefined);
+ setSeerrServerUrl(undefined);
+ });
+ };
+
+ return (
+
+
+ {seerrUser ? (
+ <>
+
+
+
+
+
+
+
+
+
+
+ {t("home.settings.plugins.seerr.reset_seerr_config_button")}
+
+
+ >
+ ) : (
+
+
+ {t("home.settings.plugins.seerr.seerr_warning")}
+
+
+ {t("home.settings.plugins.seerr.server_url")}
+
+
+
+ {t("home.settings.plugins.seerr.server_url_hint")}
+
+
+
+
+
+ {t("home.settings.plugins.seerr.password")}
+
+
+ loginToSeerrMutation.mutate()}
+ >
+ {t("home.settings.plugins.seerr.login_button")}
+
+
+
+ )}
+
+
+ );
+};
diff --git a/hooks/useJellyseerr.ts b/hooks/useSeerr.ts
similarity index 82%
rename from hooks/useJellyseerr.ts
rename to hooks/useSeerr.ts
index d1d511fb..55a242a9 100644
--- a/hooks/useJellyseerr.ts
+++ b/hooks/useSeerr.ts
@@ -2,7 +2,7 @@ import axios, { type AxiosError, type AxiosInstance } from "axios";
import { atom } from "jotai";
import { useAtom } from "jotai/index";
import { inRange } from "lodash";
-import type { User as JellyseerrUser } from "@/utils/jellyseerr/server/entity/User";
+import type { User as SeerrUser } from "@/utils/jellyseerr/server/entity/User";
import type {
MovieResult,
Results,
@@ -62,12 +62,12 @@ interface SearchResults {
results: Results[];
}
-const JELLYSEERR_USER = "JELLYSEERR_USER";
-const JELLYSEERR_COOKIES = "JELLYSEERR_COOKIES";
+const SEERR_USER = "SEERR_USER";
+const SEERR_COOKIES = "SEERR_COOKIES";
-export const clearJellyseerrStorageData = () => {
- storage.remove(JELLYSEERR_USER);
- storage.remove(JELLYSEERR_COOKIES);
+export const clearSeerrStorageData = () => {
+ storage.remove(SEERR_USER);
+ storage.remove(SEERR_COOKIES);
};
export enum Endpoints {
@@ -111,7 +111,7 @@ export type TestResult =
isValid: false;
};
-export class JellyseerrApi {
+export class SeerrApi {
axios: AxiosInstance;
constructor(baseUrl: string) {
@@ -126,8 +126,8 @@ export class JellyseerrApi {
}
async test(): Promise {
- const user = storage.get(JELLYSEERR_USER);
- const cookies = storage.get(JELLYSEERR_COOKIES);
+ const user = storage.get(SEERR_USER);
+ const cookies = storage.get(SEERR_COOKIES);
if (user && cookies) {
return Promise.resolve({
@@ -142,15 +142,13 @@ export class JellyseerrApi {
const { status, headers, data } = response;
if (inRange(status, 200, 299)) {
if (data.version < "2.0.0") {
- const error = t(
- "jellyseerr.toasts.jellyseer_does_not_meet_requirements",
- );
+ const error = t("seerr.toasts.seer_does_not_meet_requirements");
toast.error(error);
throw Error(error);
}
storage.setAny(
- JELLYSEERR_COOKIES,
+ SEERR_COOKIES,
headers["set-cookie"]?.flatMap((c) => c.split("; ")) ?? [],
);
return {
@@ -158,7 +156,7 @@ export class JellyseerrApi {
requiresPass: true,
};
}
- toast.error(t("jellyseerr.toasts.jellyseerr_test_failed"));
+ toast.error(t("seerr.toasts.seerr_test_failed"));
writeErrorLog(
`Seerr returned a ${status} for url:\n${response.config.url}`,
response.data,
@@ -169,7 +167,7 @@ export class JellyseerrApi {
};
})
.catch((e) => {
- const msg = t("jellyseerr.toasts.failed_to_test_jellyseerr_server_url");
+ const msg = t("seerr.toasts.failed_to_test_seerr_server_url");
toast.error(msg);
console.error(msg, e);
return {
@@ -179,9 +177,9 @@ export class JellyseerrApi {
});
}
- async login(username: string, password: string): Promise {
+ async login(username: string, password: string): Promise {
return this.axios
- ?.post(Endpoints.API_V1 + Endpoints.AUTH_JELLYFIN, {
+ ?.post(Endpoints.API_V1 + Endpoints.AUTH_JELLYFIN, {
username,
password,
email: username,
@@ -189,7 +187,7 @@ export class JellyseerrApi {
.then((response) => {
const user = response?.data;
if (!user) throw Error("Login failed");
- storage.setAny(JELLYSEERR_USER, user);
+ storage.setAny(SEERR_USER, user);
return user;
});
}
@@ -364,7 +362,7 @@ export class JellyseerrApi {
const issue = response.data;
if (issue.status === IssueStatus.OPEN) {
- toast.success(t("jellyseerr.toasts.issue_submitted"));
+ toast.success(t("seerr.toasts.issue_submitted"));
}
return issue;
});
@@ -392,7 +390,7 @@ export class JellyseerrApi {
const cookies = response.headers["set-cookie"];
if (cookies) {
storage.setAny(
- JELLYSEERR_COOKIES,
+ SEERR_COOKIES,
response.headers["set-cookie"]?.flatMap((c) => c.split("; ")),
);
}
@@ -404,7 +402,7 @@ export class JellyseerrApi {
error.response?.data,
);
if (error.response?.status === 403) {
- clearJellyseerrStorageData();
+ clearSeerrStorageData();
}
return Promise.reject(error);
},
@@ -412,7 +410,7 @@ export class JellyseerrApi {
this.axios.interceptors.request.use(
async (config) => {
- const cookies = storage.get(JELLYSEERR_COOKIES);
+ const cookies = storage.get(SEERR_COOKIES);
if (cookies) {
const headerName = this.axios.defaults.xsrfHeaderName!;
const xsrfToken = cookies
@@ -431,59 +429,55 @@ export class JellyseerrApi {
}
}
-const jellyseerrUserAtom = atom(storage.get(JELLYSEERR_USER));
+const seerrUserAtom = atom(storage.get(SEERR_USER));
-export const useJellyseerr = () => {
+export const useSeerr = () => {
const { settings, updateSettings } = useSettings();
- const [jellyseerrUser, setJellyseerrUser] = useAtom(jellyseerrUserAtom);
+ const [seerrUser, setSeerrUser] = useAtom(seerrUserAtom);
const queryClient = useNetworkAwareQueryClient();
- const jellyseerrApi = useMemo(() => {
- const cookies = storage.get(JELLYSEERR_COOKIES);
- if (settings?.jellyseerrServerUrl && cookies && jellyseerrUser) {
- return new JellyseerrApi(settings?.jellyseerrServerUrl);
+ const seerrApi = useMemo(() => {
+ const cookies = storage.get(SEERR_COOKIES);
+ if (settings?.seerrServerUrl && cookies && seerrUser) {
+ return new SeerrApi(settings?.seerrServerUrl);
}
return undefined;
- }, [settings?.jellyseerrServerUrl, jellyseerrUser]);
+ }, [settings?.seerrServerUrl, seerrUser]);
- const clearAllJellyseerData = useCallback(async () => {
- clearJellyseerrStorageData();
- setJellyseerrUser(undefined);
- updateSettings({ jellyseerrServerUrl: undefined });
+ const clearAllSeerrData = useCallback(async () => {
+ clearSeerrStorageData();
+ setSeerrUser(undefined);
+ updateSettings({ seerrServerUrl: undefined });
}, []);
const requestMedia = useCallback(
(title: string, request: MediaRequestBody, onSuccess?: () => void) => {
- jellyseerrApi?.request?.(request)?.then(async (mediaRequest) => {
+ seerrApi?.request?.(request)?.then(async (mediaRequest) => {
await queryClient.invalidateQueries({
- queryKey: ["search", "jellyseerr"],
+ queryKey: ["search", "seerr"],
});
switch (mediaRequest.status) {
case MediaRequestStatus.PENDING:
case MediaRequestStatus.APPROVED:
- toast.success(
- t("jellyseerr.toasts.requested_item", { item: title }),
- );
+ toast.success(t("seerr.toasts.requested_item", { item: title }));
onSuccess?.();
break;
case MediaRequestStatus.DECLINED:
- toast.error(
- t("jellyseerr.toasts.you_dont_have_permission_to_request"),
- );
+ toast.error(t("seerr.toasts.you_dont_have_permission_to_request"));
break;
case MediaRequestStatus.FAILED:
toast.error(
- t("jellyseerr.toasts.something_went_wrong_requesting_media"),
+ t("seerr.toasts.something_went_wrong_requesting_media"),
);
break;
}
});
},
- [jellyseerrApi],
+ [seerrApi],
);
- const isJellyseerrMovieOrTvResult = (
+ const isSeerrMovieOrTvResult = (
items: any | null | undefined,
): items is MovieResult | TvResult => {
return (
@@ -496,7 +490,7 @@ export const useJellyseerr = () => {
const getTitle = (
item?: TvResult | TvDetails | MovieResult | MovieDetails | PersonCreditCast,
) => {
- return isJellyseerrMovieOrTvResult(item)
+ return isSeerrMovieOrTvResult(item)
? item.mediaType === MediaType.MOVIE
? item?.title
: item?.name
@@ -509,7 +503,7 @@ export const useJellyseerr = () => {
item?: TvResult | TvDetails | MovieResult | MovieDetails | PersonCreditCast,
) => {
return new Date(
- (isJellyseerrMovieOrTvResult(item)
+ (isSeerrMovieOrTvResult(item)
? item.mediaType === MediaType.MOVIE
? item?.releaseDate
: item?.firstAirDate
@@ -522,32 +516,32 @@ export const useJellyseerr = () => {
const getMediaType = (
item?: TvResult | TvDetails | MovieResult | MovieDetails | PersonCreditCast,
): MediaType => {
- return isJellyseerrMovieOrTvResult(item)
+ return isSeerrMovieOrTvResult(item)
? (item.mediaType as MediaType)
: item?.mediaInfo?.mediaType;
};
- const jellyseerrRegion = useMemo(
+ const seerrRegion = useMemo(
// streamingRegion and discoverRegion exists. region doesn't
- () => jellyseerrUser?.settings?.discoverRegion || "US",
- [jellyseerrUser],
+ () => seerrUser?.settings?.discoverRegion || "US",
+ [seerrUser],
);
- const jellyseerrLocale = useMemo(() => {
- return jellyseerrUser?.settings?.locale || "en";
- }, [jellyseerrUser]);
+ const seerrLocale = useMemo(() => {
+ return seerrUser?.settings?.locale || "en";
+ }, [seerrUser]);
return {
- jellyseerrApi,
- jellyseerrUser,
- setJellyseerrUser,
- clearAllJellyseerData,
- isJellyseerrMovieOrTvResult,
+ seerrApi,
+ seerrUser,
+ setSeerrUser,
+ clearAllSeerrData,
+ isSeerrMovieOrTvResult,
getTitle,
getYear,
getMediaType,
- jellyseerrRegion,
- jellyseerrLocale,
+ seerrRegion,
+ seerrLocale,
requestMedia,
};
};
diff --git a/providers/JellyfinProvider.tsx b/providers/JellyfinProvider.tsx
index da75dcd1..616e5d4e 100644
--- a/providers/JellyfinProvider.tsx
+++ b/providers/JellyfinProvider.tsx
@@ -23,7 +23,7 @@ import { getDeviceName } from "react-native-device-info";
import uuid from "react-native-uuid";
import useRouter from "@/hooks/useAppRouter";
import { useInterval } from "@/hooks/useInterval";
-import { JellyseerrApi, useJellyseerr } from "@/hooks/useJellyseerr";
+import { SeerrApi, useSeerr } from "@/hooks/useSeerr";
import { useSettings } from "@/utils/atoms/settings";
import { writeErrorLog, writeInfoLog } from "@/utils/log";
import { storage } from "@/utils/mmkv";
@@ -113,7 +113,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
const [isPolling, setIsPolling] = useState(false);
const [secret, setSecret] = useState(null);
const { setPluginSettings, refreshStreamyfinPluginSettings } = useSettings();
- const { clearAllJellyseerData, setJellyseerrUser } = useJellyseerr();
+ const { clearAllSeerrData, setSeerrUser } = useSeerr();
const headers = useMemo(() => {
if (!deviceId) return {};
@@ -290,13 +290,13 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
}
const recentPluginSettings = await refreshStreamyfinPluginSettings();
- if (recentPluginSettings?.jellyseerrServerUrl?.value) {
- const jellyseerrApi = new JellyseerrApi(
- recentPluginSettings.jellyseerrServerUrl.value,
+ if (recentPluginSettings?.seerrServerUrl?.value) {
+ const seerrApi = new SeerrApi(
+ recentPluginSettings.seerrServerUrl.value,
);
- await jellyseerrApi.test().then((result) => {
+ await seerrApi.test().then((result) => {
if (result.isValid && result.requiresPass) {
- jellyseerrApi.login(username, password).then(setJellyseerrUser);
+ seerrApi.login(username, password).then(setSeerrUser);
}
});
}
@@ -349,7 +349,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
setUser(null);
setApi(null);
setPluginSettings(undefined);
- await clearAllJellyseerData();
+ await clearAllSeerrData();
// Note: We keep saved credentials for quick switching back
},
onError: (error) => {
diff --git a/translations/en.json b/translations/en.json
index 27e38ddb..c6652310 100644
--- a/translations/en.json
+++ b/translations/en.json
@@ -96,7 +96,7 @@
"a_free_and_open_source_client_for_jellyfin": "A Free and Open-Source Client for Jellyfin",
"features_title": "Features",
"features_description": "Streamyfin offers many features and integrates with a wide array of software which you can find in the settings menu, including:",
- "jellyseerr_feature_description": "Connect to your Seerr instance and request movies directly in the app.",
+ "seerr_feature_description": "Connect to your Seerr instance and request movies directly in the app.",
"downloads_feature_title": "Downloads",
"downloads_feature_description": "Download movies and TV shows to view offline.",
"chromecast_feature_description": "Cast movies and TV shows to your Chromecast devices.",
@@ -326,8 +326,8 @@
},
"plugins": {
"plugins_title": "Plugins",
- "jellyseerr": {
- "jellyseerr_warning": "This integration is in early development. Features may change.",
+ "seerr": {
+ "seerr_warning": "This integration is in early development. Features may change.",
"server_url": "Server URL",
"server_url_hint": "Example: http(s)://your-host.url\n(add port if required)",
"server_url_placeholder": "Seerr URL",
@@ -339,7 +339,7 @@
"movie_quota_days": "Movie Quota Days",
"tv_quota_limit": "TV Quota Limit",
"tv_quota_days": "TV Quota Days",
- "reset_jellyseerr_config_button": "Reset Seerr Config",
+ "reset_seerr_config_button": "Reset Seerr Config",
"unlimited": "Unlimited",
"plus_n_more": "+{{n}} more",
"order_by": {
@@ -675,7 +675,7 @@
"for_kids": "For Kids",
"news": "News"
},
- "jellyseerr": {
+ "seerr": {
"confirm": "Confirm",
"cancel": "Cancel",
"yes": "Yes",
@@ -719,9 +719,9 @@
"requested_by": "Requested by {{user}}",
"unknown_user": "Unknown User",
"toasts": {
- "jellyseer_does_not_meet_requirements": "Seerr server does not meet minimum version requirements! Please update to at least 2.0.0",
- "jellyseerr_test_failed": "Seerr test failed. Please try again.",
- "failed_to_test_jellyseerr_server_url": "Failed to test Seerr server URL",
+ "seer_does_not_meet_requirements": "Seerr server does not meet minimum version requirements! Please update to at least 2.0.0",
+ "seerr_test_failed": "Seerr test failed. Please try again.",
+ "failed_to_test_seerr_server_url": "Failed to test Seerr server URL",
"issue_submitted": "Issue Submitted!",
"requested_item": "Requested {{item}}!",
"you_dont_have_permission_to_request": "You don't have permission to request!",
diff --git a/utils/_jellyseerr/useJellyseerrCanRequest.ts b/utils/_seerr/useSeerrCanRequest.ts
similarity index 83%
rename from utils/_jellyseerr/useJellyseerrCanRequest.ts
rename to utils/_seerr/useSeerrCanRequest.ts
index 2cd67a33..15e395db 100644
--- a/utils/_jellyseerr/useJellyseerrCanRequest.ts
+++ b/utils/_seerr/useSeerrCanRequest.ts
@@ -1,5 +1,5 @@
import { useMemo } from "react";
-import { useJellyseerr } from "@/hooks/useJellyseerr";
+import { useSeerr } from "@/hooks/useSeerr";
import {
MediaRequestStatus,
MediaStatus,
@@ -18,13 +18,13 @@ import type MediaRequest from "../jellyseerr/server/entity/MediaRequest";
import type { MovieDetails } from "../jellyseerr/server/models/Movie";
import type { TvDetails } from "../jellyseerr/server/models/Tv";
-export const useJellyseerrCanRequest = (
+export const useSeerrCanRequest = (
item?: MovieResult | TvResult | MovieDetails | TvDetails | PersonCreditCast,
) => {
- const { jellyseerrUser } = useJellyseerr();
+ const { seerrUser } = useSeerr();
const canRequest = useMemo(() => {
- if (!jellyseerrUser || !item) return false;
+ if (!seerrUser || !item) return false;
const canNotRequest =
item?.mediaInfo?.requests?.some(
@@ -46,22 +46,22 @@ export const useJellyseerrCanRequest = (
? Permission.REQUEST_MOVIE
: Permission.REQUEST_TV,
],
- jellyseerrUser.permissions,
+ seerrUser.permissions,
{ type: "or" },
);
return userHasPermission && !canNotRequest;
- }, [item, jellyseerrUser]);
+ }, [item, seerrUser]);
const hasAdvancedRequestPermission = useMemo(() => {
- if (!jellyseerrUser) return false;
+ if (!seerrUser) return false;
return hasPermission(
[Permission.REQUEST_ADVANCED, Permission.MANAGE_REQUESTS],
- jellyseerrUser.permissions,
+ seerrUser.permissions,
{ type: "or" },
);
- }, [jellyseerrUser]);
+ }, [seerrUser]);
return [canRequest, hasAdvancedRequestPermission];
};
diff --git a/utils/atoms/settings.ts b/utils/atoms/settings.ts
index 28f7d1b4..ecfd7a74 100644
--- a/utils/atoms/settings.ts
+++ b/utils/atoms/settings.ts
@@ -174,7 +174,7 @@ export type Settings = {
disableHapticFeedback: boolean;
subtitleSize: number;
safeAreaInControlsEnabled: boolean;
- jellyseerrServerUrl?: string;
+ seerrServerUrl?: string;
useKefinTweaks: boolean;
hiddenLibraries?: string[];
enableH265ForChromecast: boolean;
@@ -259,7 +259,7 @@ export const defaultValues: Settings = {
disableHapticFeedback: false,
subtitleSize: 100, // Scale value * 100, so 100 = 1.0x
safeAreaInControlsEnabled: true,
- jellyseerrServerUrl: undefined,
+ seerrServerUrl: undefined,
useKefinTweaks: false,
hiddenLibraries: [],
enableH265ForChromecast: false,