diff --git a/anime-game-core b/anime-game-core index fcb297e..f4ad771 160000 --- a/anime-game-core +++ b/anime-game-core @@ -1 +1 @@ -Subproject commit fcb297e323bb2de70cb59d78e32f87ec8b0ec029 +Subproject commit f4ad7711ac156c4c69bc8a14c896f07ad54a101c diff --git a/src/lib/config/mod.rs b/src/lib/config/mod.rs index 3beadae..a356867 100644 --- a/src/lib/config/mod.rs +++ b/src/lib/config/mod.rs @@ -112,7 +112,7 @@ impl Config { None }, - Err(err) => None + Err(_) => None } }, None => None @@ -122,13 +122,15 @@ impl Config { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Launcher { - pub language: String + pub language: String, + pub temp: Option } impl Default for Launcher { fn default() -> Self { Self { - language: String::from("en-us") + language: String::from("en-us"), + temp: launcher_dir() } } } diff --git a/src/main.rs b/src/main.rs index a91be12..0bf2c3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ async fn main() { // Create app 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() ); diff --git a/src/ui/components/wine_group.rs b/src/ui/components/wine_group.rs index d8aefda..5e16e6c 100644 --- a/src/ui/components/wine_group.rs +++ b/src/ui/components/wine_group.rs @@ -1,9 +1,6 @@ use gtk4::{self as gtk, prelude::*}; use libadwaita::{self as adw, prelude::*}; -use gtk::glib; -use gtk::Align; - use crate::lib::wine::Group; use super::wine_row::WineRow; diff --git a/src/ui/main.rs b/src/ui/main.rs index c852ff4..d01fa03 100644 --- a/src/ui/main.rs +++ b/src/ui/main.rs @@ -78,7 +78,7 @@ impl AppWidgets { /// 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 -#[derive(Debug, glib::Downgrade)] +#[derive(Debug, Clone, glib::Downgrade)] pub enum Actions { OpenPreferencesPage, PreferencesGoBack, @@ -91,8 +91,8 @@ pub enum Actions { impl Actions { pub fn into_fn>(&self, app: &App) -> Box { - Box::new(clone!(@weak self as action, @strong app => move |_| { - app.update(action); + Box::new(clone!(@strong self as action, @strong app => move |_| { + app.update(action.clone()).expect(&format!("Failed to execute action {:?}", &action)); })) } } @@ -138,21 +138,7 @@ impl App { result.widgets.window.set_application(Some(app)); // Load initial launcher state - std::thread::spawn(clone!(@strong result => move || { - 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); - }); - } - } - })); + result.update_state(); Ok(result) } @@ -182,7 +168,10 @@ impl App { receiver.attach(None, move |action| { // Some debug output - println!("[main] [update] action: {:?}", &action); + match &action { + Actions::UpdateProgress { .. } => (), + action => println!("[main] [update] action: {:?}", action) + } match action { Actions::OpenPreferencesPage => { @@ -191,7 +180,8 @@ impl App { tasks::run(clone!(@strong this => async move { if let Err(err) = this.widgets.preferences_stack.update() { glib::MainContext::default().invoke(move || { - this.update(Actions::PreferencesGoBack); + this.update(Actions::PreferencesGoBack).unwrap(); + this.toast_error("Failed to update preferences", err); }); } @@ -222,7 +212,7 @@ impl App { LauncherState::VoiceNotInstalled(diff) | LauncherState::GameUpdateAvailable(diff) | LauncherState::GameNotInstalled(diff) => { - this.update(Actions::DownloadDiff(Rc::new(diff))); + this.update(Actions::DownloadDiff(Rc::new(diff))).unwrap(); }, LauncherState::GameOutdated(_) => (), @@ -238,17 +228,20 @@ impl App { } let diff = (*diff).clone(); + let this = this.clone(); - std::thread::spawn(clone!(@strong this => move || { - diff.install_to(config.game.path, clone!(@strong this => move |state| { + std::thread::spawn(move || { + let this = this.clone(); + + diff.install_to_by(config.game.path, config.launcher.temp, move |state| { match state { InstallerUpdate::DownloadingStarted(_) => { - this.update(Actions::ShowProgressBar); + this.update(Actions::ShowProgressBar).unwrap(); this.update(Actions::UpdateProgress { fraction: Rc::new(0.0), title: Rc::new(String::from("Downloading...")) - }); + }).unwrap(); } InstallerUpdate::DownloadingProgress(curr, total) => { @@ -264,7 +257,7 @@ impl App { to_gb(curr), to_gb(total) )) - }); + }).unwrap(); } } @@ -272,7 +265,7 @@ impl App { this.update(Actions::UpdateProgress { fraction: Rc::new(0.0), title: Rc::new(String::from("Unpacking...")) - }); + }).unwrap(); } InstallerUpdate::UnpackingProgress(curr, total) => { @@ -286,20 +279,21 @@ impl App { to_gb(curr), to_gb(total) )) - }); + }).unwrap(); } InstallerUpdate::DownloadingFinished => (), 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::UnpackingError => this.toast_error("Failed to unpack game", "?") } - })).unwrap(); - })); + }).unwrap(); + }); }, Err(err) => { glib::MainContext::default().invoke(clone!(@strong this => move || { @@ -391,6 +385,26 @@ impl App { 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 { diff --git a/src/ui/preferences/general_page.rs b/src/ui/preferences/general_page.rs index 39444ed..64d11e0 100644 --- a/src/ui/preferences/general_page.rs +++ b/src/ui/preferences/general_page.rs @@ -151,7 +151,7 @@ pub enum Actions { impl Actions { pub fn into_fn>(&self, app: &App) -> Box { 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| { if let Some(model) = combo_row.model() { 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| { if let Some(model) = combo_row.model() { 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() { 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 |_| { - let config = config::get().expect("Failed to load config"); + component.apply_button.connect_clicked(clone!(@strong component, @strong self as this => move |_| { + 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) { - this.toast_error("Failed to apply DXVK", err); - } + if let Err(err) = component.apply(config.game.dxvk.builds, config.game.wine.prefix) { + 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) { this.update(Actions::ToastError(Rc::new(( String::from("Failed to delete DXVK"), err - )))); + )))).unwrap(); } component.update_state(&config.game.dxvk.builds); - this.update(Actions::UpdateDxvkComboRow); + this.update(Actions::UpdateDxvkComboRow).unwrap(); } else { @@ -303,12 +307,12 @@ impl App { if let Err(err) = component.apply(&config.game.dxvk.builds, &config.game.wine.prefix) { this.update(Actions::ToastError(Rc::new(( String::from("Failed to apply DXVK"), err - )))); + )))).unwrap(); } 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) { this.update(Actions::ToastError(Rc::new(( String::from("Failed to delete wine"), err - )))); + )))).unwrap(); } component.update_state(&config.game.wine.builds); - this.update(Actions::UpdateWineComboRow); + this.update(Actions::UpdateWineComboRow).unwrap(); } else { @@ -336,7 +340,7 @@ impl App { awaiter.then(clone!(@strong this => move |_| { 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 - self.update(Actions::UpdateWineComboRow); + self.update(Actions::UpdateWineComboRow).unwrap(); // Update downloaded DXVK versions - self.update(Actions::UpdateDxvkComboRow); + self.update(Actions::UpdateDxvkComboRow).unwrap(); Ok(()) } diff --git a/src/ui/traits/download_component.rs b/src/ui/traits/download_component.rs index 8926845..e59f380 100644 --- a/src/ui/traits/download_component.rs +++ b/src/ui/traits/download_component.rs @@ -57,15 +57,15 @@ pub trait DownloadComponent { progress_bar.set_visible(false); button.set_visible(true); - downl_send.send(DownloadingResult::Done); + downl_send.send(DownloadingResult::Done).unwrap(); }, InstallerUpdate::DownloadingError(err) => { - downl_send.send(DownloadingResult::DownloadingError(err.into())); + downl_send.send(DownloadingResult::DownloadingError(err.into())).unwrap(); }, 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 installation_path = installation_path.to_string(); - send.send(installer); + send.send(installer).unwrap(); std::thread::spawn(move || { let mut installer = recv.recv().unwrap(); installer.install(installation_path, move |state| { - sender.send(state); + sender.send(state).unwrap(); }); });