use flatland_client_ui::{UiKeyCode, UiKeyEvent};
#[derive(Debug, Clone, Default)]
pub struct ChatSession {
pub active: bool,
pub whisper: bool,
pub buffer: String,
}
impl ChatSession {
pub const MAX_LEN: usize = 200;
pub fn open(&mut self, whisper: bool) {
self.active = true;
self.whisper = whisper;
self.buffer.clear();
}
pub fn close(&mut self) {
self.active = false;
self.buffer.clear();
}
pub fn handle_key(&mut self, key: UiKeyEvent) -> Option<String> {
match key.code {
UiKeyCode::Esc => {
self.close();
None
}
UiKeyCode::Enter => {
let text = self.buffer.trim().to_string();
self.close();
if text.is_empty() {
None
} else {
Some(text)
}
}
UiKeyCode::Backspace => {
self.buffer.pop();
None
}
UiKeyCode::Char(c) => {
if self.buffer.len() < Self::MAX_LEN {
self.buffer.push(c);
}
None
}
_ => None,
}
}
pub fn prompt_line(&self) -> String {
if !self.active {
return String::new();
}
let prefix = if self.whisper { "whisper> " } else { "say> " };
format!("{prefix}{}", self.buffer)
}
}
#[cfg(test)]
mod tests {
use super::*;
use flatland_client_ui::{UiKeyEventKind, UiKeyModifiers};
fn char_key(c: char) -> UiKeyEvent {
UiKeyEvent {
kind: UiKeyEventKind::Press,
code: UiKeyCode::Char(c),
modifiers: UiKeyModifiers::default(),
}
}
#[test]
fn submit_trims_and_clears() {
let mut chat = ChatSession::default();
chat.open(false);
for c in " hello ".chars() {
assert!(chat.handle_key(char_key(c)).is_none());
}
let submitted = chat
.handle_key(UiKeyEvent {
kind: UiKeyEventKind::Press,
code: UiKeyCode::Enter,
modifiers: UiKeyModifiers::default(),
})
.expect("submit");
assert_eq!(submitted, "hello");
assert!(!chat.active);
}
}