@@ -31,6 +31,9 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
31
31
@State private var keyboardShown = false
32
32
@State private var pendingKeyboardUpdate : Bool ?
33
33
34
+ private var messageRenderingUtil = MessageRenderingUtil . shared
35
+ private var skipRenderingMessageIds = [ String] ( )
36
+
34
37
private var dateFormatter : DateFormatter {
35
38
utils. dateFormatter
36
39
}
@@ -75,6 +78,19 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
75
78
_scrolledId = scrolledId
76
79
_showScrollToLatestButton = showScrollToLatestButton
77
80
_quotedMessage = quotedMessage
81
+ if !messageRenderingUtil. hasPreviousMessageSet
82
+ || self . showScrollToLatestButton == false
83
+ || self . scrolledId != nil
84
+ || messages. first? . isSentByCurrentUser == true {
85
+ messageRenderingUtil. update ( previousTopMessage: messages. first)
86
+ }
87
+ skipRenderingMessageIds = messageRenderingUtil. messagesToSkipRendering ( newMessages: messages)
88
+ if !skipRenderingMessageIds. isEmpty {
89
+ self . messages = LazyCachedMapCollection (
90
+ source: messages. filter { !skipRenderingMessageIds. contains ( $0. id) } ,
91
+ map: { $0 }
92
+ )
93
+ }
78
94
}
79
95
80
96
public var body : some View {
@@ -151,10 +167,6 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
151
167
. flippedUpsideDown ( )
152
168
. frame ( minWidth: self . width, minHeight: height)
153
169
. onChange ( of: scrolledId) { scrolledId in
154
- if !self . scrolledIdAvailableInMessages {
155
- self . scrolledId = nil
156
- return
157
- }
158
170
if let scrolledId = scrolledId {
159
171
if scrolledId == messages. first? . messageId {
160
172
self . scrolledId = nil
@@ -199,13 +211,8 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
199
211
}
200
212
} )
201
213
. modifier ( HideKeyboardOnTapGesture ( shouldAdd: keyboardShown) )
202
- }
203
-
204
- private var scrolledIdAvailableInMessages : Bool {
205
- if let scrolledId = scrolledId {
206
- return messages. map ( \. messageId) . contains ( scrolledId)
207
- } else {
208
- return false
214
+ . onDisappear {
215
+ messageRenderingUtil. update ( previousTopMessage: nil )
209
216
}
210
217
}
211
218
@@ -340,3 +347,41 @@ struct TypingIndicatorBottomView: View {
340
347
}
341
348
}
342
349
}
350
+
351
+ private class MessageRenderingUtil {
352
+
353
+ private var previousTopMessage : ChatMessage ?
354
+
355
+ static let shared = MessageRenderingUtil ( )
356
+
357
+ var hasPreviousMessageSet : Bool {
358
+ previousTopMessage != nil
359
+ }
360
+
361
+ func update( previousTopMessage: ChatMessage ? ) {
362
+ self . previousTopMessage = previousTopMessage
363
+ }
364
+
365
+ func messagesToSkipRendering( newMessages: LazyCachedMapCollection < ChatMessage > ) -> [ String ] {
366
+ let newTopMessage = newMessages. first
367
+ if newTopMessage? . id == previousTopMessage? . id {
368
+ return [ ]
369
+ }
370
+
371
+ if newTopMessage? . cid != previousTopMessage? . cid {
372
+ previousTopMessage = newTopMessage
373
+ return [ ]
374
+ }
375
+
376
+ var skipRendering = [ String] ( )
377
+ for message in newMessages {
378
+ if previousTopMessage? . id == message. id {
379
+ break
380
+ } else {
381
+ skipRendering. append ( message. id)
382
+ }
383
+ }
384
+
385
+ return skipRendering
386
+ }
387
+ }
0 commit comments