diff --git a/src/app/browser/window/tab/item/page.rs b/src/app/browser/window/tab/item/page.rs index 4b5ba5d9..3965c7f0 100644 --- a/src/app/browser/window/tab/item/page.rs +++ b/src/app/browser/window/tab/item/page.rs @@ -275,8 +275,7 @@ impl Page { meta.borrow_mut().status = Some(Status::Success); // This content type may return parsed title - let result = content.reset(content::Mime::TextGemini, &uri, &source); - meta.borrow_mut().title = result.title.clone(); + meta.borrow_mut().title = content.set_text_gemini(&uri, &source); // Add new history record let request = uri.to_str(); @@ -326,8 +325,7 @@ impl Page { // Select widget match parts.get(3) { Some(source) => { - let _ = content.reset( - content::Mime::TextGemini, + let _ = content.set_text_gemini( &uri, // @TODO use template file &gformat!("# Redirect\n\nAuto-follow disabled, click on link below to continue\n\n=> {source}") @@ -410,12 +408,19 @@ impl Page { "nex" => {} */ scheme => { - // Update - meta.borrow_mut().status = Some(Status::Failure); - meta.borrow_mut().title = Some(gformat!("Oops")); - meta.borrow_mut().description = - Some(gformat!("Protocol {scheme} not supported")); + let status = Status::Failure; + let title = gformat!("Oops"); + let description = gformat!("Protocol {scheme} not supported"); + // Update widget + content.set_status_error(title.as_str(), description.as_str()); + + // Update meta + meta.borrow_mut().status = Some(status); + meta.borrow_mut().title = Some(title); + meta.borrow_mut().description = Some(description); + + // Update window action_update.activate(Some(&self.id.to_variant())); } } diff --git a/src/app/browser/window/tab/item/page/content.rs b/src/app/browser/window/tab/item/page/content.rs index b4f15529..18ce3fa5 100644 --- a/src/app/browser/window/tab/item/page/content.rs +++ b/src/app/browser/window/tab/item/page/content.rs @@ -1,6 +1,8 @@ // @TODO mod image; +mod status; mod text; +use status::Status; use text::Text; use gtk::{ @@ -12,18 +14,9 @@ use gtk::{ use std::sync::Arc; -pub enum Mime { - TextGemini, - // TextPlain, -} - -pub struct ResetResult { - pub title: Option, -} - pub struct Content { // GTK - widget: Box, + gobject: Box, // Actions action_tab_open: Arc, action_page_open: Arc, @@ -33,43 +26,44 @@ impl Content { // Construct pub fn new(action_tab_open: Arc, action_page_open: Arc) -> Self { Self { - widget: Box::builder().orientation(Orientation::Vertical).build(), + gobject: Box::builder().orientation(Orientation::Vertical).build(), action_tab_open, action_page_open, } } // Actions - pub fn reset(&self, mime: Mime, base: &Uri, data: &str) -> ResetResult { - // Cleanup - while let Some(child) = self.widget.last_child() { - self.widget.remove(&child) - } + pub fn set_status_error(&self, title: &str, description: &str) { + self.clean(); - // Re-compose - match mime { - Mime::TextGemini => { - let child = Text::gemini( - data, - base, - self.action_tab_open.clone(), - self.action_page_open.clone(), - ); + let status_default = Status::new_error(title, description); - self.widget.append(child.widget()); + self.gobject.append(status_default.gobject()); + } - ResetResult { - title: child.meta_title().clone(), - } - } /* @TODO - Mime::TextPlain => { - todo!() - } */ + pub fn set_text_gemini(&self, base: &Uri, data: &str) -> Option { + self.clean(); + + let text_gemini = Text::gemini( + data, + base, + self.action_tab_open.clone(), + self.action_page_open.clone(), + ); + + self.gobject.append(text_gemini.gobject()); + + text_gemini.meta_title().clone() // @TODO + } + + pub fn clean(&self) { + while let Some(child) = self.gobject.last_child() { + self.gobject.remove(&child); } } // Getters pub fn gobject(&self) -> &Box { - &self.widget + &self.gobject } } diff --git a/src/app/browser/window/tab/item/page/content/status.rs b/src/app/browser/window/tab/item/page/content/status.rs new file mode 100644 index 00000000..7eaece75 --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/status.rs @@ -0,0 +1,23 @@ +mod error; + +use error::Error; + +use adw::StatusPage; + +pub struct Status { + gobject: StatusPage, +} + +impl Status { + // Construct + pub fn new_error(title: &str, description: &str) -> Self { + Self { + gobject: Error::new(title, description), + } + } + + // Getters + pub fn gobject(&self) -> &StatusPage { + &self.gobject + } +} diff --git a/src/app/browser/window/tab/item/page/content/status/error.rs b/src/app/browser/window/tab/item/page/content/status/error.rs new file mode 100644 index 00000000..08326c2a --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/status/error.rs @@ -0,0 +1,15 @@ +use adw::StatusPage; + +pub struct Error { + gobject: StatusPage, +} + +impl Error { + pub fn new(title: &str, description: &str) -> StatusPage { + StatusPage::builder() + .description(description) + .icon_name("dialog-error-symbolic") + .title(title) + .build() + } +} diff --git a/src/app/browser/window/tab/item/page/content/text.rs b/src/app/browser/window/tab/item/page/content/text.rs index bc1b7c2f..069099fb 100644 --- a/src/app/browser/window/tab/item/page/content/text.rs +++ b/src/app/browser/window/tab/item/page/content/text.rs @@ -16,7 +16,7 @@ pub struct Meta { pub struct Text { meta: Meta, - widget: ScrolledWindow, + gobject: ScrolledWindow, } impl Text { @@ -35,13 +35,13 @@ impl Text { title: gemini.reader_title().clone(), }; - // Init widget - let widget = ScrolledWindow::builder().build(); + // Init gobject + let gobject = ScrolledWindow::builder().build(); - widget.set_child(Some(gemini.gobject())); + gobject.set_child(Some(gemini.gobject())); // Result - Self { meta, widget } + Self { meta, gobject } } // Getters @@ -49,7 +49,7 @@ impl Text { &self.meta.title } - pub fn widget(&self) -> &ScrolledWindow { - &self.widget + pub fn gobject(&self) -> &ScrolledWindow { + &self.gobject } }