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:
@@ -78,7 +78,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
super.init(initialViewState: TimelineViewState(isPinnedEventsTimeline: timelineController.timelineKind == .pinned,
|
||||
roomID: roomProxy.id,
|
||||
isEncryptedOneToOneRoom: roomProxy.isEncryptedOneToOneRoom,
|
||||
timelineViewState: TimelineState(focussedEvent: focussedEventID.map { .init(eventID: $0, appearance: .immediate) }),
|
||||
timelineState: TimelineState(focussedEvent: focussedEventID.map { .init(eventID: $0, appearance: .immediate) }),
|
||||
ownUserID: roomProxy.ownUserID,
|
||||
isViewSourceEnabled: appSettings.viewSourceEnabled,
|
||||
isCreateMediaCaptionsEnabled: appSettings.createMediaCaptionsEnabled,
|
||||
@@ -107,6 +107,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
return self.timelineInteractionHandler.audioPlayerState(for: itemID)
|
||||
}
|
||||
|
||||
state.timelineState.paginationState = timelineController.paginationState
|
||||
buildTimelineViews(timelineItems: timelineController.timelineItems)
|
||||
|
||||
updateMembers(roomProxy.membersPublisher.value)
|
||||
@@ -174,7 +175,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
case .scrolledToFocussedItem:
|
||||
didScrollToFocussedItem()
|
||||
case .hasSwitchedTimeline:
|
||||
Task { state.timelineViewState.isSwitchingTimelines = false }
|
||||
Task { state.timelineState.isSwitchingTimelines = false }
|
||||
case let .hasScrolled(direction):
|
||||
actionsSubject.send(.hasScrolled(direction: direction))
|
||||
case .setOpenURLAction(let action):
|
||||
@@ -215,8 +216,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
|
||||
func focusOnEvent(eventID: String) async {
|
||||
if state.timelineViewState.hasLoadedItem(with: eventID) {
|
||||
state.timelineViewState.focussedEvent = .init(eventID: eventID, appearance: .animated)
|
||||
if state.timelineState.hasLoadedItem(with: eventID) {
|
||||
state.timelineState.focussedEvent = .init(eventID: eventID, appearance: .animated)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -225,7 +226,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
|
||||
switch await timelineController.focusOnEvent(eventID, timelineSize: Constants.detachedTimelineSize) {
|
||||
case .success:
|
||||
state.timelineViewState.focussedEvent = .init(eventID: eventID, appearance: .immediate)
|
||||
state.timelineState.focussedEvent = .init(eventID: eventID, appearance: .immediate)
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed to focus on event \(eventID)")
|
||||
|
||||
@@ -244,9 +245,9 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
|
||||
private func didScrollToFocussedItem() {
|
||||
if var focussedEvent = state.timelineViewState.focussedEvent {
|
||||
if var focussedEvent = state.timelineState.focussedEvent {
|
||||
focussedEvent.appearance = .hasAppeared
|
||||
state.timelineViewState.focussedEvent = focussedEvent
|
||||
state.timelineState.focussedEvent = focussedEvent
|
||||
hideFocusLoadingIndicator()
|
||||
}
|
||||
}
|
||||
@@ -362,16 +363,16 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
case .updatedTimelineItems(let updatedItems, let isSwitchingTimelines):
|
||||
buildTimelineViews(timelineItems: updatedItems, isSwitchingTimelines: isSwitchingTimelines)
|
||||
case .paginationState(let paginationState):
|
||||
if state.timelineViewState.paginationState != paginationState {
|
||||
state.timelineViewState.paginationState = paginationState
|
||||
if state.timelineState.paginationState != paginationState {
|
||||
state.timelineState.paginationState = paginationState
|
||||
}
|
||||
case .isLive(let isLive):
|
||||
if state.timelineViewState.isLive != isLive {
|
||||
state.timelineViewState.isLive = isLive
|
||||
if state.timelineState.isLive != isLive {
|
||||
state.timelineState.isLive = isLive
|
||||
|
||||
// Remove the event highlight *only* when transitioning from non-live to live.
|
||||
if isLive, state.timelineViewState.focussedEvent != nil {
|
||||
state.timelineViewState.focussedEvent = nil
|
||||
if isLive, state.timelineState.focussedEvent != nil {
|
||||
state.timelineState.focussedEvent = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -516,7 +517,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
break
|
||||
}
|
||||
|
||||
if state.timelineViewState.paginationState.forward == .timelineEndReached {
|
||||
if state.timelineState.paginationState.forward == .timelineEndReached {
|
||||
focusLive()
|
||||
}
|
||||
|
||||
@@ -525,8 +526,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
|
||||
private func scrollToBottom() {
|
||||
if state.timelineViewState.isLive {
|
||||
state.timelineViewState.scrollToBottomPublisher.send(())
|
||||
if state.timelineState.isLive {
|
||||
state.timelineState.scrollToBottomPublisher.send(())
|
||||
} else {
|
||||
focusLive()
|
||||
}
|
||||
@@ -703,14 +704,14 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
|
||||
if isSwitchingTimelines {
|
||||
state.timelineViewState.isSwitchingTimelines = true
|
||||
state.timelineState.isSwitchingTimelines = true
|
||||
}
|
||||
|
||||
state.timelineViewState.itemsDictionary = timelineItemsDictionary
|
||||
state.timelineState.itemsDictionary = timelineItemsDictionary
|
||||
}
|
||||
|
||||
private func updateViewState(item: RoomTimelineItemProtocol, groupStyle: TimelineGroupStyle) -> RoomTimelineItemViewState {
|
||||
if let timelineItemViewState = state.timelineViewState.itemsDictionary[item.id.uniqueID] {
|
||||
if let timelineItemViewState = state.timelineState.itemsDictionary[item.id.uniqueID] {
|
||||
timelineItemViewState.groupStyle = groupStyle
|
||||
timelineItemViewState.type = .init(item: item)
|
||||
return timelineItemViewState
|
||||
@@ -744,7 +745,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
userIndicatorController.alertInfo = .init(id: .init(),
|
||||
title: L10n.screenRoomInviteAgainAlertTitle,
|
||||
message: L10n.screenRoomInviteAgainAlertMessage,
|
||||
primaryButton: .init(title: L10n.actionInvite, action: { [weak self] in self?.inviteOtherDMUserBack() }),
|
||||
primaryButton: .init(title: L10n.actionInvite) { [weak self] in self?.inviteOtherDMUserBack() },
|
||||
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
|
||||
}
|
||||
|
||||
@@ -830,14 +831,14 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
state.bindings.alertInfo = .init(id: type,
|
||||
title: L10n.dialogPermissionMicrophoneTitleIos(InfoPlistReader.main.bundleDisplayName),
|
||||
message: L10n.dialogPermissionMicrophoneDescriptionIos,
|
||||
primaryButton: .init(title: L10n.commonSettings, action: { [weak self] in self?.appMediator.openAppSettings() }),
|
||||
primaryButton: .init(title: L10n.commonSettings) { [weak self] in self?.appMediator.openAppSettings() },
|
||||
secondaryButton: .init(title: L10n.actionNotNow, role: .cancel, action: nil))
|
||||
case .pollEndConfirmation(let pollStartID):
|
||||
state.bindings.alertInfo = .init(id: type,
|
||||
title: L10n.actionEndPoll,
|
||||
message: L10n.commonPollEndConfirmation,
|
||||
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
|
||||
secondaryButton: .init(title: L10n.actionOk, action: { self.timelineInteractionHandler.endPoll(pollStartID: pollStartID) }))
|
||||
secondaryButton: .init(title: L10n.actionOk) { self.timelineInteractionHandler.endPoll(pollStartID: pollStartID) })
|
||||
case .sendingFailed:
|
||||
state.bindings.alertInfo = .init(id: type,
|
||||
title: L10n.commonSendingFailed,
|
||||
|
||||
Reference in New Issue
Block a user