13 const messageBuffer = 5
14 const reHighlight = `\b(%s)\b`
16 var ErrUserClosed = errors.New("user closed")
18 // User definition, implemented set Item interface and io.Writer
27 replyTo *User // Set when user gets a /msg, for replying.
32 func NewUser(identity Identifier) *User {
35 Config: DefaultUserConfig,
37 msg: make(chan Message, messageBuffer),
38 done: make(chan struct{}),
40 u.SetColorIdx(rand.Int())
45 func NewUserScreen(identity Identifier, screen io.WriteCloser) *User {
46 u := NewUser(identity)
52 // Rename the user with a new Identifier.
53 func (u *User) SetId(id string) {
54 u.Identifier.SetId(id)
55 u.SetColorIdx(rand.Int())
58 // ReplyTo returns the last user that messaged this user.
59 func (u *User) ReplyTo() *User {
63 // SetReplyTo sets the last user to message this user.
64 func (u *User) SetReplyTo(user *User) {
68 // ToggleQuietMode will toggle whether or not quiet mode is enabled
69 func (u *User) ToggleQuietMode() {
70 u.Config.Quiet = !u.Config.Quiet
73 // SetColorIdx will set the colorIdx to a specific value, primarily used for
75 func (u *User) SetColorIdx(idx int) {
79 // Block until user is closed
80 func (u *User) Wait() {
84 // Disconnect user, stop accepting messages
85 func (u *User) Close() {
86 u.closeOnce.Do(func() {
90 // close(u.msg) TODO: Close?
95 // Consume message buffer into the handler. Will block, should be called in a
97 func (u *User) Consume() {
102 case m, ok := <-u.msg:
111 // Consume one message and stop, mostly for testing
112 func (u *User) ConsumeOne() Message {
116 // SetHighlight sets the highlighting regular expression to match string.
117 func (u *User) SetHighlight(s string) error {
118 re, err := regexp.Compile(fmt.Sprintf(reHighlight, s))
122 u.Config.Highlight = re
126 func (u *User) render(m Message) string {
127 switch m := m.(type) {
129 return m.RenderFor(u.Config) + Newline
131 u.SetReplyTo(m.From())
132 return m.Render(u.Config.Theme) + Newline
134 return m.Render(u.Config.Theme) + Newline
138 // HandleMsg will render the message to the screen, blocking.
139 func (u *User) HandleMsg(m Message) error {
141 _, err := u.screen.Write([]byte(r))
143 logger.Printf("Write failed to %s, closing: %s", u.Name(), err)
149 // Add message to consume by user
150 func (u *User) Send(m Message) error {
156 logger.Printf("Msg buffer full, closing: %s", u.Name())
163 // Container for per-user configurations.
164 type UserConfig struct {
165 Highlight *regexp.Regexp
171 // Default user configuration to use
172 var DefaultUserConfig UserConfig
175 DefaultUserConfig = UserConfig{
180 // TODO: Seed random?