@@ -30,6 +30,7 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
3030 @State private var width : CGFloat ?
3131 @State private var keyboardShown = false
3232 @State private var pendingKeyboardUpdate : Bool ?
33+ @State private var newMessagesStartId : String ?
3334
3435 private var messageRenderingUtil = MessageRenderingUtil . shared
3536 private var skipRenderingMessageIds = [ String] ( )
@@ -49,6 +50,10 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
4950 private var lastInGroupHeaderSize : CGFloat {
5051 messageListConfig. messageDisplayOptions. lastInGroupHeaderSize
5152 }
53+
54+ private var newMessagesSeparatorSize : CGFloat {
55+ messageListConfig. messageDisplayOptions. newMessagesSeparatorSize
56+ }
5257
5358 private let scrollAreaId = " scrollArea "
5459
@@ -95,6 +100,14 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
95100 map: { $0 }
96101 )
97102 }
103+ if messageListConfig. showNewMessagesSeparator && channel. unreadCount. messages > 0 {
104+ let index = channel. unreadCount. messages - 1
105+ if index < messages. count {
106+ _newMessagesStartId = . init( wrappedValue: messages [ index] . id)
107+ }
108+ } else {
109+ _newMessagesStartId = . init( wrappedValue: nil )
110+ }
98111 }
99112
100113 public var body : some View {
@@ -113,6 +126,7 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
113126 ForEach ( messages, id: \. messageId) { message in
114127 var index : Int ? = messageListDateUtils. indexForMessageDate ( message: message, in: messages)
115128 let messageDate : Date ? = messageListDateUtils. showMessageDate ( for: index, in: messages)
129+ let showUnreadSeparator = message. id == newMessagesStartId
116130 let showsLastInGroupInfo = showsLastInGroupInfo ( for: message, channel: channel)
117131 factory. makeMessageContainerView (
118132 channel: channel,
@@ -136,16 +150,29 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
136150 . padding (
137151 . top,
138152 messageDate != nil ?
139- offsetForDateIndicator ( showsLastInGroupInfo: showsLastInGroupInfo) :
140- additionalTopPadding ( showsLastInGroupInfo: showsLastInGroupInfo)
153+ offsetForDateIndicator (
154+ showsLastInGroupInfo: showsLastInGroupInfo,
155+ showUnreadSeparator: showUnreadSeparator
156+ ) :
157+ additionalTopPadding (
158+ showsLastInGroupInfo: showsLastInGroupInfo,
159+ showUnreadSeparator: showUnreadSeparator
160+ )
141161 )
142162 . overlay (
143- ( messageDate != nil || showsLastInGroupInfo) ?
163+ ( messageDate != nil || showsLastInGroupInfo || showUnreadSeparator ) ?
144164 VStack ( spacing: 0 ) {
145165 messageDate != nil ?
146166 factory. makeMessageListDateIndicator ( date: messageDate!)
147167 . frame ( maxHeight: messageListConfig. messageDisplayOptions. dateLabelSize)
148168 : nil
169+
170+ showUnreadSeparator ?
171+ factory. makeNewMessagesIndicatorView (
172+ newMessagesStartId: $newMessagesStartId,
173+ count: newMessagesCount ( for: index)
174+ )
175+ : nil
149176
150177 showsLastInGroupInfo ?
151178 factory. makeLastInGroupHeaderView ( for: message)
@@ -247,15 +274,27 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
247274 . accessibilityIdentifier ( " MessageListView " )
248275 }
249276
250- private func additionalTopPadding( showsLastInGroupInfo: Bool ) -> CGFloat {
251- showsLastInGroupInfo ? lastInGroupHeaderSize : 0
277+ private func additionalTopPadding( showsLastInGroupInfo: Bool , showUnreadSeparator: Bool ) -> CGFloat {
278+ var padding = showsLastInGroupInfo ? lastInGroupHeaderSize : 0
279+ if showUnreadSeparator {
280+ padding += newMessagesSeparatorSize
281+ }
282+ return padding
252283 }
253284
254- private func offsetForDateIndicator( showsLastInGroupInfo: Bool ) -> CGFloat {
285+ private func offsetForDateIndicator( showsLastInGroupInfo: Bool , showUnreadSeparator : Bool ) -> CGFloat {
255286 var offset = messageListConfig. messageDisplayOptions. dateLabelSize
256- offset += additionalTopPadding ( showsLastInGroupInfo: showsLastInGroupInfo)
287+ offset += additionalTopPadding ( showsLastInGroupInfo: showsLastInGroupInfo, showUnreadSeparator : showUnreadSeparator )
257288 return offset
258289 }
290+
291+ private func newMessagesCount( for index: Int ? ) -> Int {
292+ if let index = index {
293+ return index + 1
294+ } else {
295+ return channel. unreadCount. messages
296+ }
297+ }
259298
260299 private func showsAllData( for message: ChatMessage ) -> Bool {
261300 if !messageListConfig. groupMessages {
@@ -303,6 +342,34 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
303342 }
304343}
305344
345+ public struct NewMessagesIndicator : View {
346+
347+ @Injected ( \. colors) var colors
348+
349+ @Binding var newMessagesStartId : String ?
350+ var count : Int
351+
352+ public init ( newMessagesStartId: Binding < String ? > , count: Int ) {
353+ _newMessagesStartId = newMessagesStartId
354+ self . count = count
355+ }
356+
357+ public var body : some View {
358+ HStack {
359+ Text ( " \( L10n . MessageList. newMessages ( count) ) " )
360+ . foregroundColor ( Color ( colors. textLowEmphasis) )
361+ . font ( . headline)
362+ . padding ( . all, 8 )
363+ }
364+ . frame ( maxWidth: . infinity)
365+ . background ( Color ( colors. background8) )
366+ . padding ( . top, 4 )
367+ . onDisappear {
368+ newMessagesStartId = nil
369+ }
370+ }
371+ }
372+
306373public struct ScrollToBottomButton : View {
307374 @Injected ( \. images) private var images
308375 @Injected ( \. colors) private var colors
0 commit comments