Added temp folder path param to config
it fixes issue with huge data downloading. You can specify `null` as temp path and then default system temp folder will be used Also added `unwrap` everywhere I could add it just not to see warnings in the code editor
This commit is contained in:
parent
5565e10eb6
commit
5fee051c43
7 changed files with 78 additions and 61 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit fcb297e323bb2de70cb59d78e32f87ec8b0ec029
|
Subproject commit f4ad7711ac156c4c69bc8a14c896f07ad54a101c
|
|
@ -112,7 +112,7 @@ impl Config {
|
||||||
|
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
Err(err) => None
|
Err(_) => None
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => None
|
None => None
|
||||||
|
@ -122,13 +122,15 @@ impl Config {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Launcher {
|
pub struct Launcher {
|
||||||
pub language: String
|
pub language: String,
|
||||||
|
pub temp: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Launcher {
|
impl Default for Launcher {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
language: String::from("en-us")
|
language: String::from("en-us"),
|
||||||
|
temp: launcher_dir()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ async fn main() {
|
||||||
|
|
||||||
// Create app
|
// Create app
|
||||||
let application = gtk::Application::new(
|
let application = gtk::Application::new(
|
||||||
Some("com.gitlab.an-anime-team.an-anime-game-launcher"),
|
Some("com.gitlab.an-anime-team.an-anime-game-launcher-gtk"),
|
||||||
Default::default()
|
Default::default()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use gtk4::{self as gtk, prelude::*};
|
use gtk4::{self as gtk, prelude::*};
|
||||||
use libadwaita::{self as adw, prelude::*};
|
use libadwaita::{self as adw, prelude::*};
|
||||||
|
|
||||||
use gtk::glib;
|
|
||||||
use gtk::Align;
|
|
||||||
|
|
||||||
use crate::lib::wine::Group;
|
use crate::lib::wine::Group;
|
||||||
use super::wine_row::WineRow;
|
use super::wine_row::WineRow;
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl AppWidgets {
|
||||||
/// This enum is used to describe an action inside of this application
|
/// This enum is used to describe an action inside of this application
|
||||||
///
|
///
|
||||||
/// 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, glib::Downgrade)]
|
#[derive(Debug, Clone, glib::Downgrade)]
|
||||||
pub enum Actions {
|
pub enum Actions {
|
||||||
OpenPreferencesPage,
|
OpenPreferencesPage,
|
||||||
PreferencesGoBack,
|
PreferencesGoBack,
|
||||||
|
@ -91,8 +91,8 @@ pub enum Actions {
|
||||||
|
|
||||||
impl Actions {
|
impl Actions {
|
||||||
pub fn into_fn<T: gtk::glib::IsA<gtk::Widget>>(&self, app: &App) -> Box<dyn Fn(&T)> {
|
pub fn into_fn<T: gtk::glib::IsA<gtk::Widget>>(&self, app: &App) -> Box<dyn Fn(&T)> {
|
||||||
Box::new(clone!(@weak self as action, @strong app => move |_| {
|
Box::new(clone!(@strong self as action, @strong app => move |_| {
|
||||||
app.update(action);
|
app.update(action.clone()).expect(&format!("Failed to execute action {:?}", &action));
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,21 +138,7 @@ impl App {
|
||||||
result.widgets.window.set_application(Some(app));
|
result.widgets.window.set_application(Some(app));
|
||||||
|
|
||||||
// Load initial launcher state
|
// Load initial launcher state
|
||||||
std::thread::spawn(clone!(@strong result => move || {
|
result.update_state();
|
||||||
match LauncherState::get(Some(&result.widgets.status_page)) {
|
|
||||||
Ok(state) => {
|
|
||||||
result.set_state(state);
|
|
||||||
|
|
||||||
result.widgets.status_page.hide();
|
|
||||||
result.widgets.launcher_content.show();
|
|
||||||
},
|
|
||||||
Err(err) => {
|
|
||||||
glib::MainContext::default().invoke(move || {
|
|
||||||
result.toast_error("Failed to get initial launcher state", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
@ -182,7 +168,10 @@ impl App {
|
||||||
|
|
||||||
receiver.attach(None, move |action| {
|
receiver.attach(None, move |action| {
|
||||||
// Some debug output
|
// Some debug output
|
||||||
println!("[main] [update] action: {:?}", &action);
|
match &action {
|
||||||
|
Actions::UpdateProgress { .. } => (),
|
||||||
|
action => println!("[main] [update] action: {:?}", action)
|
||||||
|
}
|
||||||
|
|
||||||
match action {
|
match action {
|
||||||
Actions::OpenPreferencesPage => {
|
Actions::OpenPreferencesPage => {
|
||||||
|
@ -191,7 +180,8 @@ impl App {
|
||||||
tasks::run(clone!(@strong this => async move {
|
tasks::run(clone!(@strong this => async move {
|
||||||
if let Err(err) = this.widgets.preferences_stack.update() {
|
if let Err(err) = this.widgets.preferences_stack.update() {
|
||||||
glib::MainContext::default().invoke(move || {
|
glib::MainContext::default().invoke(move || {
|
||||||
this.update(Actions::PreferencesGoBack);
|
this.update(Actions::PreferencesGoBack).unwrap();
|
||||||
|
|
||||||
this.toast_error("Failed to update preferences", err);
|
this.toast_error("Failed to update preferences", err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -222,7 +212,7 @@ impl App {
|
||||||
LauncherState::VoiceNotInstalled(diff) |
|
LauncherState::VoiceNotInstalled(diff) |
|
||||||
LauncherState::GameUpdateAvailable(diff) |
|
LauncherState::GameUpdateAvailable(diff) |
|
||||||
LauncherState::GameNotInstalled(diff) => {
|
LauncherState::GameNotInstalled(diff) => {
|
||||||
this.update(Actions::DownloadDiff(Rc::new(diff)));
|
this.update(Actions::DownloadDiff(Rc::new(diff))).unwrap();
|
||||||
},
|
},
|
||||||
|
|
||||||
LauncherState::GameOutdated(_) => (),
|
LauncherState::GameOutdated(_) => (),
|
||||||
|
@ -238,17 +228,20 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
let diff = (*diff).clone();
|
let diff = (*diff).clone();
|
||||||
|
let this = this.clone();
|
||||||
|
|
||||||
std::thread::spawn(clone!(@strong this => move || {
|
std::thread::spawn(move || {
|
||||||
diff.install_to(config.game.path, clone!(@strong this => move |state| {
|
let this = this.clone();
|
||||||
|
|
||||||
|
diff.install_to_by(config.game.path, config.launcher.temp, move |state| {
|
||||||
match state {
|
match state {
|
||||||
InstallerUpdate::DownloadingStarted(_) => {
|
InstallerUpdate::DownloadingStarted(_) => {
|
||||||
this.update(Actions::ShowProgressBar);
|
this.update(Actions::ShowProgressBar).unwrap();
|
||||||
|
|
||||||
this.update(Actions::UpdateProgress {
|
this.update(Actions::UpdateProgress {
|
||||||
fraction: Rc::new(0.0),
|
fraction: Rc::new(0.0),
|
||||||
title: Rc::new(String::from("Downloading..."))
|
title: Rc::new(String::from("Downloading..."))
|
||||||
});
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallerUpdate::DownloadingProgress(curr, total) => {
|
InstallerUpdate::DownloadingProgress(curr, total) => {
|
||||||
|
@ -264,7 +257,7 @@ impl App {
|
||||||
to_gb(curr),
|
to_gb(curr),
|
||||||
to_gb(total)
|
to_gb(total)
|
||||||
))
|
))
|
||||||
});
|
}).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +265,7 @@ impl App {
|
||||||
this.update(Actions::UpdateProgress {
|
this.update(Actions::UpdateProgress {
|
||||||
fraction: Rc::new(0.0),
|
fraction: Rc::new(0.0),
|
||||||
title: Rc::new(String::from("Unpacking..."))
|
title: Rc::new(String::from("Unpacking..."))
|
||||||
});
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallerUpdate::UnpackingProgress(curr, total) => {
|
InstallerUpdate::UnpackingProgress(curr, total) => {
|
||||||
|
@ -286,20 +279,21 @@ impl App {
|
||||||
to_gb(curr),
|
to_gb(curr),
|
||||||
to_gb(total)
|
to_gb(total)
|
||||||
))
|
))
|
||||||
});
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallerUpdate::DownloadingFinished => (),
|
InstallerUpdate::DownloadingFinished => (),
|
||||||
|
|
||||||
InstallerUpdate::UnpackingFinished => {
|
InstallerUpdate::UnpackingFinished => {
|
||||||
this.update(Actions::HideProgressBar);
|
this.update(Actions::HideProgressBar).unwrap();
|
||||||
|
this.update_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallerUpdate::DownloadingError(err) => this.toast_error("Failed to download game", err),
|
InstallerUpdate::DownloadingError(err) => this.toast_error("Failed to download game", err),
|
||||||
InstallerUpdate::UnpackingError => this.toast_error("Failed to unpack game", "?")
|
InstallerUpdate::UnpackingError => this.toast_error("Failed to unpack game", "?")
|
||||||
}
|
}
|
||||||
})).unwrap();
|
}).unwrap();
|
||||||
}));
|
});
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
glib::MainContext::default().invoke(clone!(@strong this => move || {
|
glib::MainContext::default().invoke(clone!(@strong this => move || {
|
||||||
|
@ -391,6 +385,26 @@ impl App {
|
||||||
|
|
||||||
self.values.set(values);
|
self.values.set(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_state(&self) {
|
||||||
|
let this = self.clone();
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
match LauncherState::get(Some(&this.widgets.status_page)) {
|
||||||
|
Ok(state) => {
|
||||||
|
this.set_state(state);
|
||||||
|
|
||||||
|
this.widgets.status_page.hide();
|
||||||
|
this.widgets.launcher_content.show();
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
glib::MainContext::default().invoke(move || {
|
||||||
|
this.toast_error("Failed to get initial launcher state", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToastError for App {
|
impl ToastError for App {
|
||||||
|
|
|
@ -151,7 +151,7 @@ pub enum Actions {
|
||||||
impl Actions {
|
impl Actions {
|
||||||
pub fn into_fn<T: gtk::glib::IsA<gtk::Widget>>(&self, app: &App) -> Box<dyn Fn(&T)> {
|
pub fn into_fn<T: gtk::glib::IsA<gtk::Widget>>(&self, app: &App) -> Box<dyn Fn(&T)> {
|
||||||
Box::new(clone!(@strong self as action, @strong app => move |_| {
|
Box::new(clone!(@strong self as action, @strong app => move |_| {
|
||||||
app.update(action.clone());
|
app.update(action.clone()).expect(&format!("Failed to execute action {:?}", &action));
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ impl App {
|
||||||
self.widgets.wine_selected.connect_selected_notify(clone!(@strong self as this => move |combo_row| {
|
self.widgets.wine_selected.connect_selected_notify(clone!(@strong self as this => move |combo_row| {
|
||||||
if let Some(model) = combo_row.model() {
|
if let Some(model) = combo_row.model() {
|
||||||
if model.n_items() > 0 {
|
if model.n_items() > 0 {
|
||||||
this.update(Actions::SelectWineVersion(Rc::new(combo_row.selected() as usize)));
|
this.update(Actions::SelectWineVersion(Rc::new(combo_row.selected() as usize))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -210,7 +210,7 @@ impl App {
|
||||||
self.widgets.dxvk_selected.connect_selected_notify(clone!(@strong self as this => move |combo_row| {
|
self.widgets.dxvk_selected.connect_selected_notify(clone!(@strong self as this => move |combo_row| {
|
||||||
if let Some(model) = combo_row.model() {
|
if let Some(model) = combo_row.model() {
|
||||||
if model.n_items() > 0 {
|
if model.n_items() > 0 {
|
||||||
this.update(Actions::SelectDxvkVersion(Rc::new(combo_row.selected() as usize)));
|
this.update(Actions::SelectDxvkVersion(Rc::new(combo_row.selected() as usize))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -254,12 +254,16 @@ impl App {
|
||||||
for (i, component) in components.into_iter().enumerate() {
|
for (i, component) in components.into_iter().enumerate() {
|
||||||
component.button.connect_clicked(Actions::DxvkPerformAction(Rc::new(i)).into_fn(&self));
|
component.button.connect_clicked(Actions::DxvkPerformAction(Rc::new(i)).into_fn(&self));
|
||||||
|
|
||||||
component.apply_button.connect_clicked(clone!(@strong component.version as version, @strong self as this => move |_| {
|
component.apply_button.connect_clicked(clone!(@strong component, @strong self as this => move |_| {
|
||||||
let config = config::get().expect("Failed to load config");
|
std::thread::spawn(clone!(@strong component, @strong this => move || {
|
||||||
|
let config = config::get().expect("Failed to load config");
|
||||||
|
|
||||||
if let Err(err) = version.apply(config.game.dxvk.builds, config.game.wine.prefix) {
|
if let Err(err) = component.apply(config.game.dxvk.builds, config.game.wine.prefix) {
|
||||||
this.toast_error("Failed to apply DXVK", err);
|
this.update(Actions::ToastError(Rc::new((
|
||||||
}
|
String::from("Failed to apply DXVK"), err
|
||||||
|
)))).unwrap();
|
||||||
|
}
|
||||||
|
}));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,12 +293,12 @@ impl App {
|
||||||
if let Err(err) = component.delete(&config.game.dxvk.builds) {
|
if let Err(err) = component.delete(&config.game.dxvk.builds) {
|
||||||
this.update(Actions::ToastError(Rc::new((
|
this.update(Actions::ToastError(Rc::new((
|
||||||
String::from("Failed to delete DXVK"), err
|
String::from("Failed to delete DXVK"), err
|
||||||
))));
|
)))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
component.update_state(&config.game.dxvk.builds);
|
component.update_state(&config.game.dxvk.builds);
|
||||||
|
|
||||||
this.update(Actions::UpdateDxvkComboRow);
|
this.update(Actions::UpdateDxvkComboRow).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -303,12 +307,12 @@ impl App {
|
||||||
if let Err(err) = component.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
if let Err(err) = component.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
|
||||||
this.update(Actions::ToastError(Rc::new((
|
this.update(Actions::ToastError(Rc::new((
|
||||||
String::from("Failed to apply DXVK"), err
|
String::from("Failed to apply DXVK"), err
|
||||||
))));
|
)))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
component.update_state(&config.game.dxvk.builds);
|
component.update_state(&config.game.dxvk.builds);
|
||||||
|
|
||||||
this.update(Actions::UpdateDxvkComboRow);
|
this.update(Actions::UpdateDxvkComboRow).unwrap();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,12 +327,12 @@ impl App {
|
||||||
if let Err(err) = component.delete(&config.game.wine.builds) {
|
if let Err(err) = component.delete(&config.game.wine.builds) {
|
||||||
this.update(Actions::ToastError(Rc::new((
|
this.update(Actions::ToastError(Rc::new((
|
||||||
String::from("Failed to delete wine"), err
|
String::from("Failed to delete wine"), err
|
||||||
))));
|
)))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
component.update_state(&config.game.wine.builds);
|
component.update_state(&config.game.wine.builds);
|
||||||
|
|
||||||
this.update(Actions::UpdateWineComboRow);
|
this.update(Actions::UpdateWineComboRow).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -336,7 +340,7 @@ impl App {
|
||||||
awaiter.then(clone!(@strong this => move |_| {
|
awaiter.then(clone!(@strong this => move |_| {
|
||||||
component.update_state(&config.game.wine.builds);
|
component.update_state(&config.game.wine.builds);
|
||||||
|
|
||||||
this.update(Actions::UpdateWineComboRow);
|
this.update(Actions::UpdateWineComboRow).unwrap();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,10 +554,10 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update downloaded wine versions
|
// Update downloaded wine versions
|
||||||
self.update(Actions::UpdateWineComboRow);
|
self.update(Actions::UpdateWineComboRow).unwrap();
|
||||||
|
|
||||||
// Update downloaded DXVK versions
|
// Update downloaded DXVK versions
|
||||||
self.update(Actions::UpdateDxvkComboRow);
|
self.update(Actions::UpdateDxvkComboRow).unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,15 +57,15 @@ pub trait DownloadComponent {
|
||||||
progress_bar.set_visible(false);
|
progress_bar.set_visible(false);
|
||||||
button.set_visible(true);
|
button.set_visible(true);
|
||||||
|
|
||||||
downl_send.send(DownloadingResult::Done);
|
downl_send.send(DownloadingResult::Done).unwrap();
|
||||||
},
|
},
|
||||||
|
|
||||||
InstallerUpdate::DownloadingError(err) => {
|
InstallerUpdate::DownloadingError(err) => {
|
||||||
downl_send.send(DownloadingResult::DownloadingError(err.into()));
|
downl_send.send(DownloadingResult::DownloadingError(err.into())).unwrap();
|
||||||
},
|
},
|
||||||
|
|
||||||
InstallerUpdate::UnpackingError => {
|
InstallerUpdate::UnpackingError => {
|
||||||
downl_send.send(DownloadingResult::UnpackingError);
|
downl_send.send(DownloadingResult::UnpackingError).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,13 +77,13 @@ pub trait DownloadComponent {
|
||||||
let installer = Installer::new(self.get_download_uri())?;
|
let installer = Installer::new(self.get_download_uri())?;
|
||||||
let installation_path = installation_path.to_string();
|
let installation_path = installation_path.to_string();
|
||||||
|
|
||||||
send.send(installer);
|
send.send(installer).unwrap();
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let mut installer = recv.recv().unwrap();
|
let mut installer = recv.recv().unwrap();
|
||||||
|
|
||||||
installer.install(installation_path, move |state| {
|
installer.install(installation_path, move |state| {
|
||||||
sender.send(state);
|
sender.send(state).unwrap();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue