From 1cc3ddaf2ea333cf7becd69822a28bc4b629cb53 Mon Sep 17 00:00:00 2001 From: yggverse Date: Thu, 26 Sep 2024 14:30:54 +0300 Subject: [PATCH] draft gemtext composer --- src/browser/main/tab/page/content/mod.rs | 32 ++++++++++++++++++- .../main/tab/page/content/text/gemini/mod.rs | 30 +++++++++++++++++ .../page/content/text/gemini/reader/mod.rs | 4 ++- src/browser/main/tab/page/content/text/mod.rs | 19 ++++++++--- src/browser/main/tab/page/mod.rs | 12 +++++-- 5 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 src/browser/main/tab/page/content/text/gemini/mod.rs diff --git a/src/browser/main/tab/page/content/mod.rs b/src/browser/main/tab/page/content/mod.rs index 81dc018c..a4e313e5 100644 --- a/src/browser/main/tab/page/content/mod.rs +++ b/src/browser/main/tab/page/content/mod.rs @@ -1,6 +1,18 @@ -use gtk::{Box, Orientation}; +// @TODO mod image; +mod text; + +use text::Text; + +use gtk::{prelude::BoxExt, Box, Orientation}; + +pub enum Mime { + Undefined, + TextGemini, + TextPlain, +} pub struct Content { + mime: Mime, widget: Box, } @@ -8,10 +20,28 @@ impl Content { // Construct pub fn new() -> Self { Self { + mime: Mime::Undefined, widget: Box::builder().orientation(Orientation::Vertical).build(), } } + // Actions + pub fn reset(&self, mime: Mime, data: &str) { + //self.widget.remove(self.child.widget()); + match mime { + Mime::TextGemini => { + let child = Text::gemini(data); + self.widget.append(child.widget()); + } + Mime::TextPlain => { + todo!() + } + Mime::Undefined => { + todo!() + } + } + } + // Getters pub fn widget(&self) -> &Box { &self.widget diff --git a/src/browser/main/tab/page/content/text/gemini/mod.rs b/src/browser/main/tab/page/content/text/gemini/mod.rs new file mode 100644 index 00000000..42d532d9 --- /dev/null +++ b/src/browser/main/tab/page/content/text/gemini/mod.rs @@ -0,0 +1,30 @@ +mod reader; + +use reader::Reader; + +use gtk::Viewport; + +pub struct Gemini { + widget: Viewport, +} + +impl Gemini { + // Construct + pub fn new(gemtext: &str) -> Self { + // Init components + let reader = Reader::new(gemtext); + + // Init widget + let widget = Viewport::builder().scroll_to_focus(false).build(); + + widget.set_child(Some(reader.widget())); + + // Result + Self { widget } + } + + // Getters + pub fn widget(&self) -> &Viewport { + &self.widget + } +} diff --git a/src/browser/main/tab/page/content/text/gemini/reader/mod.rs b/src/browser/main/tab/page/content/text/gemini/reader/mod.rs index 572aa23b..d3198e9b 100644 --- a/src/browser/main/tab/page/content/text/gemini/reader/mod.rs +++ b/src/browser/main/tab/page/content/text/gemini/reader/mod.rs @@ -6,16 +6,18 @@ pub struct Reader { impl Reader { // Construct - pub fn new() -> Self { + pub fn new(gemtext: &str) -> Self { Self { widget: Label::builder() .halign(Align::Start) .valign(Align::Start) + .vexpand(true) .margin_start(8) .margin_end(8) .wrap(true) .selectable(true) .use_markup(true) + .label(gemtext) // @TODO .build(), } } diff --git a/src/browser/main/tab/page/content/text/mod.rs b/src/browser/main/tab/page/content/text/mod.rs index a7630ae7..5e6e60ed 100644 --- a/src/browser/main/tab/page/content/text/mod.rs +++ b/src/browser/main/tab/page/content/text/mod.rs @@ -1,3 +1,7 @@ +mod gemini; + +use gemini::Gemini; + use gtk::ScrolledWindow; pub struct Text { @@ -6,10 +10,17 @@ pub struct Text { impl Text { // Construct - pub fn new() -> Self { - Self { - widget: ScrolledWindow::builder().build(), - } + pub fn gemini(gemtext: &str) -> Self { + // Init components + let gemini = Gemini::new(gemtext); + + // Init widget + let widget = ScrolledWindow::builder().build(); + + widget.set_child(Some(gemini.widget())); + + // Result + Self { widget } } // Getters diff --git a/src/browser/main/tab/page/mod.rs b/src/browser/main/tab/page/mod.rs index 5c2dda22..77ec4c95 100644 --- a/src/browser/main/tab/page/mod.rs +++ b/src/browser/main/tab/page/mod.rs @@ -61,6 +61,7 @@ impl Page { let request_text = self.navigation.request_text(); // Init shared objects for async access + let content = self.content.clone(); let meta = self.meta.clone(); let widget = self.widget.clone(); @@ -148,6 +149,8 @@ impl Page { RegexMatchFlags::DEFAULT, ); + println!("{:?}",parts); + // https://geminiprotocol.net/docs/protocol-specification.gmi#status-codes match parts.get(1) { Some(code) => match code.as_str() { @@ -155,12 +158,17 @@ impl Page { match parts.get(2) { Some(mime) => match mime.as_str() { "text/gemini" => { + // Update meta meta.borrow_mut().mime = Mime::TextGemini; - // @TODO + // Select widget + match parts.get(4) { + Some(source) => content.reset(content::Mime::TextGemini, source), + None => todo!(), + } }, "text/plain" => { meta.borrow_mut().mime = Mime::TextPlain; - // @TODO + todo!() }, _ => { meta.borrow_mut().title = GString::from("Oops");