aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar lancebord 2026-03-10 11:07:44 -0400
committerGravatar lancebord 2026-03-10 11:07:44 -0400
commite9d9766d72740c7d7c9918b4839f3379f57cd6ef (patch)
tree3694b83845354af116a77f66ed22931d2d11536e
parenthandle window resize events since draw is event driven now (diff)
merge consecutive join/part messages
-rw-r--r--src/client/event.rs13
-rw-r--r--src/client/handler.rs22
-rw-r--r--src/main.rs29
-rw-r--r--src/tui/app.rs20
4 files changed, 36 insertions, 48 deletions
diff --git a/src/client/event.rs b/src/client/event.rs
index 2c06d98..56e133e 100644
--- a/src/client/event.rs
+++ b/src/client/event.rs
@@ -17,20 +17,13 @@ pub enum Event {
SysMessage { text: String },
/// We joined a channel
- Joined { channel: String, nick: String },
+ Joined { nick: String },
/// We or someone else left a channel
- Parted {
- channel: String,
- nick: String,
- reason: Option<String>,
- },
+ Parted { nick: String },
/// Someone quit the server
- Quit {
- nick: String,
- reason: Option<String>,
- },
+ Quit { nick: String },
/// A nick change (could be ours)
NickChanged { old_nick: String, new_nick: String },
diff --git a/src/client/handler.rs b/src/client/handler.rs
index 63baf87..f30260f 100644
--- a/src/client/handler.rs
+++ b/src/client/handler.rs
@@ -90,40 +90,28 @@ pub fn handle(msg: IrcMessage, state: &mut ClientState, sender: &Sender) -> Vec<
Command::Join => {
let nick = nick_from_prefix(&msg.prefix);
- if let Some(channel) = msg.params.first() {
- events.push(Event::Joined {
- channel: channel.clone(),
- nick: nick.clone(),
- });
- if nick != state.nick {
- state.channel.members.insert(nick);
- }
+ events.push(Event::Joined { nick: nick.clone() });
+ if nick != state.nick {
+ state.channel.members.insert(nick);
}
}
Command::Part => {
let nick = nick_from_prefix(&msg.prefix);
- let channel = msg.params.first().cloned().unwrap_or_default();
- let reason = msg.params.get(1).cloned();
if nick != state.nick {
state.channel.members.remove(&nick);
}
- events.push(Event::Parted {
- channel,
- nick,
- reason,
- });
+ events.push(Event::Parted { nick });
}
Command::Quit => {
let nick = nick_from_prefix(&msg.prefix);
- let reason = msg.params.first().cloned();
state.channel.members.remove(&nick);
- events.push(Event::Quit { nick, reason });
+ events.push(Event::Quit { nick });
}
Command::Nick => {
diff --git a/src/main.rs b/src/main.rs
index 9a5a69b..d788553 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -96,9 +96,9 @@ async fn run(
let sender = client.sender();
let (tx, mut rx) = mpsc::unbounded_channel::<AppEvent>();
+
// Spawn keyboard task — blocks on crossterm's async read,
// zero CPU until a key is actually pressed
-
let kb_tx = tx.clone();
tokio::spawn(async move {
loop {
@@ -260,11 +260,11 @@ fn handle_irc_event(event: IrcEvent, app: &mut AppState) {
app.push_system(&format!("Connected to {} as {}", server, nick));
}
- IrcEvent::Joined { channel, nick } => {
+ IrcEvent::Joined { nick } => {
if nick == app.nick {
- app.push_system(&format!("You joined {}", channel));
+ app.push_join_leave(&format!("+{}", nick));
} else {
- app.push_system(&format!("{} joined {}", nick, channel));
+ app.push_join_leave(&format!("+{}", nick));
app.members.push(nick);
app.sort_members();
}
@@ -292,33 +292,20 @@ fn handle_irc_event(event: IrcEvent, app: &mut AppState) {
app.push_system(text.as_str());
}
- IrcEvent::Parted {
- channel,
- nick,
- reason,
- } => {
+ IrcEvent::Parted { nick } => {
app.members.retain(|m| {
let bare = m.trim_start_matches(&['@', '+', '%'][..]);
bare != nick
});
- app.push_system(&format!(
- "{} left {}{}",
- nick,
- channel,
- reason.map(|r| format!(" ({})", r)).unwrap_or_default()
- ));
+ app.push_join_leave(&format!("-{}", nick,));
}
- IrcEvent::Quit { nick, reason } => {
+ IrcEvent::Quit { nick } => {
app.members.retain(|m| {
let bare = m.trim_start_matches(&['@', '+', '%'][..]);
bare != nick
});
- app.push_system(&format!(
- "{} quit{}",
- nick,
- reason.map(|r| format!(" ({})", r)).unwrap_or_default()
- ));
+ app.push_join_leave(&format!("-{}", nick,));
}
IrcEvent::NickChanged { old_nick, new_nick } => {
diff --git a/src/tui/app.rs b/src/tui/app.rs
index 52fc85a..47af74d 100644
--- a/src/tui/app.rs
+++ b/src/tui/app.rs
@@ -6,6 +6,7 @@ pub struct ChatLine {
pub nick: String,
pub text: String,
pub is_system: bool,
+ pub is_join_leave: bool,
pub is_notice: bool,
}
@@ -46,6 +47,7 @@ impl AppState {
nick: nick.to_string(),
text: text.to_string(),
is_system: false,
+ is_join_leave: false,
is_notice: false,
});
}
@@ -55,6 +57,24 @@ impl AppState {
nick: String::new(),
text: text.to_string(),
is_system: true,
+ is_join_leave: false,
+ is_notice: false,
+ });
+ }
+
+ pub fn push_join_leave(&mut self, text: &str) {
+ if let Some(m) = self.messages.last_mut() {
+ if m.is_join_leave {
+ m.text += format!(" {text}").as_str();
+ return;
+ }
+ }
+
+ self.messages.push(ChatLine {
+ nick: String::new(),
+ text: text.to_string(),
+ is_system: true,
+ is_join_leave: true,
is_notice: false,
});
}