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 futures::StreamExt;
use irc::proto::Capability;
use tokio::{
select,
sync::mpsc::{UnboundedReceiver, UnboundedSender},
};
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(
@ -21,13 +24,13 @@ pub async fn message_loop(
select! {
val = irc_stream.next() => {
if let Some(message) = val.transpose()? {
print!("[Rx] {message}");
println!("[Rx] {} {:?}", message.to_string().trim(), message.tags);
message_tx.send(message)?;
}
}
val = input_rx.recv() => {
let message = val.unwrap();
print!("[Tx] {message}");
println!("[Tx] {} {:?}", message.to_string().trim(), message.tags);
client.send(message)?;
}
}

View file

@ -11,7 +11,7 @@ use iced::{
widget::{column, container, mouse_area, row, text, text_input},
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 std::cell::RefCell;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
@ -56,6 +56,7 @@ struct Cri {
input_tx: RefCell<UnboundedSender<irc::proto::Message>>,
message_log: MessageLog,
input_value: String,
nickname: String,
}
impl Cri {
@ -63,15 +64,6 @@ impl Cri {
if let Some(active_channel) = &self.message_log.active_channel {
let command = IrcCommand::PRIVMSG(active_channel.to_string(), input_value.to_string());
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();
}
}
@ -81,66 +73,69 @@ impl Cri {
let command = tokens.next().unwrap();
match command {
"/join" => {
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));
}
"/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())),
"/join" => self.handle_join_command(&mut tokens),
"/part" => self.handle_part_command(&mut tokens),
"/query" => self.handle_query_command(tokens),
_ => 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 {
@ -156,6 +151,7 @@ impl Application for Cri {
input_tx: RefCell::new(flags.input_tx),
message_log: MessageLog::new(),
input_value: String::new(),
nickname: "cri".to_string(), // TODO take default value from config
},
iced::Command::none(),
)
@ -169,7 +165,10 @@ impl Application for Cri {
match message {
UiMessage::IrcMessageReceived(message) => {
// 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 {
IrcCommand::JOIN(chanlist, _, _) => {
@ -190,12 +189,19 @@ impl Application for Cri {
.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();
self.message_log
.on_privmsg(&channel, &source_nickname, content);
self.message_log.on_privmsg(
&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()),
}
}
@ -232,7 +238,7 @@ impl Application for Cri {
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 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)
.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 channel = self.get_mut(Some(channel_name.to_string()));
@ -104,8 +110,8 @@ impl<'a> MessageLog {
});
if !is_active {
// TODO Configurable nickname
let highlight_regex = Regex::new(r"\bcri\b").unwrap();
let highlight_regex =
Regex::new(&format!(r"\b{}\b", regex::escape(current_nickname))).unwrap();
if highlight_regex.is_match(message) {
channel.unread_highlights += 1;
} else {
@ -128,7 +134,7 @@ impl<'a> MessageLog {
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 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);
@ -154,7 +160,7 @@ impl<'a> MessageLog {
};
let messages = self
.get(active_channel)
.get(&self.active_channel)
.unwrap()
.messages
.iter()
@ -218,8 +224,7 @@ impl<'a> MessageLog {
)
}
IrcMessage::Privmsg { nickname, message } => {
// TODO don't hardcode nickname lol
let is_self = nickname == "cri";
let is_self = nickname == current_nickname;
let mut elements = Vec::new();
if !is_self {