From 87dd859fed3c7a259f28ef770218cec6fb308a88 Mon Sep 17 00:00:00 2001 From: Andrey Petrov Date: Fri, 19 Jan 2018 13:35:37 -0500 Subject: [PATCH] /timestamp: Toggle timestamps after 30min of inactivity Closes #244 CC #194, #99, #242 --- chat/command.go | 20 ++++++++++++++++++++ chat/message/user.go | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/chat/command.go b/chat/command.go index e84350b..5d00a87 100644 --- a/chat/command.go +++ b/chat/command.go @@ -275,6 +275,26 @@ func InitCommands(c *Commands) { }, }) + c.Add(Command{ + Prefix: "/timestamp", + Help: "Timestamps after 30min of inactivity.", + Handler: func(room *Room, msg message.CommandMsg) error { + u := msg.From() + cfg := u.Config() + cfg.Timestamp = !cfg.Timestamp + u.SetConfig(cfg) + + var body string + if cfg.Timestamp { + body = "Timestamp is toggled ON" + } else { + body = "Timestamp is toggled OFF" + } + room.Send(message.NewSystemMsg(body, u)) + return nil + }, + }) + c.Add(Command{ Prefix: "/ignore", PrefixHelp: "[USER]", diff --git a/chat/message/user.go b/chat/message/user.go index d6f97fa..cc12ebc 100644 --- a/chat/message/user.go +++ b/chat/message/user.go @@ -15,6 +15,8 @@ import ( const messageBuffer = 5 const messageTimeout = 5 * time.Second const reHighlight = `\b(%s)\b` +const timestampTimeout = 30 * time.Minute +const timestampLayout = "2006-01-02 15:04:05 UTC" var ErrUserClosed = errors.New("user closed") @@ -32,7 +34,8 @@ type User struct { mu sync.Mutex config UserConfig - replyTo *User // Set when user gets a /msg, for replying. + replyTo *User // Set when user gets a /msg, for replying. + lastMsg time.Time // When the last message was rendered } func NewUser(identity Identifier) *User { @@ -164,8 +167,9 @@ func (u *User) render(m Message) string { } } -// HandleMsg will render the message to the screen, blocking. -func (u *User) HandleMsg(m Message) error { +// writeMsg renders the message and attempts to write it, will Close the user +// if it fails. +func (u *User) writeMsg(m Message) error { r := u.render(m) _, err := u.screen.Write([]byte(r)) if err != nil { @@ -175,6 +179,26 @@ func (u *User) HandleMsg(m Message) error { return err } +// HandleMsg will render the message to the screen, blocking. +func (u *User) HandleMsg(m Message) error { + u.mu.Lock() + cfg := u.config + lastMsg := u.lastMsg + u.lastMsg = m.Timestamp() + injectTimestamp := !lastMsg.IsZero() && cfg.Timestamp && u.lastMsg.Sub(lastMsg) > timestampTimeout + u.mu.Unlock() + + if injectTimestamp { + // Inject a timestamp at most once every timestampTimeout between message intervals + ts := NewSystemMsg(fmt.Sprintf("Timestamp: %s", m.Timestamp().UTC().Format(timestampLayout)), u) + if err := u.writeMsg(ts); err != nil { + return err + } + } + + return u.writeMsg(m) +} + // Add message to consume by user func (u *User) Send(m Message) error { select { @@ -194,6 +218,7 @@ type UserConfig struct { Highlight *regexp.Regexp Bell bool Quiet bool + Timestamp bool Theme *Theme } @@ -202,8 +227,9 @@ var DefaultUserConfig UserConfig func init() { DefaultUserConfig = UserConfig{ - Bell: true, - Quiet: false, + Bell: true, + Quiet: false, + Timestamp: false, } // TODO: Seed random?