Skip to content

Commit 9051682

Browse files
Added possiblity to inject view models
1 parent 5e88503 commit 9051682

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ public struct ChatChannelView<Factory: ViewFactory>: View, KeyboardReadable {
1919

2020
public init(
2121
viewFactory: Factory,
22+
viewModel: ChatChannelViewModel? = nil,
2223
channelController: ChatChannelController,
2324
messageController: ChatMessageController? = nil,
2425
scrollToMessage: ChatMessage? = nil
2526
) {
2627
_viewModel = StateObject(
27-
wrappedValue: ViewModelsFactory.makeChannelViewModel(
28+
wrappedValue: viewModel ?? ViewModelsFactory.makeChannelViewModel(
2829
with: channelController,
2930
messageController: messageController,
3031
scrollToMessage: scrollToMessage

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ public struct ChatChannelListView<Factory: ViewFactory>: View {
2121

2222
public init(
2323
viewFactory: Factory,
24+
viewModel: ChatChannelListViewModel? = nil,
2425
channelListController: ChatChannelListController? = nil,
2526
title: String = "Stream Chat",
2627
onItemTap: ((ChatChannel) -> Void)? = nil,
2728
selectedChannelId: String? = nil
2829
) {
29-
let channelListVM = ViewModelsFactory.makeChannelListViewModel(
30+
let channelListVM = viewModel ?? ViewModelsFactory.makeChannelListViewModel(
3031
channelListController: channelListController,
3132
selectedChannelId: selectedChannelId
3233
)

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListViewModel.swift

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
2020
/// The maximum number of images that combine to form a single avatar
2121
private let maxNumberOfImagesInCombinedAvatar = 4
2222

23-
private var controller: ChatChannelListController!
23+
private var controller: ChatChannelListController?
2424

2525
/// Used when screen is shown from a deeplink.
2626
private var selectedChannelId: String?
@@ -30,6 +30,8 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
3030

3131
private var messageSearchController: ChatMessageSearchController?
3232

33+
private var timer: Timer?
34+
3335
/// Controls loading the channels.
3436
@Atomic private var loadingNextChannels: Bool = false
3537

@@ -121,15 +123,15 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
121123
///
122124
/// - Parameter index: the currently displayed index.
123125
public func checkForChannels(index: Int) {
124-
if index < controller.channels.count - 10 {
126+
if index < controller?.channels.count ?? 0 - 10 {
125127
return
126128
}
127129

128130
if _loadingNextChannels.compareAndSwap(old: false, new: true) {
129-
controller.loadNextChannels { [weak self] _ in
131+
controller?.loadNextChannels { [weak self] _ in
130132
guard let self = self else { return }
131133
self.loadingNextChannels = false
132-
self.channels = self.controller.channels
134+
self.updateChannels()
133135
}
134136
}
135137
}
@@ -238,26 +240,30 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
238240
}
239241

240242
private func makeDefaultChannelListController() {
243+
guard let currentUserId = chatClient.currentUserId else {
244+
observeClientIdChange()
245+
return
246+
}
241247
controller = chatClient.channelListController(
242-
query: .init(filter: .containMembers(userIds: [chatClient.currentUserId!]))
248+
query: .init(filter: .containMembers(userIds: [currentUserId]))
243249
)
244250
}
245251

246252
private func setupChannelListController() {
247-
controller.delegate = self
253+
controller?.delegate = self
248254

249-
channels = controller.channels
255+
updateChannels()
250256

251257
loading = true
252-
controller.synchronize { [weak self] error in
258+
controller?.synchronize { [weak self] error in
253259
guard let self = self else { return }
254260
self.loading = false
255261
if error != nil {
256262
// handle error
257263
self.channelAlertType = .error
258264
} else {
259265
// access channels
260-
self.channels = self.controller.channels
266+
self.updateChannels()
261267
self.checkForDeeplinks()
262268
}
263269
}
@@ -296,9 +302,30 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
296302
} else {
297303
messageSearchController = nil
298304
searchResults = []
299-
channels = controller.channels
305+
updateChannels()
300306
}
301307
}
308+
309+
private func observeClientIdChange() {
310+
timer?.invalidate()
311+
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self] _ in
312+
guard let self = self else { return }
313+
if self.chatClient.currentUserId != nil {
314+
self.stopTimer()
315+
self.makeDefaultChannelListController()
316+
self.setupChannelListController()
317+
}
318+
})
319+
}
320+
321+
private func stopTimer() {
322+
timer?.invalidate()
323+
timer = nil
324+
}
325+
326+
private func updateChannels() {
327+
channels = controller?.channels ?? LazyCachedMapCollection<ChatChannel>()
328+
}
302329
}
303330

304331
/// Enum for the type of alert presented in the channel list view.

0 commit comments

Comments
 (0)