From d1a2d51351e815dec1d65322c518a2ffa9a6c483 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 17 Sep 2026 22:32:47 +0800 Subject: [PATCH] fix(plugins): block updates while connections are active --- .../plugins/PluginContributionsPanel.vue | 11 +- .../PluginContributionsPanelBatch.spec.ts | 31 ++- .../src/i18n/__tests__/backendErrors.spec.ts | 16 ++ apps/desktop/src/i18n/backend-errors.ts | 4 + apps/desktop/src/i18n/locales/en.ts | 3 + apps/desktop/src/i18n/locales/zh-CN.ts | 3 + apps/desktop/src/i18n/locales/zh-TW.ts | 3 + crates/dbx-core/src/connection.rs | 2 +- crates/dbx-core/src/plugins.rs | 66 +++++-- crates/dbx-core/src/plugins/host.rs | 72 +++++++ crates/dbx-core/src/plugins/installer.rs | 109 ++++++++++- crates/dbx-core/src/plugins/lifecycle.rs | 183 ++++++++++++++++++ crates/dbx-core/src/plugins/marketplace.rs | 79 +++++++- crates/dbx-web/src/routes/plugins.rs | 13 +- src-tauri/src/commands/plugins.rs | 16 +- 15 files changed, 571 insertions(+), 40 deletions(-) create mode 100644 crates/dbx-core/src/plugins/lifecycle.rs diff --git a/apps/desktop/src/components/plugins/PluginContributionsPanel.vue b/apps/desktop/src/components/plugins/PluginContributionsPanel.vue index 0e6074e380..1094760bb4 100644 --- a/apps/desktop/src/components/plugins/PluginContributionsPanel.vue +++ b/apps/desktop/src/components/plugins/PluginContributionsPanel.vue @@ -204,7 +204,7 @@ async function installMarketplaceListing(listing: MarketplacePluginListing) { installedPlugins.value = await api.listPlugins(); selectPlugin(result.plugin.manifest.id); } catch (cause) { - toast(cause instanceof Error ? cause.message : String(cause), 8000); + toast(translateBackendError(t, cause), 8000); // A failed install can still have mutated the store (a partially replaced version directory, for // instance), so re-read the installed list instead of leaving the card on state it may no longer // describe. @@ -218,8 +218,9 @@ function batchSummaryKey(outcome: { succeeded: unknown[]; failed: { name: string return outcome.failed.length ? "pluginPlatform.batchSummaryWithFailures" : "pluginPlatform.batchSummary"; } -function reportBatchSummary(outcome: { succeeded: unknown[]; failed: { name: string }[] }) { +function reportBatchSummary(outcome: { succeeded: unknown[]; failed: { name: string; error: string }[] }) { const failedNames = outcome.failed.map((failure) => failure.name).join("、"); + error.value = outcome.failed.map((failure) => `${failure.name}: ${translateBackendError(t, failure.error)}`).join("\n"); toast(t(batchSummaryKey(outcome), { success: outcome.succeeded.length, failed: outcome.failed.length, names: failedNames }), outcome.failed.length ? 8000 : 4000); } @@ -227,7 +228,7 @@ async function refreshAfterBatch() { try { installedPlugins.value = await api.listPlugins(); } catch (cause) { - error.value = t("pluginPlatform.batchRefreshFailed", { error: cause instanceof Error ? cause.message : String(cause) }); + error.value = [error.value, t("pluginPlatform.batchRefreshFailed", { error: cause instanceof Error ? cause.message : String(cause) })].filter(Boolean).join("\n"); } } @@ -661,7 +662,7 @@ async function rollbackSelectedPlugin() { installedPlugins.value = await api.listPlugins(); selectPlugin(result.plugin.manifest.id); } catch (cause) { - toast(cause instanceof Error ? cause.message : String(cause), 5000); + toast(translateBackendError(t, cause), 8000); } finally { operating.value = false; } @@ -732,7 +733,7 @@ onBeforeUnmount(() => {