mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Configure the media preview screen based on the event and presentation. (#3604)
* Configure media previews based on the presenting screen. * Switch on TimelineKind instead of having an isPinnedEventsTimeline Bool.
This commit is contained in:
@@ -11,6 +11,7 @@ import Foundation
|
||||
typealias TimelineMediaPreviewViewModelType = StateStoreViewModel<TimelineMediaPreviewViewState, TimelineMediaPreviewViewAction>
|
||||
|
||||
class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType {
|
||||
private let timelineViewModel: TimelineViewModelProtocol
|
||||
private let mediaProvider: MediaProviderProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
@@ -19,26 +20,51 @@ class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(previewItems: [EventBasedMessageTimelineItemProtocol], mediaProvider: MediaProviderProtocol, userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
init(initialItem: EventBasedMessageTimelineItemProtocol,
|
||||
timelineViewModel: TimelineViewModelProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.timelineViewModel = timelineViewModel
|
||||
self.mediaProvider = mediaProvider
|
||||
|
||||
// We might not want to inject this, instead creating a new instance with a custom position and colour scheme 🤔
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
super.init(initialViewState: TimelineMediaPreviewViewState(previewItems: previewItems.map(TimelineMediaPreviewItem.init)), mediaProvider: mediaProvider)
|
||||
let currentItem = TimelineMediaPreviewItem(timelineItem: initialItem)
|
||||
|
||||
super.init(initialViewState: TimelineMediaPreviewViewState(previewItems: [currentItem],
|
||||
currentItem: currentItem),
|
||||
mediaProvider: mediaProvider)
|
||||
|
||||
rebuildCurrentItemActions()
|
||||
|
||||
timelineViewModel.context.$viewState.map(\.canCurrentUserRedactSelf)
|
||||
.merge(with: timelineViewModel.context.$viewState.map(\.canCurrentUserRedactOthers))
|
||||
.sink { [weak self] _ in
|
||||
self?.rebuildCurrentItemActions()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
override func process(viewAction: TimelineMediaPreviewViewAction) {
|
||||
switch viewAction {
|
||||
case .viewInTimeline:
|
||||
actionsSubject.send(.viewInTimeline)
|
||||
case .redact:
|
||||
case .menuAction(let action):
|
||||
switch action {
|
||||
case .viewInRoomTimeline:
|
||||
actionsSubject.send(.viewInTimeline)
|
||||
case .redact:
|
||||
state.bindings.isPresentingRedactConfirmation = true
|
||||
default:
|
||||
MXLog.error("Received unexpected action: \(action)")
|
||||
}
|
||||
case .redactConfirmation:
|
||||
break // Do it here??
|
||||
}
|
||||
}
|
||||
|
||||
func updateCurrentItem(_ previewItem: TimelineMediaPreviewItem) async {
|
||||
state.currentItem = previewItem
|
||||
rebuildCurrentItemActions()
|
||||
|
||||
if previewItem.fileHandle == nil, let source = previewItem.mediaSource {
|
||||
showDownloadingIndicator(itemID: previewItem.id)
|
||||
@@ -50,11 +76,26 @@ class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType {
|
||||
actionsSubject.send(.loadedMediaFile)
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed loading media: \(error)")
|
||||
#warning("Show the error!")
|
||||
showDownloadErrorIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func rebuildCurrentItemActions() {
|
||||
let timelineContext = timelineViewModel.context
|
||||
let provider = TimelineItemMenuActionProvider(timelineItem: state.currentItem.timelineItem,
|
||||
canCurrentUserRedactSelf: timelineContext.viewState.canCurrentUserRedactSelf,
|
||||
canCurrentUserRedactOthers: timelineContext.viewState.canCurrentUserRedactOthers,
|
||||
canCurrentUserPin: timelineContext.viewState.canCurrentUserPin,
|
||||
pinnedEventIDs: timelineContext.viewState.pinnedEventIDs,
|
||||
isDM: timelineContext.viewState.isEncryptedOneToOneRoom,
|
||||
isViewSourceEnabled: timelineContext.viewState.isViewSourceEnabled,
|
||||
isCreateMediaCaptionsEnabled: timelineContext.viewState.isCreateMediaCaptionsEnabled,
|
||||
timelineKind: timelineContext.viewState.timelineKind,
|
||||
emojiProvider: timelineContext.viewState.emojiProvider)
|
||||
state.currentItemActions = provider.makeActions()
|
||||
}
|
||||
|
||||
private func showDownloadingIndicator(itemID: TimelineItemIdentifier) {
|
||||
let indicatorID = makeDownloadIndicatorID(itemID: itemID)
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: indicatorID,
|
||||
@@ -69,7 +110,16 @@ class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType {
|
||||
userIndicatorController.retractIndicatorWithId(indicatorID)
|
||||
}
|
||||
|
||||
private func showDownloadErrorIndicator() {
|
||||
// FIXME: Add the correct string and indicator type??
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: downloadErrorIndicatorID,
|
||||
type: .modal,
|
||||
title: L10n.errorUnknown,
|
||||
iconName: "exclamationmark.circle.fill"))
|
||||
}
|
||||
|
||||
private var downloadErrorIndicatorID: String { "\(Self.self)-DownloadError" }
|
||||
private func makeDownloadIndicatorID(itemID: TimelineItemIdentifier) -> String {
|
||||
"\(TimelineMediaPreviewViewModel.self)-Download-\(itemID.uniqueID.id)"
|
||||
"\(Self.self)-Download-\(itemID.uniqueID.id)"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user