Turn ChatMessage into drawing

This commit is contained in:
Joscha 2024-03-30 12:52:39 +01:00
parent 13ee9c5267
commit 57fc128be0
3 changed files with 101 additions and 103 deletions

View file

@ -1,25 +1,18 @@
mod calendar; mod calendar;
mod cells; mod cells;
mod chat_message;
mod image; mod image;
mod photo; mod photo;
mod text; mod text;
use showbits_common::{ use showbits_common::widgets::{FontStuff, HasFontStuff};
color::{BLACK, WHITE},
widgets::{Block, FontStuff, HasFontStuff, Text},
Node, Tree, WidgetExt,
};
use taffy::{
style_helpers::{length, percent},
AlignItems, FlexDirection,
};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use crate::printer::Printer; use crate::printer::Printer;
pub use self::{ pub use self::{
calendar::CalendarDrawing, cells::CellsDrawing, image::ImageDrawing, photo::PhotoDrawing, calendar::CalendarDrawing, cells::CellsDrawing, chat_message::ChatMessageDrawing,
text::TextDrawing, image::ImageDrawing, photo::PhotoDrawing, text::TextDrawing,
}; };
#[derive(Default)] #[derive(Default)]
@ -31,17 +24,11 @@ pub trait Drawing {
fn draw(&self, printer: &mut Printer, ctx: &mut Context) -> anyhow::Result<()>; fn draw(&self, printer: &mut Printer, ctx: &mut Context) -> anyhow::Result<()>;
} }
pub struct BoxedDrawing(Box<dyn Drawing + Send>); pub struct Command(Box<dyn Drawing + Send>);
pub enum Command {
Draw(BoxedDrawing),
ChatMessage { username: String, content: String },
}
impl Command { impl Command {
pub fn draw<D: Drawing + Send + 'static>(drawing: D) -> Self { pub fn draw<D: Drawing + Send + 'static>(drawing: D) -> Self {
Self::Draw(BoxedDrawing(Box::new(drawing))) Self(Box::new(drawing))
} }
} }
@ -68,88 +55,8 @@ impl Drawer {
pub fn run(&mut self) -> anyhow::Result<()> { pub fn run(&mut self) -> anyhow::Result<()> {
while let Some(command) = self.rx.blocking_recv() { while let Some(command) = self.rx.blocking_recv() {
self.on_command(command)?; command.0.draw(&mut self.printer, &mut self.ctx)?;
} }
Ok(()) Ok(())
} }
fn on_command(&mut self, command: Command) -> anyhow::Result<()> {
match command {
Command::Draw(drawing) => drawing.0.draw(&mut self.printer, &mut self.ctx)?,
Command::ChatMessage { username, content } => {
self.on_chat_message(username, content)?
}
}
Ok(())
}
fn on_chat_message(&mut self, username: String, content: String) -> anyhow::Result<()> {
let mut tree = Tree::<Context>::new(WHITE);
let max_username_width_in_chars = 32.0;
let max_username_height_in_lines = 3.0;
let max_content_height_in_lines = 16.0;
let username = Text::new()
.and_plain(username)
.widget(&mut self.ctx.font_stuff)
.node()
.with_max_size_width(length(max_username_width_in_chars * 8.0))
.with_max_size_height(length(max_username_height_in_lines * 16.0))
.register(&mut tree)?;
let username = Block::new()
.with_border(BLACK)
.node()
.with_border_all(length(1.0))
.with_padding_horiz(length(1.0))
.with_flex_shrink(0.0) // Avoid wrapping
.and_child(username)
.register(&mut tree)?;
let content = if let Some(content) = content.strip_prefix("/me") {
let content = content.trim_start();
let content = Text::new()
.and_plain(content)
.widget(&mut self.ctx.font_stuff)
.node()
.with_max_size_height(length(max_content_height_in_lines * 16.0))
.register(&mut tree)?;
Block::new()
.with_border(BLACK)
.node()
.with_border_all(length(1.0))
.with_padding_horiz(length(1.0))
.and_child(content)
.register(&mut tree)?
} else {
let content = Text::new()
.and_plain(content)
.widget(&mut self.ctx.font_stuff)
.node()
.with_max_size_height(length(max_content_height_in_lines * 16.0))
.register(&mut tree)?;
Node::empty()
.with_padding_vert(length(1.0))
.and_child(content)
.register(&mut tree)?
};
let root = Node::empty()
.with_size_width(percent(1.0))
.with_padding_all(length(1.0))
.with_flex_direction(FlexDirection::Row)
.with_align_items(Some(AlignItems::Start))
.with_gap_width(length(2.0))
.and_child(username)
.and_child(content)
.register(&mut tree)?;
self.printer.print_tree(&mut tree, &mut self.ctx, root)?;
Ok(())
}
} }

View file

@ -0,0 +1,90 @@
use showbits_common::{
color::{BLACK, WHITE},
widgets::{Block, Text},
Node, Tree, WidgetExt,
};
use taffy::{
style_helpers::{length, percent},
AlignItems, Display, FlexDirection,
};
use crate::printer::Printer;
use super::{Context, Drawing};
pub struct ChatMessageDrawing {
pub username: String,
pub content: String,
}
impl Drawing for ChatMessageDrawing {
fn draw(&self, printer: &mut Printer, ctx: &mut Context) -> anyhow::Result<()> {
let mut tree = Tree::<Context>::new(WHITE);
let max_username_width_in_chars = 32.0;
let max_username_height_in_lines = 3.0;
let max_content_height_in_lines = 16.0;
let username = Text::new()
.and_plain(&self.username)
.widget(&mut ctx.font_stuff)
.node()
.with_max_size_width(length(max_username_width_in_chars * 8.0))
.with_max_size_height(length(max_username_height_in_lines * 16.0))
.register(&mut tree)?;
let username = Block::new()
.with_border(BLACK)
.node()
.with_border_all(length(1.0))
.with_padding_horiz(length(1.0))
.with_flex_shrink(0.0) // Avoid wrapping
.and_child(username)
.register(&mut tree)?;
let content = if let Some(content) = self.content.strip_prefix("/me") {
let content = content.trim_start();
let content = Text::new()
.and_plain(content)
.widget(&mut ctx.font_stuff)
.node()
.with_max_size_height(length(max_content_height_in_lines * 16.0))
.register(&mut tree)?;
Block::new()
.with_border(BLACK)
.node()
.with_border_all(length(1.0))
.with_padding_horiz(length(1.0))
.and_child(content)
.register(&mut tree)?
} else {
let content = Text::new()
.and_plain(&self.content)
.widget(&mut ctx.font_stuff)
.node()
.with_max_size_height(length(max_content_height_in_lines * 16.0))
.register(&mut tree)?;
Node::empty()
.with_padding_vert(length(1.0))
.and_child(content)
.register(&mut tree)?
};
let root = Node::empty()
.with_size_width(percent(1.0))
.with_padding_all(length(1.0))
.with_display(Display::Flex)
.with_flex_direction(FlexDirection::Row)
.with_align_items(Some(AlignItems::Start))
.with_gap_width(length(2.0))
.and_child(username)
.and_child(content)
.register(&mut tree)?;
printer.print_tree(&mut tree, ctx, root)?;
Ok(())
}
}

View file

@ -13,7 +13,8 @@ use serde::Deserialize;
use tokio::{net::TcpListener, sync::mpsc}; use tokio::{net::TcpListener, sync::mpsc};
use crate::drawer::{ use crate::drawer::{
CalendarDrawing, CellsDrawing, Command, ImageDrawing, PhotoDrawing, TextDrawing, CalendarDrawing, CellsDrawing, ChatMessageDrawing, Command, ImageDrawing, PhotoDrawing,
TextDrawing,
}; };
use self::{r#static::get_static_file, statuscode::status_code}; use self::{r#static::get_static_file, statuscode::status_code};
@ -123,10 +124,10 @@ struct PostChatMessageForm {
async fn post_chat_message(server: State<Server>, request: Form<PostChatMessageForm>) { async fn post_chat_message(server: State<Server>, request: Form<PostChatMessageForm>) {
let _ = server let _ = server
.tx .tx
.send(Command::ChatMessage { .send(Command::draw(ChatMessageDrawing {
username: request.0.username, username: request.0.username,
content: request.0.content, content: request.0.content,
}) }))
.await; .await;
} }