crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit 7783a5912a43962ce91c9e4b640d78354c1fe784
parent 86f3bee7034f96697b99ad06d1a6c9e38cb06c50
Author: Michael Camilleri <[email protected]>
Date:   Fri,  1 May 2026 07:04:35 +0900

Make last update time update live

This commit causes the last updated time in the game list view to update
live.

Co-Authored-By: Claude Opus 4.7 <[email protected]>

Diffstat:
MCrossmate/Views/GameListView.swift | 42+++++++++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/Crossmate/Views/GameListView.swift b/Crossmate/Views/GameListView.swift @@ -276,13 +276,15 @@ private struct LastUpdatedView: View { let usesRoomierType: Bool var body: some View { - Text(text) - .font(usesRoomierType ? .footnote : .caption) - .foregroundStyle(.secondary) + TimelineView(.lastUpdated(from: date)) { context in + Text(text(now: context.date)) + .font(usesRoomierType ? .footnote : .caption) + .foregroundStyle(.secondary) + } } - private var text: String { - let elapsed = max(0, Date().timeIntervalSince(date)) + private func text(now: Date) -> String { + let elapsed = max(0, now.timeIntervalSince(date)) if elapsed < 60 { let seconds = max(1, Int(elapsed.rounded(.down))) return "Last updated \(seconds) \(seconds == 1 ? "second" : "seconds") ago" @@ -299,6 +301,36 @@ private struct LastUpdatedView: View { } } +private struct LastUpdatedSchedule: TimelineSchedule { + let anchor: Date + + func entries(from startDate: Date, mode: TimelineScheduleMode) -> AnyIterator<Date> { + var next = startDate + return AnyIterator { + let current = next + let elapsed = max(0, current.timeIntervalSince(anchor)) + let step: TimeInterval + if elapsed < 60 { + step = 1 + } else if elapsed < 60 * 60 { + step = 60 + } else if elapsed <= 48 * 60 * 60 { + step = 60 * 60 + } else { + return nil + } + next = current.addingTimeInterval(step) + return current + } + } +} + +extension TimelineSchedule where Self == LastUpdatedSchedule { + static func lastUpdated(from date: Date) -> LastUpdatedSchedule { + LastUpdatedSchedule(anchor: date) + } +} + private struct GameMetadataView: View { let puzzleDate: Date? let publisher: String?