mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Delivery status is displayed only for last message (#1193)
* checkmark only displays for the last message * delivery status is now displayed only for last message * changelog
This commit is contained in:
@@ -40,25 +40,32 @@ struct TimelineItemStyler_Previews: PreviewProvider {
|
|||||||
|
|
||||||
static let base = TextRoomTimelineItem(id: UUID().uuidString, timestamp: "Now", isOutgoing: true, isEditable: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test"))
|
static let base = TextRoomTimelineItem(id: UUID().uuidString, timestamp: "Now", isOutgoing: true, isEditable: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test"))
|
||||||
|
|
||||||
static let sent: TextRoomTimelineItem = {
|
static let sentNonLast: TextRoomTimelineItem = {
|
||||||
var result = base
|
var result = base
|
||||||
result.properties.deliveryStatus = .sent
|
result.properties.deliveryStatus = .sent
|
||||||
return result
|
return result
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let sending: TextRoomTimelineItem = {
|
static let sendingNonLast: TextRoomTimelineItem = {
|
||||||
var result = base
|
var result = base
|
||||||
result.properties.deliveryStatus = .sending
|
result.properties.deliveryStatus = .sending
|
||||||
return result
|
return result
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
static let sendingLast: TextRoomTimelineItem = {
|
||||||
|
let id = viewModel.state.items.last?.id ?? UUID().uuidString
|
||||||
|
var result = TextRoomTimelineItem(id: id, timestamp: "Now", isOutgoing: true, isEditable: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test"))
|
||||||
|
result.properties.deliveryStatus = .sending
|
||||||
|
return result
|
||||||
|
}()
|
||||||
|
|
||||||
static let failed: TextRoomTimelineItem = {
|
static let failed: TextRoomTimelineItem = {
|
||||||
var result = base
|
var result = base
|
||||||
result.properties.deliveryStatus = .sendingFailed
|
result.properties.deliveryStatus = .sendingFailed
|
||||||
return result
|
return result
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let last: TextRoomTimelineItem = {
|
static let sentLast: TextRoomTimelineItem = {
|
||||||
let id = viewModel.state.items.last?.id ?? UUID().uuidString
|
let id = viewModel.state.items.last?.id ?? UUID().uuidString
|
||||||
let result = TextRoomTimelineItem(id: id, timestamp: "Now", isOutgoing: true, isEditable: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test"))
|
let result = TextRoomTimelineItem(id: id, timestamp: "Now", isOutgoing: true, isEditable: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test"))
|
||||||
return result
|
return result
|
||||||
@@ -78,10 +85,11 @@ struct TimelineItemStyler_Previews: PreviewProvider {
|
|||||||
|
|
||||||
static var testView: some View {
|
static var testView: some View {
|
||||||
VStack {
|
VStack {
|
||||||
TextRoomTimelineView(timelineItem: sent)
|
|
||||||
TextRoomTimelineView(timelineItem: sending)
|
|
||||||
TextRoomTimelineView(timelineItem: base)
|
TextRoomTimelineView(timelineItem: base)
|
||||||
TextRoomTimelineView(timelineItem: last)
|
TextRoomTimelineView(timelineItem: sentNonLast)
|
||||||
|
TextRoomTimelineView(timelineItem: sentLast)
|
||||||
|
TextRoomTimelineView(timelineItem: sendingNonLast)
|
||||||
|
TextRoomTimelineView(timelineItem: sendingLast)
|
||||||
TextRoomTimelineView(timelineItem: failed)
|
TextRoomTimelineView(timelineItem: failed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-19
@@ -22,10 +22,8 @@ struct TimelineItemStatusView: View {
|
|||||||
@Environment(\.readReceiptsEnabled) private var readReceiptsEnabled
|
@Environment(\.readReceiptsEnabled) private var readReceiptsEnabled
|
||||||
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
||||||
|
|
||||||
@State private var shouldShowDeliveryStatus = true
|
|
||||||
|
|
||||||
private var isLastOutgoingMessage: Bool {
|
private var isLastOutgoingMessage: Bool {
|
||||||
context.viewState.items.last(where: { !$0.isUnsent })?.id == timelineItem.id &&
|
context.viewState.items.last?.id == timelineItem.id &&
|
||||||
timelineItem.isOutgoing
|
timelineItem.isOutgoing
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,18 +34,8 @@ struct TimelineItemStatusView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
if !timelineItem.properties.orderedReadReceipts.isEmpty, readReceiptsEnabled {
|
if !timelineItem.properties.orderedReadReceipts.isEmpty, readReceiptsEnabled {
|
||||||
readReceipts
|
readReceipts
|
||||||
} else if shouldShowDeliveryStatus {
|
} else {
|
||||||
deliveryStatus
|
deliveryStatus
|
||||||
.onChange(of: timelineItem.properties.deliveryStatus) { newValue in
|
|
||||||
if newValue == .sent, !isLast {
|
|
||||||
Task {
|
|
||||||
try? await Task.sleep(for: .milliseconds(1500))
|
|
||||||
withAnimation {
|
|
||||||
shouldShowDeliveryStatus = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,12 +43,13 @@ struct TimelineItemStatusView: View {
|
|||||||
var deliveryStatus: some View {
|
var deliveryStatus: some View {
|
||||||
switch timelineItem.properties.deliveryStatus {
|
switch timelineItem.properties.deliveryStatus {
|
||||||
case .sending:
|
case .sending:
|
||||||
TimelineDeliveryStatusView(deliveryStatus: .sending)
|
|
||||||
case .sent:
|
|
||||||
TimelineDeliveryStatusView(deliveryStatus: .sent)
|
|
||||||
case .none:
|
|
||||||
if isLastOutgoingMessage {
|
if isLastOutgoingMessage {
|
||||||
// We always display the sent icon for the latest echoed outgoing message
|
// We only display the sending icon for the latest outgoing message
|
||||||
|
TimelineDeliveryStatusView(deliveryStatus: .sending)
|
||||||
|
}
|
||||||
|
case .sent, .none:
|
||||||
|
if isLastOutgoingMessage {
|
||||||
|
// We only display the sent icon for the latest outgoing message
|
||||||
TimelineDeliveryStatusView(deliveryStatus: .sent)
|
TimelineDeliveryStatusView(deliveryStatus: .sent)
|
||||||
}
|
}
|
||||||
case .sendingFailed:
|
case .sendingFailed:
|
||||||
|
|||||||
@@ -105,31 +105,6 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isUnsent: Bool {
|
|
||||||
switch self {
|
|
||||||
case .text(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.image(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.video(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.audio(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.file(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.emote(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.notice(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.redacted(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.encrypted(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.sticker(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.unsupported(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.state(let item as EventBasedTimelineItemProtocol, _),
|
|
||||||
.location(let item as EventBasedTimelineItemProtocol, _):
|
|
||||||
return item.properties.deliveryStatus == .sending || item.properties.deliveryStatus == .sendingFailed
|
|
||||||
case .separator,
|
|
||||||
.readMarker,
|
|
||||||
.paginationIndicator,
|
|
||||||
.timelineStart,
|
|
||||||
.group:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether or not it is possible to send a reaction to this timeline item.
|
/// Whether or not it is possible to send a reaction to this timeline item.
|
||||||
var isReactable: Bool {
|
var isReactable: Bool {
|
||||||
switch self {
|
switch self {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Delivery status is now displayed only for the last outgoing message.
|
||||||
Reference in New Issue
Block a user