Skip to content

Commit c3e3a78

Browse files
Exposed a way for custom creation of view snapshots
1 parent a2ef77f commit c3e3a78

File tree

8 files changed

+66
-15
lines changed

8 files changed

+66
-15
lines changed

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public struct ChatChannelView<Factory: ViewFactory>: View, KeyboardReadable {
5959
onLongPress: { displayInfo in
6060
messageDisplayInfo = displayInfo
6161
withAnimation {
62-
viewModel.showReactionOverlay()
62+
viewModel.showReactionOverlay(for: AnyView(self))
6363
}
6464
}
6565
)

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -225,19 +225,8 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
225225
checkHeaderType()
226226
}
227227

228-
public func showReactionOverlay() {
229-
guard let view: UIView = topVC()?.view else {
230-
currentSnapshot = images.snapshot
231-
return
232-
}
233-
UIGraphicsBeginImageContext(view.frame.size)
234-
if let currentGraphicsContext = UIGraphicsGetCurrentContext() {
235-
view.layer.render(in: currentGraphicsContext)
236-
currentSnapshot = UIGraphicsGetImageFromCurrentImageContext()
237-
} else {
238-
currentSnapshot = images.snapshot
239-
}
240-
UIGraphicsEndImageContext()
228+
public func showReactionOverlay(for view: AnyView) {
229+
currentSnapshot = utils.snapshotCreator.makeSnapshot(for: view)
241230
}
242231

243232
public func messageActionExecuted(_ messageActionInfo: MessageActionInfo) {

Sources/StreamChatSwiftUI/Utils.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class Utils {
2323
public var messageListConfig: MessageListConfig
2424
public var composerConfig: ComposerConfig
2525
public var shouldSyncChannelControllerOnAppear: (ChatChannelController) -> Bool
26+
public var snapshotCreator: SnapshotCreator
2627

2728
var messageCachingUtils = MessageCachingUtils()
2829
var messageListDateUtils: MessageListDateUtils
@@ -43,6 +44,7 @@ public class Utils {
4344
composerConfig: ComposerConfig = ComposerConfig(),
4445
channelNamer: @escaping ChatChannelNamer = DefaultChatChannelNamer(),
4546
chatUserNamer: ChatUserNamer = DefaultChatUserNamer(),
47+
snapshotCreator: SnapshotCreator = DefaultSnapshotCreator(),
4648
shouldSyncChannelControllerOnAppear: @escaping (ChatChannelController) -> Bool = { _ in true }
4749
) {
4850
self.dateFormatter = dateFormatter
@@ -59,6 +61,7 @@ public class Utils {
5961
self.commandsConfig = commandsConfig
6062
self.messageListConfig = messageListConfig
6163
self.composerConfig = composerConfig
64+
self.snapshotCreator = snapshotCreator
6265
self.shouldSyncChannelControllerOnAppear = shouldSyncChannelControllerOnAppear
6366
messageListDateUtils = MessageListDateUtils(messageListConfig: messageListConfig)
6467
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// Copyright © 2022 Stream.io Inc. All rights reserved.
3+
//
4+
5+
import SwiftUI
6+
7+
/// Helper for creating snapshot from SwiftUI Views.
8+
public protocol SnapshotCreator {
9+
10+
/// Creates a snapshot of the provided SwiftUI view.
11+
/// - Parameter view: the view whose snapshot would be created.
12+
/// - Returns: `UIImage` representing the snapshot of the view.
13+
func makeSnapshot(for view: AnyView) -> UIImage
14+
}
15+
16+
/// Default implementation of the `SnapshotCreator`.
17+
public class DefaultSnapshotCreator: SnapshotCreator {
18+
19+
@Injected(\.images) var images
20+
21+
public init() { /* Public init. */ }
22+
23+
public func makeSnapshot(for view: AnyView) -> UIImage {
24+
let currentSnapshot: UIImage?
25+
guard let view: UIView = topVC()?.view else {
26+
return images.snapshot
27+
}
28+
UIGraphicsBeginImageContext(view.frame.size)
29+
if let currentGraphicsContext = UIGraphicsGetCurrentContext() {
30+
view.layer.render(in: currentGraphicsContext)
31+
currentSnapshot = UIGraphicsGetImageFromCurrentImageContext()
32+
} else {
33+
currentSnapshot = images.snapshot
34+
}
35+
UIGraphicsEndImageContext()
36+
return currentSnapshot ?? images.snapshot
37+
}
38+
}

StreamChatSwiftUI.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@
241241
84BB4C4C2841104700CBE004 /* MessageListDateUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BB4C4B2841104700CBE004 /* MessageListDateUtils.swift */; };
242242
84BB4C4E284115C200CBE004 /* MessageListDateUtils_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BB4C4D284115C200CBE004 /* MessageListDateUtils_Tests.swift */; };
243243
84BB4C50284122E600CBE004 /* ChatChannelViewDateOverlay_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BB4C4F284122E600CBE004 /* ChatChannelViewDateOverlay_Tests.swift */; };
244+
84C0C9A328CF18F700CD0136 /* SnapshotCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C0C9A228CF18F700CD0136 /* SnapshotCreator.swift */; };
244245
84C2042327917B6A0024D616 /* MessageListView_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C2042227917B6A0024D616 /* MessageListView_Tests.swift */; };
245246
84C94C8027567D3F007FE2B9 /* ChatChannelListViewModel_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C94C7F27567D3F007FE2B9 /* ChatChannelListViewModel_Tests.swift */; };
246247
84C94D0327578BF2007FE2B9 /* WaitFor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C94CEB27578BF2007FE2B9 /* WaitFor.swift */; };
@@ -632,6 +633,7 @@
632633
84BB4C4B2841104700CBE004 /* MessageListDateUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListDateUtils.swift; sourceTree = "<group>"; };
633634
84BB4C4D284115C200CBE004 /* MessageListDateUtils_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListDateUtils_Tests.swift; sourceTree = "<group>"; };
634635
84BB4C4F284122E600CBE004 /* ChatChannelViewDateOverlay_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatChannelViewDateOverlay_Tests.swift; sourceTree = "<group>"; };
636+
84C0C9A228CF18F700CD0136 /* SnapshotCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotCreator.swift; sourceTree = "<group>"; };
635637
84C2042227917B6A0024D616 /* MessageListView_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListView_Tests.swift; sourceTree = "<group>"; };
636638
84C94C7E27567D3F007FE2B9 /* StreamChatSwiftUITests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StreamChatSwiftUITests-Bridging-Header.h"; sourceTree = "<group>"; };
637639
84C94C7F27567D3F007FE2B9 /* ChatChannelListViewModel_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatChannelListViewModel_Tests.swift; sourceTree = "<group>"; };
@@ -1169,6 +1171,7 @@
11691171
8465FD352746A95600AF091E /* LazyView.swift */,
11701172
8465FD362746A95600AF091E /* KeyboardHandling.swift */,
11711173
8465FD372746A95600AF091E /* ImageLoading.swift */,
1174+
84C0C9A228CF18F700CD0136 /* SnapshotCreator.swift */,
11721175
8465FD4A2746A95600AF091E /* BundleExtensions.swift */,
11731176
8465FD3B2746A95600AF091E /* StringExtensions.swift */,
11741177
841B64C92775BBC10016FF3B /* Errors.swift */,
@@ -1903,6 +1906,7 @@
19031906
8465FD8A2746A95700AF091E /* DiscardAttachmentButton.swift in Sources */,
19041907
8465FDCB2746A95700AF091E /* ChatChannelListView.swift in Sources */,
19051908
841B2EF4278DB9E500ED619E /* MessageListHelperViews.swift in Sources */,
1909+
84C0C9A328CF18F700CD0136 /* SnapshotCreator.swift in Sources */,
19061910
8465FDD22746A95800AF091E /* Utils.swift in Sources */,
19071911
8465FDA12746A95700AF091E /* ChatChannelHeaderViewModifier.swift in Sources */,
19081912
84F2908A276B90610045472D /* GalleryView.swift in Sources */,

StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
@testable import StreamChat
66
@testable import StreamChatSwiftUI
7+
import SwiftUI
78
import XCTest
89

910
class ChatChannelViewModel_Tests: StreamChatTestCase {
@@ -93,7 +94,7 @@ class ChatChannelViewModel_Tests: StreamChatTestCase {
9394
let viewModel = ChatChannelViewModel(channelController: channelController)
9495

9596
// When
96-
viewModel.showReactionOverlay()
97+
viewModel.showReactionOverlay(for: AnyView(EmptyView()))
9798

9899
// Then
99100
XCTAssert(viewModel.currentSnapshot != nil)

StreamChatSwiftUITests/Tests/ChatChannel/MessageListView_Tests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
@testable import SnapshotTesting
66
@testable import StreamChat
77
@testable import StreamChatSwiftUI
8+
import SwiftUI
89
import XCTest
910

1011
class MessageListView_Tests: StreamChatTestCase {
@@ -59,6 +60,21 @@ class MessageListView_Tests: StreamChatTestCase {
5960
assertSnapshot(matching: messageListView, as: .image)
6061
}
6162

63+
func test_messageListView_snapshotFallback() {
64+
// Given
65+
let channelConfig = ChannelConfig(reactionsEnabled: true)
66+
let messageListView = makeMessageListView(channelConfig: channelConfig)
67+
.applyDefaultSize()
68+
69+
// When
70+
let snapshotCreator = DefaultSnapshotCreator()
71+
let snapshot = snapshotCreator.makeSnapshot(for: AnyView(messageListView))
72+
let view = Image(uiImage: snapshot)
73+
74+
// Then
75+
assertSnapshot(matching: view, as: .image)
76+
}
77+
6278
// MARK: - private
6379

6480
private func makeMessageListView(
Loading

0 commit comments

Comments
 (0)