Add the empty state to SpaceScreen. (#4985)

* Rename PaginationState.timelineEndReached to PaginationState.endReached.

* Rename PaginationState to TimelinePaginationState.

Also renames PaginationStatus to PaginationState so that a TimelinePaginationState consists of the forward and backward pagination states.

* Add the empty state to SpaceScreen.

Only has 1 of the 2 buttons for now.
This commit is contained in:
Doug
2026-01-22 12:37:34 +00:00
committed by GitHub
parent d1f1a598d5
commit ed892fee94
30 changed files with 164 additions and 94 deletions

View File

@@ -73,7 +73,7 @@ class RoomScreenViewModelTests: XCTestCase {
// setup the loaded pinned events injection in the timeline
let pinnedTimelineMock = TimelineProxyMock()
let pinnedTimelineItemProviderMock = TimelineItemProviderMock()
let providerUpdateSubject = PassthroughSubject<([TimelineItemProxy], PaginationState), Never>()
let providerUpdateSubject = PassthroughSubject<([TimelineItemProxy], TimelinePaginationState), Never>()
pinnedTimelineItemProviderMock.underlyingUpdatePublisher = providerUpdateSubject.eraseToAnyPublisher()
pinnedTimelineMock.timelineItemProvider = pinnedTimelineItemProviderMock
pinnedTimelineItemProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init("1"))),
@@ -116,7 +116,7 @@ class RoomScreenViewModelTests: XCTestCase {
let pinnedTimelineMock = TimelineProxyMock()
let pinnedTimelineItemProviderMock = TimelineItemProviderMock()
pinnedTimelineMock.timelineItemProvider = pinnedTimelineItemProviderMock
pinnedTimelineItemProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], PaginationState), Never>().eraseToAnyPublisher()
pinnedTimelineItemProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], TimelinePaginationState), Never>().eraseToAnyPublisher()
pinnedTimelineItemProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init("1"))),
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init("2"))),
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: .init("3")))]
@@ -175,7 +175,7 @@ class RoomScreenViewModelTests: XCTestCase {
let pinnedTimelineMock = TimelineProxyMock()
let pinnedTimelineItemProviderMock = TimelineItemProviderMock()
pinnedTimelineMock.timelineItemProvider = pinnedTimelineItemProviderMock
pinnedTimelineItemProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], PaginationState), Never>().eraseToAnyPublisher()
pinnedTimelineItemProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], TimelinePaginationState), Never>().eraseToAnyPublisher()
pinnedTimelineItemProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init("1"))),
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init("2"))),
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: .init("3")))]

View File

@@ -31,7 +31,7 @@ class SpaceScreenViewModelTests: XCTestCase {
func testInitialState() {
setupViewModel()
XCTAssertFalse(context.viewState.isPaginating)
XCTAssertEqual(context.viewState.paginationState, .idle)
XCTAssertTrue(context.viewState.rooms.isEmpty)
XCTAssertFalse(spaceRoomListProxy.paginateCalled)
}
@@ -41,7 +41,7 @@ class SpaceScreenViewModelTests: XCTestCase {
let response = mockSpaceRooms.prefix(3)
setupViewModel(paginationResponses: [Array(response)])
XCTAssertFalse(context.viewState.isPaginating)
XCTAssertEqual(context.viewState.paginationState, .idle)
XCTAssertTrue(context.viewState.rooms.isEmpty)
XCTAssertFalse(spaceRoomListProxy.paginateCalled)
XCTAssertFalse(response.isEmpty, "There should be some test rooms.")
@@ -52,7 +52,7 @@ class SpaceScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
// Then the screen should show a paginating indicator.
XCTAssertTrue(context.viewState.isPaginating)
XCTAssertEqual(context.viewState.paginationState, .paginating)
XCTAssertEqual(spaceRoomListProxy.paginateCallsCount, 1)
// When waiting for the pagination to finish.
@@ -60,7 +60,7 @@ class SpaceScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
// Then no more pagination requests should be made the the space rooms should be populated.
XCTAssertFalse(context.viewState.isPaginating)
XCTAssertEqual(context.viewState.paginationState, .endReached)
XCTAssertEqual(spaceRoomListProxy.paginateCallsCount, 1)
XCTAssertEqual(context.viewState.rooms.map(\.id), response.map(\.id))
}
@@ -71,14 +71,14 @@ class SpaceScreenViewModelTests: XCTestCase {
let response2 = mockSpaceRooms.suffix(mockSpaceRooms.count - 3)
setupViewModel(paginationResponses: [Array(response1), Array(response2)])
XCTAssertFalse(context.viewState.isPaginating)
XCTAssertEqual(context.viewState.paginationState, .idle)
XCTAssertTrue(context.viewState.rooms.isEmpty)
XCTAssertFalse(spaceRoomListProxy.paginateCalled)
XCTAssertFalse(response1.isEmpty, "There should be some test rooms.")
XCTAssertFalse(response2.isEmpty, "There should be more test rooms.")
// When the pagination is triggered.
let deferredIsPaginating = deferFulfillment(context.observe(\.viewState.isPaginating), transitionValues: [true, false, true, false])
let deferredIsPaginating = deferFulfillment(context.observe(\.viewState.paginationState), transitionValues: [.paginating, .idle, .paginating, .endReached])
let deferredState = deferFulfillment(spaceRoomListProxy.paginationStatePublisher, keyPath: \.self, transitionValues: [.loading,
.idle(endReached: false),
.loading,
@@ -89,7 +89,7 @@ class SpaceScreenViewModelTests: XCTestCase {
try await deferredIsPaginating.fulfill()
try await deferredState.fulfill()
XCTAssertFalse(context.viewState.isPaginating)
XCTAssertEqual(context.viewState.paginationState, .endReached)
XCTAssertEqual(spaceRoomListProxy.paginateCallsCount, 2)
XCTAssertEqual(context.viewState.rooms.map(\.id), mockSpaceRooms.map(\.id))
}

View File

@@ -91,7 +91,7 @@ class TimelineMediaPreviewViewModelTests: XCTestCase {
XCTAssertEqual(timelineController.paginateBackwardsCallCount, 0)
// When swiping to a "loading more" item and there are more media items to load.
timelineController.paginationState = .init(backward: .idle, forward: .timelineEndReached)
timelineController.paginationState = .init(backward: .idle, forward: .endReached)
timelineController.backPaginationResponses.append(RoomTimelineItemFixtures.mediaChunk)
let failure = deferFailure(viewModel.state.previewControllerDriver, timeout: 1) { $0.isItemLoaded }
context.send(viewAction: .updateCurrentItem(.loading(.paginatingBackwards)))