mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-08-26 06:21:58 +00:00
isolate request entry, fix proxy resolver change on entry update (by using sync lookup impl)
This commit is contained in:
parent
65c5ffebb0
commit
6e4eec54f0
@ -76,8 +76,8 @@ impl Tab {
|
||||
if let Some(item) = index.borrow_mut().remove(tab_page) {
|
||||
// keep removed `Item` reference in the memory (to reopen from the main menu)
|
||||
// * skip item with blank request
|
||||
if !item.page.navigation.request().is_empty() {
|
||||
profile.history.close(&item.page.navigation.request());
|
||||
if !item.page.navigation.request.is_empty() {
|
||||
profile.history.close(&item.page.navigation.request.text());
|
||||
}
|
||||
}
|
||||
// reassign global actions to active tab
|
||||
@ -160,7 +160,7 @@ impl Tab {
|
||||
// Expect user input on tab appended has empty request entry
|
||||
// * this action initiated here because should be applied on tab appending event only
|
||||
if request.is_none() || request.is_some_and(|value| value.is_empty()) {
|
||||
item.page.navigation.grab_focus();
|
||||
item.page.navigation.request.grab_focus();
|
||||
}
|
||||
|
||||
// Relate with GTK `TabPage` with app `Item`
|
||||
@ -221,7 +221,7 @@ impl Tab {
|
||||
// Save page at given `position`, `None` to save selected page (if available)
|
||||
pub fn save_as(&self, page_position: Option<i32>) {
|
||||
if let Some(item) = self.item(page_position) {
|
||||
item.page.navigation.to_download();
|
||||
item.page.navigation.request.to_download();
|
||||
self.window_action.reload.activate();
|
||||
}
|
||||
}
|
||||
@ -229,7 +229,7 @@ impl Tab {
|
||||
// View source for page at given `position`, `None` to use selected page (if available)
|
||||
pub fn source(&self, page_position: Option<i32>) {
|
||||
if let Some(item) = self.item(page_position) {
|
||||
item.page.navigation.to_source();
|
||||
item.page.navigation.request.to_source();
|
||||
self.window_action.reload.activate();
|
||||
}
|
||||
}
|
||||
@ -273,7 +273,7 @@ impl Tab {
|
||||
pub fn reload(&self, page_position: Option<i32>) {
|
||||
if let Some(item) = self.item(page_position) {
|
||||
item.client
|
||||
.handle(&item.page.navigation.request(), true, false);
|
||||
.handle(&item.page.navigation.request.text(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,7 +414,7 @@ fn update_actions(
|
||||
window_action
|
||||
.save_as
|
||||
.simple_action
|
||||
.set_enabled(!item.page.navigation.is_file());
|
||||
.set_enabled(!item.page.navigation.request.is_file());
|
||||
|
||||
window_action.change_state(Some(tab_view.page_position(tab_page)));
|
||||
return;
|
||||
|
@ -83,9 +83,9 @@ impl Item {
|
||||
let page = page.clone();
|
||||
move |this, _| {
|
||||
this.set_enabled(false);
|
||||
if let Some(uri) = page.navigation.home() {
|
||||
if let Some(uri) = page.navigation.request.home() {
|
||||
let request = uri.to_string();
|
||||
page.navigation.set_request(&request);
|
||||
page.navigation.request.set_text(&request);
|
||||
client.handle(&request, true, false);
|
||||
}
|
||||
}
|
||||
@ -96,7 +96,7 @@ impl Item {
|
||||
let client = client.clone();
|
||||
move |request, is_snap_history, is_redirect| {
|
||||
if let Some(request) = request {
|
||||
page.navigation.set_request(&request);
|
||||
page.navigation.request.set_text(&request);
|
||||
client.handle(&request, is_snap_history, is_redirect);
|
||||
}
|
||||
}
|
||||
@ -110,7 +110,7 @@ impl Item {
|
||||
action.reload.connect_activate({
|
||||
let page = page.clone();
|
||||
let client = client.clone();
|
||||
move |_, _| client.handle(&page.navigation.request(), true, false)
|
||||
move |_, _| client.handle(&page.navigation.request.text(), true, false)
|
||||
});
|
||||
|
||||
action.reload.connect_enabled_notify({
|
||||
@ -145,7 +145,7 @@ impl Item {
|
||||
|
||||
// Handle immediately on request
|
||||
if let Some(request) = request {
|
||||
page.navigation.set_request(request);
|
||||
page.navigation.request.set_text(request);
|
||||
if is_load {
|
||||
client.handle(request, true, false)
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ fn handle(
|
||||
} else {
|
||||
let t = target.to_string();
|
||||
if matches!(redirect, Redirect::Permanent { .. }) {
|
||||
page.navigation.set_request(&t);
|
||||
page.navigation.request.set_text(&t);
|
||||
}
|
||||
redirects.replace(total);
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ impl Nex {
|
||||
.request
|
||||
.info
|
||||
.replace(i.into_permanent_redirect());
|
||||
self.page.navigation.set_request(&r);
|
||||
self.page.navigation.request.set_text(&r);
|
||||
self.page.item_action.load.activate(Some(&r), false, true);
|
||||
return; // prevents operation cancelled message on redirect
|
||||
}
|
||||
|
@ -98,10 +98,10 @@ impl Page {
|
||||
pub fn snap_history(&self) {
|
||||
self.item_action
|
||||
.history
|
||||
.add(self.navigation.request(), true);
|
||||
.add(self.navigation.request.text(), true);
|
||||
self.profile
|
||||
.history
|
||||
.open(self.navigation.request(), Some(self.title()))
|
||||
.open(self.navigation.request.text(), Some(self.title()))
|
||||
}
|
||||
|
||||
/// Cleanup session for `Self`
|
||||
@ -136,7 +136,7 @@ impl Page {
|
||||
// Make initial page history snap
|
||||
self.profile
|
||||
.history
|
||||
.open(self.navigation.request(), Some(self.title()));
|
||||
.open(self.navigation.request.text(), Some(self.title()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -176,7 +176,9 @@ impl Page {
|
||||
}
|
||||
|
||||
pub fn set_progress(&self, progress_fraction: f64) {
|
||||
self.navigation.set_progress_fraction(progress_fraction);
|
||||
self.navigation
|
||||
.request
|
||||
.set_progress_fraction(progress_fraction);
|
||||
self.tab_page.set_loading(progress_fraction > 0.0)
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,7 @@ mod request;
|
||||
use super::{ItemAction, Profile, TabAction, WindowAction};
|
||||
use anyhow::Result;
|
||||
use bookmark::Bookmark;
|
||||
use gtk::{
|
||||
Box, Button, Orientation,
|
||||
glib::{GString, Uri},
|
||||
prelude::{BoxExt, EditableExt, EntryExt, WidgetExt},
|
||||
};
|
||||
use gtk::{Box, Button, Orientation, prelude::BoxExt};
|
||||
use history::History;
|
||||
use home::Home;
|
||||
use reload::Reload;
|
||||
@ -43,7 +39,7 @@ impl Navigation {
|
||||
let request = Rc::new(Request::build(item_action, profile));
|
||||
let reload = Button::reload((window_action, tab_action, item_action), &request);
|
||||
let home = Button::home((window_action, tab_action, item_action), &request);
|
||||
let bookmark = Rc::new(Bookmark::build(window_action, profile, &request.entry));
|
||||
let bookmark = Rc::new(Bookmark::build(window_action, profile, &request));
|
||||
|
||||
// Init main widget
|
||||
let g_box = Box::builder()
|
||||
@ -57,7 +53,7 @@ impl Navigation {
|
||||
g_box.append(&home);
|
||||
g_box.append(&history);
|
||||
g_box.append(&reload);
|
||||
g_box.append(&request.entry);
|
||||
request.append_to(&g_box); // private member
|
||||
g_box.append(&bookmark.button);
|
||||
|
||||
Self {
|
||||
@ -114,45 +110,9 @@ impl Navigation {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn grab_focus(&self) -> bool {
|
||||
self.request.entry.grab_focus()
|
||||
}
|
||||
|
||||
pub fn show_identity_dialog(&self) {
|
||||
self.request.show_identity_dialog()
|
||||
}
|
||||
|
||||
// Setters
|
||||
|
||||
pub fn set_request(&self, value: &str) {
|
||||
self.request.entry.set_text(value);
|
||||
}
|
||||
|
||||
pub fn set_progress_fraction(&self, value: f64) {
|
||||
self.request.entry.set_progress_fraction(value);
|
||||
}
|
||||
|
||||
pub fn to_download(&self) {
|
||||
self.request.to_download();
|
||||
}
|
||||
|
||||
pub fn to_source(&self) {
|
||||
self.request.to_source();
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
pub fn request(&self) -> GString {
|
||||
self.request.entry.text()
|
||||
}
|
||||
|
||||
pub fn home(&self) -> Option<Uri> {
|
||||
self.request.home()
|
||||
}
|
||||
|
||||
pub fn is_file(&self) -> bool {
|
||||
self.request.is_file()
|
||||
}
|
||||
}
|
||||
|
||||
// Tools
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{Profile, WindowAction};
|
||||
use super::{Profile, Request, WindowAction};
|
||||
use gtk::{
|
||||
Button, Entry,
|
||||
prelude::{ActionExt, ButtonExt, EditableExt, WidgetExt},
|
||||
Button,
|
||||
prelude::{ActionExt, ButtonExt, WidgetExt},
|
||||
};
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -10,12 +10,12 @@ const TOOLTIP_TEXT: (&str, &str) = ("Add Bookmark", "Remove Bookmark");
|
||||
|
||||
pub struct Bookmark {
|
||||
profile: Rc<Profile>,
|
||||
request: Entry,
|
||||
request: Rc<Request>,
|
||||
pub button: Button,
|
||||
}
|
||||
|
||||
impl Bookmark {
|
||||
pub fn build(action: &Rc<WindowAction>, profile: &Rc<Profile>, request: &Entry) -> Self {
|
||||
pub fn build(action: &Rc<WindowAction>, profile: &Rc<Profile>, request: &Rc<Request>) -> Self {
|
||||
let button = Button::builder()
|
||||
.action_name(format!(
|
||||
"{}.{}",
|
||||
@ -23,11 +23,12 @@ impl Bookmark {
|
||||
action.bookmark.simple_action.name()
|
||||
))
|
||||
.build();
|
||||
update(profile, &button, request.text());
|
||||
request.connect_changed({
|
||||
let profile = profile.clone();
|
||||
let button = button.clone();
|
||||
move |entry| update(&profile, &button, entry.text())
|
||||
update(profile, &button, &request.text());
|
||||
request.on_change({
|
||||
let b = button.clone();
|
||||
let p = profile.clone();
|
||||
let r = request.clone();
|
||||
move || update(&p, &b, &r.text())
|
||||
});
|
||||
Self {
|
||||
profile: profile.clone(),
|
||||
@ -65,14 +66,10 @@ fn icon_name(has_bookmark: bool) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
fn update(profile: &Rc<Profile>, button: &Button, request: gtk::glib::GString) {
|
||||
let profile = profile.clone();
|
||||
let button = button.clone();
|
||||
gtk::glib::spawn_future_local(async move {
|
||||
button.set_sensitive(false); // lock
|
||||
let has_bookmark = profile.bookmark.is_match_request(&request);
|
||||
button.set_icon_name(icon_name(has_bookmark));
|
||||
button.set_tooltip_text(Some(tooltip_text(has_bookmark)));
|
||||
button.set_sensitive(true);
|
||||
}); // may take a while
|
||||
fn update(profile: &Profile, button: &Button, request: &str) {
|
||||
button.set_sensitive(false); // lock
|
||||
let has_bookmark = profile.bookmark.is_match_request(request);
|
||||
button.set_icon_name(icon_name(has_bookmark));
|
||||
button.set_tooltip_text(Some(tooltip_text(has_bookmark)));
|
||||
button.set_sensitive(true);
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ const PREFIX_DOWNLOAD: &str = "download:";
|
||||
const PREFIX_SOURCE: &str = "source:";
|
||||
|
||||
pub struct Request {
|
||||
pub entry: Entry,
|
||||
/// * keep it private to properly update some local dependencies on change (e.g. proxy resolver)
|
||||
entry: Entry,
|
||||
pub info: Rc<RefCell<Info>>,
|
||||
profile: Rc<Profile>,
|
||||
proxy_resolver: Rc<RefCell<Option<ProxyResolver>>>,
|
||||
@ -290,6 +291,27 @@ impl Request {
|
||||
self.entry.text().starts_with("file://")
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.entry.text_length() > 0
|
||||
}
|
||||
|
||||
pub fn grab_focus(&self) -> bool {
|
||||
self.entry.grab_focus()
|
||||
}
|
||||
|
||||
pub fn set_progress_fraction(&self, value: f64) {
|
||||
self.entry.set_progress_fraction(value);
|
||||
}
|
||||
|
||||
pub fn set_text(&self, value: &str) {
|
||||
self.entry.set_text(value);
|
||||
self.refresh()
|
||||
}
|
||||
|
||||
pub fn text(&self) -> GString {
|
||||
self.entry.text()
|
||||
}
|
||||
|
||||
/// Get [ProxyResolver](https://docs.gtk.org/gio/iface.ProxyResolver.html)
|
||||
/// which is constructed for every `Request` entry change
|
||||
/// * useful on build new [SocketClient](https://docs.gtk.org/gio/class.SocketClient.html)
|
||||
@ -298,6 +320,15 @@ impl Request {
|
||||
self.proxy_resolver.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn append_to(&self, parent: >k::Box) {
|
||||
use gtk::prelude::BoxExt;
|
||||
parent.append(&self.entry)
|
||||
}
|
||||
|
||||
pub fn on_change(&self, callback: impl Fn() + 'static) {
|
||||
self.entry.connect_changed(move |_| callback());
|
||||
}
|
||||
|
||||
// Tools
|
||||
|
||||
/// Get request value with formatted `download` prefix
|
||||
@ -474,34 +505,30 @@ fn update_blocked(
|
||||
}
|
||||
|
||||
/// Indicate proxy connections @TODO cancel previous operation on update
|
||||
/// * note: it's important to use sync lookup method by the current impl
|
||||
fn refresh_proxy_resolver(
|
||||
entry: &Entry,
|
||||
profile: &Rc<Profile>,
|
||||
resolver: &Rc<RefCell<Option<ProxyResolver>>>,
|
||||
profile: &Profile,
|
||||
resolver: &RefCell<Option<ProxyResolver>>,
|
||||
) {
|
||||
const NONE: &[&str] = &[];
|
||||
|
||||
let t = entry.text(); // allocate once
|
||||
|
||||
match profile.proxy.matches(&t) {
|
||||
Some(m) => m.clone().lookup_async(&t, Cancellable::NONE, {
|
||||
let e = entry.clone();
|
||||
let p = profile.clone();
|
||||
let r = resolver.clone();
|
||||
move |l| {
|
||||
let (css_classes, tooltip_text) = match l {
|
||||
Ok(h) => (&["accent"], format!("Proxy over {}", h.join(","))),
|
||||
Err(i) => (&["error"], i.to_string()),
|
||||
};
|
||||
e.set_css_classes(if p.proxy.misc.is_highlight_request_entry() {
|
||||
css_classes
|
||||
} else {
|
||||
NONE
|
||||
});
|
||||
e.set_tooltip_text(Some(&tooltip_text));
|
||||
r.replace(Some(m));
|
||||
}
|
||||
}),
|
||||
Some(m) => {
|
||||
let (css_classes, tooltip_text) = match m.lookup(&t, Cancellable::NONE) {
|
||||
Ok(h) => (&["accent"], format!("Proxy over {}", h.join(","))),
|
||||
Err(i) => (&["error"], i.to_string()),
|
||||
};
|
||||
entry.set_css_classes(if profile.proxy.misc.is_highlight_request_entry() {
|
||||
css_classes
|
||||
} else {
|
||||
NONE
|
||||
});
|
||||
entry.set_tooltip_text(Some(&tooltip_text));
|
||||
resolver.replace(Some(m));
|
||||
}
|
||||
None => {
|
||||
entry.set_css_classes(NONE);
|
||||
entry.set_tooltip_text(None);
|
||||
|
Loading…
x
Reference in New Issue
Block a user