feat: process more chat event types
This commit is contained in:
parent
c6f9d34490
commit
ddcbbf274e
3 changed files with 49 additions and 18 deletions
13
src/app.rs
13
src/app.rs
|
@ -20,7 +20,7 @@ impl History {
|
||||||
|
|
||||||
fn down(&mut self, x: u16) {
|
fn down(&mut self, x: u16) {
|
||||||
if self.count < self.height { return };
|
if self.count < self.height { return };
|
||||||
let delta = self.count - self.height;
|
let delta = self.count - (self.height/2);
|
||||||
if self.offset >= delta { return }
|
if self.offset >= delta { return }
|
||||||
self.offset += std::cmp::min(x, delta - self.offset);
|
self.offset += std::cmp::min(x, delta - self.offset);
|
||||||
}
|
}
|
||||||
|
@ -103,12 +103,17 @@ pub async fn run<T: ratatui::backend::Backend>(term: &mut Terminal<T>, args: cra
|
||||||
let tl_input_len = ((tl_input.len() as u16 + 3) / history.width) + 1;
|
let tl_input_len = ((tl_input.len() as u16 + 3) / history.width) + 1;
|
||||||
let tl_header = args.server.clone();
|
let tl_header = args.server.clone();
|
||||||
// TODO only render bottom lines
|
// TODO only render bottom lines
|
||||||
let tl_text = history
|
let mut tl_text_vec = history
|
||||||
.lines
|
.lines
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| format!("{x}"))
|
.map(|x| format!("{x}"))
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>();
|
||||||
.join("\n");
|
|
||||||
|
// two empty lines because my math is wrong and im lazy rn
|
||||||
|
tl_text_vec.push("".to_string());
|
||||||
|
tl_text_vec.push("".to_string());
|
||||||
|
|
||||||
|
let tl_text = tl_text_vec.join("\n");
|
||||||
|
|
||||||
term.draw(|frame| {
|
term.draw(|frame| {
|
||||||
let layout = Layout::default()
|
let layout = Layout::default()
|
||||||
|
|
29
src/chat.rs
29
src/chat.rs
|
@ -27,16 +27,20 @@ pub enum ChatLine {
|
||||||
body: String,
|
body: String,
|
||||||
},
|
},
|
||||||
Error(String),
|
Error(String),
|
||||||
|
Rename(String, String),
|
||||||
Join(String),
|
Join(String),
|
||||||
Leave(String),
|
Leave(String),
|
||||||
Connect(String),
|
Connect(String),
|
||||||
|
Raw(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ChatEvent {
|
impl Display for ChatEvent {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let time = self.0.format("%H:%M:%S");
|
let time = self.0.format("%H:%M:%S");
|
||||||
match &self.1 {
|
match &self.1 {
|
||||||
|
ChatLine::Raw(s) => write!(f, "{time} {s}"),
|
||||||
ChatLine::Error(err) => write!(f, "{time} /!\\ {err}"),
|
ChatLine::Error(err) => write!(f, "{time} /!\\ {err}"),
|
||||||
|
ChatLine::Rename(before, after) => write!(f, "{time} user <{before}> renamed to <{after}>"),
|
||||||
ChatLine::Join(user) => write!(f, "{time} [{user} joined]"),
|
ChatLine::Join(user) => write!(f, "{time} [{user} joined]"),
|
||||||
ChatLine::Leave(user) => write!(f, "{time} [{user} left]"),
|
ChatLine::Leave(user) => write!(f, "{time} [{user} left]"),
|
||||||
ChatLine::Connect(user) => write!(f, "{time} [{user} connected]"),
|
ChatLine::Connect(user) => write!(f, "{time} [{user} connected]"),
|
||||||
|
@ -110,16 +114,23 @@ impl Chat {
|
||||||
Message::Ping(_) | tokio_tungstenite::tungstenite::Message::Pong(_) => {}, // ignore
|
Message::Ping(_) | tokio_tungstenite::tungstenite::Message::Pong(_) => {}, // ignore
|
||||||
Message::Text(payload) => for line in payload.lines() {
|
Message::Text(payload) => for line in payload.lines() {
|
||||||
match serde_json::from_str::<Event>(line) {
|
match serde_json::from_str::<Event>(line) {
|
||||||
Err(e) => chan.send(ChatEvent(chrono::Utc::now(), ChatLine::Error(format!("failed parsing message: {e}"))))?,
|
Err(e) => {
|
||||||
|
chan.send(ChatEvent(chrono::Utc::now(), ChatLine::Error(format!("failed parsing message: {e}"))))?;
|
||||||
|
chan.send(ChatEvent(chrono::Utc::now(), ChatLine::Raw(line.to_string())))?;
|
||||||
|
},
|
||||||
Ok(event) => match event.inner {
|
Ok(event) => match event.inner {
|
||||||
EventInner::Chat { body, visible: _ } =>
|
EventInner::Chat { body, user, visible } =>
|
||||||
chan.send(ChatEvent(event.timestamp, ChatLine::Message { user: event.user.display_name, body }))?,
|
chan.send(ChatEvent(event.timestamp, if visible { ChatLine::Message { user: user.display_name, body } } else { ChatLine::Raw("| REDACTED |".into()) }))?,
|
||||||
EventInner::ConnectedUserInfo =>
|
EventInner::ConnectedUserInfo { user } =>
|
||||||
chan.send(ChatEvent(event.timestamp, ChatLine::Connect(event.user.display_name)))?,
|
chan.send(ChatEvent(event.timestamp, ChatLine::Connect(user.display_name)))?,
|
||||||
EventInner::UserJoined =>
|
EventInner::UserJoined { user } =>
|
||||||
chan.send(ChatEvent(event.timestamp, ChatLine::Join(event.user.display_name)))?,
|
chan.send(ChatEvent(event.timestamp, ChatLine::Join(user.display_name)))?,
|
||||||
EventInner::UserParted =>
|
EventInner::UserParted { user } =>
|
||||||
chan.send(ChatEvent(event.timestamp, ChatLine::Leave(event.user.display_name)))?,
|
chan.send(ChatEvent(event.timestamp, ChatLine::Leave(user.display_name)))?,
|
||||||
|
EventInner::NameChange { old_name, user } =>
|
||||||
|
chan.send(ChatEvent(event.timestamp, ChatLine::Rename(old_name, user.display_name)))?,
|
||||||
|
EventInner::ChatAction { body } =>
|
||||||
|
chan.send(ChatEvent(event.timestamp, ChatLine::Raw(body)))?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
25
src/proto.rs
25
src/proto.rs
|
@ -33,26 +33,41 @@ pub mod ws {
|
||||||
pub struct Event {
|
pub struct Event {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub timestamp: chrono::DateTime<chrono::Utc>,
|
pub timestamp: chrono::DateTime<chrono::Utc>,
|
||||||
pub user: User,
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub inner: EventInner,
|
pub inner: EventInner,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO can i avoid repeating id,timestamp,user in each msg type??
|
// TODO can i avoid repeating id,timestamp,user in each msg type??
|
||||||
#[derive(Debug, serde::Deserialize)]
|
#[derive(Debug, serde::Deserialize)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type", rename_all = "camelCase")]
|
||||||
pub enum EventInner {
|
pub enum EventInner {
|
||||||
#[serde(rename = "CHAT")]
|
#[serde(rename = "CHAT")]
|
||||||
Chat {
|
Chat {
|
||||||
body: String,
|
body: String,
|
||||||
visible: bool,
|
visible: bool,
|
||||||
|
user: User,
|
||||||
},
|
},
|
||||||
#[serde(rename = "CONNECTED_USER_INFO")]
|
#[serde(rename = "CONNECTED_USER_INFO")]
|
||||||
ConnectedUserInfo,
|
ConnectedUserInfo {
|
||||||
|
user: User,
|
||||||
|
},
|
||||||
#[serde(rename = "USER_JOINED")]
|
#[serde(rename = "USER_JOINED")]
|
||||||
UserJoined,
|
UserJoined {
|
||||||
|
user: User,
|
||||||
|
},
|
||||||
#[serde(rename = "USER_PARTED")]
|
#[serde(rename = "USER_PARTED")]
|
||||||
UserParted,
|
UserParted {
|
||||||
|
user: User,
|
||||||
|
},
|
||||||
|
#[serde(rename = "NAME_CHANGE")]
|
||||||
|
NameChange {
|
||||||
|
old_name: String,
|
||||||
|
user: User,
|
||||||
|
},
|
||||||
|
#[serde(rename = "CHAT_ACTION")]
|
||||||
|
ChatAction {
|
||||||
|
body: String,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize)]
|
#[derive(Debug, serde::Deserialize)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue