Render the number of thread replies on the thread summary timeline view.

This commit is contained in:
Stefan Ceriu
2025-06-12 15:26:57 +03:00
committed by Stefan Ceriu
parent 264a68d3e2
commit 9309b543b8
19 changed files with 114 additions and 63 deletions

View File

@@ -8736,7 +8736,7 @@
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
requirement = { requirement = {
kind = exactVersion; kind = exactVersion;
version = 25.06.12; version = "25.06.12-2";
}; };
}; };
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {

View File

@@ -158,8 +158,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/element-hq/matrix-rust-components-swift", "location" : "https://github.com/element-hq/matrix-rust-components-swift",
"state" : { "state" : {
"revision" : "6450696917e54b4ab62cad9275d673e43d0e865c", "revision" : "0f239a906115a792bdca0741ca20fc59a64b8e39",
"version" : "25.6.12" "version" : "25.6.12-2"
} }
}, },
{ {

View File

@@ -222,6 +222,7 @@
"common_reason" = "Reason"; "common_reason" = "Reason";
"common_recovery_key" = "Recovery key"; "common_recovery_key" = "Recovery key";
"common_refreshing" = "Refreshing…"; "common_refreshing" = "Refreshing…";
"common_replies" = "%1$d replies";
"common_replying_to" = "Replying to %1$@"; "common_replying_to" = "Replying to %1$@";
"common_report_a_bug" = "Report a bug"; "common_report_a_bug" = "Report a bug";
"common_report_a_problem" = "Report a problem"; "common_report_a_problem" = "Report a problem";
@@ -332,6 +333,7 @@
"error_no_compatible_app_found" = "No compatible app was found to handle this action."; "error_no_compatible_app_found" = "No compatible app was found to handle this action.";
"error_some_messages_have_not_been_sent" = "Some messages have not been sent"; "error_some_messages_have_not_been_sent" = "Some messages have not been sent";
"error_unknown" = "Sorry, an error occurred"; "error_unknown" = "Sorry, an error occurred";
"event_shield_mismatched_sender" = "The sender of the event does not match the owner of the device that sent it.";
"event_shield_reason_authenticity_not_guaranteed" = "The authenticity of this encrypted message can't be guaranteed on this device."; "event_shield_reason_authenticity_not_guaranteed" = "The authenticity of this encrypted message can't be guaranteed on this device.";
"event_shield_reason_previously_verified" = "Encrypted by a previously-verified user."; "event_shield_reason_previously_verified" = "Encrypted by a previously-verified user.";
"event_shield_reason_sent_in_clear" = "Not encrypted."; "event_shield_reason_sent_in_clear" = "Not encrypted.";

View File

@@ -512,6 +512,10 @@ internal enum L10n {
internal static var commonRecoveryKey: String { return L10n.tr("Localizable", "common_recovery_key") } internal static var commonRecoveryKey: String { return L10n.tr("Localizable", "common_recovery_key") }
/// Refreshing /// Refreshing
internal static var commonRefreshing: String { return L10n.tr("Localizable", "common_refreshing") } internal static var commonRefreshing: String { return L10n.tr("Localizable", "common_refreshing") }
/// %1$d replies
internal static func commonReplies(_ p1: Int) -> String {
return L10n.tr("Localizable", "common_replies", p1)
}
/// Replying to %1$@ /// Replying to %1$@
internal static func commonReplyingTo(_ p1: Any) -> String { internal static func commonReplyingTo(_ p1: Any) -> String {
return L10n.tr("Localizable", "common_replying_to", String(describing: p1)) return L10n.tr("Localizable", "common_replying_to", String(describing: p1))
@@ -764,6 +768,8 @@ internal enum L10n {
internal static var errorSomeMessagesHaveNotBeenSent: String { return L10n.tr("Localizable", "error_some_messages_have_not_been_sent") } internal static var errorSomeMessagesHaveNotBeenSent: String { return L10n.tr("Localizable", "error_some_messages_have_not_been_sent") }
/// Sorry, an error occurred /// Sorry, an error occurred
internal static var errorUnknown: String { return L10n.tr("Localizable", "error_unknown") } internal static var errorUnknown: String { return L10n.tr("Localizable", "error_unknown") }
/// The sender of the event does not match the owner of the device that sent it.
internal static var eventShieldMismatchedSender: String { return L10n.tr("Localizable", "event_shield_mismatched_sender") }
/// The authenticity of this encrypted message can't be guaranteed on this device. /// The authenticity of this encrypted message can't be guaranteed on this device.
internal static var eventShieldReasonAuthenticityNotGuaranteed: String { return L10n.tr("Localizable", "event_shield_reason_authenticity_not_guaranteed") } internal static var eventShieldReasonAuthenticityNotGuaranteed: String { return L10n.tr("Localizable", "event_shield_reason_authenticity_not_guaranteed") }
/// Encrypted by a previously-verified user. /// Encrypted by a previously-verified user.

View File

@@ -419,7 +419,8 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
ScrollView { ScrollView {
let threadSummary = TimelineItemThreadSummary.loaded(senderID: "@alice:matrix.org", let threadSummary = TimelineItemThreadSummary.loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.text(.init(body: "This is a very long, multi-lined, threaded message")))) latestEventContent: .message(.text(.init(body: "This is a very long, multi-lined, threaded message"))),
numberOfReplies: 42)
MockTimelineContent(threadSummary: threadSummary) MockTimelineContent(threadSummary: threadSummary)
} }

View File

@@ -23,7 +23,7 @@ struct TimelineThreadSummaryView: View {
@ViewBuilder @ViewBuilder
private var content: some View { private var content: some View {
switch threadSummary { switch threadSummary {
case .loaded(let senderID, let sender, let latestEventContent): case .loaded(let senderID, let sender, let latestEventContent, let numberOfReplies):
switch latestEventContent { switch latestEventContent {
case .message(let content): case .message(let content):
switch content { switch content {
@@ -31,58 +31,69 @@ struct TimelineThreadSummaryView: View {
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: content.caption ?? content.filename, plainBody: content.caption ?? content.filename,
formattedBody: content.formattedCaption) formattedBody: content.formattedCaption,
numberOfReplies: numberOfReplies)
case .emote(let content): case .emote(let content):
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: content.body, plainBody: content.body,
formattedBody: content.formattedBody) formattedBody: content.formattedBody,
numberOfReplies: numberOfReplies)
case .file(let content): case .file(let content):
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: content.caption ?? content.filename, plainBody: content.caption ?? content.filename,
formattedBody: content.formattedCaption) formattedBody: content.formattedCaption,
numberOfReplies: numberOfReplies)
case .image(let content): case .image(let content):
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: content.caption ?? content.filename, plainBody: content.caption ?? content.filename,
formattedBody: content.formattedCaption) formattedBody: content.formattedCaption,
numberOfReplies: numberOfReplies)
case .notice(let content): case .notice(let content):
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: content.body, plainBody: content.body,
formattedBody: content.formattedBody) formattedBody: content.formattedBody,
numberOfReplies: numberOfReplies)
case .text(let content): case .text(let content):
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: content.body, plainBody: content.body,
formattedBody: content.formattedBody) formattedBody: content.formattedBody,
numberOfReplies: numberOfReplies)
case .video(let content): case .video(let content):
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: content.caption ?? content.filename, plainBody: content.caption ?? content.filename,
formattedBody: content.formattedCaption) formattedBody: content.formattedCaption,
numberOfReplies: numberOfReplies)
case .voice: case .voice:
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: L10n.commonVoiceMessage, plainBody: L10n.commonVoiceMessage,
formattedBody: nil) formattedBody: nil,
numberOfReplies: numberOfReplies)
case .location: case .location:
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: L10n.commonSharedLocation, plainBody: L10n.commonSharedLocation,
formattedBody: nil) formattedBody: nil,
numberOfReplies: numberOfReplies)
} }
case .poll(let question): case .poll(let question):
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: question, plainBody: question,
formattedBody: nil) formattedBody: nil,
numberOfReplies: numberOfReplies)
case .redacted: case .redacted:
ThreadView(senderID: senderID, ThreadView(senderID: senderID,
sender: sender, sender: sender,
plainBody: L10n.commonMessageRemoved, plainBody: L10n.commonMessageRemoved,
formattedBody: nil) formattedBody: nil,
numberOfReplies: numberOfReplies)
} }
default: default:
LoadingThreadView() LoadingThreadView()
@@ -91,7 +102,11 @@ struct TimelineThreadSummaryView: View {
private struct LoadingThreadView: View { private struct LoadingThreadView: View {
var body: some View { var body: some View {
ThreadView(senderID: "@alice:matrix.org", sender: nil, plainBody: "Hello world", formattedBody: nil) ThreadView(senderID: "@alice:matrix.org",
sender: nil,
plainBody: "Hello world",
formattedBody: nil,
numberOfReplies: 42)
.redacted(reason: .placeholder) .redacted(reason: .placeholder)
} }
} }
@@ -103,12 +118,17 @@ struct TimelineThreadSummaryView: View {
let sender: TimelineItemSender? let sender: TimelineItemSender?
let plainBody: String let plainBody: String
let formattedBody: AttributedString? let formattedBody: AttributedString?
let numberOfReplies: Int
var body: some View { var body: some View {
HStack(spacing: 8) { HStack(spacing: 4) {
CompoundIcon(\.threads, size: .xSmall, relativeTo: .compound.bodyXS) CompoundIcon(\.threads, size: .xSmall, relativeTo: .compound.bodyXS)
.foregroundColor(.compound.iconSecondary) .foregroundColor(.compound.iconSecondary)
Text(L10n.commonReplies(numberOfReplies))
.font(.compound.bodyXSSemibold)
.foregroundColor(.compound.textPrimary)
LoadableAvatarImage(url: sender?.avatarURL, LoadableAvatarImage(url: sender?.avatarURL,
name: sender?.displayName, name: sender?.displayName,
contentID: sender?.id, contentID: sender?.id,
@@ -121,13 +141,11 @@ struct TimelineThreadSummaryView: View {
.accessibilityLabel(L10n.commonInReplyTo(sender?.disambiguatedDisplayName ?? senderID)) .accessibilityLabel(L10n.commonInReplyTo(sender?.disambiguatedDisplayName ?? senderID))
Text(context.viewState.buildMessagePreview(formattedBody: formattedBody, plainBody: plainBody)) Text(context.viewState.buildMessagePreview(formattedBody: formattedBody, plainBody: plainBody))
.multilineTextAlignment(.leading)
.font(.compound.bodyXS) .font(.compound.bodyXS)
.foregroundColor(.compound.textSecondary) .foregroundColor(.compound.textSecondary)
.tint(.compound.textLinkExternal)
.lineLimit(2)
} }
.padding(.vertical, 4.0) .lineLimit(1)
.padding(.vertical, 7.0)
.padding(.horizontal, 8.0) .padding(.horizontal, 8.0)
.background(Color.compound.bgSubtlePrimary) .background(Color.compound.bgSubtlePrimary)
.cornerRadius(8) .cornerRadius(8)
@@ -183,12 +201,14 @@ struct TimelineThreadSummaryView_Previews: PreviewProvider, TestablePreview {
TimelineThreadSummaryView(threadSummary: .error(message: "Error")), TimelineThreadSummaryView(threadSummary: .error(message: "Error")),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice McAliceFace"),
latestEventContent: .message(.text(.init(body: "This is a threaded message"))))), latestEventContent: .message(.text(.init(body: "This is a very long, multi-lined, threaded message"))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.notice(.init(body: "Hello world"))))), latestEventContent: .message(.notice(.init(body: "Hello world"))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
@@ -198,7 +218,8 @@ struct TimelineThreadSummaryView_Previews: PreviewProvider, TestablePreview {
waveform: nil, waveform: nil,
source: nil, source: nil,
fileSize: nil, fileSize: nil,
contentType: nil))))), contentType: nil))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
@@ -207,24 +228,28 @@ struct TimelineThreadSummaryView_Previews: PreviewProvider, TestablePreview {
source: nil, source: nil,
fileSize: nil, fileSize: nil,
thumbnailSource: nil, thumbnailSource: nil,
contentType: nil))))), contentType: nil))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.image(.init(filename: "image.jpg", latestEventContent: .message(.image(.init(filename: "image.jpg",
caption: "Some image", caption: "Some image",
imageInfo: .mockImage, imageInfo: .mockImage,
thumbnailInfo: .mockThumbnail))))), thumbnailInfo: .mockThumbnail))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.video(.init(filename: "video.mp4", latestEventContent: .message(.video(.init(filename: "video.mp4",
caption: "Some video", caption: "Some video",
videoInfo: .mockVideo, videoInfo: .mockVideo,
thumbnailInfo: .mockVideoThumbnail))))), thumbnailInfo: .mockVideoThumbnail))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.location(.init(body: ""))))), latestEventContent: .message(.location(.init(body: ""))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
@@ -234,34 +259,43 @@ struct TimelineThreadSummaryView_Previews: PreviewProvider, TestablePreview {
waveform: nil, waveform: nil,
source: nil, source: nil,
fileSize: nil, fileSize: nil,
contentType: nil))))), contentType: nil))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .poll(question: "Do you like polls?"))), latestEventContent: .poll(question: "Do you like polls?"),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .redacted)), latestEventContent: .redacted,
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithMention))))), latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithMention))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithAtRoomMention))))), latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithAtRoomMention))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithRoomAliasMention))))), latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithRoomAliasMention))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithRoomIDMention))))), latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithRoomIDMention))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomIDMention))))), latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomIDMention))),
numberOfReplies: 42)),
TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org", TimelineThreadSummaryView(threadSummary: .loaded(senderID: "@alice:matrix.org",
sender: .init(id: "@alice:matrix.org", displayName: "Alice"), sender: .init(id: "@alice:matrix.org", displayName: "Alice"),
latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomAliasMention))))) latestEventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomAliasMention))),
numberOfReplies: 42))
] ]
} }

View File

@@ -21,6 +21,7 @@ enum EncryptionAuthenticity: Hashable {
case unverifiedIdentity(color: Color) case unverifiedIdentity(color: Color)
case verificationViolation(color: Color) case verificationViolation(color: Color)
case sentInClear(color: Color) case sentInClear(color: Color)
case mismatchedSender(color: Color)
var message: String { var message: String {
switch self { switch self {
@@ -36,6 +37,8 @@ enum EncryptionAuthenticity: Hashable {
L10n.eventShieldReasonPreviouslyVerified L10n.eventShieldReasonPreviouslyVerified
case .sentInClear: case .sentInClear:
L10n.eventShieldReasonSentInClear L10n.eventShieldReasonSentInClear
case .mismatchedSender:
L10n.eventShieldMismatchedSender
} }
} }
@@ -46,7 +49,8 @@ enum EncryptionAuthenticity: Hashable {
.unsignedDevice(let color), .unsignedDevice(let color),
.unverifiedIdentity(let color), .unverifiedIdentity(let color),
.verificationViolation(let color), .verificationViolation(let color),
.sentInClear(let color): .sentInClear(let color),
.mismatchedSender(let color):
color color
} }
} }
@@ -54,7 +58,7 @@ enum EncryptionAuthenticity: Hashable {
var icon: KeyPath<CompoundIcons, Image> { var icon: KeyPath<CompoundIcons, Image> {
switch self { switch self {
case .notGuaranteed: \.info case .notGuaranteed: \.info
case .unknownDevice, .unsignedDevice, .unverifiedIdentity, .verificationViolation: \.helpSolid case .unknownDevice, .unsignedDevice, .unverifiedIdentity, .verificationViolation, .mismatchedSender: \.helpSolid
case .sentInClear: \.lockOff case .sentInClear: \.lockOff
} }
} }
@@ -86,6 +90,8 @@ extension EncryptionAuthenticity {
self = .verificationViolation(color: color) self = .verificationViolation(color: color)
case .sentInClear: case .sentInClear:
self = .sentInClear(color: color) self = .sentInClear(color: color)
case .mismatchedSender:
self = .mismatchedSender(color: color)
} }
} }
} }

View File

@@ -10,6 +10,6 @@ import MatrixRustSDK
enum TimelineItemThreadSummary: Hashable { enum TimelineItemThreadSummary: Hashable {
case notLoaded case notLoaded
case loading case loading
case loaded(senderID: String, sender: TimelineItemSender, latestEventContent: TimelineEventContent) case loaded(senderID: String, sender: TimelineItemSender, latestEventContent: TimelineEventContent, numberOfReplies: Int)
case error(message: String) case error(message: String)
} }

View File

@@ -699,7 +699,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
return .loaded(senderID: senderID, return .loaded(senderID: senderID,
sender: sender, sender: sender,
latestEventContent: latestEventContent) latestEventContent: latestEventContent,
numberOfReplies: Int(threadSummary.numReplies()))
case .error(let message): case .error(let message):
return .error(message: message) return .error(message: message)

View File

@@ -1,4 +1,5 @@
{ {
"originHash" : "f818e663a0525244e7213b08a1bf75d9223d516b797de9b2d90b511c62dedc99",
"pins" : [ "pins" : [
{ {
"identity" : "swift-argument-parser", "identity" : "swift-argument-parser",
@@ -22,10 +23,10 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/Yams", "location" : "https://github.com/jpsim/Yams",
"state" : { "state" : {
"revision" : "9281f8c99aff4f4a55dce22ae29b1181c935caa5", "revision" : "7568d1c6c63a094405afb32264c57dc4e1435835",
"version" : "6.0.0" "version" : "6.0.1"
} }
} }
], ],
"version" : 2 "version" : 3
} }

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:bfe8a376d3de35ee8c5c87dbc8c2e76485294cda575cb95f4a477d0533619caa oid sha256:dd045932b14349f98ed11f488bf1dcc16e73a6f44432f004fa3466fe7cb7b6fc
size 2557843 size 2575000

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:797e94aa2584fd960f828e5e87c4207e1106e62be8254630a14406a5af7be6cf oid sha256:eb8a5e3c36fabd52fddb0fa298c0fbf6145f832311df1bc5201bab20016450ce
size 2556128 size 2585179

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:50bb8dd3931574e4464321f2020a2f5f5e7603655bcac2cf0f9b1456c667f257 oid sha256:58c42cded5458253bf570df2661c849d4a69c76fb83b884d9642a5425233f7ec
size 1273104 size 1255297

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:614e39891312cdeab5caca4e6ab3d35773bd1df4edfa4eb3e137794a067667fe oid sha256:9c1a75e26221738dc0ff905393f39aba7ab6629b36d777eb465c5b1b6bce957d
size 1270109 size 1251286

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:57e6b180bfb36b09a8037dbf51948e31aa14e11446beb80eb445a853bdb51924 oid sha256:4adc90edca8173a1808ac32a7b7dc314d79d1bde7e27699791b730ad73418282
size 204274 size 254752

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:9cfd71844e9650e4dddb3ae402d4d9637932866ed5e7ce47be06ec504c594c2a oid sha256:88220246ed9669d2c46d51a1f470b7f74812a96185cad0618ffc6831d01bc2f3
size 209066 size 285956

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:f7f03c9bef8f1893c319839f3564695742b9e53ae4205a290082f6cbe2512375 oid sha256:b494f40f2dd355953f8544e25f4acdafd639868060f61fb0172f9cc78c50e40c
size 142314 size 170440

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:f1aa50f59b5e3c3b1310ea0a196a4df4edb90ea9ab7ef8f4589c4962ee36cba6 oid sha256:83a41a7bc90881e60bfe03b236db6c3c30a1b2217d25e21174e3553d1d240b87
size 141379 size 190907

View File

@@ -65,7 +65,7 @@ packages:
# Element/Matrix dependencies # Element/Matrix dependencies
MatrixRustSDK: MatrixRustSDK:
url: https://github.com/element-hq/matrix-rust-components-swift url: https://github.com/element-hq/matrix-rust-components-swift
exactVersion: 25.06.12 exactVersion: 25.06.12-2
# path: ../matrix-rust-sdk # path: ../matrix-rust-sdk
Compound: Compound:
url: https://github.com/element-hq/compound-ios url: https://github.com/element-hq/compound-ios