feat: image loading on different thread
This commit is contained in:
parent
83c478cfd2
commit
6240c59e24
8 changed files with 137 additions and 23 deletions
97
Cargo.lock
generated
97
Cargo.lock
generated
|
@ -362,6 +362,21 @@ dependencies = [
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gdk"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f5ba081bdef3b75ebcdbfc953699ed2d7417d6bd853347a42a37d76406a33646"
|
||||||
|
dependencies = [
|
||||||
|
"cairo-rs",
|
||||||
|
"gdk-pixbuf",
|
||||||
|
"gdk-sys",
|
||||||
|
"gio",
|
||||||
|
"glib",
|
||||||
|
"libc",
|
||||||
|
"pango",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk-pixbuf"
|
name = "gdk-pixbuf"
|
||||||
version = "0.18.5"
|
version = "0.18.5"
|
||||||
|
@ -388,6 +403,23 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gdk-sys"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2"
|
||||||
|
dependencies = [
|
||||||
|
"cairo-sys-rs",
|
||||||
|
"gdk-pixbuf-sys",
|
||||||
|
"gio-sys",
|
||||||
|
"glib-sys",
|
||||||
|
"gobject-sys",
|
||||||
|
"libc",
|
||||||
|
"pango-sys",
|
||||||
|
"pkg-config",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk4"
|
name = "gdk4"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
|
@ -878,6 +910,16 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
|
@ -940,13 +982,16 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures",
|
"futures",
|
||||||
|
"gdk",
|
||||||
"gdk-pixbuf",
|
"gdk-pixbuf",
|
||||||
"gettext-rs",
|
"gettext-rs",
|
||||||
|
"glib",
|
||||||
"gsettings-macro",
|
"gsettings-macro",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
@ -1108,6 +1153,29 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-targets 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -1323,6 +1391,12 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.9.2"
|
version = "2.9.2"
|
||||||
|
@ -1413,6 +1487,15 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -1581,11 +1664,25 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
"parking_lot",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-native-tls"
|
name = "tokio-native-tls"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
|
@ -18,6 +18,9 @@ gsettings-macro = "0.1.20"
|
||||||
gdk-pixbuf = "0.18.5"
|
gdk-pixbuf = "0.18.5"
|
||||||
bytes = "1.5.0"
|
bytes = "1.5.0"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
|
tokio = { version = "1.35.1", features = ["full"] }
|
||||||
|
glib = "0.18.5"
|
||||||
|
gdk = "0.18.0"
|
||||||
|
|
||||||
[dependencies.adw]
|
[dependencies.adw]
|
||||||
package = "libadwaita"
|
package = "libadwaita"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.card image {
|
.card image {
|
||||||
min-width: 500px;
|
min-width: 200px;
|
||||||
min-height: 500px;
|
min-height: 200px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ template $Card: Box {
|
||||||
orientation: horizontal;
|
orientation: horizontal;
|
||||||
styles ["card"]
|
styles ["card"]
|
||||||
|
|
||||||
Image image {}
|
Image image {
|
||||||
|
icon-name: "image-loading";
|
||||||
|
}
|
||||||
|
|
||||||
Box contents {
|
Box contents {
|
||||||
orientation: vertical;
|
orientation: vertical;
|
||||||
|
|
|
@ -22,3 +22,17 @@ pub fn get_curse_forge_client() -> Result<reqwest::blocking::Client, reqwest::Er
|
||||||
.default_headers(headers)
|
.default_headers(headers)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_async_curse_forge_client() -> Result<reqwest::Client, reqwest::Error> {
|
||||||
|
let mut api_key_header =
|
||||||
|
reqwest::header::HeaderValue::from_str(crate::config::API_KEY).unwrap();
|
||||||
|
api_key_header.set_sensitive(true);
|
||||||
|
|
||||||
|
let mut headers = reqwest::header::HeaderMap::new();
|
||||||
|
headers.insert("x-api-key", api_key_header);
|
||||||
|
|
||||||
|
reqwest::Client::builder()
|
||||||
|
.user_agent(format!("dev.mnts.ModManager/{}", crate::config::VERSION))
|
||||||
|
.default_headers(headers)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
// Inspired by https://github.com/xou816/spot/blob/aa1c57842c3f4e424eb62c69365438f904b2dc63/src/app/loader.rs
|
|
||||||
// Without the caching.
|
|
||||||
//
|
|
||||||
use bytes::Bytes;
|
|
||||||
use gdk_pixbuf::traits::PixbufLoaderExt;
|
use gdk_pixbuf::traits::PixbufLoaderExt;
|
||||||
use gdk_pixbuf::{Pixbuf, PixbufLoader};
|
use gdk_pixbuf::{Pixbuf, PixbufLoader};
|
||||||
use std::io::{Error, ErrorKind, Write};
|
use std::io::{Error, ErrorKind, Write};
|
||||||
|
use std::thread;
|
||||||
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
use crate::api::*;
|
use crate::api::*;
|
||||||
|
|
||||||
|
@ -34,20 +32,21 @@ impl ImageLoader {
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_image(url: &str) -> Option<Bytes> {
|
pub async fn from_url(&self, url: String) -> Option<Pixbuf> {
|
||||||
let client = base::get_curse_forge_client().unwrap();
|
let (sender, receiver) = oneshot::channel();
|
||||||
let response = client.get(url).send().ok();
|
|
||||||
response.unwrap().bytes().ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_remote(&self, url: &str, width: i32, height: i32) -> Option<Pixbuf> {
|
|
||||||
let pixbuf_loader = PixbufLoader::new();
|
let pixbuf_loader = PixbufLoader::new();
|
||||||
pixbuf_loader.set_size(width, height);
|
|
||||||
let mut loader = LocalPixbufLoader(&pixbuf_loader);
|
let mut loader = LocalPixbufLoader(&pixbuf_loader);
|
||||||
|
|
||||||
if let Some(mut resp) = Self::get_image(url) {
|
thread::spawn(move || {
|
||||||
loader.write_all(&resp).ok()?;
|
let client = base::get_curse_forge_client().unwrap();
|
||||||
}
|
let response = client.get(url).send();
|
||||||
|
let bytes = response.unwrap().bytes().ok().unwrap();
|
||||||
|
sender.send(bytes).unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
let bytes = receiver.await.ok()?;
|
||||||
|
loader.write_all(&bytes).ok()?;
|
||||||
|
|
||||||
pixbuf_loader.close().ok()?;
|
pixbuf_loader.close().ok()?;
|
||||||
pixbuf_loader.pixbuf()
|
pixbuf_loader.pixbuf()
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use adw::subclass::prelude::*;
|
use adw::subclass::prelude::*;
|
||||||
use glib::clone;
|
|
||||||
use gtk::CompositeTemplate;
|
use gtk::CompositeTemplate;
|
||||||
use gtk::{gio, glib};
|
use gtk::{gio, glib};
|
||||||
|
|
||||||
|
@ -64,10 +63,11 @@ impl Card {
|
||||||
|
|
||||||
let url = image_url.to_string();
|
let url = image_url.to_string();
|
||||||
|
|
||||||
worker.send_local_task(clone!(@weak widget => async move {
|
let image = widget.image.clone();
|
||||||
|
worker.send_local_task(async move {
|
||||||
let loader = ImageLoader::new();
|
let loader = ImageLoader::new();
|
||||||
let pixbuf = loader.load_remote(url.as_str(), 800, 800);
|
let pixbuf = loader.from_url(url).await;
|
||||||
widget.image.set_from_pixbuf(pixbuf.as_ref());
|
image.set_from_pixbuf(pixbuf.as_ref());
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ mod settings;
|
||||||
mod windows;
|
mod windows;
|
||||||
|
|
||||||
use self::application::ModManagerApplication;
|
use self::application::ModManagerApplication;
|
||||||
use self::dispatch::spawn_task_handler;
|
|
||||||
|
|
||||||
use config::{GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE};
|
use config::{GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE};
|
||||||
use gettextrs::{gettext, LocaleCategory};
|
use gettextrs::{gettext, LocaleCategory};
|
||||||
|
|
Loading…
Reference in a new issue