RoomTimeline… refactor (drop the Room). (#3728)

* Add the timeline controller factory to the timeline view model.

In preparation for building a timeline to swipe through media in QuickLook.

* Refactor RoomTimelineControllerFactory.

* Refactor RoomTimelineController.

* Refactor RoomTimelineProvider.
This commit is contained in:
Doug
2025-02-03 14:14:01 +00:00
committed by GitHub
parent 9df5a8fddb
commit d195e603c9
53 changed files with 688 additions and 631 deletions
@@ -13,7 +13,7 @@ import Combine
@MainActor
class UserSessionFlowCoordinatorTests: XCTestCase {
var clientProxy: ClientProxyMock!
var timelineControllerFactory: RoomTimelineControllerFactoryMock!
var timelineControllerFactory: TimelineControllerFactoryMock!
var userSessionFlowCoordinator: UserSessionFlowCoordinator!
var navigationRootCoordinator: NavigationRootCoordinator!
var notificationManager: NotificationManagerMock!
@@ -27,7 +27,7 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
override func setUp() async throws {
cancellables.removeAll()
clientProxy = ClientProxyMock(.init(userID: "hi@bob", roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms)))))
timelineControllerFactory = RoomTimelineControllerFactoryMock(configuration: .init())
timelineControllerFactory = TimelineControllerFactoryMock(.init())
navigationRootCoordinator = NavigationRootCoordinator()
@@ -38,7 +38,7 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
appLockService: AppLockServiceMock(),
bugReportService: BugReportServiceMock(),
elementCallService: ElementCallServiceMock(.init()),
roomTimelineControllerFactory: timelineControllerFactory,
timelineControllerFactory: timelineControllerFactory,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
appHooks: AppHooks(),
@@ -211,8 +211,8 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
XCTAssertTrue(detailNavigationStack?.rootCoordinator is RoomScreenCoordinator)
XCTAssertEqual(detailNavigationStack?.stackCoordinators.count, 0)
XCTAssertNotNil(detailCoordinator)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 1)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "1")
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 1)
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "1")
// A child event route should push a new room screen onto the stack and focus on the event.
userSessionFlowCoordinator.handleAppRoute(.childEvent(eventID: "2", roomID: "2", via: []), animated: true)
@@ -221,24 +221,24 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
XCTAssertEqual(detailNavigationStack?.stackCoordinators.count, 1)
XCTAssertTrue(detailNavigationStack?.stackCoordinators.first is RoomScreenCoordinator)
XCTAssertNotNil(detailCoordinator)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 2)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "2")
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 2)
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "2")
// A subsequent regular event route should clear the stack and set the new room as the root of the stack.
try await process(route: .event(eventID: "3", roomID: "3", via: []), expectedState: .roomList(selectedRoomID: "3"))
XCTAssertTrue(detailNavigationStack?.rootCoordinator is RoomScreenCoordinator)
XCTAssertEqual(detailNavigationStack?.stackCoordinators.count, 0)
XCTAssertNotNil(detailCoordinator)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 3)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "3")
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 3)
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "3")
// A regular event route for the same room should set a new instance of the room as the root of the stack.
try await process(route: .event(eventID: "4", roomID: "3", via: []), expectedState: .roomList(selectedRoomID: "3"))
XCTAssertTrue(detailNavigationStack?.rootCoordinator is RoomScreenCoordinator)
XCTAssertEqual(detailNavigationStack?.stackCoordinators.count, 0)
XCTAssertNotNil(detailCoordinator)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 4)
XCTAssertEqual(timelineControllerFactory.buildRoomTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "4",
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderCallsCount, 4)
XCTAssertEqual(timelineControllerFactory.buildTimelineControllerRoomProxyInitialFocussedEventIDTimelineItemFactoryMediaProviderReceivedArguments?.initialFocussedEventID, "4",
"A new timeline should be created for the same room ID, so that the screen isn't stale while loading.")
}