Added wine downloading feature
This commit is contained in:
parent
fb021a0742
commit
c3413cef12
4 changed files with 104 additions and 17 deletions
|
@ -82,6 +82,11 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"async": [
|
"async": [
|
||||||
|
{
|
||||||
|
"version": "1.10.2",
|
||||||
|
"uri": "https://github.com/Sporif/dxvk-async/releases/download/1.10.2/dxvk-async-1.10.2.tar.gz",
|
||||||
|
"recommended": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "1.10.1",
|
"version": "1.10.1",
|
||||||
"uri": "https://github.com/Sporif/dxvk-async/releases/download/1.10.1/dxvk-async-1.10.1.tar.gz",
|
"uri": "https://github.com/Sporif/dxvk-async/releases/download/1.10.1/dxvk-async-1.10.1.tar.gz",
|
||||||
|
|
|
@ -38,4 +38,10 @@ impl WineGroup {
|
||||||
expander_row
|
expander_row
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_states<T: ToString>(&self, runners_folder: T) {
|
||||||
|
for component in &self.version_components {
|
||||||
|
component.update_state(runners_folder.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,10 @@ use libadwaita::{self as adw, prelude::*};
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use gtk::Align;
|
use gtk::Align;
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anime_game_core::prelude::*;
|
||||||
|
|
||||||
use crate::lib::wine::Version;
|
use crate::lib::wine::Version;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -48,31 +52,78 @@ impl WineRow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn download(&self) {
|
pub fn is_downloaded<T: ToString>(&self, runners_folder: T) -> bool {
|
||||||
let (sender, receiver) = glib::MainContext::channel::<i32>(glib::PRIORITY_DEFAULT);
|
Path::new(&format!("{}/{}", runners_folder.to_string(), self.version.name)).exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_state<T: ToString>(&self, runners_folder: T) {
|
||||||
|
if self.is_downloaded(runners_folder) {
|
||||||
|
self.button.set_icon_name("user-trash-symbolic");
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
self.button.set_icon_name("document-save-symbolic");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Download wine
|
||||||
|
///
|
||||||
|
/// This method doesn't update components states, so you need to call `update_state` method manually
|
||||||
|
pub fn download<T: ToString>(&self, runners_folder: T) -> Result<(), std::io::Error> {
|
||||||
|
let (sender, receiver) = glib::MainContext::channel::<InstallerUpdate>(glib::PRIORITY_DEFAULT);
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
|
|
||||||
this.progress_bar.set_visible(true);
|
this.progress_bar.set_visible(true);
|
||||||
this.button.set_visible(false);
|
this.button.set_visible(false);
|
||||||
|
|
||||||
receiver.attach(None, move |fraction| {
|
receiver.attach(None, move |state| {
|
||||||
this.progress_bar.set_fraction(fraction as f64 / 100f64);
|
match state {
|
||||||
this.progress_bar.set_text(Some(&format!("Downloading: {}%", fraction)));
|
InstallerUpdate::DownloadingStarted(_) => (),
|
||||||
|
InstallerUpdate::DownloadingFinished => (),
|
||||||
|
InstallerUpdate::UnpackingStarted(_) => (),
|
||||||
|
|
||||||
if fraction == 100 {
|
InstallerUpdate::DownloadingProgress(curr, total) => {
|
||||||
this.progress_bar.set_visible(false);
|
let progress = curr as f64 / total as f64;
|
||||||
this.button.set_visible(true);
|
|
||||||
|
this.progress_bar.set_fraction(progress);
|
||||||
|
this.progress_bar.set_text(Some(&format!("Downloading: {}%", (progress * 100.0) as u64)));
|
||||||
|
},
|
||||||
|
|
||||||
|
InstallerUpdate::UnpackingProgress(curr, total) => {
|
||||||
|
let progress = curr as f64 / total as f64;
|
||||||
|
|
||||||
|
this.progress_bar.set_fraction(progress);
|
||||||
|
this.progress_bar.set_text(Some(&format!("Unpacking: {}%", (progress * 100.0) as u64)));
|
||||||
|
},
|
||||||
|
|
||||||
|
InstallerUpdate::UnpackingFinished => {
|
||||||
|
this.progress_bar.set_visible(false);
|
||||||
|
this.button.set_visible(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: proper handling
|
||||||
|
InstallerUpdate::DownloadingError(err) => panic!("Failed to download wine: {}", err),
|
||||||
|
InstallerUpdate::UnpackingError => panic!("Failed to unpack wine")
|
||||||
}
|
}
|
||||||
|
|
||||||
glib::Continue(true)
|
glib::Continue(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
let (send, recv) = std::sync::mpsc::channel();
|
||||||
for i in 1..101 {
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(150));
|
|
||||||
|
|
||||||
sender.send(i);
|
let installer = Installer::new(&self.version.uri)?;
|
||||||
}
|
let runners_folder = runners_folder.to_string();
|
||||||
|
|
||||||
|
send.send(installer);
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let mut installer = recv.recv().unwrap();
|
||||||
|
|
||||||
|
installer.install(runners_folder, move |state| {
|
||||||
|
sender.send(state);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,11 @@ impl AppWidgets {
|
||||||
dxvk_components: Default::default()
|
dxvk_components: Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let config = match config::get() {
|
||||||
|
Ok(config) => config,
|
||||||
|
Err(err) => return Err(err.to_string())
|
||||||
|
};
|
||||||
|
|
||||||
// Update wine versions lists
|
// Update wine versions lists
|
||||||
let groups = match wine::List::get() {
|
let groups = match wine::List::get() {
|
||||||
Ok(list) => list,
|
Ok(list) => list,
|
||||||
|
@ -76,6 +81,8 @@ impl AppWidgets {
|
||||||
for group in groups {
|
for group in groups {
|
||||||
let group = WineGroup::new(group);
|
let group = WineGroup::new(group);
|
||||||
|
|
||||||
|
group.update_states(&config.game.wine.builds);
|
||||||
|
|
||||||
result.wine_groups.add(&group.expander_row);
|
result.wine_groups.add(&group.expander_row);
|
||||||
|
|
||||||
components.push(group);
|
components.push(group);
|
||||||
|
@ -116,7 +123,8 @@ impl AppWidgets {
|
||||||
/// It may be helpful if you want to add the same event for several widgets, or call an action inside of another action
|
/// It may be helpful if you want to add the same event for several widgets, or call an action inside of another action
|
||||||
#[derive(Debug, Clone, glib::Downgrade)]
|
#[derive(Debug, Clone, glib::Downgrade)]
|
||||||
pub enum Actions {
|
pub enum Actions {
|
||||||
DownloadDXVK(Rc<usize>)
|
DownloadDXVK(Rc<usize>),
|
||||||
|
DownloadWine(Rc<(usize, usize)>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actions {
|
impl Actions {
|
||||||
|
@ -180,6 +188,15 @@ impl App {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Wine install/remove buttons
|
||||||
|
let components = &*self.widgets.wine_components;
|
||||||
|
|
||||||
|
for (i, group) in components.into_iter().enumerate() {
|
||||||
|
for (j, component) in (&group.version_components).into_iter().enumerate() {
|
||||||
|
component.button.connect_clicked(Actions::DownloadWine(Rc::new((i, j))).into_fn(&self));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set DXVK recommended only switcher event
|
// Set DXVK recommended only switcher event
|
||||||
self.widgets.dxvk_recommended_only.connect_state_notify(clone!(@strong self as this => move |switcher| {
|
self.widgets.dxvk_recommended_only.connect_state_notify(clone!(@strong self as this => move |switcher| {
|
||||||
for component in &*this.widgets.dxvk_components {
|
for component in &*this.widgets.dxvk_components {
|
||||||
|
@ -218,11 +235,19 @@ impl App {
|
||||||
|
|
||||||
match action {
|
match action {
|
||||||
Actions::DownloadDXVK(i) => {
|
Actions::DownloadDXVK(i) => {
|
||||||
let component = &this.widgets.dxvk_components[*i];
|
this.widgets.dxvk_components[*i].download();
|
||||||
|
}
|
||||||
|
|
||||||
println!("Download DXVK: {:?}", &component.version);
|
Actions::DownloadWine(version) => {
|
||||||
|
let config = config::get().expect("Failed to load config");
|
||||||
|
|
||||||
component.download();
|
let component = &this.widgets
|
||||||
|
.wine_components[version.0]
|
||||||
|
.version_components[version.1];
|
||||||
|
|
||||||
|
if let Ok(_) = component.download(&config.game.wine.builds) {
|
||||||
|
component.update_state(&config.game.wine.builds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue