Switch to new toss commit

This commit is contained in:
Joscha 2022-07-04 19:40:11 +02:00
parent 11422801b0
commit 93cc2a6c13
12 changed files with 62 additions and 80 deletions

2
Cargo.lock generated
View file

@ -1120,7 +1120,7 @@ dependencies = [
[[package]] [[package]]
name = "toss" name = "toss"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/Garmelon/toss.git?rev=761519c1a7cdc950eab70fd6539c71bf22919a50#761519c1a7cdc950eab70fd6539c71bf22919a50" source = "git+https://github.com/Garmelon/toss.git?rev=ee9d6018c0efb5e6eb02db94dff7483d33b96a43#ee9d6018c0efb5e6eb02db94dff7483d33b96a43"
dependencies = [ dependencies = [
"crossterm", "crossterm",
"unicode-linebreak", "unicode-linebreak",

View file

@ -27,4 +27,4 @@ features = ["rustls-tls-native-roots"]
[dependencies.toss] [dependencies.toss]
git = "https://github.com/Garmelon/toss.git" git = "https://github.com/Garmelon/toss.git"
rev = "761519c1a7cdc950eab70fd6539c71bf22919a50" rev = "ee9d6018c0efb5e6eb02db94dff7483d33b96a43"

View file

@ -79,6 +79,6 @@ impl<M: Msg> TreeView<M> {
let blocks = self let blocks = self
.layout_blocks(store, cursor.as_ref(), frame, size) .layout_blocks(store, cursor.as_ref(), frame, size)
.await; .await;
Self::render_blocks(frame, pos, size, &blocks); Self::render_blocks(frame, pos, size, blocks);
} }
} }

View file

@ -3,7 +3,7 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use crossterm::style::ContentStyle; use toss::styled::Styled;
use crate::chat::Cursor; use crate::chat::Cursor;
@ -24,9 +24,8 @@ impl<I> Block<I> {
id: I, id: I,
indent: usize, indent: usize,
time: DateTime<Utc>, time: DateTime<Utc>,
nick: String, nick: Styled,
nick_style: ContentStyle, lines: Vec<Styled>,
lines: Vec<String>,
) -> Self { ) -> Self {
Self { Self {
id, id,
@ -35,11 +34,7 @@ impl<I> Block<I> {
indent, indent,
time: Some(time), time: Some(time),
cursor: false, cursor: false,
body: BlockBody::Msg(MsgBlock { body: BlockBody::Msg(MsgBlock { nick, lines }),
nick,
nick_style,
lines,
}),
} }
} }
@ -66,9 +61,8 @@ pub enum BlockBody {
} }
pub struct MsgBlock { pub struct MsgBlock {
pub nick: String, pub nick: Styled,
pub nick_style: ContentStyle, pub lines: Vec<Styled>,
pub lines: Vec<String>,
} }
/// Pre-layouted messages as a sequence of blocks. /// Pre-layouted messages as a sequence of blocks.

View file

@ -13,14 +13,14 @@ fn msg_to_block<M: Msg>(frame: &mut Frame, size: Size, msg: &M, indent: usize) -
let nick = msg.nick(); let nick = msg.nick();
let content = msg.content(); let content = msg.content();
let content_width = size.width as i32 - util::after_nick(frame, indent, &nick); let content_width = size.width as i32 - util::after_nick(frame, indent, &nick.text());
if content_width < MIN_CONTENT_WIDTH as i32 { if content_width < MIN_CONTENT_WIDTH as i32 {
Block::placeholder(msg.id(), indent).time(msg.time()) Block::placeholder(msg.id(), indent).time(msg.time())
} else { } else {
let content_width = content_width as usize; let content_width = content_width as usize;
let lines = toss::split_at_indices(&content, &frame.wrap(&content, content_width)); let breaks = frame.wrap(&content.text(), content_width);
let lines = lines.into_iter().map(|s| s.to_string()).collect::<Vec<_>>(); let lines = content.split_at_indices(&breaks);
Block::msg(msg.id(), indent, msg.time(), nick, msg.nick_style(), lines) Block::msg(msg.id(), indent, msg.time(), nick, lines)
} }
} }

View file

@ -1,8 +1,8 @@
//! Rendering blocks to a [`Frame`]. //! Rendering blocks to a [`Frame`].
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use crossterm::style::ContentStyle;
use toss::frame::{Frame, Pos, Size}; use toss::frame::{Frame, Pos, Size};
use toss::styled::Styled;
use crate::store::Msg; use crate::store::Msg;
@ -24,46 +24,39 @@ fn render_time(frame: &mut Frame, x: i32, y: i32, cursor: bool, time: Option<Dat
if let Some(time) = time { if let Some(time) = time {
let time = format!("{}", time.format(TIME_FORMAT)); let time = format!("{}", time.format(TIME_FORMAT));
frame.write(pos, &time, style); frame.write(pos, (&time, style));
} else { } else {
frame.write(pos, TIME_EMPTY, style); frame.write(pos, (TIME_EMPTY, style));
} }
} }
fn render_indent(frame: &mut Frame, x: i32, y: i32, cursor: bool, indent: usize) { fn render_indent(frame: &mut Frame, x: i32, y: i32, cursor: bool, indent: usize) {
for i in 0..indent { let style = if cursor {
let pos = Pos::new(x + util::after_indent(i), y); style_indent_inverted()
} else {
style_indent()
};
let style = if cursor { let mut styled = Styled::default();
style_indent_inverted() for _ in 0..indent {
} else { styled = styled.then((INDENT, style));
style_indent()
};
frame.write(pos, INDENT, style);
} }
frame.write(Pos::new(x + util::after_indent(0), y), styled);
} }
fn render_nick( fn render_nick(frame: &mut Frame, x: i32, y: i32, indent: usize, nick: Styled) {
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_pos = Pos::new(x + util::after_indent(indent), y);
let inner_nick_pos = Pos::new(nick_pos.x + 1, nick_pos.y); let styled = Styled::new("[").and_then(nick).then("]");
frame.write(nick_pos, &format!("[{nick}]"), ContentStyle::default()); frame.write(nick_pos, styled);
frame.write(inner_nick_pos, nick, nick_style);
} }
fn render_block<M: Msg>(frame: &mut Frame, pos: Pos, size: Size, block: &Block<M::Id>) { fn render_block<M: Msg>(frame: &mut Frame, pos: Pos, size: Size, block: Block<M::Id>) {
match &block.body { match block.body {
BlockBody::Msg(msg) => { BlockBody::Msg(msg) => {
let after_nick = util::after_nick(frame, block.indent, &msg.nick); let after_nick = util::after_nick(frame, block.indent, &msg.nick.text());
for (i, line) in msg.lines.iter().enumerate() { for (i, line) in msg.lines.into_iter().enumerate() {
let y = pos.y + block.line + i as i32; let y = pos.y + block.line + i as i32;
if y < 0 || y >= pos.y + size.height as i32 { if y < 0 || y >= pos.y + size.height as i32 {
continue; continue;
@ -72,7 +65,7 @@ fn render_block<M: Msg>(frame: &mut Frame, pos: Pos, size: Size, block: &Block<M
if i == 0 { if i == 0 {
render_indent(frame, pos.x, y, block.cursor, block.indent); render_indent(frame, pos.x, y, block.cursor, block.indent);
render_time(frame, pos.x, y, block.cursor, block.time); render_time(frame, pos.x, y, block.cursor, block.time);
render_nick(frame, pos.x, y, block.indent, &msg.nick, msg.nick_style); render_nick(frame, pos.x, y, block.indent, msg.nick.clone());
} else { } else {
render_indent(frame, pos.x, y, false, block.indent + 1); render_indent(frame, pos.x, y, false, block.indent + 1);
render_indent(frame, pos.x, y, block.cursor, block.indent); render_indent(frame, pos.x, y, block.cursor, block.indent);
@ -80,7 +73,7 @@ fn render_block<M: Msg>(frame: &mut Frame, pos: Pos, size: Size, block: &Block<M
} }
let line_pos = Pos::new(pos.x + after_nick, y); let line_pos = Pos::new(pos.x + after_nick, y);
frame.write(line_pos, line, ContentStyle::default()); frame.write(line_pos, line);
} }
} }
BlockBody::Placeholder => { BlockBody::Placeholder => {
@ -88,14 +81,14 @@ fn render_block<M: Msg>(frame: &mut Frame, pos: Pos, size: Size, block: &Block<M
render_time(frame, pos.x, y, block.cursor, block.time); render_time(frame, pos.x, y, block.cursor, block.time);
render_indent(frame, pos.x, y, block.cursor, block.indent); render_indent(frame, pos.x, y, block.cursor, block.indent);
let pos = Pos::new(pos.x + util::after_indent(block.indent), y); let pos = Pos::new(pos.x + util::after_indent(block.indent), y);
frame.write(pos, PLACEHOLDER, style_placeholder()); frame.write(pos, (PLACEHOLDER, style_placeholder()));
} }
} }
} }
impl<M: Msg> TreeView<M> { impl<M: Msg> TreeView<M> {
pub fn render_blocks(frame: &mut Frame, pos: Pos, size: Size, layout: &Blocks<M::Id>) { pub fn render_blocks(frame: &mut Frame, pos: Pos, size: Size, layout: Blocks<M::Id>) {
for block in &layout.blocks { for block in layout.blocks {
render_block::<M>(frame, pos, size, block); render_block::<M>(frame, pos, size, block);
} }
} }

View file

@ -7,6 +7,7 @@ use crossterm::style::{ContentStyle, Stylize};
use log::{Level, Log}; use log::{Level, Log};
use parking_lot::Mutex; use parking_lot::Mutex;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use toss::styled::Styled;
use crate::store::{Msg, MsgStore, Path, Tree}; use crate::store::{Msg, MsgStore, Path, Tree};
@ -33,22 +34,20 @@ impl Msg for LogMsg {
self.time self.time
} }
fn nick(&self) -> String { fn nick(&self) -> Styled {
format!("{}", self.level) let style = match self.level {
}
fn nick_style(&self) -> ContentStyle {
match self.level {
Level::Error => ContentStyle::default().bold().red(), Level::Error => ContentStyle::default().bold().red(),
Level::Warn => ContentStyle::default().bold().yellow(), Level::Warn => ContentStyle::default().bold().yellow(),
Level::Info => ContentStyle::default().bold().green(), Level::Info => ContentStyle::default().bold().green(),
Level::Debug => ContentStyle::default().bold().blue(), Level::Debug => ContentStyle::default().bold().blue(),
Level::Trace => ContentStyle::default().bold().magenta(), Level::Trace => ContentStyle::default().bold().magenta(),
} };
let text = format!("{}", self.level);
Styled::new((text, style))
} }
fn content(&self) -> String { fn content(&self) -> Styled {
self.content.clone() Styled::new(&self.content)
} }
} }

View file

@ -1,5 +1,7 @@
#![warn(clippy::use_self)] #![warn(clippy::use_self)]
// TODO Clean up use and manipulation of toss Pos and Size
mod chat; mod chat;
mod euph; mod euph;
mod logger; mod logger;

View file

@ -4,7 +4,7 @@ use std::hash::Hash;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use crossterm::style::ContentStyle; use toss::styled::Styled;
pub trait Msg { pub trait Msg {
type Id: Clone + Debug + Hash + Eq + Ord; type Id: Clone + Debug + Hash + Eq + Ord;
@ -12,9 +12,8 @@ pub trait Msg {
fn parent(&self) -> Option<Self::Id>; fn parent(&self) -> Option<Self::Id>;
fn time(&self) -> DateTime<Utc>; fn time(&self) -> DateTime<Utc>;
fn nick(&self) -> String; fn nick(&self) -> Styled;
fn nick_style(&self) -> ContentStyle; fn content(&self) -> Styled;
fn content(&self) -> String;
} }
#[derive(PartialEq, Eq, PartialOrd, Ord)] #[derive(PartialEq, Eq, PartialOrd, Ord)]

View file

@ -1,7 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crossterm::event::{KeyCode, KeyEvent}; use crossterm::event::{KeyCode, KeyEvent};
use crossterm::style::ContentStyle;
use parking_lot::FairMutex; use parking_lot::FairMutex;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use toss::frame::{Frame, Pos, Size}; use toss::frame::{Frame, Pos, Size};
@ -80,8 +79,8 @@ impl EuphRoom {
// Clear area in case something accidentally wrote on it already // Clear area in case something accidentally wrote on it already
let size = frame.size(); let size = frame.size();
for x in 0..size.width as i32 { for x in 0..size.width as i32 {
frame.write(Pos::new(x, 0), " ", ContentStyle::default()); frame.write(Pos::new(x, 0), " ");
frame.write(Pos::new(x, 1), "", ContentStyle::default()); frame.write(Pos::new(x, 1), "");
} }
// Write status // Write status
@ -104,7 +103,7 @@ impl EuphRoom {
} }
} }
}; };
frame.write(Pos::new(0, 0), &status, ContentStyle::default()); frame.write(Pos::new(0, 0), status);
} }
pub async fn handle_key_event( pub async fn handle_key_event(

View file

@ -145,7 +145,7 @@ impl Rooms {
}; };
for x in 0..size.width { for x in 0..size.width {
frame.write(Pos::new(x.into(), y), " ", style); frame.write(Pos::new(x.into(), y), (" ", style));
} }
let suffix = if let Some(room) = self.euph_rooms.get(room) { let suffix = if let Some(room) = self.euph_rooms.get(room) {
if room.connected() { if room.connected() {
@ -157,7 +157,7 @@ impl Rooms {
"" ""
}; };
let room_str = format!("&{room}{suffix}"); let room_str = format!("&{room}{suffix}");
frame.write(Pos::new(0, y), &room_str, style); frame.write(Pos::new(0, y), (&room_str, style));
} }
} }

View file

@ -1,11 +1,11 @@
use std::mem; use std::mem;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, TimeZone, Utc}; use chrono::{DateTime, Utc};
use crossterm::style::ContentStyle;
use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}; use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef};
use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Transaction}; use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Transaction};
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
use toss::styled::Styled;
use crate::euph; use crate::euph;
use crate::euph::api::{Message, Snowflake, Time}; use crate::euph::api::{Message, Snowflake, Time};
@ -63,16 +63,12 @@ impl Msg for EuphMsg {
self.time.0 self.time.0
} }
fn nick(&self) -> String { fn nick(&self) -> Styled {
self.nick.clone() (&self.nick, euph::nick_style(&self.nick)).into()
} }
fn nick_style(&self) -> ContentStyle { fn content(&self) -> Styled {
euph::nick_style(&self.nick) self.content.trim().into()
}
fn content(&self) -> String {
self.content.trim().to_string()
} }
} }