mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 14:27:27 +00:00
members: show joined date in admin + public lists; 'last active: X ago'
Admin Users view appends 'joined YYYY-MM-DD'. Public member directory shows 'last active: N days ago' for offline members plus the joined date, both sourced from store.User.CreatedAt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
28ad36834e
commit
042166b05f
2 changed files with 35 additions and 3 deletions
|
|
@ -344,6 +344,9 @@ func (m Model) viewUsers() (string, string) {
|
||||||
if u.EmailVerified {
|
if u.EmailVerified {
|
||||||
flags = append(flags, "verified")
|
flags = append(flags, "verified")
|
||||||
}
|
}
|
||||||
|
if !u.CreatedAt.IsZero() {
|
||||||
|
flags = append(flags, "joined "+u.CreatedAt.Format("2006-01-02"))
|
||||||
|
}
|
||||||
name := u.Name
|
name := u.Name
|
||||||
if u.Banned {
|
if u.Banned {
|
||||||
name = warnStyle.Render(name + " [BANNED]")
|
name = warnStyle.Render(name + " [BANNED]")
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ type person struct {
|
||||||
online bool
|
online bool
|
||||||
lastSeen time.Time
|
lastSeen time.Time
|
||||||
seenOK bool
|
seenOK bool
|
||||||
|
joined time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type model struct {
|
type model struct {
|
||||||
|
|
@ -92,7 +93,7 @@ func (m *model) load() tea.Cmd {
|
||||||
if u.Name == me {
|
if u.Name == me {
|
||||||
continue // don't list yourself in the directory
|
continue // don't list yourself in the directory
|
||||||
}
|
}
|
||||||
p := person{name: u.Name, kind: u.Kind, online: online[strings.ToLower(u.Name)]}
|
p := person{name: u.Name, kind: u.Kind, online: online[strings.ToLower(u.Name)], joined: u.CreatedAt}
|
||||||
if t, ok, _ := st.LastSeen(u.ID); ok {
|
if t, ok, _ := st.LastSeen(u.ID); ok {
|
||||||
p.lastSeen, p.seenOK = t, true
|
p.lastSeen, p.seenOK = t, true
|
||||||
}
|
}
|
||||||
|
|
@ -410,9 +411,12 @@ func (m *model) listView() string {
|
||||||
c = cur.Render("❯ ")
|
c = cur.Render("❯ ")
|
||||||
name = sel.Render(name)
|
name = sel.Render(name)
|
||||||
}
|
}
|
||||||
seen := "online"
|
seen := "online now"
|
||||||
if !p.online {
|
if !p.online {
|
||||||
seen = "last " + relTime(p.lastSeen, p.seenOK)
|
seen = "last active: " + relTimeLong(p.lastSeen, p.seenOK)
|
||||||
|
}
|
||||||
|
if !p.joined.IsZero() {
|
||||||
|
seen += " · joined " + p.joined.Format("2006-01-02")
|
||||||
}
|
}
|
||||||
row := fmt.Sprintf("%s%s %s %-20s %-8s %s", c, box, dot, name, p.kind, dim.Render(seen))
|
row := fmt.Sprintf("%s%s %s %-20s %-8s %s", c, box, dot, name, p.kind, dim.Render(seen))
|
||||||
s += row + "\n"
|
s += row + "\n"
|
||||||
|
|
@ -507,3 +511,28 @@ func relTime(t time.Time, ok bool) string {
|
||||||
return fmt.Sprintf("%dd", int(d.Hours()/24))
|
return fmt.Sprintf("%dd", int(d.Hours()/24))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// relTimeLong renders a spelled-out "3 days ago" / "2 hours ago" / "just now"
|
||||||
|
// age for the public directory. ok=false → "never".
|
||||||
|
func relTimeLong(t time.Time, ok bool) string {
|
||||||
|
if !ok || t.IsZero() {
|
||||||
|
return "never"
|
||||||
|
}
|
||||||
|
d := time.Since(t)
|
||||||
|
plural := func(n int, unit string) string {
|
||||||
|
if n == 1 {
|
||||||
|
return fmt.Sprintf("1 %s ago", unit)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d %ss ago", n, unit)
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case d < time.Minute:
|
||||||
|
return "just now"
|
||||||
|
case d < time.Hour:
|
||||||
|
return plural(int(d.Minutes()), "minute")
|
||||||
|
case d < 24*time.Hour:
|
||||||
|
return plural(int(d.Hours()), "hour")
|
||||||
|
default:
|
||||||
|
return plural(int(d.Hours()/24), "day")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue