Fixes #1455 - Use the stable timeline id to match timeline items in between local echo and remote echo states

This commit is contained in:
Stefan Ceriu 2023-08-08 09:41:10 +03:00 committed by Stefan Ceriu
parent 74e0f03356
commit 10259e9345
3 changed files with 14 additions and 8 deletions

View File

@ -67,3 +67,9 @@ extension Array {
return newItems return newItems
} }
} }
extension Array where Element == RoomTimelineItemProtocol {
func firstUsingStableID(_ id: TimelineItemIdentifier) -> Element? {
first { $0.id.timelineID == id.timelineID }
}
}

View File

@ -469,7 +469,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
// MARK: TimelineItemActionMenu // MARK: TimelineItemActionMenu
private func showTimelineItemActionMenu(for itemID: TimelineItemIdentifier) { private func showTimelineItemActionMenu(for itemID: TimelineItemIdentifier) {
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemID }), guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID),
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else { let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
// Don't show a menu for non-event based items. // Don't show a menu for non-event based items.
return return
@ -479,7 +479,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
} }
private func timelineItemMenuActionsForItemId(_ itemID: TimelineItemIdentifier) -> TimelineItemMenuActions? { private func timelineItemMenuActionsForItemId(_ itemID: TimelineItemIdentifier) -> TimelineItemMenuActions? {
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemID }), guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID),
let item = timelineItem as? EventBasedTimelineItemProtocol else { let item = timelineItem as? EventBasedTimelineItemProtocol else {
// Don't show a context menu for non-event based items. // Don't show a context menu for non-event based items.
return nil return nil
@ -541,7 +541,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
// swiftlint:disable:next cyclomatic_complexity function_body_length // swiftlint:disable:next cyclomatic_complexity function_body_length
private func processTimelineItemMenuAction(_ action: TimelineItemMenuAction, itemID: TimelineItemIdentifier) { private func processTimelineItemMenuAction(_ action: TimelineItemMenuAction, itemID: TimelineItemIdentifier) {
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemID }), guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID),
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else { let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
return return
} }
@ -766,7 +766,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
// MARK: - Reactions // MARK: - Reactions
private func showEmojiPicker(for itemID: TimelineItemIdentifier) { private func showEmojiPicker(for itemID: TimelineItemIdentifier) {
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemID }), guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID),
timelineItem.isReactable, timelineItem.isReactable,
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else { let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
return return
@ -776,7 +776,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
} }
private func showReactionSummary(for itemID: TimelineItemIdentifier, selectedKey: String) { private func showReactionSummary(for itemID: TimelineItemIdentifier, selectedKey: String) {
guard let timelineItem = timelineController.timelineItems.first(where: { $0.id == itemID }), guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID),
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else { let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
return return
} }

View File

@ -96,7 +96,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
} }
func processItemAppearance(_ itemID: TimelineItemIdentifier) async { func processItemAppearance(_ itemID: TimelineItemIdentifier) async {
guard let timelineItem = timelineItems.first(where: { $0.id == itemID }) else { guard let timelineItem = timelineItems.firstUsingStableID(itemID) else {
return return
} }
@ -108,7 +108,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
func processItemDisappearance(_ itemID: TimelineItemIdentifier) { } func processItemDisappearance(_ itemID: TimelineItemIdentifier) { }
func processItemTap(_ itemID: TimelineItemIdentifier) async -> RoomTimelineControllerAction { func processItemTap(_ itemID: TimelineItemIdentifier) async -> RoomTimelineControllerAction {
guard let timelineItem = timelineItems.first(where: { $0.id == itemID }) else { guard let timelineItem = timelineItems.firstUsingStableID(itemID) else {
return .none return .none
} }
@ -158,7 +158,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
func editMessage(_ newMessage: String, original itemID: TimelineItemIdentifier) async { func editMessage(_ newMessage: String, original itemID: TimelineItemIdentifier) async {
MXLog.info("Edit message in \(roomID)") MXLog.info("Edit message in \(roomID)")
if let timelineItem = timelineItems.first(where: { $0.id == itemID }), if let timelineItem = timelineItems.firstUsingStableID(itemID),
let item = timelineItem as? EventBasedTimelineItemProtocol, let item = timelineItem as? EventBasedTimelineItemProtocol,
item.hasFailedToSend { item.hasFailedToSend {
MXLog.info("Editing a failed echo, will cancel and resend it as a new message") MXLog.info("Editing a failed echo, will cancel and resend it as a new message")