import { baseUrl } from "@/api/baseUrl"; import ClassificationModelWizardDialog from "@/components/classification/ClassificationModelWizardDialog"; import ActivityIndicator from "@/components/indicators/activity-indicator"; import { ImageShadowOverlay } from "@/components/overlay/ImageShadowOverlay"; import { Button } from "@/components/ui/button"; import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; import useOptimisticState from "@/hooks/use-optimistic-state"; import { cn } from "@/lib/utils"; import { CustomClassificationModelConfig, FrigateConfig, } from "@/types/frigateConfig"; import { useMemo, useState } from "react"; import { isMobile } from "react-device-detect"; import { useTranslation } from "react-i18next"; import { FaFolderPlus } from "react-icons/fa"; import useSWR from "swr"; const allModelTypes = ["objects", "states"] as const; type ModelType = (typeof allModelTypes)[number]; type ModelSelectionViewProps = { onClick: (model: CustomClassificationModelConfig) => void; }; export default function ModelSelectionView({ onClick, }: ModelSelectionViewProps) { const { t } = useTranslation(["views/classificationModel"]); const [page, setPage] = useState("objects"); const [pageToggle, setPageToggle] = useOptimisticState(page, setPage, 100); const { data: config } = useSWR("config", { revalidateOnFocus: false, }); // data const classificationConfigs = useMemo(() => { if (!config) { return []; } return Object.values(config.classification.custom); }, [config]); const selectedClassificationConfigs = useMemo(() => { return classificationConfigs.filter((model) => { if (pageToggle == "objects" && model.object_config != undefined) { return true; } if (pageToggle == "states" && model.state_config != undefined) { return true; } return false; }); }, [classificationConfigs, pageToggle]); // new model wizard const [newModel, setNewModel] = useState(false); if (!config) { return ; } if (classificationConfigs.length == 0) { return
You need to setup a custom model configuration.
; } return (
setNewModel(false)} />
{ if (value) { // Restrict viewer navigation setPageToggle(value); } }} > {allModelTypes.map((item) => (
{t("menu." + item)}
))}
{selectedClassificationConfigs.map((config) => ( onClick(config)} /> ))}
); } type ModelCardProps = { config: CustomClassificationModelConfig; onClick: () => void; }; function ModelCard({ config, onClick }: ModelCardProps) { const { data: dataset } = useSWR<{ [id: string]: string[]; }>(`classification/${config.name}/dataset`, { revalidateOnFocus: false }); const coverImage = useMemo(() => { if (!dataset?.length) { return undefined; } const keys = Object.keys(dataset).filter((key) => key != "none"); const selectedKey = keys[0]; return { name: selectedKey, img: dataset[selectedKey][0], }; }, [dataset]); return (
onClick()} >
{config.name}
); }