@@ -569,9 +569,18 @@ Summary: "who is connected to the BBS right now", Free: true,
Run: func(context.Context, *dispatch.Call) (*dispatch.Result, error) {
online := s.presence.List()
+ for i := range online {
+ if online[i].Anonymous {
+ online[i].Doing = "" // what a guest does stays theirs
+ }
+ }
lines := make([]string, 0, len(online))
for _, o := range online {
- lines = append(lines, fmt.Sprintf("%-16s %-4s %s", o.Nick, o.Where, ago(time.Since(o.Since))))
+ line := fmt.Sprintf("%-16s %-4s %s", o.Nick, o.Where, ago(time.Since(o.Since)))
+ if o.Doing != "" && !o.Anonymous {
+ line += " " + o.Doing
+ }
+ lines = append(lines, line)
}
if online == nil {
online = []community.Online{}
@@ -411,4 +411,7 @@ "BBS_RADIO_SHARED": "Recommended on the wall", "BBS_RADIO_PICKED": "%s is now on Hammer FM",
"AWARD_TUNED_IN": "Tuned in",
"AWARD_DJ": "DJ",
+ "BBS_WHERE_ALMANAC": "under the sky",
+ "BBS_WHERE_RADIO": "at the radio",
+ "BBS_LINECAST_DOING": "watching the %s",
}
@@ -289,6 +289,10 @@ where: community.WhereAlmanac, counter: awards.Almanac,
}
play.start = func(node int, deadline time.Time) (door.Session, error) {
+ if st.pres != nil {
+ defer st.pres.SetDoing(st.tf("BBS_LINECAST_DOING", st.t("BBS_LINECAST_"+strings.ToUpper(app))))
+ }
+
return door.Start(door.Spec{
Name: "linecast",
Program: lc.program,
@@ -48,6 +48,11 @@ if !waitWhere(srv, "ana", community.WhereAlmanac) {
t.Errorf("presence does not show ana in the almanac: %+v", srv.presence.List())
}
+ for _, o := range srv.presence.List() {
+ if o.Nick == "ana" && o.Doing != "olhando: lua" && o.Doing != "watching the moon" {
+ t.Errorf("doing = %q, want her watching the moon", o.Doing)
+ }
+ }
mark := ana.mark()
ana.send("q")
@@ -39,6 +39,7 @@ // liveOnline is one person on the live page. type liveOnline struct {
Nick string `json:"nick"`
Where string `json:"where"`
+ Doing string `json:"doing,omitempty"`
Since time.Time `json:"since"`
}
@@ -56,7 +57,7 @@ snap.Guests++
continue
}
- snap.Online = append(snap.Online, liveOnline{Nick: o.Nick, Where: o.Where, Since: o.Since.UTC().Truncate(time.Second)})
+ snap.Online = append(snap.Online, liveOnline{Nick: o.Nick, Where: o.Where, Doing: o.Doing, Since: o.Since.UTC().Truncate(time.Second)})
}
return snap
@@ -229,7 +230,7 @@ function show(snap) { list.replaceChildren();
for (const o of snap.online) {
const li = document.createElement('li');
- for (const [cls, text] of [['nick', o.nick], ['where', o.where], ['since', ago(o.since)]]) {
+ for (const [cls, text] of [['nick', o.nick], ['where', o.doing || o.where], ['since', ago(o.since)]]) {
const span = document.createElement('span');
span.className = cls; span.textContent = text; li.append(span);
}
@@ -0,0 +1,45 @@+package bbs
+
+import (
+ "encoding/json"
+ "strings"
+ "testing"
+
+ "github.com/runawaydevil/hammer/internal/community"
+)
+
+// Who is on, the node monitor and /:live show the radio and the sky, and
+// what people are listening to; a guest's never reaches the public page.
+func TestPresenceShowsRadioAndSky(t *testing.T) {
+ srv := testServer(t, &Config{Live: &LiveConfig{Enabled: true}})
+ ana := srv.presence.Join("fp:SHA256:ana", "ana", false)
+ ana.SetWhere(community.WhereRadio)
+ ana.SetDoing("listening to Jazz FM")
+ cia := srv.presence.Join("fp:SHA256:cia", "cia", false)
+ cia.SetWhere(community.WhereAlmanac)
+ cia.SetDoing("watching the moon")
+ guest := srv.presence.Join("anon:1", "guest-1", true)
+ guest.SetWhere(community.WhereRadio)
+ guest.SetDoing("listening to Secret Station")
+
+ bia := login(t, listen(t, srv), "bia", newSigner(t))
+ bia.send("w")
+ bia.send("o\r")
+ bia.waitFor("listening to Jazz FM")
+ bia.waitFor("watching the moon")
+ bia.waitFor("at the radio")
+ bia.waitFor("under the sky")
+
+ raw, _ := json.Marshal(srv.liveSnapshot())
+ if !strings.Contains(string(raw), "listening to Jazz FM") || !strings.Contains(string(raw), "watching the moon") {
+ t.Fatalf("/:live lacks what people are doing: %s", raw)
+ }
+ if strings.Contains(string(raw), "Secret Station") {
+ t.Fatalf("/:live shows a guest's station: %s", raw)
+ }
+
+ st := &session{}
+ if st.whereShort(community.WhereRadio) != "radio" || st.whereShort(community.WhereAlmanac) != "sky" {
+ t.Fatalf("node monitor: radio %q, almanac %q", st.whereShort(community.WhereRadio), st.whereShort(community.WhereAlmanac))
+ }
+}
@@ -405,5 +405,8 @@ "BBS_RADIO_RECOMMENDS": "♪ recommends %s (%s), find it in [o] on the air", "BBS_RADIO_SHARED": "Recommended on the wall",
"BBS_RADIO_PICKED": "%s is now on Hammer FM",
"AWARD_TUNED_IN": "Tuned in",
- "AWARD_DJ": "DJ"
+ "AWARD_DJ": "DJ",
+ "BBS_WHERE_ALMANAC": "under the sky",
+ "BBS_WHERE_RADIO": "at the radio",
+ "BBS_LINECAST_DOING": "watching the %s"
}
@@ -405,5 +405,8 @@ "BBS_RADIO_RECOMMENDS": "♪ recomenda %s (%s), está no [o] no ar", "BBS_RADIO_SHARED": "Recomendada no mural",
"BBS_RADIO_PICKED": "%s agora está na Hammer FM",
"AWARD_TUNED_IN": "Sintonizado",
- "AWARD_DJ": "DJ"
+ "AWARD_DJ": "DJ",
+ "BBS_WHERE_ALMANAC": "sob o céu",
+ "BBS_WHERE_RADIO": "no rádio",
+ "BBS_LINECAST_DOING": "olhando: %s"
}