implement identity button as navigation entry primary icon

This commit is contained in:
yggverse 2024-12-11 05:44:59 +02:00
parent a5415fa4e5
commit 5348417a73
6 changed files with 66 additions and 105 deletions

View File

@ -2,7 +2,6 @@ mod bookmark;
mod database; mod database;
mod history; mod history;
mod home; mod home;
mod identity;
mod reload; mod reload;
mod request; mod request;
mod widget; mod widget;
@ -10,7 +9,6 @@ mod widget;
use bookmark::Bookmark; use bookmark::Bookmark;
use history::History; use history::History;
use home::Home; use home::Home;
use identity::Identity;
use reload::Reload; use reload::Reload;
use request::Request; use request::Request;
use widget::Widget; use widget::Widget;
@ -27,7 +25,6 @@ pub struct Navigation {
pub bookmark: Rc<Bookmark>, pub bookmark: Rc<Bookmark>,
pub history: Rc<History>, pub history: Rc<History>,
pub home: Rc<Home>, pub home: Rc<Home>,
pub identity: Rc<Identity>,
pub profile: Rc<Profile>, pub profile: Rc<Profile>,
pub reload: Rc<Reload>, pub reload: Rc<Reload>,
pub request: Rc<Request>, pub request: Rc<Request>,
@ -40,7 +37,6 @@ impl Navigation {
action: (Rc<BrowserAction>, Rc<WindowAction>, Rc<TabAction>), action: (Rc<BrowserAction>, Rc<WindowAction>, Rc<TabAction>),
) -> Self { ) -> Self {
// Init components // Init components
let identity = Rc::new(Identity::new(action.2.clone()));
let home = Rc::new(Home::new(action.1.clone())); let home = Rc::new(Home::new(action.1.clone()));
let history = Rc::new(History::new(action.1.clone())); let history = Rc::new(History::new(action.1.clone()));
let reload = Rc::new(Reload::new(action.1.clone())); let reload = Rc::new(Reload::new(action.1.clone()));
@ -49,7 +45,6 @@ impl Navigation {
// Init widget // Init widget
let widget = Rc::new(Widget::new( let widget = Rc::new(Widget::new(
&identity.widget.gobject,
&home.widget.gobject, &home.widget.gobject,
&history.widget.gobject, &history.widget.gobject,
&reload.widget.gobject, &reload.widget.gobject,
@ -62,7 +57,6 @@ impl Navigation {
bookmark, bookmark,
history, history,
home, home,
identity,
profile, profile,
reload, reload,
request, request,
@ -75,7 +69,14 @@ impl Navigation {
pub fn update(&self, progress_fraction: Option<f64>) { pub fn update(&self, progress_fraction: Option<f64>) {
let request_text = self.request.widget.entry.text(); let request_text = self.request.widget.entry.text();
self.identity.update( self.bookmark
.update(self.profile.bookmark.get(&request_text).is_ok());
self.history.update();
self.home.update(self.request.uri());
self.reload.update(!request_text.is_empty());
self.request.update(
progress_fraction,
!request_text.is_empty() && request_text.starts_with("gemini"),
self.profile self.profile
.identity .identity
.gemini .gemini
@ -83,14 +84,7 @@ impl Navigation {
.memory .memory
.match_scope(&request_text) .match_scope(&request_text)
.is_some(), .is_some(),
!request_text.is_empty() && request_text.starts_with("gemini"),
); );
self.bookmark
.update(self.profile.bookmark.get(&request_text).is_ok());
self.history.update();
self.home.update(self.request.uri());
self.reload.update(!request_text.is_empty());
self.request.update(progress_fraction);
} }
pub fn clean( pub fn clean(

View File

@ -1,29 +0,0 @@
mod widget;
use widget::Widget;
use crate::app::browser::window::tab::item::Action;
use std::rc::Rc;
pub struct Identity {
action: Rc<Action>,
pub widget: Rc<Widget>,
}
impl Identity {
// Construct
pub fn new(action: Rc<Action>) -> Self {
Self {
action: action.clone(),
widget: Rc::new(Widget::new(action)),
}
}
// Actions
pub fn update(&self, is_auth: bool, is_enabled: bool) {
// Update action status
self.action.ident.simple_action.set_enabled(is_enabled);
// Update widget
self.widget.update(is_auth, is_enabled)
}
}

View File

@ -1,35 +0,0 @@
use crate::app::browser::window::tab::item::Action;
use gtk::{
prelude::{ButtonExt, WidgetExt},
Button,
};
use std::rc::Rc;
pub struct Widget {
pub gobject: Button,
}
impl Widget {
// Construct
pub fn new(action: Rc<Action>) -> Self {
// Init gobject
let gobject = Button::builder()
.icon_name("avatar-default-symbolic")
.tooltip_text("Identity")
//.sensitive(false)
.build();
// Init events @TODO dialog window required
gobject.connect_clicked(move |_| action.ident.activate());
// Return activated `Self`
Self { gobject }
}
// Actions
pub fn update(&self, is_auth: bool, is_enabled: bool) {
self.gobject.set_sensitive(is_enabled);
self.gobject
.set_css_classes(if is_auth { &["success"] } else { &[] });
}
}

View File

@ -25,8 +25,17 @@ impl Request {
} }
// Actions // Actions
pub fn update(&self, progress_fraction: Option<f64>) { pub fn update(
self.widget.update(progress_fraction); &self,
progress_fraction: Option<f64>,
is_identity_applicable: bool,
is_identity_active: bool,
) {
self.widget.update(
progress_fraction,
is_identity_applicable,
is_identity_active,
);
} }
pub fn clean( pub fn clean(

View File

@ -2,7 +2,6 @@ mod database;
use crate::app::browser::{window::tab::item::Action as TabAction, Action as BrowserAction}; use crate::app::browser::{window::tab::item::Action as TabAction, Action as BrowserAction};
use gtk::{ use gtk::{
gio::Icon,
glib::{timeout_add_local, ControlFlow, SourceId}, glib::{timeout_add_local, ControlFlow, SourceId},
prelude::{EditableExt, EntryExt, WidgetExt}, prelude::{EditableExt, EntryExt, WidgetExt},
Entry, EntryIconPosition, StateFlags, Entry, EntryIconPosition, StateFlags,
@ -15,7 +14,16 @@ use std::{
}; };
const PLACEHOLDER_TEXT: &str = "URL or search term..."; const PLACEHOLDER_TEXT: &str = "URL or search term...";
const GO_TOOLTIP_TEXT: &str = "Go to the address"; const GO_TOOLTIP_TEXT: &str = "Go to the address";
const GO_ICON_NAME: &str = "pan-end-symbolic";
const IDENTITY_TOOLTIP_TEXT: (&str, &str) = (
"Identity",
"Identity feature not available for this location",
);
const IDENTITY_ICON_NAME: (&str, &str) =
("avatar-default-symbolic", "applications-system-symbolic");
// Progress bar animation setup // Progress bar animation setup
const PROGRESS_ANIMATION_STEP: f64 = 0.05; const PROGRESS_ANIMATION_STEP: f64 = 0.05;
@ -49,31 +57,19 @@ impl Widget {
.hexpand(true) .hexpand(true)
.build(); .build();
// Init `go` button feature (if icon available) entry.set_primary_icon_name(Some(IDENTITY_ICON_NAME.0));
let go = match Icon::for_string("pan-end-symbolic") { entry.set_primary_icon_tooltip_text(Some(IDENTITY_TOOLTIP_TEXT.0));
Ok(icon) => {
entry.set_secondary_icon_gicon(Some(&icon)); entry.set_secondary_icon_name(Some(GO_ICON_NAME));
entry.set_secondary_icon_tooltip_text(Some(GO_TOOLTIP_TEXT)); entry.set_secondary_icon_tooltip_text(Some(GO_TOOLTIP_TEXT));
Some(icon)
}
Err(e) => {
println!("{e}"); // drop notice @TODO
None
}
};
// Connect events // Connect events
entry.connect_icon_release({ entry.connect_icon_release({
let tab_action = tab_action.clone(); let tab_action = tab_action.clone();
let go = go.clone();
move |this, position| match position { move |this, position| match position {
EntryIconPosition::Primary => todo!(), EntryIconPosition::Primary => tab_action.ident.activate(),
EntryIconPosition::Secondary => { EntryIconPosition::Secondary => tab_action.load.activate(Some(&this.text()), true),
if go.is_some() { _ => todo!(), // unexpected
tab_action.load.activate(Some(&this.text()), true);
}
}
_ => println!("Undefined icon position"), // drop notice @TODO
} }
}); });
@ -190,8 +186,36 @@ impl Widget {
Ok(()) Ok(())
} }
pub fn update(&self, progress_fraction: Option<f64>) { pub fn update(
// Skip update animation for None value &self,
progress_fraction: Option<f64>,
is_identity_applicable: bool,
is_identity_active: bool,
) {
// Update identity
self.entry
.set_primary_icon_activatable(is_identity_applicable);
self.entry
.set_primary_icon_sensitive(is_identity_applicable);
if is_identity_applicable {
self.entry.set_primary_icon_name(Some(IDENTITY_ICON_NAME.0));
self.entry
.set_primary_icon_tooltip_text(Some(IDENTITY_TOOLTIP_TEXT.0));
} else {
self.entry.set_primary_icon_name(Some(IDENTITY_ICON_NAME.1));
self.entry
.set_primary_icon_tooltip_text(Some(IDENTITY_TOOLTIP_TEXT.1));
}
let identity = self.entry.first_child().unwrap(); // @TODO handle
identity.remove_css_class("success");
if is_identity_active {
identity.add_css_class("success");
}
// Update progress
// * skip update animation for None value
if let Some(value) = progress_fraction { if let Some(value) = progress_fraction {
// Update shared fraction on new value was changed // Update shared fraction on new value was changed
if value != self.progress.fraction.replace(value) { if value != self.progress.fraction.replace(value) {

View File

@ -13,7 +13,6 @@ pub struct Widget {
impl Widget { impl Widget {
// Construct // Construct
pub fn new( pub fn new(
auth: &impl IsA<gtk::Widget>,
base: &impl IsA<gtk::Widget>, base: &impl IsA<gtk::Widget>,
history: &impl IsA<gtk::Widget>, history: &impl IsA<gtk::Widget>,
reload: &impl IsA<gtk::Widget>, reload: &impl IsA<gtk::Widget>,
@ -33,7 +32,6 @@ impl Widget {
gobject.append(reload); gobject.append(reload);
gobject.append(request); gobject.append(request);
gobject.append(bookmark); gobject.append(bookmark);
gobject.append(auth);
Self { gobject } Self { gobject }
} }