Use current nickname instead of hardcoded value

This commit is contained in:
Sijmen 2023-11-17 13:39:37 +01:00
parent 8065fdd8ff
commit 63b04208d0
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
3 changed files with 97 additions and 83 deletions

View file

@ -1,12 +1,15 @@
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use futures::StreamExt; use futures::StreamExt;
use irc::proto::Capability;
use tokio::{ use tokio::{
select, select,
sync::mpsc::{UnboundedReceiver, UnboundedSender}, sync::mpsc::{UnboundedReceiver, UnboundedSender},
}; };
pub async fn connect() -> Result<irc::client::Client> { pub async fn connect() -> Result<irc::client::Client> {
Ok(irc::client::Client::new("config.toml").await?) let client = irc::client::Client::new("config.toml").await?;
client.send_cap_req(&[Capability::EchoMessage, Capability::ServerTime])?;
Ok(client)
} }
pub async fn message_loop( pub async fn message_loop(
@ -21,13 +24,13 @@ pub async fn message_loop(
select! { select! {
val = irc_stream.next() => { val = irc_stream.next() => {
if let Some(message) = val.transpose()? { if let Some(message) = val.transpose()? {
print!("[Rx] {message}"); println!("[Rx] {} {:?}", message.to_string().trim(), message.tags);
message_tx.send(message)?; message_tx.send(message)?;
} }
} }
val = input_rx.recv() => { val = input_rx.recv() => {
let message = val.unwrap(); let message = val.unwrap();
print!("[Tx] {message}"); println!("[Tx] {} {:?}", message.to_string().trim(), message.tags);
client.send(message)?; client.send(message)?;
} }
} }

View file

@ -11,7 +11,7 @@ use iced::{
widget::{column, container, mouse_area, row, text, text_input}, widget::{column, container, mouse_area, row, text, text_input},
Application, Background, Color, Element, Length, Settings, Application, Background, Color, Element, Length, Settings,
}; };
use irc::proto::Command as IrcCommand; use irc::proto::{Command as IrcCommand, Response};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::cell::RefCell; use std::cell::RefCell;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
@ -56,6 +56,7 @@ struct Cri {
input_tx: RefCell<UnboundedSender<irc::proto::Message>>, input_tx: RefCell<UnboundedSender<irc::proto::Message>>,
message_log: MessageLog, message_log: MessageLog,
input_value: String, input_value: String,
nickname: String,
} }
impl Cri { impl Cri {
@ -63,15 +64,6 @@ impl Cri {
if let Some(active_channel) = &self.message_log.active_channel { if let Some(active_channel) = &self.message_log.active_channel {
let command = IrcCommand::PRIVMSG(active_channel.to_string(), input_value.to_string()); let command = IrcCommand::PRIVMSG(active_channel.to_string(), input_value.to_string());
let message: irc::proto::Message = command.into(); let message: irc::proto::Message = command.into();
self.message_log
.get_mut(self.message_log.active_channel.clone())
.messages
.push(IrcMessage::Privmsg {
nickname: String::from("cri"),
message: input_value.to_string(),
});
self.input_tx.borrow().send(message.clone()).unwrap(); self.input_tx.borrow().send(message.clone()).unwrap();
} }
} }
@ -81,66 +73,69 @@ impl Cri {
let command = tokens.next().unwrap(); let command = tokens.next().unwrap();
match command { match command {
"/join" => { "/join" => self.handle_join_command(&mut tokens),
let channel = tokens "/part" => self.handle_part_command(&mut tokens),
.next() "/query" => self.handle_query_command(tokens),
.map(str::to_string)
.or_else(|| self.message_log.active_channel.clone());
if channel.is_none() {
// TODO error message
return;
}
let channel = channel.unwrap();
if !channel.starts_with('#') {
// TODO error message
return;
}
self.input_tx
.borrow()
.send(
IrcCommand::JOIN(channel.clone(), tokens.next().map(str::to_string), None)
.into(),
)
.unwrap();
self.message_log.set_active(Some(channel));
}
"/part" => {
let channel = tokens
.next()
.map(str::to_string)
.or_else(|| self.message_log.active_channel.clone());
if channel.is_none() {
// TODO error message
return;
}
let channel = channel.unwrap();
if !channel.starts_with('#') {
// TODO error message
return;
}
let reason = tokens.collect::<Vec<_>>().join(" ");
let reason = if reason.is_empty() {
None
} else {
Some(reason)
};
self.input_tx
.borrow()
.send(IrcCommand::PART(channel, reason).into())
.unwrap();
}
"/query" => self
.message_log
.set_active(Some(tokens.next().unwrap().to_string())),
_ => todo!(), _ => todo!(),
} }
} }
fn handle_part_command(&mut self, tokens: &mut std::str::SplitWhitespace<'_>) {
let channel = tokens
.next()
.map(str::to_string)
.or_else(|| self.message_log.active_channel.clone());
if channel.is_none() {
// TODO error message
return;
}
let channel = channel.unwrap();
if !channel.starts_with('#') {
// TODO error message
return;
}
let reason = tokens.collect::<Vec<_>>().join(" ");
let reason = if reason.is_empty() {
None
} else {
Some(reason)
};
self.input_tx
.borrow()
.send(IrcCommand::PART(channel, reason).into())
.unwrap();
}
fn handle_join_command(&mut self, tokens: &mut std::str::SplitWhitespace<'_>) {
let channel = tokens
.next()
.map(str::to_string)
.or_else(|| self.message_log.active_channel.clone());
if channel.is_none() {
// TODO error message
return;
}
let channel = channel.unwrap();
if !channel.starts_with('#') {
// TODO error message
return;
}
self.input_tx
.borrow()
.send(IrcCommand::JOIN(channel.clone(), tokens.next().map(str::to_string), None).into())
.unwrap();
self.message_log.set_active(Some(channel));
}
fn handle_query_command(&mut self, mut tokens: std::str::SplitWhitespace<'_>) {
self.message_log
.set_active(Some(tokens.next().unwrap().to_string()));
}
} }
impl Application for Cri { impl Application for Cri {
@ -156,6 +151,7 @@ impl Application for Cri {
input_tx: RefCell::new(flags.input_tx), input_tx: RefCell::new(flags.input_tx),
message_log: MessageLog::new(), message_log: MessageLog::new(),
input_value: String::new(), input_value: String::new(),
nickname: "cri".to_string(), // TODO take default value from config
}, },
iced::Command::none(), iced::Command::none(),
) )
@ -169,7 +165,10 @@ impl Application for Cri {
match message { match message {
UiMessage::IrcMessageReceived(message) => { UiMessage::IrcMessageReceived(message) => {
// TODO use actual nickname // TODO use actual nickname
let source_nickname = message.source_nickname().unwrap_or("cri").to_string(); let source_nickname = message
.source_nickname()
.unwrap_or(&self.nickname)
.to_string();
match &message.command { match &message.command {
IrcCommand::JOIN(chanlist, _, _) => { IrcCommand::JOIN(chanlist, _, _) => {
@ -190,12 +189,19 @@ impl Application for Cri {
.on_quit(&source_nickname, comment.as_deref()); .on_quit(&source_nickname, comment.as_deref());
} }
IrcCommand::PRIVMSG(msgtarget, content) | IrcCommand::NOTICE(msgtarget, content) => { IrcCommand::PRIVMSG(msgtarget, content)
| IrcCommand::NOTICE(msgtarget, content) => {
let channel = message.response_target().unwrap_or(msgtarget).to_string(); let channel = message.response_target().unwrap_or(msgtarget).to_string();
self.message_log self.message_log.on_privmsg(
.on_privmsg(&channel, &source_nickname, content); &self.nickname,
&channel,
&source_nickname,
content,
);
}
IrcCommand::Response(Response::RPL_WELCOME, args) => {
self.nickname = args[0].clone()
} }
_ => self.message_log.on_other(&message.to_string()), _ => self.message_log.on_other(&message.to_string()),
} }
} }
@ -232,7 +238,7 @@ impl Application for Cri {
let light_blue = Color::new(0.26, 0.62, 0.85, 1.0); let light_blue = Color::new(0.26, 0.62, 0.85, 1.0);
let light_red = Color::new(0.99, 0.36, 0.40, 1.0); let light_red = Color::new(0.99, 0.36, 0.40, 1.0);
let log = self.message_log.view(&self.message_log.active_channel); let log = self.message_log.view(&self.nickname);
let message_box = text_input("your magnum opus", &self.input_value) let message_box = text_input("your magnum opus", &self.input_value)
.id(INPUT_ID.clone()) .id(INPUT_ID.clone())

View file

@ -94,7 +94,13 @@ impl<'a> MessageLog {
} }
} }
pub fn on_privmsg(&mut self, channel_name: &str, nickname: &str, message: &str) { pub fn on_privmsg(
&mut self,
current_nickname: &str,
channel_name: &str,
nickname: &str,
message: &str,
) {
let is_active = self.active_channel.as_deref() == Some(channel_name); let is_active = self.active_channel.as_deref() == Some(channel_name);
let channel = self.get_mut(Some(channel_name.to_string())); let channel = self.get_mut(Some(channel_name.to_string()));
@ -104,8 +110,8 @@ impl<'a> MessageLog {
}); });
if !is_active { if !is_active {
// TODO Configurable nickname let highlight_regex =
let highlight_regex = Regex::new(r"\bcri\b").unwrap(); Regex::new(&format!(r"\b{}\b", regex::escape(current_nickname))).unwrap();
if highlight_regex.is_match(message) { if highlight_regex.is_match(message) {
channel.unread_highlights += 1; channel.unread_highlights += 1;
} else { } else {
@ -128,7 +134,7 @@ impl<'a> MessageLog {
channel.unread_highlights = 0; channel.unread_highlights = 0;
} }
pub fn view(&self, active_channel: &Option<String>) -> Container<'_, crate::UiMessage> { pub fn view(&self, current_nickname: &str) -> Container<'_, crate::UiMessage> {
let lighter_grey = Color::new(0.93, 0.94, 0.95, 1.0); let lighter_grey = Color::new(0.93, 0.94, 0.95, 1.0);
let dark_grey = Color::new(0.58, 0.65, 0.65, 1.0); let dark_grey = Color::new(0.58, 0.65, 0.65, 1.0);
let lighter_green = Color::new(0.94, 0.99, 0.87, 1.0); let lighter_green = Color::new(0.94, 0.99, 0.87, 1.0);
@ -154,7 +160,7 @@ impl<'a> MessageLog {
}; };
let messages = self let messages = self
.get(active_channel) .get(&self.active_channel)
.unwrap() .unwrap()
.messages .messages
.iter() .iter()
@ -218,8 +224,7 @@ impl<'a> MessageLog {
) )
} }
IrcMessage::Privmsg { nickname, message } => { IrcMessage::Privmsg { nickname, message } => {
// TODO don't hardcode nickname lol let is_self = nickname == current_nickname;
let is_self = nickname == "cri";
let mut elements = Vec::new(); let mut elements = Vec::new();
if !is_self { if !is_self {