From 96230ee4766b545b4a3e7a94398115b6f0a1fc82 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 22 Mar 2025 05:04:43 +0200 Subject: [PATCH] draft page info dialog features --- .../window/tab/item/client/driver/gemini.rs | 2 +- .../tab/item/page/navigation/request.rs | 11 +- .../tab/item/page/navigation/request/info.rs | 10 +- .../page/navigation/request/info/dialog.rs | 104 ++++++++++++++++++ .../page/navigation/request/info/event.rs | 10 ++ 5 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 src/app/browser/window/tab/item/page/navigation/request/info/dialog.rs diff --git a/src/app/browser/window/tab/item/client/driver/gemini.rs b/src/app/browser/window/tab/item/client/driver/gemini.rs index ef1a5edf..64240c33 100644 --- a/src/app/browser/window/tab/item/client/driver/gemini.rs +++ b/src/app/browser/window/tab/item/client/driver/gemini.rs @@ -75,7 +75,7 @@ impl Gemini { 0.9 } SocketClientEvent::Complete => { - i.add_event("Complete".to_string()); + i.add_event("Receiving".to_string()); 1.0 } _ => panic!(), // alert on API change diff --git a/src/app/browser/window/tab/item/page/navigation/request.rs b/src/app/browser/window/tab/item/page/navigation/request.rs index bdba1827..62ef4000 100644 --- a/src/app/browser/window/tab/item/page/navigation/request.rs +++ b/src/app/browser/window/tab/item/page/navigation/request.rs @@ -91,6 +91,7 @@ impl Request { }); entry.connect_icon_release({ + let i = info.clone(); let p = profile.clone(); move |e, position| match position { EntryIconPosition::Primary => { @@ -100,8 +101,14 @@ impl Request { show_identity_dialog(e, &p) } } - EntryIconPosition::Secondary => e.emit_activate(), - _ => todo!(), // unexpected + EntryIconPosition::Secondary => { + if is_focused(e) { + e.emit_activate() + } else { + i.borrow().dialog(Some(e)); + } + } + _ => panic!(), } }); diff --git a/src/app/browser/window/tab/item/page/navigation/request/info.rs b/src/app/browser/window/tab/item/page/navigation/request/info.rs index 150897b1..0f3185e0 100644 --- a/src/app/browser/window/tab/item/page/navigation/request/info.rs +++ b/src/app/browser/window/tab/item/page/navigation/request/info.rs @@ -1,3 +1,5 @@ +mod dialog; + // Public dependencies pub mod event; @@ -5,7 +7,8 @@ pub use event::Event; // Local dependencies -use gtk::gio::NetworkAddress; +use dialog::Dialog; +use gtk::{gio::NetworkAddress, prelude::IsA}; /// Common, shared `Page` information holder /// * used for the Information dialog window on request indicator activate @@ -48,6 +51,11 @@ impl Info { // Actions + pub fn dialog(&self, parent: Option<&impl IsA>) { + use adw::{PreferencesDialog, prelude::AdwDialogExt}; + PreferencesDialog::info(self).present(parent) + } + /// Mark `Self` as deprecated /// * tip: usually called on page handler begin pub fn deprecate(&mut self) { diff --git a/src/app/browser/window/tab/item/page/navigation/request/info/dialog.rs b/src/app/browser/window/tab/item/page/navigation/request/info/dialog.rs new file mode 100644 index 00000000..973d24e7 --- /dev/null +++ b/src/app/browser/window/tab/item/page/navigation/request/info/dialog.rs @@ -0,0 +1,104 @@ +use super::Info; +use adw::{ + ActionRow, PreferencesDialog, PreferencesGroup, PreferencesPage, + prelude::{PreferencesDialogExt, PreferencesGroupExt, PreferencesPageExt}, +}; + +pub trait Dialog { + fn info(info: &Info) -> Self; +} + +impl Dialog for PreferencesDialog { + fn info(info: &Info) -> Self { + let d = PreferencesDialog::builder() + .search_enabled(true) + .title("Page info") + .build(); + + d.add(&{ + let p = PreferencesPage::builder() + .title("General") + .icon_name("help-about-symbolic") + .build(); + if info.mime.is_some() { + p.add(&{ + let g = PreferencesGroup::builder().title("Meta").build(); + if let Some(ref mime) = info.mime { + g.add(&{ + let r = ActionRow::builder() + .css_classes(["property"]) + .subtitle(mime) + .title("Content type") + .build(); + r + }) + } + g + }); + } // @TODO content language, header size, etc. + if info.size.is_some() { + p.add(&{ + let g = PreferencesGroup::builder().title("Size").build(); + if let Some(ref size) = info.size { + g.add(&{ + use crate::tool::Format; + let r = ActionRow::builder() + .css_classes(["property"]) + .subtitle(size.bytes()) + .title("Content") + .build(); + r + }) + } + g + }); + } // @TODO header size, total size, etc. + p + }); + if let Some(ref redirect) = info.redirect { + d.add(&{ + PreferencesPage::builder() + .title("Redirect") + .icon_name("insert-link-symbolic") + .build() + }); + // @TODO recursive lookup + } + if !info.event.is_empty() { + d.add(&{ + let p = PreferencesPage::builder() + .title("Events") + .icon_name("system-run-symbolic") + .build(); + p.add(&{ + let g = PreferencesGroup::new(); + let e = &info.event[0]; + let t = e.time(); + let n = e.name(); + g.add(&{ + let r = ActionRow::builder() + .subtitle(t.format_iso8601().unwrap()) + .title(n) + .build(); + r + }); + for e in &info.event[1..] { + g.add(&{ + let r = ActionRow::builder() + .subtitle(gtk::glib::gformat!( + "{} ms", + e.time().difference(t).as_milliseconds() + )) + .title(e.name()) + .build(); + r + }) + } + g + }); + p + }) + } + d + } +} diff --git a/src/app/browser/window/tab/item/page/navigation/request/info/event.rs b/src/app/browser/window/tab/item/page/navigation/request/info/event.rs index d2825da0..6ce80dab 100644 --- a/src/app/browser/window/tab/item/page/navigation/request/info/event.rs +++ b/src/app/browser/window/tab/item/page/navigation/request/info/event.rs @@ -19,4 +19,14 @@ impl Event { time: DateTime::now_local().unwrap(), } } + + // Getters + + pub fn name(&self) -> &str { + &self.name + } + + pub fn time(&self) -> &DateTime { + &self.time + } }