Use a Date for the timestamp in all timeline items. (#3590)

* Use a Date for the timestamp in all timeline items.

* UI test snapshots.

* Update snapshots

---------

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
This commit is contained in:
Doug
2024-12-06 13:55:29 +00:00
committed by GitHub
parent 176a8b880a
commit a9e4837b62
235 changed files with 522 additions and 510 deletions
@@ -85,7 +85,7 @@ struct TimelineItemMenu: View {
Spacer(minLength: 16.0)
Text(item.timestamp)
Text(item.timestamp.formattedTime())
.font(.compound.bodyXS)
.foregroundColor(.compound.textSecondary)
}
@@ -20,7 +20,7 @@ struct SwipeToReplyView: View {
struct SwipeToReplyView_Previews: PreviewProvider, TestablePreview {
static let timelineItem = TextRoomTimelineItem(id: .randomEvent,
timestamp: "",
timestamp: .mock,
isOutgoing: true,
isEditable: true,
canBeRepliedTo: true,
@@ -412,7 +412,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
static var replies: some View {
VStack(spacing: 0) {
RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .randomEvent,
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -425,7 +425,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
groupStyle: .single))
RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .randomEvent,
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -460,7 +460,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
static var encryptionAuthenticity: some View {
VStack(spacing: 0) {
RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .randomEvent,
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -471,7 +471,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
groupStyle: .single))
RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .randomEvent,
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -483,7 +483,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
groupStyle: .single))
RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .randomEvent,
timestamp: "10:42",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -494,7 +494,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
groupStyle: .first))
RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .randomEvent,
timestamp: "10:42",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -505,7 +505,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
groupStyle: .last))
ImageRoomTimelineView(timelineItem: ImageRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -518,7 +518,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
properties: RoomTimelineItemProperties(encryptionAuthenticity: .notGuaranteed(color: .gray))))
VoiceMessageRoomTimelineView(timelineItem: .init(id: .randomEvent,
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -547,7 +547,7 @@ private struct MockTimelineContent: View {
var body: some View {
RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: makeItemIdentifier(),
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -558,7 +558,7 @@ private struct MockTimelineContent: View {
groupStyle: .single))
AudioRoomTimelineView(timelineItem: .init(id: makeItemIdentifier(),
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -573,7 +573,7 @@ private struct MockTimelineContent: View {
replyDetails: replyDetails))
FileRoomTimelineView(timelineItem: .init(id: makeItemIdentifier(),
timestamp: "10:42",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -588,7 +588,7 @@ private struct MockTimelineContent: View {
replyDetails: replyDetails))
ImageRoomTimelineView(timelineItem: .init(id: makeItemIdentifier(),
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: true,
canBeRepliedTo: true,
@@ -600,7 +600,7 @@ private struct MockTimelineContent: View {
replyDetails: replyDetails))
LocationRoomTimelineView(timelineItem: .init(id: makeItemIdentifier(),
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -613,7 +613,7 @@ private struct MockTimelineContent: View {
replyDetails: replyDetails))
LocationRoomTimelineView(timelineItem: .init(id: makeItemIdentifier(),
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -624,7 +624,7 @@ private struct MockTimelineContent: View {
replyDetails: replyDetails))
VoiceMessageRoomTimelineView(timelineItem: .init(id: makeItemIdentifier(),
timestamp: "10:42",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -58,7 +58,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
static let viewModel = TimelineViewModel.mock
static let base = TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -81,7 +81,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
static let sendingLast: TextRoomTimelineItem = {
let id = viewModel.state.timelineViewState.uniqueIDs.last ?? .init(id: UUID().uuidString)
var result = TextRoomTimelineItem(id: .event(uniqueID: id, eventOrTransactionID: .eventId(eventId: UUID().uuidString)),
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -101,7 +101,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
static let sentLast: TextRoomTimelineItem = {
let id = viewModel.state.timelineViewState.uniqueIDs.last ?? .init(id: UUID().uuidString)
let result = TextRoomTimelineItem(id: .event(uniqueID: id, eventOrTransactionID: .eventId(eventId: UUID().uuidString)),
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -112,7 +112,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
}()
static let ltrString = TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -120,7 +120,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
sender: .test, content: .init(body: "house!"))
static let rtlString = TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -128,7 +128,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
sender: .test, content: .init(body: "באמת!"))
static let ltrStringThatContainsRtl = TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -137,7 +137,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
content: .init(body: "house! -- באמת‏! -- house!"))
static let rtlStringThatContainsLtr = TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -146,7 +146,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
content: .init(body: "באמת‏! -- house! -- באמת!"))
static let ltrStringThatFinishesInRtl = TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -155,7 +155,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
content: .init(body: "house! -- באמת!"))
static let rtlStringThatFinishesInLtr = TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -102,7 +102,7 @@ struct TimelineReadReceiptsView_Previews: PreviewProvider, TestablePreview {
static func mockTimelineItem(with receipts: [ReadReceipt]) -> TextRoomTimelineItem {
TextRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -42,7 +42,7 @@ struct AudioRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static func makeItem(filename: String, fileSize: UInt, caption: String? = nil) -> AudioRoomTimelineItem {
.init(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -34,7 +34,7 @@ struct CallInviteRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static var body: some View {
CallInviteRoomTimelineView(timelineItem: .init(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isEditable: false,
canBeRepliedTo: false,
sender: .init(id: "Bob")))
@@ -39,7 +39,7 @@ struct CallNotificationRoomTimelineView: View {
Spacer()
Text(timelineItem.timestamp)
Text(timelineItem.timestamp.formattedTime())
.font(.compound.bodyXS)
.foregroundColor(.compound.textSecondary)
}
@@ -61,7 +61,7 @@ struct CallNotificationRoomTimelineView_Previews: PreviewProvider, TestablePrevi
static var body: some View {
CallNotificationRoomTimelineView(timelineItem: .init(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isEditable: false,
canBeRepliedTo: false,
sender: .init(id: "Bob")))
@@ -32,16 +32,16 @@ struct EmoteRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static var body: some View {
VStack(alignment: .leading, spacing: 20.0) {
EmoteRoomTimelineView(timelineItem: itemWith(text: "Short loin ground round tongue hamburger, fatback salami shoulder. Beef turkey sausage kielbasa strip steak. Alcatra capicola pig tail pancetta chislic.",
timestamp: "Now",
timestamp: .mock,
senderId: "Bob"))
EmoteRoomTimelineView(timelineItem: itemWith(text: "Some other text",
timestamp: "Later",
timestamp: .mock,
senderId: "Anne"))
}
}
private static func itemWith(text: String, timestamp: String, senderId: String) -> EmoteRoomTimelineItem {
private static func itemWith(text: String, timestamp: Date, senderId: String) -> EmoteRoomTimelineItem {
EmoteRoomTimelineItem(id: .randomEvent,
timestamp: timestamp,
isOutgoing: false,
@@ -61,27 +61,27 @@ struct EncryptedRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static var body: some View {
VStack(alignment: .leading, spacing: 20.0) {
EncryptedRoomTimelineView(timelineItem: itemWith(text: L10n.commonWaitingForDecryptionKey,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
senderId: "Bob"))
EncryptedRoomTimelineView(timelineItem: itemWith(text: L10n.commonWaitingForDecryptionKey,
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
EncryptedRoomTimelineView(timelineItem: itemWith(text: "Some other text that is very long and will wrap onto multiple lines.",
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
EncryptedRoomTimelineView(timelineItem: expectedItemWith(timestamp: "Now",
EncryptedRoomTimelineView(timelineItem: expectedItemWith(timestamp: .mock,
isOutgoing: false,
senderId: "Bob"))
}
}
private static func itemWith(text: String, timestamp: String, isOutgoing: Bool, senderId: String) -> EncryptedRoomTimelineItem {
private static func itemWith(text: String, timestamp: Date, isOutgoing: Bool, senderId: String) -> EncryptedRoomTimelineItem {
EncryptedRoomTimelineItem(id: .randomEvent,
body: text,
encryptionType: .unknown,
@@ -92,7 +92,7 @@ struct EncryptedRoomTimelineView_Previews: PreviewProvider, TestablePreview {
sender: .init(id: senderId))
}
private static func expectedItemWith(timestamp: String, isOutgoing: Bool, senderId: String) -> EncryptedRoomTimelineItem {
private static func expectedItemWith(timestamp: Date, isOutgoing: Bool, senderId: String) -> EncryptedRoomTimelineItem {
EncryptedRoomTimelineItem(id: .randomEvent,
body: L10n.commonUnableToDecryptNoAccess,
encryptionType: .megolmV1AesSha2(sessionID: "foo", cause: .sentBeforeWeJoined),
@@ -112,7 +112,7 @@ struct FileRoomTimelineView_Previews: PreviewProvider, TestablePreview {
caption: String? = nil,
formattedCaption: AttributedString? = nil) -> FileRoomTimelineItem {
.init(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -94,7 +94,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview {
private static func makeTimelineItem(caption: String? = nil, isEdited: Bool = false) -> ImageRoomTimelineItem {
ImageRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -91,7 +91,7 @@ struct LocationRoomTimelineView_Previews: PreviewProvider, TestablePreview {
@ViewBuilder
static var states: some View {
LocationRoomTimelineView(timelineItem: .init(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -100,7 +100,7 @@ struct LocationRoomTimelineView_Previews: PreviewProvider, TestablePreview {
content: .init(body: "Fallback geo uri description")))
LocationRoomTimelineView(timelineItem: .init(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -109,7 +109,7 @@ struct LocationRoomTimelineView_Previews: PreviewProvider, TestablePreview {
content: .init(body: "Fallback geo uri description",
geoURI: .init(latitude: 41.902782, longitude: 12.496366), description: "Location description description description description description description description description")))
LocationRoomTimelineView(timelineItem: .init(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -44,16 +44,16 @@ struct NoticeRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static var body: some View {
VStack(alignment: .leading, spacing: 20.0) {
NoticeRoomTimelineView(timelineItem: itemWith(text: "Short loin ground round tongue hamburger, fatback salami shoulder. Beef turkey sausage kielbasa strip steak. Alcatra capicola pig tail pancetta chislic.",
timestamp: "Now",
timestamp: .mock,
senderId: "Bob"))
NoticeRoomTimelineView(timelineItem: itemWith(text: "Some other text",
timestamp: "Later",
timestamp: .mock,
senderId: "Anne"))
}
}
private static func itemWith(text: String, timestamp: String, senderId: String) -> NoticeRoomTimelineItem {
private static func itemWith(text: String, timestamp: Date, senderId: String) -> NoticeRoomTimelineItem {
NoticeRoomTimelineItem(id: .randomEvent,
timestamp: timestamp,
isOutgoing: false,
@@ -35,7 +35,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
VStack(alignment: .leading, spacing: 0) {
RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .virtual(uniqueID: .init(id: "Separator")), text: "Today")), groupStyle: .single))
RoomTimelineItemView(viewState: .init(type: .text(.init(id: .randomEvent,
timestamp: "",
timestamp: .mock,
isOutgoing: true,
isEditable: false,
canBeRepliedTo: true,
@@ -47,7 +47,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .virtual(uniqueID: .init(id: "Separator")), text: "Today")), groupStyle: .single))
RoomTimelineItemView(viewState: .init(type: .text(.init(id: .randomEvent,
timestamp: "",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -26,13 +26,13 @@ struct RedactedRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
VStack(alignment: .leading, spacing: 20.0) {
RedactedRoomTimelineView(timelineItem: itemWith(text: L10n.commonMessageRemoved,
timestamp: "Later",
timestamp: .mock,
senderId: "Anne"))
}
.environmentObject(viewModel.context)
}
private static func itemWith(text: String, timestamp: String, senderId: String) -> RedactedRoomTimelineItem {
private static func itemWith(text: String, timestamp: Date, senderId: String) -> RedactedRoomTimelineItem {
RedactedRoomTimelineItem(id: .randomEvent,
body: text,
timestamp: timestamp,
@@ -32,7 +32,7 @@ struct StateRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static let item = StateRoomTimelineItem(id: .randomVirtual,
body: "Alice joined",
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -44,7 +44,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
VStack(spacing: 20.0) {
StickerRoomTimelineView(timelineItem: StickerRoomTimelineItem(id: .randomEvent,
body: "Some image",
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -53,7 +53,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
StickerRoomTimelineView(timelineItem: StickerRoomTimelineItem(id: .randomEvent,
body: "Blurhashed image",
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,
@@ -42,44 +42,44 @@ struct TextRoomTimelineView_Previews: PreviewProvider, TestablePreview {
ScrollView {
VStack(alignment: .leading, spacing: 20.0) {
TextRoomTimelineView(timelineItem: itemWith(text: "Short loin ground round tongue hamburger, fatback salami shoulder. Beef turkey sausage kielbasa strip steak. Alcatra capicola pig tail pancetta chislic.",
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
senderId: "Bob"))
TextRoomTimelineView(timelineItem: itemWith(text: "Some other text",
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
TextRoomTimelineView(timelineItem: itemWith(text: "Short loin ground round tongue hamburger, fatback salami shoulder. Beef turkey sausage kielbasa strip steak. Alcatra capicola pig tail pancetta chislic.",
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
senderId: "Bob"))
TextRoomTimelineView(timelineItem: itemWith(text: "Some other text",
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
TextRoomTimelineView(timelineItem: itemWith(text: "טקסט אחר",
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
TextRoomTimelineView(timelineItem: itemWith(html: "<ol><li>First item</li><li>Second item</li><li>Third item</li></ol>",
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
TextRoomTimelineView(timelineItem: itemWith(html: "<ol><li>פריט ראשון</li><li>הפריט השני</li><li>פריט שלישי</li></ol>",
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
}
}
}
private static func itemWith(text: String, timestamp: String, isOutgoing: Bool, senderId: String) -> TextRoomTimelineItem {
private static func itemWith(text: String, timestamp: Date, isOutgoing: Bool, senderId: String) -> TextRoomTimelineItem {
TextRoomTimelineItem(id: .randomEvent,
timestamp: timestamp,
isOutgoing: isOutgoing,
@@ -90,7 +90,7 @@ struct TextRoomTimelineView_Previews: PreviewProvider, TestablePreview {
content: .init(body: text))
}
private static func itemWith(html: String, timestamp: String, isOutgoing: Bool, senderId: String) -> TextRoomTimelineItem {
private static func itemWith(html: String, timestamp: Date, isOutgoing: Bool, senderId: String) -> TextRoomTimelineItem {
let builder = AttributedStringBuilder(cacheKey: "preview", mentionBuilder: MentionBuilder())
let attributedString = builder.fromHTML(html)
@@ -40,18 +40,18 @@ struct UnsupportedRoomTimelineView_Previews: PreviewProvider, TestablePreview {
static var body: some View {
VStack(alignment: .leading, spacing: 20.0) {
UnsupportedRoomTimelineView(timelineItem: itemWith(text: "Text",
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
senderId: "Bob"))
UnsupportedRoomTimelineView(timelineItem: itemWith(text: "Some other text",
timestamp: "Later",
timestamp: .mock,
isOutgoing: true,
senderId: "Anne"))
}
}
private static func itemWith(text: String, timestamp: String, isOutgoing: Bool, senderId: String) -> UnsupportedRoomTimelineItem {
private static func itemWith(text: String, timestamp: Date, isOutgoing: Bool, senderId: String) -> UnsupportedRoomTimelineItem {
UnsupportedRoomTimelineItem(id: .randomEvent,
body: text,
eventType: "Some Event Type",
@@ -98,7 +98,7 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview {
private static func makeTimelineItem(caption: String? = nil, isEdited: Bool = false) -> VideoRoomTimelineItem {
VideoRoomTimelineItem(id: .randomEvent,
timestamp: "Now",
timestamp: .mock,
isOutgoing: false,
isEditable: false,
canBeRepliedTo: true,