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")
var out string
switch m := m.(type) {
case PublicMsg:
- out += m.RenderFor(cfg)
+ if u == m.From() {
+ if !cfg.Echo {
+ return ""
+ }
+ out += m.RenderSelf(cfg)
+ } else {
+ out += m.RenderFor(cfg)
+ }
case *PrivateMsg:
out += m.Render(cfg.Theme)
if cfg.Bell {
out += Bel
}
+ case *CommandMsg:
+ out += m.RenderSelf(cfg)
default:
out += m.Render(cfg.Theme)
}
- if cfg.Timestamp {
- return cfg.Theme.Timestamp(m.Timestamp()) + " " + out + Newline
+ if cfg.Timeformat != nil {
+ ts := m.Timestamp()
+ if cfg.Timezone != nil {
+ ts = ts.In(cfg.Timezone)
+ } else {
+ ts = ts.UTC()
+ }
+ return cfg.Theme.Timestamp(ts.Format(*cfg.Timeformat)) + " " + out + Newline
}
return out + Newline
}
// 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)
}
// Container for per-user configurations.
type UserConfig struct {
- Highlight *regexp.Regexp
- Bell bool
- Quiet bool
- Timestamp bool
- Theme *Theme
+ Highlight *regexp.Regexp
+ Bell bool
+ Quiet bool
+ Echo bool // Echo shows your own messages after sending, disabled for bots
+ Timeformat *string
+ Timezone *time.Location
+ Theme *Theme
}
// Default user configuration to use
func init() {
DefaultUserConfig = UserConfig{
- Bell: true,
- Quiet: false,
- Timestamp: false,
+ Bell: true,
+ Echo: true,
+ Quiet: false,
}
// TODO: Seed random?
}
+
+// RecentActiveUsers is a slice of *Users that knows how to be sorted by the time of the last message.
+type RecentActiveUsers []*User
+
+func (a RecentActiveUsers) Len() int { return len(a) }
+func (a RecentActiveUsers) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a RecentActiveUsers) Less(i, j int) bool {
+ a[i].mu.Lock()
+ defer a[i].mu.Unlock()
+ 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)
+ }
+
+}