mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Media gallery - part 1(#3588)
* Introduce a `MediaEventsTimelineFlowCoordinator` * Update SDK API and architecture * Add a feature flag, add translations * Move the media events timeline presentation under the room flow coordinator state machine * Rename `TimelineViewState.timelineViewState` of type `TimelineState` to `timelineState` * Enabled SwiftLint's `trailing_closure` rule and fix the warnings.
This commit is contained in:
+19
-4
@@ -23,6 +23,12 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
|
||||
let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>()
|
||||
|
||||
var paginationState: PaginationState = .initial {
|
||||
didSet {
|
||||
callbacks.send(.paginationState(paginationState))
|
||||
}
|
||||
}
|
||||
|
||||
var timelineItems: [RoomTimelineItemProtocol] = RoomTimelineItemFixtures.default
|
||||
var timelineItemsTimestamp: [TimelineItemIdentifier: Date] = [:]
|
||||
|
||||
@@ -30,9 +36,18 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
|
||||
init(timelineKind: TimelineKind = .live, listenForSignals: Bool = false) {
|
||||
self.timelineKind = timelineKind
|
||||
callbacks.send(.paginationState(PaginationState(backward: .idle, forward: .timelineEndReached)))
|
||||
paginationState = PaginationState(backward: .idle, forward: .timelineEndReached)
|
||||
callbacks.send(.isLive(true))
|
||||
|
||||
switch timelineKind {
|
||||
case .media:
|
||||
timelineItems = (0..<5).reduce([]) { partialResult, _ in
|
||||
partialResult + RoomTimelineItemFixtures.mediaChunk
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
guard listenForSignals else { return }
|
||||
|
||||
do {
|
||||
@@ -56,7 +71,7 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
}
|
||||
|
||||
func paginateBackwards(requestSize: UInt16) async -> Result<Void, RoomTimelineControllerError> {
|
||||
callbacks.send(.paginationState(PaginationState(backward: .paginating, forward: .timelineEndReached)))
|
||||
paginationState = PaginationState(backward: .paginating, forward: .timelineEndReached)
|
||||
|
||||
if client == nil {
|
||||
try? await simulateBackPagination()
|
||||
@@ -170,8 +185,8 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
/// Prepends the next chunk of items to the `timelineItems` array.
|
||||
private func simulateBackPagination() async throws {
|
||||
defer {
|
||||
callbacks.send(.paginationState(PaginationState(backward: backPaginationResponses.isEmpty ? .timelineEndReached : .idle,
|
||||
forward: .timelineEndReached)))
|
||||
paginationState = PaginationState(backward: backPaginationResponses.isEmpty ? .timelineEndReached : .idle,
|
||||
forward: .timelineEndReached)
|
||||
}
|
||||
|
||||
guard !backPaginationResponses.isEmpty else { return }
|
||||
|
||||
@@ -30,6 +30,12 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
}
|
||||
|
||||
private(set) var timelineItems = [RoomTimelineItemProtocol]()
|
||||
|
||||
private(set) var paginationState: PaginationState = .initial {
|
||||
didSet {
|
||||
callbacks.send(.paginationState(paginationState))
|
||||
}
|
||||
}
|
||||
|
||||
var roomID: String {
|
||||
roomProxy.id
|
||||
@@ -64,7 +70,8 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
}
|
||||
|
||||
Task {
|
||||
callbacks.send(.paginationState(PaginationState(backward: .paginating, forward: .paginating)))
|
||||
paginationState = PaginationState(backward: .paginating, forward: .paginating)
|
||||
|
||||
switch await focusOnEvent(initialFocussedEventID, timelineSize: 100) {
|
||||
case .success:
|
||||
break
|
||||
@@ -368,7 +375,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
isSwitchingTimelines = true
|
||||
|
||||
// Inform the world that the initial items are loading from the store
|
||||
callbacks.send(.paginationState(.init(backward: .paginating, forward: .paginating)))
|
||||
paginationState = PaginationState(backward: .paginating, forward: .paginating)
|
||||
callbacks.send(.isLive(activeTimelineProvider.kind == .live))
|
||||
|
||||
updateTimelineItemsCancellable = activeTimelineProvider
|
||||
@@ -446,7 +453,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
}
|
||||
|
||||
callbacks.send(.updatedTimelineItems(timelineItems: newTimelineItems, isSwitchingTimelines: isNewTimeline))
|
||||
callbacks.send(.paginationState(paginationState))
|
||||
self.paginationState = paginationState
|
||||
}
|
||||
|
||||
private func buildTimelineItem(for itemProxy: TimelineItemProxy) -> RoomTimelineItemProtocol? {
|
||||
|
||||
+22
-3
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
struct RoomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol {
|
||||
func buildRoomTimelineController(roomProxy: JoinedRoomProxyProtocol,
|
||||
@@ -20,12 +21,13 @@ struct RoomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol {
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
}
|
||||
|
||||
func buildRoomPinnedTimelineController(roomProxy: JoinedRoomProxyProtocol,
|
||||
timelineItemFactory: RoomTimelineItemFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol) async -> RoomTimelineControllerProtocol? {
|
||||
func buildPinnedEventsRoomTimelineController(roomProxy: JoinedRoomProxyProtocol,
|
||||
timelineItemFactory: RoomTimelineItemFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol) async -> RoomTimelineControllerProtocol? {
|
||||
guard let pinnedEventsTimeline = await roomProxy.pinnedEventsTimeline else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return RoomTimelineController(roomProxy: roomProxy,
|
||||
timelineProxy: pinnedEventsTimeline,
|
||||
initialFocussedEventID: nil,
|
||||
@@ -33,4 +35,21 @@ struct RoomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol {
|
||||
mediaProvider: mediaProvider,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
}
|
||||
|
||||
func buildMessageFilteredRoomTimelineController(allowedMessageTypes: [RoomMessageEventMessageType],
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
timelineItemFactory: RoomTimelineItemFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol) async -> Result<RoomTimelineControllerProtocol, RoomTimelineFactoryControllerError> {
|
||||
switch await roomProxy.messageFilteredTimeline(allowedMessageTypes: allowedMessageTypes) {
|
||||
case .success(let timelineProxy):
|
||||
return .success(RoomTimelineController(roomProxy: roomProxy,
|
||||
timelineProxy: timelineProxy,
|
||||
initialFocussedEventID: nil,
|
||||
timelineItemFactory: timelineItemFactory,
|
||||
mediaProvider: mediaProvider,
|
||||
appSettings: ServiceLocator.shared.settings))
|
||||
case .failure(let error):
|
||||
return .failure(.roomProxyError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-3
@@ -6,6 +6,11 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum RoomTimelineFactoryControllerError: Error {
|
||||
case roomProxyError(RoomProxyError)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
protocol RoomTimelineControllerFactoryProtocol {
|
||||
@@ -13,9 +18,15 @@ protocol RoomTimelineControllerFactoryProtocol {
|
||||
initialFocussedEventID: String?,
|
||||
timelineItemFactory: RoomTimelineItemFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol) -> RoomTimelineControllerProtocol
|
||||
func buildRoomPinnedTimelineController(roomProxy: JoinedRoomProxyProtocol,
|
||||
timelineItemFactory: RoomTimelineItemFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol) async -> RoomTimelineControllerProtocol?
|
||||
|
||||
func buildPinnedEventsRoomTimelineController(roomProxy: JoinedRoomProxyProtocol,
|
||||
timelineItemFactory: RoomTimelineItemFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol) async -> RoomTimelineControllerProtocol?
|
||||
|
||||
func buildMessageFilteredRoomTimelineController(allowedMessageTypes: [RoomMessageEventMessageType],
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
timelineItemFactory: RoomTimelineItemFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol) async -> Result<RoomTimelineControllerProtocol, RoomTimelineFactoryControllerError>
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
|
||||
+5
@@ -31,7 +31,12 @@ protocol RoomTimelineControllerProtocol {
|
||||
var roomID: String { get }
|
||||
var timelineKind: TimelineKind { get }
|
||||
|
||||
/// The currently known items, use only for setting up the intial state.
|
||||
var timelineItems: [RoomTimelineItemProtocol] { get }
|
||||
|
||||
/// The current pagination state, use only for setting up the intial state
|
||||
var paginationState: PaginationState { get }
|
||||
|
||||
var callbacks: PassthroughSubject<RoomTimelineControllerCallback, Never> { get }
|
||||
|
||||
func processItemAppearance(_ itemID: TimelineItemIdentifier) async
|
||||
|
||||
Reference in New Issue
Block a user