From 4f423ef97184b2e6b9d0e209f9acfbc4fe65fa7a Mon Sep 17 00:00:00 2001 From: psavarmattas Date: Sat, 15 Aug 2026 00:17:51 +0100 Subject: [PATCH] fix(settings): keep the sidebar visible instead of a full-window overlay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Settings now swaps into the same NavigationSplitView detail pane as Home/collections (gated on AppNavigation.isShowingSettings) instead of covering the whole root window — the sidebar, and the ability to just click something else in it to leave Settings, stays available. Any sidebar navigation (Home, a collection, a document) exits Settings. --- .../Collections/ContentView_macOS.swift | 22 ++++++++++++++++--- Outpost/Root/RootView.swift | 10 --------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Outpost/Features/Collections/ContentView_macOS.swift b/Outpost/Features/Collections/ContentView_macOS.swift index 01dc410..bbcb029 100644 --- a/Outpost/Features/Collections/ContentView_macOS.swift +++ b/Outpost/Features/Collections/ContentView_macOS.swift @@ -4,6 +4,7 @@ import OutlineKit struct ContentView_macOS: View { @Environment(SessionStore.self) private var session + @Environment(AppNavigation.self) private var navigation /// The landing state — no collection selected yet is what Home actually /// means, so this starts `true` rather than auto-selecting the first /// collection the way this used to work. @@ -75,7 +76,7 @@ struct ContentView_macOS: View { // `CollectionOverviewView`, so on Home it was a dead end: a // user could click it, type, and nothing would happen. The // sidebar's global search already covers "search everything." - if !(isShowingHome && documentPath.isEmpty) { + if !navigation.isShowingSettings && !(isShowingHome && documentPath.isEmpty) { ToolbarItem(placement: .primaryAction) { contextualSearchField } @@ -96,6 +97,7 @@ struct ContentView_macOS: View { isContextualSearchExpanded = false selectedCollection = nil isShowingHome = true + navigation.isShowingSettings = false replaceDocumentPath(with: []) } @@ -144,7 +146,12 @@ struct ContentView_macOS: View { @ViewBuilder private var leadingToolbarContent: some View { Group { - if !trimmedGlobalQuery.isEmpty { + if navigation.isShowingSettings { + HStack(spacing: 6) { + Image(systemName: "gearshape.fill") + Text("Settings") + } + } else if !trimmedGlobalQuery.isEmpty { HStack(spacing: 6) { Image(systemName: "magnifyingglass") Text("Search") @@ -223,6 +230,7 @@ struct ContentView_macOS: View { globalSearchQuery = "" selectedCollection = collection isContextualSearchExpanded = true + navigation.isShowingSettings = false Task { @MainActor in isContextualSearchFocused = true } @@ -233,11 +241,13 @@ struct ContentView_macOS: View { /// hierarchy immediately rather than just the leaf. private func selectDocumentChain(_ collection: OutlineCollection, _ chain: [OutlineDocument]) { selectedCollection = collection + navigation.isShowingSettings = false replaceDocumentPath(with: chain) } /// Flat-list / search-result clicks: no known ancestors, single-level push. private func openDocument(_ document: OutlineDocument) { + navigation.isShowingSettings = false replaceDocumentPath(with: [document]) } @@ -256,7 +266,13 @@ struct ContentView_macOS: View { @ViewBuilder private var detail: some View { - if let apiClient = session.apiClient { + if navigation.isShowingSettings { + // Deliberately not a `NavigationStack` destination or a separate + // window — it's its own page swapped into the same detail pane + // Home/collections use, so the sidebar (and the ability to just + // click something else in it) stays available while it's open. + SettingsView(onDone: { navigation.isShowingSettings = false }) + } else if let apiClient = session.apiClient { // A fresh NavigationStack per collection (or when entering/leaving // search), so switching either also clears any pushed document. NavigationStack(path: $documentPath) { diff --git a/Outpost/Root/RootView.swift b/Outpost/Root/RootView.swift index ce508af..ab32307 100644 --- a/Outpost/Root/RootView.swift +++ b/Outpost/Root/RootView.swift @@ -3,7 +3,6 @@ import OutlineKit struct RootView: View { @Environment(SessionStore.self) private var session - @Environment(AppNavigation.self) private var navigation @State private var welcomeName: String? @State private var starStore = StarStore() @AppStorage("outpost.fullLocalSyncEnabled") private var isFullLocalSyncEnabled = false @@ -21,18 +20,9 @@ struct RootView: View { .transition(.opacity) .zIndex(1) } - - #if os(macOS) - if navigation.isShowingSettings { - SettingsView(onDone: { navigation.isShowingSettings = false }) - .transition(.opacity) - .zIndex(2) - } - #endif } .environment(starStore) .animation(.easeInOut(duration: 0.45), value: welcomeName != nil) - .animation(.easeInOut(duration: 0.2), value: navigation.isShowingSettings) .task { await session.refreshTeamInfoIfNeeded() }