diff --git a/data/src/client.rs b/data/src/client.rs index 14fd6443..d4ae3427 100644 --- a/data/src/client.rs +++ b/data/src/client.rs @@ -3,7 +3,7 @@ use std::collections::{BTreeMap, HashMap}; use irc::client::Client; use itertools::Itertools; -use crate::user::NickRef; +use crate::user::{Nick, NickRef}; use crate::{message, Message, Server, User}; #[derive(Debug, Clone, Copy)] @@ -27,8 +27,15 @@ pub enum State { #[derive(Debug)] pub enum Brodcast { - Quit(User, Option), - Nickname(String, String, bool), + Quit { + user: User, + comment: Option, + }, + Nickname { + old_user: User, + new_nick: Nick, + ourself: bool, + }, } #[derive(Debug)] @@ -83,23 +90,18 @@ impl Connection { match &message.command { Command::NICK(nick) => { - let Some(old_nick) = message.prefix.as_ref().and_then(|prefix| match prefix { - irc::proto::Prefix::ServerName(_) => None, - irc::proto::Prefix::Nickname(nick, _, _) => Some(nick), - }) else { - return None; - }; - - let changed_own_nickname = self.resolved_nick.as_ref() == Some(old_nick); - if changed_own_nickname { + let old_user = message.user()?; + let ourself = self.nickname() == old_user.nickname(); + + if ourself { self.resolved_nick = Some(nick.clone()); } - return Some(Event::Brodcast(Brodcast::Nickname( - nick.clone(), - old_nick.clone(), - changed_own_nickname, - ))); + return Some(Event::Brodcast(Brodcast::Nickname { + old_user, + new_nick: Nick::from(nick.as_str()), + ourself, + })); } Command::Response(Response::RPL_WELCOME, args) => { if let Some(nick) = args.first() { @@ -109,7 +111,10 @@ impl Connection { Command::QUIT(comment) => { let user = message.user()?; - return Some(Event::Brodcast(Brodcast::Quit(user, comment.clone()))); + return Some(Event::Brodcast(Brodcast::Quit { + user, + comment: comment.clone(), + })); } _ => {} } @@ -212,12 +217,10 @@ impl Map { .and_then(|connection| connection.receive(message)) } - pub fn sync(&mut self) { - self.0.values_mut().for_each(|state| { - if let State::Ready(connection) = state { - connection.sync(); - } - }); + pub fn sync(&mut self, server: &Server) { + if let Some(State::Ready(connection)) = self.0.get_mut(server) { + connection.sync(); + } } pub fn send(&mut self, server: &Server, message: message::Encoded) { diff --git a/data/src/history/manager.rs b/data/src/history/manager.rs index 212043a6..911889c9 100644 --- a/data/src/history/manager.rs +++ b/data/src/history/manager.rs @@ -284,23 +284,31 @@ impl Manager { message::broadcast::quit(user_channels, user_query, &user, &comment) } Broadcast::Nickname { - new_nick, old_nick, - changed_own_nickname, + new_nick, + ourself, user_channels, } => { - let user_query = queries.find(|nick| { - let old_nick = NickRef::from(old_nick.as_str()); - old_nick == *nick - }); - - message::broadcast::nickname( - user_channels, - user_query, - &new_nick, - &old_nick, - changed_own_nickname, - ) + if ourself { + // If ourself, broadcast to all query channels (since we are in all of them) + message::broadcast::nickname( + user_channels, + queries, + &old_nick, + &new_nick, + ourself, + ) + } else { + // Otherwise just the query channel of the user w/ nick change + let user_query = queries.find(|nick| old_nick == *nick); + message::broadcast::nickname( + user_channels, + user_query, + &old_nick, + &new_nick, + ourself, + ) + } } }; @@ -472,9 +480,9 @@ pub enum Broadcast { user_channels: Vec, }, Nickname { - new_nick: String, - old_nick: String, - changed_own_nickname: bool, + old_nick: Nick, + new_nick: Nick, + ourself: bool, user_channels: Vec, }, } diff --git a/data/src/message.rs b/data/src/message.rs index e8ad613b..adc15ab3 100644 --- a/data/src/message.rs +++ b/data/src/message.rs @@ -431,11 +431,11 @@ pub(crate) mod broadcast { pub fn nickname( channels: impl IntoIterator, queries: impl IntoIterator, - new_nick: &str, - old_nick: &str, - changed_own_nickname: bool, + old_nick: &Nick, + new_nick: &Nick, + ourself: bool, ) -> Vec { - let text = if changed_own_nickname { + let text = if ourself { format!(" ∙ You're now known as {new_nick}") } else { format!(" ∙ {old_nick} is now known as {new_nick}") diff --git a/src/main.rs b/src/main.rs index fdd2ca8e..f0f63ad2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -324,7 +324,7 @@ impl Application for Halloy { dashboard.record_message(&server, message); } data::client::Event::Brodcast(brodcast) => match brodcast { - data::client::Brodcast::Quit(user, comment) => { + data::client::Brodcast::Quit { user, comment } => { let user_channels = self .clients .get_user_channels(&server, user.nickname()); @@ -336,20 +336,20 @@ impl Application for Halloy { user_channels, ); } - data::client::Brodcast::Nickname( + data::client::Brodcast::Nickname { + old_user, new_nick, - old_nick, - changed_own_nickname, - ) => { - let user_channels = self - .clients - .get_user_channels(&server, old_nick.as_str().into()); + ourself, + } => { + let old_nick = old_user.nickname(); + let user_channels = + self.clients.get_user_channels(&server, old_nick); dashboard.broadcast_nickname( &server, + old_nick.to_owned(), new_nick, - old_nick, - changed_own_nickname, + ourself, user_channels, ); } @@ -360,7 +360,7 @@ impl Application for Halloy { // Must be called after receiving message batches to ensure // user & channel lists are in sync - self.clients.sync(); + self.clients.sync(&server); Command::none() } diff --git a/src/screen/dashboard.rs b/src/screen/dashboard.rs index cb0d3a32..f8a315b5 100644 --- a/src/screen/dashboard.rs +++ b/src/screen/dashboard.rs @@ -4,6 +4,7 @@ pub mod side_menu; use std::time::{Duration, Instant}; use data::history::manager::Broadcast; +use data::user::Nick; use data::{dashboard, history, Config, Server, User}; use iced::widget::pane_grid::{self, PaneGrid}; use iced::widget::{container, row}; @@ -516,9 +517,9 @@ impl Dashboard { pub fn broadcast_nickname( &mut self, server: &Server, - new_nick: String, - old_nick: String, - changed_own_nickname: bool, + old_nick: Nick, + new_nick: Nick, + ourself: bool, user_channels: Vec, ) { self.history.broadcast( @@ -526,7 +527,7 @@ impl Dashboard { Broadcast::Nickname { new_nick, old_nick, - changed_own_nickname, + ourself, user_channels, }, );