Filter out some actions for failed local echoes (#1184)

* done

* pr suggestion
This commit is contained in:
Mauro
2023-06-27 18:41:18 +02:00
committed by GitHub
parent 13f5ec8a73
commit f54eb78503
9 changed files with 80 additions and 23 deletions
@@ -355,7 +355,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
.reply .reply
] ]
if timelineItem is EventBasedMessageTimelineItemProtocol { if item.isMessage {
actions.append(.forward(itemID: itemId)) actions.append(.forward(itemID: itemId))
} }
@@ -363,7 +363,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
actions.append(.edit) actions.append(.edit)
} }
if timelineItem is EventBasedMessageTimelineItemProtocol { if item.isMessage {
actions.append(.copy) actions.append(.copy)
} }
@@ -382,6 +382,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
debugActions.append(.retryDecryption(sessionID: sessionID)) debugActions.append(.retryDecryption(sessionID: sessionID))
} }
if item.hasFailedToSend {
actions = actions.filter(\.canAppearInFailedEcho)
}
if item.isRedacted {
actions = actions.filter(\.canAppearInRedacted)
}
return .init(actions: actions, debugActions: debugActions) return .init(actions: actions, debugActions: debugActions)
} }
@@ -416,7 +424,12 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
} }
case .redact: case .redact:
Task { Task {
await timelineController.redact(itemID) if eventTimelineItem.hasFailedToSend,
let transactionID = eventTimelineItem.properties.transactionID {
await timelineController.cancelSend(transactionID)
} else {
await timelineController.redact(itemID)
}
} }
case .reply: case .reply:
state.bindings.composerFocused = true state.bindings.composerFocused = true
@@ -151,7 +151,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
@ViewBuilder @ViewBuilder
var interactiveLocalizedSendInfo: some View { var interactiveLocalizedSendInfo: some View {
if timelineItem.properties.deliveryStatus == .sendingFailed { if timelineItem.hasFailedToSend {
backgroundedLocalizedSendInfo backgroundedLocalizedSendInfo
.onTapGesture { .onTapGesture {
context.sendFailedConfirmationDialogInfo = .init(transactionID: timelineItem.properties.transactionID) context.sendFailedConfirmationDialogInfo = .init(transactionID: timelineItem.properties.transactionID)
@@ -186,12 +186,12 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
Text(timelineItem.timestamp) Text(timelineItem.timestamp)
} }
if timelineItem.properties.deliveryStatus == .sendingFailed { if timelineItem.hasFailedToSend {
Image(systemName: "exclamationmark.circle.fill") Image(systemName: "exclamationmark.circle.fill")
} }
} }
.font(.compound.bodyXS) .font(.compound.bodyXS)
.foregroundColor(timelineItem.properties.deliveryStatus == .sendingFailed ? .compound.textCriticalPrimary : .compound.textSecondary) .foregroundColor(timelineItem.hasFailedToSend ? .compound.textCriticalPrimary : .compound.textSecondary)
.padding(.bottom, shouldFillBubble ? 0 : -4) .padding(.bottom, shouldFillBubble ? 0 : -4)
} }
@@ -32,7 +32,7 @@ extension TextBasedRoomTimelineViewProtocol {
} }
// To account for the extra spacing created by the alert icon // To account for the extra spacing created by the alert icon
if timelineItem.properties.deliveryStatus == .sendingFailed { if timelineItem.hasFailedToSend {
whiteSpaces += 3 whiteSpaces += 3
} }
@@ -51,6 +51,24 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
return true return true
} }
} }
var canAppearInFailedEcho: Bool {
switch self {
case .copy, .redact, .viewSource:
return true
default:
return false
}
}
var canAppearInRedacted: Bool {
switch self {
case .viewSource:
return true
default:
return false
}
}
} }
public struct TimelineItemMenu: View { public struct TimelineItemMenu: View {
@@ -70,17 +88,21 @@ public struct TimelineItemMenu: View {
ScrollView { ScrollView {
VStack(alignment: .leading, spacing: 0.0) { VStack(alignment: .leading, spacing: 0.0) {
reactionsSection if !item.isRedacted, !item.hasFailedToSend {
.padding(.top, 4.0) reactionsSection
.padding(.bottom, 8.0) .padding(.top, 4.0)
.padding(.bottom, 8.0)
Divider() Divider()
.background(Color.compound.bgSubtlePrimary) .background(Color.compound.bgSubtlePrimary)
}
viewsForActions(actions.actions) if !actions.actions.isEmpty {
viewsForActions(actions.actions)
Divider() Divider()
.background(Color.compound.bgSubtlePrimary) .background(Color.compound.bgSubtlePrimary)
}
viewsForActions(actions.debugActions) viewsForActions(actions.debugActions)
} }
@@ -65,6 +65,8 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
func redact(_ itemID: String) async { } func redact(_ itemID: String) async { }
func cancelSend(_ transactionID: String) async { }
func debugInfo(for itemID: String) -> TimelineItemDebugInfo { func debugInfo(for itemID: String) -> TimelineItemDebugInfo {
.init(model: "Mock debug description", originalJSON: nil, latestEditJSON: nil) .init(model: "Mock debug description", originalJSON: nil, latestEditJSON: nil)
} }
@@ -186,6 +186,11 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
} }
} }
func cancelSend(_ transactionID: String) async {
MXLog.info("Cancelling send in \(roomID)")
await roomProxy.cancelSend(transactionID: transactionID)
}
// Handle this parallel to the timeline items so we're not forced // Handle this parallel to the timeline items so we're not forced
// to bundle the Rust side objects within them // to bundle the Rust side objects within them
func debugInfo(for itemID: String) -> TimelineItemDebugInfo { func debugInfo(for itemID: String) -> TimelineItemDebugInfo {
@@ -58,6 +58,8 @@ protocol RoomTimelineControllerProtocol {
func redact(_ itemID: String) async func redact(_ itemID: String) async
func cancelSend(_ transactionID: String) async
func debugInfo(for itemID: String) -> TimelineItemDebugInfo func debugInfo(for itemID: String) -> TimelineItemDebugInfo
func retryDecryption(for sessionID: String) async func retryDecryption(for sessionID: String) async
@@ -33,4 +33,16 @@ extension EventBasedTimelineItemProtocol {
var description: String { var description: String {
"\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)" "\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)"
} }
var hasFailedToSend: Bool {
properties.deliveryStatus == .sendingFailed
}
var isMessage: Bool {
self is EventBasedMessageTimelineItemProtocol
}
var isRedacted: Bool {
self is RedactedRoomTimelineItem
}
} }
+1
View File
@@ -0,0 +1 @@
Filter out some message actions and reactions for failed local echoes and redacted messages.