From 343455091c9af4ad78765b9d93bea55da3ea78e2 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 13 Jul 2020 12:51:09 +0200 Subject: [PATCH] Show offline user status When the WHO reply is empty, it means user isn't connected to IRC. --- components/app.js | 20 +++++++++++++++++--- components/buffer-header.js | 31 +++++++++++++++++++++++++------ style.css | 3 +++ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/components/app.js b/components/app.js index d615222..545ebb2 100644 --- a/components/app.js +++ b/components/app.js @@ -162,8 +162,9 @@ export default class App extends Component { type, serverInfo: null, // if server topic: null, // if channel + members: new Map(), // if channel who: null, // if nick - members: new Map(), + offline: false, // if nick messages: [], unread: Unread.NONE, }); @@ -327,9 +328,21 @@ export default class App extends Component { realname: last.slice(last.indexOf(" ") + 1), }; - this.setBufferState(who.nick, { who }); + this.setBufferState(who.nick, { who, offline: false }); break; case irc.RPL_ENDOFWHO: + var target = msg.params[1]; + if (!this.isChannel(target) && target.indexOf("*") < 0) { + // Not a channel nor a mask, likely a nick + this.setBufferState(target, (buf) => { + // TODO: mark user offline if we have old WHO info but this + // WHO reply is empty + if (buf.who) { + return; + } + return { offline: true }; + }); + } break; case "NOTICE": case "PRIVMSG": @@ -376,7 +389,8 @@ export default class App extends Component { } var members = new Map(buf.members); members.delete(msg.prefix.name); - buffers.set(buf.name, { ...buf, members }); + var offline = buf.name == msg.prefix.name; + buffers.set(buf.name, { ...buf, members, offline }); affectedBuffers.push(buf.name); }); return { buffers }; diff --git a/components/buffer-header.js b/components/buffer-header.js index 641b43e..a36e0db 100644 --- a/components/buffer-header.js +++ b/components/buffer-header.js @@ -1,6 +1,22 @@ import { html, Component } from "/lib/index.js"; import { BufferType } from "/state.js"; +const Status = { + HERE: "here", + GONE: "gone", + OFFLINE: "offline", +}; + +function NickStatus(props) { + var textMap = { + [Status.HERE]: "User is online", + [Status.GONE]: "User is away", + [Status.OFFLINE]: "User is offline", + }; + var text = textMap[props.status]; + return html``; +} + export default function BufferHeader(props) { function handlePartClick(event) { event.preventDefault(); @@ -16,15 +32,18 @@ export default function BufferHeader(props) { } else if (props.buffer.who) { var who = props.buffer.who; - var statusClass = "here"; - var statusText = "User is online"; + var status = Status.HERE; if (who.away) { - statusClass = "gone"; - statusText = "User is away"; + status = Status.GONE; + } + if (props.buffer.offline) { + status = Status.OFFLINE; } - var status = html``; - description = html`${status} ${who.realname} (${who.username}@${who.hostname})`; + description = html`<${NickStatus} status=${status}/> ${who.realname} (${who.username}@${who.hostname})`; + } else if (props.buffer.offline) { + // User is offline, but we don't have WHO information + description = html`<${NickStatus} status=${Status.OFFLINE}/> ${props.buffer.name}`; } var closeText = "Close"; diff --git a/style.css b/style.css index 2f9646b..3d1166f 100644 --- a/style.css +++ b/style.css @@ -76,6 +76,9 @@ body { #buffer-header .status-gone { color: orange; } +#buffer-header .status-offline { + color: red; +} #buffer-header .actions { float: right;