Run SwiftFormat.

This commit is contained in:
Doug
2026-05-27 14:38:50 +01:00
committed by Doug
parent 5138e05e47
commit fa67713726
573 changed files with 2426 additions and 2426 deletions
@@ -100,7 +100,7 @@ enum RoomTimelineItemFixtures {
TextRoomTimelineItem(text: "How are you?",
senderDisplayName: "Alice")]
}
/// A small chunk of events, containing 2 text items.
static var smallChunkWithReadReceipts: [RoomTimelineItemProtocol] {
[TextRoomTimelineItem(text: "Hey there 👋",
@@ -219,17 +219,17 @@ enum RoomTimelineItemFixtures {
TextRoomTimelineItem(text: "Pork buffalo mollit culpa strip steak in leberkas flank cow.",
senderDisplayName: "Alice")]
}
static var disclosedPolls: [RoomTimelineItemProtocol] {
[PollRoomTimelineItem.mock(poll: .disclosed(), isOutgoing: false),
PollRoomTimelineItem.mock(poll: .endedDisclosed)]
}
static var undisclosedPolls: [RoomTimelineItemProtocol] {
[PollRoomTimelineItem.mock(poll: .undisclosed(), isOutgoing: false),
PollRoomTimelineItem.mock(poll: .endedUndisclosed)]
}
static var outgoingPolls: [RoomTimelineItemProtocol] {
[PollRoomTimelineItem.mock(poll: .disclosed(createdByAccountOwner: true), isOutgoing: true)]
}
@@ -12,7 +12,7 @@ import Foundation
/// A structure that parses a geo URI (i.e. geo:53.99803101552848,-8.25347900390625;u=10) and constructs their constituent parts.
struct GeoURI: Hashable {
// MARK: - Properties
let latitude: Double
let longitude: Double
let uncertainty: Double?
@@ -20,9 +20,9 @@ struct GeoURI: Hashable {
var bodyMessage: String {
"Location was shared at \(string)"
}
// MARK: - Setup
init?(string: String) {
guard let parsedURI = Self.parseGeoURI(from: string) else {
MXLog.warning("\(Self.self) failed to parse the string: \(string)")
@@ -30,13 +30,13 @@ struct GeoURI: Hashable {
}
self = parsedURI
}
init(latitude: Double, longitude: Double, uncertainty: Double? = nil) {
self.latitude = latitude
self.longitude = longitude
self.uncertainty = uncertainty
}
var string: String {
if let uncertainty {
return "geo:\(string(for: latitude)),\(string(for: longitude));u=\(string(for: uncertainty))"
@@ -44,9 +44,9 @@ struct GeoURI: Hashable {
return "geo:\(string(for: latitude)),\(string(for: longitude))"
}
}
// MARK: - Private
/// Parse a geo URI string like "geo:53.99803101552848,-8.25347900390625;u=10"
private static func parseGeoURI(from string: String) -> GeoURI? {
guard
@@ -56,11 +56,11 @@ struct GeoURI: Hashable {
else {
return nil
}
let uncertainty = matchOutput.uncertainty.flatMap(Double.init)
return .init(latitude: latitude, longitude: longitude, uncertainty: uncertainty)
}
private func string(for number: Double) -> String {
NumberFormatter.decimal.string(from: .init(floatLiteral: number)) ?? "\(number)"
}
@@ -27,7 +27,7 @@ class MockTimelineController: TimelineControllerProtocol {
var roomID: String {
roomProxy?.id ?? "MockRoomIdentifier"
}
var timelineKind: TimelineKind
let callbacks = PassthroughSubject<TimelineControllerCallback, Never>()
@@ -43,7 +43,7 @@ class MockTimelineController: TimelineControllerProtocol {
callbacks.send(.updatedTimelineItems(timelineItems: timelineItems, isSwitchingTimelines: false))
}
}
var timelineItemsTimestamp: [TimelineItemIdentifier: Date] = [:]
private var client: UITestsSignalling.Client?
@@ -120,7 +120,7 @@ class MockTimelineController: TimelineControllerProtocol {
func processItemAppearance(_ itemID: TimelineItemIdentifier) async { }
func processItemDisappearance(_ itemID: TimelineItemIdentifier) async { }
func toggleReaction(_ reaction: String, to eventID: TimelineItemIdentifier.EventOrTransactionID) async {
if let timelineProxy {
_ = await timelineProxy.toggleReaction(reaction, to: eventID)
@@ -173,7 +173,7 @@ class MockTimelineController: TimelineControllerProtocol {
func sendHandle(for itemID: TimelineItemIdentifier) -> SendHandleProxy? {
nil
}
func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date? {
timelineItemsTimestamp[itemID] ?? .now
}
@@ -328,7 +328,7 @@ class MockTimelineController: TimelineControllerProtocol {
}
return .success(())
}
// MARK: - UI Test signalling
/// The cancellable used for UI Tests signalling.
@@ -35,7 +35,7 @@ class TimelineController: TimelineControllerProtocol {
callbacks.send(.paginationState(paginationState))
}
}
var roomID: String {
roomProxy.id
}
@@ -128,7 +128,7 @@ class TimelineController: TimelineControllerProtocol {
guard let eventID = itemID.eventID else {
return
}
_ = await activeTimeline.sendReadReceipt(for: eventID, type: receiptType)
}
@@ -571,7 +571,7 @@ class TimelineController: TimelineControllerProtocol {
guard let eventID = timelineItem.id.eventID else {
return
}
switch timelineItem.properties.replyDetails {
case .notLoaded:
activeTimeline.fetchDetails(for: eventID)
@@ -11,7 +11,7 @@ import MatrixRustSDK
struct TimelineControllerFactory: TimelineControllerFactoryProtocol {
let appSettings: AppSettings
func buildTimelineController(roomProxy: JoinedRoomProxyProtocol,
initialFocussedEventID: String?,
timelineItemFactory: RoomTimelineItemFactoryProtocol,
@@ -80,7 +80,7 @@ protocol TimelineControllerProtocol: Sendable {
func removeCaption(_ eventOrTransactionID: TimelineItemIdentifier.EventOrTransactionID) async
func toggleReaction(_ reaction: String, to eventOrTransactionID: TimelineItemIdentifier.EventOrTransactionID) async
func redact(_ eventOrTransactionID: TimelineItemIdentifier.EventOrTransactionID) async
func pin(eventID: String) async
@@ -12,58 +12,58 @@ import MatrixRustSDK
class TimelineItemProvider: TimelineItemProviderProtocol {
private var cancellables = Set<AnyCancellable>()
private var roomTimelineObservationToken: TaskHandle?
/// Bridge from the SDK's synchronous callback into Swift Concurrency. Yielding is safe from any
/// thread; a single long-lived `for await` consumer (set up in `init`) applies the diffs on the
/// main actor in FIFO order, guaranteeing one in-flight update at a time.
private let diffContinuation: AsyncStream<[TimelineDiff]>.Continuation
private let paginationStateSubject = CurrentValueSubject<TimelinePaginationState, Never>(.initial)
var paginationState: TimelinePaginationState {
paginationStateSubject.value
}
private let itemProxiesSubject: CurrentValueSubject<[TimelineItemProxy], Never>
private(set) var itemProxies: [TimelineItemProxy] = [] {
didSet {
itemProxiesSubject.send(itemProxies)
}
}
var updatePublisher: AnyPublisher<([TimelineItemProxy], TimelinePaginationState), Never> {
itemProxiesSubject
.combineLatest(paginationStateSubject)
.eraseToAnyPublisher()
}
let kind: TimelineKind
private let membershipChangeSubject = PassthroughSubject<Void, Never>()
var membershipChangePublisher: AnyPublisher<Void, Never> {
membershipChangeSubject
.eraseToAnyPublisher()
}
deinit {
diffContinuation.finish()
roomTimelineObservationToken?.cancel()
}
init(timeline: Timeline, kind: TimelineKind, paginationStatePublisher: AnyPublisher<TimelinePaginationState, Never>) {
itemProxiesSubject = CurrentValueSubject<[TimelineItemProxy], Never>([])
self.kind = kind
let (diffStream, diffContinuation) = AsyncStream<[TimelineDiff]>.makeStream()
self.diffContinuation = diffContinuation
paginationStatePublisher
.sink { [weak self] in
self?.paginationStateSubject.send($0)
}
.store(in: &cancellables)
// `for await` guarantees FIFO ordering and that only one diff is being applied at a time.
// The stream also allows to handle the sendable items in the listener.
Task { [weak self] in
@@ -71,7 +71,7 @@ class TimelineItemProvider: TimelineItemProviderProtocol {
self?.updateItemsWithDiffs(diffs)
}
}
Task {
roomTimelineObservationToken = await timeline.addListener(listener: SDKListener { diffs in
diffContinuation.yield(diffs)
@@ -128,11 +128,11 @@ class TimelineItemProvider: TimelineItemProviderProtocol {
changes.append(.insert(offset: Int(index), element: itemProxy, associatedWith: nil))
case .popBack:
guard let itemProxy = itemProxies.last else { fatalError() }
changes.append(.remove(offset: itemProxies.count - 1, element: itemProxy, associatedWith: nil))
case .popFront:
guard let itemProxy = itemProxies.first else { fatalError() }
changes.append(.remove(offset: 0, element: itemProxy, associatedWith: nil))
case .pushBack(let item):
let itemProxy = TimelineItemProxy(item: item)
@@ -154,7 +154,7 @@ class TimelineItemProvider: TimelineItemProviderProtocol {
for (index, itemProxy) in itemProxies.enumerated() {
changes.append(.remove(offset: index, element: itemProxy, associatedWith: nil))
}
for (index, timelineItem) in items.enumerated() {
changes.append(.insert(offset: index, element: TimelineItemProxy(item: timelineItem), associatedWith: nil))
}
@@ -101,11 +101,11 @@ class EventTimelineItemProxy {
}()
lazy var canBeRepliedTo = item.canBeRepliedTo
lazy var content = item.content
lazy var isOwn = item.isOwn
lazy var isEditable = item.isEditable
lazy var sender = TimelineItemSender(senderID: item.sender, senderProfile: item.senderProfile)
@@ -192,11 +192,11 @@ struct SendHandleProxy: Hashable {
}
// MARK: - Hashable
static func == (lhs: SendHandleProxy, rhs: SendHandleProxy) -> Bool {
lhs.itemID == rhs.itemID
}
func hash(into hasher: inout Hasher) {
hasher.combine(itemID)
}
@@ -38,7 +38,7 @@ struct TimelineItemSender: Identifiable, Hashable {
avatarURL: nil)
}
}
var disambiguatedDisplayName: String? {
guard let displayName else {
return nil
@@ -26,11 +26,11 @@ extension EventBasedTimelineItemProtocol {
var description: String {
"\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)"
}
var isForwardable: Bool {
isRemoteMessage && !(self is PollRoomTimelineItem)
}
var isRemoteMessage: Bool {
id.eventID != nil
}
@@ -50,11 +50,11 @@ extension EventBasedTimelineItemProtocol {
var hasFailedToSend: Bool {
properties.deliveryStatus?.isSendingFailed == true
}
var hasFailedDecryption: Bool {
self is EncryptedRoomTimelineItem
}
var timelineMenuDescription: String {
switch self {
case is VoiceMessageRoomTimelineItem:
@@ -63,7 +63,7 @@ extension EventBasedTimelineItemProtocol {
return body.trimmingCharacters(in: .whitespacesAndNewlines)
}
}
/// The inline area to reserve at the trailing edge of the message text so the
/// bubble's natural size accommodates the timestamp (which is overlaid on the
/// bubble's bottom-trailing corner). Text wraps around this area: if it fits on
@@ -86,7 +86,7 @@ extension EventBasedTimelineItemProtocol {
width += 4
return CGSize(width: ceil(width), height: ceil(height))
}
/// contains the timestamp and an optional edited localised prefix
/// example: (edited) 12:17 PM
var localizedSendInfo: String {
@@ -96,12 +96,12 @@ extension EventBasedTimelineItemProtocol {
}
return start + timestamp.formattedTime()
}
var isCopyable: Bool {
guard let messageBasedItem = self as? EventBasedMessageTimelineItemProtocol else {
return false
}
switch messageBasedItem.contentType {
case .audio, .file, .image, .video, .location, .voice:
return false
@@ -19,7 +19,7 @@ struct AudioRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable {
let sender: TimelineItemSender
let content: AudioRoomTimelineItemContent
var properties = RoomTimelineItemProperties()
var body: String {
@@ -14,7 +14,7 @@ struct LiveLocationRoomTimelineItem: EventBasedTimelineItemProtocol, Equatable {
var body: String {
""
}
let timestamp: Date
let isOutgoing: Bool
let isEditable: Bool
@@ -16,15 +16,15 @@ struct LocationRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatabl
let canBeRepliedTo: Bool
let sender: TimelineItemSender
let content: LocationRoomTimelineItemContent
var properties = RoomTimelineItemProperties()
var body: String {
content.body
}
var contentType: EventBasedMessageTimelineItemContentType {
.location(content)
}
@@ -12,7 +12,7 @@ struct LocationRoomTimelineItemContent: Hashable {
let body: String
let geoURI: GeoURI?
let kind: StaticLocationKind
init(body: String,
geoURI: GeoURI? = nil,
kind: StaticLocationKind = .sender) {
@@ -18,7 +18,7 @@ struct VideoRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable {
var shouldBoost = false
let sender: TimelineItemSender
let content: VideoRoomTimelineItemContent
var properties = RoomTimelineItemProperties()
@@ -18,7 +18,7 @@ struct VoiceMessageRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equa
let sender: TimelineItemSender
let content: AudioRoomTimelineItemContent
var properties = RoomTimelineItemProperties()
var body: String {
@@ -29,11 +29,11 @@ struct Poll: Hashable {
let endDate: Date?
/// Whether the poll has been created by the account owner
let createdByAccountOwner: Bool
var hasEnded: Bool {
endDate != nil
}
enum Kind: Hashable {
case disclosed
case undisclosed
@@ -42,7 +42,7 @@ struct Poll: Hashable {
var hasMaxSelections: Bool {
options.filter(\.isSelected).count == maxSelections
}
struct Option: Hashable {
let id: String
let text: String
@@ -384,9 +384,9 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
let allVotes = votes.reduce(0) { count, pair in
count + pair.value.count
}
let maxOptionVotes = votes.map(\.value.count).max()
let options = answers.map { answer in
let optionVotesCount = votes[answer.id]?.count
@@ -404,7 +404,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
case .undisclosed:
.undisclosed
}
let poll = Poll(question: question,
kind: pollKind,
maxSelections: Int(maxSelections),
@@ -412,7 +412,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
votes: votes,
endDate: endTime.map { Date(timeIntervalSince1970: TimeInterval($0 / 1000)) },
createdByAccountOwner: eventItemProxy.sender.id == userID)
return PollRoomTimelineItem(id: eventItemProxy.id,
poll: poll,
body: poll.question,
@@ -538,7 +538,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
if let audioWaveform = messageContent.audio?.waveform {
waveform = EstimatedWaveform(data: audioWaveform)
}
return AudioRoomTimelineItemContent(filename: messageContent.filename,
caption: messageContent.caption,
formattedCaption: formattedCaption,
@@ -602,13 +602,13 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
blurhash: messageContent.info?.blurhash,
contentType: UTType(mimeType: messageContent.info?.mimetype, fallbackFilename: messageContent.filename))
}
private func buildLocationTimelineItemContent(_ locationContent: LocationContent) -> LocationRoomTimelineItemContent {
LocationRoomTimelineItemContent(body: locationContent.body,
geoURI: .init(string: locationContent.geoUri),
kind: .init(from: locationContent.asset))
}
private func buildFileTimelineItemContent(_ messageContent: FileMessageContent) -> FileRoomTimelineItemContent {
let htmlCaption = messageContent.formattedCaption?.format == .html ? messageContent.formattedCaption?.body : nil
let formattedCaption = htmlCaption != nil ? attributedStringBuilder.fromHTML(htmlCaption) : attributedStringBuilder.fromPlain(messageContent.caption)
@@ -636,7 +636,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
let name = senderDisplayName ?? senderID
let htmlBody = messageContent.formatted?.format == .html ? messageContent.formatted?.body : nil
var formattedBody: AttributedString?
if let htmlBody {
formattedBody = buildEmoteFormattedBodyFromHTML(html: htmlBody, name: name)
@@ -686,7 +686,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
return a.count > b.count
}
}
private func buildOrderedReadReceipts(_ receipts: [String: Receipt]) -> [ReadReceipt] {
receipts
.sorted { firstElement, secondElement in
@@ -25,7 +25,7 @@ struct RoomTimelineItemView: View {
context?.send(viewAction: .itemDisappeared(itemID: viewState.identifier))
}
}
@ViewBuilder private var timelineView: some View {
switch viewState.type {
case .text(let item):
@@ -12,17 +12,17 @@ import MatrixRustSDK
final class RoomTimelineItemViewState: Identifiable, Equatable, ObservableObject {
@Published var type: RoomTimelineItemType
@Published var groupStyle: TimelineGroupStyle
/// Contains all the identification info of the item, `uniqueID`, `eventID` and `transactionID`
var identifier: TimelineItemIdentifier {
type.id
}
init(type: RoomTimelineItemType, groupStyle: TimelineGroupStyle) {
self.type = type
self.groupStyle = groupStyle
}
convenience init(item: RoomTimelineItemProtocol, groupStyle: TimelineGroupStyle) {
self.init(type: .init(item: item), groupStyle: groupStyle)
}
@@ -70,7 +70,7 @@ enum RoomTimelineItemType: Equatable {
case callInvite(CallInviteRoomTimelineItem)
case callNotification(CallNotificationRoomTimelineItem)
case liveLocation(LiveLocationRoomTimelineItem)
init(item: RoomTimelineItemProtocol) {
switch item {
case let item as TextRoomTimelineItem:
@@ -123,7 +123,7 @@ enum RoomTimelineItemType: Equatable {
fatalError("Unknown timeline item")
}
}
var id: TimelineItemIdentifier {
switch self {
case .text(let item as RoomTimelineItemProtocol),
@@ -24,7 +24,7 @@ final class TimelineProxy: TimelineProxyProtocol {
private let forwardPaginationStateSubject = CurrentValueSubject<PaginationState, Never>(.endReached)
private let kind: TimelineKind
private var innerTimelineItemProvider: TimelineItemProviderProtocol!
var timelineItemProvider: TimelineItemProviderProtocol {
innerTimelineItemProvider
@@ -146,7 +146,7 @@ final class TimelineProxy: TimelineProxyProtocol {
case .forwards: try await timeline.paginateForwards(numEvents: requestSize)
}
MXLog.info("Finished paginating \(direction.rawValue)")
subject.send(timelineEndReached ? .endReached : .idle)
return .success(())
} catch {
@@ -170,7 +170,7 @@ final class TimelineProxy: TimelineProxyProtocol {
try await timeline.edit(eventOrTransactionId: eventOrTransactionID.rustValue, newContent: newContent)
MXLog.info("Finished editing timeline item: \(eventOrTransactionID)")
return .success(())
} catch {
MXLog.error("Failed editing timeline item: \(eventOrTransactionID) with error: \(error)")
@@ -412,10 +412,10 @@ final class TimelineProxy: TimelineProxyProtocol {
} else {
MXLog.error("Failed sending message with error: \(error)")
}
return .failure(.sdkError(error))
}
return .success(())
}
@@ -473,7 +473,7 @@ final class TimelineProxy: TimelineProxyProtocol {
}
// MARK: - Polls
func createPoll(question: String, answers: [String],
pollKind: Poll.Kind) async -> Result<Void, TimelineProxyError> {
MXLog.info("Creating poll")
@@ -528,7 +528,7 @@ final class TimelineProxy: TimelineProxyProtocol {
return .failure(.sdkError(error))
}
}
func sendPollResponse(pollStartID: String, answers: [String]) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending response for poll with eventID: \(pollStartID)")
@@ -543,7 +543,7 @@ final class TimelineProxy: TimelineProxyProtocol {
return .failure(.sdkError(error))
}
}
func buildMessageContentFor(_ message: String,
html: String?,
intentionalMentions: Mentions) -> RoomMessageEventContentWithoutRelation {