UI redesign Phase 1: NavigationSplitView with collapsible sidebar

- Replace root VStack with NavigationSplitView (2-column, collapsible sidebar)
- Add SidebarView: new chat button, conversation search, list with swipe actions
- Slim HeaderView to text-only (provider + model + star); remove all icon rows
- Move status pills (Online, MCP, Synced) to footer right side
- Remove version number and shortcut hints from footer
- Add resizable InputBar with drag handle (persisted height) and globe/network.slash online toggle
- Fix Norwegian menu appearing on English systems (CFBundleLocalizations in Info.plist)
- Add View menu (Model Info, History, Stats, Credits, Online Mode toggle ⌘⇧O)
- Add ⌘L as alias for Search Conversations (muscle memory for /load users)
- Add Check for Updates to Help menu with download URL from Gitea API
- Add one-time Intel/Rosetta deprecation warning on first launch
- Swift 6: fix self.Self.isoString() call sites in DatabaseService

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 11:18:48 +02:00
parent cd0ceeab41
commit 8451db1142
19 changed files with 702 additions and 363 deletions
+2 -2
View File
@@ -1313,7 +1313,7 @@ Don't narrate future actions ("Let me...") - just use the tools.
// Append the complete system prompt (default + custom)
systemContent += "\n\n---\n\n" + effectiveSystemPrompt
var messagesToSend: [Message] = memoryEnabled
let messagesToSend: [Message] = memoryEnabled
? messages.filter { $0.role != .system }
: [messages.last(where: { $0.role == .user })].compactMap { $0 }
@@ -1659,7 +1659,7 @@ Don't narrate future actions ("Let me...") - just use the tools.
if isOverloaded && attempt < maxAttempts && !Task.isCancelled {
let delay = Double(1 << attempt) // 2s, 4s, 8s
Log.api.warning("API overloaded, retrying in \(Int(delay))s (attempt \(attempt)/\(maxAttempts - 1))...")
await MainActor.run {
_ = await MainActor.run {
showSystemMessage("⏳ API overloaded, retrying in \(Int(delay))s… (attempt \(attempt)/\(maxAttempts - 1))")
}
try await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000))