mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Be more lenient with the power levels as they can still be missing at the time the various screens are created e.g. after accepting an invite.
The correct solution is to subscribe to update and update the UI accordingly when receiving them.
This commit is contained in:
committed by
Stefan Ceriu
parent
37cbf733d4
commit
9c28a69ccf
+8
-7
@@ -26,7 +26,7 @@ class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, Kn
|
|||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
super.init(initialViewState: KnockRequestsListScreenViewState(), mediaProvider: mediaProvider)
|
super.init(initialViewState: KnockRequestsListScreenViewState(), mediaProvider: mediaProvider)
|
||||||
|
|
||||||
updateRoomInfo(roomInfo: roomProxy.infoPublisher.value)
|
updateRoomInfo(roomProxy.infoPublisher.value)
|
||||||
|
|
||||||
setupSubscriptions()
|
setupSubscriptions()
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, Kn
|
|||||||
roomProxy.infoPublisher
|
roomProxy.infoPublisher
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] roomInfo in
|
.sink { [weak self] roomInfo in
|
||||||
self?.updateRoomInfo(roomInfo: roomInfo)
|
self?.updateRoomInfo(roomInfo)
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, Kn
|
|||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateRoomInfo(roomInfo: RoomInfoProxyProtocol) {
|
private func updateRoomInfo(_ roomInfo: RoomInfoProxyProtocol) {
|
||||||
switch roomInfo.joinRule {
|
switch roomInfo.joinRule {
|
||||||
case .knock, .knockRestricted:
|
case .knock, .knockRestricted:
|
||||||
state.isKnockableRoom = true
|
state.isKnockableRoom = true
|
||||||
@@ -218,10 +218,11 @@ class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, Kn
|
|||||||
state.isKnockableRoom = false
|
state.isKnockableRoom = false
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let powerLevels = roomProxy.infoPublisher.value.powerLevels else { fatalError("Missing room power levels") }
|
if let powerLevels = roomProxy.infoPublisher.value.powerLevels {
|
||||||
state.canAccept = powerLevels.canOwnUserInvite()
|
state.canAccept = powerLevels.canOwnUserInvite()
|
||||||
state.canDecline = powerLevels.canOwnUserKick()
|
state.canDecline = powerLevels.canOwnUserKick()
|
||||||
state.canBan = powerLevels.canOwnUserBan()
|
state.canBan = powerLevels.canOwnUserBan()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static let loadingIndicatorIdentifier = "\(KnockRequestsListScreenViewModel.self)-Loading"
|
private static let loadingIndicatorIdentifier = "\(KnockRequestsListScreenViewModel.self)-Loading"
|
||||||
|
|||||||
+12
-4
@@ -39,6 +39,13 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
|
|||||||
avatarURL: roomAvatar,
|
avatarURL: roomAvatar,
|
||||||
bindings: .init(name: roomName ?? "", topic: roomTopic ?? "")), mediaProvider: mediaProvider)
|
bindings: .init(name: roomName ?? "", topic: roomTopic ?? "")), mediaProvider: mediaProvider)
|
||||||
|
|
||||||
|
roomProxy.infoPublisher
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] roomInfo in
|
||||||
|
self?.updateRoomInfo(roomInfo: roomInfo)
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
updateRoomInfo(roomInfo: roomProxy.infoPublisher.value)
|
updateRoomInfo(roomInfo: roomProxy.infoPublisher.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,10 +94,11 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
|
|||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func updateRoomInfo(roomInfo: RoomInfoProxyProtocol) {
|
private func updateRoomInfo(roomInfo: RoomInfoProxyProtocol) {
|
||||||
guard let powerLevels = roomInfo.powerLevels else { fatalError("Missing room power levels") }
|
if let powerLevels = roomInfo.powerLevels {
|
||||||
state.canEditAvatar = powerLevels.canOwnUser(sendStateEvent: .roomAvatar)
|
state.canEditAvatar = powerLevels.canOwnUser(sendStateEvent: .roomAvatar)
|
||||||
state.canEditName = powerLevels.canOwnUser(sendStateEvent: .roomName)
|
state.canEditName = powerLevels.canOwnUser(sendStateEvent: .roomName)
|
||||||
state.canEditTopic = powerLevels.canOwnUser(sendStateEvent: .roomTopic)
|
state.canEditTopic = powerLevels.canOwnUser(sendStateEvent: .roomTopic)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func saveRoomDetails() {
|
private func saveRoomDetails() {
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
|
|
||||||
private func setupRoomSubscription() {
|
private func setupRoomSubscription() {
|
||||||
roomProxy.infoPublisher
|
roomProxy.infoPublisher
|
||||||
.throttle(for: .milliseconds(200), scheduler: DispatchQueue.main, latest: true)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] roomInfo in
|
.sink { [weak self] roomInfo in
|
||||||
self?.updateRoomInfo(roomInfo)
|
self?.updateRoomInfo(roomInfo)
|
||||||
}
|
}
|
||||||
@@ -233,8 +233,6 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
state.canBanUsers = powerLevels.canOwnUserBan()
|
state.canBanUsers = powerLevels.canOwnUserBan()
|
||||||
state.canJoinCall = powerLevels.canOwnUserJoinCall()
|
state.canJoinCall = powerLevels.canOwnUserJoinCall()
|
||||||
state.canEditRolesOrPermissions = powerLevels.suggestedRole(forUser: roomProxy.ownUserID) == .administrator
|
state.canEditRolesOrPermissions = powerLevels.suggestedRole(forUser: roomProxy.ownUserID) == .administrator
|
||||||
} else {
|
|
||||||
fatalError("Missing room power levels")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,10 +103,11 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
|
|||||||
bannedMembers: roomMembersDetails.bannedMembers,
|
bannedMembers: roomMembersDetails.bannedMembers,
|
||||||
bindings: state.bindings)
|
bindings: state.bindings)
|
||||||
|
|
||||||
guard let powerLevels = roomProxy.infoPublisher.value.powerLevels else { fatalError("Missing room power levels") }
|
if let powerLevels = roomProxy.infoPublisher.value.powerLevels {
|
||||||
self.state.canInviteUsers = powerLevels.canOwnUserInvite()
|
self.state.canInviteUsers = powerLevels.canOwnUserInvite()
|
||||||
self.state.canKickUsers = powerLevels.canOwnUserKick()
|
self.state.canKickUsers = powerLevels.canOwnUserKick()
|
||||||
self.state.canBanUsers = powerLevels.canOwnUserBan()
|
self.state.canBanUsers = powerLevels.canOwnUserBan()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -114,8 +114,9 @@ class RoomRolesAndPermissionsScreenViewModel: RoomRolesAndPermissionsScreenViewM
|
|||||||
// MARK: - Permissions
|
// MARK: - Permissions
|
||||||
|
|
||||||
private func updateRoomInfo(roomInfo: RoomInfoProxyProtocol) {
|
private func updateRoomInfo(roomInfo: RoomInfoProxyProtocol) {
|
||||||
guard let powerLevels = roomInfo.powerLevels else { fatalError("Missing room power levels") }
|
if let powerLevels = roomInfo.powerLevels {
|
||||||
state.permissions = .init(powerLevels: powerLevels.values)
|
state.permissions = .init(powerLevels: powerLevels.values)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func editPermissions(group: RoomRolesAndPermissionsScreenPermissionsGroup) {
|
private func editPermissions(group: RoomRolesAndPermissionsScreenPermissionsGroup) {
|
||||||
|
|||||||
+17
-2
@@ -19,10 +19,13 @@ private enum SuggestionTriggerRegex {
|
|||||||
final class CompletionSuggestionService: CompletionSuggestionServiceProtocol {
|
final class CompletionSuggestionService: CompletionSuggestionServiceProtocol {
|
||||||
private let roomProxy: JoinedRoomProxyProtocol
|
private let roomProxy: JoinedRoomProxyProtocol
|
||||||
private var canMentionAllUsers = false
|
private var canMentionAllUsers = false
|
||||||
|
|
||||||
private(set) var suggestionsPublisher: AnyPublisher<[SuggestionItem], Never> = Empty().eraseToAnyPublisher()
|
private(set) var suggestionsPublisher: AnyPublisher<[SuggestionItem], Never> = Empty().eraseToAnyPublisher()
|
||||||
|
|
||||||
private let suggestionTriggerSubject = CurrentValueSubject<SuggestionTrigger?, Never>(nil)
|
private let suggestionTriggerSubject = CurrentValueSubject<SuggestionTrigger?, Never>(nil)
|
||||||
|
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
init(roomProxy: JoinedRoomProxyProtocol,
|
init(roomProxy: JoinedRoomProxyProtocol,
|
||||||
roomListPublisher: AnyPublisher<[RoomSummary], Never>) {
|
roomListPublisher: AnyPublisher<[RoomSummary], Never>) {
|
||||||
self.roomProxy = roomProxy
|
self.roomProxy = roomProxy
|
||||||
@@ -47,8 +50,14 @@ final class CompletionSuggestionService: CompletionSuggestionServiceProtocol {
|
|||||||
self?.suggestionTriggerSubject.value != nil ? .milliseconds(500) : .milliseconds(0)
|
self?.suggestionTriggerSubject.value != nil ? .milliseconds(500) : .milliseconds(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let powerLevels = roomProxy.infoPublisher.value.powerLevels else { fatalError("Missing room power levels") }
|
roomProxy.infoPublisher
|
||||||
canMentionAllUsers = powerLevels.canOwnUserTriggerRoomNotification()
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] roomInfo in
|
||||||
|
self?.updateRoomInfo(roomInfo)
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
updateRoomInfo(roomProxy.infoPublisher.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func processTextMessage(_ textMessage: String, selectedRange: NSRange) {
|
func processTextMessage(_ textMessage: String, selectedRange: NSRange) {
|
||||||
@@ -61,6 +70,12 @@ final class CompletionSuggestionService: CompletionSuggestionServiceProtocol {
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func updateRoomInfo(_ roomInfo: RoomInfoProxyProtocol) {
|
||||||
|
if let powerLevels = roomProxy.infoPublisher.value.powerLevels {
|
||||||
|
canMentionAllUsers = powerLevels.canOwnUserTriggerRoomNotification()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func membersSuggestions(suggestionTrigger: SuggestionTrigger,
|
private func membersSuggestions(suggestionTrigger: SuggestionTrigger,
|
||||||
members: [RoomMemberProxyProtocol],
|
members: [RoomMemberProxyProtocol],
|
||||||
ownUserID: String) -> [SuggestionItem] {
|
ownUserID: String) -> [SuggestionItem] {
|
||||||
|
|||||||
@@ -77,12 +77,12 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
super.init(initialViewState: appHooks.roomScreenHook.update(viewState),
|
super.init(initialViewState: appHooks.roomScreenHook.update(viewState),
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
|
|
||||||
|
updateRoomInfo(roomProxy.infoPublisher.value)
|
||||||
|
setupSubscriptions(ongoingCallRoomIDPublisher: ongoingCallRoomIDPublisher)
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
await handleRoomInfoUpdate(roomProxy.infoPublisher.value)
|
|
||||||
await updateVerificationBadge()
|
await updateVerificationBadge()
|
||||||
}
|
}
|
||||||
|
|
||||||
setupSubscriptions(ongoingCallRoomIDPublisher: ongoingCallRoomIDPublisher)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func process(viewAction: RoomScreenViewAction) {
|
override func process(viewAction: RoomScreenViewAction) {
|
||||||
@@ -157,31 +157,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
appSettings.$knockingEnabled
|
appSettings.$knockingEnabled
|
||||||
.weakAssign(to: \.state.isKnockingEnabled, on: self)
|
.weakAssign(to: \.state.isKnockingEnabled, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
let roomInfoSubscription = roomProxy
|
roomProxy.infoPublisher
|
||||||
.infoPublisher
|
.receive(on: DispatchQueue.main)
|
||||||
|
|
||||||
roomInfoSubscription
|
|
||||||
.throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: true)
|
|
||||||
.sink { [weak self] roomInfo in
|
.sink { [weak self] roomInfo in
|
||||||
guard let self else { return }
|
self?.updateRoomInfo(roomInfo)
|
||||||
state.roomTitle = roomInfo.displayName ?? roomProxy.id
|
|
||||||
state.roomAvatar = roomInfo.avatar
|
|
||||||
state.hasOngoingCall = roomInfo.hasRoomCall
|
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
Task { [weak self] in
|
|
||||||
for await roomInfo in roomInfoSubscription.receive(on: DispatchQueue.main).values {
|
|
||||||
guard !Task.isCancelled else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await self?.handleRoomInfoUpdate(roomInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
let identityStatusChangesPublisher = roomProxy.identityStatusChangesPublisher.receive(on: DispatchQueue.main)
|
let identityStatusChangesPublisher = roomProxy.identityStatusChangesPublisher.receive(on: DispatchQueue.main)
|
||||||
|
|
||||||
Task { [weak self] in
|
Task { [weak self] in
|
||||||
@@ -332,7 +315,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleRoomInfoUpdate(_ roomInfo: RoomInfoProxyProtocol) async {
|
private func updateRoomInfo(_ roomInfo: RoomInfoProxyProtocol) {
|
||||||
|
state.roomTitle = roomInfo.displayName ?? roomProxy.id
|
||||||
|
state.roomAvatar = roomInfo.avatar
|
||||||
|
state.hasOngoingCall = roomInfo.hasRoomCall
|
||||||
state.hasSuccessor = roomInfo.successor != nil
|
state.hasSuccessor = roomInfo.successor != nil
|
||||||
|
|
||||||
let pinnedEventIDs = roomInfo.pinnedEventIDs
|
let pinnedEventIDs = roomInfo.pinnedEventIDs
|
||||||
@@ -348,12 +334,13 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
state.isKnockableRoom = false
|
state.isKnockableRoom = false
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let powerLevels = roomInfo.powerLevels else { fatalError("Missing room power levels") }
|
if let powerLevels = roomInfo.powerLevels {
|
||||||
state.canSendMessage = powerLevels.canOwnUser(sendMessage: .roomMessage)
|
state.canSendMessage = powerLevels.canOwnUser(sendMessage: .roomMessage)
|
||||||
state.canJoinCall = powerLevels.canOwnUserJoinCall()
|
state.canJoinCall = powerLevels.canOwnUserJoinCall()
|
||||||
state.canAcceptKnocks = powerLevels.canOwnUserInvite()
|
state.canAcceptKnocks = powerLevels.canOwnUserInvite()
|
||||||
state.canDeclineKnocks = powerLevels.canOwnUserKick()
|
state.canDeclineKnocks = powerLevels.canOwnUserKick()
|
||||||
state.canBan = powerLevels.canOwnUserBan()
|
state.canBan = powerLevels.canOwnUserBan()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupPinnedEventsTimelineItemProviderIfNeeded() {
|
private func setupPinnedEventsTimelineItemProviderIfNeeded() {
|
||||||
|
|||||||
@@ -23,18 +23,14 @@ class ThreadTimelineScreenViewModel: ThreadTimelineScreenViewModelType, ThreadTi
|
|||||||
|
|
||||||
super.init(initialViewState: ThreadTimelineScreenViewState())
|
super.init(initialViewState: ThreadTimelineScreenViewState())
|
||||||
|
|
||||||
Task { [weak self] in
|
roomProxy.infoPublisher
|
||||||
for await roomInfo in roomProxy.infoPublisher.receive(on: DispatchQueue.main).values {
|
.receive(on: DispatchQueue.main)
|
||||||
guard !Task.isCancelled else {
|
.sink { [weak self] roomInfo in
|
||||||
return
|
self?.updateRoomInfo(roomInfo)
|
||||||
}
|
|
||||||
|
|
||||||
self?.handleRoomInfoUpdate(roomInfo)
|
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
handleRoomInfoUpdate(roomProxy.infoPublisher.value)
|
updateRoomInfo(roomProxy.infoPublisher.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@@ -62,8 +58,9 @@ class ThreadTimelineScreenViewModel: ThreadTimelineScreenViewModelType, ThreadTi
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func handleRoomInfoUpdate(_ roomInfo: RoomInfoProxyProtocol) {
|
private func updateRoomInfo(_ roomInfo: RoomInfoProxyProtocol) {
|
||||||
guard let powerLevels = roomInfo.powerLevels else { fatalError("Missing room power levels") }
|
if let powerLevels = roomInfo.powerLevels {
|
||||||
state.canSendMessage = powerLevels.canOwnUser(sendMessage: .roomMessage)
|
state.canSendMessage = powerLevels.canOwnUser(sendMessage: .roomMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,8 +119,6 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
setupSubscriptions()
|
setupSubscriptions()
|
||||||
setupDirectRoomSubscriptionsIfNeeded()
|
setupDirectRoomSubscriptionsIfNeeded()
|
||||||
|
|
||||||
updateRoomInfo(roomInfo: roomProxy.infoPublisher.value)
|
|
||||||
|
|
||||||
state.audioPlayerStateProvider = { [weak self] itemID -> AudioPlayerState? in
|
state.audioPlayerStateProvider = { [weak self] itemID -> AudioPlayerState? in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return nil
|
return nil
|
||||||
@@ -144,6 +142,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
state.timelineState.paginationState = timelineController.paginationState
|
state.timelineState.paginationState = timelineController.paginationState
|
||||||
buildTimelineViews(timelineItems: timelineController.timelineItems)
|
buildTimelineViews(timelineItems: timelineController.timelineItems)
|
||||||
|
|
||||||
|
updateRoomInfo(roomProxy.infoPublisher.value)
|
||||||
updateMembers(roomProxy.membersPublisher.value)
|
updateMembers(roomProxy.membersPublisher.value)
|
||||||
|
|
||||||
// Note: beware if we get to e.g. restore a reply / edit,
|
// Note: beware if we get to e.g. restore a reply / edit,
|
||||||
@@ -402,16 +401,17 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateRoomInfo(roomInfo: RoomInfoProxyProtocol) {
|
private func updateRoomInfo(_ roomInfo: RoomInfoProxyProtocol) {
|
||||||
state.pinnedEventIDs = roomInfo.pinnedEventIDs
|
state.pinnedEventIDs = roomInfo.pinnedEventIDs
|
||||||
|
|
||||||
guard let powerLevels = roomInfo.powerLevels else { fatalError("Missing room power levels") }
|
if let powerLevels = roomInfo.powerLevels {
|
||||||
state.canCurrentUserSendMessage = powerLevels.canOwnUser(sendMessage: .roomMessage)
|
state.canCurrentUserSendMessage = powerLevels.canOwnUser(sendMessage: .roomMessage)
|
||||||
state.canCurrentUserRedactOthers = powerLevels.canOwnUserRedactOther()
|
state.canCurrentUserRedactOthers = powerLevels.canOwnUserRedactOther()
|
||||||
state.canCurrentUserRedactSelf = powerLevels.canOwnUserRedactOwn()
|
state.canCurrentUserRedactSelf = powerLevels.canOwnUserRedactOwn()
|
||||||
state.canCurrentUserPin = powerLevels.canOwnUserPinOrUnpin()
|
state.canCurrentUserPin = powerLevels.canOwnUserPinOrUnpin()
|
||||||
state.canCurrentUserKick = powerLevels.canOwnUserKick()
|
state.canCurrentUserKick = powerLevels.canOwnUserKick()
|
||||||
state.canCurrentUserBan = powerLevels.canOwnUserBan()
|
state.canCurrentUserBan = powerLevels.canOwnUserBan()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupSubscriptions() {
|
private func setupSubscriptions() {
|
||||||
@@ -440,17 +440,12 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
let roomInfoSubscription = roomProxy.infoPublisher
|
roomProxy.infoPublisher
|
||||||
Task { [weak self] in
|
.receive(on: DispatchQueue.main)
|
||||||
for await roomInfo in roomInfoSubscription.receive(on: DispatchQueue.main).values {
|
.sink { [weak self] roomInfo in
|
||||||
guard !Task.isCancelled else {
|
self?.updateRoomInfo(roomInfo)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self?.updateRoomInfo(roomInfo: roomInfo)
|
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
setupAppSettingsSubscriptions()
|
setupAppSettingsSubscriptions()
|
||||||
|
|
||||||
|
|||||||
@@ -165,15 +165,19 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
func testRoomInfoUpdate() async throws {
|
func testRoomInfoUpdate() async throws {
|
||||||
var configuration = JoinedRoomProxyMockConfiguration(id: "TestID", name: "StartingName", avatarURL: nil, hasOngoingCall: false)
|
var configuration = JoinedRoomProxyMockConfiguration(id: "TestID", name: "StartingName", avatarURL: nil, hasOngoingCall: false)
|
||||||
let infoSubject = CurrentValueSubject<RoomInfoProxyProtocol, Never>(RoomInfoProxyMock(configuration))
|
|
||||||
let roomProxyMock = JoinedRoomProxyMock(configuration)
|
let roomProxyMock = JoinedRoomProxyMock(configuration)
|
||||||
|
|
||||||
let powerLevelsMock = RoomPowerLevelsProxyMock(configuration: .init())
|
let powerLevelsMock = RoomPowerLevelsProxyMock(configuration: .init())
|
||||||
|
powerLevelsMock.canUserJoinCallUserIDReturnValue = .success(false)
|
||||||
|
powerLevelsMock.canOwnUserJoinCallReturnValue = false
|
||||||
roomProxyMock.powerLevelsReturnValue = .success(powerLevelsMock)
|
roomProxyMock.powerLevelsReturnValue = .success(powerLevelsMock)
|
||||||
|
|
||||||
// setup the room proxy actions publisher
|
let roomInfoProxyMock = RoomInfoProxyMock(configuration)
|
||||||
powerLevelsMock.canUserJoinCallUserIDReturnValue = .success(false)
|
roomInfoProxyMock.powerLevels = powerLevelsMock
|
||||||
|
|
||||||
|
let infoSubject = CurrentValueSubject<RoomInfoProxyProtocol, Never>(roomInfoProxyMock)
|
||||||
roomProxyMock.underlyingInfoPublisher = infoSubject.asCurrentValuePublisher()
|
roomProxyMock.underlyingInfoPublisher = infoSubject.asCurrentValuePublisher()
|
||||||
|
|
||||||
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
initialSelectedPinnedEventID: nil,
|
initialSelectedPinnedEventID: nil,
|
||||||
@@ -186,27 +190,25 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
self.viewModel = viewModel
|
self.viewModel = viewModel
|
||||||
|
|
||||||
var deferred = deferFulfillment(viewModel.context.$viewState) { viewState in
|
XCTAssertEqual(viewModel.state.roomTitle, "StartingName")
|
||||||
viewState.roomTitle == "StartingName" &&
|
XCTAssertEqual(viewModel.state.roomAvatar, .room(id: "TestID", name: "StartingName", avatarURL: nil))
|
||||||
viewState.roomAvatar == .room(id: "TestID", name: "StartingName", avatarURL: nil) &&
|
XCTAssertFalse(viewModel.state.canJoinCall)
|
||||||
!viewState.canJoinCall &&
|
XCTAssertFalse(viewModel.state.hasOngoingCall)
|
||||||
!viewState.hasOngoingCall
|
|
||||||
}
|
let deferred = deferFulfillment(viewModel.context.$viewState) { viewState in
|
||||||
try await deferred.fulfill()
|
|
||||||
|
|
||||||
configuration.name = "NewName"
|
|
||||||
configuration.avatarURL = .mockMXCAvatar
|
|
||||||
configuration.hasOngoingCall = true
|
|
||||||
powerLevelsMock.canUserJoinCallUserIDReturnValue = .success(true)
|
|
||||||
|
|
||||||
deferred = deferFulfillment(viewModel.context.$viewState) { viewState in
|
|
||||||
viewState.roomTitle == "NewName" &&
|
viewState.roomTitle == "NewName" &&
|
||||||
viewState.roomAvatar == .room(id: "TestID", name: "NewName", avatarURL: .mockMXCAvatar) &&
|
viewState.roomAvatar == .room(id: "TestID", name: "NewName", avatarURL: .mockMXCAvatar) &&
|
||||||
viewState.canJoinCall &&
|
viewState.canJoinCall &&
|
||||||
viewState.hasOngoingCall
|
viewState.hasOngoingCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configuration.name = "NewName"
|
||||||
|
configuration.avatarURL = .mockMXCAvatar
|
||||||
|
configuration.hasOngoingCall = true
|
||||||
|
powerLevelsMock.canUserJoinCallUserIDReturnValue = .success(true)
|
||||||
|
|
||||||
infoSubject.send(RoomInfoProxyMock(configuration))
|
infoSubject.send(RoomInfoProxyMock(configuration))
|
||||||
|
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user