summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Hirtz <hubert@hirtz.pm>2021-10-23 19:10:49 +0200
committerHubert Hirtz <hubert@hirtz.pm>2021-10-23 19:10:49 +0200
commita3fb5135ee19fa8e9388654f5649529626f09207 (patch)
treee12b0c75282f46d97a9c03398869ed0e5190bca8
parentDon't panic when a command is sent when offline (diff)
Make use of away-notify
-rw-r--r--irc/session.go36
-rw-r--r--irc/tokens.go1
-rw-r--r--ui/ui.go12
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
diff --git a/ui/ui.go b/ui/ui.go
index 31968f4..d1007cb 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -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)
}
}