mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Fixes #974 - Replace the timeline item contex menu with a bottom sheet
(+10 squashed commits) [ba1d3160] Update timeline item action menu reaction UI [410315ac] Move away from item bound action meus plus various tweaks following code review [c25cd998] Add emoji reactions to the new timeline item action menu [57001f49] Prevent timeline view layouts from dismissing the action menu [d1e70538] Various UI tweaks [652f4143] Switch to a long press gesture, move the header outside of the scroll view [569a485c] Workaround timeline item action menu presentation state not being stored [80c29567] Add currently selected item information in the TimelineItemMenu [ff7790ec] Fixes #974 - Replace the timeline item contex menu with a bottom sheet [ba1d3160] Rename TimelineItemContextMenu to TimelineIteMenu so that git correctly interprets it
This commit is contained in:
committed by
Stefan Ceriu
parent
8ff5c6144c
commit
5a4f73e2b8
@@ -67,12 +67,12 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
state.contextMenuActionProvider = { [weak self] itemId -> TimelineItemContextMenuActions? in
|
||||
state.timelineItemMenuActionProvider = { [weak self] itemId -> TimelineItemMenuActions? in
|
||||
guard let self else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.contextMenuActionsForItemId(itemId)
|
||||
return self.timelineItemMenuActionsForItemId(itemId)
|
||||
}
|
||||
|
||||
roomProxy
|
||||
@@ -109,8 +109,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
Task { await timelineController.processItemDisappearance(id) }
|
||||
case .itemTapped(let id):
|
||||
Task { await itemTapped(with: id) }
|
||||
case .itemDoubleTapped(let id):
|
||||
itemDoubleTapped(with: id)
|
||||
case .linkClicked(let url):
|
||||
MXLog.warning("Link clicked: \(url)")
|
||||
case .sendMessage:
|
||||
@@ -124,8 +122,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
state.bindings.composerText = ""
|
||||
case .markRoomAsRead:
|
||||
Task { await markRoomAsRead() }
|
||||
case .contextMenuAction(let itemID, let action):
|
||||
processContentMenuAction(action, itemID: itemID)
|
||||
case .timelineItemMenu(let itemID):
|
||||
showTimelineItemActionMenu(for: itemID)
|
||||
case .timelineItemMenuAction(let itemID, let action):
|
||||
processTimelineItemMenuAction(action, itemID: itemID)
|
||||
case .displayCameraPicker:
|
||||
callback?(.displayCameraPicker)
|
||||
case .displayMediaPicker:
|
||||
@@ -136,6 +136,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
handlePasteOrDrop(provider)
|
||||
case .tappedOnUser(userID: let userID):
|
||||
Task { await handleTappedUser(userID: userID) }
|
||||
|
||||
case .displayEmojiPicker(let itemID):
|
||||
guard let item = state.items.first(where: { $0.id == itemID }), item.isReactable else { return }
|
||||
callback?(.displayEmojiPicker(itemID: itemID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,12 +170,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
}
|
||||
state.showLoading = false
|
||||
}
|
||||
|
||||
private func itemDoubleTapped(with itemId: String) {
|
||||
guard let item = state.items.first(where: { $0.id == itemId }), item.isReactable else { return }
|
||||
callback?(.displayEmojiPicker(itemID: itemId))
|
||||
}
|
||||
|
||||
|
||||
private func buildTimelineViews() {
|
||||
var timelineViews = [RoomTimelineViewProvider]()
|
||||
|
||||
@@ -259,9 +258,19 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: ContextMenus
|
||||
// MARK: TimelineItemActionMenu
|
||||
|
||||
private func contextMenuActionsForItemId(_ itemId: String) -> TimelineItemContextMenuActions? {
|
||||
private func showTimelineItemActionMenu(for itemID: String) {
|
||||
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemID }),
|
||||
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
|
||||
// Don't show a menu for non-event based items.
|
||||
return
|
||||
}
|
||||
|
||||
state.bindings.actionMenuInfo = .init(item: eventTimelineItem)
|
||||
}
|
||||
|
||||
private func timelineItemMenuActionsForItemId(_ itemId: String) -> TimelineItemMenuActions? {
|
||||
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemId }),
|
||||
let item = timelineItem as? EventBasedTimelineItemProtocol else {
|
||||
// Don't show a context menu for non-event based items.
|
||||
@@ -273,8 +282,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
return nil
|
||||
}
|
||||
|
||||
var actions: [TimelineItemContextMenuAction] = [
|
||||
.react, .reply, .copyPermalink
|
||||
var actions: [TimelineItemMenuAction] = [
|
||||
.reply, .copyPermalink
|
||||
]
|
||||
|
||||
if timelineItem is EventBasedMessageTimelineItemProtocol {
|
||||
@@ -291,7 +300,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
actions.append(.report)
|
||||
}
|
||||
|
||||
var debugActions: [TimelineItemContextMenuAction] = ServiceLocator.shared.settings.canShowDeveloperOptions ? [.viewSource] : []
|
||||
var debugActions: [TimelineItemMenuAction] = ServiceLocator.shared.settings.canShowDeveloperOptions ? [.viewSource] : []
|
||||
|
||||
if let item = timelineItem as? EncryptedRoomTimelineItem,
|
||||
case let .megolmV1AesSha2(sessionID) = item.encryptionType {
|
||||
@@ -302,15 +311,13 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
}
|
||||
|
||||
// swiftlint:disable:next cyclomatic_complexity function_body_length
|
||||
private func processContentMenuAction(_ action: TimelineItemContextMenuAction, itemID: String) {
|
||||
private func processTimelineItemMenuAction(_ action: TimelineItemMenuAction, itemID: String) {
|
||||
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemID }),
|
||||
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
|
||||
return
|
||||
}
|
||||
|
||||
switch action {
|
||||
case .react:
|
||||
callback?(.displayEmojiPicker(itemID: eventTimelineItem.id))
|
||||
case .copy:
|
||||
guard let messageTimelineItem = timelineItem as? EventBasedMessageTimelineItemProtocol else {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user