Skip to content

Commit e2b133e

Browse files
committed
🐛 Fix Message scrollToBottom
1 parent ba25a8c commit e2b133e

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

ChatMLX/Features/Conversation/ConversationDetailView.swift

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ struct ConversationDetailView: View {
3131
@State private var toastMessage = ""
3232
@State private var toastType: AlertToast.AlertType = .regular
3333
@State private var loading = true
34+
@State private var scrollViewProxy: ScrollViewProxy?
3435

35-
@Namespace var bottomId
3636
@FocusState private var isInputFocused: Bool
3737

3838
var body: some View {
@@ -93,38 +93,40 @@ struct ConversationDetailView: View {
9393
}
9494
}
9595
.padding()
96-
.id(bottomId)
9796
}
9897
.onChange(
9998
of: conversation.messages.last,
100-
{
101-
proxy.scrollTo(bottomId, anchor: .bottom)
99+
{ _, _ in
100+
scrollToBottom()
102101
}
103102
)
104103
.onAppear {
105-
proxy.scrollTo(bottomId, anchor: .bottom)
104+
scrollViewProxy = proxy
105+
scrollToBottom()
106106
}
107107
}
108108
}
109109

110+
private func scrollToBottom() {
111+
guard let lastMessageId = conversation.messages.last?.id, let scrollViewProxy else {
112+
return
113+
}
114+
115+
withAnimation {
116+
scrollViewProxy.scrollTo(lastMessageId, anchor: .bottom)
117+
}
118+
}
119+
110120
@MainActor
111121
@ViewBuilder
112122
private func EditorToolbar() -> some View {
113123
HStack {
114124
Button {
115125
withAnimation {
116-
if displayStyle == .markdown {
117-
displayStyle = .plain
118-
} else {
119-
displayStyle = .markdown
120-
}
126+
displayStyle = (displayStyle == .markdown) ? .plain : .markdown
121127
}
122128
} label: {
123-
if displayStyle == .markdown {
124-
Image("plaintext")
125-
} else {
126-
Image("markdown")
127-
}
129+
Image(displayStyle == .markdown ? "plaintext" : "markdown")
128130
}
129131

130132
Button(action: {
@@ -296,7 +298,11 @@ struct ConversationDetailView: View {
296298

297299
Message(context: viewContext).user(content: trimmedMessage, conversation: conversation)
298300

299-
runner.generate(conversation: conversation, in: viewContext)
301+
runner.generate(conversation: conversation, in: viewContext) {
302+
scrollToBottom()
303+
}
304+
305+
scrollToBottom()
300306

301307
Task(priority: .background) {
302308
do {

ChatMLX/Utilities/LLMRunner.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ class LLMRunner {
107107
]
108108
}
109109

110-
func generate(conversation: Conversation, in context: NSManagedObjectContext) {
110+
func generate(
111+
conversation: Conversation, in context: NSManagedObjectContext,
112+
progressing: @escaping () -> Void = {}
113+
) {
111114
guard !running else { return }
112115
running = true
113116

@@ -157,6 +160,7 @@ class LLMRunner {
157160
let text = tokenizer.decode(tokens: tokens)
158161
Task { @MainActor in
159162
assistantMessage.content = text
163+
progressing()
160164
}
161165
}
162166

0 commit comments

Comments
 (0)