Fixes #2808 - Switch the message sending failure options from a dialog to an alert

* Fixes #2808 - Switch the message sending failure options from a dialog to an alert
- this prevents it from showing up as a popup on the room list on an iPad
- it used to be set on the timeline and not on the timeline item because of our use of a UITableView
* Cleanup room screen action names
This commit is contained in:
Stefan Ceriu
2024-05-09 14:35:47 +03:00
committed by GitHub
parent d97f912df7
commit 905b21e0a8
16 changed files with 180 additions and 245 deletions
@@ -55,7 +55,6 @@ struct RoomScreen: View {
.toolbarBackground(.visible, for: .navigationBar) // Fix the toolbar's background.
.overlay { loadingIndicator }
.alert(item: $context.alertInfo)
.alert(item: $context.confirmationAlertInfo)
.sheet(item: $context.debugInfo) { TimelineItemDebugView(info: $0) }
.sheet(item: $context.actionMenuInfo) { info in
context.viewState.timelineItemMenuActionProvider?(info.item.id).map { actions in
@@ -82,14 +81,6 @@ struct RoomScreen: View {
context.send(viewAction: .handlePasteOrDrop(provider: provider))
return true
}
.confirmationDialog(item: $context.sendFailedConfirmationDialogInfo, titleVisibility: .visible) { info in
Button(L10n.screenRoomRetrySendMenuSendAgainAction) {
context.send(viewAction: .retrySend(itemID: info.itemID))
}
Button(L10n.actionRemove, role: .destructive) {
context.send(viewAction: .cancelSend(itemID: info.itemID))
}
}
}
private var timeline: some View {
@@ -168,7 +159,7 @@ struct RoomScreen: View {
private var callButton: some View {
if context.viewState.hasOngoingCall {
Button {
context.send(viewAction: .presentCall)
context.send(viewAction: .displayCall)
} label: {
Label(L10n.actionJoin, icon: \.videoCallSolid)
.labelStyle(.titleAndIcon)
@@ -177,7 +168,7 @@ struct RoomScreen: View {
.accessibilityIdentifier(A11yIdentifiers.roomScreen.joinCall)
} else {
Button {
context.send(viewAction: .presentCall)
context.send(viewAction: .displayCall)
} label: {
CompoundIcon(\.videoCallSolid)
}
@@ -99,7 +99,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
// sender info are read inside the `TimelineAccessibilityModifier`
.accessibilityHidden(true)
.onTapGesture {
context.send(viewAction: .tappedOnUser(userID: timelineItem.sender.id))
context.send(viewAction: .displayRoomMemberDetails(userID: timelineItem.sender.id))
}
.padding(.top, 8)
}
@@ -111,9 +111,9 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
messageBubble
.timelineItemAccessibility(timelineItem) {
if adjustedDeliveryStatus == .sendingFailed {
context.sendFailedConfirmationDialogInfo = .init(itemID: timelineItem.id)
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
} else {
context.send(viewAction: .timelineItemMenu(itemID: timelineItem.id))
context.send(viewAction: .displayTimelineItemMenu(itemID: timelineItem.id))
}
}
@@ -139,7 +139,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
// We need a tap gesture before this long one so that it doesn't
// steal away the gestures from the scroll view
.longPressWithFeedback {
context.send(viewAction: .timelineItemMenu(itemID: timelineItem.id))
context.send(viewAction: .displayTimelineItemMenu(itemID: timelineItem.id))
}
.swipeRightAction {
SwipeToReplyView(timelineItem: timelineItem)
@@ -147,12 +147,12 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
context.viewState.timelineItemMenuActionProvider?(timelineItem.id)?.canReply ?? false
} action: {
let isThread = (timelineItem as? EventBasedMessageTimelineItemProtocol)?.isThreaded ?? false
context.send(viewAction: .timelineItemMenuAction(itemID: timelineItem.id, action: .reply(isThread: isThread)))
context.send(viewAction: .handleTimelineItemMenuAction(itemID: timelineItem.id, action: .reply(isThread: isThread)))
}
.contextMenu {
TimelineItemMacContextMenu(item: timelineItem,
actionProvider: context.viewState.timelineItemMenuActionProvider) { action in
context.send(viewAction: .timelineItemMenuAction(itemID: timelineItem.id, action: action))
context.send(viewAction: .handleTimelineItemMenuAction(itemID: timelineItem.id, action: action))
}
}
.padding(.top, messageBubbleTopPadding)
@@ -180,7 +180,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
if adjustedDeliveryStatus == .sendingFailed {
layoutedLocalizedSendInfo
.onTapGesture {
context.sendFailedConfirmationDialogInfo = .init(itemID: timelineItem.id)
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
}
} else {
layoutedLocalizedSendInfo
@@ -69,7 +69,7 @@ struct TimelineItemPlainStylerView<Content: View>: View {
content()
.layoutPriority(1)
.timelineItemAccessibility(timelineItem) {
context.send(viewAction: .timelineItemMenu(itemID: timelineItem.id))
context.send(viewAction: .displayTimelineItemMenu(itemID: timelineItem.id))
}
}
.onTapGesture(count: 2) {
@@ -81,7 +81,7 @@ struct TimelineItemPlainStylerView<Content: View>: View {
// We need a tap gesture before this long one so that it doesn't
// steal away the gestures from the scroll view
.longPressWithFeedback {
context.send(viewAction: .timelineItemMenu(itemID: timelineItem.id))
context.send(viewAction: .displayTimelineItemMenu(itemID: timelineItem.id))
}
.swipeRightAction {
SwipeToReplyView(timelineItem: timelineItem)
@@ -89,12 +89,12 @@ struct TimelineItemPlainStylerView<Content: View>: View {
context.viewState.timelineItemMenuActionProvider?(timelineItem.id)?.canReply ?? false
} action: {
let isThread = (timelineItem as? EventBasedMessageTimelineItemProtocol)?.isThreaded ?? false
context.send(viewAction: .timelineItemMenuAction(itemID: timelineItem.id, action: .reply(isThread: isThread)))
context.send(viewAction: .handleTimelineItemMenuAction(itemID: timelineItem.id, action: .reply(isThread: isThread)))
}
.contextMenu {
TimelineItemMacContextMenu(item: timelineItem,
actionProvider: context.viewState.timelineItemMenuActionProvider) { action in
context.send(viewAction: .timelineItemMenuAction(itemID: timelineItem.id, action: action))
context.send(viewAction: .handleTimelineItemMenuAction(itemID: timelineItem.id, action: action))
}
}
}
@@ -111,7 +111,7 @@ struct TimelineItemPlainStylerView<Content: View>: View {
.lineLimit(1)
}
.onTapGesture {
context.send(viewAction: .tappedOnUser(userID: timelineItem.sender.id))
context.send(viewAction: .displayRoomMemberDetails(userID: timelineItem.sender.id))
}
Spacer()
Text(timelineItem.timestamp)
@@ -56,7 +56,7 @@ struct TimelineItemStatusView: View {
CompoundIcon(\.error, size: .xSmall, relativeTo: .compound.bodyMD)
.foregroundColor(.compound.iconCriticalPrimary)
.onTapGesture {
context.sendFailedConfirmationDialogInfo = .init(itemID: timelineItem.id)
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
}
.accessibilityLabel(L10n.commonSendingFailed)
.accessibilityHint(L10n.actionTapForOptions)
@@ -57,7 +57,7 @@ struct TimelineReactionsView: View {
feedbackGenerator.impactOccurred()
context.send(viewAction: .toggleReaction(key: key, itemID: itemID))
} showReactionSummary: { key in
context.send(viewAction: .reactionSummary(itemID: itemID, key: key))
context.send(viewAction: .displayReactionSummary(itemID: itemID, key: key))
}
.reactionLayoutItem(.reaction)
.environment(\.layoutDirection, layoutDirection)
@@ -46,7 +46,7 @@ struct TimelineReadReceiptsView: View {
}
}
.onTapGesture {
context.send(viewAction: .showReadReceipts(itemID: timelineItem.id))
context.send(viewAction: .displayReadReceipts(itemID: timelineItem.id))
}
.accessibilityElement(children: .ignore)
.accessibilityLabel(accessibilityLabel)
@@ -26,13 +26,13 @@ struct PollRoomTimelineView: View {
switch action {
case .selectOption(let optionID):
guard let eventID, let option = poll.options.first(where: { $0.id == optionID }), !option.isSelected else { return }
context.send(viewAction: .poll(.selectOption(pollStartID: eventID, optionID: option.id)))
context.send(viewAction: .handlePollAction(.selectOption(pollStartID: eventID, optionID: option.id)))
case .edit:
guard let eventID else { return }
context.send(viewAction: .poll(.edit(pollStartID: eventID, poll: poll)))
context.send(viewAction: .handlePollAction(.edit(pollStartID: eventID, poll: poll)))
case .end:
guard let eventID else { return }
context.send(viewAction: .poll(.end(pollStartID: eventID)))
context.send(viewAction: .handlePollAction(.end(pollStartID: eventID)))
}
}
}
@@ -298,7 +298,7 @@ struct TimelineItemMenu: View {
dismiss()
// Otherwise we might get errors that a sheet is already presented
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
context.send(viewAction: .timelineItemMenuAction(itemID: item.id, action: action))
context.send(viewAction: .handleTimelineItemMenuAction(itemID: item.id, action: action))
}
}
}