From ef276740103b9aba021df40a1641080709095ce7 Mon Sep 17 00:00:00 2001 From: Gauvain Date: Thu, 4 Jun 2026 21:16:57 +0200 Subject: [PATCH] =?UTF-8?q?refactor(server-url):=20drop=20the=20inline=20s?= =?UTF-8?q?tatus=20chip=20=E2=80=94=20auto-resolve=20on=20blur=20+=20statu?= =?UTF-8?q?s=20line=20is=20enough=20(no=20redundant=20test=20affordance)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/common/ServerUrlField.tsx | 137 +++++++-------------------- 1 file changed, 33 insertions(+), 104 deletions(-) diff --git a/components/common/ServerUrlField.tsx b/components/common/ServerUrlField.tsx index 0ef774cc0..e8fa6b5fe 100644 --- a/components/common/ServerUrlField.tsx +++ b/components/common/ServerUrlField.tsx @@ -1,17 +1,10 @@ -import { Ionicons } from "@expo/vector-icons"; import { useCallback, useRef } from "react"; -import { useTranslation } from "react-i18next"; -import { ActivityIndicator, Pressable, View } from "react-native"; -import { - type ServerUrlResolverState, - useServerUrlResolver, -} from "@/hooks/useServerUrlResolver"; -import type { - ResolveFailureReason, - ResolveOptions, -} from "@/utils/serverUrl/resolve"; +import { View } from "react-native"; +import { useServerUrlResolver } from "@/hooks/useServerUrlResolver"; +import type { ResolveOptions } from "@/utils/serverUrl/resolve"; import type { ServerProbe } from "@/utils/serverUrl/types"; import { Input } from "./Input"; +import { ServerUrlStatusText } from "./ServerUrlStatusText"; import { Text } from "./Text"; interface ServerUrlFieldProps { @@ -31,31 +24,11 @@ interface ServerUrlFieldProps { resolveOptions?: ResolveOptions; } -function errorMessage( - t: (key: string, opts?: Record) => string, - reason: ResolveFailureReason, - version?: string, - minVersion?: string, -): string { - switch (reason) { - case "version-too-low": - return t("server_url.version_too_low", { - version: version ?? "?", - min: minVersion ?? "", - }); - case "wrong-service": - return t("server_url.wrong_service"); - case "invalid": - return t("server_url.invalid_url"); - default: - return t("server_url.unreachable"); - } -} - /** * Unified server-URL input: the user types a loose address (`media.example.com`, - * `https://…`, `host:port`), it auto-resolves on blur via the given probe and - * persists the canonical URL. Inline status chip (tap to re-test) + resolved URL. + * `https://…`, `host:port`); on blur it auto-resolves via the given probe, + * adopts the canonical URL into the field, and persists it. A small status line + * (checking / resolved / error) shows underneath. */ export function ServerUrlField({ value, @@ -69,7 +42,6 @@ export function ServerUrlField({ editable = true, resolveOptions, }: ServerUrlFieldProps) { - const { t } = useTranslation(); const resolver = useServerUrlResolver(probe, resolveOptions); const lastResolvedInput = useRef(null); @@ -82,8 +54,11 @@ export function ServerUrlField({ } lastResolvedInput.current = input; const result = await resolver.resolve(input); - if (result.ok) onResolved?.(result.url, result.meta); - }, [value, resolver, onResolved]); + if (result.ok) { + onChangeText(result.url); // adopt the canonical URL into the field + onResolved?.(result.url, result.meta); + } + }, [value, resolver, onChangeText, onResolved]); const handleBlur = useCallback(() => { const input = value.trim(); @@ -93,7 +68,7 @@ export function ServerUrlField({ const handleChange = useCallback( (text: string) => { onChangeText(text); - // Editing invalidates a previous result; drop the stale chip. + // Editing invalidates a previous result; drop the stale status. if (resolver.status !== "idle") resolver.reset(); lastResolvedInput.current = null; }, @@ -105,73 +80,27 @@ export function ServerUrlField({ {label ? {label} : null} {hint ? {hint} : null} - - - - - - + - {resolver.status === "ok" ? ( - - {t("server_url.resolved", { url: resolver.resolvedUrl })} - - ) : null} - {resolver.status === "error" ? ( - - {errorMessage(t, resolver.reason, resolver.version, minVersion)} - - ) : null} + ); } - -function StatusChip({ - state, - onRetry, -}: { - state: ServerUrlResolverState; - onRetry: () => void; -}) { - if (state.status === "resolving") { - return ; - } - - if (state.status === "ok") { - const scheme = state.resolvedUrl.startsWith("https") ? "https" : "http"; - return ( - - - {scheme} - - ); - } - - if (state.status === "error") { - return ( - - - - ); - } - - return null; -}