From c2f5392673f8673a0b09ac3cac40509b17813a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sun, 14 Jan 2018 13:27:14 +0300 Subject: [PATCH] Show all NOTICE messages in server tabs (fixes #21) --- CHANGELOG.md | 3 +++ src/lib.rs | 50 ++++++++++++++++++----------------------------- src/tui/mod.rs | 5 ++++- src/tui/tabbed.rs | 11 +++++++++++ src/wire.rs | 26 ++++++------------------ 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1771ce72..f20fd347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ - Fixed a bug that caused incorrect tab bar rendering in some cases (#76). - tiny no longer creates `~/logs` directory. This directory was used for debug logs in the past (#82). +- `NOTICE` messages (used by services like `NickServ`, `MemoServ`, `Global` + etc.) are now shown in server tabs unless there's already a tab for the sender + (#21). # 2017/11/12: 0.3.0 diff --git a/src/lib.rs b/src/lib.rs index 34f59dd4..25e3ef9f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -341,21 +341,8 @@ impl<'poll> Tiny<'poll> { MsgSource::User { ref serv_name, ref nick, - } => { - let msg_target = if nick.eq_ignore_ascii_case("nickserv") - || nick.eq_ignore_ascii_case("chanserv") - { - MsgTarget::Server { - serv_name: serv_name, - } - } else { - MsgTarget::User { - serv_name: serv_name, - nick: nick, - } - }; - (msg_target, nick, serv_name) - } + } => + (MsgTarget::User { serv_name, nick }, nick, serv_name), } }; @@ -509,7 +496,7 @@ impl<'poll> Tiny<'poll> { let conn = &self.conns[conn_idx]; let pfx = msg.pfx; match msg.cmd { - Cmd::PRIVMSG { target, msg } | Cmd::NOTICE { target, msg } => { + Cmd::PRIVMSG { target, msg, is_notice } => { let pfx = match pfx { Some(pfx) => pfx, @@ -521,6 +508,8 @@ impl<'poll> Tiny<'poll> { return; } }; + + // sender to be shown in the UI let origin = match pfx { Pfx::Server(_) => conn.get_serv_name(), @@ -573,21 +562,20 @@ impl<'poll> Tiny<'poll> { } wire::MsgTarget::User(target) => { let serv_name = conn.get_serv_name(); - let msg_target = match pfx { - Pfx::Server(_) => - MsgTarget::Server { - serv_name: serv_name, - }, - Pfx::User { ref nick, .. } if nick.eq_ignore_ascii_case("nickserv") || - nick.eq_ignore_ascii_case("chanserv") => - MsgTarget::Server { - serv_name: serv_name, - }, - Pfx::User { ref nick, .. } => - MsgTarget::User { - serv_name: serv_name, - nick: nick, - }, + let msg_target = { + match pfx { + Pfx::Server(_) => + MsgTarget::Server { serv_name }, + Pfx::User { ref nick, .. } => { + // show NOTICE messages in server tabs if we don't have a tab + // for the sender already (see #21) + if is_notice && !self.tui.does_user_tab_exist(serv_name, nick) { + MsgTarget::Server { serv_name } + } else { + MsgTarget::User { serv_name, nick } + } + } + } }; self.tui .add_privmsg(origin, msg, ts, &msg_target, is_ctcp_action); diff --git a/src/tui/mod.rs b/src/tui/mod.rs index eb056133..b388de61 100644 --- a/src/tui/mod.rs +++ b/src/tui/mod.rs @@ -107,6 +107,10 @@ impl TUI { pub fn get_nicks(&self, serv_name: &str, chan_name: &str) -> Option<&Trie> { self.ui.get_nicks(serv_name, chan_name) } + + pub fn does_user_tab_exist(&self, serv_name: &str, nick: &str) -> bool { + self.ui.does_user_tab_exist(serv_name, nick) + } } //////////////////////////////////////////////////////////////////////////////// @@ -177,7 +181,6 @@ impl TUI { // Showing messages /// Target of a message coming from an IRC server. -/// `size_of::() == 40`. Good idea to pass by reference. pub enum MsgTarget<'a> { Server { serv_name: &'a str, diff --git a/src/tui/tabbed.rs b/src/tui/tabbed.rs index 22f58fc6..b874bbe0 100644 --- a/src/tui/tabbed.rs +++ b/src/tui/tabbed.rs @@ -1032,6 +1032,17 @@ impl Tabbed { } } + pub fn does_user_tab_exist(&self, serv_name_: &str, nick_: &str) -> bool { + for tab in &self.tabs { + if let MsgSource::User { ref serv_name, ref nick } = tab.src { + if serv_name_ == serv_name && nick_ == nick { + return true; + } + } + } + false + } + //////////////////////////////////////////////////////////////////////////// // Helpers diff --git a/src/wire.rs b/src/wire.rs index 14c663cc..540732c2 100644 --- a/src/wire.rs +++ b/src/wire.rs @@ -92,16 +92,13 @@ pub struct Msg { #[derive(Debug, PartialEq, Eq)] pub enum Cmd { + /// A PRIVMSG or NOTICE. Check `is_notice` field. PRIVMSG { // TODO: In theory this should be a list of targets, but in practice I've never // encountered that case. target: MsgTarget, msg: String, - }, - - NOTICE { - target: MsgTarget, - msg: String, + is_notice: bool, }, JOIN { @@ -224,7 +221,8 @@ impl Msg { let params: Vec<&str> = parse_params(unsafe { str::from_utf8_unchecked(slice) }); let cmd = match msg_ty { - MsgType::Cmd("PRIVMSG") if params.len() == 2 => { + MsgType::Cmd("PRIVMSG") | MsgType::Cmd("NOTICE") if params.len() == 2 => { + let is_notice = if let MsgType::Cmd("NOTICE") = msg_ty { true } else { false }; let target = params[0]; let msg = params[1]; let target = if target.chars().nth(0) == Some('#') { @@ -233,21 +231,9 @@ impl Msg { MsgTarget::User(target.to_owned()) }; Cmd::PRIVMSG { - target: target, - msg: msg.to_owned(), - } - } - MsgType::Cmd("NOTICE") if params.len() == 2 => { - let target = params[0]; - let msg = params[1]; - let target = if target.chars().nth(0) == Some('#') { - MsgTarget::Chan(target.to_owned()) - } else { - MsgTarget::User(target.to_owned()) - }; - Cmd::NOTICE { - target: target, + target, msg: msg.to_owned(), + is_notice, } } MsgType::Cmd("JOIN") if params.len() == 1 => {