mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-04 21:18:31 +01:00
refactor(jellyseerr): keep the server version out of the field UI; enforce it at login
The resolver field only needs to find the working URL — the Jellyseerr version requirement is irrelevant there and only polluted the UI. - jellyseerrProbe: validate reachability + that it's a jellyseerr (no version gate, no version-too-low outcome). - Drop the version-too-low reason from the whole resolver stack (types, resolve, hook, status text, i18n). - Min version 2.0.0 stays enforced in JellyseerrApi.test() at login: now writes an error log + toast, and uses numeric isVersionBelow (fixes the "2.10.0" < "2.0.0" string-compare bug).
This commit is contained in:
@@ -18,8 +18,6 @@ interface ServerUrlFieldProps {
|
||||
label?: string;
|
||||
hint?: string;
|
||||
placeholder?: string;
|
||||
/** Shown in the "version too low" message. */
|
||||
minVersion?: string;
|
||||
editable?: boolean;
|
||||
resolveOptions?: ResolveOptions;
|
||||
}
|
||||
@@ -38,7 +36,6 @@ export function ServerUrlField({
|
||||
label,
|
||||
hint,
|
||||
placeholder,
|
||||
minVersion,
|
||||
editable = true,
|
||||
resolveOptions,
|
||||
}: ServerUrlFieldProps) {
|
||||
@@ -96,11 +93,7 @@ export function ServerUrlField({
|
||||
clearButtonMode='never'
|
||||
/>
|
||||
|
||||
<ServerUrlStatusText
|
||||
state={resolver}
|
||||
minVersion={minVersion}
|
||||
className='mt-2'
|
||||
/>
|
||||
<ServerUrlStatusText state={resolver} className='mt-2' />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,11 +10,9 @@ import { Text } from "./Text";
|
||||
*/
|
||||
export function ServerUrlStatusText({
|
||||
state,
|
||||
minVersion,
|
||||
className = "",
|
||||
}: {
|
||||
state: ServerUrlResolverState;
|
||||
minVersion?: string;
|
||||
className?: string;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
@@ -41,16 +39,11 @@ export function ServerUrlStatusText({
|
||||
}
|
||||
|
||||
const message =
|
||||
state.reason === "version-too-low"
|
||||
? t("server_url.version_too_low", {
|
||||
version: state.version ?? "?",
|
||||
min: minVersion ?? "",
|
||||
})
|
||||
: state.reason === "wrong-service"
|
||||
? t("server_url.wrong_service")
|
||||
: state.reason === "invalid"
|
||||
? t("server_url.invalid_url")
|
||||
: t("server_url.unreachable");
|
||||
state.reason === "wrong-service"
|
||||
? t("server_url.wrong_service")
|
||||
: state.reason === "invalid"
|
||||
? t("server_url.invalid_url")
|
||||
: t("server_url.unreachable");
|
||||
|
||||
return <Text className={`text-xs text-red-500 ${className}`}>{message}</Text>;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,6 @@ export const JellyseerrSettings = () => {
|
||||
onChangeText={setjellyseerrServerUrl}
|
||||
onResolved={(url) => setResolvedUrl(url)}
|
||||
probe={jellyseerrProbe}
|
||||
minVersion='2.0.0'
|
||||
label={t("home.settings.plugins.jellyseerr.server_url")}
|
||||
hint={t("home.settings.plugins.jellyseerr.server_url_hint")}
|
||||
placeholder={t(
|
||||
|
||||
@@ -48,6 +48,7 @@ import type {
|
||||
TvDetails,
|
||||
} from "@/utils/jellyseerr/server/models/Tv";
|
||||
import { writeErrorLog } from "@/utils/log";
|
||||
import { isVersionBelow } from "@/utils/serverUrl/semver";
|
||||
|
||||
interface SearchParams {
|
||||
query: string;
|
||||
@@ -141,10 +142,13 @@ export class JellyseerrApi {
|
||||
.then((response) => {
|
||||
const { status, headers, data } = response;
|
||||
if (inRange(status, 200, 299)) {
|
||||
if (data.version < "2.0.0") {
|
||||
if (data.version && isVersionBelow(data.version, "2.0.0")) {
|
||||
const error = t(
|
||||
"jellyseerr.toasts.jellyseer_does_not_meet_requirements",
|
||||
);
|
||||
writeErrorLog(
|
||||
`Jellyseerr version ${data.version} is below the required 2.0.0`,
|
||||
);
|
||||
toast.error(error);
|
||||
throw Error(error);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export type ServerUrlResolverState =
|
||||
| { status: "idle" }
|
||||
| { status: "resolving" }
|
||||
| { status: "ok"; resolvedUrl: string; meta?: Record<string, unknown> }
|
||||
| { status: "error"; reason: ResolveFailureReason; version?: string };
|
||||
| { status: "error"; reason: ResolveFailureReason };
|
||||
|
||||
/**
|
||||
* Stateful wrapper around `resolveServerUrl` for screens.
|
||||
@@ -46,11 +46,7 @@ export function useServerUrlResolver(
|
||||
setState(
|
||||
result.ok
|
||||
? { status: "ok", resolvedUrl: result.url, meta: result.meta }
|
||||
: {
|
||||
status: "error",
|
||||
reason: result.reason,
|
||||
version: result.version,
|
||||
},
|
||||
: { status: "error", reason: result.reason },
|
||||
);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"connected": "Connected to {{url}}",
|
||||
"unreachable": "Server unreachable",
|
||||
"wrong_service": "Reachable, but not the expected server",
|
||||
"version_too_low": "Version {{version}} is too old (minimum {{min}})",
|
||||
"invalid_url": "Enter a valid address"
|
||||
},
|
||||
"login": {
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import axios from "axios";
|
||||
import { isVersionBelow } from "../semver";
|
||||
import type { ServerProbe } from "../types";
|
||||
|
||||
/** Jellyseerr/Overseerr minimum supported version. */
|
||||
const MIN_VERSION = "2.0.0";
|
||||
|
||||
/**
|
||||
* Probe for a Jellyseerr server. `/api/v1/status` is jellyseerr/overseerr
|
||||
* specific and unauthenticated, so it both proves reachability and confirms
|
||||
* we hit the right service.
|
||||
* specific and unauthenticated, so it both proves reachability and confirms we
|
||||
* hit the right service. The minimum-version requirement is enforced at login
|
||||
* time (see JellyseerrApi.test) — not surfaced here, to keep the field UI clean.
|
||||
*/
|
||||
export const jellyseerrProbe: ServerProbe = async (url, signal) => {
|
||||
try {
|
||||
@@ -19,22 +16,14 @@ export const jellyseerrProbe: ServerProbe = async (url, signal) => {
|
||||
|
||||
if (status < 200 || status >= 300) return { status: "unreachable" };
|
||||
|
||||
const version: string | undefined =
|
||||
typeof data?.version === "string" ? data.version : undefined;
|
||||
|
||||
// A JSON body carrying version/commitTag identifies a real jellyseerr.
|
||||
if (
|
||||
!version &&
|
||||
!(data && typeof data === "object" && "commitTag" in data)
|
||||
) {
|
||||
return { status: "wrong-service" };
|
||||
}
|
||||
const looksLikeJellyseerr =
|
||||
!!data &&
|
||||
typeof data === "object" &&
|
||||
(typeof data.version === "string" || "commitTag" in data);
|
||||
if (!looksLikeJellyseerr) return { status: "wrong-service" };
|
||||
|
||||
if (version && isVersionBelow(version, MIN_VERSION)) {
|
||||
return { status: "version-too-low", version };
|
||||
}
|
||||
|
||||
return { status: "ok", meta: { version } };
|
||||
return { status: "ok", meta: { version: data.version } };
|
||||
} catch {
|
||||
return { status: "unreachable" };
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@ import type { ServerProbe, ServerProbeOutcome } from "./types";
|
||||
export type ResolveFailureReason =
|
||||
| "empty"
|
||||
| "invalid"
|
||||
| "version-too-low"
|
||||
| "wrong-service"
|
||||
| "unreachable";
|
||||
|
||||
export type ResolveResult =
|
||||
| { ok: true; url: string; meta?: Record<string, unknown> }
|
||||
| { ok: false; reason: ResolveFailureReason; version?: string };
|
||||
| { ok: false; reason: ResolveFailureReason };
|
||||
|
||||
export interface ResolveOptions {
|
||||
/** Per-candidate probe timeout in ms. Default 5000. */
|
||||
@@ -22,7 +21,6 @@ export interface ResolveOptions {
|
||||
// Order in which to surface a failure when no candidate validated:
|
||||
// the more specific/actionable the reason, the earlier it is reported.
|
||||
const FAILURE_PRIORITY = [
|
||||
"version-too-low",
|
||||
"wrong-service",
|
||||
"unreachable",
|
||||
] as const satisfies ReadonlyArray<ResolveFailureReason>;
|
||||
@@ -62,11 +60,7 @@ export async function resolveServerUrl(
|
||||
for (const reason of FAILURE_PRIORITY) {
|
||||
const hit = outcomes.find((outcome) => outcome.status === reason);
|
||||
if (hit) {
|
||||
return {
|
||||
ok: false,
|
||||
reason,
|
||||
version: hit.status === "version-too-low" ? hit.version : undefined,
|
||||
};
|
||||
return { ok: false, reason };
|
||||
}
|
||||
}
|
||||
return { ok: false, reason: "unreachable" };
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/** Result of probing a single candidate URL for a specific service. */
|
||||
export type ServerProbeOutcome =
|
||||
| { status: "ok"; meta?: Record<string, unknown> }
|
||||
| { status: "version-too-low"; version?: string }
|
||||
| { status: "wrong-service" }
|
||||
| { status: "unreachable" };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user