Fixes #2842, fixes #2841 - Adopt new message sending queue API

- automatically retry failed requests as soon as the network is availble again
- remove manual retry options
This commit is contained in:
Stefan Ceriu
2024-05-28 10:17:13 +03:00
committed by Stefan Ceriu
parent 53fc5df55b
commit 6c1647b851
28 changed files with 827 additions and 606 deletions
@@ -157,7 +157,9 @@ class RoomScreenInteractionHandler {
actions.append(.copy)
}
actions.append(.copyPermalink)
if item.isRemoteMessage {
actions.append(.copyPermalink)
}
if canRedactItem(item), let poll = item.pollIfAvailable, !poll.hasEnded, let eventID = itemID.eventID {
actions.append(.endPoll(pollStartID: eventID))
@@ -224,11 +226,7 @@ class RoomScreenInteractionHandler {
}
case .redact:
Task {
if eventTimelineItem.hasFailedToSend {
await timelineController.cancelSending(itemID: itemID)
} else {
await timelineController.redact(itemID)
}
await timelineController.redact(itemID)
}
case .reply:
guard let eventID = eventTimelineItem.id.eventID else {
@@ -91,7 +91,6 @@ enum RoomScreenViewAction {
case displayRoomMemberDetails(userID: String)
case displayReactionSummary(itemID: TimelineItemIdentifier, key: String)
case displayEmojiPicker(itemID: TimelineItemIdentifier)
case displayMessageSendingFailureAlert(itemID: TimelineItemIdentifier)
case displayReadReceipts(itemID: TimelineItemIdentifier)
case displayCall
@@ -175,10 +174,6 @@ struct TimelineItemActionMenuInfo: Equatable, Identifiable {
}
}
struct MessageSendingFailureInfo: Hashable {
let itemID: TimelineItemIdentifier
}
struct ReactionSummaryInfo: Identifiable {
let reactions: [AggregatedReaction]
let selectedKey: String
@@ -196,7 +191,6 @@ struct ReadReceiptSummaryInfo: Identifiable {
enum RoomScreenAlertInfoType: Hashable {
case audioRecodingPermissionError
case pollEndConfirmation(String)
case messageSendingFailure(TimelineItemIdentifier)
}
struct RoomMemberState {
@@ -174,8 +174,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
roomScreenInteractionHandler.displayEmojiPicker(for: itemID)
case .displayReactionSummary(let itemID, let key):
displayReactionSummary(for: itemID, selectedKey: key)
case .displayMessageSendingFailureAlert(let itemID):
displayAlert(.messageSendingFailure(itemID))
case .displayReadReceipts(itemID: let itemID):
displayReadReceipts(for: itemID)
case .displayCall:
@@ -387,14 +385,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
}
.store(in: &cancellables)
roomProxy.timeline.actions
.filter { $0 == .sentMessage }
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
self?.scrollToBottom()
}
.store(in: &cancellables)
appSettings.$timelineStyle
.weakAssign(to: \.state.timelineStyle, on: self)
.store(in: &cancellables)
@@ -558,10 +548,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
inReplyTo: itemId,
intentionalMentions: intentionalMentions)
case .edit(let originalItemId):
await timelineController.editMessage(message,
html: html,
original: originalItemId,
intentionalMentions: intentionalMentions)
await timelineController.edit(originalItemId,
message: message,
html: html,
intentionalMentions: intentionalMentions)
case .default:
await timelineController.sendMessage(message,
html: html,
@@ -569,6 +559,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
case .recordVoiceMessage, .previewVoiceMessage:
fatalError("invalid composer mode.")
}
scrollToBottom()
}
private func trackComposerMode(_ mode: RoomScreenComposerMode) {
@@ -770,15 +762,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
message: L10n.commonPollEndConfirmation,
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
secondaryButton: .init(title: L10n.actionOk, action: { self.roomScreenInteractionHandler.endPoll(pollStartID: pollStartID) }))
case .messageSendingFailure(let itemID):
state.bindings.alertInfo = .init(id: type,
title: L10n.screenRoomRetrySendMenuTitle,
primaryButton: .init(title: L10n.screenRoomRetrySendMenuSendAgainAction) {
Task { await self.timelineController.retrySending(itemID: itemID) }
},
secondaryButton: .init(title: L10n.actionRemove, role: .destructive) {
Task { await self.timelineController.cancelSending(itemID: itemID) }
})
}
}
@@ -110,9 +110,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
VStack(alignment: alignment, spacing: -3) {
messageBubble
.timelineItemAccessibility(timelineItem) {
if adjustedDeliveryStatus == .sendingFailed {
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
} else {
if adjustedDeliveryStatus != .sendingFailed {
context.send(viewAction: .displayTimelineItemMenu(itemID: timelineItem.id))
}
}
@@ -171,22 +169,10 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
timelineItem.bubbleSendInfoLayoutType
.layout {
contentWithReply
interactiveLocalizedSendInfo
layoutedLocalizedSendInfo
}
}
@ViewBuilder
var interactiveLocalizedSendInfo: some View {
if adjustedDeliveryStatus == .sendingFailed {
layoutedLocalizedSendInfo
.onTapGesture {
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
}
} else {
layoutedLocalizedSendInfo
}
}
@ViewBuilder
var layoutedLocalizedSendInfo: some View {
switch timelineItem.bubbleSendInfoLayoutType {
@@ -55,9 +55,6 @@ struct TimelineItemStatusView: View {
if style == .plain {
CompoundIcon(\.error, size: .xSmall, relativeTo: .compound.bodyMD)
.foregroundColor(.compound.iconCriticalPrimary)
.onTapGesture {
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
}
.accessibilityLabel(L10n.commonSendingFailed)
.accessibilityHint(L10n.actionTapForOptions)
}