diff --git a/src/app/browser/window/tab/item/page/content/text/gemini/reader.rs b/src/app/browser/window/tab/item/page/content/text/gemini/reader.rs index abb44ff2..cdf81817 100644 --- a/src/app/browser/window/tab/item/page/content/text/gemini/reader.rs +++ b/src/app/browser/window/tab/item/page/content/text/gemini/reader.rs @@ -1,10 +1,12 @@ mod ansi; pub mod error; +mod icon; mod syntax; mod tag; mod widget; pub use error::Error; +use icon::Icon; use syntax::Syntax; use tag::Tag; use widget::Widget; @@ -58,6 +60,9 @@ impl Reader { // Init multiline code builder features let mut multiline = None; + // Init quote icon feature + let mut is_line_after_quote = false; + // Init colors // @TODO use accent colors in adw 1.6 / ubuntu 24.10+ let link_color = (RGBA::new(0.2, 0.5, 0.9, 1.0), RGBA::new(0.2, 0.5, 0.9, 0.9)); @@ -65,6 +70,9 @@ impl Reader { // Init syntect highlight features let syntax = Syntax::new(); + // Init icons + let icon = Icon::new(); + // Init tags let tag = Tag::new(); @@ -282,12 +290,24 @@ impl Reader { // Is quote if let Some(quote) = Quote::from(line) { + // Show quote indicator if last line is not quote (to prevent duplicates) + if !is_line_after_quote { + // Show only if the icons resolved for default `Display` + if let Some(ref icon) = icon { + buffer.insert_paintable(&mut buffer.end_iter(), &icon.quote); + buffer.insert(&mut buffer.end_iter(), NEW_LINE); + } + } + is_line_after_quote = true; + // Append value to buffer buffer.insert_with_tags(&mut buffer.end_iter(), "e.value, &[&tag.quote]); buffer.insert(&mut buffer.end_iter(), NEW_LINE); // Skip other actions for this line continue; + } else { + is_line_after_quote = false; } // Nothing match custom tags above, diff --git a/src/app/browser/window/tab/item/page/content/text/gemini/reader/icon.rs b/src/app/browser/window/tab/item/page/content/text/gemini/reader/icon.rs new file mode 100644 index 00000000..203d1c65 --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/text/gemini/reader/icon.rs @@ -0,0 +1,31 @@ +use gtk::{gdk::Display, IconLookupFlags, IconPaintable, IconTheme, TextDirection}; + +const SIZE: i32 = 16; + +/// Indication icons asset (for tag blocks decoration) +pub struct Icon { + pub quote: IconPaintable, + // @TODO other tags.. +} + +impl Icon { + pub fn new() -> Option { + Display::default().map(|display| { + let theme = IconTheme::for_display(&display); + Self { + quote: icon(&theme, "mail-forward-symbolic"), + } + }) + } +} + +fn icon(theme: &IconTheme, name: &str) -> IconPaintable { + theme.lookup_icon( + name, + &[], // @TODO + SIZE, + SIZE, + TextDirection::None, + IconLookupFlags::FORCE_SYMBOLIC, + ) +} diff --git a/src/app/browser/window/tab/item/page/content/text/gemini/reader/tag/quote.rs b/src/app/browser/window/tab/item/page/content/text/gemini/reader/tag/quote.rs index 3a151443..d97d7ff7 100644 --- a/src/app/browser/window/tab/item/page/content/text/gemini/reader/tag/quote.rs +++ b/src/app/browser/window/tab/item/page/content/text/gemini/reader/tag/quote.rs @@ -1,8 +1,8 @@ -use gtk::{pango::Style, TextTag, WrapMode}; +use gtk::{TextTag, WrapMode}; pub fn new() -> TextTag { TextTag::builder() - .style(Style::Italic) + .left_margin(28) .wrap_mode(WrapMode::Word) .build() }