implement notice banner

This commit is contained in:
yggverse 2025-03-03 09:54:02 +02:00
parent a68033bc01
commit 12474b0f44
7 changed files with 71 additions and 16 deletions

View File

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

View File

@ -260,6 +260,9 @@ 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,14 +3,16 @@ mod database;
mod error;
mod input;
mod navigation;
mod notice;
mod search;
use super::{Action as ItemAction, BrowserAction, Profile, TabAction, WindowAction};
use adw::TabPage;
use adw::{Banner, TabPage};
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;
@ -23,9 +25,10 @@ pub struct Page {
pub window_action: Rc<WindowAction>,
// Components
pub content: Rc<Content>,
pub search: Rc<Search>,
pub input: Rc<Input>,
pub navigation: Rc<Navigation>,
pub notice: Banner,
pub search: Rc<Search>,
// System
/// Reference to [TabPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.TabPage.html)
/// wanted to update title, loading status and other features related with page.
@ -56,6 +59,7 @@ impl Page {
(window_action, tab_action, item_action),
));
let input = Rc::new(Input::new());
let notice = Banner::notice();
// Done
Self {
@ -67,9 +71,10 @@ impl Page {
window_action: window_action.clone(),
// Components
content,
search,
input,
navigation,
notice,
search,
}
}
@ -99,6 +104,11 @@ 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

@ -12,6 +12,7 @@ use std::rc::Rc;
pub struct Meta {
pub title: Option<String>,
pub notice: Option<String>,
} // @TODO move to separated mod
pub struct Text {
@ -27,7 +28,15 @@ impl Text {
gemtext: &str,
) -> Self {
// Init gemtext reader
let gemini = Gemini::build(actions, base, gemtext).unwrap(); // @TODO handle
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()
@ -42,6 +51,7 @@ impl Text {
text_view: gemini.text_view,
meta: Meta {
title: gemini.title,
notice,
},
scrolled_window: ScrolledWindow::builder().child(&clamp_scrollable).build(),
}
@ -60,7 +70,10 @@ impl Text {
Self {
scrolled_window: ScrolledWindow::builder().child(&clamp_scrollable).build(),
text_view,
meta: Meta { title: None },
meta: Meta {
title: None,
notice: None,
},
}
}
@ -69,7 +82,10 @@ impl Text {
Self {
scrolled_window: ScrolledWindow::builder().child(&source).build(),
text_view: source.into_text_view(),
meta: Meta { title: None },
meta: Meta {
title: None,
notice: None,
},
}
}
}

View File

@ -234,7 +234,7 @@ impl Gemini {
// Skip other actions for this line
continue;
}
Err(e) => return Err(Error::Gemtext(e.to_string())),
Err(_) => todo!(),
}
}
}
@ -502,6 +502,10 @@ impl Gemini {
}); // @TODO may be expensive for CPU, add timeout?
// Result
Ok(Self { text_view, title })
if is_multiline_enabled {
Ok(Self { text_view, title })
} else {
Err(Error::Multiline(Self { text_view, title }))
}
}
}

View File

@ -1,15 +1,12 @@
use std::fmt::{Display, Formatter, Result};
#[derive(Debug)]
pub enum Error {
Gemtext(String),
Multiline(super::Gemini),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
impl Error {
pub fn message(&self) -> String {
match self {
Self::Gemtext(e) => {
write!(f, "Gemtext error: {e}")
Self::Multiline(_) => {
"Invalid multiline markup! Gemtext format partially ignored.".to_string()
}
}
}

View File

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