Add mechanism for opening up a threaded timeline

This commit is contained in:
Stefan Ceriu
2025-04-11 15:41:06 +03:00
committed by Stefan Ceriu
parent 2f938d3cbf
commit 10fb2b5dda
22 changed files with 505 additions and 13 deletions
@@ -302,6 +302,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case (_, .dismissFlow):
return .complete
case (_, .presentThread(let itemID)):
return .thread(itemID: itemID)
case (_, .dismissThread):
return .room
case (.initial, .presentRoomDetails):
return .roomDetails(isRoot: true)
case (.room, .presentRoomDetails):
@@ -462,6 +467,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
}
case (_, .dismissFlow, .complete):
dismissFlow(animated: animated)
case (.room, .presentThread(let itemID), .thread):
Task { await self.presentThread(itemID: itemID) }
case (.thread, .dismissThread, .room):
break
case (.initial, .presentRoomDetails, .roomDetails(let isRoot)),
(.room, .presentRoomDetails, .roomDetails(let isRoot)),
@@ -618,7 +628,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
presentDeclineAndBlockScreen(userID: userID)
case (.declineAndBlockScreen, .dismissDeclineAndBlockScreen, .joinRoomScreen):
break
// Child flow
case (_, .startChildFlow(let roomID, let via, let entryPoint), .presentingChild):
Task { await self.startChildFlow(for: roomID, via: via, entryPoint: entryPoint) }
@@ -782,6 +792,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.tryEvent(.presentResolveSendFailure(failure: failure, sendHandle: sendHandle))
case .presentKnockRequestsList:
stateMachine.tryEvent(.presentKnockRequestsListScreen)
case .presentThread(let itemID):
stateMachine.tryEvent(.presentThread(itemID: itemID))
}
}
.store(in: &cancellables)
@@ -789,6 +801,41 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
return coordinator
}
private func presentThread(itemID: TimelineItemIdentifier) async {
showLoadingIndicator()
defer { hideLoadingIndicator() }
let timelineItemFactory = RoomTimelineItemFactory(userID: userSession.clientProxy.userID,
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userSession.clientProxy.userID))
guard let eventID = itemID.eventID else {
fatalError("Invalid thread event ID")
}
guard case let .success(timelineController) = await timelineControllerFactory.buildThreadTimelineController(eventID: eventID,
roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
MXLog.error("Failed presenting media timeline")
return
}
let coordinator = ThreadTimelineScreenCoordinator(parameters: .init(roomProxy: roomProxy,
timelineController: timelineController,
mediaProvider: userSession.mediaProvider,
mediaPlayerProvider: MediaPlayerProvider(),
voiceMessageMediaManager: userSession.voiceMessageMediaManager,
appMediator: appMediator,
emojiProvider: emojiProvider,
timelineControllerFactory: timelineControllerFactory,
clientProxy: userSession.clientProxy))
navigationStackCoordinator.push(coordinator) { [weak self] in
self?.stateMachine.tryEvent(.dismissThread)
}
}
private func presentJoinRoomScreen(via: [String], animated: Bool) {
let coordinator = JoinRoomScreenCoordinator(parameters: .init(roomID: roomID,
via: via,
@@ -1747,6 +1794,7 @@ private extension RoomFlowCoordinator {
case initial
case joinRoomScreen
case room
case thread(itemID: TimelineItemIdentifier)
case roomDetails(isRoot: Bool)
case roomDetailsEditScreen
case notificationSettings
@@ -1790,6 +1838,9 @@ private extension RoomFlowCoordinator {
case presentRoom(presentationAction: PresentationAction?)
case dismissFlow
case presentThread(itemID: TimelineItemIdentifier)
case dismissThread
case presentReportContent(itemID: TimelineItemIdentifier, senderID: String)
case dismissReportContent