diff options
author | Hubert Hirtz <hubert@hirtz.pm> | 2021-10-23 19:10:49 +0200 |
---|---|---|
committer | Hubert Hirtz <hubert@hirtz.pm> | 2021-10-23 19:10:49 +0200 |
commit | a3fb5135ee19fa8e9388654f5649529626f09207 (patch) | |
tree | e12b0c75282f46d97a9c03398869ed0e5190bca8 | |
parent | Don't panic when a command is sent when offline (diff) |
Make use of away-notify
-rw-r--r-- | irc/session.go | 36 | ||||
-rw-r--r-- | irc/tokens.go | 1 | ||||
-rw-r--r-- | ui/ui.go | 12 |
3 files changed, 42 insertions, 7 deletions
diff --git a/irc/session.go b/irc/session.go index b98b514..e0421a7 100644 --- a/irc/session.go +++ b/irc/session.go @@ -71,8 +71,8 @@ const ( // User is a known IRC user (we share a channel with it). type User struct { - Name *Prefix // the nick, user and hostname of the user if known. - AwayMsg string // the away message if the user is away, "" otherwise. + Name *Prefix // the nick, user and hostname of the user if known. + Away bool // whether the user is away or not } // Channel is a joined channel. @@ -217,6 +217,7 @@ func (s *Session) Names(channel string) []Member { names = append(names, Member{ PowerLevel: pl, Name: u.Name.Copy(), + Away: u.Away, }) } } @@ -581,14 +582,23 @@ func (s *Session) handleRegistered(msg Message) (Event, error) { } s.updateFeatures(msg.Params[1 : len(msg.Params)-1]) case rplWhoreply: - var nick, host string - if err := msg.ParseParams(nil, nil, nil, &host, nil, &nick); err != nil { + var nick, host, stats string + if err := msg.ParseParams(nil, nil, nil, &host, nil, &nick, &stats, nil); err != nil { return nil, err } - if s.nickCf == s.Casemap(nick) { + nickCf := s.Casemap(nick) + away := stats[0] == 'G' // stats is not empty because it's not the trailing parameter + + if s.nickCf == nickCf { s.host = host } + + if u, ok := s.users[nickCf]; ok { + u.Away = away + } + case rplEndofwho: + // do nothing case "CAP": var subcommand, caps string if err := msg.ParseParams(nil, &subcommand, &caps); err != nil { @@ -654,6 +664,12 @@ func (s *Session) handleRegistered(msg Message) (Event, error) { Name: msg.Params[0], Members: map[*User]string{}, } + if _, ok := s.enabledCaps["away-notify"]; ok { + // Only try to know who is away if the list is + // updated by the server via away-notify. + // Otherwise, it'll become outdated over time. + s.out <- NewMessage("WHO", channel) + } } else if c, ok := s.channels[channelCf]; ok { if _, ok := s.users[nickCf]; !ok { s.users[nickCf] = &User{Name: msg.Prefix.Copy()} @@ -893,6 +909,16 @@ func (s *Session) handleRegistered(msg Message) (Event, error) { Invitee: nick, Channel: channel, }, nil + case "AWAY": + if msg.Prefix == nil { + return nil, errMissingPrefix + } + + nickCf := s.Casemap(msg.Prefix.Name) + + if u, ok := s.users[nickCf]; ok { + u.Away = len(msg.Params) == 1 + } case "PRIVMSG", "NOTICE": if msg.Prefix == nil { return nil, errMissingPrefix diff --git a/irc/tokens.go b/irc/tokens.go index 1d0db1b..b9c87dd 100644 --- a/irc/tokens.go +++ b/irc/tokens.go @@ -463,6 +463,7 @@ func ParseCaps(caps string) (diff []Cap) { type Member struct { PowerLevel string Name *Prefix + Away bool } type members []Member @@ -370,7 +370,15 @@ func drawVerticalMemberList(screen tcell.Screen, x0, y0, width, height int, memb } else { x++ } - name := truncate(m.Name.Name, width-1, "\u2026") - printString(screen, &x, y, PlainString(name)) + + var name StyledString + nameText := truncate(m.Name.Name, width-1, "\u2026") + if m.Away { + name = Styled(nameText, tcell.StyleDefault.Foreground(tcell.ColorGray)) + } else { + name = PlainString(nameText) + } + + printString(screen, &x, y, name) } } |