feat(settings): split driver store paths
This commit is contained in:
parent
3bd0f50ff7
commit
0b9aef1ca8
|
|
@ -45,8 +45,12 @@ import { useSettingsStore } from "@/stores/settingsStore";
|
|||
import type { DriverStorePathInfo } from "@/lib/api";
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const driverStoreDir = computed(() => settingsStore.desktopSettings.driver_store_dir ?? null);
|
||||
const driverStoreDirMigrating = ref(false);
|
||||
type DriverStoreDirKind = "plugin" | "agent";
|
||||
|
||||
const legacyDriverStoreDir = computed(() => settingsStore.desktopSettings.driver_store_dir ?? null);
|
||||
const pluginStoreDir = computed(() => settingsStore.desktopSettings.plugin_store_dir ?? null);
|
||||
const agentStoreDir = computed(() => settingsStore.desktopSettings.agent_store_dir ?? null);
|
||||
const driverStoreDirMigrating = ref<DriverStoreDirKind | null>(null);
|
||||
const currentDriverStorePath = ref<DriverStorePathInfo | null>(null);
|
||||
|
||||
async function loadDriverStorePath() {
|
||||
|
|
@ -58,49 +62,82 @@ async function loadDriverStorePath() {
|
|||
}
|
||||
}
|
||||
|
||||
const driverStoreDirDisplay = computed(() => {
|
||||
if (currentDriverStorePath.value) {
|
||||
return driverStoreDir.value || currentDriverStorePath.value.plugins_dir;
|
||||
function configuredDriverStoreDir(kind: DriverStoreDirKind): string | null {
|
||||
if (kind === "plugin") {
|
||||
return pluginStoreDir.value ?? (legacyDriverStoreDir.value ? `${legacyDriverStoreDir.value}/plugins` : null);
|
||||
}
|
||||
return driverStoreDir.value || t("driverStore.driverStoreDirDefault");
|
||||
});
|
||||
return agentStoreDir.value ?? (legacyDriverStoreDir.value ? `${legacyDriverStoreDir.value}/agents` : null);
|
||||
}
|
||||
|
||||
async function chooseDriverStoreDir() {
|
||||
function actualDriverStoreDir(kind: DriverStoreDirKind): string | null {
|
||||
if (!currentDriverStorePath.value) return null;
|
||||
return kind === "plugin" ? currentDriverStorePath.value.plugins_dir : currentDriverStorePath.value.agents_dir;
|
||||
}
|
||||
|
||||
function driverStoreDirDisplay(kind: DriverStoreDirKind): string {
|
||||
return actualDriverStoreDir(kind) ?? configuredDriverStoreDir(kind) ?? t("driverStore.driverStoreDirDefault");
|
||||
}
|
||||
|
||||
function driverStoreTargetLabel(kind: DriverStoreDirKind): string {
|
||||
return kind === "plugin" ? t("driverStore.pluginStoreDir") : t("driverStore.agentStoreDir");
|
||||
}
|
||||
|
||||
const driverStorePathRows = computed(() => [
|
||||
{
|
||||
kind: "plugin" as const,
|
||||
label: t("driverStore.pluginStoreDir"),
|
||||
description: t("driverStore.pluginStoreDirDescription"),
|
||||
display: driverStoreDirDisplay("plugin"),
|
||||
custom: Boolean(pluginStoreDir.value || legacyDriverStoreDir.value),
|
||||
},
|
||||
{
|
||||
kind: "agent" as const,
|
||||
label: t("driverStore.agentStoreDir"),
|
||||
description: t("driverStore.agentStoreDirDescription"),
|
||||
display: driverStoreDirDisplay("agent"),
|
||||
custom: Boolean(agentStoreDir.value || legacyDriverStoreDir.value),
|
||||
},
|
||||
]);
|
||||
|
||||
async function chooseDriverStoreDir(kind: DriverStoreDirKind) {
|
||||
if (isWeb || driverStoreDirMigrating.value) return;
|
||||
const { open } = await import("@tauri-apps/plugin-dialog");
|
||||
const selected = await open({
|
||||
title: t("driverStore.driverStoreDirDialogTitle"),
|
||||
title: t("driverStore.driverStoreDirDialogTitle", { target: driverStoreTargetLabel(kind) }),
|
||||
directory: true,
|
||||
multiple: false,
|
||||
});
|
||||
if (typeof selected === "string") {
|
||||
await applyDriverStoreDir(selected);
|
||||
await applyDriverStoreDir(kind, selected);
|
||||
}
|
||||
}
|
||||
|
||||
async function resetDriverStoreDir() {
|
||||
async function resetDriverStoreDir(kind: DriverStoreDirKind) {
|
||||
if (driverStoreDirMigrating.value) return;
|
||||
await applyDriverStoreDir(null);
|
||||
await applyDriverStoreDir(kind, null);
|
||||
}
|
||||
|
||||
async function applyDriverStoreDir(newDir: string | null) {
|
||||
async function applyDriverStoreDir(kind: DriverStoreDirKind, newDir: string | null) {
|
||||
if (driverStoreDirMigrating.value) return;
|
||||
|
||||
const confirmed = window.confirm(t("driverStore.driverStoreDirConfirm"));
|
||||
const target = driverStoreTargetLabel(kind);
|
||||
const confirmed = window.confirm(t("driverStore.driverStoreDirConfirm", { target }));
|
||||
if (!confirmed) return;
|
||||
|
||||
driverStoreDirMigrating.value = true;
|
||||
driverStoreDirMigrating.value = kind;
|
||||
try {
|
||||
const result = await api.setDriverStoreDir(newDir);
|
||||
const result = kind === "plugin" ? await api.setPluginStoreDir(newDir) : await api.setAgentStoreDir(newDir);
|
||||
settingsStore.desktopSettings.driver_store_dir = result.driver_store_dir;
|
||||
toast(t("driverStore.driverStoreDirSuccess"));
|
||||
settingsStore.desktopSettings.plugin_store_dir = result.plugin_store_dir;
|
||||
settingsStore.desktopSettings.agent_store_dir = result.agent_store_dir;
|
||||
toast(t("driverStore.driverStoreDirSuccess", { target }));
|
||||
// Restart the app to use the new paths
|
||||
const { relaunch } = await import("@tauri-apps/plugin-process");
|
||||
relaunch();
|
||||
} catch (e: any) {
|
||||
toast(t("driverStore.driverStoreDirMigrationFailed", { error: e?.message || String(e) }), 5000);
|
||||
} finally {
|
||||
driverStoreDirMigrating.value = false;
|
||||
driverStoreDirMigrating.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1226,28 +1263,39 @@ watch(driverStoreTab, (tab) => {
|
|||
<div v-if="!isWeb" class="rounded-xl border bg-muted/20 p-4 space-y-3">
|
||||
<div class="text-sm font-medium">{{ t("driverStore.driverStoreDir") }}</div>
|
||||
<p class="text-xs text-muted-foreground">{{ t("driverStore.driverStoreDirDescription") }}</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<div class="min-w-0 flex-1 rounded-md border bg-background px-3 py-2 text-xs font-mono truncate">
|
||||
{{ driverStoreDirDisplay }}
|
||||
<div class="space-y-2.5">
|
||||
<div v-for="row in driverStorePathRows" :key="row.kind" class="rounded-lg border bg-background/50 p-3">
|
||||
<div class="mb-2 flex items-start justify-between gap-3">
|
||||
<div class="min-w-0 text-xs leading-5">
|
||||
<span class="font-medium">{{ row.label }}</span>
|
||||
<span class="ml-2 text-[11px] text-muted-foreground">{{ row.description }}</span>
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom" class="max-w-100 break-all text-xs">
|
||||
{{ driverStoreDirDisplay }}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Button variant="outline" size="sm" class="shrink-0 gap-1" :disabled="driverStoreDirMigrating" @click="chooseDriverStoreDir">
|
||||
<FolderSync class="h-3.5 w-3.5" />
|
||||
{{ t("driverStore.driverStoreDirChange") }}
|
||||
</Button>
|
||||
<Button v-if="driverStoreDir" variant="ghost" size="sm" class="shrink-0 gap-1 text-muted-foreground" :disabled="driverStoreDirMigrating" @click="resetDriverStoreDir">
|
||||
{{ t("driverStore.driverStoreDirReset") }}
|
||||
</Button>
|
||||
<Loader2 v-if="driverStoreDirMigrating === row.kind" class="mt-0.5 h-3.5 w-3.5 shrink-0 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<div class="min-w-0 flex-1 rounded-md border bg-background px-3 py-2 text-xs font-mono truncate">
|
||||
{{ row.display }}
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom" class="max-w-100 break-all text-xs">
|
||||
{{ row.display }}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Button variant="outline" size="sm" class="shrink-0 gap-1" :disabled="Boolean(driverStoreDirMigrating)" @click="chooseDriverStoreDir(row.kind)">
|
||||
<FolderSync class="h-3.5 w-3.5" />
|
||||
{{ t("driverStore.driverStoreDirChange") }}
|
||||
</Button>
|
||||
<Button v-if="row.custom" variant="ghost" size="sm" class="shrink-0 gap-1 text-muted-foreground" :disabled="Boolean(driverStoreDirMigrating)" @click="resetDriverStoreDir(row.kind)">
|
||||
{{ t("driverStore.driverStoreDirReset") }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="driverStoreDirMigrating" class="text-xs text-muted-foreground flex items-center gap-1.5">
|
||||
<Loader2 class="h-3 w-3 animate-spin" />
|
||||
{{ t("driverStore.driverStoreDirMigrating") }}
|
||||
{{ t("driverStore.driverStoreDirMigrating", { target: driverStoreTargetLabel(driverStoreDirMigrating) }) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -2296,15 +2296,19 @@
|
|||
runtimeRestartSuccess: "{label} runtime restarted",
|
||||
runtimeRestartFailed: "Failed to restart {label}: {error}",
|
||||
driverStoreDir: "Driver Store Path",
|
||||
driverStoreDirDescription: "Customize where drivers and JREs are stored. The app will restart automatically after migration.",
|
||||
driverStoreDirDescription: "Set separate storage locations for the JDBC plugin and Agent/JRE data. The app will restart automatically after migration.",
|
||||
pluginStoreDir: "JDBC plugin directory",
|
||||
pluginStoreDirDescription: "Stores the JDBC plugin, Maven resolver, and JDBC driver jars.",
|
||||
agentStoreDir: "Agent / JRE directory",
|
||||
agentStoreDirDescription: "Stores Agent driver packages, managed JREs, and runtime cache.",
|
||||
driverStoreDirDefault: "Default (install directory)",
|
||||
driverStoreDirChange: "Change",
|
||||
driverStoreDirReset: "Reset to Default",
|
||||
driverStoreDirMigrating: "Migrating driver data…",
|
||||
driverStoreDirConfirm: "Changing the driver store path will migrate all driver data to the new location. Active driver connections will be disconnected during migration. The app will restart automatically after migration. Continue?",
|
||||
driverStoreDirMigrating: "Migrating {target}…",
|
||||
driverStoreDirConfirm: "Changing {target} will migrate the related driver data to the new location. Related driver connections may be disconnected during migration. The app will restart automatically after migration. Continue?",
|
||||
driverStoreDirMigrationFailed: "Driver store migration failed: {error}",
|
||||
driverStoreDirDialogTitle: "Select Driver Store Directory",
|
||||
driverStoreDirSuccess: "Driver store path changed, restarting…",
|
||||
driverStoreDirDialogTitle: "Select {target}",
|
||||
driverStoreDirSuccess: "{target} changed, restarting…",
|
||||
},
|
||||
databaseExport: {
|
||||
title: "Export Database",
|
||||
|
|
|
|||
|
|
@ -2000,15 +2000,19 @@
|
|||
runtimeRestartSuccess: "Runtime de {label} reiniciado",
|
||||
runtimeRestartFailed: "Error al reiniciar {label}: {error}",
|
||||
driverStoreDir: "Ruta de almacenamiento de controladores",
|
||||
driverStoreDirDescription: "Personaliza dónde se almacenan los controladores y JRE. La aplicación se reiniciará automáticamente después de la migración.",
|
||||
driverStoreDirDescription: "Configura ubicaciones separadas para el plugin JDBC y los datos de Agent/JRE. La aplicación se reiniciará automáticamente después de la migración.",
|
||||
pluginStoreDir: "Directorio del plugin JDBC",
|
||||
pluginStoreDirDescription: "Almacena el plugin JDBC, Maven resolver y los jars de controladores JDBC.",
|
||||
agentStoreDir: "Directorio Agent / JRE",
|
||||
agentStoreDirDescription: "Almacena paquetes de controladores Agent, JRE gestionados y caché de runtime.",
|
||||
driverStoreDirDefault: "Predeterminado (directorio de instalación)",
|
||||
driverStoreDirChange: "Cambiar",
|
||||
driverStoreDirReset: "Restablecer",
|
||||
driverStoreDirMigrating: "Migrando datos de controladores…",
|
||||
driverStoreDirConfirm: "Cambiar la ruta de almacenamiento migrará todos los datos de controladores a la nueva ubicación. Las conexiones activas se desconectarán durante la migración. La aplicación se reiniciará automáticamente después. ¿Continuar?",
|
||||
driverStoreDirMigrating: "Migrando {target}…",
|
||||
driverStoreDirConfirm: "Cambiar {target} migrará los datos relacionados a la nueva ubicación. Las conexiones relacionadas pueden desconectarse durante la migración. La aplicación se reiniciará automáticamente después. ¿Continuar?",
|
||||
driverStoreDirMigrationFailed: "Error en la migración de controladores: {error}",
|
||||
driverStoreDirDialogTitle: "Seleccionar directorio de controladores",
|
||||
driverStoreDirSuccess: "Ruta de almacenamiento cambiada, reiniciando…",
|
||||
driverStoreDirDialogTitle: "Seleccionar {target}",
|
||||
driverStoreDirSuccess: "{target} cambiado, reiniciando…",
|
||||
},
|
||||
databaseExport: {
|
||||
title: "Exportar base de datos",
|
||||
|
|
|
|||
|
|
@ -2069,15 +2069,19 @@
|
|||
runtimeRestartSuccess: "Runtime {label} riavviato",
|
||||
runtimeRestartFailed: "Riavvio di {label} non riuscito: {error}",
|
||||
driverStoreDir: "Percorso archiviazione driver",
|
||||
driverStoreDirDescription: "Personalizza dove vengono archiviati driver e JRE. L'app si riavvierà automaticamente dopo la migrazione.",
|
||||
driverStoreDirDescription: "Configura percorsi separati per il plugin JDBC e i dati Agent/JRE. L'app si riavvierà automaticamente dopo la migrazione.",
|
||||
pluginStoreDir: "Directory plugin JDBC",
|
||||
pluginStoreDirDescription: "Archivia il plugin JDBC, Maven resolver e i jar dei driver JDBC.",
|
||||
agentStoreDir: "Directory Agent / JRE",
|
||||
agentStoreDirDescription: "Archivia pacchetti driver Agent, JRE gestiti e cache runtime.",
|
||||
driverStoreDirDefault: "Predefinito (directory di installazione)",
|
||||
driverStoreDirChange: "Cambia",
|
||||
driverStoreDirReset: "Ripristina",
|
||||
driverStoreDirMigrating: "Migrazione dati driver in corso…",
|
||||
driverStoreDirConfirm: "La modifica del percorso di archiviazione migrerà tutti i dati dei driver nella nuova posizione. Le connessioni attive verranno disconnesse durante la migrazione. L'app si riavvierà automaticamente dopo. Continuare?",
|
||||
driverStoreDirMigrating: "Migrazione {target} in corso…",
|
||||
driverStoreDirConfirm: "La modifica di {target} migrerà i dati correlati nella nuova posizione. Le connessioni correlate potrebbero essere disconnesse durante la migrazione. L'app si riavvierà automaticamente dopo. Continuare?",
|
||||
driverStoreDirMigrationFailed: "Migrazione driver fallita: {error}",
|
||||
driverStoreDirDialogTitle: "Seleziona directory driver",
|
||||
driverStoreDirSuccess: "Percorso cambiato, riavvio in corso…",
|
||||
driverStoreDirDialogTitle: "Seleziona {target}",
|
||||
driverStoreDirSuccess: "{target} cambiato, riavvio in corso…",
|
||||
},
|
||||
databaseExport: {
|
||||
title: "Esporta Database",
|
||||
|
|
|
|||
|
|
@ -2080,15 +2080,19 @@
|
|||
runtimeRestartSuccess: "Runtime {label} reiniciado",
|
||||
runtimeRestartFailed: "Falha ao reiniciar {label}: {error}",
|
||||
driverStoreDir: "Caminho de armazenamento de drivers",
|
||||
driverStoreDirDescription: "Personalize onde drivers e JREs são armazenados. O app será reiniciado automaticamente após a migração.",
|
||||
driverStoreDirDescription: "Configure locais separados para o plugin JDBC e dados de Agent/JRE. O app será reiniciado automaticamente após a migração.",
|
||||
pluginStoreDir: "Diretório do plugin JDBC",
|
||||
pluginStoreDirDescription: "Armazena o plugin JDBC, Maven resolver e jars de drivers JDBC.",
|
||||
agentStoreDir: "Diretório Agent / JRE",
|
||||
agentStoreDirDescription: "Armazena pacotes de drivers Agent, JREs gerenciados e cache de runtime.",
|
||||
driverStoreDirDefault: "Padrão (diretório de instalação)",
|
||||
driverStoreDirChange: "Alterar",
|
||||
driverStoreDirReset: "Restaurar padrão",
|
||||
driverStoreDirMigrating: "Migrando dados de drivers…",
|
||||
driverStoreDirConfirm: "Alterar o caminho de armazenamento migrará todos os dados de drivers para o novo local. Conexões ativas serão desconectadas durante a migração. O app será reiniciado automaticamente após. Continuar?",
|
||||
driverStoreDirMigrating: "Migrando {target}…",
|
||||
driverStoreDirConfirm: "Alterar {target} migrará os dados relacionados para o novo local. Conexões relacionadas podem ser desconectadas durante a migração. O app será reiniciado automaticamente após. Continuar?",
|
||||
driverStoreDirMigrationFailed: "Falha na migração de drivers: {error}",
|
||||
driverStoreDirDialogTitle: "Selecionar diretório de drivers",
|
||||
driverStoreDirSuccess: "Caminho alterado, reiniciando…",
|
||||
driverStoreDirDialogTitle: "Selecionar {target}",
|
||||
driverStoreDirSuccess: "{target} alterado, reiniciando…",
|
||||
},
|
||||
databaseExport: {
|
||||
title: "Exportar banco de dados",
|
||||
|
|
|
|||
|
|
@ -2320,15 +2320,19 @@
|
|||
runtimeRestartSuccess: "{label} 运行时已重启",
|
||||
runtimeRestartFailed: "重启 {label} 失败: {error}",
|
||||
driverStoreDir: "驱动存储路径",
|
||||
driverStoreDirDescription: "自定义驱动和 JRE 的存储位置,迁移后应用将自动重启。",
|
||||
driverStoreDirDescription: "JDBC 插件和 Agent/JRE 可分别指定存储位置,迁移后应用将自动重启。",
|
||||
pluginStoreDir: "JDBC 插件目录",
|
||||
pluginStoreDirDescription: "存放 JDBC 插件、Maven resolver 和 JDBC 驱动 jar。",
|
||||
agentStoreDir: "Agent / JRE 目录",
|
||||
agentStoreDirDescription: "存放 Agent 驱动包、托管 JRE 和运行时缓存。",
|
||||
driverStoreDirDefault: "默认(安装目录)",
|
||||
driverStoreDirChange: "更改",
|
||||
driverStoreDirReset: "恢复默认",
|
||||
driverStoreDirMigrating: "正在迁移驱动数据…",
|
||||
driverStoreDirConfirm: "更改驱动存储路径将迁移所有驱动数据到新位置,迁移期间会断开驱动连接。迁移完成后应用将自动重启。是否继续?",
|
||||
driverStoreDirMigrating: "正在迁移 {target}…",
|
||||
driverStoreDirConfirm: "更改 {target} 将迁移对应驱动数据到新位置,迁移期间可能会断开相关驱动连接。迁移完成后应用将自动重启。是否继续?",
|
||||
driverStoreDirMigrationFailed: "驱动存储路径迁移失败:{error}",
|
||||
driverStoreDirDialogTitle: "选择驱动存储目录",
|
||||
driverStoreDirSuccess: "驱动存储路径已更改,正在重启…",
|
||||
driverStoreDirDialogTitle: "选择 {target}",
|
||||
driverStoreDirSuccess: "{target} 已更改,正在重启…",
|
||||
},
|
||||
databaseExport: {
|
||||
title: "导出数据库",
|
||||
|
|
|
|||
|
|
@ -2075,15 +2075,19 @@
|
|||
runtimeRestartSuccess: "{label} 執行環境已重新啟動",
|
||||
runtimeRestartFailed: "重新啟動 {label} 失敗: {error}",
|
||||
driverStoreDir: "驅動儲存路徑",
|
||||
driverStoreDirDescription: "自訂驅動和 JRE 的儲存位置,遷移後應用將自動重啟。",
|
||||
driverStoreDirDescription: "JDBC 外掛程式和 Agent/JRE 可分別指定儲存位置,遷移後應用將自動重啟。",
|
||||
pluginStoreDir: "JDBC 外掛程式目錄",
|
||||
pluginStoreDirDescription: "存放 JDBC 外掛程式、Maven resolver 和 JDBC 驅動 jar。",
|
||||
agentStoreDir: "Agent / JRE 目錄",
|
||||
agentStoreDirDescription: "存放 Agent 驅動包、託管 JRE 和執行環境快取。",
|
||||
driverStoreDirDefault: "預設(安裝目錄)",
|
||||
driverStoreDirChange: "更改",
|
||||
driverStoreDirReset: "恢復預設",
|
||||
driverStoreDirMigrating: "正在遷移驅動資料…",
|
||||
driverStoreDirConfirm: "更改驅動儲存路徑將遷移所有驅動資料到新位置,遷移期間會斷開驅動連線。遷移完成後應用將自動重啟。是否繼續?",
|
||||
driverStoreDirMigrating: "正在遷移 {target}…",
|
||||
driverStoreDirConfirm: "更改 {target} 將遷移對應驅動資料到新位置,遷移期間可能會斷開相關驅動連線。遷移完成後應用將自動重啟。是否繼續?",
|
||||
driverStoreDirMigrationFailed: "驅動儲存路徑遷移失敗:{error}",
|
||||
driverStoreDirDialogTitle: "選擇驅動儲存目錄",
|
||||
driverStoreDirSuccess: "驅動儲存路徑已更改,正在重啟…",
|
||||
driverStoreDirDialogTitle: "選擇 {target}",
|
||||
driverStoreDirSuccess: "{target} 已更改,正在重啟…",
|
||||
},
|
||||
databaseExport: {
|
||||
title: "匯出資料庫",
|
||||
|
|
|
|||
|
|
@ -188,6 +188,8 @@ export const loadAiConfig = forward("loadAiConfig");
|
|||
export const loadDesktopSettings = forward("loadDesktopSettings");
|
||||
export const saveDesktopSettings = forward("saveDesktopSettings");
|
||||
export const setDriverStoreDir = forward("setDriverStoreDir");
|
||||
export const setPluginStoreDir = forward("setPluginStoreDir");
|
||||
export const setAgentStoreDir = forward("setAgentStoreDir");
|
||||
export const getDriverStorePath = forward("getDriverStorePath");
|
||||
export const loadPinnedTreeNodeIds = forward("loadPinnedTreeNodeIds");
|
||||
export const savePinnedTreeNodeIds = forward("savePinnedTreeNodeIds");
|
||||
|
|
|
|||
|
|
@ -851,7 +851,7 @@ export async function loadAiConfig(): Promise<AiConfig | null> {
|
|||
}
|
||||
|
||||
export async function loadDesktopSettings(): Promise<DesktopSettings> {
|
||||
return { show_tray_icon: true, icon_theme: "default", debug_logging_enabled: false, saved_sql_sync_dir: null, driver_store_dir: null };
|
||||
return { show_tray_icon: true, icon_theme: "default", debug_logging_enabled: false, saved_sql_sync_dir: null, driver_store_dir: null, plugin_store_dir: null, agent_store_dir: null };
|
||||
}
|
||||
|
||||
export async function saveDesktopSettings(_settings: DesktopSettings): Promise<void> {
|
||||
|
|
@ -860,6 +860,8 @@ export async function saveDesktopSettings(_settings: DesktopSettings): Promise<v
|
|||
|
||||
export interface DriverStoreMigrationResult {
|
||||
driver_store_dir: string | null;
|
||||
plugin_store_dir: string | null;
|
||||
agent_store_dir: string | null;
|
||||
migrated_plugins: boolean;
|
||||
migrated_agents: boolean;
|
||||
}
|
||||
|
|
@ -868,8 +870,18 @@ export async function setDriverStoreDir(_newDir: string | null): Promise<DriverS
|
|||
throw new Error("Not available in web mode");
|
||||
}
|
||||
|
||||
export async function setPluginStoreDir(_newDir: string | null): Promise<DriverStoreMigrationResult> {
|
||||
throw new Error("Not available in web mode");
|
||||
}
|
||||
|
||||
export async function setAgentStoreDir(_newDir: string | null): Promise<DriverStoreMigrationResult> {
|
||||
throw new Error("Not available in web mode");
|
||||
}
|
||||
|
||||
export interface DriverStorePathInfo {
|
||||
driver_store_dir: string | null;
|
||||
plugin_store_dir: string | null;
|
||||
agent_store_dir: string | null;
|
||||
plugins_dir: string;
|
||||
agents_dir: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ export interface DesktopSettings {
|
|||
debug_logging_enabled: boolean;
|
||||
saved_sql_sync_dir?: string | null;
|
||||
driver_store_dir?: string | null;
|
||||
plugin_store_dir?: string | null;
|
||||
agent_store_dir?: string | null;
|
||||
}
|
||||
|
||||
export interface SavedSqlSyncEntry {
|
||||
|
|
@ -334,6 +336,8 @@ export async function saveDesktopSettings(settings: DesktopSettings): Promise<vo
|
|||
|
||||
export interface DriverStoreMigrationResult {
|
||||
driver_store_dir: string | null;
|
||||
plugin_store_dir: string | null;
|
||||
agent_store_dir: string | null;
|
||||
migrated_plugins: boolean;
|
||||
migrated_agents: boolean;
|
||||
}
|
||||
|
|
@ -342,8 +346,18 @@ export async function setDriverStoreDir(newDir: string | null): Promise<DriverSt
|
|||
return invoke("set_driver_store_dir", { newDir });
|
||||
}
|
||||
|
||||
export async function setPluginStoreDir(newDir: string | null): Promise<DriverStoreMigrationResult> {
|
||||
return invoke("set_plugin_store_dir", { newDir });
|
||||
}
|
||||
|
||||
export async function setAgentStoreDir(newDir: string | null): Promise<DriverStoreMigrationResult> {
|
||||
return invoke("set_agent_store_dir", { newDir });
|
||||
}
|
||||
|
||||
export interface DriverStorePathInfo {
|
||||
driver_store_dir: string | null;
|
||||
plugin_store_dir: string | null;
|
||||
agent_store_dir: string | null;
|
||||
plugins_dir: string;
|
||||
agents_dir: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ export interface DesktopSettings {
|
|||
debug_logging_enabled: boolean;
|
||||
saved_sql_sync_dir?: string | null;
|
||||
driver_store_dir?: string | null;
|
||||
plugin_store_dir?: string | null;
|
||||
agent_store_dir?: string | null;
|
||||
}
|
||||
|
||||
export type DesktopIconTheme = "default" | "black";
|
||||
|
|
@ -51,6 +53,8 @@ export const DEFAULT_DESKTOP_SETTINGS: DesktopSettings = {
|
|||
debug_logging_enabled: false,
|
||||
saved_sql_sync_dir: null,
|
||||
driver_store_dir: null,
|
||||
plugin_store_dir: null,
|
||||
agent_store_dir: null,
|
||||
};
|
||||
|
||||
function normalizeDesktopSettings(settings: Partial<DesktopSettings> | null | undefined): DesktopSettings {
|
||||
|
|
@ -61,6 +65,8 @@ function normalizeDesktopSettings(settings: Partial<DesktopSettings> | null | un
|
|||
debug_logging_enabled: settings?.debug_logging_enabled ?? DEFAULT_DESKTOP_SETTINGS.debug_logging_enabled,
|
||||
saved_sql_sync_dir: settings?.saved_sql_sync_dir?.trim() || DEFAULT_DESKTOP_SETTINGS.saved_sql_sync_dir,
|
||||
driver_store_dir: settings?.driver_store_dir?.trim() || DEFAULT_DESKTOP_SETTINGS.driver_store_dir,
|
||||
plugin_store_dir: settings?.plugin_store_dir?.trim() || DEFAULT_DESKTOP_SETTINGS.plugin_store_dir,
|
||||
agent_store_dir: settings?.agent_store_dir?.trim() || DEFAULT_DESKTOP_SETTINGS.agent_store_dir,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1112,7 +1112,7 @@ fn default_plugin_dir() -> PathBuf {
|
|||
default_dbx_dir().join("plugins")
|
||||
}
|
||||
|
||||
fn default_agent_dir() -> PathBuf {
|
||||
pub fn default_agent_dir() -> PathBuf {
|
||||
default_dbx_dir().join("agents")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ pub struct DesktopSettings {
|
|||
pub saved_sql_sync_dir: Option<String>,
|
||||
#[serde(default)]
|
||||
pub driver_store_dir: Option<String>,
|
||||
#[serde(default)]
|
||||
pub plugin_store_dir: Option<String>,
|
||||
#[serde(default)]
|
||||
pub agent_store_dir: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for DesktopSettings {
|
||||
|
|
@ -48,6 +52,8 @@ impl Default for DesktopSettings {
|
|||
debug_logging_enabled: false,
|
||||
saved_sql_sync_dir: None,
|
||||
driver_store_dir: None,
|
||||
plugin_store_dir: None,
|
||||
agent_store_dir: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -518,6 +524,22 @@ impl Storage {
|
|||
settings.remove("driver_store_dir");
|
||||
}
|
||||
}
|
||||
match desktop_settings.plugin_store_dir.as_ref().filter(|path| !path.trim().is_empty()) {
|
||||
Some(path) => {
|
||||
settings.insert("plugin_store_dir".to_string(), serde_json::Value::String(path.clone()));
|
||||
}
|
||||
None => {
|
||||
settings.remove("plugin_store_dir");
|
||||
}
|
||||
}
|
||||
match desktop_settings.agent_store_dir.as_ref().filter(|path| !path.trim().is_empty()) {
|
||||
Some(path) => {
|
||||
settings.insert("agent_store_dir".to_string(), serde_json::Value::String(path.clone()));
|
||||
}
|
||||
None => {
|
||||
settings.remove("agent_store_dir");
|
||||
}
|
||||
}
|
||||
self.save_app_settings_json(&settings).await
|
||||
}
|
||||
|
||||
|
|
@ -546,6 +568,18 @@ impl Storage {
|
|||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(ToString::to_string),
|
||||
plugin_store_dir: settings
|
||||
.get("plugin_store_dir")
|
||||
.and_then(|value| value.as_str())
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(ToString::to_string),
|
||||
agent_store_dir: settings
|
||||
.get("agent_store_dir")
|
||||
.and_then(|value| value.as_str())
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(ToString::to_string),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1495,6 +1529,8 @@ mod tests {
|
|||
debug_logging_enabled: true,
|
||||
saved_sql_sync_dir: None,
|
||||
driver_store_dir: Some("/tmp/dbx-drivers".to_string()),
|
||||
plugin_store_dir: Some("/tmp/dbx-plugins".to_string()),
|
||||
agent_store_dir: Some("/tmp/dbx-agents".to_string()),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -1507,7 +1543,9 @@ mod tests {
|
|||
icon_theme: DesktopIconTheme::Black,
|
||||
debug_logging_enabled: true,
|
||||
saved_sql_sync_dir: None,
|
||||
driver_store_dir: Some("/tmp/dbx-drivers".to_string())
|
||||
driver_store_dir: Some("/tmp/dbx-drivers".to_string()),
|
||||
plugin_store_dir: Some("/tmp/dbx-plugins".to_string()),
|
||||
agent_store_dir: Some("/tmp/dbx-agents".to_string())
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use std::{path::PathBuf, sync::Arc};
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use dbx_core::storage::DesktopSettings;
|
||||
use tauri::{AppHandle, Manager, State};
|
||||
|
|
@ -9,6 +12,8 @@ use crate::{apply_debug_log_level, apply_desktop_settings};
|
|||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct DriverStoreMigrationResult {
|
||||
pub driver_store_dir: Option<String>,
|
||||
pub plugin_store_dir: Option<String>,
|
||||
pub agent_store_dir: Option<String>,
|
||||
pub migrated_plugins: bool,
|
||||
pub migrated_agents: bool,
|
||||
}
|
||||
|
|
@ -53,6 +58,8 @@ pub async fn load_native_debug_logs(app: AppHandle) -> Result<String, String> {
|
|||
#[derive(Debug, Clone, serde::Serialize)]
|
||||
pub struct DriverStorePathInfo {
|
||||
pub driver_store_dir: Option<String>,
|
||||
pub plugin_store_dir: Option<String>,
|
||||
pub agent_store_dir: Option<String>,
|
||||
pub plugins_dir: String,
|
||||
pub agents_dir: String,
|
||||
}
|
||||
|
|
@ -62,6 +69,8 @@ pub async fn get_driver_store_path(state: State<'_, Arc<AppState>>) -> Result<Dr
|
|||
let settings = state.storage.load_desktop_settings().await.unwrap_or_default();
|
||||
Ok(DriverStorePathInfo {
|
||||
driver_store_dir: settings.driver_store_dir,
|
||||
plugin_store_dir: settings.plugin_store_dir,
|
||||
agent_store_dir: settings.agent_store_dir,
|
||||
plugins_dir: state.plugins.root_dir().to_string_lossy().to_string(),
|
||||
agents_dir: state.agent_manager.base_dir().to_string_lossy().to_string(),
|
||||
})
|
||||
|
|
@ -69,91 +78,180 @@ pub async fn get_driver_store_path(state: State<'_, Arc<AppState>>) -> Result<Dr
|
|||
|
||||
#[tauri::command]
|
||||
pub async fn set_driver_store_dir(
|
||||
app: AppHandle,
|
||||
state: State<'_, Arc<AppState>>,
|
||||
new_dir: Option<String>,
|
||||
) -> Result<DriverStoreMigrationResult, String> {
|
||||
let new_dir = new_dir.filter(|d| !d.trim().is_empty()).map(|d| d.trim().to_string());
|
||||
let new_path = new_dir.as_ref().map(PathBuf::from);
|
||||
|
||||
// Resolve current plugin/agent directories
|
||||
let new_dir = normalize_store_dir(new_dir);
|
||||
let current_plugins_dir = state.plugins.root_dir().to_path_buf();
|
||||
let current_agents_dir = state.agent_manager.base_dir().clone();
|
||||
|
||||
// Validate: if setting a custom dir, it must be different from current parent
|
||||
if let Some(ref np) = new_path {
|
||||
let target_plugins = np.join("plugins");
|
||||
let target_agents = np.join("agents");
|
||||
|
||||
// Canonicalize for comparison (both sides)
|
||||
let np_canonical = if np.exists() {
|
||||
np.canonicalize().map_err(|e| format!("Invalid path {}: {e}", np.display()))?
|
||||
} else {
|
||||
std::fs::create_dir_all(np).map_err(|e| format!("Failed to create directory {}: {e}", np.display()))?;
|
||||
np.canonicalize().map_err(|e| format!("Invalid path {}: {e}", np.display()))?
|
||||
};
|
||||
|
||||
let current_plugins_parent = current_plugins_dir.parent();
|
||||
let current_agents_parent = current_agents_dir.parent();
|
||||
|
||||
// Check if the new dir is the same as the current parent (no-op)
|
||||
if current_plugins_parent == Some(&np_canonical) && current_agents_parent == Some(&np_canonical) {
|
||||
return Ok(DriverStoreMigrationResult {
|
||||
driver_store_dir: new_dir,
|
||||
migrated_plugins: false,
|
||||
migrated_agents: false,
|
||||
});
|
||||
let (target_plugins_dir, target_agents_dir) = match new_dir.as_ref() {
|
||||
Some(dir) => {
|
||||
let driver_base = PathBuf::from(dir);
|
||||
(driver_base.join("plugins"), driver_base.join("agents"))
|
||||
}
|
||||
None => default_store_dirs(&app)?,
|
||||
};
|
||||
|
||||
// Stop all running agent daemons before migration
|
||||
state.agent_manager.stop_daemons().await;
|
||||
state.agent_manager.stop_daemons().await;
|
||||
let migrated_plugins = migrate_store_directory(¤t_plugins_dir, &target_plugins_dir)?;
|
||||
let migrated_agents = migrate_store_directory(¤t_agents_dir, &target_agents_dir)?;
|
||||
|
||||
// Migrate plugins directory
|
||||
let migrated_plugins = if current_plugins_dir.exists() {
|
||||
migrate_directory(¤t_plugins_dir, &target_plugins)?;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// Migrate agents directory
|
||||
let migrated_agents = if current_agents_dir.exists() {
|
||||
migrate_directory(¤t_agents_dir, &target_agents)?;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// Verify migration
|
||||
if migrated_plugins {
|
||||
verify_migration(¤t_plugins_dir, &target_plugins)?;
|
||||
}
|
||||
if migrated_agents {
|
||||
verify_migration(¤t_agents_dir, &target_agents)?;
|
||||
}
|
||||
|
||||
// Delete old data after successful verification
|
||||
if migrated_plugins {
|
||||
if let Err(err) = std::fs::remove_dir_all(¤t_plugins_dir) {
|
||||
log::warn!("Failed to remove old plugins dir {}: {err}", current_plugins_dir.display());
|
||||
}
|
||||
}
|
||||
if migrated_agents {
|
||||
if let Err(err) = std::fs::remove_dir_all(¤t_agents_dir) {
|
||||
log::warn!("Failed to remove old agents dir {}: {err}", current_agents_dir.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save the setting
|
||||
let mut settings = state.storage.load_desktop_settings().await.unwrap_or_default();
|
||||
settings.driver_store_dir = new_dir.clone();
|
||||
settings.plugin_store_dir = None;
|
||||
settings.agent_store_dir = None;
|
||||
state.storage.save_desktop_settings(&settings).await?;
|
||||
|
||||
Ok(DriverStoreMigrationResult { driver_store_dir: new_dir, migrated_plugins: true, migrated_agents: true })
|
||||
Ok(driver_store_migration_result(settings, migrated_plugins, migrated_agents))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_plugin_store_dir(
|
||||
app: AppHandle,
|
||||
state: State<'_, Arc<AppState>>,
|
||||
new_dir: Option<String>,
|
||||
) -> Result<DriverStoreMigrationResult, String> {
|
||||
let new_dir = normalize_store_dir(new_dir);
|
||||
let current_plugins_dir = state.plugins.root_dir().to_path_buf();
|
||||
let current_agents_dir = state.agent_manager.base_dir().clone();
|
||||
let target_plugins_dir = match new_dir.as_ref() {
|
||||
Some(dir) => PathBuf::from(dir),
|
||||
None => default_plugin_store_dir(&app)?,
|
||||
};
|
||||
|
||||
let migrated_plugins = migrate_store_directory(¤t_plugins_dir, &target_plugins_dir)?;
|
||||
|
||||
let mut settings = state.storage.load_desktop_settings().await.unwrap_or_default();
|
||||
convert_legacy_driver_store(&mut settings, ¤t_plugins_dir, ¤t_agents_dir);
|
||||
settings.plugin_store_dir = new_dir;
|
||||
state.storage.save_desktop_settings(&settings).await?;
|
||||
|
||||
Ok(driver_store_migration_result(settings, migrated_plugins, false))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_agent_store_dir(
|
||||
app: AppHandle,
|
||||
state: State<'_, Arc<AppState>>,
|
||||
new_dir: Option<String>,
|
||||
) -> Result<DriverStoreMigrationResult, String> {
|
||||
let new_dir = normalize_store_dir(new_dir);
|
||||
let current_plugins_dir = state.plugins.root_dir().to_path_buf();
|
||||
let current_agents_dir = state.agent_manager.base_dir().clone();
|
||||
let target_agents_dir = match new_dir.as_ref() {
|
||||
Some(dir) => PathBuf::from(dir),
|
||||
None => default_agent_store_dir(&app)?,
|
||||
};
|
||||
|
||||
state.agent_manager.stop_daemons().await;
|
||||
let migrated_agents = migrate_store_directory(¤t_agents_dir, &target_agents_dir)?;
|
||||
|
||||
let mut settings = state.storage.load_desktop_settings().await.unwrap_or_default();
|
||||
convert_legacy_driver_store(&mut settings, ¤t_plugins_dir, ¤t_agents_dir);
|
||||
settings.agent_store_dir = new_dir;
|
||||
state.storage.save_desktop_settings(&settings).await?;
|
||||
|
||||
Ok(driver_store_migration_result(settings, false, migrated_agents))
|
||||
}
|
||||
|
||||
fn normalize_store_dir(dir: Option<String>) -> Option<String> {
|
||||
dir.and_then(|value| {
|
||||
let trimmed = value.trim();
|
||||
(!trimmed.is_empty()).then(|| trimmed.to_string())
|
||||
})
|
||||
}
|
||||
|
||||
fn default_store_dirs(app: &AppHandle) -> Result<(PathBuf, PathBuf), String> {
|
||||
Ok((default_plugin_store_dir(app)?, default_agent_store_dir(app)?))
|
||||
}
|
||||
|
||||
fn default_plugin_store_dir(app: &AppHandle) -> Result<PathBuf, String> {
|
||||
let default_data_dir = app.path().app_data_dir().map_err(|e| e.to_string())?;
|
||||
Ok(crate::data_dir::resolve_data_dir(default_data_dir).join("plugins"))
|
||||
}
|
||||
|
||||
fn default_agent_store_dir(app: &AppHandle) -> Result<PathBuf, String> {
|
||||
let default_data_dir = app.path().app_data_dir().map_err(|e| e.to_string())?;
|
||||
let data_dir = crate::data_dir::resolve_data_dir(default_data_dir);
|
||||
Ok(if crate::data_dir::uses_custom_data_dir() {
|
||||
data_dir.join("agents")
|
||||
} else {
|
||||
dbx_core::connection::default_agent_dir()
|
||||
})
|
||||
}
|
||||
|
||||
fn convert_legacy_driver_store(settings: &mut DesktopSettings, current_plugins_dir: &Path, current_agents_dir: &Path) {
|
||||
if settings.driver_store_dir.is_none() {
|
||||
return;
|
||||
}
|
||||
if settings.plugin_store_dir.is_none() {
|
||||
settings.plugin_store_dir = Some(current_plugins_dir.to_string_lossy().to_string());
|
||||
}
|
||||
if settings.agent_store_dir.is_none() {
|
||||
settings.agent_store_dir = Some(current_agents_dir.to_string_lossy().to_string());
|
||||
}
|
||||
settings.driver_store_dir = None;
|
||||
}
|
||||
|
||||
fn driver_store_migration_result(
|
||||
settings: DesktopSettings,
|
||||
migrated_plugins: bool,
|
||||
migrated_agents: bool,
|
||||
) -> DriverStoreMigrationResult {
|
||||
DriverStoreMigrationResult {
|
||||
driver_store_dir: settings.driver_store_dir,
|
||||
plugin_store_dir: settings.plugin_store_dir,
|
||||
agent_store_dir: settings.agent_store_dir,
|
||||
migrated_plugins,
|
||||
migrated_agents,
|
||||
}
|
||||
}
|
||||
|
||||
fn migrate_store_directory(current_dir: &Path, target_dir: &Path) -> Result<bool, String> {
|
||||
std::fs::create_dir_all(target_dir)
|
||||
.map_err(|e| format!("Failed to create directory {}: {e}", target_dir.display()))?;
|
||||
let target_canonical =
|
||||
target_dir.canonicalize().map_err(|e| format!("Invalid path {}: {e}", target_dir.display()))?;
|
||||
|
||||
if !current_dir.exists() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let current_canonical =
|
||||
current_dir.canonicalize().map_err(|e| format!("Invalid path {}: {e}", current_dir.display()))?;
|
||||
if current_canonical == target_canonical {
|
||||
return Ok(false);
|
||||
}
|
||||
if target_canonical.starts_with(¤t_canonical) {
|
||||
return Err(format!(
|
||||
"Target directory {} cannot be inside current directory {}",
|
||||
target_dir.display(),
|
||||
current_dir.display()
|
||||
));
|
||||
}
|
||||
if target_dir_has_entries(target_dir)? {
|
||||
return Err(format!(
|
||||
"Target directory {} is not empty. Please choose an empty directory or remove the existing data first.",
|
||||
target_dir.display()
|
||||
));
|
||||
}
|
||||
|
||||
migrate_directory(current_dir, target_dir)?;
|
||||
verify_migration(current_dir, target_dir)?;
|
||||
if let Err(err) = std::fs::remove_dir_all(current_dir) {
|
||||
log::warn!("Failed to remove old driver store dir {}: {err}", current_dir.display());
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn target_dir_has_entries(dir: &Path) -> Result<bool, String> {
|
||||
let mut entries = std::fs::read_dir(dir).map_err(|e| format!("Failed to read {}: {e}", dir.display()))?;
|
||||
Ok(entries.next().transpose().map_err(|e| e.to_string())?.is_some())
|
||||
}
|
||||
|
||||
/// Recursively copy a directory to a new location.
|
||||
fn migrate_directory(src: &PathBuf, dst: &PathBuf) -> Result<(), String> {
|
||||
fn migrate_directory(src: &Path, dst: &Path) -> Result<(), String> {
|
||||
if !src.exists() {
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -178,7 +276,7 @@ fn copy_dir_recursive(src: &std::path::Path, dst: &std::path::Path) -> Result<()
|
|||
}
|
||||
|
||||
/// Verify that the migrated directory has the same file count and total size.
|
||||
fn verify_migration(src: &PathBuf, dst: &PathBuf) -> Result<(), String> {
|
||||
fn verify_migration(src: &Path, dst: &Path) -> Result<(), String> {
|
||||
let src_info = count_files_recursive(src)?;
|
||||
let dst_info = count_files_recursive(dst)?;
|
||||
if src_info.count != dst_info.count || src_info.total_size != dst_info.total_size {
|
||||
|
|
|
|||
|
|
@ -261,27 +261,29 @@ pub fn run() {
|
|||
apply_debug_log_level(desktop_settings.debug_logging_enabled);
|
||||
eprintln!("[STARTUP] storage ready in {:?}", t.elapsed());
|
||||
|
||||
let state = if let Some(ref driver_dir) = desktop_settings.driver_store_dir {
|
||||
let driver_base = std::path::PathBuf::from(driver_dir);
|
||||
let legacy_driver_base = desktop_settings.driver_store_dir.as_ref().map(std::path::PathBuf::from);
|
||||
let plugin_dir = desktop_settings
|
||||
.plugin_store_dir
|
||||
.as_ref()
|
||||
.map(std::path::PathBuf::from)
|
||||
.or_else(|| legacy_driver_base.as_ref().map(|base| base.join("plugins")))
|
||||
.unwrap_or_else(|| data_dir.join("plugins"));
|
||||
let agent_dir = desktop_settings
|
||||
.agent_store_dir
|
||||
.as_ref()
|
||||
.map(std::path::PathBuf::from)
|
||||
.or_else(|| legacy_driver_base.as_ref().map(|base| base.join("agents")))
|
||||
.or_else(|| data_dir::uses_custom_data_dir().then(|| data_dir.join("agents")));
|
||||
|
||||
let state = if let Some(agent_dir) = agent_dir {
|
||||
Arc::new(AppState::new_with_plugin_and_agent_dir_and_app_version(
|
||||
storage,
|
||||
driver_base.join("plugins"),
|
||||
driver_base.join("agents"),
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
))
|
||||
} else if data_dir::uses_custom_data_dir() {
|
||||
Arc::new(AppState::new_with_plugin_and_agent_dir_and_app_version(
|
||||
storage,
|
||||
data_dir.join("plugins"),
|
||||
data_dir.join("agents"),
|
||||
plugin_dir,
|
||||
agent_dir,
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
))
|
||||
} else {
|
||||
Arc::new(AppState::new_with_plugin_dir_and_app_version(
|
||||
storage,
|
||||
data_dir.join("plugins"),
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
))
|
||||
Arc::new(AppState::new_with_plugin_dir_and_app_version(storage, plugin_dir, env!("CARGO_PKG_VERSION")))
|
||||
};
|
||||
app.manage(state.clone());
|
||||
app.manage(commands::saved_sql::SavedSqlStorageState { data_dir: data_dir.clone() });
|
||||
|
|
@ -337,6 +339,8 @@ pub fn run() {
|
|||
commands::app_settings::load_desktop_settings,
|
||||
commands::app_settings::save_desktop_settings,
|
||||
commands::app_settings::set_driver_store_dir,
|
||||
commands::app_settings::set_plugin_store_dir,
|
||||
commands::app_settings::set_agent_store_dir,
|
||||
commands::app_settings::get_driver_store_path,
|
||||
commands::app_settings::load_pinned_tree_node_ids,
|
||||
commands::app_settings::save_pinned_tree_node_ids,
|
||||
|
|
|
|||
Loading…
Reference in New Issue