hide incompatible frigate+ models behind a toggle

This commit is contained in:
Josh Hawkins
2026-10-16 08:14:49 -05:00
parent 4f1efb97d7
commit ab671bdd46
2 changed files with 29 additions and 6 deletions
@@ -1310,6 +1310,7 @@
"loadingAvailableModels": "Loading available models…", "loadingAvailableModels": "Loading available models…",
"selectModel": "Select a model", "selectModel": "Select a model",
"noModelsAvailable": "No models available", "noModelsAvailable": "No models available",
"showIncompatible": "Show incompatible models",
"filter": { "filter": {
"ariaLabel": "Filter models by type", "ariaLabel": "Filter models by type",
"baseModels": "Base Models", "baseModels": "Base Models",
@@ -1,4 +1,4 @@
import { ReactNode, useMemo, useState } from "react"; import { ReactNode, useState } from "react";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import useSWR from "swr"; import useSWR from "swr";
import axios from "axios"; import axios from "axios";
@@ -10,6 +10,7 @@ import {
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import type { FrigateConfig } from "@/types/frigateConfig"; import type { FrigateConfig } from "@/types/frigateConfig";
import { describeSupportedDetectors } from "@/utils/plusModels"; import { describeSupportedDetectors } from "@/utils/plusModels";
@@ -79,10 +80,7 @@ export function ModelSourcePicker({
}, },
}); });
const entries = useMemo( const [showIncompatible, setShowIncompatible] = useState(false);
() => Object.entries(availableModels ?? {}),
[availableModels],
);
// the tab cannot be derived from the path alone: switching to Frigate+ // the tab cannot be derived from the path alone: switching to Frigate+
// leaves the path untouched until a model is picked // leaves the path untouched until a model is picked
@@ -102,6 +100,16 @@ export function ModelSourcePicker({
const isCompatible = (model: FrigatePlusModel) => const isCompatible = (model: FrigatePlusModel) =>
!detector || model.supportedDetectors.includes(detector); !detector || model.supportedDetectors.includes(detector);
const allEntries = Object.entries(availableModels ?? {});
const hasIncompatible = allEntries.some(([, model]) => !isCompatible(model));
// the saved model stays listed even when incompatible
const entries = showIncompatible
? allEntries
: allEntries.filter(
([id, model]) => isCompatible(model) || id === selectedId,
);
if (!plusEnabled) { if (!plusEnabled) {
return <div className="space-y-6">{customFields}</div>; return <div className="space-y-6">{customFields}</div>;
} }
@@ -123,7 +131,21 @@ export function ModelSourcePicker({
</TabsList> </TabsList>
<TabsContent value="plus" className="space-y-1"> <TabsContent value="plus" className="space-y-1">
<div className="flex max-w-2xl items-center justify-between">
<Label>{t("frigatePlus.modelInfo.availableModels")}</Label> <Label>{t("frigatePlus.modelInfo.availableModels")}</Label>
{hasIncompatible && (
<div className="flex items-center gap-2">
<Label htmlFor="plus-show-incompatible" className="text-xs">
{t("frigatePlus.modelInfo.showIncompatible")}
</Label>
<Switch
id="plus-show-incompatible"
checked={showIncompatible}
onCheckedChange={setShowIncompatible}
/>
</div>
)}
</div>
<Select <Select
value={selectedId ?? ""} value={selectedId ?? ""}
onValueChange={(id) => onPathChange(`${PLUS_PREFIX}${id}`)} onValueChange={(id) => onPathChange(`${PLUS_PREFIX}${id}`)}