move identity feature to request area

This commit is contained in:
yggverse 2025-01-29 15:13:35 +02:00
parent 78957ff85b
commit 2dc6154d54
32 changed files with 59 additions and 84 deletions

View file

@ -1,15 +1,14 @@
mod action; mod action;
mod client; mod client;
mod database; mod database;
mod identity;
mod page; mod page;
use super::{Action as TabAction, BrowserAction, Position, WindowAction}; use super::{Action as TabAction, BrowserAction, Position, WindowAction};
use crate::Profile; use crate::Profile;
use action::Action; use action::Action;
use adw::{prelude::AdwDialogExt, TabView}; use adw::TabView;
use client::Client; use client::Client;
use gtk::prelude::{ActionMapExt, Cast}; use gtk::prelude::ActionMapExt;
use page::Page; use page::Page;
use sqlite::Transaction; use sqlite::Transaction;
use std::rc::Rc; use std::rc::Rc;
@ -81,29 +80,6 @@ impl Item {
} }
}); });
action.ident.connect_activate({
let client = client.clone();
let page = page.clone();
let parent = tab_view.clone().upcast::<gtk::Widget>();
let profile = profile.clone();
move || {
if let Some(request) = page.navigation.uri() {
if ["gemini", "titan"].contains(&request.scheme().as_str()) {
return identity::default(&profile, &request, {
let client = client.clone();
let page = page.clone();
move || {
page.navigation.update(); // update indicators immediately
client.handle(&page.navigation.request(), false);
} // on apply
})
.present(Some(&parent));
}
}
identity::unsupported().present(Some(&parent));
}
});
action.load.connect_activate({ action.load.connect_activate({
let page = page.clone(); let page = page.clone();
let client = client.clone(); let client = client.clone();

View file

@ -1,13 +1,13 @@
mod history; mod history;
mod home; mod home;
mod ident; mod identity;
mod load; mod load;
mod reload; mod reload;
use gtk::gio::SimpleAction; use gtk::gio::SimpleAction;
use history::History; use history::History;
use home::Home; use home::Home;
use ident::Ident; use identity::Identity;
use load::Load; use load::Load;
use reload::Reload; use reload::Reload;
@ -17,7 +17,7 @@ use std::rc::Rc;
pub struct Action { pub struct Action {
pub history: Rc<History>, pub history: Rc<History>,
pub home: SimpleAction, pub home: SimpleAction,
pub ident: Rc<Ident>, pub identity: SimpleAction,
pub load: Rc<Load>, pub load: Rc<Load>,
pub reload: SimpleAction, pub reload: SimpleAction,
} }
@ -33,9 +33,9 @@ impl Action {
/// Create new `Self` /// Create new `Self`
pub fn new() -> Self { pub fn new() -> Self {
let ident = Rc::new(Ident::new());
let load = Rc::new(Load::new());
let home = SimpleAction::home(); let home = SimpleAction::home();
let identity = SimpleAction::identity();
let load = Rc::new(Load::new());
let reload = SimpleAction::reload(); let reload = SimpleAction::reload();
let history = Rc::new(History::build({ let history = Rc::new(History::build({
@ -45,10 +45,10 @@ impl Action {
Self { Self {
history, history,
reload,
home, home,
ident, identity,
load, load,
reload,
} }
} }
} }

View file

@ -1,39 +0,0 @@
use gtk::{gio::SimpleAction, glib::uuid_string_random, prelude::ActionExt};
/// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `Ident` action of `Item` group
pub struct Ident {
pub simple_action: SimpleAction,
}
impl Default for Ident {
fn default() -> Self {
Self::new()
}
}
impl Ident {
// Constructors
/// Create new `Self`
pub fn new() -> Self {
Self {
simple_action: SimpleAction::new(&uuid_string_random(), None),
}
}
// Actions
/// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal
/// with formatted for this action [Variant](https://docs.gtk.org/glib/struct.Variant.html) value
pub fn activate(&self) {
self.simple_action.activate(None);
}
// Events
/// Define callback function for
/// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal
pub fn connect_activate(&self, callback: impl Fn() + 'static) {
self.simple_action.connect_activate(move |_, _| callback());
}
}

View file

@ -0,0 +1,13 @@
use gtk::{gio::SimpleAction, glib::uuid_string_random};
pub trait Identity {
fn identity() -> Self;
}
impl Identity for SimpleAction {
fn identity() -> Self {
let identity = SimpleAction::new(&uuid_string_random(), None);
identity.set_enabled(false);
identity
}
}

View file

@ -47,7 +47,7 @@ impl Page {
(position, is_pinned, is_selected, is_needs_attention): (Position, bool, bool, bool), (position, is_pinned, is_selected, is_needs_attention): (Position, bool, bool, bool),
) -> Self { ) -> Self {
// Init components // Init components
let content = Rc::new(Content::build((window_action, item_action))); let content = Rc::new(Content::build((window_action, tab_action, item_action)));
let search = Rc::new(Search::new()); let search = Rc::new(Search::new());
let navigation = Rc::new(Navigation::build( let navigation = Rc::new(Navigation::build(
profile, profile,

View file

@ -5,7 +5,7 @@ mod text;
use image::Image; use image::Image;
use text::Text; use text::Text;
use super::{ItemAction, WindowAction}; use super::{ItemAction, TabAction, WindowAction};
use adw::StatusPage; use adw::StatusPage;
use gtk::{ use gtk::{
gdk::Paintable, gdk::Paintable,
@ -19,6 +19,7 @@ use std::{rc::Rc, time::Duration};
pub struct Content { pub struct Content {
window_action: Rc<WindowAction>, window_action: Rc<WindowAction>,
item_action: Rc<ItemAction>, item_action: Rc<ItemAction>,
tab_action: Rc<TabAction>,
pub g_box: Box, pub g_box: Box,
} }
@ -26,11 +27,18 @@ impl Content {
// Construct // Construct
/// Create new container for different components /// Create new container for different components
pub fn build((window_action, item_action): (&Rc<WindowAction>, &Rc<ItemAction>)) -> Self { pub fn build(
(window_action, tab_action, item_action): (
&Rc<WindowAction>,
&Rc<TabAction>,
&Rc<ItemAction>,
),
) -> Self {
Self { Self {
g_box: Box::builder().orientation(Orientation::Vertical).build(), g_box: Box::builder().orientation(Orientation::Vertical).build(),
window_action: window_action.clone(), window_action: window_action.clone(),
item_action: item_action.clone(), item_action: item_action.clone(),
tab_action: tab_action.clone(),
} }
} }
@ -90,7 +98,7 @@ impl Content {
/// * action removes previous children component from `Self` /// * action removes previous children component from `Self`
pub fn to_status_identity(&self) -> StatusPage { pub fn to_status_identity(&self) -> StatusPage {
self.clean(); self.clean();
let status = status::identity::build(self.item_action.clone()); let status = status::identity::build((&self.tab_action, &self.item_action));
self.g_box.append(&status); self.g_box.append(&status);
status status
} }

View file

@ -4,4 +4,4 @@ pub mod identity;
pub mod loading; pub mod loading;
pub mod mime; pub mod mime;
use super::ItemAction; use super::{ItemAction, TabAction};

View file

@ -1,6 +1,6 @@
use crate::app::browser::window::tab::item::Action; use super::{ItemAction, TabAction};
use adw::StatusPage; use adw::StatusPage;
use gtk::{prelude::ButtonExt, Align, Button}; use gtk::{prelude::ActionExt, Align, Button};
use std::rc::Rc; use std::rc::Rc;
// Defaults // Defaults
@ -13,18 +13,16 @@ 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 build(action: Rc<Action>) -> StatusPage { pub fn build((tab_action, item_action): (&Rc<TabAction>, &Rc<ItemAction>)) -> StatusPage {
// Init certificate selection // Init certificate selection
let button = &Button::builder() let button = &Button::builder()
.action_name(format!("{}.{}", tab_action.id, item_action.identity.name()))
.css_classes([DEFAULT_BUTTON_CLASS]) .css_classes([DEFAULT_BUTTON_CLASS])
.label(DEFAULT_BUTTON_LABEL) .label(DEFAULT_BUTTON_LABEL)
.tooltip_text(DEFAULT_BUTTON_TOOLTIP_TEXT) .tooltip_text(DEFAULT_BUTTON_TOOLTIP_TEXT)
.halign(Align::Center) .halign(Align::Center)
.build(); .build();
// Init events
button.connect_clicked(move |_| action.ident.activate());
// Init status page // Init status page
StatusPage::builder() StatusPage::builder()
.description(DEFAULT_DESCRIPTION) .description(DEFAULT_DESCRIPTION)

View file

@ -1,6 +1,8 @@
mod database; mod database;
mod identity;
mod primary_icon; mod primary_icon;
use adw::prelude::AdwDialogExt;
use primary_icon::PrimaryIcon; use primary_icon::PrimaryIcon;
use super::{ItemAction, Profile}; use super::{ItemAction, Profile};
@ -71,8 +73,25 @@ impl Request for Entry {
// Connect events // Connect events
entry.connect_icon_release({ entry.connect_icon_release({
let item_action = item_action.clone(); let item_action = item_action.clone();
let profile = profile.clone();
move |this, position| match position { move |this, position| match position {
EntryIconPosition::Primary => item_action.ident.activate(), // @TODO PrimaryIcon impl EntryIconPosition::Primary => {
if let Some(request) = this.uri() {
if ["gemini", "titan"].contains(&request.scheme().as_str()) {
return identity::default(&profile, &request, {
let item_action = item_action.clone();
let profile = profile.clone();
let this = this.clone();
move || {
this.update(&profile);
item_action.load.activate(Some(&this.text()), false);
} // on apply
})
.present(Some(this));
}
}
identity::unsupported().present(Some(this));
}
EntryIconPosition::Secondary => item_action.load.activate(Some(&this.text()), true), EntryIconPosition::Secondary => item_action.load.activate(Some(&this.text()), true),
_ => todo!(), // unexpected _ => todo!(), // unexpected
} }