From f9a41fd4f322618b7d15314d7d4842afc5ed617c Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 11 May 2023 13:10:45 -0400 Subject: [PATCH] Show edit timestamps on statuses --- .../Sources/Pachyderm/Model/Status.swift | 3 +++ Tusker/CoreData/StatusMO.swift | 2 ++ .../Tusker.xcdatamodel/contents | 1 + ...ersationMainStatusCollectionViewCell.swift | 23 ++++++++++++++++--- .../TimelineStatusCollectionViewCell.swift | 3 ++- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Packages/Pachyderm/Sources/Pachyderm/Model/Status.swift b/Packages/Pachyderm/Sources/Pachyderm/Model/Status.swift index cec48c56bb..9a8db7c40e 100644 --- a/Packages/Pachyderm/Sources/Pachyderm/Model/Status.swift +++ b/Packages/Pachyderm/Sources/Pachyderm/Model/Status.swift @@ -41,6 +41,7 @@ public final class Status: StatusProtocol, Decodable, Sendable { public let poll: Poll? // Hometown, Glitch only public let localOnly: Bool? + public let editedAt: Date? public var applicationName: String? { application?.name } @@ -92,6 +93,7 @@ public final class Status: StatusProtocol, Decodable, Sendable { self.bookmarked = try container.decodeIfPresent(Bool.self, forKey: .bookmarked) self.card = try container.decodeIfPresent(Card.self, forKey: .card) self.poll = try container.decodeIfPresent(Poll.self, forKey: .poll) + self.editedAt = try container.decodeIfPresent(Date.self, forKey: .editedAt) } public static func getContext(_ statusID: String) -> Request { @@ -197,6 +199,7 @@ public final class Status: StatusProtocol, Decodable, Sendable { case card case poll case localOnly = "local_only" + case editedAt = "edited_at" } } diff --git a/Tusker/CoreData/StatusMO.swift b/Tusker/CoreData/StatusMO.swift index cdb14745f1..774f87264d 100644 --- a/Tusker/CoreData/StatusMO.swift +++ b/Tusker/CoreData/StatusMO.swift @@ -31,6 +31,7 @@ public final class StatusMO: NSManagedObject, StatusProtocol { @NSManaged public var cardData: Data? @NSManaged public var content: String @NSManaged public var createdAt: Date + @NSManaged public var editedAt: Date? @NSManaged private var emojisData: Data? @NSManaged public var favourited: Bool @NSManaged public var favouritesCount: Int @@ -113,6 +114,7 @@ extension StatusMO { self.card = status.card self.content = status.content self.createdAt = status.createdAt + self.editedAt = status.editedAt self.emojis = status.emojis self.favourited = status.favourited ?? false self.favouritesCount = status.favouritesCount diff --git a/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents b/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents index e89b9333e2..32419bcb75 100644 --- a/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents +++ b/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents @@ -89,6 +89,7 @@ + diff --git a/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift b/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift index 56a25d0380..c75a757d03 100644 --- a/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift @@ -154,6 +154,11 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status $0.adjustsFontForContentSizeCategory = true } + private let editTimestampButton = UIButton().configure { + $0.titleLabel!.adjustsFontForContentSizeCategory = true + $0.isPointerInteractionEnabled = true + } + private let firstSeparator = UIView().configure { $0.backgroundColor = .separator NSLayoutConstraint.activate([ @@ -171,6 +176,7 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status firstSeparator, actionsCountHStack, timestampAndClientLabel, + editTimestampButton, secondSeparator, ]).configure { $0.axis = .vertical @@ -341,21 +347,21 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status accountDetailAccessibilityElement.navigationDelegate = delegate accountDetailAccessibilityElement.accountID = accountID - let favoriteAndReblogAttributes = AttributeContainer([ + let metaButtonAttributes = AttributeContainer([ .font: ConversationMainStatusCollectionViewCell.metaFont ]) let favoritesFormat = NSLocalizedString("favorites count", comment: "conv main status favorites button label") var favoritesConfig = UIButton.Configuration.plain() favoritesConfig.baseForegroundColor = .secondaryLabel - favoritesConfig.attributedTitle = AttributedString(String.localizedStringWithFormat(favoritesFormat, status.favouritesCount), attributes: favoriteAndReblogAttributes) + favoritesConfig.attributedTitle = AttributedString(String.localizedStringWithFormat(favoritesFormat, status.favouritesCount), attributes: metaButtonAttributes) favoritesConfig.contentInsets = .zero favoritesCountButton.configuration = favoritesConfig let reblogsFormat = NSLocalizedString("reblogs count", comment: "conv main status reblogs button label") var reblogsConfig = UIButton.Configuration.plain() reblogsConfig.baseForegroundColor = .secondaryLabel - reblogsConfig.attributedTitle = AttributedString(String.localizedStringWithFormat(reblogsFormat, status.reblogsCount), attributes: favoriteAndReblogAttributes) + reblogsConfig.attributedTitle = AttributedString(String.localizedStringWithFormat(reblogsFormat, status.reblogsCount), attributes: metaButtonAttributes) reblogsConfig.contentInsets = .zero reblogsCountButton.configuration = reblogsConfig @@ -364,6 +370,17 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status timestampAndClientText += " • \(application)" } timestampAndClientLabel.text = timestampAndClientText + + if let editedAt = status.editedAt { + editTimestampButton.isHidden = false + var config = UIButton.Configuration.plain() + config.baseForegroundColor = .secondaryLabel + config.attributedTitle = AttributedString("Edited on \(ConversationMainStatusCollectionViewCell.dateFormatter.string(from: editedAt))", attributes: metaButtonAttributes) + config.contentInsets = .zero + editTimestampButton.configuration = config + } else { + editTimestampButton.isHidden = true + } } private func createObservers() { diff --git a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift index b0b4eef4f7..a7190f66b7 100644 --- a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift @@ -637,7 +637,8 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti // if there's a pending update timestamp work item, cancel it updateTimestampWorkItem?.cancel() - timestampLabel.text = status.createdAt.timeAgoString() + let timeAgo = status.createdAt.timeAgoString() + timestampLabel.text = "\(timeAgo)\(status.editedAt != nil ? "*" : "")" let delay: DispatchTimeInterval? switch status.createdAt.timeAgo().1 {