diff --git a/Cargo.lock b/Cargo.lock index 3290691..c48caa5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,15 @@ version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "async-trait" version = "0.1.56" @@ -138,6 +147,7 @@ dependencies = [ "edit", "futures", "log", + "palette", "parking_lot", "rand", "rusqlite", @@ -260,6 +270,15 @@ dependencies = [ "instant", ] +[[package]] +name = "find-crate" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2" +dependencies = [ + "toml", +] + [[package]] name = "fnv" version = "1.0.7" @@ -571,6 +590,29 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "palette" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9735f7e1e51a3f740bacd5dc2724b61a7806f23597a8736e679f38ee3435d18" +dependencies = [ + "approx", + "num-traits", + "palette_derive", +] + +[[package]] +name = "palette_derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7799c3053ea8a6d8a1193c7ba42f534e7863cf52e378a7f90406f4a645d33bad" +dependencies = [ + "find-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1066,6 +1108,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + [[package]] name = "toss" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 395941f..6568aef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ directories = "4.0.1" edit = "0.1.4" futures = "0.3.21" log = { version = "0.4.17", features = ["std"] } +palette = { version = "0.6.0", default-features = false, features = ["std"] } parking_lot = "0.12.1" rand = "0.8.5" rusqlite = { version = "0.27.0", features = ["chrono"] } diff --git a/src/chat/tree/blocks.rs b/src/chat/tree/blocks.rs index 3ec1e7a..05e582c 100644 --- a/src/chat/tree/blocks.rs +++ b/src/chat/tree/blocks.rs @@ -3,6 +3,7 @@ use std::collections::VecDeque; use chrono::{DateTime, Utc}; +use crossterm::style::ContentStyle; use crate::chat::Cursor; @@ -24,6 +25,7 @@ impl Block { indent: usize, time: DateTime, nick: String, + nick_style: ContentStyle, lines: Vec, ) -> Self { Self { @@ -33,7 +35,11 @@ impl Block { indent, time: Some(time), cursor: false, - body: BlockBody::Msg(MsgBlock { nick, lines }), + body: BlockBody::Msg(MsgBlock { + nick, + nick_style, + lines, + }), } } @@ -61,6 +67,7 @@ pub enum BlockBody { pub struct MsgBlock { pub nick: String, + pub nick_style: ContentStyle, pub lines: Vec, } diff --git a/src/chat/tree/layout.rs b/src/chat/tree/layout.rs index 3fad499..6149035 100644 --- a/src/chat/tree/layout.rs +++ b/src/chat/tree/layout.rs @@ -20,7 +20,7 @@ fn msg_to_block(frame: &mut Frame, size: Size, msg: &M, indent: usize) - let content_width = content_width as usize; let lines = toss::split_at_indices(&content, &frame.wrap(&content, content_width)); let lines = lines.into_iter().map(|s| s.to_string()).collect::>(); - Block::msg(msg.id(), indent, msg.time(), nick, lines) + Block::msg(msg.id(), indent, msg.time(), nick, msg.nick_style(), lines) } } diff --git a/src/chat/tree/render.rs b/src/chat/tree/render.rs index 70c5668..2518e25 100644 --- a/src/chat/tree/render.rs +++ b/src/chat/tree/render.rs @@ -44,10 +44,18 @@ fn render_indent(frame: &mut Frame, x: i32, y: i32, cursor: bool, indent: usize) } } -fn render_nick(frame: &mut Frame, x: i32, y: i32, indent: usize, nick: &str) { +fn render_nick( + frame: &mut Frame, + x: i32, + y: i32, + indent: usize, + nick: &str, + nick_style: ContentStyle, +) { let nick_pos = Pos::new(x + util::after_indent(indent), y); - let nick = format!("[{}]", nick); - frame.write(nick_pos, &nick, ContentStyle::default()); + let inner_nick_pos = Pos::new(nick_pos.x + 1, nick_pos.y); + frame.write(nick_pos, &format!("[{nick}]"), ContentStyle::default()); + frame.write(inner_nick_pos, nick, nick_style); } fn render_block(frame: &mut Frame, pos: Pos, size: Size, block: &Block) { @@ -64,7 +72,7 @@ fn render_block(frame: &mut Frame, pos: Pos, size: Size, block: &Block ContentStyle { + match self.level { + Level::Error => ContentStyle::default().bold().red(), + Level::Warn => ContentStyle::default().bold().yellow(), + Level::Info => ContentStyle::default().bold().green(), + Level::Debug => ContentStyle::default().bold().blue(), + Level::Trace => ContentStyle::default().bold().magenta(), + } + } + fn content(&self) -> String { self.content.clone() } diff --git a/src/store.rs b/src/store.rs index 5b96d46..019c4ce 100644 --- a/src/store.rs +++ b/src/store.rs @@ -4,6 +4,7 @@ use std::hash::Hash; use async_trait::async_trait; use chrono::{DateTime, Utc}; +use crossterm::style::ContentStyle; pub trait Msg { type Id: Clone + Debug + Hash + Eq + Ord; @@ -12,6 +13,7 @@ pub trait Msg { fn time(&self) -> DateTime; fn nick(&self) -> String; + fn nick_style(&self) -> ContentStyle; fn content(&self) -> String; } diff --git a/src/vault/euph.rs b/src/vault/euph.rs index 0fe494e..2214030 100644 --- a/src/vault/euph.rs +++ b/src/vault/euph.rs @@ -2,10 +2,12 @@ use std::mem; use async_trait::async_trait; use chrono::{DateTime, TimeZone, Utc}; +use crossterm::style::ContentStyle; use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}; use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Transaction}; use tokio::sync::{mpsc, oneshot}; +use crate::euph; use crate::euph::api::{Message, Snowflake, Time}; use crate::store::{Msg, MsgStore, Path, Tree}; @@ -65,6 +67,10 @@ impl Msg for EuphMsg { self.nick.clone() } + fn nick_style(&self) -> ContentStyle { + euph::nick_style(&self.nick) + } + fn content(&self) -> String { self.content.trim().to_string() }