update gemtext error handler

This commit is contained in:
yggverse 2025-03-05 17:57:28 +02:00
parent c8607e151a
commit 33943d37f1
9 changed files with 64 additions and 108 deletions

View File

@ -63,7 +63,6 @@ impl Item {
));
target_child.append(&page.navigation.g_box);
target_child.append(&page.notice.banner);
target_child.append(&page.content.g_box);
target_child.append(&page.search.g_box);
target_child.append(&page.input.clamp);

View File

@ -49,7 +49,6 @@ impl Client {
// Reset widgets
self.page.input.unset();
self.page.notice.unset();
self.page.search.unset();
self.page.set_title("Loading..");
self.page.set_progress(0.1);

View File

@ -260,9 +260,6 @@ fn handle(
_ => panic!() // unexpected
}
};
if let Some(notice) = widget.meta.notice {
page.notice(&notice)
}
page.search.set(Some(widget.text_view));
page.set_title(&match widget.meta.title {
Some(title) => title.into(), // @TODO

View File

@ -3,7 +3,6 @@ mod database;
mod error;
mod input;
mod navigation;
mod notice;
mod search;
use super::{Action as ItemAction, BrowserAction, Profile, TabAction, WindowAction};
@ -12,7 +11,6 @@ use content::Content;
use error::Error;
use input::Input;
use navigation::Navigation;
use notice::Notice;
use search::Search;
use sqlite::Transaction;
use std::rc::Rc;
@ -27,7 +25,6 @@ pub struct Page {
pub content: Rc<Content>,
pub input: Rc<Input>,
pub navigation: Rc<Navigation>,
pub notice: Rc<Notice>,
pub search: Rc<Search>,
// System
/// Reference to [TabPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.TabPage.html)
@ -59,7 +56,6 @@ impl Page {
(window_action, tab_action, item_action),
));
let input = Rc::new(Input::new());
let notice = Rc::new(Notice::new());
// Done
Self {
@ -73,7 +69,6 @@ impl Page {
content,
input,
navigation,
notice,
search,
}
}
@ -104,11 +99,6 @@ impl Page {
self.search.show()
}
/// Toggle `Notice` widget
pub fn notice(&self, title: &str) {
self.notice.show(title)
}
/// Cleanup session for `Self`
pub fn clean(
&self,

View File

@ -118,9 +118,30 @@ impl Content {
/// `text/gemini`
pub fn to_text_gemini(&self, base: &Uri, data: &str) -> Text {
self.clean();
let text = Text::gemini((&self.window_action, &self.item_action), base, data);
self.g_box.append(&text.scrolled_window);
text
match Text::gemini((&self.window_action, &self.item_action), base, data) {
Ok(text) => {
self.g_box.append(&text.scrolled_window);
text
}
Err((message, text)) => {
self.g_box.append(&{
let banner = adw::Banner::builder()
.title(message)
.revealed(true)
.button_label("Ok")
.build();
banner.connect_button_clicked(|this| this.set_revealed(false));
banner
});
match text {
Some(text) => {
self.g_box.append(&text.scrolled_window);
text
}
None => todo!(),
}
}
}
}
/// `text/plain`

View File

@ -12,7 +12,6 @@ use std::rc::Rc;
pub struct Meta {
pub title: Option<String>,
pub notice: Option<String>,
} // @TODO move to separated mod
pub struct Text {
@ -26,54 +25,36 @@ impl Text {
actions: (&Rc<WindowAction>, &Rc<ItemAction>),
base: &Uri,
gemtext: &str,
) -> Self {
// Init gemtext reader
let (gemini, notice) = match Gemini::build(actions, base, gemtext) {
Ok(gemini) => (gemini, None),
Err(e) => {
let notice = e.message();
match e {
gemini::Error::Multiline(gemini) => (gemini, Some(notice)),
}
}
};
// Init container widget
let clamp_scrollable = ClampScrollable::builder()
.child(&gemini.text_view)
.css_classes(["view"])
.maximum_size(800)
.build();
grab_focus_patch(&clamp_scrollable, &gemini.text_view);
Self {
text_view: gemini.text_view,
meta: Meta {
title: gemini.title,
notice,
) -> Result<Self, (String, Option<Self>)> {
match Gemini::build(actions, base, gemtext) {
Ok(widget) => Ok(Self {
scrolled_window: reader(&widget.text_view),
text_view: widget.text_view,
meta: Meta {
title: widget.title,
},
}),
Err(e) => match e {
gemini::Error::Markup(message, widget) => Err((
message,
Some(Self {
scrolled_window: reader(&widget.text_view),
text_view: widget.text_view,
meta: Meta {
title: widget.title,
},
}),
)),
},
scrolled_window: ScrolledWindow::builder().child(&clamp_scrollable).build(),
}
}
pub fn plain(data: &str) -> Self {
let text_view = TextView::plain(data);
let clamp_scrollable = ClampScrollable::builder()
.child(&text_view)
.css_classes(["view"])
.maximum_size(800) // @TODO auto-expand
.build();
grab_focus_patch(&clamp_scrollable, &text_view);
Self {
scrolled_window: ScrolledWindow::builder().child(&clamp_scrollable).build(),
scrolled_window: reader(&text_view),
text_view,
meta: Meta {
title: None,
notice: None,
},
meta: Meta { title: None },
}
}
@ -82,10 +63,7 @@ impl Text {
Self {
scrolled_window: ScrolledWindow::builder().child(&source).build(),
text_view: source.into_text_view(),
meta: Meta {
title: None,
notice: None,
},
meta: Meta { title: None },
}
}
}
@ -106,3 +84,15 @@ fn grab_focus_patch(clamp_scrollable: &ClampScrollable, text_view: &TextView) {
clamp_scrollable.add_controller(controller);
}
fn reader(text_view: &TextView) -> ScrolledWindow {
let clamp_scrollable = ClampScrollable::builder()
.child(text_view)
.css_classes(["view"])
.maximum_size(800)
.build();
grab_focus_patch(&clamp_scrollable, text_view);
ScrolledWindow::builder().child(&clamp_scrollable).build()
}

View File

@ -506,7 +506,10 @@ impl Gemini {
if is_multiline_enabled {
Ok(Self { text_view, title })
} else {
Err(Error::Multiline(Self { text_view, title }))
Err(Error::Markup(
"Invalid multiline markup! Gemtext format partially ignored.".to_string(),
Self { text_view, title },
))
}
}
}

View File

@ -1,13 +1,3 @@
pub enum Error {
Multiline(super::Gemini),
}
impl Error {
pub fn message(&self) -> String {
match self {
Self::Multiline(_) => {
"Invalid multiline markup! Gemtext format partially ignored.".to_string()
}
}
}
Markup(String, super::Gemini),
}

View File

@ -1,33 +0,0 @@
use adw::Banner;
pub struct Notice {
pub banner: Banner,
}
impl Notice {
// Constructors
/// Create new `Self`
pub fn new() -> Self {
let banner = Banner::builder().button_label("Ok").build();
banner.connect_button_clicked(|this| this.set_revealed(false));
Self { banner }
}
// Actions
pub fn show(&self, title: &str) {
self.banner.set_title(title);
self.banner.set_revealed(true);
}
pub fn unset(&self) {
self.banner.set_revealed(false);
}
}
impl Default for Notice {
fn default() -> Self {
Self::new()
}
}