Files
luma/Sources/LumaCore/RelativeTime.swift
Ole André Vadla Ravnås 235b978234 Add lab title and render times relatively
Every lab now has a title. On .create the client mints one from
the owner's local timezone — "<Weekday> <morning|afternoon|
evening|night> <verb>" with verb ∈ {reversing, tracing, hacking,
spelunking, poking, sleuthing, dissecting} — so the first thing
everyone sees is something like "Friday evening spelunking"
instead of an opaque id. Owners rename at any time via a pencil
button in the CollaborationPanel (SwiftUI inline field on Mac,
inline Entry on GTK); the server broadcasts +update on
/labs/<id> so every connected client gets the new title live.

Separately, all visible timestamps switch to a coarse "time ago"
form ("just now", "5 min ago", "2 hr ago", "yesterday", "3 days
ago", "last week"). A shared `LumaCore.RelativeTime.string(from:)`
helper keeps Mac and GTK consistent; the absolute timestamp lives
on as a tooltip for anyone who needs it. Event stream / REPL
cells keep their absolute high-precision times since those are
high-volume and the exact value matters.
2026-04-20 09:54:46 +02:00

42 lines
1.4 KiB
Swift

import Foundation
/// Compact, UI-friendly "time ago" strings. Bucketed so the numbers
/// don't churn on every tick: rounding is coarse for older timestamps
/// because the exact value stops mattering the further out you go.
///
/// Examples: "just now", "5 min ago", "2 hr ago", "yesterday",
/// "3 days ago", "last week", "Jan 5".
public enum RelativeTime {
public static func string(from date: Date, now: Date = .now) -> String {
let interval = now.timeIntervalSince(date)
if interval < 0 { return "just now" }
let seconds = Int(interval)
if seconds < 45 { return "just now" }
if seconds < 90 { return "1 min ago" }
let minutes = seconds / 60
if minutes < 60 { return "\(minutes) min ago" }
let hours = minutes / 60
if hours < 22 { return "\(hours) hr ago" }
let days = Int(interval / 86_400)
if days < 1 { return "yesterday" }
if days == 1 { return "yesterday" }
if days < 7 { return "\(days) days ago" }
if days < 14 { return "last week" }
if days < 30 { return "\(days / 7) weeks ago" }
let formatter = Self.absoluteFormatter
return formatter.string(from: date)
}
private static let absoluteFormatter: DateFormatter = {
let f = DateFormatter()
f.locale = Locale(identifier: "en_US_POSIX")
f.dateFormat = "MMM d"
return f
}()
}