remove extra members

This commit is contained in:
yggverse 2024-12-12 13:20:04 +02:00
parent 1497896f6d
commit 6911559915
7 changed files with 104 additions and 233 deletions

View File

@ -71,7 +71,7 @@ impl Page {
let widget = Rc::new(Widget::new( let widget = Rc::new(Widget::new(
&id, &id,
&navigation.widget.gobject, &navigation.widget.gobject,
&content.gobject, &content.g_box,
&input.widget.clamp, &input.widget.clamp,
)); ));
@ -205,23 +205,19 @@ impl Page {
self.load_gemini(uri, is_download, is_source, is_history) self.load_gemini(uri, is_download, is_source, is_history)
} }
scheme => { scheme => {
// Define common data
let status = Status::Failure;
let title = "Oops";
// Add history record // Add history record
if is_history { if is_history {
snap_history(self.navigation.clone()); snap_history(self.navigation.clone());
} }
// Update widget // Update widget
self.content let status = self.content.to_status_failure();
.to_status_failure() status.set_description(Some(&format!("Scheme `{scheme}` not supported")));
.set_title(title)
.set_description(Some(&format!("Scheme `{scheme}` not supported")));
// Update meta // Update meta
self.meta.set_status(status).set_title(title); self.meta
.set_status(Status::Failure)
.set_title(&status.title());
// Update window // Update window
self.browser_action.update.activate(Some(&id)); self.browser_action.update.activate(Some(&id));
@ -419,7 +415,7 @@ impl Page {
match self.profile.identity.gemini.match_scope(&uri.to_string()) { match self.profile.identity.gemini.match_scope(&uri.to_string()) {
Some(identity) => match identity.to_tls_certificate() { Some(identity) => match identity.to_tls_certificate() {
Ok(certificate) => Some(certificate), Ok(certificate) => Some(certificate),
Err(reason) => todo!("{reason}"), Err(e) => todo!("{e}"),
}, },
None => None, None => None,
}, },
@ -568,21 +564,14 @@ impl Page {
// Update window components // Update window components
update.activate(Some(&id)); update.activate(Some(&id));
} }
Err(reason) => { Err(e) => {
// Define common data
let status = Status::Failure;
let title = "Oops";
let description = reason.to_string();
// Update widget // Update widget
content let status = content.to_status_failure();
.to_status_failure() status.set_description(Some(&e.to_string()));
.set_title(title)
.set_description(Some(&description));
// Update meta // Update meta
meta.set_status(status) meta.set_status(Status::Failure)
.set_title(title); .set_title(&status.title());
// Update window // Update window
update.activate(Some(&id)); update.activate(Some(&id));
@ -638,40 +627,27 @@ impl Page {
// Update window components // Update window components
update.activate(Some(&id)); update.activate(Some(&id));
} }
Err(reason) => { Err(e) => {
// Define common data
let status = Status::Failure;
let title = "Oops";
// Update widget // Update widget
content let status = content.to_status_failure();
.to_status_failure() status.set_description(Some(e.message()));
.set_title(title)
.set_description(Some(reason.message()));
// Update meta // Update meta
meta.set_status(status) meta.set_status(Status::Failure)
.set_title(title); .set_title(&status.title());
} }
} }
} }
); );
}, },
Err(reason) => { Err(e) => {
// Define common data
let status = Status::Failure;
let title = "Oops";
let description = reason.to_string();
// Update widget // Update widget
content let status = content.to_status_failure();
.to_status_failure() status.set_description(Some(&e.to_string()));
.set_title(title)
.set_description(Some(&description));
// Update meta // Update meta
meta.set_status(status) meta.set_status(Status::Failure)
.set_title(title); .set_title(&status.title());
} }
} }
} }
@ -686,7 +662,7 @@ impl Page {
// Update page meta // Update page meta
meta.set_status(Status::Failure) meta.set_status(Status::Failure)
.set_title(status.gobject.title().as_str()); .set_title(&status.title());
// Update window // Update window
update.activate(Some(&id)); update.activate(Some(&id));
@ -763,45 +739,36 @@ impl Page {
tab_action.load.activate(None, false); tab_action.load.activate(None, false);
} }
}, },
Err(reason) => { Err(e) => {
let status = Status::Failure; // Update widget
let title = "Oops"; let status = content.to_status_failure();
status.set_description(Some(&e.to_string()));
meta.set_status(status) // Update meta
.set_title(title); meta.set_status(Status::Failure)
.set_title(&status.title());
content
.to_status_failure()
.set_title(title)
.set_description(Some(reason.message()));
} }
} }
} }
Err(reason) => { Err(e) => {
let status = Status::Failure; // Update widget
let title = "Oops"; let status = content.to_status_failure();
status.set_description(Some(&e.to_string()));
meta.set_status(status) // Update meta
.set_title(title); meta.set_status(Status::Failure)
.set_title(&status.title());
content
.to_status_failure()
.set_title(title)
.set_description(Some(reason.message()));
}, },
} }
}, },
None => { None => {
let status = Status::Failure; // Update widget
let title = "Oops"; let status = content.to_status_failure();
status.set_description(Some("Redirection target not defined"));
meta.set_status(status) // Update meta
.set_title(title); meta.set_status(Status::Failure)
.set_title(&status.title());
content
.to_status_failure()
.set_title(title)
.set_description(Some("Redirection target not defined"));
}, },
} }
@ -813,83 +780,66 @@ impl Page {
gemini::client::connection::response::meta::Status::CertificateUnauthorized | gemini::client::connection::response::meta::Status::CertificateUnauthorized |
// https://geminiprotocol.net/docs/protocol-specification.gmi#status-62-certificate-not-valid // https://geminiprotocol.net/docs/protocol-specification.gmi#status-62-certificate-not-valid
gemini::client::connection::response::meta::Status::CertificateInvalid => { gemini::client::connection::response::meta::Status::CertificateInvalid => {
// Define common data
let status = Status::Success;
let title = "Identity";
// Add history record // Add history record
if is_history { if is_history {
snap_history(navigation.clone()); snap_history(navigation.clone());
} }
// Update widget // Update widget
content let status = content.to_status_identity();
.to_status_identity()
.set_title(title) status.set_description(Some(&match response.meta.data {
.set_description(Some(&match response.meta.data { Some(data) => data.value,
Some(data) => data.value, None => match response.meta.status {
None => match response.meta.status { gemini::client::connection::response::meta::Status::CertificateUnauthorized => gformat!("Certificate not authorized"),
gemini::client::connection::response::meta::Status::CertificateUnauthorized => gformat!("Certificate not authorized"), gemini::client::connection::response::meta::Status::CertificateInvalid => gformat!("Certificate not valid"),
gemini::client::connection::response::meta::Status::CertificateInvalid => gformat!("Certificate not valid"), _ => gformat!("Client certificate required")
_ => gformat!("Client certificate required") },
}, }));
}));
// Update meta // Update meta
meta.set_status(status) meta.set_status(Status::Success)
.set_title(title); .set_title(&status.title());
// Update window // Update window
update.activate(Some(&id)); update.activate(Some(&id));
} }
_ => { _ => {
// Define common data
let status = Status::Failure;
let title = "Oops";
// Add history record // Add history record
if is_history { if is_history {
snap_history(navigation.clone()); snap_history(navigation.clone());
} }
// Update widget // Update widget
content let status = content.to_status_failure();
.to_status_failure()
.set_title(title) status.set_description(Some(&match response.meta.data {
.set_description(Some(&match response.meta.data { Some(data) => data.value,
Some(data) => data.value, None => gformat!("Status code not supported"),
None => gformat!("Status code not supported"), }));
}));
// Update meta // Update meta
meta.set_status(status) meta.set_status(Status::Failure)
.set_title(title); .set_title(&status.title());
// Update window // Update window
update.activate(Some(&id)); update.activate(Some(&id));
} }
} }
}, },
Err(reason) => { Err(e) => {
// Define common data
let status = Status::Failure;
let title = "Oops";
let description = reason.to_string();
// Add history record // Add history record
if is_history { if is_history {
snap_history(navigation.clone()); snap_history(navigation.clone());
} }
// Update widget // Update widget
content let status = content.to_status_failure();
.to_status_failure() status.set_description(Some(&e.to_string()));
.set_title(title)
.set_description(Some(&description));
// Update meta // Update meta
meta.set_status(status) meta.set_status(Status::Failure)
.set_title(title); .set_title(&status.title());
// Update window // Update window
update.activate(Some(&id)); update.activate(Some(&id));

View File

@ -3,10 +3,10 @@ mod status;
mod text; mod text;
use image::Image; use image::Image;
use status::Status;
use text::Text; use text::Text;
use super::{TabAction, WindowAction}; use super::{TabAction, WindowAction};
use adw::StatusPage;
use gtk::{ use gtk::{
gdk::Paintable, gdk::Paintable,
gio::{Cancellable, File}, gio::{Cancellable, File},
@ -19,7 +19,7 @@ use std::{rc::Rc, time::Duration};
pub struct Content { pub struct Content {
window_action: Rc<WindowAction>, window_action: Rc<WindowAction>,
tab_action: Rc<TabAction>, tab_action: Rc<TabAction>,
pub gobject: Box, pub g_box: Box,
} }
impl Content { impl Content {
@ -28,7 +28,7 @@ impl Content {
/// Create new container for different components /// Create new container for different components
pub fn new(action: (Rc<WindowAction>, Rc<TabAction>)) -> Self { pub fn new(action: (Rc<WindowAction>, Rc<TabAction>)) -> Self {
Self { Self {
gobject: Box::builder().orientation(Orientation::Vertical).build(), g_box: Box::builder().orientation(Orientation::Vertical).build(),
window_action: action.0, window_action: action.0,
tab_action: action.1, tab_action: action.1,
} }
@ -42,7 +42,7 @@ impl Content {
pub fn to_image(&self, paintable: &impl IsA<Paintable>) -> Image { pub fn to_image(&self, paintable: &impl IsA<Paintable>) -> Image {
self.clean(); self.clean();
let image = Image::new_from_paintable(paintable); let image = Image::new_from_paintable(paintable);
self.gobject.append(&image.picture); self.g_box.append(&image.picture);
image image
} }
@ -54,50 +54,54 @@ impl Content {
initial_filename: &str, initial_filename: &str,
cancellable: &Cancellable, cancellable: &Cancellable,
on_choose: impl Fn(File, Rc<status::download::Action>) + 'static, on_choose: impl Fn(File, Rc<status::download::Action>) + 'static,
) -> Status { ) -> StatusPage {
self.clean(); self.clean();
let status = Status::new_download(initial_filename, cancellable, on_choose); let status = status::download::new(initial_filename, cancellable, on_choose);
self.gobject.append(&status.gobject); self.g_box.append(&status);
status status
} }
/// Set new `content::Status` component for `Self` with new `status::Failure` preset /// Set new `content::Status` component for `Self` with new `status::Failure` preset
/// ///
/// * action removes previous children component from `Self` /// * action removes previous children component from `Self`
pub fn to_status_failure(&self) -> Status { pub fn to_status_failure(&self) -> StatusPage {
self.clean(); self.clean();
let status = Status::new_failure(); let status = status::failure::new();
self.gobject.append(&status.gobject); self.g_box.append(&status);
status status
} }
/// Set new `content::Status` component for `Self` with new `status::Mime` issue preset /// Set new `content::Status` component for `Self` with new `status::Mime` issue preset
/// ///
/// * action removes previous children component from `Self` /// * action removes previous children component from `Self`
pub fn to_status_mime(&self, mime: &str, download: Option<(Rc<TabAction>, GString)>) -> Status { pub fn to_status_mime(
&self,
mime: &str,
download: Option<(Rc<TabAction>, GString)>,
) -> StatusPage {
self.clean(); self.clean();
let status = Status::new_mime(mime, download); let status = status::mime::new(mime, download);
self.gobject.append(&status.gobject); self.g_box.append(&status);
status status
} }
/// Set new `content::Status` component for `Self` with new `status::Identity` preset /// Set new `content::Status` component for `Self` with new `status::Identity` preset
/// ///
/// * action removes previous children component from `Self` /// * action removes previous children component from `Self`
pub fn to_status_identity(&self) -> Status { pub fn to_status_identity(&self) -> StatusPage {
self.clean(); self.clean();
let status = Status::new_identity(self.tab_action.clone()); let status = status::identity::new(self.tab_action.clone());
self.gobject.append(&status.gobject); self.g_box.append(&status);
status status
} }
/// Set new `content::Status` component for `Self` with new `status::Loading` preset /// Set new `content::Status` component for `Self` with new `status::Loading` preset
/// ///
/// * action removes previous children component from `Self` /// * action removes previous children component from `Self`
pub fn to_status_loading(&self, show_with_delay: Option<Duration>) -> Status { pub fn to_status_loading(&self, show_with_delay: Option<Duration>) -> StatusPage {
self.clean(); self.clean();
let status = Status::new_loading(show_with_delay); let status = status::loading::new(show_with_delay);
self.gobject.append(&status.gobject); self.g_box.append(&status);
status status
} }
@ -123,21 +127,21 @@ impl Content {
base, base,
(self.window_action.clone(), self.tab_action.clone()), (self.window_action.clone(), self.tab_action.clone()),
); );
self.gobject.append(&text.scrolled_window); self.g_box.append(&text.scrolled_window);
text text
} }
pub fn to_text_source(&self, data: &str) -> Text { pub fn to_text_source(&self, data: &str) -> Text {
self.clean(); self.clean();
let text = Text::new_source(data); let text = Text::new_source(data);
self.gobject.append(&text.scrolled_window); self.g_box.append(&text.scrolled_window);
text text
} }
/// Remove all children components from `Self` /// Remove all children components from `Self`
pub fn clean(&self) { pub fn clean(&self) {
while let Some(child) = self.gobject.last_child() { while let Some(child) = self.g_box.last_child() {
self.gobject.remove(&child); self.g_box.remove(&child);
} }
} }
} }

View File

@ -1,89 +1,7 @@
pub mod download; pub mod download;
mod failure; pub mod failure;
mod identity; pub mod identity;
mod loading; pub mod loading;
mod mime; pub mod mime;
use super::TabAction; use super::TabAction;
use adw::StatusPage;
use gtk::{
gio::{Cancellable, File},
glib::GString,
};
use std::{rc::Rc, time::Duration};
pub struct Status {
pub gobject: StatusPage,
}
impl Status {
// Constructors
/// Create new download preset
pub fn new_download(
initial_filename: &str,
cancellable: &Cancellable,
on_choose: impl Fn(File, Rc<download::Action>) + 'static,
) -> Self {
Self {
gobject: download::new(initial_filename, cancellable, on_choose),
}
}
/// Create new failure preset
///
/// Useful as placeholder widget for error handlers
pub fn new_failure() -> Self {
Self {
gobject: failure::new_gobject(),
}
}
/// Create new mime issue preset
///
/// Useful as placeholder widget for mime issue handlers
pub fn new_mime(mime: &str, download: Option<(Rc<TabAction>, GString)>) -> Self {
Self {
gobject: mime::new_gobject(mime, download),
}
}
/// Create new identity preset
///
/// Useful as placeholder for 60 status code
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-60
pub fn new_identity(action: Rc<crate::app::browser::window::tab::item::Action>) -> Self {
Self {
gobject: identity::new_gobject(action),
}
}
/// Create new loading preset
///
/// Useful as placeholder widget for async operations
pub fn new_loading(show_with_delay: Option<Duration>) -> Self {
Self {
gobject: loading::new_gobject(show_with_delay),
}
}
// Setters
/// Set new title for `Self`
///
/// Return `Self` reference to apply another functions in chain
pub fn set_title(&self, value: &str) -> &Self {
self.gobject.set_title(value);
self
}
/// Set new description for `Self`
///
/// Useful for loading widgets to update byte totals and other dynamically changed information
///
/// Return `Self` reference to apply another functions in chain
pub fn set_description(&self, value: Option<&str>) -> &Self {
self.gobject.set_description(value);
self
}
}

View File

@ -5,7 +5,7 @@ const DEFAULT_ICON_NAME: &str = "dialog-error";
/// Create new default `GObject` preset for failure /// Create new default `GObject` preset for failure
/// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html) /// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html)
pub fn new_gobject() -> StatusPage { pub fn new() -> StatusPage {
StatusPage::builder() StatusPage::builder()
.title(DEFAULT_TITLE) .title(DEFAULT_TITLE)
.icon_name(DEFAULT_ICON_NAME) .icon_name(DEFAULT_ICON_NAME)

View File

@ -1,8 +1,7 @@
use std::rc::Rc;
use crate::app::browser::window::tab::item::Action; use crate::app::browser::window::tab::item::Action;
use adw::StatusPage; use adw::StatusPage;
use gtk::{prelude::ButtonExt, Align, Button}; use gtk::{prelude::ButtonExt, Align, Button};
use std::rc::Rc;
// Defaults // Defaults
const DEFAULT_ICON_NAME: &str = "avatar-default-symbolic"; const DEFAULT_ICON_NAME: &str = "avatar-default-symbolic";
@ -14,7 +13,7 @@ const DEFAULT_BUTTON_CLASS: &str = "suggested-action";
/// Create new default preset for `Identity` /// Create new default preset for `Identity`
/// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html) /// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html)
pub fn new_gobject(action: Rc<Action>) -> StatusPage { pub fn new(action: Rc<Action>) -> StatusPage {
// Init certificate selection // Init certificate selection
let button = &Button::builder() let button = &Button::builder()
.css_classes([DEFAULT_BUTTON_CLASS]) .css_classes([DEFAULT_BUTTON_CLASS])

View File

@ -11,7 +11,7 @@ const DEFAULT_TITLE: &str = "Loading..";
/// Create new default preset for loading /// Create new default preset for loading
/// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html) /// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html)
pub fn new_gobject(show_with_delay: Option<Duration>) -> StatusPage { pub fn new(show_with_delay: Option<Duration>) -> StatusPage {
// Init spinner component // Init spinner component
let spinner = Spinner::builder() let spinner = Spinner::builder()
.width_request(SPINNER_SIZE) .width_request(SPINNER_SIZE)

View File

@ -5,7 +5,7 @@ use std::rc::Rc;
/// Create new default `GObject` preset for mime issue /// Create new default `GObject` preset for mime issue
/// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html) /// [StatusPage](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.StatusPage.html)
pub fn new_gobject(mime: &str, download: Option<(Rc<TabAction>, GString)>) -> StatusPage { pub fn new(mime: &str, download: Option<(Rc<TabAction>, GString)>) -> StatusPage {
let status_page = StatusPage::builder() let status_page = StatusPage::builder()
.description(format!("Content type `{mime}` not supported!")) .description(format!("Content type `{mime}` not supported!"))
.icon_name("dialog-question-symbolic") .icon_name("dialog-question-symbolic")