Skip to content

Commit c18253b

Browse files
authored
Fix crash when force unwrapping messageDisplayInfo in ChatChannelView (#1052)
* Fix crash when force unwrapping messageDisplayInfo in ChatChannelView * Update CHANGELOG.md
1 parent 1e35bca commit c18253b

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1111
### 🐞 Fixed
1212
- Fix `Throttler` crash in `ChatChannelViewModel.handleMessageAppear()` [#1050](https://github.com/GetStream/stream-chat-swiftui/pull/1050)
1313
- Remove unnecessary channel query call when leaving the channel view in a mid-page [#1050](https://github.com/GetStream/stream-chat-swiftui/pull/1050)
14+
- Fix crash when force unwrapping `messageDisplayInfo` in `ChatChannelView` [#1052](https://github.com/GetStream/stream-chat-swiftui/pull/1052)
1415

1516
# [4.92.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.92.0)
1617
_November 07, 2025_

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public struct ChatChannelView<Factory: ViewFactory>: View, KeyboardReadable {
145145
.opacity(0) // Fixes showing accessibility button shape
146146
}
147147
.overlay(
148-
viewModel.reactionsShown ?
148+
viewModel.currentSnapshot != nil && messageDisplayInfo != nil && viewModel.reactionsShown ?
149149
factory.makeReactionsOverlayView(
150150
channel: channel,
151151
currentSnapshot: viewModel.currentSnapshot!,

StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelView_Tests.swift

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,76 @@ class ChatChannelView_Tests: StreamChatTestCase {
167167
// Then
168168
assertSnapshot(matching: view, as: .image(perceptualPrecision: precision))
169169
}
170+
171+
// MARK: - Reactions Overlay Tests
172+
173+
func test_chatChannelView_doesNotCrash_whenCurrentSnapshotIsNil_andReactionsShownIsTrue() {
174+
// Given
175+
let controller = ChatChannelController_Mock.mock(
176+
channelQuery: .init(cid: .unique),
177+
channelListQuery: nil,
178+
client: chatClient
179+
)
180+
let mockChannel = ChatChannel.mock(cid: .unique, name: "Test channel")
181+
let message = ChatMessage.mock(
182+
id: .unique,
183+
cid: mockChannel.cid,
184+
text: "Test message",
185+
author: .mock(id: .unique, name: "User")
186+
)
187+
controller.simulateInitial(channel: mockChannel, messages: [message], state: .remoteDataFetched)
188+
189+
let viewModel = ChatChannelViewModel(channelController: controller)
190+
191+
// When
192+
viewModel.currentSnapshot = nil
193+
viewModel.reactionsShown = true
194+
195+
let view = ChatChannelView(
196+
viewFactory: DefaultViewFactory.shared,
197+
viewModel: viewModel,
198+
channelController: controller
199+
)
200+
201+
// Then - Should not crash when rendering
202+
let hostingController = UIHostingController(rootView: view)
203+
XCTAssertNotNil(hostingController.view)
204+
XCTAssertNil(viewModel.currentSnapshot)
205+
XCTAssertTrue(viewModel.reactionsShown)
206+
}
207+
208+
func test_chatChannelView_doesNotCrash_whenMessageDisplayInfoIsNil_andReactionsShownIsTrue() {
209+
// Given
210+
let controller = ChatChannelController_Mock.mock(
211+
channelQuery: .init(cid: .unique),
212+
channelListQuery: nil,
213+
client: chatClient
214+
)
215+
let mockChannel = ChatChannel.mock(cid: .unique, name: "Test channel")
216+
let message = ChatMessage.mock(
217+
id: .unique,
218+
cid: mockChannel.cid,
219+
text: "Test message",
220+
author: .mock(id: .unique, name: "User")
221+
)
222+
controller.simulateInitial(channel: mockChannel, messages: [message], state: .remoteDataFetched)
223+
224+
let viewModel = ChatChannelViewModel(channelController: controller)
225+
226+
// When
227+
viewModel.showReactionOverlay(for: AnyView(EmptyView()))
228+
// messageDisplayInfo remains nil (not set)
229+
230+
let view = ChatChannelView(
231+
viewFactory: DefaultViewFactory.shared,
232+
viewModel: viewModel,
233+
channelController: controller
234+
)
235+
236+
// Then - Should not crash when rendering
237+
let hostingController = UIHostingController(rootView: view)
238+
XCTAssertNotNil(hostingController.view)
239+
XCTAssertNotNil(viewModel.currentSnapshot)
240+
XCTAssertTrue(viewModel.reactionsShown)
241+
}
170242
}

0 commit comments

Comments
 (0)