diff --git a/chat/message/message.go b/chat/message/message.go index 01de0ce..79244eb 100644 --- a/chat/message/message.go +++ b/chat/message/message.go @@ -131,6 +131,9 @@ func (m PublicMsg) RenderFor(cfg UserConfig) string { // RenderSelf renders the message for when it's echoing your own message. func (m PublicMsg) RenderSelf(cfg UserConfig) string { + if cfg.Theme == nil { + return fmt.Sprintf("[%s] %s", m.from.Name(), m.body) + } return fmt.Sprintf("[%s] %s", cfg.Theme.ColorName(m.from), m.body) } diff --git a/chat/message/user.go b/chat/message/user.go index d4cc304..8e522d2 100644 --- a/chat/message/user.go +++ b/chat/message/user.go @@ -62,6 +62,12 @@ func (u *User) Joined() time.Time { return u.joined } +func (u *User) LastMsg() time.Time { + u.mu.Lock() + defer u.mu.Unlock() + return u.lastMsg +} + func (u *User) Config() UserConfig { u.mu.Lock() defer u.mu.Unlock() @@ -161,6 +167,10 @@ func (u *User) render(m Message) string { switch m := m.(type) { case PublicMsg: if u == m.From() { + u.mu.Lock() + u.lastMsg = m.Timestamp() + u.mu.Unlock() + if !cfg.Echo { return "" } @@ -204,9 +214,6 @@ func (u *User) writeMsg(m Message) error { // HandleMsg will render the message to the screen, blocking. func (u *User) HandleMsg(m Message) error { - u.mu.Lock() - u.lastMsg = m.Timestamp() - u.mu.Unlock() return u.writeMsg(m) } @@ -248,7 +255,9 @@ func init() { // TODO: Seed random? } -// RecentActiveUsers is a slice of *Users that knows how to be sorted by the time of the last message. +// RecentActiveUsers is a slice of *Users that knows how to be sorted by the +// time of the last message. If no message has been sent, then fall back to the +// time joined instead. type RecentActiveUsers []*User func (a RecentActiveUsers) Len() int { return len(a) } @@ -259,10 +268,15 @@ func (a RecentActiveUsers) Less(i, j int) bool { a[j].mu.Lock() defer a[j].mu.Unlock() - if a[i].lastMsg.IsZero() { - return a[i].joined.Before(a[j].joined) - } else { - return a[i].lastMsg.Before(a[j].lastMsg) + ai := a[i].lastMsg + if ai.IsZero() { + ai = a[i].joined } + aj := a[j].lastMsg + if aj.IsZero() { + aj = a[j].joined + } + + return ai.After(aj) } diff --git a/chat/room_test.go b/chat/room_test.go index c316e15..44c8f0c 100644 --- a/chat/room_test.go +++ b/chat/room_test.go @@ -388,17 +388,22 @@ func TestRoomNamesPrefix(t *testing.T) { } } + sendMsg := func(from *Member, body string) { + // lastMsg is set during render of self messags, so we can't use NewMsg + from.HandleMsg(message.NewPublicMsg(body, from.User)) + } + // Inject some activity - members[2].HandleMsg(message.NewMsg("hi")) // aac - members[0].HandleMsg(message.NewMsg("hi")) // aaa - members[3].HandleMsg(message.NewMsg("hi")) // foo - members[1].HandleMsg(message.NewMsg("hi")) // aab + sendMsg(members[2], "hi") // aac + sendMsg(members[0], "hi") // aaa + sendMsg(members[3], "hi") // foo + sendMsg(members[1], "hi") // aab if got, want := r.NamesPrefix("a"), []string{"aab", "aaa", "aac"}; !reflect.DeepEqual(got, want) { t.Errorf("got: %q; want: %q", got, want) } - members[2].HandleMsg(message.NewMsg("hi")) // aac + sendMsg(members[2], "hi") // aac if got, want := r.NamesPrefix("a"), []string{"aac", "aab", "aaa"}; !reflect.DeepEqual(got, want) { t.Errorf("got: %q; want: %q", got, want) }