Skip to content

Commit a7147c6

Browse files
authored
Merge pull request #45 from mcintyre94/confirm-stream-stop-action-495031f2
Add confirmation dialog before stopping Claude stream
2 parents 194424e + 8c65a70 commit a7147c6

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

Wisp/ViewModels/ChatViewModel.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,11 @@ final class ChatViewModel {
541541
func interrupt(apiClient: SpritesAPIClient? = nil, modelContext: ModelContext? = nil) {
542542
detach(modelContext: modelContext)
543543

544+
// Interrupted sessions are not cleanly resumable, so clear the session ID
545+
// to avoid a spurious "Session expired" message on the next send
546+
sessionId = nil
547+
if let modelContext { saveSession(modelContext: modelContext) }
548+
544549
// Delete the service to stop it
545550
if let apiClient {
546551
let sName = spriteName

Wisp/Views/SpriteDetail/Chat/ChatInputBar.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ struct ChatInputBar: View {
1515
var lastUploadedFileName: String? = nil
1616
var isFocused: FocusState<Bool>.Binding
1717

18+
@State private var showStopConfirmation = false
19+
1820
private var isEmpty: Bool {
1921
text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && attachedFiles.isEmpty
2022
}
@@ -65,12 +67,20 @@ struct ChatInputBar: View {
6567
.disabled(hasQueuedMessage)
6668

6769
if isStreaming {
68-
Button(action: onInterrupt) {
70+
Button {
71+
showStopConfirmation = true
72+
} label: {
6973
Image(systemName: "stop.circle.fill")
7074
.font(.title2)
7175
}
7276
.tint(.red)
7377
.buttonStyle(.glass)
78+
.confirmationDialog("Stop Claude?", isPresented: $showStopConfirmation) {
79+
Button("Stop", role: .destructive, action: onInterrupt)
80+
Button("Cancel", role: .cancel) {}
81+
} message: {
82+
Text("This will interrupt the current response.")
83+
}
7484
}
7585

7686
Button {
@@ -100,3 +110,27 @@ struct ChatInputBar: View {
100110
#endif
101111
}
102112
}
113+
114+
#Preview("Idle") {
115+
@Previewable @State var text = ""
116+
@Previewable @FocusState var isFocused: Bool
117+
ChatInputBar(
118+
text: $text,
119+
isStreaming: false,
120+
onSend: {},
121+
onInterrupt: {},
122+
isFocused: $isFocused
123+
)
124+
}
125+
126+
#Preview("Streaming") {
127+
@Previewable @State var text = ""
128+
@Previewable @FocusState var isFocused: Bool
129+
ChatInputBar(
130+
text: $text,
131+
isStreaming: true,
132+
onSend: {},
133+
onInterrupt: {},
134+
isFocused: $isFocused
135+
)
136+
}

0 commit comments

Comments
 (0)