mirror of
https://github.com/mastodon/mastodon-ios
synced 2025-04-11 22:58:02 +02:00
Regularly update the time-elapsed stamps in the notification views
Contributes to #399 [BUG] Multiple interactions do not collapse into a single notification
This commit is contained in:
parent
77f81e5849
commit
6783182e21
@ -51,6 +51,8 @@ final public class GroupedNotificationFeedLoader {
|
||||
return cacheManager?.currentLastReadMarker
|
||||
}
|
||||
|
||||
private let timestampUpdater = TimestampUpdater(TimeInterval(30))
|
||||
|
||||
private var isFetching: Bool = false
|
||||
|
||||
public let useGroupedNotificationsApi: Bool
|
||||
@ -319,7 +321,7 @@ extension GroupedNotificationFeedLoader {
|
||||
|
||||
if let ungrouped = results as? [Mastodon.Entity.Notification] {
|
||||
return NotificationRowViewModel.viewModelsFromUngroupedNotifications(
|
||||
ungrouped, myAccountID: authenticationBox.userID,
|
||||
ungrouped, timestamper: timestampUpdater, myAccountID: authenticationBox.userID,
|
||||
myAccountDomain: authenticationBox.domain,
|
||||
navigateToScene: navigateToScene ?? { _, _ in },
|
||||
presentError: presentError ?? { _ in }
|
||||
@ -328,6 +330,7 @@ extension GroupedNotificationFeedLoader {
|
||||
return NotificationRowViewModel
|
||||
.viewModelsFromGroupedNotificationResults(
|
||||
grouped,
|
||||
timestamper: timestampUpdater,
|
||||
myAccountID: authenticationBox.userID,
|
||||
myAccountDomain: authenticationBox.domain,
|
||||
navigateToScene: navigateToScene ?? { _, _ in },
|
||||
@ -363,3 +366,16 @@ extension NotificationRowViewModel: Hashable {
|
||||
hasher.combine(identifier)
|
||||
}
|
||||
}
|
||||
|
||||
class TimestampUpdater: ObservableObject {
|
||||
@Published var timestamp: Date = .now
|
||||
private var timer: Timer?
|
||||
|
||||
init(_ interval: TimeInterval) {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true, block: { [weak self] _ in
|
||||
Task { @MainActor in
|
||||
self?.timestamp = .now
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -532,6 +532,12 @@ let actionSuperheaderHeight: CGFloat = 20
|
||||
|
||||
struct NotificationRowView: View {
|
||||
@ObservedObject var viewModel: NotificationRowViewModel
|
||||
@ObservedObject var timestamper: TimestampUpdater
|
||||
|
||||
init(viewModel: NotificationRowViewModel) {
|
||||
self.viewModel = viewModel
|
||||
self.timestamper = viewModel.timestampUpdater
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .top, spacing: avatarSpacing) {
|
||||
@ -602,7 +608,7 @@ struct NotificationRowView: View {
|
||||
Text(string)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
case .timeSinceLabel(let date):
|
||||
Text(date.localizedExtremelyAbbreviatedTimeElapsedUntilNow)
|
||||
Text(date.localizedExtremelyAbbreviatedTimeElapsedUntil(now: timestamper.timestamp))
|
||||
.font(.subheadline)
|
||||
.frame(height: actionSuperheaderHeight)
|
||||
.fixedSize(horizontal: true, vertical: false)
|
||||
@ -628,7 +634,7 @@ struct NotificationRowView: View {
|
||||
HStack(alignment: .top, spacing: 2) {
|
||||
Text(string)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(date.localizedExtremelyAbbreviatedTimeElapsedUntilNow)
|
||||
Text(date.localizedExtremelyAbbreviatedTimeElapsedUntil(now: timestamper.timestamp))
|
||||
.font(.subheadline)
|
||||
.frame(height: actionSuperheaderHeight)
|
||||
.fixedSize(horizontal: true, vertical: false)
|
||||
|
@ -11,6 +11,7 @@ import SwiftUICore
|
||||
class NotificationRowViewModel: ObservableObject {
|
||||
let identifier: MastodonFeedItemIdentifier
|
||||
let timestamp: Date?
|
||||
let timestampUpdater: TimestampUpdater
|
||||
let oldestID: String?
|
||||
let newestID: String?
|
||||
let type: GroupedNotificationType
|
||||
@ -45,6 +46,7 @@ class NotificationRowViewModel: ObservableObject {
|
||||
|
||||
init(
|
||||
_ notificationInfo: GroupedNotificationInfo,
|
||||
timestamper: TimestampUpdater,
|
||||
myAccountDomain: String,
|
||||
navigateToScene: @escaping (
|
||||
SceneCoordinator.Scene, SceneCoordinator.Transition
|
||||
@ -53,6 +55,7 @@ class NotificationRowViewModel: ObservableObject {
|
||||
|
||||
self.identifier = .notificationGroup(id: notificationInfo.id)
|
||||
self.timestamp = notificationInfo.timestamp
|
||||
self.timestampUpdater = timestamper
|
||||
self.oldestID = notificationInfo.oldestNotificationID
|
||||
self.newestID = notificationInfo.newestNotificationID
|
||||
self.type = notificationInfo.groupedNotificationType
|
||||
@ -526,6 +529,7 @@ extension NotificationRowViewModel {
|
||||
extension NotificationRowViewModel {
|
||||
static func viewModelsFromGroupedNotificationResults(
|
||||
_ results: Mastodon.Entity.GroupedNotificationsResults,
|
||||
timestamper: TimestampUpdater,
|
||||
myAccountID: String,
|
||||
myAccountDomain: String,
|
||||
navigateToScene: @escaping (
|
||||
@ -607,7 +611,7 @@ extension NotificationRowViewModel {
|
||||
)
|
||||
|
||||
return NotificationRowViewModel(
|
||||
info, myAccountDomain: myAccountDomain,
|
||||
info, timestamper: timestamper, myAccountDomain: myAccountDomain,
|
||||
navigateToScene: navigateToScene,
|
||||
presentError: presentError)
|
||||
}
|
||||
@ -615,6 +619,7 @@ extension NotificationRowViewModel {
|
||||
|
||||
static func viewModelsFromUngroupedNotifications(
|
||||
_ notifications: [Mastodon.Entity.Notification],
|
||||
timestamper: TimestampUpdater,
|
||||
myAccountID: String,
|
||||
myAccountDomain: String,
|
||||
navigateToScene: @escaping (
|
||||
@ -675,7 +680,7 @@ extension NotificationRowViewModel {
|
||||
)
|
||||
|
||||
return NotificationRowViewModel(
|
||||
info, myAccountDomain: myAccountDomain,
|
||||
info, timestamper: timestamper, myAccountDomain: myAccountDomain,
|
||||
navigateToScene: navigateToScene,
|
||||
presentError: presentError)
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ extension Date {
|
||||
return Date.relativeTimestampFormatter.localizedString(for: self, relativeTo: Date())
|
||||
}
|
||||
|
||||
public var localizedExtremelyAbbreviatedTimeElapsedUntilNow: String {
|
||||
let interval = Date.now.timeIntervalSince(self)
|
||||
public func localizedExtremelyAbbreviatedTimeElapsedUntil(now: Date) -> String {
|
||||
let interval = now.timeIntervalSince(self)
|
||||
guard interval > TimeInterval(integerLiteral: 60) else { return "now" }
|
||||
return extremeDateAbbreviatingFormatter.string(from: interval) ?? ""
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user