diff --git a/Cargo.lock b/Cargo.lock index 9db6bb3..8839b7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1313,8 +1313,9 @@ dependencies = [ [[package]] name = "toss" version = "0.1.0" -source = "git+https://github.com/Garmelon/toss.git?rev=0d59116012a51516a821991e2969b1cf4779770f#0d59116012a51516a821991e2969b1cf4779770f" +source = "git+https://github.com/Garmelon/toss.git?rev=59710c816269c434b97ece3ab1701d3fef2269cb#59710c816269c434b97ece3ab1701d3fef2269cb" dependencies = [ + "async-trait", "crossterm", "unicode-linebreak", "unicode-segmentation", diff --git a/Cargo.toml b/Cargo.toml index 89209ed..63742b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ features = ["bot"] [dependencies.toss] git = "https://github.com/Garmelon/toss.git" -rev = "0d59116012a51516a821991e2969b1cf4779770f" +rev = "59710c816269c434b97ece3ab1701d3fef2269cb" # [patch."https://github.com/Garmelon/toss.git"] # toss = { path = "../toss/" } diff --git a/src/euph/small_message.rs b/src/euph/small_message.rs index 4d2f4f4..2751058 100644 --- a/src/euph/small_message.rs +++ b/src/euph/small_message.rs @@ -1,9 +1,9 @@ use std::mem; -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use euphoxide::api::{MessageId, Snowflake, Time}; use time::OffsetDateTime; -use toss::styled::Styled; +use toss::{Style, Styled}; use crate::store::Msg; use crate::ui::ChatMsg; @@ -35,7 +35,7 @@ enum Span { struct Highlighter<'a> { content: &'a str, - base_style: ContentStyle, + base_style: Style, exact: bool, span: Span, @@ -177,7 +177,7 @@ impl<'a> Highlighter<'a> { self.room_or_mention_possible = !char.is_alphanumeric(); } - fn highlight(content: &'a str, base_style: ContentStyle, exact: bool) -> Styled { + fn highlight(content: &'a str, base_style: Style, exact: bool) -> Styled { let mut this = Self { content: if exact { content } else { content.trim() }, base_style, @@ -198,7 +198,7 @@ impl<'a> Highlighter<'a> { } } -fn highlight_content(content: &str, base_style: ContentStyle, exact: bool) -> Styled { +fn highlight_content(content: &str, base_style: Style, exact: bool) -> Styled { Highlighter::highlight(content, base_style, exact) } @@ -216,13 +216,13 @@ fn as_me(content: &str) -> Option<&str> { content.strip_prefix("/me") } -fn style_me() -> ContentStyle { - ContentStyle::default().grey().italic() +fn style_me() -> Style { + Style::new().grey().italic() } fn styled_nick(nick: &str) -> Styled { Styled::new_plain("[") - .and_then(util::style_nick(nick, ContentStyle::default())) + .and_then(util::style_nick(nick, Style::new())) .then_plain("]") } @@ -232,7 +232,7 @@ fn styled_nick_me(nick: &str) -> Styled { } fn styled_content(content: &str) -> Styled { - highlight_content(content.trim(), ContentStyle::default(), false) + highlight_content(content.trim(), Style::new(), false) } fn styled_content_me(content: &str) -> Styled { @@ -244,7 +244,7 @@ fn styled_editor_content(content: &str) -> Styled { let style = if as_me(content).is_some() { style_me() } else { - ContentStyle::default() + Style::new() }; highlight_content(content, style, true) } diff --git a/src/euph/util.rs b/src/euph/util.rs index 4769c7b..fdf11a3 100644 --- a/src/euph/util.rs +++ b/src/euph/util.rs @@ -1,7 +1,7 @@ -use crossterm::style::{Color, ContentStyle, Stylize}; +use crossterm::style::{Color, Stylize}; use euphoxide::Emoji; use once_cell::sync::Lazy; -use toss::styled::Styled; +use toss::{Style, Styled}; pub static EMOJI: Lazy = Lazy::new(Emoji::load); @@ -42,15 +42,15 @@ pub fn nick_color(nick: &str) -> (u8, u8, u8) { hsl_to_rgb(hue, 1.0, 0.72) } -pub fn nick_style(nick: &str, base: ContentStyle) -> ContentStyle { +pub fn nick_style(nick: &str, base: Style) -> Style { let (r, g, b) = nick_color(nick); base.bold().with(Color::Rgb { r, g, b }) } -pub fn style_nick(nick: &str, base: ContentStyle) -> Styled { +pub fn style_nick(nick: &str, base: Style) -> Styled { Styled::new(EMOJI.replace(nick), nick_style(nick, base)) } -pub fn style_nick_exact(nick: &str, base: ContentStyle) -> Styled { +pub fn style_nick_exact(nick: &str, base: Style) -> Styled { Styled::new(nick, nick_style(nick, base)) } diff --git a/src/logger.rs b/src/logger.rs index f1d3cc0..731a000 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -3,12 +3,12 @@ use std::sync::Arc; use std::vec; use async_trait::async_trait; -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use log::{Level, LevelFilter, Log}; use parking_lot::Mutex; use time::OffsetDateTime; use tokio::sync::mpsc; -use toss::styled::Styled; +use toss::{Style, Styled}; use crate::store::{Msg, MsgStore, Path, Tree}; use crate::ui::ChatMsg; @@ -48,11 +48,11 @@ impl ChatMsg for LogMsg { fn styled(&self) -> (Styled, Styled) { let nick_style = 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(), + Level::Error => Style::new().bold().red(), + Level::Warn => Style::new().bold().yellow(), + Level::Info => Style::new().bold().green(), + Level::Debug => Style::new().bold().blue(), + Level::Trace => Style::new().bold().magenta(), }; let nick = Styled::new(format!("{}", self.level), nick_style); let content = Styled::new_plain(&self.content); diff --git a/src/main.rs b/src/main.rs index 116c75a..d5a402b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ use cookie::CookieJar; use directories::{BaseDirs, ProjectDirs}; use log::info; use tokio::sync::mpsc; -use toss::terminal::Terminal; +use toss::Terminal; use crate::config::Config; use crate::logger::Logger; diff --git a/src/ui.rs b/src/ui.rs index a9caaf9..208a8cd 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -14,7 +14,7 @@ use parking_lot::FairMutex; use tokio::sync::mpsc::error::TryRecvError; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::task; -use toss::terminal::Terminal; +use toss::Terminal; use crate::config::Config; use crate::logger::{LogMsg, Logger}; @@ -144,14 +144,7 @@ impl Ui { terminal.present()?; loop { - // 1. Measure grapheme widths if required - if terminal.measuring_required() { - let _guard = crossterm_lock.lock(); - terminal.measure_widths()?; - ok_or_return!(self.event_tx.send(UiEvent::GraphemeWidthsChanged), Ok(())); - } - - // 2. Handle events (in batches) + // 1. Handle events (in batches) let mut event = match event_rx.recv().await { Some(event) => event, None => return Ok(()), @@ -174,12 +167,18 @@ impl Ui { }; } - // 3. Render and present final state if redraw { + // 2. Draw and present resulting state terminal.autoresize()?; - terminal.frame().reset(); self.widget().await.render(terminal.frame()).await; terminal.present()?; + + // 3. Measure grapheme widths + if terminal.measuring_required() { + let _guard = crossterm_lock.lock(); + terminal.measure_widths()?; + ok_or_return!(self.event_tx.send(UiEvent::GraphemeWidthsChanged), Ok(())); + } } } } diff --git a/src/ui/chat.rs b/src/ui/chat.rs index 124d95d..475f7f0 100644 --- a/src/ui/chat.rs +++ b/src/ui/chat.rs @@ -11,9 +11,7 @@ use std::{fmt, io}; use async_trait::async_trait; use parking_lot::FairMutex; use time::OffsetDateTime; -use toss::frame::{Frame, Size}; -use toss::styled::Styled; -use toss::terminal::Terminal; +use toss::{Frame, Size, Styled, Terminal}; use crate::store::{Msg, MsgStore}; diff --git a/src/ui/chat/blocks.rs b/src/ui/chat/blocks.rs index 1389d43..240981c 100644 --- a/src/ui/chat/blocks.rs +++ b/src/ui/chat/blocks.rs @@ -1,7 +1,7 @@ use std::collections::{vec_deque, VecDeque}; use std::ops::Range; -use toss::frame::Frame; +use toss::Frame; use crate::macros::some_or_return; use crate::ui::widgets::BoxedWidget; diff --git a/src/ui/chat/tree.rs b/src/ui/chat/tree.rs index ad8e6ab..0749ac4 100644 --- a/src/ui/chat/tree.rs +++ b/src/ui/chat/tree.rs @@ -12,8 +12,7 @@ use std::sync::Arc; use async_trait::async_trait; use parking_lot::FairMutex; use tokio::sync::Mutex; -use toss::frame::{Frame, Pos, Size}; -use toss::terminal::Terminal; +use toss::{Frame, Pos, Size, Terminal}; use crate::macros::logging_unwrap; use crate::store::{Msg, MsgStore}; diff --git a/src/ui/chat/tree/layout.rs b/src/ui/chat/tree/layout.rs index baccfbe..f474bf9 100644 --- a/src/ui/chat/tree/layout.rs +++ b/src/ui/chat/tree/layout.rs @@ -1,4 +1,4 @@ -use toss::frame::Frame; +use toss::Frame; use crate::store::{Msg, MsgStore, Path, Tree}; use crate::ui::chat::blocks::Block; diff --git a/src/ui/chat/tree/widgets.rs b/src/ui/chat/tree/widgets.rs index 8854dcd..919d98b 100644 --- a/src/ui/chat/tree/widgets.rs +++ b/src/ui/chat/tree/widgets.rs @@ -2,9 +2,8 @@ mod indent; mod seen; mod time; -use crossterm::style::{ContentStyle, Stylize}; -use toss::styled::Styled; -use toss::widthdb::WidthDb; +use crossterm::style::Stylize; +use toss::{Style, Styled, WidthDb}; use super::super::ChatMsg; use crate::store::Msg; @@ -19,36 +18,36 @@ use self::indent::Indent; pub const PLACEHOLDER: &str = "[...]"; -pub fn style_placeholder() -> ContentStyle { - ContentStyle::default().dark_grey() +pub fn style_placeholder() -> Style { + Style::new().dark_grey() } -fn style_time(highlighted: bool) -> ContentStyle { +fn style_time(highlighted: bool) -> Style { if highlighted { - ContentStyle::default().black().on_white() + Style::new().black().on_white() } else { - ContentStyle::default().grey() + Style::new().grey() } } -fn style_indent(highlighted: bool) -> ContentStyle { +fn style_indent(highlighted: bool) -> Style { if highlighted { - ContentStyle::default().black().on_white() + Style::new().black().on_white() } else { - ContentStyle::default().dark_grey() + Style::new().dark_grey() } } -fn style_info() -> ContentStyle { - ContentStyle::default().italic().dark_grey() +fn style_info() -> Style { + Style::new().italic().dark_grey() } -fn style_editor_highlight() -> ContentStyle { - ContentStyle::default().black().on_cyan() +fn style_editor_highlight() -> Style { + Style::new().black().on_cyan() } -fn style_pseudo_highlight() -> ContentStyle { - ContentStyle::default().black().on_yellow() +fn style_pseudo_highlight() -> Style { + Style::new().black().on_yellow() } pub fn msg( @@ -74,7 +73,9 @@ pub fn msg( ), Segment::new(Indent::new(indent, style_indent(highlighted))), Segment::new(Layer::new(vec![ - Indent::new(1, style_indent(false)).into(), + Padding::new(Indent::new(1, style_indent(false))) + .top(1) + .into(), Padding::new(Text::new(nick)).right(1).into(), ])), // TODO Minimum content width @@ -129,7 +130,9 @@ pub fn editor( ), Segment::new(Indent::new(indent, style_editor_highlight())), Segment::new(Layer::new(vec![ - Indent::new(1, style_indent(false)).into(), + Padding::new(Indent::new(1, style_indent(false))) + .top(1) + .into(), Padding::new(Text::new(nick)).right(1).into(), ])), Segment::new(editor).priority(1).expanding(true), @@ -151,7 +154,9 @@ pub fn pseudo(indent: usize, nick: &str, editor: &EditorState) -> Bo ), Segment::new(Indent::new(indent, style_pseudo_highlight())), Segment::new(Layer::new(vec![ - Indent::new(1, style_indent(false)).into(), + Padding::new(Indent::new(1, style_indent(false))) + .top(1) + .into(), Padding::new(Text::new(nick)).right(1).into(), ])), Segment::new(Text::new(content).wrap(true)).priority(1), diff --git a/src/ui/chat/tree/widgets/indent.rs b/src/ui/chat/tree/widgets/indent.rs index d512102..4e120c6 100644 --- a/src/ui/chat/tree/widgets/indent.rs +++ b/src/ui/chat/tree/widgets/indent.rs @@ -1,6 +1,5 @@ use async_trait::async_trait; -use crossterm::style::ContentStyle; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size, Style}; use crate::ui::widgets::Widget; @@ -9,11 +8,11 @@ pub const INDENT_WIDTH: usize = 2; pub struct Indent { level: usize, - style: ContentStyle, + style: Style, } impl Indent { - pub fn new(level: usize, style: ContentStyle) -> Self { + pub fn new(level: usize, style: Style) -> Self { Self { level, style } } } diff --git a/src/ui/chat/tree/widgets/seen.rs b/src/ui/chat/tree/widgets/seen.rs index 8197afd..d53271b 100644 --- a/src/ui/chat/tree/widgets/seen.rs +++ b/src/ui/chat/tree/widgets/seen.rs @@ -1,4 +1,5 @@ -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; +use toss::Style; use crate::ui::widgets::background::Background; use crate::ui::widgets::empty::Empty; @@ -8,8 +9,8 @@ use crate::ui::widgets::BoxedWidget; const UNSEEN: &str = "*"; const WIDTH: u16 = 1; -fn seen_style() -> ContentStyle { - ContentStyle::default().black().on_green() +fn seen_style() -> Style { + Style::new().black().on_green() } pub fn widget(seen: bool) -> BoxedWidget { diff --git a/src/ui/chat/tree/widgets/time.rs b/src/ui/chat/tree/widgets/time.rs index 0976197..0801126 100644 --- a/src/ui/chat/tree/widgets/time.rs +++ b/src/ui/chat/tree/widgets/time.rs @@ -1,7 +1,7 @@ -use crossterm::style::ContentStyle; use time::format_description::FormatItem; use time::macros::format_description; use time::OffsetDateTime; +use toss::Style; use crate::ui::widgets::background::Background; use crate::ui::widgets::empty::Empty; @@ -11,7 +11,7 @@ use crate::ui::widgets::BoxedWidget; const TIME_FORMAT: &[FormatItem<'_>] = format_description!("[year]-[month]-[day] [hour]:[minute]"); const TIME_WIDTH: u16 = 16; -pub fn widget(time: Option, style: ContentStyle) -> BoxedWidget { +pub fn widget(time: Option, style: Style) -> BoxedWidget { if let Some(time) = time { let text = time.format(TIME_FORMAT).expect("could not format time"); Background::new(Text::new((text, style))) diff --git a/src/ui/euph/account.rs b/src/ui/euph/account.rs index 3112719..c303375 100644 --- a/src/ui/euph/account.rs +++ b/src/ui/euph/account.rs @@ -1,7 +1,7 @@ -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use euphoxide::api::PersonalAccountView; use euphoxide::conn; -use toss::terminal::Terminal; +use toss::{Style, Terminal}; use crate::euph::{self, Room}; use crate::ui::input::{key, InputEvent, KeyBindingsList}; @@ -36,7 +36,7 @@ impl LoggedOut { } fn widget(&self) -> BoxedWidget { - let bold = ContentStyle::default().bold(); + let bold = Style::new().bold(); VJoin::new(vec![ Segment::new(Text::new(("Not logged in", bold.yellow()))), Segment::new(Empty::new().height(1)), @@ -64,7 +64,7 @@ pub struct LoggedIn(PersonalAccountView); impl LoggedIn { fn widget(&self) -> BoxedWidget { - let bold = ContentStyle::default().bold(); + let bold = Style::new().bold(); VJoin::new(vec![ Segment::new(Text::new(("Logged in", bold.green()))), Segment::new(Empty::new().height(1)), diff --git a/src/ui/euph/auth.rs b/src/ui/euph/auth.rs index b9b72b9..682d967 100644 --- a/src/ui/euph/auth.rs +++ b/src/ui/euph/auth.rs @@ -1,4 +1,4 @@ -use toss::terminal::Terminal; +use toss::Terminal; use crate::euph::Room; use crate::ui::input::{key, InputEvent, KeyBindingsList}; diff --git a/src/ui/euph/inspect.rs b/src/ui/euph/inspect.rs index 4f1f427..2d15c15 100644 --- a/src/ui/euph/inspect.rs +++ b/src/ui/euph/inspect.rs @@ -1,7 +1,7 @@ -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use euphoxide::api::{Message, NickEvent, SessionView}; use euphoxide::conn::SessionInfo; -use toss::styled::Styled; +use toss::{Style, Styled}; use crate::ui::input::{key, InputEvent, KeyBindingsList}; use crate::ui::widgets::popup::Popup; @@ -11,31 +11,33 @@ use crate::ui::widgets::BoxedWidget; macro_rules! line { ( $text:ident, $name:expr, $val:expr ) => { $text = $text - .then($name, ContentStyle::default().cyan()) + .then($name, Style::new().cyan()) .then_plain(format!(" {}\n", $val)); }; ( $text:ident, $name:expr, $val:expr, debug ) => { $text = $text - .then($name, ContentStyle::default().cyan()) + .then($name, Style::new().cyan()) .then_plain(format!(" {:?}\n", $val)); }; ( $text:ident, $name:expr, $val:expr, optional ) => { if let Some(val) = $val { $text = $text - .then($name, ContentStyle::default().cyan()) + .then($name, Style::new().cyan()) .then_plain(format!(" {val}\n")); } else { $text = $text - .then($name, ContentStyle::default().cyan()) + .then($name, Style::new().cyan()) .then_plain(" ") - .then("none", ContentStyle::default().italic().grey()) + .then("none", Style::new().italic().grey()) .then_plain("\n"); } }; ( $text:ident, $name:expr, $val:expr, yes or no ) => { - $text = $text - .then($name, ContentStyle::default().cyan()) - .then_plain(if $val { " yes\n" } else { " no\n" }); + $text = $text.then($name, Style::new().cyan()).then_plain(if $val { + " yes\n" + } else { + " no\n" + }); }; } @@ -87,7 +89,7 @@ fn message_lines(mut text: Styled, msg: &Message) -> Styled { } pub fn session_widget(session: &SessionInfo) -> BoxedWidget { - let heading_style = ContentStyle::default().bold(); + let heading_style = Style::new().bold(); let text = match session { SessionInfo::Full(session) => { @@ -104,7 +106,7 @@ pub fn session_widget(session: &SessionInfo) -> BoxedWidget { } pub fn message_widget(msg: &Message) -> BoxedWidget { - let heading_style = ContentStyle::default().bold(); + let heading_style = Style::new().bold(); let mut text = Styled::new("Message", heading_style).then_plain("\n"); diff --git a/src/ui/euph/links.rs b/src/ui/euph/links.rs index b1ebcb0..9ccdc51 100644 --- a/src/ui/euph/links.rs +++ b/src/ui/euph/links.rs @@ -1,8 +1,8 @@ use std::io; -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use linkify::{LinkFinder, LinkKind}; -use toss::styled::Styled; +use toss::{Style, Styled}; use crate::ui::input::{key, InputEvent, KeyBindingsList}; use crate::ui::widgets::list::ListState; @@ -40,24 +40,18 @@ impl LinksState { } pub fn widget(&self) -> BoxedWidget { - let style_selected = ContentStyle::default().black().on_white(); + let style_selected = Style::new().black().on_white(); let mut list = self.list.widget().focus(true); if self.links.is_empty() { - list.add_unsel(Text::new(( - "No links found", - ContentStyle::default().grey().italic(), - ))) + list.add_unsel(Text::new(("No links found", Style::new().grey().italic()))) } for (id, link) in self.links.iter().enumerate() { let (line_normal, line_selected) = if let Some(number_key) = NUMBER_KEYS.get(id) { ( - Styled::new( - format!("[{number_key}]"), - ContentStyle::default().dark_grey().bold(), - ) - .then_plain(" ") - .then_plain(link), + Styled::new(format!("[{number_key}]"), Style::new().dark_grey().bold()) + .then_plain(" ") + .then_plain(link), Styled::new(format!("[{number_key}]"), style_selected.bold()) .then(" ", style_selected) .then(link, style_selected), diff --git a/src/ui/euph/nick.rs b/src/ui/euph/nick.rs index e520fef..18e3d5d 100644 --- a/src/ui/euph/nick.rs +++ b/src/ui/euph/nick.rs @@ -1,6 +1,5 @@ -use crossterm::style::ContentStyle; use euphoxide::conn::Joined; -use toss::terminal::Terminal; +use toss::{Style, Terminal}; use crate::euph::{self, Room}; use crate::ui::input::{key, InputEvent, KeyBindingsList}; @@ -17,7 +16,7 @@ pub fn new(joined: Joined) -> EditorState { pub fn widget(editor: &EditorState) -> BoxedWidget { let editor = editor .widget() - .highlight(|s| euph::style_nick_exact(s, ContentStyle::default())); + .highlight(|s| euph::style_nick_exact(s, Style::new())); Popup::new(Padding::new(editor).left(1)) .title("Choose nick") .inner_padding(false) diff --git a/src/ui/euph/nick_list.rs b/src/ui/euph/nick_list.rs index 926ca68..05ef864 100644 --- a/src/ui/euph/nick_list.rs +++ b/src/ui/euph/nick_list.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; use std::iter; -use crossterm::style::{Color, ContentStyle, Stylize}; +use crossterm::style::{Color, Stylize}; use euphoxide::api::{NickEvent, SessionId, SessionType, SessionView, UserId}; use euphoxide::conn::{Joined, SessionInfo}; -use toss::styled::Styled; +use toss::{Style, Styled}; use crate::euph; use crate::ui::widgets::background::Background; @@ -98,7 +98,7 @@ fn render_section( return; } - let heading_style = ContentStyle::new().bold(); + let heading_style = Style::new().bold(); if !list.is_empty() { list.add_unsel(Empty::new()); @@ -117,16 +117,16 @@ fn render_section( fn render_row(list: &mut List, session: &HalfSession, own_session: &SessionView) { let (name, style, style_inv, perms_style_inv) = if session.name.is_empty() { let name = "lurk"; - let style = ContentStyle::default().grey(); - let style_inv = ContentStyle::default().black().on_grey(); + let style = Style::new().grey(); + let style_inv = Style::new().black().on_grey(); (Cow::Borrowed(name), style, style_inv, style_inv) } else { let name = &session.name as &str; let (r, g, b) = euph::nick_color(name); let color = Color::Rgb { r, g, b }; - let style = ContentStyle::default().bold().with(color); - let style_inv = ContentStyle::default().bold().black().on(color); - let perms_style_inv = ContentStyle::default().black().on(color); + let style = Style::new().bold().with(color); + let style_inv = Style::new().bold().black().on(color); + let perms_style_inv = Style::new().black().on(color); (euph::EMOJI.replace(name), style, style_inv, perms_style_inv) }; diff --git a/src/ui/euph/popup.rs b/src/ui/euph/popup.rs index 8bc8c6c..d5cbe76 100644 --- a/src/ui/euph/popup.rs +++ b/src/ui/euph/popup.rs @@ -1,5 +1,5 @@ -use crossterm::style::{ContentStyle, Stylize}; -use toss::styled::Styled; +use crossterm::style::Stylize; +use toss::{Style, Styled}; use crate::ui::widgets::float::Float; use crate::ui::widgets::popup::Popup; @@ -12,10 +12,10 @@ pub enum RoomPopup { impl RoomPopup { fn server_error_widget(description: &str, reason: &str) -> BoxedWidget { - let border_style = ContentStyle::default().red().bold(); + let border_style = Style::new().red().bold(); let text = Styled::new_plain(description) .then_plain("\n\n") - .then("Reason:", ContentStyle::default().bold()) + .then("Reason:", Style::new().bold()) .then_plain(" ") .then_plain(reason); Popup::new(Text::new(text)) diff --git a/src/ui/euph/room.rs b/src/ui/euph/room.rs index 740d9f7..75d1f11 100644 --- a/src/ui/euph/room.rs +++ b/src/ui/euph/room.rs @@ -1,15 +1,14 @@ use std::collections::VecDeque; use std::sync::Arc; -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use euphoxide::api::{Data, Message, MessageId, PacketType, SessionId}; use euphoxide::bot::instance::{Event, ServerConfig}; use euphoxide::conn::{self, Joined, Joining, SessionInfo}; use parking_lot::FairMutex; use tokio::sync::oneshot::error::TryRecvError; use tokio::sync::{mpsc, oneshot}; -use toss::styled::Styled; -use toss::terminal::Terminal; +use toss::{Style, Styled, Terminal}; use crate::config; use crate::euph; @@ -277,7 +276,7 @@ impl EuphRoom { } async fn status_widget(&self, state: Option<&euph::State>) -> BoxedWidget { - let room_style = ContentStyle::default().bold().blue(); + let room_style = Style::new().bold().blue(); let mut info = Styled::new(format!("&{}", self.name()), room_style); info = match state { @@ -296,7 +295,7 @@ impl EuphRoom { info.then_plain(", present without nick") } else { info.then_plain(", present as ") - .and_then(euph::style_nick(nick, ContentStyle::default())) + .and_then(euph::style_nick(nick, Style::new())) } } }; @@ -305,7 +304,7 @@ impl EuphRoom { if unseen > 0 { info = info .then_plain(" (") - .then(format!("{unseen}"), ContentStyle::default().bold().green()) + .then(format!("{unseen}"), Style::new().bold().green()) .then_plain(")"); } diff --git a/src/ui/input.rs b/src/ui/input.rs index d8cf209..4c3362e 100644 --- a/src/ui/input.rs +++ b/src/ui/input.rs @@ -1,8 +1,8 @@ use std::convert::Infallible; use crossterm::event::{Event, KeyCode, KeyModifiers}; -use crossterm::style::{ContentStyle, Stylize}; -use toss::styled::Styled; +use crossterm::style::Stylize; +use toss::{Style, Styled}; use super::widgets::background::Background; use super::widgets::border::Border; @@ -94,8 +94,8 @@ impl KeyBindingsList { Self(state.widget()) } - fn binding_style() -> ContentStyle { - ContentStyle::default().cyan() + fn binding_style() -> Style { + Style::new().cyan() } pub fn widget(self) -> BoxedWidget { @@ -124,8 +124,7 @@ impl KeyBindingsList { } pub fn heading(&mut self, name: &str) { - self.0 - .add_unsel(Text::new((name, ContentStyle::default().bold()))); + self.0.add_unsel(Text::new((name, Style::new().bold()))); } pub fn binding(&mut self, binding: &str, description: &str) { diff --git a/src/ui/rooms.rs b/src/ui/rooms.rs index be59196..c0e875c 100644 --- a/src/ui/rooms.rs +++ b/src/ui/rooms.rs @@ -2,14 +2,13 @@ use std::collections::{HashMap, HashSet}; use std::iter; use std::sync::{Arc, Mutex}; -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use euphoxide::api::SessionType; use euphoxide::bot::instance::{Event, ServerConfig}; use euphoxide::conn::{self, Joined}; use parking_lot::FairMutex; use tokio::sync::mpsc; -use toss::styled::Styled; -use toss::terminal::Terminal; +use toss::{Style, Styled, Terminal}; use crate::config::{Config, RoomsSortOrder}; use crate::euph; @@ -199,7 +198,7 @@ impl Rooms { } fn new_room_widget(editor: &EditorState) -> BoxedWidget { - let room_style = ContentStyle::default().bold().blue(); + let room_style = Style::new().bold().blue(); let editor = editor.widget().highlight(|s| Styled::new(s, room_style)); Popup::new(HJoin::new(vec![ Segment::new(Text::new(("&", room_style))), @@ -210,8 +209,8 @@ impl Rooms { } fn delete_room_widget(name: &str, editor: &EditorState) -> BoxedWidget { - let warn_style = ContentStyle::default().bold().red(); - let room_style = ContentStyle::default().bold().blue(); + let warn_style = Style::new().bold().red(); + let room_style = Style::new().bold().blue(); let editor = editor.widget().highlight(|s| Styled::new(s, room_style)); let text = Styled::new_plain("Are you sure you want to delete ") .then("&", room_style) @@ -219,7 +218,7 @@ impl Rooms { .then_plain("?\n\n") .then_plain("This will delete the entire room history from your vault. ") .then_plain("To shrink your vault afterwards, run ") - .then("cove gc", ContentStyle::default().italic().grey()) + .then("cove gc", Style::new().italic().grey()) .then_plain(".\n\n") .then_plain("To confirm the deletion, ") .then_plain("enter the full name of the room and press enter:"); @@ -304,7 +303,7 @@ impl Rooms { } fn format_room_info(state: Option<&euph::State>, unseen: usize) -> Styled { - let unseen_style = ContentStyle::default().bold().green(); + let unseen_style = Style::new().bold().green(); let state = Self::format_room_state(state); let unseen = Self::format_unseen_msgs(unseen); @@ -336,7 +335,7 @@ impl Rooms { if self.euph_rooms.is_empty() { list.add_unsel(Text::new(( "Press F1 for key bindings", - ContentStyle::default().grey().italic(), + Style::new().grey().italic(), ))) } @@ -348,8 +347,8 @@ impl Rooms { } self.sort_rooms(&mut rooms); for (name, state, unseen) in rooms { - let room_style = ContentStyle::default().bold().blue(); - let room_sel_style = ContentStyle::default().bold().black().on_white(); + let room_style = Style::new().bold().blue(); + let room_sel_style = Style::new().bold().black().on_white(); let mut normal = Styled::new(format!("&{name}"), room_style); let mut selected = Styled::new(format!("&{name}"), room_sel_style); @@ -363,7 +362,7 @@ impl Rooms { } async fn rooms_widget(&self) -> BoxedWidget { - let heading_style = ContentStyle::default().bold(); + let heading_style = Style::new().bold(); let amount = self.euph_rooms.len(); let heading = Text::new(Styled::new("Rooms", heading_style).then_plain(format!(" ({amount})"))); diff --git a/src/ui/util.rs b/src/ui/util.rs index 583dcd5..2ba5241 100644 --- a/src/ui/util.rs +++ b/src/ui/util.rs @@ -2,7 +2,7 @@ use std::io; use std::sync::Arc; use parking_lot::FairMutex; -use toss::terminal::Terminal; +use toss::Terminal; use super::input::{key, InputEvent, KeyBindingsList}; use super::widgets::editor::EditorState; diff --git a/src/ui/widgets.rs b/src/ui/widgets.rs index 33c2c49..f5cb59c 100644 --- a/src/ui/widgets.rs +++ b/src/ui/widgets.rs @@ -19,7 +19,7 @@ pub mod rules; pub mod text; use async_trait::async_trait; -use toss::frame::{Frame, Size}; +use toss::{Frame, Size}; // TODO Add Error type and return Result-s (at least in Widget::render) diff --git a/src/ui/widgets/background.rs b/src/ui/widgets/background.rs index 4990bcf..f075a91 100644 --- a/src/ui/widgets/background.rs +++ b/src/ui/widgets/background.rs @@ -1,23 +1,22 @@ use async_trait::async_trait; -use crossterm::style::ContentStyle; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size, Style}; use super::{BoxedWidget, Widget}; pub struct Background { inner: BoxedWidget, - style: ContentStyle, + style: Style, } impl Background { pub fn new>(inner: W) -> Self { Self { inner: inner.into(), - style: ContentStyle::default(), + style: Style::new().opaque(), } } - pub fn style(mut self, style: ContentStyle) -> Self { + pub fn style(mut self, style: Style) -> Self { self.style = style; self } diff --git a/src/ui/widgets/border.rs b/src/ui/widgets/border.rs index fd32a9c..134312b 100644 --- a/src/ui/widgets/border.rs +++ b/src/ui/widgets/border.rs @@ -1,23 +1,22 @@ use async_trait::async_trait; -use crossterm::style::ContentStyle; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size, Style}; use super::{BoxedWidget, Widget}; pub struct Border { inner: BoxedWidget, - style: ContentStyle, + style: Style, } impl Border { pub fn new>(inner: W) -> Self { Self { inner: inner.into(), - style: ContentStyle::default(), + style: Style::new(), } } - pub fn style(mut self, style: ContentStyle) -> Self { + pub fn style(mut self, style: Style) -> Self { self.style = style; self } diff --git a/src/ui/widgets/cursor.rs b/src/ui/widgets/cursor.rs index 205c5c1..09856f4 100644 --- a/src/ui/widgets/cursor.rs +++ b/src/ui/widgets/cursor.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size}; use super::{BoxedWidget, Widget}; diff --git a/src/ui/widgets/editor.rs b/src/ui/widgets/editor.rs index 54c8fd4..088373e 100644 --- a/src/ui/widgets/editor.rs +++ b/src/ui/widgets/editor.rs @@ -2,12 +2,9 @@ use std::sync::Arc; use std::{io, iter}; use async_trait::async_trait; -use crossterm::style::{ContentStyle, Stylize}; +use crossterm::style::Stylize; use parking_lot::{FairMutex, Mutex}; -use toss::frame::{Frame, Pos, Size}; -use toss::styled::Styled; -use toss::terminal::Terminal; -use toss::widthdb::WidthDb; +use toss::{Frame, Pos, Size, Style, Styled, Terminal, WidthDb}; use unicode_segmentation::UnicodeSegmentation; use crate::ui::util; @@ -461,7 +458,7 @@ impl Editor { } pub fn hidden(self) -> Self { - self.hidden_with_placeholder(("", ContentStyle::default().grey().italic())) + self.hidden_with_placeholder(("", Style::new().grey().italic())) } pub fn hidden_with_placeholder>(mut self, placeholder: S) -> Self { diff --git a/src/ui/widgets/empty.rs b/src/ui/widgets/empty.rs index 40ff3bf..790c8b1 100644 --- a/src/ui/widgets/empty.rs +++ b/src/ui/widgets/empty.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Size}; +use toss::{Frame, Size}; use super::Widget; diff --git a/src/ui/widgets/float.rs b/src/ui/widgets/float.rs index 96f398c..6a82284 100644 --- a/src/ui/widgets/float.rs +++ b/src/ui/widgets/float.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size}; use super::{BoxedWidget, Widget}; diff --git a/src/ui/widgets/join.rs b/src/ui/widgets/join.rs index 04d01c0..00d18fa 100644 --- a/src/ui/widgets/join.rs +++ b/src/ui/widgets/join.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size}; use super::{BoxedWidget, Widget}; diff --git a/src/ui/widgets/layer.rs b/src/ui/widgets/layer.rs index 7c5e659..30807e6 100644 --- a/src/ui/widgets/layer.rs +++ b/src/ui/widgets/layer.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Size}; +use toss::{Frame, Size}; use super::{BoxedWidget, Widget}; diff --git a/src/ui/widgets/list.rs b/src/ui/widgets/list.rs index 8df110c..0dcd0aa 100644 --- a/src/ui/widgets/list.rs +++ b/src/ui/widgets/list.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use async_trait::async_trait; use parking_lot::Mutex; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size}; use super::{BoxedWidget, Widget}; diff --git a/src/ui/widgets/padding.rs b/src/ui/widgets/padding.rs index 74a7e29..e2be11d 100644 --- a/src/ui/widgets/padding.rs +++ b/src/ui/widgets/padding.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size}; use super::{BoxedWidget, Widget}; diff --git a/src/ui/widgets/popup.rs b/src/ui/widgets/popup.rs index 96ce7c2..b7ec0fe 100644 --- a/src/ui/widgets/popup.rs +++ b/src/ui/widgets/popup.rs @@ -1,5 +1,4 @@ -use crossterm::style::ContentStyle; -use toss::styled::Styled; +use toss::{Style, Styled}; use super::background::Background; use super::border::Border; @@ -13,8 +12,8 @@ pub struct Popup { inner: BoxedWidget, inner_padding: bool, title: Option, - border_style: ContentStyle, - bg_style: ContentStyle, + border_style: Style, + bg_style: Style, } impl Popup { @@ -23,8 +22,8 @@ impl Popup { inner: inner.into(), inner_padding: true, title: None, - border_style: ContentStyle::default(), - bg_style: ContentStyle::default(), + border_style: Style::new(), + bg_style: Style::new().opaque(), } } @@ -38,12 +37,12 @@ impl Popup { self } - pub fn border(mut self, style: ContentStyle) -> Self { + pub fn border(mut self, style: Style) -> Self { self.border_style = style; self } - pub fn background(mut self, style: ContentStyle) -> Self { + pub fn background(mut self, style: Style) -> Self { self.bg_style = style; self } diff --git a/src/ui/widgets/resize.rs b/src/ui/widgets/resize.rs index 15f5577..67c07ed 100644 --- a/src/ui/widgets/resize.rs +++ b/src/ui/widgets/resize.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Size}; +use toss::{Frame, Size}; use super::{BoxedWidget, Widget}; diff --git a/src/ui/widgets/rules.rs b/src/ui/widgets/rules.rs index 9fcc5df..f6b01c1 100644 --- a/src/ui/widgets/rules.rs +++ b/src/ui/widgets/rules.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Pos, Size}; +use toss::{Frame, Pos, Size}; use super::Widget; diff --git a/src/ui/widgets/text.rs b/src/ui/widgets/text.rs index 5ab65d8..1a383f5 100644 --- a/src/ui/widgets/text.rs +++ b/src/ui/widgets/text.rs @@ -1,7 +1,5 @@ use async_trait::async_trait; -use toss::frame::{Frame, Pos, Size}; -use toss::styled::Styled; -use toss::widthdb::WidthDb; +use toss::{Frame, Pos, Size, Styled, WidthDb}; use super::Widget;