fix(review): effective streamystats gate, honest refresh toast, locked jellyseerr url, i18n admin notice

This commit is contained in:
Gauvain
2026-07-17 17:41:12 +02:00
parent b7bdd99cdd
commit fd4215407d
5 changed files with 32 additions and 11 deletions

View File

@@ -28,7 +28,9 @@ export default function MarlinSearchPage() {
const searchEngineLocked = pluginSettings?.searchEngine?.locked === true;
const marlinUrlLocked = pluginSettings?.marlinServerUrl?.locked === true;
const hasStreamystats = !!pluginSettings?.streamyStatsServerUrl?.value;
// Effective (user/admin merged) URL, same source the search screen uses —
// the raw plugin value misses a user-configured Streamystats.
const hasStreamystats = !!settings?.streamyStatsServerUrl;
const onSave = (val: string) => {
updateSettings({
@@ -74,6 +76,9 @@ export default function MarlinSearchPage() {
"home.settings.plugins.marlin_search.enable_marlin_search",
)}
disabledByAdmin={searchEngineLocked}
// Streamystats owns the search engine while configured — block the
// row tap too, not just the Switch, so it can't force "Jellyfin".
disabled={hasStreamystats}
onPress={() => {
updateSettings({ searchEngine: "Jellyfin" });
queryClient.invalidateQueries({ queryKey: ["search"] });

View File

@@ -13,8 +13,15 @@ export default function PluginsPage() {
const { refreshStreamyfinPluginSettings } = useSettings();
const handleRefreshFromServer = useCallback(async () => {
await refreshStreamyfinPluginSettings();
toast.success(t("home.settings.plugins.streamystats.toasts.refreshed"));
// Returns undefined when the API call fails (handled internally).
const refreshed = await refreshStreamyfinPluginSettings();
if (refreshed) {
toast.success(t("home.settings.plugins.streamystats.toasts.refreshed"));
} else {
toast.error(
t("home.settings.plugins.streamystats.toasts.refresh_failed"),
);
}
}, [refreshStreamyfinPluginSettings, t]);
return (

View File

@@ -1,5 +1,6 @@
import { Ionicons } from "@expo/vector-icons";
import type { PropsWithChildren, ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { TouchableOpacity, View, type ViewProps } from "react-native";
import { Text } from "../common/Text";
@@ -32,7 +33,10 @@ export const ListItem: React.FC<PropsWithChildren<Props>> = ({
disabledByAdmin = false,
...viewProps
}) => {
const effectiveSubtitle = disabledByAdmin ? "Disabled by admin" : subtitle;
const { t } = useTranslation();
const effectiveSubtitle = disabledByAdmin
? t("home.settings.disabled_by_admin")
: subtitle;
const isDisabled = disabled || disabledByAdmin;
if (onPress)
return (

View File

@@ -33,22 +33,25 @@ export const JellyseerrSettings = () => {
string | undefined
>(settings?.jellyseerrServerUrl || undefined);
// When the URL is admin-pinned, ignore any locally-typed value so the login
// targets the same server the (read-only) input displays.
const effectiveServerUrl = urlLocked
? settings?.jellyseerrServerUrl
: jellyseerrServerUrl || settings?.jellyseerrServerUrl;
const loginToJellyseerrMutation = useMutation({
mutationFn: async () => {
if (!jellyseerrServerUrl && !settings?.jellyseerrServerUrl)
throw new Error("Missing server url");
if (!effectiveServerUrl) 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 jellyseerrTempApi = new JellyseerrApi(effectiveServerUrl);
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 });
updateSettings({ jellyseerrServerUrl: effectiveServerUrl });
},
onError: () => {
toast.error(t("jellyseerr.failed_to_login"));
@@ -149,7 +152,7 @@ export const JellyseerrSettings = () => {
/>
{urlLocked && (
<Text className='text-xs text-red-600 mb-2'>
Disabled by admin
{t("home.settings.disabled_by_admin")}
</Text>
)}
</View>

View File

@@ -118,6 +118,7 @@
},
"settings": {
"settings_title": "Settings",
"disabled_by_admin": "Disabled by admin",
"log_out_button": "Log out",
"switch_user": {
"title": "Switch user",
@@ -370,6 +371,7 @@
"toasts": {
"saved": "Saved",
"refreshed": "Settings refreshed from server",
"refresh_failed": "Couldn't refresh settings from server",
"disabled": "Streamystats disabled"
},
"refresh_from_server": "Refresh settings from server"