144 lines
4.5 KiB
TypeScript
144 lines
4.5 KiB
TypeScript
import type {
|
|
ProxiFyreSetupProgress,
|
|
ProxiFyreSetupStatus,
|
|
} from "../../api/tauriCommands";
|
|
|
|
interface ProxiFyreSetupStripProps {
|
|
setupStatus: ProxiFyreSetupStatus | null;
|
|
progress: ProxiFyreSetupProgress | null;
|
|
}
|
|
|
|
const SETUP_PLACEHOLDERS: ProxiFyreSetupStatus["items"] = [
|
|
{
|
|
id: "vc-runtime",
|
|
name: "Среда запуска",
|
|
installed: false,
|
|
details: "Проверяю",
|
|
},
|
|
{
|
|
id: "packet-filter",
|
|
name: "Сетевой драйвер",
|
|
installed: false,
|
|
details: "Проверяю",
|
|
},
|
|
{
|
|
id: "proxifyre",
|
|
name: "Клиент ProxiFyre",
|
|
installed: false,
|
|
details: "Проверяю",
|
|
},
|
|
];
|
|
|
|
export function ProxiFyreSetupStrip({
|
|
setupStatus,
|
|
progress,
|
|
}: ProxiFyreSetupStripProps) {
|
|
const stripItems = setupStatus?.items ?? SETUP_PLACEHOLDERS;
|
|
const visibleProgress = isVisibleProgress(progress) ? progress : null;
|
|
const progressTone =
|
|
visibleProgress?.status === "failed" ? "failed" : "running";
|
|
const percent = clampPercent(visibleProgress?.percent ?? 0);
|
|
|
|
return (
|
|
<div
|
|
className={`setup-strip ${setupStatus?.ready ? "ready" : "attention"} ${visibleProgress ? "with-progress" : ""}`}
|
|
aria-label="Состав ProxiFyre"
|
|
>
|
|
<span className="setup-strip-title">Состав</span>
|
|
<div className="setup-strip-items">
|
|
{stripItems.map((item) => (
|
|
<div
|
|
className={`setup-strip-item ${setupItemClass(item, visibleProgress)}`}
|
|
key={item.id}
|
|
>
|
|
<span className="setup-strip-dot" aria-hidden="true" />
|
|
<strong>{setupItemUserName(item.id, item.name)}</strong>
|
|
<span>{setupItemShortStatus(item, visibleProgress)}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
{visibleProgress ? (
|
|
<div className={`setup-progress setup-progress--${progressTone}`}>
|
|
<div
|
|
className="setup-progress-track"
|
|
role="progressbar"
|
|
aria-valuemin={0}
|
|
aria-valuemax={100}
|
|
aria-valuenow={percent}
|
|
aria-label={visibleProgress.message}
|
|
>
|
|
<span
|
|
className="setup-progress-fill"
|
|
style={{ width: `${percent}%` }}
|
|
/>
|
|
</div>
|
|
<span className="setup-progress-message">
|
|
{visibleProgress.message}
|
|
</span>
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function setupItemClass(
|
|
item: ProxiFyreSetupStatus["items"][number],
|
|
progress: ProxiFyreSetupProgress | null,
|
|
) {
|
|
if (progress?.activeStep === item.id) {
|
|
if (progress.status === "failed") return "failed";
|
|
return "active";
|
|
}
|
|
if (item.installed) return "installed";
|
|
return "missing";
|
|
}
|
|
|
|
function setupItemUserName(id: string, fallbackName: string) {
|
|
if (id === "vc-runtime") return "Среда запуска";
|
|
if (id === "packet-filter") return "Сетевой драйвер";
|
|
if (id === "proxifyre") return "Клиент ProxiFyre";
|
|
return fallbackName;
|
|
}
|
|
|
|
function setupItemShortStatus(
|
|
item: ProxiFyreSetupStatus["items"][number],
|
|
progress: ProxiFyreSetupProgress | null,
|
|
) {
|
|
if (progress?.activeStep === item.id) {
|
|
if (progress.status === "failed") return "ошибка";
|
|
if (progress.status === "succeeded")
|
|
return progress.operation === "uninstall" ? "удалено" : "готово";
|
|
return "в процессе";
|
|
}
|
|
if (item.details === "Проверяю") return "проверяю";
|
|
if (!item.installed)
|
|
return progress?.operation === "uninstall" &&
|
|
progress.status === "succeeded"
|
|
? "удалено"
|
|
: "нужно установить";
|
|
if (item.id === "proxifyre")
|
|
return proxifyreSetupServiceSummary(item.version);
|
|
return "готово";
|
|
}
|
|
|
|
function proxifyreSetupServiceSummary(version: string | undefined) {
|
|
const normalized = version?.trim().toLowerCase() ?? "";
|
|
if (normalized.includes("не установлена")) return "служба не установлена";
|
|
if (normalized.includes("остановлена") || normalized.includes("не запущена"))
|
|
return "служба остановлена";
|
|
if (normalized.includes("запущена")) return "служба запущена";
|
|
return "готово";
|
|
}
|
|
|
|
function isVisibleProgress(
|
|
progress: ProxiFyreSetupProgress | null,
|
|
): progress is ProxiFyreSetupProgress {
|
|
if (!progress || progress.status === "idle") return false;
|
|
return progress.status === "running" || progress.status === "failed";
|
|
}
|
|
|
|
function clampPercent(value: number) {
|
|
if (!Number.isFinite(value)) return 0;
|
|
return Math.max(0, Math.min(100, Math.round(value)));
|
|
}
|