Rename all crate directories, package names, binary names, proto package/module paths, ALPN strings, env var prefixes, config filenames, mDNS service names, and plugin ABI symbols from quicproquo/qpq to quicprochat/qpc.
83 lines
2.5 KiB
Rust
83 lines
2.5 KiB
Rust
//! Terminal display helpers for the REPL.
|
|
|
|
use super::conversation::StoredMessage;
|
|
use super::session::SessionState;
|
|
|
|
// ANSI color codes
|
|
const RESET: &str = "\x1b[0m";
|
|
const BOLD: &str = "\x1b[1m";
|
|
const DIM: &str = "\x1b[2m";
|
|
const GREEN: &str = "\x1b[32m";
|
|
const CYAN: &str = "\x1b[36m";
|
|
const YELLOW: &str = "\x1b[33m";
|
|
|
|
/// Print the REPL prompt showing the active conversation and unread count.
|
|
pub fn print_prompt(session: &SessionState) {
|
|
use std::io::Write;
|
|
let name = session
|
|
.active_display_name()
|
|
.unwrap_or_else(|| "no conversation".into());
|
|
let unread = session.total_unread();
|
|
if unread > 0 {
|
|
print!("{DIM}[{RESET}{BOLD}{name}{RESET} {YELLOW}{unread} unread{RESET}{DIM}]{RESET} > ");
|
|
} else {
|
|
print!("{DIM}[{RESET}{BOLD}{name}{RESET}{DIM}]{RESET} > ");
|
|
}
|
|
let _ = std::io::stdout().flush();
|
|
}
|
|
|
|
/// Print an incoming or outgoing message.
|
|
pub fn print_message(msg: &StoredMessage) {
|
|
let body = if msg.msg_type == "reaction" {
|
|
format!("reacted {}", msg.body)
|
|
} else {
|
|
msg.body.clone()
|
|
};
|
|
if msg.is_outgoing {
|
|
println!("\r{GREEN}> {body}{RESET}");
|
|
} else {
|
|
let fallback = hex::encode(&msg.sender_key[..4]);
|
|
let sender = msg.sender_name.as_deref().unwrap_or(&fallback);
|
|
println!("\r{CYAN}{BOLD}[{sender}]{RESET} {body}");
|
|
}
|
|
}
|
|
|
|
/// Print a message received in real-time (clears current line first).
|
|
pub fn print_incoming(sender: &str, body: &str) {
|
|
use std::io::Write;
|
|
// Clear current line, print message, then re-show prompt context
|
|
print!("\r\x1b[2K");
|
|
println!("{CYAN}{BOLD}[{sender}]{RESET} {body}");
|
|
let _ = std::io::stdout().flush();
|
|
}
|
|
|
|
/// Print a system/status message.
|
|
pub fn print_status(msg: &str) {
|
|
println!("{DIM} {msg}{RESET}");
|
|
}
|
|
|
|
/// Print a transient typing indicator (clears current line first).
|
|
pub fn print_typing(sender: &str) {
|
|
use std::io::Write;
|
|
print!("\r\x1b[2K");
|
|
println!("{DIM} {sender} is typing...{RESET}");
|
|
let _ = std::io::stdout().flush();
|
|
}
|
|
|
|
/// Print an error message.
|
|
pub fn print_error(msg: &str) {
|
|
println!("{YELLOW} error: {msg}{RESET}");
|
|
}
|
|
|
|
/// Format a conversation list entry for `/list`.
|
|
pub fn format_conv_line(display_name: &str, kind: &str, unread: u32, members: usize) -> String {
|
|
let unread_str = if unread > 0 {
|
|
format!(" {YELLOW}({unread} new){RESET}")
|
|
} else {
|
|
String::new()
|
|
};
|
|
format!(
|
|
" {BOLD}{display_name}{RESET} {DIM}[{kind}, {members} members]{RESET}{unread_str}"
|
|
)
|
|
}
|