Skip to content

Commit f90f0dc

Browse files
committed
Prevent re-parsing markdown on scroll
1 parent bb5d1fd commit f90f0dc

5 files changed

Lines changed: 58 additions & 36 deletions

File tree

Core/Sources/ChatGPTChatTab/Chat.swift

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ChatService
22
import ComposableArchitecture
33
import Foundation
4+
import MarkdownUI
45
import OpenAIService
56
import Preferences
67
import Terminal
@@ -40,12 +41,14 @@ public struct DisplayedChatMessage: Equatable {
4041
public var id: String
4142
public var role: Role
4243
public var text: String
44+
public var markdownContent: MarkdownContent
4345
public var references: [Reference] = []
4446

4547
public init(id: String, role: Role, text: String, references: [Reference]) {
4648
self.id = id
4749
self.role = role
4850
self.text = text
51+
self.markdownContent = .init(text)
4952
self.references = references
5053
}
5154
}
@@ -151,7 +154,7 @@ struct Chat {
151154
case let .setIsEnabled(isEnabled):
152155
state.isEnabled = isEnabled
153156
return .none
154-
157+
155158
case .sendButtonTapped:
156159
guard !state.typedMessage.isEmpty else { return .none }
157160
let message = state.typedMessage
@@ -213,11 +216,11 @@ struct Chat {
213216
await openURL(url)
214217
}
215218
}
216-
219+
217220
case .manuallyScrolledUp:
218221
state.isPinnedToBottom = false
219222
return .none
220-
223+
221224
case .scrollToBottomButtonTapped:
222225
state.isPinnedToBottom = true
223226
return .none
@@ -248,7 +251,7 @@ struct Chat {
248251
let debouncedHistoryChange = TimedDebounceFunction(duration: 0.2) {
249252
await send(.historyChanged)
250253
}
251-
254+
252255
for await _ in stream {
253256
await debouncedHistoryChange()
254257
}
@@ -502,9 +505,10 @@ private actor TimedDebounceFunction {
502505
}
503506
}
504507
}
505-
508+
506509
func fire() async {
507510
lastFireTime = Date()
508511
await block()
509512
}
510513
}
514+

Core/Sources/ChatGPTChatTab/ChatPanel.swift

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -283,20 +283,27 @@ struct ChatHistoryItem: View {
283283
var body: some View {
284284
WithPerceptionTracking {
285285
let text = message.text
286+
let markdownContent = message.markdownContent
286287
switch message.role {
287288
case .user:
288-
UserMessage(id: message.id, text: text, chat: chat)
289-
.listRowInsets(EdgeInsets(
290-
top: 0,
291-
leading: -8,
292-
bottom: 0,
293-
trailing: -8
294-
))
295-
.padding(.vertical, 4)
289+
UserMessage(
290+
id: message.id,
291+
text: text,
292+
markdownContent: markdownContent,
293+
chat: chat
294+
)
295+
.listRowInsets(EdgeInsets(
296+
top: 0,
297+
leading: -8,
298+
bottom: 0,
299+
trailing: -8
300+
))
301+
.padding(.vertical, 4)
296302
case .assistant:
297303
BotMessage(
298304
id: message.id,
299305
text: text,
306+
markdownContent: markdownContent,
300307
references: message.references,
301308
chat: chat
302309
)

Core/Sources/ChatGPTChatTab/Views/BotMessage.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct BotMessage: View {
88
var r: Double { messageBubbleCornerRadius }
99
let id: String
1010
let text: String
11+
let markdownContent: MarkdownContent
1112
let references: [DisplayedChatMessage.Reference]
1213
let chat: StoreOf<Chat>
1314
@Environment(\.colorScheme) var colorScheme
@@ -43,7 +44,7 @@ struct BotMessage: View {
4344
}
4445
}
4546

46-
ThemedMarkdownText(text)
47+
ThemedMarkdownText(markdownContent)
4748
}
4849
.frame(alignment: .trailing)
4950
.padding()
@@ -209,14 +210,16 @@ struct ReferenceIcon: View {
209210
}
210211

211212
#Preview("Bot Message") {
212-
BotMessage(
213-
id: "1",
214-
text: """
213+
let text = """
215214
**Hey**! What can I do for you?**Hey**! What can I do for you?**Hey**! What can I do for you?**Hey**! What can I do for you?
216215
```swift
217216
func foo() {}
218217
```
219-
""",
218+
"""
219+
return BotMessage(
220+
id: "1",
221+
text: text,
222+
markdownContent: .init(text),
220223
references: .init(repeating: .init(
221224
title: "ReferenceList",
222225
subtitle: "/Core/Sources/ChatGPTChatTab/Views/BotMessage.swift:100",

Core/Sources/ChatGPTChatTab/Views/ThemedMarkdownText.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ struct ThemedMarkdownText: View {
1212
@AppStorage(\.chatCodeFont) var chatCodeFont
1313
@Environment(\.colorScheme) var colorScheme
1414

15-
let text: String
15+
let content: MarkdownContent
1616

1717
init(_ text: String) {
18-
self.text = text
18+
self.content = .init(text)
19+
}
20+
21+
init(_ content: MarkdownContent) {
22+
self.content = content
1923
}
2024

2125
var body: some View {
22-
Markdown(text)
26+
Markdown(content)
2327
.textSelection(.enabled)
2428
.markdownTheme(.custom(
2529
fontSize: chatFontSize,

Core/Sources/ChatGPTChatTab/Views/UserMessage.swift

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ struct UserMessage: View {
77
var r: Double { messageBubbleCornerRadius }
88
let id: String
99
let text: String
10+
let markdownContent: MarkdownContent
1011
let chat: StoreOf<Chat>
1112
@Environment(\.colorScheme) var colorScheme
1213

1314
var body: some View {
14-
ThemedMarkdownText(text)
15+
ThemedMarkdownText(markdownContent)
1516
.frame(alignment: .leading)
1617
.padding()
1718
.background {
@@ -50,21 +51,24 @@ struct UserMessage: View {
5051
}
5152

5253
#Preview {
53-
UserMessage(
54+
let text = #"""
55+
Please buy me a coffee!
56+
| Coffee | Milk |
57+
|--------|------|
58+
| Espresso | No |
59+
| Latte | Yes |
60+
```swift
61+
func foo() {}
62+
```
63+
```objectivec
64+
- (void)bar {}
65+
```
66+
"""#
67+
68+
return UserMessage(
5469
id: "A",
55-
text: #"""
56-
Please buy me a coffee!
57-
| Coffee | Milk |
58-
|--------|------|
59-
| Espresso | No |
60-
| Latte | Yes |
61-
```swift
62-
func foo() {}
63-
```
64-
```objectivec
65-
- (void)bar {}
66-
```
67-
"""#,
70+
text: text,
71+
markdownContent: .init(text),
6872
chat: .init(
6973
initialState: .init(history: [] as [DisplayedChatMessage], isReceivingMessage: false),
7074
reducer: { Chat(service: .init()) }

0 commit comments

Comments
 (0)