mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-02-06 16:34:13 +00:00
separate page handler from loader, draft some Titan features
This commit is contained in:
parent
123be8c97e
commit
f73b5c7956
@ -325,9 +325,6 @@ pub fn history_forward(page: &Rc<Page>) {
|
|||||||
|
|
||||||
/// Page load function with recursive redirection support
|
/// Page load function with recursive redirection support
|
||||||
pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
||||||
use client::response::{Certificate, Failure, Input, Redirect};
|
|
||||||
use client::Response;
|
|
||||||
|
|
||||||
// Move focus out from navigation entry
|
// Move focus out from navigation entry
|
||||||
page.browser_action
|
page.browser_action
|
||||||
.escape
|
.escape
|
||||||
@ -354,7 +351,17 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
|
|
||||||
page.client.request(query, {
|
page.client.request(query, {
|
||||||
let page = page.clone();
|
let page = page.clone();
|
||||||
move |response| {
|
move |response| handle(&page, response)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Response handler for `Page`
|
||||||
|
/// * may call itself on Titan response
|
||||||
|
fn handle(page: &Rc<Page>, response: client::Response) {
|
||||||
|
use client::{
|
||||||
|
response::{Certificate, Failure, Input, Redirect},
|
||||||
|
Response,
|
||||||
|
};
|
||||||
match response {
|
match response {
|
||||||
Response::Certificate(this) => match this {
|
Response::Certificate(this) => match this {
|
||||||
Certificate::Invalid {
|
Certificate::Invalid {
|
||||||
@ -391,9 +398,15 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
// Update window
|
// Update window
|
||||||
page.browser_action.update.activate(Some(&page.id));
|
page.browser_action.update.activate(Some(&page.id));
|
||||||
}
|
}
|
||||||
Failure::Mime { base, mime, message } => {
|
Failure::Mime {
|
||||||
|
base,
|
||||||
|
mime,
|
||||||
|
message,
|
||||||
|
} => {
|
||||||
// Update widget
|
// Update widget
|
||||||
let status = page.content.to_status_mime(&mime, Some((&page.tab_action, &base)));
|
let status = page
|
||||||
|
.content
|
||||||
|
.to_status_mime(&mime, Some((&page.tab_action, &base)));
|
||||||
status.set_description(Some(&message));
|
status.set_description(Some(&message));
|
||||||
|
|
||||||
// Update meta
|
// Update meta
|
||||||
@ -437,8 +450,22 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
|
|
||||||
page.browser_action.update.activate(Some(&page.id));
|
page.browser_action.update.activate(Some(&page.id));
|
||||||
}
|
}
|
||||||
Input::Titan { .. } => {
|
Input::Titan(this) => {
|
||||||
page.input.set_new_titan(move |_| todo!());
|
page.input.set_new_titan(this, {
|
||||||
|
let page = page.clone();
|
||||||
|
move |result| match result {
|
||||||
|
Ok(response) => handle(&page, response),
|
||||||
|
Err(e) => {
|
||||||
|
let status = page.content.to_status_failure();
|
||||||
|
//status.set_description(Some(&e.to_string()));
|
||||||
|
// @TODO
|
||||||
|
|
||||||
|
page.status.replace(Status::Failure { time: now() });
|
||||||
|
page.title.replace(status.title());
|
||||||
|
page.browser_action.update.activate(Some(&page.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
page.status.replace(Status::Input { time: now() });
|
page.status.replace(Status::Input { time: now() });
|
||||||
page.title.replace("Titan input".into());
|
page.title.replace("Titan input".into());
|
||||||
@ -449,7 +476,7 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
Response::Redirect(this) => match this {
|
Response::Redirect(this) => match this {
|
||||||
Redirect::Background(request) => {
|
Redirect::Background(request) => {
|
||||||
load(&page, Some(&request.as_uri().to_string()), false)
|
load(&page, Some(&request.as_uri().to_string()), false)
|
||||||
},
|
}
|
||||||
Redirect::Foreground(request) => {
|
Redirect::Foreground(request) => {
|
||||||
page.navigation
|
page.navigation
|
||||||
.request
|
.request
|
||||||
@ -458,8 +485,12 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
.set_text(&request.as_uri().to_string());
|
.set_text(&request.as_uri().to_string());
|
||||||
load(&page, Some(&request.as_uri().to_string()), false);
|
load(&page, Some(&request.as_uri().to_string()), false);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
Response::TextGemini { base, source, is_source_request } => {
|
Response::TextGemini {
|
||||||
|
base,
|
||||||
|
source,
|
||||||
|
is_source_request,
|
||||||
|
} => {
|
||||||
let widget = if is_source_request {
|
let widget = if is_source_request {
|
||||||
page.content.to_text_source(&source)
|
page.content.to_text_source(&source)
|
||||||
} else {
|
} else {
|
||||||
@ -480,7 +511,11 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
page.window_action.find.simple_action.set_enabled(true);
|
page.window_action.find.simple_action.set_enabled(true);
|
||||||
page.browser_action.update.activate(Some(&page.id));
|
page.browser_action.update.activate(Some(&page.id));
|
||||||
}
|
}
|
||||||
Response::Download { base, cancellable, stream } => {
|
Response::Download {
|
||||||
|
base,
|
||||||
|
cancellable,
|
||||||
|
stream,
|
||||||
|
} => {
|
||||||
// Init download widget
|
// Init download widget
|
||||||
let status = page.content.to_status_download(
|
let status = page.content.to_status_download(
|
||||||
uri_to_title(&base).trim_matches(MAIN_SEPARATOR), // grab default filename from base URI,
|
uri_to_title(&base).trim_matches(MAIN_SEPARATOR), // grab default filename from base URI,
|
||||||
@ -494,7 +529,7 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
gtk::gio::FileCreateFlags::NONE,
|
gtk::gio::FileCreateFlags::NONE,
|
||||||
Some(&cancellable)
|
Some(&cancellable),
|
||||||
) {
|
) {
|
||||||
Ok(file_output_stream) => {
|
Ok(file_output_stream) => {
|
||||||
// Asynchronously read [IOStream](https://docs.gtk.org/gio/class.IOStream.html)
|
// Asynchronously read [IOStream](https://docs.gtk.org/gio/class.IOStream.html)
|
||||||
@ -509,36 +544,39 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
(
|
(
|
||||||
0x100000, // 1M bytes per chunk
|
0x100000, // 1M bytes per chunk
|
||||||
None, // unlimited
|
None, // unlimited
|
||||||
0 // initial totals
|
0, // initial totals
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
// on chunk
|
// on chunk
|
||||||
{
|
{
|
||||||
let action = action.clone();
|
let action = action.clone();
|
||||||
move |_, total| action.update.activate(
|
move |_, total| {
|
||||||
&format!(
|
action.update.activate(&format!(
|
||||||
"Received {}...",
|
"Received {}...",
|
||||||
crate::tool::format_bytes(total)
|
crate::tool::format_bytes(total)
|
||||||
)
|
))
|
||||||
)
|
}
|
||||||
},
|
},
|
||||||
// on complete
|
// on complete
|
||||||
{
|
{
|
||||||
let action = action.clone();
|
let action = action.clone();
|
||||||
move |result| match result {
|
move |result| match result {
|
||||||
Ok((_, total)) => action.complete.activate(
|
Ok((_, total)) => {
|
||||||
&format!("Saved to {} ({total} bytes total)", file.parse_name())
|
action.complete.activate(&format!(
|
||||||
),
|
"Saved to {} ({total} bytes total)",
|
||||||
Err(e) => action.cancel.activate(&e.to_string())
|
file.parse_name()
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
Err(e) => action.cancel.activate(&e.to_string()),
|
||||||
}
|
}
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
Err(e) => action.cancel.activate(&e.to_string())
|
),
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
Err(e) => action.cancel.activate(&e.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update meta
|
// Update meta
|
||||||
@ -548,7 +586,12 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
// Update window
|
// Update window
|
||||||
page.browser_action.update.activate(Some(&page.id));
|
page.browser_action.update.activate(Some(&page.id));
|
||||||
}
|
}
|
||||||
Response::Stream { base, mime, stream, cancellable } => match mime.as_str() {
|
Response::Stream {
|
||||||
|
base,
|
||||||
|
mime,
|
||||||
|
stream,
|
||||||
|
cancellable,
|
||||||
|
} => match mime.as_str() {
|
||||||
// @TODO use client-side const or enum?
|
// @TODO use client-side const or enum?
|
||||||
"image/png" | "image/gif" | "image/jpeg" | "image/webp" => {
|
"image/png" | "image/gif" | "image/jpeg" | "image/webp" => {
|
||||||
// Final image size unknown, show loading widget
|
// Final image size unknown, show loading widget
|
||||||
@ -568,9 +611,7 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
0xA00000, // 10M bytes max to prevent memory overflow if server play with promises
|
0xA00000, // 10M bytes max to prevent memory overflow if server play with promises
|
||||||
move |_, total| {
|
move |_, total| {
|
||||||
// Update loading progress
|
// Update loading progress
|
||||||
status.set_description(Some(&format!(
|
status.set_description(Some(&format!("Download: {total} bytes")));
|
||||||
"Download: {total} bytes"
|
|
||||||
)));
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
let page = page.clone();
|
let page = page.clone();
|
||||||
@ -584,32 +625,25 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
match result {
|
match result {
|
||||||
Ok(buffer) => {
|
Ok(buffer) => {
|
||||||
// Update page meta
|
// Update page meta
|
||||||
page.status.replace(Status::Success {
|
page.status
|
||||||
time: now(),
|
.replace(Status::Success { time: now() });
|
||||||
});
|
|
||||||
page.title.replace(uri_to_title(&base));
|
page.title.replace(uri_to_title(&base));
|
||||||
|
|
||||||
// Update page content
|
// Update page content
|
||||||
page.content.to_image(
|
page.content
|
||||||
&Texture::for_pixbuf(&buffer),
|
.to_image(&Texture::for_pixbuf(&buffer));
|
||||||
);
|
|
||||||
|
|
||||||
// Update window components
|
// Update window components
|
||||||
page.browser_action
|
page.browser_action.update.activate(Some(&page.id));
|
||||||
.update
|
|
||||||
.activate(Some(&page.id));
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Update widget
|
// Update widget
|
||||||
let status = page.content.to_status_failure();
|
let status = page.content.to_status_failure();
|
||||||
status.set_description(Some(
|
status.set_description(Some(e.message()));
|
||||||
e.message(),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Update meta
|
// Update meta
|
||||||
page.status.replace(Status::Failure {
|
page.status
|
||||||
time: now(),
|
.replace(Status::Failure { time: now() });
|
||||||
});
|
|
||||||
page.title.replace(status.title());
|
page.title.replace(status.title());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,8 +664,6 @@ pub fn load(page: &Rc<Page>, request: Option<&str>, is_history: bool) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => todo!(), // unexpected
|
_ => todo!(), // unexpected
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
use gtk::{
|
pub mod titan;
|
||||||
gio::{Cancellable, IOStream},
|
pub use titan::Titan;
|
||||||
glib::{GString, Uri},
|
|
||||||
};
|
use gtk::glib::{GString, Uri};
|
||||||
|
|
||||||
pub enum Input {
|
pub enum Input {
|
||||||
Response {
|
Response { base: Uri, title: GString },
|
||||||
base: Uri,
|
Sensitive { base: Uri, title: GString },
|
||||||
title: GString,
|
Titan(Titan),
|
||||||
},
|
|
||||||
Sensitive {
|
|
||||||
base: Uri,
|
|
||||||
title: GString,
|
|
||||||
},
|
|
||||||
Titan {
|
|
||||||
base: Uri,
|
|
||||||
cancellable: Cancellable,
|
|
||||||
stream: IOStream,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
use gtk::gio::{Cancellable, IOStream};
|
||||||
|
|
||||||
|
pub struct Titan {
|
||||||
|
cancellable: Cancellable,
|
||||||
|
stream: IOStream,
|
||||||
|
}
|
@ -3,15 +3,14 @@ mod sensitive;
|
|||||||
mod titan;
|
mod titan;
|
||||||
mod widget;
|
mod widget;
|
||||||
|
|
||||||
|
use super::TabAction;
|
||||||
|
use gtk::glib::Uri;
|
||||||
use response::Response;
|
use response::Response;
|
||||||
use sensitive::Sensitive;
|
use sensitive::Sensitive;
|
||||||
|
use std::rc::Rc;
|
||||||
use titan::Titan;
|
use titan::Titan;
|
||||||
use widget::Widget;
|
use widget::Widget;
|
||||||
|
|
||||||
use crate::app::browser::window::tab::item::Action as TabAction;
|
|
||||||
use gtk::glib::Uri;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub struct Input {
|
pub struct Input {
|
||||||
pub widget: Rc<Widget>,
|
pub widget: Rc<Widget>,
|
||||||
}
|
}
|
||||||
@ -66,8 +65,12 @@ impl Input {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_new_titan(&self, callback: impl Fn(&[u8]) + 'static) {
|
pub fn set_new_titan(
|
||||||
|
&self,
|
||||||
|
titan: super::client::response::input::Titan,
|
||||||
|
callback: impl Fn(Result<super::client::Response, ()>) + 'static,
|
||||||
|
) {
|
||||||
self.widget
|
self.widget
|
||||||
.update(Some(&Titan::build(callback).widget.g_box));
|
.update(Some(&Titan::build(titan, callback).widget.g_box));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,10 @@ mod widget;
|
|||||||
|
|
||||||
use control::Control;
|
use control::Control;
|
||||||
use form::Form;
|
use form::Form;
|
||||||
use title::Title;
|
|
||||||
use widget::Widget;
|
|
||||||
|
|
||||||
use gtk::{gio::SimpleAction, glib::uuid_string_random};
|
use gtk::{gio::SimpleAction, glib::uuid_string_random};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use title::Title;
|
||||||
|
use widget::Widget;
|
||||||
|
|
||||||
pub struct Titan {
|
pub struct Titan {
|
||||||
// Components
|
// Components
|
||||||
@ -20,7 +19,10 @@ impl Titan {
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
/// Build new `Self`
|
/// Build new `Self`
|
||||||
pub fn build(on_sent: impl Fn(&[u8]) + 'static) -> Self {
|
pub fn build(
|
||||||
|
titan: super::super::client::response::input::Titan,
|
||||||
|
callback: impl Fn(Result<super::super::client::Response, ()>) + 'static,
|
||||||
|
) -> Self {
|
||||||
// Init local actions
|
// Init local actions
|
||||||
let action_update = SimpleAction::new(&uuid_string_random(), None);
|
let action_update = SimpleAction::new(&uuid_string_random(), None);
|
||||||
let action_send = SimpleAction::new(&uuid_string_random(), None);
|
let action_send = SimpleAction::new(&uuid_string_random(), None);
|
||||||
@ -46,7 +48,7 @@ impl Titan {
|
|||||||
|
|
||||||
action_send.connect_activate({
|
action_send.connect_activate({
|
||||||
// @TODO let form = form.clone();
|
// @TODO let form = form.clone();
|
||||||
move |_, _| on_sent(&[]) // @TODO input data
|
move |_, _| callback(todo!()) // @TODO input data
|
||||||
});
|
});
|
||||||
|
|
||||||
// Return activated struct
|
// Return activated struct
|
||||||
|
Loading…
x
Reference in New Issue
Block a user