chat/message: Set LastMsg during render of self public messages, fix sorting

Also fixed chat tests
This commit is contained in:
Andrey Petrov 2020-07-30 12:52:32 -04:00
parent 86b70a1fc7
commit 987a2e870a
3 changed files with 35 additions and 13 deletions

View File

@ -131,6 +131,9 @@ func (m PublicMsg) RenderFor(cfg UserConfig) string {
// RenderSelf renders the message for when it's echoing your own message. // RenderSelf renders the message for when it's echoing your own message.
func (m PublicMsg) RenderSelf(cfg UserConfig) string { 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) return fmt.Sprintf("[%s] %s", cfg.Theme.ColorName(m.from), m.body)
} }

View File

@ -62,6 +62,12 @@ func (u *User) Joined() time.Time {
return u.joined return u.joined
} }
func (u *User) LastMsg() time.Time {
u.mu.Lock()
defer u.mu.Unlock()
return u.lastMsg
}
func (u *User) Config() UserConfig { func (u *User) Config() UserConfig {
u.mu.Lock() u.mu.Lock()
defer u.mu.Unlock() defer u.mu.Unlock()
@ -161,6 +167,10 @@ func (u *User) render(m Message) string {
switch m := m.(type) { switch m := m.(type) {
case PublicMsg: case PublicMsg:
if u == m.From() { if u == m.From() {
u.mu.Lock()
u.lastMsg = m.Timestamp()
u.mu.Unlock()
if !cfg.Echo { if !cfg.Echo {
return "" return ""
} }
@ -204,9 +214,6 @@ func (u *User) writeMsg(m Message) error {
// HandleMsg will render the message to the screen, blocking. // HandleMsg will render the message to the screen, blocking.
func (u *User) HandleMsg(m Message) error { func (u *User) HandleMsg(m Message) error {
u.mu.Lock()
u.lastMsg = m.Timestamp()
u.mu.Unlock()
return u.writeMsg(m) return u.writeMsg(m)
} }
@ -248,7 +255,9 @@ func init() {
// TODO: Seed random? // 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 type RecentActiveUsers []*User
func (a RecentActiveUsers) Len() int { return len(a) } func (a RecentActiveUsers) Len() int { return len(a) }
@ -259,10 +268,15 @@ func (a RecentActiveUsers) Less(i, j int) bool {
a[j].mu.Lock() a[j].mu.Lock()
defer a[j].mu.Unlock() defer a[j].mu.Unlock()
if a[i].lastMsg.IsZero() { ai := a[i].lastMsg
return a[i].joined.Before(a[j].joined) if ai.IsZero() {
} else { ai = a[i].joined
return a[i].lastMsg.Before(a[j].lastMsg)
} }
aj := a[j].lastMsg
if aj.IsZero() {
aj = a[j].joined
}
return ai.After(aj)
} }

View File

@ -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 // Inject some activity
members[2].HandleMsg(message.NewMsg("hi")) // aac sendMsg(members[2], "hi") // aac
members[0].HandleMsg(message.NewMsg("hi")) // aaa sendMsg(members[0], "hi") // aaa
members[3].HandleMsg(message.NewMsg("hi")) // foo sendMsg(members[3], "hi") // foo
members[1].HandleMsg(message.NewMsg("hi")) // aab sendMsg(members[1], "hi") // aab
if got, want := r.NamesPrefix("a"), []string{"aab", "aaa", "aac"}; !reflect.DeepEqual(got, want) { if got, want := r.NamesPrefix("a"), []string{"aab", "aaa", "aac"}; !reflect.DeepEqual(got, want) {
t.Errorf("got: %q; want: %q", 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) { if got, want := r.NamesPrefix("a"), []string{"aac", "aab", "aaa"}; !reflect.DeepEqual(got, want) {
t.Errorf("got: %q; want: %q", got, want) t.Errorf("got: %q; want: %q", got, want)
} }