diff --git a/main.lua b/main.lua index 8e53a3d..9241a0a 100644 --- a/main.lua +++ b/main.lua @@ -95,6 +95,12 @@ function IrcChatView:ensureBuffer(target) if self._unread[target] == nil then self._unread[target] = 0 end + if target:sub(1,1) == "#" then + self._members = self._members or {} + if not self._members[target] then + self._members[target] = {} + end + end end function IrcChatView:switchTarget(target) @@ -335,6 +341,11 @@ function IrcChatView:handleLine(line) local nick = prefix:match("^([^!]+)!") or prefix if target:sub(1,1) == "#" then self:appendLine(string.format("<%s> %s", nick, msg), target) + -- track speaker as member + self:ensureBuffer(target) + self._members = self._members or {} + self._members[target] = self._members[target] or {} + self._members[target][nick] = true else -- PM to us self:appendLine(string.format("[%s -> you] %s", nick, msg), nick) @@ -345,7 +356,8 @@ function IrcChatView:handleLine(line) local target, msg = rest:match("^(%S+)%s+:(.+)$") if msg then local nick = prefix and (prefix:match("^([^!]+)!") or prefix) or "*" - self:appendLine(string.format("-%s- %s", nick, msg)) + local tgt = (target and target:sub(1,1) == "#") and target or nil + self:appendLine(string.format("-%s- %s", nick, msg), tgt) return end elseif command == "JOIN" then @@ -359,6 +371,10 @@ function IrcChatView:handleLine(line) self:switchTarget(ch) end end + self:ensureBuffer(ch) + self._members = self._members or {} + self._members[ch] = self._members[ch] or {} + self._members[ch][nick] = true end return elseif command == "PART" then @@ -366,16 +382,36 @@ function IrcChatView:handleLine(line) local ch, msg = rest:match("^(%S+)%s*:?(.*)$") if ch then self:appendLine(string.format("* %s left %s %s", nick, ch, msg or ""), ch) + if self._members and self._members[ch] then + self._members[ch][nick] = nil + end end return elseif command == "QUIT" then local nick = prefix:match("^([^!]+)!") or prefix local msg = rest:match("^:(.+)$") or "" - self:appendLine(string.format("* %s quit %s", nick, msg)) + local shown = false + if self._members then + for ch, set in pairs(self._members) do + if set[nick] then + self:appendLine(string.format("* %s quit %s", nick, msg), ch) + set[nick] = nil + shown = true + end + end + end + -- If not shown anywhere, drop it to avoid cross-channel noise return elseif command == "353" then -- RPL_NAMREPLY local nickmode, chan, names = rest:match("^(%S+)%s+=%s+(%S+)%s+:(.+)$") if names then + self:ensureBuffer(chan) + self._members = self._members or {} + self._members[chan] = self._members[chan] or {} + for name in names:gmatch("%S+") do + local clean = name:gsub("^[~&@%+%%]", "") + self._members[chan][clean] = true + end self:appendLine(T(_("Users: %1"), names), chan) end return @@ -392,6 +428,22 @@ function IrcChatView:handleLine(line) self:sendRaw(string.format("JOIN %s\r\n", self._pending_join)) end return + elseif command == "NICK" then -- self or others changed nick + local newnick = rest:match("^:(.+)$") or rest + local oldnick = prefix:match("^([^!]+)!") or prefix + if oldnick == self._nick and newnick and #newnick > 0 then + self._nick = newnick + self:appendLine(T(_("You are now known as %1"), newnick)) + end + if self._members and newnick and #newnick > 0 then + for ch, set in pairs(self._members) do + if set[oldnick] then + set[oldnick] = nil + set[newnick] = true + end + end + end + return elseif command == "NICK" then -- someone changed nick; update ours if it's us local newnick = rest:match("^:(.+)$") or rest local oldnick = prefix:match("^([^!]+)!") or prefix