Release 1.9.1

Fix sidebar not clickable: List(SidebarSection.allCases, selection:) ties
selection to Identifiable's id (String) while the binding was typed
SidebarSection? -- rebuilt with the standard List(selection:) { ForEach {
.tag(section) } } pattern instead, plus .listStyle(.sidebar).

Fix "Write to calendars" hard to find: still present as the Dry Run/Write
toolbar segmented control, but likely lost to toolbar overflow alongside a
status readout, Sync Now, and the overflow menu all in one
ToolbarItemGroup. Moved status out to .navigationSubtitle (native, never
overflows), toolbar now just Dry Run/Write, Sync Now/Cancel, overflow menu.

All unit tests pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 17:44:44 +02:00
co-authored by Claude Sonnet 5
parent 77e3eeaf7b
commit 622a85f4fd
3 changed files with 35 additions and 25 deletions
+23 -21
View File
@@ -568,22 +568,25 @@ struct ContentView: View {
@ViewBuilder
private var sidebarView: some View {
List(SidebarSection.allCases, selection: $selectedSection) { section in
Label {
HStack {
Text(section.title)
if section == .routes && !routes.isEmpty {
Spacer()
Text("\(routes.count)")
.font(.caption)
.foregroundStyle(.secondary)
List(selection: $selectedSection) {
ForEach(SidebarSection.allCases) { section in
Label {
HStack {
Text(section.title)
if section == .routes && !routes.isEmpty {
Spacer()
Text("\(routes.count)")
.font(.caption)
.foregroundStyle(.secondary)
}
}
} icon: {
Image(systemName: section.icon)
}
} icon: {
Image(systemName: section.icon)
.tag(section)
}
.tag(section as SidebarSection?)
}
.listStyle(.sidebar)
.navigationSplitViewColumnWidth(min: 180, ideal: 200)
}
@@ -727,6 +730,12 @@ struct ContentView: View {
}
}
private var statusSubtitle: String {
if let progressText { return progressText }
if isRunning { return "Running…" }
return hasAccess ? "\(calendars.count) calendars" : "No calendar access"
}
@ToolbarContentBuilder
private var toolbarContent: some ToolbarContent {
ToolbarItemGroup {
@@ -737,15 +746,7 @@ struct ContentView: View {
.pickerStyle(.segmented)
.frame(width: 150)
.disabled(isRunning)
HStack(spacing: 6) {
Circle()
.fill(isRunning ? Color.orange : (appController.lastRunFailed ? Color.red : Color.secondary))
.frame(width: 7, height: 7)
Text(progressText ?? (isRunning ? "Running…" : (hasAccess ? "\(calendars.count) calendars" : "No access")))
.font(.caption)
.foregroundStyle(.secondary)
}
.help("Dry Run previews changes without writing. Write actually creates/updates/deletes events.")
if isRunning {
Button("Cancel") { cancelMirror() }
@@ -813,6 +814,7 @@ struct ContentView: View {
}
}
.navigationTitle((selectedSection ?? .routes).title)
.navigationSubtitle(statusSubtitle)
.toolbar { toolbarContent }
}
.confirmationDialog(