mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Add room's update publisher (#952)
* Add room update publisher * Cleanup * Update room’s title * Add refresh logic in RoomDetailsScreenViewModel * Fix UTs * Add UT * Update timeline listener in RoomProxy * Fix caching in LoadableAvatarImage * Cleanup * Update RoomProxy api * Inject room proxy in RoomScreenViewModel * Cleanup * Fix UTs
This commit is contained in:
@@ -36,7 +36,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
canonicalAlias: roomProxy.canonicalAlias,
|
||||
isEncrypted: roomProxy.isEncrypted,
|
||||
isDirect: roomProxy.isDirect,
|
||||
title: roomProxy.displayName ?? roomProxy.name ?? "Unknown Room",
|
||||
title: roomProxy.roomTitle,
|
||||
topic: roomProxy.topic,
|
||||
avatarURL: roomProxy.avatarURL,
|
||||
permalink: roomProxy.permalink,
|
||||
@@ -81,6 +81,13 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
// MARK: - Private
|
||||
|
||||
private func setupSubscriptions() {
|
||||
switch roomProxy.registerTimelineListenerIfNeeded() {
|
||||
case .success, .failure(.roomListenerAlreadyRegistered):
|
||||
break
|
||||
case .failure:
|
||||
MXLog.error("Failed to register a room listener in room's details for the room \(roomProxy.id)")
|
||||
}
|
||||
|
||||
roomProxy.membersPublisher
|
||||
.sink { [weak self] members in
|
||||
guard let self else { return }
|
||||
@@ -102,6 +109,16 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
roomProxy.updatesPublisher
|
||||
.throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: true)
|
||||
.sink { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.state.title = self.roomProxy.roomTitle
|
||||
self.state.topic = self.roomProxy.topic
|
||||
self.state.avatarURL = self.roomProxy.avatarURL
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
private func buildMembersDetails(members: [RoomMemberProxyProtocol]) async -> RoomMembersDetails {
|
||||
|
||||
@@ -44,8 +44,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
viewModel = RoomScreenViewModel(timelineController: parameters.timelineController,
|
||||
mediaProvider: parameters.mediaProvider,
|
||||
roomName: parameters.roomProxy.displayName ?? parameters.roomProxy.name,
|
||||
roomAvatarUrl: parameters.roomProxy.avatarURL)
|
||||
roomProxy: parameters.roomProxy)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -76,7 +75,6 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
|
||||
func stop() {
|
||||
parameters.roomProxy.removeTimelineListener()
|
||||
viewModel.context.send(viewAction: .markRoomAsRead)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,17 +27,18 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
static let toastErrorID = "RoomScreenToastError"
|
||||
}
|
||||
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
private let timelineController: RoomTimelineControllerProtocol
|
||||
|
||||
init(timelineController: RoomTimelineControllerProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
roomName: String?,
|
||||
roomAvatarUrl: URL? = nil) {
|
||||
roomProxy: RoomProxyProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
self.timelineController = timelineController
|
||||
|
||||
super.init(initialViewState: RoomScreenViewState(roomId: timelineController.roomID,
|
||||
roomTitle: roomName ?? "Unknown room 💥",
|
||||
roomAvatarURL: roomAvatarUrl,
|
||||
roomTitle: roomProxy.roomTitle,
|
||||
roomAvatarURL: roomProxy.avatarURL,
|
||||
timelineStyle: ServiceLocator.shared.settings.timelineStyle,
|
||||
bindings: .init(composerText: "", composerFocused: false)),
|
||||
imageProvider: mediaProvider)
|
||||
@@ -70,6 +71,16 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
return self.contextMenuActionsForItemId(itemId)
|
||||
}
|
||||
|
||||
roomProxy
|
||||
.updatesPublisher
|
||||
.throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: true)
|
||||
.sink { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.state.roomTitle = roomProxy.roomTitle
|
||||
self.state.roomAvatarURL = roomProxy.avatarURL
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
ServiceLocator.shared.settings.$timelineStyle
|
||||
.weakAssign(to: \.state.timelineStyle, on: self)
|
||||
.store(in: &cancellables)
|
||||
@@ -406,5 +417,5 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
extension RoomScreenViewModel {
|
||||
static let mock = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Preview room")
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Preview room")))
|
||||
}
|
||||
|
||||
@@ -59,8 +59,7 @@ struct RoomHeaderView_Previews: PreviewProvider {
|
||||
static var bodyPlain: some View {
|
||||
let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Some Room name",
|
||||
roomAvatarUrl: URL.picturesDirectory)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Some Room name", avatarURL: URL.picturesDirectory)))
|
||||
|
||||
RoomHeaderView(context: viewModel.context)
|
||||
.previewLayout(.sizeThatFits)
|
||||
@@ -71,8 +70,7 @@ struct RoomHeaderView_Previews: PreviewProvider {
|
||||
static var bodyEncrypted: some View {
|
||||
let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Some Room name",
|
||||
roomAvatarUrl: nil)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Some Room name")))
|
||||
|
||||
RoomHeaderView(context: viewModel.context)
|
||||
.previewLayout(.sizeThatFits)
|
||||
|
||||
@@ -133,7 +133,7 @@ struct RoomScreen: View {
|
||||
struct RoomScreen_Previews: PreviewProvider {
|
||||
static let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Preview room")
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Preview room")))
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
|
||||
@@ -84,7 +84,7 @@ struct TimelineView: UIViewControllerRepresentable {
|
||||
struct TimelineTableView_Previews: PreviewProvider {
|
||||
static let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Preview room")
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Preview room")))
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
|
||||
Reference in New Issue
Block a user