mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 10:36:35 +00:00
Fix session rename not updating across views
After rename: - Update selectedSession so detail header refreshes immediately - Update sessionPreviews so previewFor() returns the new title - Dashboard now observes HermesFileWatcher and reloads on DB changes - Chat session menu reloads via file watcher (persists across nav) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import SwiftUI
|
||||
|
||||
struct ChatView: View {
|
||||
@Environment(ChatViewModel.self) private var viewModel
|
||||
@Environment(HermesFileWatcher.self) private var fileWatcher
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
@@ -11,6 +12,9 @@ struct ChatView: View {
|
||||
}
|
||||
.navigationTitle("Chat")
|
||||
.task { await viewModel.loadRecentSessions() }
|
||||
.onChange(of: fileWatcher.lastChangeDate) {
|
||||
Task { await viewModel.loadRecentSessions() }
|
||||
}
|
||||
}
|
||||
|
||||
private var toolbar: some View {
|
||||
@@ -36,6 +40,10 @@ struct ChatView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
if viewModel.hasActiveProcess {
|
||||
voiceControls
|
||||
}
|
||||
|
||||
if !viewModel.hermesBinaryExists {
|
||||
Label("Hermes binary not found", systemImage: "exclamationmark.triangle")
|
||||
.font(.caption)
|
||||
@@ -80,6 +88,41 @@ struct ChatView: View {
|
||||
.padding(.vertical, 6)
|
||||
}
|
||||
|
||||
private var voiceControls: some View {
|
||||
HStack(spacing: 8) {
|
||||
Button {
|
||||
viewModel.toggleVoice()
|
||||
} label: {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: viewModel.voiceEnabled ? "mic.fill" : "mic.slash")
|
||||
.foregroundStyle(viewModel.voiceEnabled ? .green : .secondary)
|
||||
Text(viewModel.voiceEnabled ? "Voice On" : "Voice Off")
|
||||
.font(.caption)
|
||||
.foregroundStyle(viewModel.voiceEnabled ? .primary : .secondary)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Toggle voice mode (/voice)")
|
||||
|
||||
if viewModel.voiceEnabled {
|
||||
Button {
|
||||
viewModel.pushToTalk()
|
||||
} label: {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: viewModel.isRecording ? "waveform.circle.fill" : "waveform.circle")
|
||||
.foregroundStyle(viewModel.isRecording ? .red : .accentColor)
|
||||
.symbolEffect(.pulse, isActive: viewModel.isRecording)
|
||||
Text(viewModel.isRecording ? "Recording..." : "Push to Talk")
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Push to talk (Ctrl+B)")
|
||||
.keyboardShortcut("b", modifiers: .control)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var terminalArea: some View {
|
||||
if let terminal = viewModel.terminalView {
|
||||
|
||||
@@ -3,6 +3,7 @@ import SwiftUI
|
||||
struct DashboardView: View {
|
||||
@State private var viewModel = DashboardViewModel()
|
||||
@Environment(AppCoordinator.self) private var coordinator
|
||||
@Environment(HermesFileWatcher.self) private var fileWatcher
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
@@ -16,6 +17,9 @@ struct DashboardView: View {
|
||||
}
|
||||
.navigationTitle("Dashboard")
|
||||
.task { await viewModel.load() }
|
||||
.onChange(of: fileWatcher.lastChangeDate) {
|
||||
Task { await viewModel.load() }
|
||||
}
|
||||
}
|
||||
|
||||
private var statusSection: some View {
|
||||
|
||||
@@ -83,7 +83,7 @@ final class SessionsViewModel {
|
||||
let result = runHermes(["sessions", "rename", sessionId, title])
|
||||
if result.exitCode == 0 {
|
||||
if let idx = sessions.firstIndex(where: { $0.id == sessionId }) {
|
||||
sessions[idx] = HermesSession(
|
||||
let updated = HermesSession(
|
||||
id: sessions[idx].id, source: sessions[idx].source,
|
||||
userId: sessions[idx].userId, model: sessions[idx].model,
|
||||
title: title, parentSessionId: sessions[idx].parentSessionId,
|
||||
@@ -94,7 +94,12 @@ final class SessionsViewModel {
|
||||
cacheWriteTokens: sessions[idx].cacheWriteTokens,
|
||||
estimatedCostUSD: sessions[idx].estimatedCostUSD
|
||||
)
|
||||
sessions[idx] = updated
|
||||
if selectedSession?.id == sessionId {
|
||||
selectedSession = updated
|
||||
}
|
||||
}
|
||||
sessionPreviews[sessionId] = title
|
||||
}
|
||||
showRenameSheet = false
|
||||
renameSessionId = nil
|
||||
|
||||
Reference in New Issue
Block a user