From dd33a62b220d7336c531cbe57502d62e8df92519 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 22 Mar 2026 04:49:10 +0100 Subject: [PATCH] fix: replace inline save banners with toast notifications Removes layout-shifting "Settings saved" / "Role saved" inline banners from 5 settings panels. Uses existing addToast from uiStore instead. Error banners kept inline. --- .gitignore | 3 + .../src/components/modals/UserSettings.tsx | 7 +- .../modals/settingsPanels/AccountPanel.tsx | 127 ------------------ .../modals/settingsPanels/DesktopPanel.tsx | 127 ++++++++++++++++++ 4 files changed, 136 insertions(+), 128 deletions(-) create mode 100644 packages/web/src/components/modals/settingsPanels/DesktopPanel.tsx diff --git a/.gitignore b/.gitignore index 4420235e..811fa9c4 100644 --- a/.gitignore +++ b/.gitignore @@ -53,5 +53,8 @@ tmp/ # Worktrees .worktrees/ +# Superpowers brainstorm artifacts +.superpowers/ + # Local files Gemini Starter.rtf diff --git a/packages/web/src/components/modals/UserSettings.tsx b/packages/web/src/components/modals/UserSettings.tsx index 51c8623c..71525edc 100644 --- a/packages/web/src/components/modals/UserSettings.tsx +++ b/packages/web/src/components/modals/UserSettings.tsx @@ -7,10 +7,12 @@ import { AccountPanel } from './settingsPanels/AccountPanel'; import { VoicePanel } from './settingsPanels/VoicePanel'; import { PrivacyPanel } from './settingsPanels/PrivacyPanel'; import { ConnectionsPanel } from './settingsPanels/ConnectionsPanel'; +import { DesktopPanel } from './settingsPanels/DesktopPanel'; import { InstancePanel } from './settingsPanels/InstancePanel'; +import { isElectron } from '../../platform/platform'; import { SettingsSectionsProvider, useSettingsSectionsContext } from './SettingsSectionsContext'; -type SettingsTab = 'account' | 'voice' | 'privacy' | 'connections' | 'instance'; +type SettingsTab = 'account' | 'voice' | 'privacy' | 'connections' | 'desktop' | 'instance'; function SidebarSubLinks() { const ctx = useSettingsSectionsContext(); @@ -123,6 +125,7 @@ export function UserSettingsModal() {
App Settings
+ {isElectron() && } {isAdmin && ( <> @@ -171,6 +174,7 @@ export function UserSettingsModal() {
App Settings
+ {isElectron() && } {isAdmin && ( <> @@ -212,6 +216,7 @@ export function UserSettingsModal() { {tab === 'voice' && } {tab === 'privacy' && } {tab === 'connections' && } + {tab === 'desktop' && } {tab === 'instance' && isAdmin && }
diff --git a/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx b/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx index 39ce2f6a..b1575bbb 100644 --- a/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx +++ b/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx @@ -9,107 +9,6 @@ import { getAvatarGradient, adjustColor, mutedGradient, AVATAR_GRADIENT_MAP, BAN import { AVATAR_COLORS } from '@backspace/shared'; import type { User, UserStatus, AvatarColor } from '@backspace/shared'; import type { FederationOpResult } from '../../../utils/federationOps'; -import { isElectron } from '../../../platform/platform'; -import { Toggle } from '../../ui/Toggle'; - - -function AutoLaunchSettings() { - const [openAtLogin, setOpenAtLogin] = useState(false); - const [startMinimized, setStartMinimized] = useState(true); - const [loading, setLoading] = useState(true); - - useEffect(() => { - window.backspace?.getAutoLaunchSettings().then((settings) => { - setOpenAtLogin(settings.openAtLogin); - setStartMinimized(settings.startMinimized); - setLoading(false); - }).catch(() => setLoading(false)); - }, []); - - const handleOpenAtLoginChange = async (enabled: boolean) => { - setOpenAtLogin(enabled); - try { - const result = await window.backspace!.setAutoLaunchSettings({ openAtLogin: enabled }); - setOpenAtLogin(result.openAtLogin); - setStartMinimized(result.startMinimized); - } catch { - setOpenAtLogin(!enabled); - } - }; - - const handleStartMinimizedChange = async (enabled: boolean) => { - setStartMinimized(enabled); - try { - const result = await window.backspace!.setAutoLaunchSettings({ startMinimized: enabled }); - setOpenAtLogin(result.openAtLogin); - setStartMinimized(result.startMinimized); - } catch { - setStartMinimized(!enabled); - } - }; - - if (loading) return null; - - return ( - <> -
-
-
Start at boot
-
- Automatically launch Backspace when you log in -
-
- -
-
-
-
Start minimized
-
- Start hidden in the system tray instead of showing the window -
-
- -
- - ); -} - -function UpdateSettings() { - const [version, setVersion] = useState(null); - const [checking, setChecking] = useState(false); - - useEffect(() => { - window.backspace?.getVersion().then(setVersion).catch(() => {}); - }, []); - - const handleCheck = () => { - setChecking(true); - window.backspace?.checkForUpdates(); - // Reset after a few seconds — electron-updater doesn't have a "no update" callback - setTimeout(() => setChecking(false), 5000); - }; - - return ( -
-
-
- {version ? `Version ${version}` : 'Backspace Desktop'} -
-
- Check for new versions of the desktop app -
-
- -
- ); -} - export function AccountPanel() { const user = useAuthStore((s) => s.user); const updateProfile = useAuthStore((s) => s.updateProfile); @@ -787,32 +686,6 @@ export function AccountPanel() {
- {/* ── Desktop (Electron only) ── */} - {isElectron() && ( -
-
Desktop
-
- - - -
- -
-
-
{window.location.origin}
-
Currently connected instance
-
- -
-
-
- )} - {/* ── Danger Zone ── */}
Danger Zone
diff --git a/packages/web/src/components/modals/settingsPanels/DesktopPanel.tsx b/packages/web/src/components/modals/settingsPanels/DesktopPanel.tsx new file mode 100644 index 00000000..afb8ce2e --- /dev/null +++ b/packages/web/src/components/modals/settingsPanels/DesktopPanel.tsx @@ -0,0 +1,127 @@ +import { useState, useEffect } from 'react'; +import { Toggle } from '../../ui/Toggle'; + +function AutoLaunchSettings() { + const [openAtLogin, setOpenAtLogin] = useState(false); + const [startMinimized, setStartMinimized] = useState(true); + const [loading, setLoading] = useState(true); + + useEffect(() => { + window.backspace?.getAutoLaunchSettings().then((settings) => { + setOpenAtLogin(settings.openAtLogin); + setStartMinimized(settings.startMinimized); + setLoading(false); + }).catch(() => setLoading(false)); + }, []); + + const handleOpenAtLoginChange = async (enabled: boolean) => { + setOpenAtLogin(enabled); + try { + const result = await window.backspace!.setAutoLaunchSettings({ openAtLogin: enabled }); + setOpenAtLogin(result.openAtLogin); + setStartMinimized(result.startMinimized); + } catch { + setOpenAtLogin(!enabled); + } + }; + + const handleStartMinimizedChange = async (enabled: boolean) => { + setStartMinimized(enabled); + try { + const result = await window.backspace!.setAutoLaunchSettings({ startMinimized: enabled }); + setOpenAtLogin(result.openAtLogin); + setStartMinimized(result.startMinimized); + } catch { + setStartMinimized(!enabled); + } + }; + + if (loading) return null; + + return ( + <> +
+
+
Start at boot
+
+ Automatically launch Backspace when you log in +
+
+ +
+
+
+
Start minimized
+
+ Start hidden in the system tray instead of showing the window +
+
+ +
+ + ); +} + +function UpdateSettings() { + const [version, setVersion] = useState(null); + const [checking, setChecking] = useState(false); + + useEffect(() => { + window.backspace?.getVersion().then(setVersion).catch(() => {}); + }, []); + + const handleCheck = () => { + setChecking(true); + window.backspace?.checkForUpdates(); + // Reset after a few seconds — electron-updater doesn't have a "no update" callback + setTimeout(() => setChecking(false), 5000); + }; + + return ( +
+
+
+ {version ? `Version ${version}` : 'Backspace Desktop'} +
+
+ Check for new versions of the desktop app +
+
+ +
+ ); +} + +export function DesktopPanel() { + return ( +
+

Desktop

+ +
+ + + +
+ +
+
+
{window.location.origin}
+
Currently connected instance
+
+ +
+
+
+ ); +}