commit 0b64302783d46977b677cf3f2bb51204ce6ac81b
parent 646cb9ffcd01f9d2a9a7fc7e69b1044de5408b26
Author: Michael Camilleri <[email protected]>
Date: Thu, 30 Apr 2026 13:30:43 +0900
Tweak game list styling
Diffstat:
1 file changed, 75 insertions(+), 14 deletions(-)
diff --git a/Crossmate/Views/GameListView.swift b/Crossmate/Views/GameListView.swift
@@ -213,21 +213,12 @@ private struct GameRowView: View {
.foregroundStyle(.secondary)
}
}
- if let puzzleDate = game.puzzleDate {
- Text(puzzleDate, format: .dateTime.day().month(.abbreviated).year())
- .font(.footnote)
- }
- if let publisher = game.publisher {
- Text(publisher)
- .font(.caption)
- .foregroundStyle(.secondary)
- .lineLimit(1)
- .truncationMode(.tail)
- }
+ GameMetadataView(
+ puzzleDate: game.puzzleDate,
+ publisher: game.publisher
+ )
if let date = game.updatedAt {
- Text(date, format: Calendar.current.isDateInToday(date) ? .dateTime.hour().minute() : .dateTime.year().month().day())
- .font(.caption)
- .foregroundStyle(.secondary)
+ LastUpdatedView(date: date)
}
}
Spacer()
@@ -264,3 +255,73 @@ private struct GameRowView: View {
}
}
}
+
+private struct LastUpdatedView: View {
+ let date: Date
+
+ var body: some View {
+ Text(text)
+ .font(.caption)
+ .foregroundStyle(.secondary)
+ }
+
+ private var text: String {
+ let elapsed = max(0, Date().timeIntervalSince(date))
+ if elapsed < 60 {
+ let seconds = max(1, Int(elapsed.rounded(.down)))
+ return "Last updated \(seconds) \(seconds == 1 ? "second" : "seconds") ago"
+ }
+ if elapsed < 60 * 60 {
+ let minutes = Int((elapsed / 60).rounded(.down))
+ return "Last updated \(minutes) \(minutes == 1 ? "minute" : "minutes") ago"
+ }
+ if elapsed <= 48 * 60 * 60 {
+ let hours = Int((elapsed / (60 * 60)).rounded(.down))
+ return "Last updated \(hours) \(hours == 1 ? "hour" : "hours") ago"
+ }
+ return "Last updated on \(date.formatted(.dateTime.day().month(.abbreviated).year()))"
+ }
+}
+
+private struct GameMetadataView: View {
+ let puzzleDate: Date?
+ let publisher: String?
+
+ var body: some View {
+ if let puzzleDate, let publisher {
+ ViewThatFits(in: .horizontal) {
+ HStack(spacing: 0) {
+ Text(puzzleDate, format: .dateTime.day().month(.abbreviated).year())
+ Text(" • ")
+ Text(publisher)
+ }
+ .font(.footnote)
+ .lineLimit(1)
+
+ VStack(alignment: .leading, spacing: 2) {
+ puzzleDateView(puzzleDate)
+ publisherView(publisher)
+ }
+ }
+ } else {
+ if let puzzleDate {
+ puzzleDateView(puzzleDate)
+ }
+ if let publisher {
+ publisherView(publisher)
+ }
+ }
+ }
+
+ private func puzzleDateView(_ puzzleDate: Date) -> some View {
+ Text(puzzleDate, format: .dateTime.day().month(.abbreviated).year())
+ .font(.footnote)
+ }
+
+ private func publisherView(_ publisher: String) -> some View {
+ Text(publisher)
+ .font(.footnote)
+ .lineLimit(1)
+ .truncationMode(.tail)
+ }
+}