Files
letro-ios/ElementX/Sources/Screens/KnockRequestsListScreen/KnockRequestsListScreenViewModel.swift
Mauro 3ffd37d4ae Knock Requests navigation flows (#3555)
* implemented navigations

* better naming for the enum

* removed list to banned users navigation

* polished the code

* avatarURL
2024-11-26 11:47:34 +00:00

108 lines
5.1 KiB
Swift

//
// Copyright 2022-2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import Combine
import SwiftUI
typealias KnockRequestsListScreenViewModelType = StateStoreViewModel<KnockRequestsListScreenViewState, KnockRequestsListScreenViewAction>
class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, KnockRequestsListScreenViewModelProtocol {
private let roomProxy: JoinedRoomProxyProtocol
private let actionsSubject: PassthroughSubject<KnockRequestsListScreenViewModelAction, Never> = .init()
var actionsPublisher: AnyPublisher<KnockRequestsListScreenViewModelAction, Never> {
actionsSubject.eraseToAnyPublisher()
}
init(roomProxy: JoinedRoomProxyProtocol, mediaProvider: MediaProviderProtocol) {
self.roomProxy = roomProxy
super.init(initialViewState: KnockRequestsListScreenViewState(), mediaProvider: mediaProvider)
updateRoomInfo(roomInfo: roomProxy.infoPublisher.value)
Task {
await updatePermissions()
}
setupSubscriptions()
}
// MARK: - Public
override func process(viewAction: KnockRequestsListScreenViewAction) {
switch viewAction {
case .acceptAllRequests:
state.bindings.alertInfo = .init(id: .acceptAllRequests,
title: L10n.screenKnockRequestsListAcceptAllAlertTitle,
message: L10n.screenKnockRequestsListAcceptAllAlertDescription,
primaryButton: .init(title: L10n.screenKnockRequestsListAcceptAllAlertConfirmButtonTitle,
// TODO: Implement action
action: nil),
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
case .acceptRequest(let userID):
// TODO: Implement
break
case .declineRequest(let userID):
state.bindings.alertInfo = .init(id: .declineRequest,
title: L10n.screenKnockRequestsListDeclineAlertTitle,
message: L10n.screenKnockRequestsListDeclineAlertDescription(userID),
primaryButton: .init(title: L10n.screenKnockRequestsListDeclineAlertConfirmButtonTitle,
role: .destructive,
// TODO: Implement action
action: nil),
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
case .ban(let userID):
state.bindings.alertInfo = .init(id: .declineAndBan,
title: L10n.screenKnockRequestsListBanAlertTitle,
message: L10n.screenKnockRequestsListBanAlertDescription(userID),
// TODO: Implement action
primaryButton: .init(title: L10n.screenKnockRequestsListBanAlertConfirmButtonTitle,
role: .destructive,
action: nil),
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
}
}
// MARK: - Private
private func setupSubscriptions() {
roomProxy.infoPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] roomInfo in
self?.updateRoomInfo(roomInfo: roomInfo)
Task { await self?.updatePermissions() }
}
.store(in: &cancellables)
}
private func updateRoomInfo(roomInfo: RoomInfoProxy) {
switch roomInfo.joinRule {
case .knock, .knockRestricted:
state.isKnockableRoom = true
default:
state.isKnockableRoom = false
}
}
private func updatePermissions() async {
state.canAccept = await (try? roomProxy.canUserInvite(userID: roomProxy.ownUserID).get()) == true
state.canDecline = await (try? roomProxy.canUserKick(userID: roomProxy.ownUserID).get()) == true
state.canBan = await (try? roomProxy.canUserBan(userID: roomProxy.ownUserID).get()) == true
}
// For testing purposes
private init(initialViewState: KnockRequestsListScreenViewState) {
roomProxy = JoinedRoomProxyMock(.init())
super.init(initialViewState: initialViewState)
}
}
extension KnockRequestsListScreenViewModel {
static func mockWithInitialState(_ initialViewState: KnockRequestsListScreenViewState) -> KnockRequestsListScreenViewModel {
.init(initialViewState: initialViewState)
}
}