mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Move message forwarding out of the flow coordinator. (#2738)
This commit is contained in:
parent
eac2552ab5
commit
e829a3ded6
@ -303,8 +303,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case (.emojiPicker, .dismissEmojiPicker):
|
||||
return .room
|
||||
|
||||
case (.room, .presentMessageForwarding(let itemID)):
|
||||
return .messageForwarding(itemID: itemID)
|
||||
case (.room, .presentMessageForwarding(let forwardingItem)):
|
||||
return .messageForwarding(forwardingItem: forwardingItem)
|
||||
case (.messageForwarding, .dismissMessageForwarding):
|
||||
return .room
|
||||
|
||||
@ -435,8 +435,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case (.emojiPicker, .dismissEmojiPicker, .room):
|
||||
break
|
||||
|
||||
case (.room, .presentMessageForwarding(let itemID), .messageForwarding):
|
||||
presentMessageForwarding(for: itemID)
|
||||
case (.room, .presentMessageForwarding(let forwardingItem), .messageForwarding):
|
||||
presentMessageForwarding(with: forwardingItem)
|
||||
case (.messageForwarding, .dismissMessageForwarding, .room):
|
||||
break
|
||||
|
||||
@ -579,8 +579,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
stateMachine.tryEvent(.presentMapNavigator(interactionMode: .viewOnly(geoURI: geoURI, description: description)))
|
||||
case .presentRoomMemberDetails(userID: let userID):
|
||||
stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID))
|
||||
case .presentMessageForwarding(let itemID):
|
||||
stateMachine.tryEvent(.presentMessageForwarding(itemID: itemID))
|
||||
case .presentMessageForwarding(let forwardingItem):
|
||||
stateMachine.tryEvent(.presentMessageForwarding(forwardingItem: forwardingItem))
|
||||
case .presentCallScreen:
|
||||
actionsSubject.send(.presentCallScreen(roomProxy: roomProxy))
|
||||
}
|
||||
@ -1100,16 +1100,18 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentMessageForwarding(for itemID: TimelineItemIdentifier) {
|
||||
guard let roomSummaryProvider = userSession.clientProxy.alternateRoomSummaryProvider, let eventID = itemID.eventID else {
|
||||
private func presentMessageForwarding(with forwardingItem: MessageForwardingItem) {
|
||||
guard let roomSummaryProvider = userSession.clientProxy.alternateRoomSummaryProvider else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let parameters = MessageForwardingScreenCoordinatorParameters(roomSummaryProvider: roomSummaryProvider,
|
||||
let parameters = MessageForwardingScreenCoordinatorParameters(forwardingItem: forwardingItem,
|
||||
clientProxy: userSession.clientProxy,
|
||||
roomSummaryProvider: roomSummaryProvider,
|
||||
mediaProvider: userSession.mediaProvider,
|
||||
sourceRoomID: roomProxy.id)
|
||||
userIndicatorController: userIndicatorController)
|
||||
let coordinator = MessageForwardingScreenCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.actions.sink { [weak self] action in
|
||||
@ -1118,12 +1120,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
switch action {
|
||||
case .dismiss:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
case .send(let roomID):
|
||||
case .sent(let roomID):
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
|
||||
Task {
|
||||
await self.forward(eventID: eventID, toRoomID: roomID)
|
||||
}
|
||||
// Timelines are cached - the local echo will be visible when fetching the room by its ID.
|
||||
stateMachine.tryEvent(.startChildFlow(roomID: roomID, entryPoint: .room))
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@ -1135,30 +1135,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func forward(eventID: String, toRoomID roomID: String) async {
|
||||
guard let messageEventContent = await roomProxy.timeline.messageEventContent(for: eventID) else {
|
||||
MXLog.error("Failed retrieving forwarded message event content for eventID: \(eventID)")
|
||||
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
return
|
||||
}
|
||||
|
||||
guard let targetRoomProxy = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
||||
MXLog.error("Failed retrieving room to forward to with id: \(roomID)")
|
||||
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
return
|
||||
}
|
||||
|
||||
if case .failure(let error) = await targetRoomProxy.timeline.sendMessageEventContent(messageEventContent) {
|
||||
MXLog.error("Failed forwarding message with error: \(error)")
|
||||
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
return
|
||||
}
|
||||
|
||||
// We don't need to worry about passing in the room proxy as timelines are
|
||||
// cached. The local echo will be visible when fetching the room by its ID.
|
||||
stateMachine.tryEvent(.startChildFlow(roomID: roomID, entryPoint: .room))
|
||||
}
|
||||
|
||||
private func presentNotificationSettingsScreen() {
|
||||
let parameters = RoomNotificationSettingsScreenCoordinatorParameters(notificationSettingsProxy: userSession.clientProxy.notificationSettings,
|
||||
roomProxy: roomProxy,
|
||||
@ -1356,7 +1332,7 @@ private extension RoomFlowCoordinator {
|
||||
case mediaUploadPreview(fileURL: URL)
|
||||
case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
||||
case mapNavigator
|
||||
case messageForwarding(itemID: TimelineItemIdentifier)
|
||||
case messageForwarding(forwardingItem: MessageForwardingItem)
|
||||
case reportContent(itemID: TimelineItemIdentifier, senderID: String)
|
||||
case pollForm
|
||||
case pollsHistory
|
||||
@ -1419,7 +1395,7 @@ private extension RoomFlowCoordinator {
|
||||
case presentMapNavigator(interactionMode: StaticLocationInteractionMode)
|
||||
case dismissMapNavigator
|
||||
|
||||
case presentMessageForwarding(itemID: TimelineItemIdentifier)
|
||||
case presentMessageForwarding(forwardingItem: MessageForwardingItem)
|
||||
case dismissMessageForwarding
|
||||
|
||||
case presentPollForm(mode: PollFormMode)
|
||||
|
@ -40,14 +40,15 @@ struct RoomProxyMockConfiguration {
|
||||
var canUserJoinCall = true
|
||||
|
||||
func makeTimeline() -> TimelineProxyMock {
|
||||
let mock = TimelineProxyMock()
|
||||
mock.underlyingActions = Empty(completeImmediately: false).eraseToAnyPublisher()
|
||||
let timeline = TimelineProxyMock()
|
||||
timeline.underlyingActions = Empty(completeImmediately: false).eraseToAnyPublisher()
|
||||
timeline.sendMessageEventContentReturnValue = .success(())
|
||||
|
||||
let timelineProvider = RoomTimelineProviderMock()
|
||||
timelineProvider.paginationState = .init(backward: timelineStartReached ? .timelineEndReached : .idle, forward: .timelineEndReached)
|
||||
timelineProvider.underlyingMembershipChangePublisher = PassthroughSubject().eraseToAnyPublisher()
|
||||
mock.underlyingTimelineProvider = timelineProvider
|
||||
return mock
|
||||
timeline.underlyingTimelineProvider = timelineProvider
|
||||
return timeline
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,14 +18,16 @@ import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct MessageForwardingScreenCoordinatorParameters {
|
||||
let forwardingItem: MessageForwardingItem
|
||||
let clientProxy: ClientProxyProtocol
|
||||
let roomSummaryProvider: RoomSummaryProviderProtocol
|
||||
let mediaProvider: MediaProviderProtocol
|
||||
let sourceRoomID: String
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
enum MessageForwardingScreenCoordinatorAction {
|
||||
case dismiss
|
||||
case send(roomID: String)
|
||||
case sent(roomID: String)
|
||||
}
|
||||
|
||||
final class MessageForwardingScreenCoordinator: CoordinatorProtocol {
|
||||
@ -38,9 +40,11 @@ final class MessageForwardingScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
|
||||
init(parameters: MessageForwardingScreenCoordinatorParameters) {
|
||||
viewModel = MessageForwardingScreenViewModel(roomSummaryProvider: parameters.roomSummaryProvider,
|
||||
mediaProvider: parameters.mediaProvider,
|
||||
sourceRoomID: parameters.sourceRoomID)
|
||||
viewModel = MessageForwardingScreenViewModel(forwardingItem: parameters.forwardingItem,
|
||||
clientProxy: parameters.clientProxy,
|
||||
roomSummaryProvider: parameters.roomSummaryProvider,
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
mediaProvider: parameters.mediaProvider)
|
||||
}
|
||||
|
||||
func start() {
|
||||
@ -48,8 +52,8 @@ final class MessageForwardingScreenCoordinator: CoordinatorProtocol {
|
||||
switch action {
|
||||
case .dismiss:
|
||||
self?.actionsSubject.send(.dismiss)
|
||||
case .send(let roomID):
|
||||
self?.actionsSubject.send(.send(roomID: roomID))
|
||||
case .sent(let roomID):
|
||||
self?.actionsSubject.send(.sent(roomID: roomID))
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
@ -15,10 +15,11 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum MessageForwardingScreenViewModelAction {
|
||||
case dismiss
|
||||
case send(roomID: String)
|
||||
case sent(roomID: String)
|
||||
}
|
||||
|
||||
struct MessageForwardingScreenViewState: BindableState {
|
||||
@ -45,3 +46,21 @@ struct MessageForwardingRoom: Identifiable, Equatable {
|
||||
let alias: String?
|
||||
let avatarURL: URL?
|
||||
}
|
||||
|
||||
struct MessageForwardingItem: Hashable {
|
||||
/// The source item's timeline ID. Only necessary for a rough Hashable conformance.
|
||||
let id: TimelineItemIdentifier
|
||||
/// The source item's room ID.
|
||||
let roomID: String
|
||||
/// The item's content to be forwarded.
|
||||
let content: RoomMessageEventContentWithoutRelation
|
||||
|
||||
static func == (lhs: MessageForwardingItem, rhs: MessageForwardingItem) -> Bool {
|
||||
lhs.id == rhs.id && lhs.roomID == rhs.roomID
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(id)
|
||||
hasher.combine(roomID)
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,10 @@ import SwiftUI
|
||||
typealias MessageForwardingScreenViewModelType = StateStoreViewModel<MessageForwardingScreenViewState, MessageForwardingScreenViewAction>
|
||||
|
||||
class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, MessageForwardingScreenViewModelProtocol {
|
||||
private let roomSummaryProvider: RoomSummaryProviderProtocol?
|
||||
private let sourceRoomID: String
|
||||
private let forwardingItem: MessageForwardingItem
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let roomSummaryProvider: RoomSummaryProviderProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private var actionsSubject: PassthroughSubject<MessageForwardingScreenViewModelAction, Never> = .init()
|
||||
|
||||
@ -29,11 +31,15 @@ class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, Me
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(roomSummaryProvider: RoomSummaryProviderProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
sourceRoomID: String) {
|
||||
init(forwardingItem: MessageForwardingItem,
|
||||
clientProxy: ClientProxyProtocol,
|
||||
roomSummaryProvider: RoomSummaryProviderProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
mediaProvider: MediaProviderProtocol) {
|
||||
self.forwardingItem = forwardingItem
|
||||
self.clientProxy = clientProxy
|
||||
self.roomSummaryProvider = roomSummaryProvider
|
||||
self.sourceRoomID = sourceRoomID
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
super.init(initialViewState: MessageForwardingScreenViewState(), imageProvider: mediaProvider)
|
||||
|
||||
@ -49,7 +55,7 @@ class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, Me
|
||||
.removeDuplicates()
|
||||
.sink { [weak self] searchQuery in
|
||||
guard let self else { return }
|
||||
self.roomSummaryProvider?.setFilter(.search(query: searchQuery))
|
||||
self.roomSummaryProvider.setFilter(.search(query: searchQuery))
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
@ -60,13 +66,9 @@ class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, Me
|
||||
switch viewAction {
|
||||
case .cancel:
|
||||
actionsSubject.send(.dismiss)
|
||||
roomSummaryProvider?.setFilter(.all(filters: []))
|
||||
roomSummaryProvider.setFilter(.all(filters: []))
|
||||
case .send:
|
||||
guard let roomID = state.selectedRoomID else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
actionsSubject.send(.send(roomID: roomID))
|
||||
Task { await forward() }
|
||||
case .selectRoom(let roomID):
|
||||
state.selectedRoomID = roomID
|
||||
case .reachedTop:
|
||||
@ -79,11 +81,6 @@ class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, Me
|
||||
// MARK: - Private
|
||||
|
||||
private func updateRooms() {
|
||||
guard let roomSummaryProvider else {
|
||||
MXLog.error("Room summary provider unavailable")
|
||||
return
|
||||
}
|
||||
|
||||
MXLog.verbose("Updating rooms")
|
||||
|
||||
var rooms = [MessageForwardingRoom]()
|
||||
@ -93,7 +90,7 @@ class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, Me
|
||||
case .empty, .invalidated:
|
||||
continue
|
||||
case .filled(let details):
|
||||
if details.id == sourceRoomID {
|
||||
if details.id == forwardingItem.roomID {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -114,10 +111,6 @@ class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, Me
|
||||
/// we just need the respective bounds to be there to trigger a next page load or
|
||||
/// a reset to just one page
|
||||
private func updateVisibleRange(edge: UIRectEdge) {
|
||||
guard let roomSummaryProvider else {
|
||||
return
|
||||
}
|
||||
|
||||
switch edge {
|
||||
case .top:
|
||||
roomSummaryProvider.updateVisibleRange(0..<0)
|
||||
@ -128,4 +121,25 @@ class MessageForwardingScreenViewModel: MessageForwardingScreenViewModelType, Me
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private func forward() async {
|
||||
guard let roomID = state.selectedRoomID else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
guard let targetRoomProxy = await clientProxy.roomForIdentifier(roomID) else {
|
||||
MXLog.error("Failed retrieving room to forward to with id: \(roomID)")
|
||||
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
return
|
||||
}
|
||||
|
||||
if case .failure(let error) = await targetRoomProxy.timeline.sendMessageEventContent(forwardingItem.content) {
|
||||
MXLog.error("Failed forwarding message with error: \(error)")
|
||||
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
return
|
||||
}
|
||||
|
||||
// Timelines are cached - the local echo will be visible when fetching the room by its ID.
|
||||
actionsSubject.send(.sent(roomID: roomID))
|
||||
}
|
||||
}
|
||||
|
@ -104,9 +104,13 @@ private struct MessageForwardingListRow: View {
|
||||
struct MessageForwardingScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
let summaryProvider = RoomSummaryProviderMock(.init(state: .loaded(.mockRooms)))
|
||||
let viewModel = MessageForwardingScreenViewModel(roomSummaryProvider: summaryProvider,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
sourceRoomID: "")
|
||||
let viewModel = MessageForwardingScreenViewModel(forwardingItem: .init(id: .init(timelineID: ""),
|
||||
roomID: "",
|
||||
content: .init(noPointer: .init())),
|
||||
clientProxy: ClientProxyMock(),
|
||||
roomSummaryProvider: summaryProvider,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaProvider: MockMediaProvider())
|
||||
|
||||
NavigationStack {
|
||||
MessageForwardingScreen(context: viewModel.context)
|
||||
|
@ -42,7 +42,7 @@ enum RoomScreenCoordinatorAction {
|
||||
case presentLocationViewer(body: String, geoURI: GeoURI, description: String?)
|
||||
case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
||||
case presentRoomMemberDetails(userID: String)
|
||||
case presentMessageForwarding(itemID: TimelineItemIdentifier)
|
||||
case presentMessageForwarding(forwardingItem: MessageForwardingItem)
|
||||
case presentCallScreen
|
||||
}
|
||||
|
||||
@ -110,8 +110,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||
actionsSubject.send(.presentMediaUploadPreviewScreen(url))
|
||||
case .displayRoomMemberDetails(userID: let userID):
|
||||
actionsSubject.send(.presentRoomMemberDetails(userID: userID))
|
||||
case .displayMessageForwarding(let itemID):
|
||||
actionsSubject.send(.presentMessageForwarding(itemID: itemID))
|
||||
case .displayMessageForwarding(let forwardingItem):
|
||||
actionsSubject.send(.presentMessageForwarding(forwardingItem: forwardingItem))
|
||||
case .displayLocation(let body, let geoURI, let description):
|
||||
actionsSubject.send(.presentLocationViewer(body: body, geoURI: geoURI, description: description))
|
||||
case .composer(let action):
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
import OrderedCollections
|
||||
|
||||
@ -31,7 +30,7 @@ enum RoomScreenViewModelAction {
|
||||
case displayPollForm(mode: PollFormMode)
|
||||
case displayMediaUploadPreviewScreen(url: URL)
|
||||
case displayRoomMemberDetails(userID: String)
|
||||
case displayMessageForwarding(itemID: TimelineItemIdentifier)
|
||||
case displayMessageForwarding(forwardingItem: MessageForwardingItem)
|
||||
case displayLocation(body: String, geoURI: GeoURI, description: String?)
|
||||
case composer(action: RoomScreenComposerAction)
|
||||
case displayCallScreen
|
||||
|
@ -429,7 +429,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
case .displayEmojiPicker(let itemID, let selectedEmojis):
|
||||
actionsSubject.send(.displayEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis))
|
||||
case .displayMessageForwarding(let itemID):
|
||||
actionsSubject.send(.displayMessageForwarding(itemID: itemID))
|
||||
Task { await self.forwardMessage(itemID: itemID) }
|
||||
case .displayPollForm(let mode):
|
||||
actionsSubject.send(.displayPollForm(mode: mode))
|
||||
case .displayReportContent(let itemID, let senderID):
|
||||
@ -738,6 +738,13 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
state.bindings.readReceiptsSummaryInfo = .init(orderedReceipts: eventTimelineItem.properties.orderedReadReceipts, id: eventTimelineItem.id)
|
||||
}
|
||||
|
||||
// MARK: - Message forwarding
|
||||
|
||||
private func forwardMessage(itemID: TimelineItemIdentifier) async {
|
||||
guard let content = await timelineController.messageEventContent(for: itemID) else { return }
|
||||
actionsSubject.send(.displayMessageForwarding(forwardingItem: .init(id: itemID, roomID: roomProxy.id, content: content)))
|
||||
}
|
||||
|
||||
// MARK: - User Indicators
|
||||
|
||||
private func showFocusLoadingIndicator() {
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
/// An array of timeline item arrays that will be inserted in order for each back pagination request.
|
||||
@ -99,6 +100,10 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
|
||||
func redact(_ itemID: TimelineItemIdentifier) async { }
|
||||
|
||||
func messageEventContent(for itemID: TimelineItemIdentifier) -> RoomMessageEventContentWithoutRelation? {
|
||||
.init(noPointer: .init())
|
||||
}
|
||||
|
||||
func debugInfo(for itemID: TimelineItemIdentifier) -> TimelineItemDebugInfo {
|
||||
.init(model: "Mock debug description", originalJSON: nil, latestEditJSON: nil)
|
||||
}
|
||||
|
@ -227,6 +227,14 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func messageEventContent(for itemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? {
|
||||
guard let eventID = itemID.eventID else {
|
||||
MXLog.warning("The item doesn't have an event ID.")
|
||||
return nil
|
||||
}
|
||||
return await activeTimeline.messageEventContent(for: eventID)
|
||||
}
|
||||
|
||||
// Handle this parallel to the timeline items so we're not forced
|
||||
// to bundle the Rust side objects within them
|
||||
func debugInfo(for itemID: TimelineItemIdentifier) -> TimelineItemDebugInfo {
|
||||
|
@ -15,8 +15,8 @@
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import UIKit
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
enum RoomTimelineControllerCallback {
|
||||
case updatedTimelineItems(timelineItems: [RoomTimelineItemProtocol], isSwitchingTimelines: Bool)
|
||||
@ -68,6 +68,8 @@ protocol RoomTimelineControllerProtocol {
|
||||
|
||||
func redact(_ itemID: TimelineItemIdentifier) async
|
||||
|
||||
func messageEventContent(for itemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation?
|
||||
|
||||
func debugInfo(for itemID: TimelineItemIdentifier) -> TimelineItemDebugInfo
|
||||
|
||||
func retryDecryption(for sessionID: String) async
|
||||
|
@ -21,20 +21,29 @@ import XCTest
|
||||
|
||||
@MainActor
|
||||
class MessageForwardingScreenViewModelTests: XCTestCase {
|
||||
let forwardingItem = MessageForwardingItem(id: .init(timelineID: "t1", eventID: "t1"),
|
||||
roomID: "1",
|
||||
content: .init(noPointer: .init()))
|
||||
var viewModel: MessageForwardingScreenViewModelProtocol!
|
||||
var context: MessageForwardingScreenViewModelType.Context!
|
||||
var cancellables = Set<AnyCancellable>()
|
||||
|
||||
override func setUpWithError() throws {
|
||||
cancellables.removeAll()
|
||||
viewModel = MessageForwardingScreenViewModel(roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
sourceRoomID: "1")
|
||||
|
||||
let clientProxy = ClientProxyMock(.init())
|
||||
clientProxy.roomForIdentifierClosure = { RoomProxyMock(with: .init(id: $0)) }
|
||||
|
||||
viewModel = MessageForwardingScreenViewModel(forwardingItem: forwardingItem,
|
||||
clientProxy: clientProxy,
|
||||
roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaProvider: MockMediaProvider())
|
||||
context = viewModel.context
|
||||
}
|
||||
|
||||
func testInitialState() {
|
||||
XCTAssertNil(context.viewState.rooms.first(where: { $0.id == "1" }), "The source room ID shouldn't be shown")
|
||||
XCTAssertNil(context.viewState.rooms.first(where: { $0.id == forwardingItem.roomID }), "The source room ID shouldn't be shown")
|
||||
}
|
||||
|
||||
func testRoomSelection() {
|
||||
@ -61,7 +70,7 @@ class MessageForwardingScreenViewModelTests: XCTestCase {
|
||||
viewModel.actions
|
||||
.sink { action in
|
||||
switch action {
|
||||
case .send(let roomID):
|
||||
case .sent(let roomID):
|
||||
XCTAssertEqual(roomID, "2")
|
||||
expectation.fulfill()
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user