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.
42 lines
1.4 KiB
Swift
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
|
|
}()
|
|
}
|