fix(settings): keep the sidebar visible instead of a full-window overlay
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.
This commit is contained in:
@@ -4,6 +4,7 @@ import OutlineKit
|
|||||||
|
|
||||||
struct ContentView_macOS: View {
|
struct ContentView_macOS: View {
|
||||||
@Environment(SessionStore.self) private var session
|
@Environment(SessionStore.self) private var session
|
||||||
|
@Environment(AppNavigation.self) private var navigation
|
||||||
/// The landing state — no collection selected yet is what Home actually
|
/// The landing state — no collection selected yet is what Home actually
|
||||||
/// means, so this starts `true` rather than auto-selecting the first
|
/// means, so this starts `true` rather than auto-selecting the first
|
||||||
/// collection the way this used to work.
|
/// 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
|
// `CollectionOverviewView`, so on Home it was a dead end: a
|
||||||
// user could click it, type, and nothing would happen. The
|
// user could click it, type, and nothing would happen. The
|
||||||
// sidebar's global search already covers "search everything."
|
// sidebar's global search already covers "search everything."
|
||||||
if !(isShowingHome && documentPath.isEmpty) {
|
if !navigation.isShowingSettings && !(isShowingHome && documentPath.isEmpty) {
|
||||||
ToolbarItem(placement: .primaryAction) {
|
ToolbarItem(placement: .primaryAction) {
|
||||||
contextualSearchField
|
contextualSearchField
|
||||||
}
|
}
|
||||||
@@ -96,6 +97,7 @@ struct ContentView_macOS: View {
|
|||||||
isContextualSearchExpanded = false
|
isContextualSearchExpanded = false
|
||||||
selectedCollection = nil
|
selectedCollection = nil
|
||||||
isShowingHome = true
|
isShowingHome = true
|
||||||
|
navigation.isShowingSettings = false
|
||||||
replaceDocumentPath(with: [])
|
replaceDocumentPath(with: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +146,12 @@ struct ContentView_macOS: View {
|
|||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var leadingToolbarContent: some View {
|
private var leadingToolbarContent: some View {
|
||||||
Group {
|
Group {
|
||||||
if !trimmedGlobalQuery.isEmpty {
|
if navigation.isShowingSettings {
|
||||||
|
HStack(spacing: 6) {
|
||||||
|
Image(systemName: "gearshape.fill")
|
||||||
|
Text("Settings")
|
||||||
|
}
|
||||||
|
} else if !trimmedGlobalQuery.isEmpty {
|
||||||
HStack(spacing: 6) {
|
HStack(spacing: 6) {
|
||||||
Image(systemName: "magnifyingglass")
|
Image(systemName: "magnifyingglass")
|
||||||
Text("Search")
|
Text("Search")
|
||||||
@@ -223,6 +230,7 @@ struct ContentView_macOS: View {
|
|||||||
globalSearchQuery = ""
|
globalSearchQuery = ""
|
||||||
selectedCollection = collection
|
selectedCollection = collection
|
||||||
isContextualSearchExpanded = true
|
isContextualSearchExpanded = true
|
||||||
|
navigation.isShowingSettings = false
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
isContextualSearchFocused = true
|
isContextualSearchFocused = true
|
||||||
}
|
}
|
||||||
@@ -233,11 +241,13 @@ struct ContentView_macOS: View {
|
|||||||
/// hierarchy immediately rather than just the leaf.
|
/// hierarchy immediately rather than just the leaf.
|
||||||
private func selectDocumentChain(_ collection: OutlineCollection, _ chain: [OutlineDocument]) {
|
private func selectDocumentChain(_ collection: OutlineCollection, _ chain: [OutlineDocument]) {
|
||||||
selectedCollection = collection
|
selectedCollection = collection
|
||||||
|
navigation.isShowingSettings = false
|
||||||
replaceDocumentPath(with: chain)
|
replaceDocumentPath(with: chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flat-list / search-result clicks: no known ancestors, single-level push.
|
/// Flat-list / search-result clicks: no known ancestors, single-level push.
|
||||||
private func openDocument(_ document: OutlineDocument) {
|
private func openDocument(_ document: OutlineDocument) {
|
||||||
|
navigation.isShowingSettings = false
|
||||||
replaceDocumentPath(with: [document])
|
replaceDocumentPath(with: [document])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +266,13 @@ struct ContentView_macOS: View {
|
|||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var detail: some View {
|
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
|
// A fresh NavigationStack per collection (or when entering/leaving
|
||||||
// search), so switching either also clears any pushed document.
|
// search), so switching either also clears any pushed document.
|
||||||
NavigationStack(path: $documentPath) {
|
NavigationStack(path: $documentPath) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import OutlineKit
|
|||||||
|
|
||||||
struct RootView: View {
|
struct RootView: View {
|
||||||
@Environment(SessionStore.self) private var session
|
@Environment(SessionStore.self) private var session
|
||||||
@Environment(AppNavigation.self) private var navigation
|
|
||||||
@State private var welcomeName: String?
|
@State private var welcomeName: String?
|
||||||
@State private var starStore = StarStore()
|
@State private var starStore = StarStore()
|
||||||
@AppStorage("outpost.fullLocalSyncEnabled") private var isFullLocalSyncEnabled = false
|
@AppStorage("outpost.fullLocalSyncEnabled") private var isFullLocalSyncEnabled = false
|
||||||
@@ -21,18 +20,9 @@ struct RootView: View {
|
|||||||
.transition(.opacity)
|
.transition(.opacity)
|
||||||
.zIndex(1)
|
.zIndex(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(macOS)
|
|
||||||
if navigation.isShowingSettings {
|
|
||||||
SettingsView(onDone: { navigation.isShowingSettings = false })
|
|
||||||
.transition(.opacity)
|
|
||||||
.zIndex(2)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
.environment(starStore)
|
.environment(starStore)
|
||||||
.animation(.easeInOut(duration: 0.45), value: welcomeName != nil)
|
.animation(.easeInOut(duration: 0.45), value: welcomeName != nil)
|
||||||
.animation(.easeInOut(duration: 0.2), value: navigation.isShowingSettings)
|
|
||||||
.task {
|
.task {
|
||||||
await session.refreshTeamInfoIfNeeded()
|
await session.refreshTeamInfoIfNeeded()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user