Skip to content

Commit 9a83c3f

Browse files
Fixed issue with blinking navigation header when many messages sent
1 parent fd0f4ff commit 9a83c3f

File tree

7 files changed

+50
-7
lines changed

7 files changed

+50
-7
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
33

44
# Upcoming
55

6+
### ✅ Added
7+
- Configuring avatars visibility in groups
8+
69
### 🔄 Changed
10+
- Message list creation requires `shouldShowTypingIndicator` as a parameter
11+
12+
### 🐞 Fixed
13+
- Channel header sometimes blinks when many messages are sent
714

815
# [4.20.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.20.0)
916
_August 04, 2022_

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public struct ChatChannelView<Factory: ViewFactory>: View, KeyboardReadable {
5353
currentDateString: viewModel.currentDateString,
5454
listId: viewModel.listId,
5555
isMessageThread: viewModel.isMessageThread,
56+
shouldShowTypingIndicator: viewModel.shouldShowTypingIndicator,
5657
onMessageAppear: viewModel.handleMessageAppear(index:),
5758
onScrollToBottom: viewModel.scrollToLastMessage,
5859
onLongPress: { displayInfo in

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
9090
}
9191
}
9292
}
93+
94+
@Published public var shouldShowTypingIndicator = false
9395

9496
public var channel: ChatChannel? {
9597
channelController.channel
@@ -219,6 +221,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
219221
channelController: ChatChannelController
220222
) {
221223
checkReadIndicators(for: channel)
224+
checkTypingIndicator()
222225
checkHeaderType()
223226
}
224227

@@ -355,7 +358,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
355358

356359
if !reactionsShown && isMessageThread {
357360
type = .messageThread
358-
} else if !typingUsers.isEmpty {
361+
} else if !typingUsers.isEmpty && utils.messageListConfig.typingIndicatorPlacement == .navigationBar {
359362
type = .typingIndicator
360363
} else {
361364
type = .regular
@@ -477,6 +480,16 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
477480
}
478481
}
479482

483+
private func checkTypingIndicator() {
484+
guard let channel = channel else { return }
485+
let shouldShow = !channel.currentlyTypingUsersFiltered(currentUserId: chatClient.currentUserId).isEmpty
486+
&& utils.messageListConfig.typingIndicatorPlacement == .bottomOverlay
487+
&& channel.config.typingEventsEnabled
488+
if shouldShow != shouldShowTypingIndicator {
489+
shouldShowTypingIndicator = shouldShow
490+
}
491+
}
492+
480493
deinit {
481494
messageCachingUtils.clearCache()
482495
if messageController == nil {

Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListView.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
2121
var currentDateString: String?
2222
var listId: String
2323
var isMessageThread: Bool
24+
var shouldShowTypingIndicator: Bool
2425

2526
var onMessageAppear: (Int) -> Void
2627
var onScrollToBottom: () -> Void
@@ -45,12 +46,6 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
4546
utils.messageListDateUtils
4647
}
4748

48-
private var shouldShowTypingIndicator: Bool {
49-
!channel.currentlyTypingUsersFiltered(currentUserId: chatClient.currentUserId).isEmpty
50-
&& messageListConfig.typingIndicatorPlacement == .bottomOverlay
51-
&& channel.config.typingEventsEnabled
52-
}
53-
5449
private var lastInGroupHeaderSize: CGFloat {
5550
messageListConfig.messageDisplayOptions.lastInGroupHeaderSize
5651
}
@@ -68,6 +63,7 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
6863
currentDateString: String? = nil,
6964
listId: String,
7065
isMessageThread: Bool,
66+
shouldShowTypingIndicator: Bool,
7167
onMessageAppear: @escaping (Int) -> Void,
7268
onScrollToBottom: @escaping () -> Void,
7369
onLongPress: @escaping (MessageDisplayInfo) -> Void
@@ -82,6 +78,7 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
8278
self.onMessageAppear = onMessageAppear
8379
self.onScrollToBottom = onScrollToBottom
8480
self.onLongPress = onLongPress
81+
self.shouldShowTypingIndicator = shouldShowTypingIndicator
8582
_scrolledId = scrolledId
8683
_showScrollToLatestButton = showScrollToLatestButton
8784
_quotedMessage = quotedMessage

StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,15 @@ class ChatChannelViewModel_Tests: StreamChatTestCase {
212212

213213
// Then
214214
XCTAssert(headerType == .regular)
215+
XCTAssert(viewModel.shouldShowTypingIndicator == false)
215216
}
216217

217218
func test_chatChannelVM_typingIndicatorMessageHeader() {
218219
// Given
220+
let utils = Utils(
221+
messageListConfig: MessageListConfig(typingIndicatorPlacement: .navigationBar)
222+
)
223+
streamChat = StreamChat(chatClient: chatClient, utils: utils)
219224
let channelController = makeChannelController()
220225
let typingUser: ChatChannelMember = ChatChannelMember.mock(id: .unique)
221226
let viewModel = ChatChannelViewModel(channelController: channelController)
@@ -233,6 +238,24 @@ class ChatChannelViewModel_Tests: StreamChatTestCase {
233238
XCTAssert(headerType == .typingIndicator)
234239
}
235240

241+
func test_chatChannelVM_typingIndicatorMessageList() {
242+
// Given
243+
let channelController = makeChannelController()
244+
let typingUser: ChatChannelMember = ChatChannelMember.mock(id: .unique)
245+
let viewModel = ChatChannelViewModel(channelController: channelController)
246+
247+
// When
248+
let channel: ChatChannel = .mockDMChannel(currentlyTypingUsers: Set(arrayLiteral: typingUser))
249+
channelController.simulate(
250+
channel: channel,
251+
change: .update(channel),
252+
typingUsers: Set(arrayLiteral: typingUser)
253+
)
254+
255+
// Then
256+
XCTAssert(viewModel.shouldShowTypingIndicator == true)
257+
}
258+
236259
func test_chatChannelVM_skipChanges() {
237260
// Given
238261
let channelController = makeChannelController()

StreamChatSwiftUITests/Tests/ChatChannel/MessageListViewAvatars_Tests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class MessageListViewAvatars_Tests: StreamChatTestCase {
8686
currentDateString: nil,
8787
listId: "listId",
8888
isMessageThread: false,
89+
shouldShowTypingIndicator: false,
8990
onMessageAppear: { _ in },
9091
onScrollToBottom: {},
9192
onLongPress: { _ in }

StreamChatSwiftUITests/Tests/ChatChannel/MessageListView_Tests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class MessageListView_Tests: StreamChatTestCase {
6969
currentDateString: nil,
7070
listId: "listId",
7171
isMessageThread: false,
72+
shouldShowTypingIndicator: false,
7273
onMessageAppear: { _ in },
7374
onScrollToBottom: {},
7475
onLongPress: { _ in }

0 commit comments

Comments
 (0)