import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import type { ModelInfo } from "@/bindings"; import type { ModelCardStatus } from "./ModelCard"; import ModelCard from "./ModelCard"; import HandyTextLogo from "../icons/HandyTextLogo"; import { useModelStore } from "../../stores/modelStore"; interface OnboardingProps { onModelSelected: () => void; } const Onboarding: React.FC = ({ onModelSelected }) => { const { t } = useTranslation(); const { models, downloadModel, selectModel, downloadingModels, extractingModels, downloadProgress, downloadStats, } = useModelStore(); const [selectedModelId, setSelectedModelId] = useState(null); const isDownloading = selectedModelId !== null; // Watch for the selected model to finish downloading + extracting useEffect(() => { if (!selectedModelId) return; const model = models.find((m) => m.id === selectedModelId); const stillDownloading = selectedModelId in downloadingModels; const stillExtracting = selectedModelId in extractingModels; if (model?.is_downloaded && !stillDownloading && !stillExtracting) { // Model is ready — select it and transition selectModel(selectedModelId).then((success) => { if (success) { onModelSelected(); } else { toast.error(t("onboarding.errors.selectModel")); setSelectedModelId(null); } }); } }, [ selectedModelId, models, downloadingModels, extractingModels, selectModel, onModelSelected, ]); const handleDownloadModel = async (modelId: string) => { setSelectedModelId(modelId); const success = await downloadModel(modelId); if (!success) { toast.error(t("onboarding.downloadFailed")); setSelectedModelId(null); } }; const getModelStatus = (modelId: string): ModelCardStatus => { if (modelId in extractingModels) return "extracting"; if (modelId in downloadingModels) return "downloading"; return "downloadable"; }; const getModelDownloadProgress = (modelId: string): number | undefined => { return downloadProgress[modelId]?.percentage; }; const getModelDownloadSpeed = (modelId: string): number | undefined => { return downloadStats[modelId]?.speed; }; return (

{t("onboarding.subtitle")}

{models .filter((m: ModelInfo) => !m.is_downloaded) .filter((model: ModelInfo) => model.is_recommended) .map((model: ModelInfo) => ( ))} {models .filter((m: ModelInfo) => !m.is_downloaded) .filter((model: ModelInfo) => !model.is_recommended) .sort( (a: ModelInfo, b: ModelInfo) => Number(a.size_mb) - Number(b.size_mb), ) .map((model: ModelInfo) => ( ))}
); }; export default Onboarding;