13 const messageBuffer = 20
14 const reHighlight = `\b(%s)\b`
16 var ErrUserClosed = errors.New("user closed")
18 // User definition, implemented set Item interface and io.Writer
26 replyTo *User // Set when user gets a /msg, for replying.
31 func NewUser(identity Identifier) *User {
34 Config: *DefaultUserConfig,
36 msg: make(chan Message, messageBuffer),
37 done: make(chan struct{}, 1),
39 u.SetColorIdx(rand.Int())
44 func NewUserScreen(identity Identifier, screen io.Writer) *User {
45 u := NewUser(identity)
51 // Rename the user with a new Identifier.
52 func (u *User) SetId(id string) {
53 u.Identifier.SetId(id)
54 u.SetColorIdx(rand.Int())
57 // ReplyTo returns the last user that messaged this user.
58 func (u *User) ReplyTo() *User {
62 // SetReplyTo sets the last user to message this user.
63 func (u *User) SetReplyTo(user *User) {
67 // ToggleQuietMode will toggle whether or not quiet mode is enabled
68 func (u *User) ToggleQuietMode() {
69 u.Config.Quiet = !u.Config.Quiet
72 // SetColorIdx will set the colorIdx to a specific value, primarily used for
74 func (u *User) SetColorIdx(idx int) {
78 // Block until user is closed
79 func (u *User) Wait() {
83 // Disconnect user, stop accepting messages
84 func (u *User) Close() {
85 u.closeOnce.Do(func() {
92 // Consume message buffer into an io.Writer. Will block, should be called in a
94 // TODO: Not sure if this is a great API.
95 func (u *User) Consume(out io.Writer) {
96 for m := range u.msg {
101 // Consume one message and stop, mostly for testing
102 func (u *User) ConsumeChan() <-chan Message {
106 // SetHighlight sets the highlighting regular expression to match string.
107 func (u *User) SetHighlight(s string) error {
108 re, err := regexp.Compile(fmt.Sprintf(reHighlight, s))
112 u.Config.Highlight = re
116 func (u *User) render(m Message) string {
117 switch m := m.(type) {
119 return m.RenderFor(u.Config) + Newline
121 u.SetReplyTo(m.From())
122 return m.Render(u.Config.Theme) + Newline
124 return m.Render(u.Config.Theme) + Newline
128 func (u *User) HandleMsg(m Message, out io.Writer) {
130 _, err := out.Write([]byte(r))
132 logger.Printf("Write failed to %s, closing: %s", u.Name(), err)
137 // Add message to consume by user
138 func (u *User) Send(m Message) error {
146 logger.Printf("Msg buffer full, closing: %s", u.Name())
153 // Container for per-user configurations.
154 type UserConfig struct {
155 Highlight *regexp.Regexp
161 // Default user configuration to use
162 var DefaultUserConfig *UserConfig
165 DefaultUserConfig = &UserConfig{
170 // TODO: Seed random?