diff --git a/src/app/browser/window/tab/item/client/driver/file.rs b/src/app/browser/window/tab/item/client/driver/file.rs index 0221c6ab..f8218b85 100644 --- a/src/app/browser/window/tab/item/client/driver/file.rs +++ b/src/app/browser/window/tab/item/client/driver/file.rs @@ -1,9 +1,8 @@ +mod status; +mod text; + use super::{Feature, Page}; -use gtk::{ - gio::Cancellable, - glib::{GString, Uri}, -}; -use sourceview::prelude::FileExt; +use gtk::{gio::Cancellable, glib::Uri}; use std::rc::Rc; /// Local files client driver @@ -23,8 +22,10 @@ impl File { use gtk::{ gio::{File, FileQueryInfoFlags, FileType}, glib::Priority, - prelude::FileExtManual, + prelude::{FileExt, FileExtManual}, }; + use status::Status; + use text::Text; let url = uri.to_string(); let file = File::for_uri(&url); @@ -70,22 +71,28 @@ impl File { if matches!(*feature, Feature::Source) { load_contents_async(file, cancellable, move |result| { match result { - Ok(data) => text(page, uri, Text::Source(data)), - Err(message) => failure(page, &message), + Ok(data) => Text::Source(uri, data).handle(page), + Err(message) => { + Status::Failure(message).handle(page) + } } }) } else if url.ends_with(".txt") { load_contents_async(file, cancellable, move |result| { match result { - Ok(data) => text(page, uri, Text::Plain(data)), - Err(message) => failure(page, &message), + Ok(data) => Text::Plain(uri, data).handle(page), + Err(message) => { + Status::Failure(message).handle(page) + } } }); } else { load_contents_async(file, cancellable, move |result| { match result { - Ok(data) => text(page, uri, Text::Gemini(data)), - Err(message) => failure(page, &message), + Ok(data) => Text::Gemini(uri, data).handle(page), + Err(message) => { + Status::Failure(message).handle(page) + } } }) } @@ -93,11 +100,15 @@ impl File { "image/png" | "image/gif" | "image/jpeg" | "image/webp" => { todo!() } - _ => failure(page, "Unsupported content type"), + mime => Status::Failure(format!( + "Content type `{mime}` yet not supported" + )) + .handle(page), }, - None => failure(page, "Undetectable content type"), + None => Status::Failure("Undetectable content type".to_string()) + .handle(page), }, - Err(e) => failure(page, &e.to_string()), + Err(e) => Status::Failure(e.to_string()).handle(page), } }, ), @@ -107,36 +118,6 @@ impl File { // Tools -/// Handle as failure status page -fn failure(page: Rc, message: &str) { - let status = page.content.to_status_failure(); - status.set_description(Some(message)); - page.set_title(&status.title()); - page.set_progress(0.0); -} - -enum Text { - Gemini(String), - Plain(String), - Source(String), -} - -/// Handle as text -fn text(page: Rc, uri: Uri, text: Text) { - let widget = match text { - Text::Gemini(data) => page.content.to_text_gemini(&uri, &data), - Text::Plain(data) => page.content.to_text_plain(&data), - Text::Source(data) => page.content.to_text_source(&data), - }; - page.search.set(Some(widget.text_view)); - page.set_title(&match widget.meta.title { - Some(title) => title.into(), // @TODO - None => uri_to_title(&uri), - }); - page.set_progress(0.0); - page.window_action.find.simple_action.set_enabled(true); -} - fn load_contents_async( file: gtk::gio::File, cancellable: Cancellable, @@ -155,18 +136,3 @@ fn load_contents_async( } }) } - -/// Helper function, extract readable title from [Uri](https://docs.gtk.org/glib/struct.Uri.html) -/// * useful as common placeholder when page title could not be detected -/// * this feature may be improved and moved outside @TODO -fn uri_to_title(uri: &Uri) -> GString { - let path = uri.path(); - if path.split('/').last().unwrap_or_default().is_empty() { - match uri.host() { - Some(host) => host, - None => "Untitled".into(), - } - } else { - path - } -} diff --git a/src/app/browser/window/tab/item/client/driver/file/status.rs b/src/app/browser/window/tab/item/client/driver/file/status.rs new file mode 100644 index 00000000..aabb894a --- /dev/null +++ b/src/app/browser/window/tab/item/client/driver/file/status.rs @@ -0,0 +1,18 @@ +use super::Page; +use std::rc::Rc; + +pub enum Status { + Failure(String), +} + +impl Status { + pub fn handle(&self, page: Rc) { + let (message, widget) = match self { + Self::Failure(message) => (message, page.content.to_status_failure()), + }; + widget.set_description(Some(message)); + page.set_title(&widget.title()); + page.set_progress(0.0); + page.window_action.find.simple_action.set_enabled(false); + } +} diff --git a/src/app/browser/window/tab/item/client/driver/file/text.rs b/src/app/browser/window/tab/item/client/driver/file/text.rs new file mode 100644 index 00000000..7ad55973 --- /dev/null +++ b/src/app/browser/window/tab/item/client/driver/file/text.rs @@ -0,0 +1,41 @@ +use super::Page; +use gtk::glib::{GString, Uri}; +use std::rc::Rc; + +pub enum Text { + Gemini(Uri, String), + Plain(Uri, String), + Source(Uri, String), +} + +impl Text { + pub fn handle(&self, page: Rc) { + let (uri, widget) = match self { + Self::Gemini(uri, data) => (uri, page.content.to_text_gemini(uri, data)), + Self::Plain(uri, data) => (uri, page.content.to_text_plain(data)), + Self::Source(uri, data) => (uri, page.content.to_text_source(data)), + }; + page.search.set(Some(widget.text_view)); + page.set_title(&match widget.meta.title { + Some(title) => title.into(), // @TODO + None => uri_to_title(uri), + }); + page.set_progress(0.0); + page.window_action.find.simple_action.set_enabled(true); + } +} + +/// Helper function, extract readable title from [Uri](https://docs.gtk.org/glib/struct.Uri.html) +/// * useful as common placeholder when page title could not be detected +/// * this feature may be improved and moved outside @TODO already duplicated! +fn uri_to_title(uri: &Uri) -> GString { + let path = uri.path(); + if path.split('/').last().unwrap_or_default().is_empty() { + match uri.host() { + Some(host) => host, + None => "Untitled".into(), + } + } else { + path + } +}