Release v2.0.0
CI / Windows baseline (push) Canceled after 0s

This commit is contained in:
2026-09-11 18:29:33 +03:00
parent c5532f2087
commit c6b66a4ed7
8 changed files with 192 additions and 19 deletions
+17 -14
View File
@@ -80,6 +80,7 @@ import { useApplyFlow } from "./hooks/useApplyFlow";
import { useConfigurationDraft } from "./hooks/useConfigurationDraft";
import { useNoticeLog } from "./hooks/useNoticeLog";
import { parseProxy, type ParsedProxy } from "./lib/parseProxy";
import { refreshAfterAction } from "./lib/refreshAfterAction";
import { normalizeItemValue, type DraftItemType } from "./lib/profileItems";
import {
configChangeRows,
@@ -844,14 +845,15 @@ export function App() {
await nextFrame();
const installResult = await installProxiFyre();
const component = installResult.component;
const detectedSetupStatus = await getProxiFyreSetupStatus();
setComponents((current) => upsertComponent(current, component));
setSetupStatus(detectedSetupStatus);
await componentPackages.refreshLocal();
const refreshWarning = await refreshAfterAction(async () => {
setSetupStatus(await getProxiFyreSetupStatus());
await componentPackages.refreshLocal();
});
showNotice({
kind: "success",
title: "ProxiFyre установлен",
text: `${proxyfierDetails(component, false)}${
text: `${proxyfierDetails(component, false)}${refreshWarning}${
installResult.rebootRequired
? " Для завершения установки перезапусти Windows."
: ""
@@ -905,14 +907,15 @@ export function App() {
await nextFrame();
const uninstallResult = await uninstallProxiFyre();
const component = uninstallResult.component;
const detectedSetupStatus = await getProxiFyreSetupStatus();
setComponents((current) => upsertComponent(current, component));
setSetupStatus(detectedSetupStatus);
await componentPackages.refreshLocal();
const refreshWarning = await refreshAfterAction(async () => {
setSetupStatus(await getProxiFyreSetupStatus());
await componentPackages.refreshLocal();
});
showNotice({
kind: "success",
title: "ProxiFyre удален",
text: `Служба, папка установки ProxiFyre и Windows Packet Filter удалены.${
text: `Служба, папка установки ProxiFyre и Windows Packet Filter удалены.${refreshWarning}${
uninstallResult.rebootRequired
? " Для завершения удаления перезапусти Windows."
: ""
@@ -960,12 +963,12 @@ export function App() {
? await startSingBoxService()
: await stopSingBoxService();
setComponents((current) => upsertComponent(current, component));
await refreshSingBoxState();
const refreshWarning = await refreshAfterAction(refreshSingBoxState);
setProxyCheck(null);
showNotice({
kind: "success",
title: shouldRun ? "sing-box запущен" : "sing-box остановлен",
text: componentDetails(component, false),
text: componentDetails(component, false) + refreshWarning,
});
} catch (error) {
showPrivilegedActionFailure(
@@ -990,12 +993,12 @@ export function App() {
const installResult = await installSingBox();
const component = installResult.component;
setComponents((current) => upsertComponent(current, component));
await refreshSingBoxState();
const refreshWarning = await refreshAfterAction(refreshSingBoxState);
setProxyCheck(null);
showNotice({
kind: "success",
title: "Local sing-box установлен",
text: `${componentDetails(component, false)}${
text: `${componentDetails(component, false)}${refreshWarning}${
installResult.rebootRequired
? " Для завершения установки перезапусти Windows."
: ""
@@ -1021,12 +1024,12 @@ export function App() {
const uninstallResult = await uninstallSingBox();
const component = uninstallResult.component;
setComponents((current) => upsertComponent(current, component));
await refreshSingBoxState();
const refreshWarning = await refreshAfterAction(refreshSingBoxState);
setProxyCheck(null);
showNotice({
kind: "success",
title: "Local sing-box удален",
text: `Служба и папка установки Local sing-box удалены.${
text: `Служба и папка установки Local sing-box удалены.${refreshWarning}${
uninstallResult.rebootRequired
? " Для завершения удаления перезапусти Windows."
: ""
+21
View File
@@ -0,0 +1,21 @@
import { describe, expect, it } from "vitest";
import { refreshAfterAction } from "./refreshAfterAction";
describe("refreshAfterAction", () => {
it("keeps a completed action successful when the following read is denied", async () => {
const warning = await refreshAfterAction(async () => {
throw {
code: "storage_error",
message: "Отказано в доступе. (os error 5)",
details: [],
};
});
expect(warning).toContain("Действие выполнено");
expect(warning).toContain("состояние интерфейса не обновлено");
expect(warning).toContain("Отказано в доступе");
});
it("does not add a warning after a successful refresh", async () => {
expect(await refreshAfterAction(async () => undefined)).toBe("");
});
});
+11
View File
@@ -0,0 +1,11 @@
import { errorMessage } from "../viewModel";
/** A confirmed system action stays successful even if its following read fails. */
export async function refreshAfterAction(refresh: () => Promise<unknown>) {
try {
await refresh();
return "";
} catch (error) {
return ` Действие выполнено, но состояние интерфейса не обновлено: ${errorMessage(error)}`;
}
}