From aa78d0eb221d825c72e49897cdefc4231b2b7541 Mon Sep 17 00:00:00 2001 From: Andrey Petrov Date: Mon, 3 Aug 2020 11:32:55 -0400 Subject: [PATCH] chat: Add /focus command Only show messages from focused users --- chat/command.go | 47 ++++++++++++++++++++++++++++++++++++++++++++ chat/message/user.go | 7 ++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/chat/command.go b/chat/command.go index 1869685..db88011 100644 --- a/chat/command.go +++ b/chat/command.go @@ -411,4 +411,51 @@ func InitCommands(c *Commands) { return nil }, }) + + c.Add(Command{ + Prefix: "/focus", + PrefixHelp: "[USER ...]", + Help: "Only show messages from focused users, or $ to reset.", + Handler: func(room *Room, msg message.CommandMsg) error { + ids := strings.TrimSpace(strings.TrimLeft(msg.Body(), "/focus")) + if ids == "" { + // Print focused names, if any. + var names []string + msg.From().Focused.Each(func(_ string, item set.Item) error { + names = append(names, item.Key()) + return nil + }) + + var systemMsg string + if len(names) == 0 { + systemMsg = "Unfocused." + } else { + systemMsg = fmt.Sprintf("Focusing on %d users: %s", len(names), strings.Join(names, ", ")) + } + + room.Send(message.NewSystemMsg(systemMsg, msg.From())) + return nil + } + + n := msg.From().Focused.Clear() + if ids == "$" { + room.Send(message.NewSystemMsg(fmt.Sprintf("Removed focus from %d users.", n), msg.From())) + return nil + } + + var focused []string + for _, name := range strings.Split(ids, " ") { + id := sanitize.Name(name) + if id == "" { + continue // Skip + } + focused = append(focused, id) + if err := msg.From().Focused.Set(set.Itemize(id, set.ZeroValue)); err != nil { + return err + } + } + room.Send(message.NewSystemMsg(fmt.Sprintf("Focusing: %s", strings.Join(focused, ", ")), msg.From())) + return nil + }, + }) } diff --git a/chat/message/user.go b/chat/message/user.go index 8e522d2..d1d862f 100644 --- a/chat/message/user.go +++ b/chat/message/user.go @@ -22,7 +22,8 @@ var ErrUserClosed = errors.New("user closed") // User definition, implemented set Item interface and io.Writer type User struct { Identifier - Ignored *set.Set + Ignored set.Interface + Focused set.Interface colorIdx int joined time.Time msg chan Message @@ -45,6 +46,7 @@ func NewUser(identity Identifier) *User { msg: make(chan Message, messageBuffer), done: make(chan struct{}), Ignored: set.New(), + Focused: set.New(), } u.setColorIdx(rand.Int()) @@ -175,6 +177,9 @@ func (u *User) render(m Message) string { return "" } out += m.RenderSelf(cfg) + } else if u.Focused.Len() > 0 && !u.Focused.In(m.From().ID()) { + // Skip message during focus + return "" } else { out += m.RenderFor(cfg) }