diff --git a/packages/ui/src/components/remote-access-overlay.tsx b/packages/ui/src/components/remote-access-overlay.tsx index 08815a15..6bcf53cf 100644 --- a/packages/ui/src/components/remote-access-overlay.tsx +++ b/packages/ui/src/components/remote-access-overlay.tsx @@ -23,6 +23,7 @@ export function RemoteAccessOverlay(props: RemoteAccessOverlayProps) { const [meta, setMeta] = createSignal(null) const [authStatus, setAuthStatus] = createSignal<{ authenticated: boolean; username?: string; passwordUserProvided?: boolean } | null>(null) const [loading, setLoading] = createSignal(false) + const [applyingListeningMode, setApplyingListeningMode] = createSignal(false) const [qrCodes, setQrCodes] = createSignal>({}) const [expandedUrl, setExpandedUrl] = createSignal(null) const [error, setError] = createSignal(null) @@ -88,6 +89,10 @@ export function RemoteAccessOverlay(props: RemoteAccessOverlayProps) { return } + if (applyingListeningMode()) { + return + } + const confirmed = await showConfirmDialog(t("remoteAccess.listeningMode.restartConfirm.message"), { title: allow ? t("remoteAccess.listeningMode.restartConfirm.title.all") : t("remoteAccess.listeningMode.restartConfirm.title.local"), variant: "warning", @@ -100,12 +105,21 @@ export function RemoteAccessOverlay(props: RemoteAccessOverlayProps) { return } - setListeningMode(targetMode) - const restarted = await restartCli() - if (!restarted) { - setError(t("remoteAccess.restart.errorManual")) - } else { - setMeta((prev) => (prev ? { ...prev, listeningMode: targetMode } : prev)) + setApplyingListeningMode(true) + setError(null) + try { + // Important: await the config patch before restart so Electron reads the updated mode from disk. + await setListeningMode(targetMode) + const restarted = await restartCli() + if (!restarted) { + setError(t("remoteAccess.restart.errorManual")) + } else { + setMeta((prev) => (prev ? { ...prev, listeningMode: targetMode } : prev)) + } + } catch (err) { + setError(err instanceof Error ? err.message : String(err)) + } finally { + setApplyingListeningMode(false) } void refreshMeta() @@ -196,6 +210,7 @@ export function RemoteAccessOverlay(props: RemoteAccessOverlayProps) { onChange={(nextChecked) => { void handleAllowConnectionsChange(nextChecked) }} + disabled={loading() || applyingListeningMode()} > diff --git a/packages/ui/src/stores/preferences.tsx b/packages/ui/src/stores/preferences.tsx index 96ec386a..00b0a04e 100644 --- a/packages/ui/src/stores/preferences.tsx +++ b/packages/ui/src/stores/preferences.tsx @@ -304,10 +304,10 @@ function setThemePreference(preference: ThemePreference): void { void patchConfigOwner("ui", { theme: preference }).catch((error) => log.error("Failed to set theme", error)) } -function setListeningMode(mode: ListeningMode): void { - if (serverSettings().listeningMode === mode) return - void patchConfigOwner("server", { listeningMode: mode }).catch((error) => log.error("Failed to set listening mode", error)) -} + async function setListeningMode(mode: ListeningMode): Promise { + if (serverSettings().listeningMode === mode) return + await patchConfigOwner("server", { listeningMode: mode }) + } function updateEnvironmentVariables(envVars: Record): void { void patchConfigOwner("server", { environmentVariables: envVars }).catch((error) =>