diff --git a/src/ui/first_run/download_components.rs b/src/ui/first_run/download_components.rs index b475981..6c0068c 100644 --- a/src/ui/first_run/download_components.rs +++ b/src/ui/first_run/download_components.rs @@ -350,6 +350,19 @@ impl SimpleAsyncComponent for DownloadComponentsApp { if wine.is_downloaded_in(&config.game.wine.builds) { tracing::info!("Wine already installed: {}", wine.name); + let mut config = config::get().unwrap_or_default(); + + config.game.wine.selected = Some(wine.name); + + if let Err(err) = config::update_raw(config) { + tracing::error!("Failed to update config: {err}"); + + sender.output(Self::Output::Toast { + title: tr("config-update-error"), + description: Some(err.to_string()) + }); + } + sender.input(DownloadComponentsAppMsg::CreatePrefix); } @@ -357,7 +370,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp { else { std::thread::spawn(move || { tracing::info!("Installing wine: {}", wine.name); - + // Install wine match get_installer(&wine.uri, config.launcher.temp.as_ref(), config.launcher.speed_limit) { Ok(mut installer) => { @@ -366,53 +379,55 @@ impl SimpleAsyncComponent for DownloadComponentsApp { std::fs::create_dir_all(&config.game.wine.builds) .expect("Failed to create wine builds directory"); } - + installer.install(&config.game.wine.builds, move |update| { match &update { InstallerUpdate::DownloadingError(err) => { tracing::error!("Failed to download wine: {err}"); - + sender.output(Self::Output::Toast { title: tr("wine-download-error"), description: Some(err.to_string()) }); } - + InstallerUpdate::UnpackingError(err) => { tracing::error!("Failed to unpack wine: {err}"); - + sender.output(Self::Output::Toast { title: tr("wine-unpack-errror"), description: Some(err.clone()) }); } - + // Create prefix InstallerUpdate::UnpackingFinished => { let mut config = config::get().unwrap_or_default(); - + config.game.wine.selected = Some(wine.name.clone()); - + if let Err(err) = config::update_raw(config) { + tracing::error!("Failed to update config: {err}"); + sender.output(Self::Output::Toast { title: tr("config-update-error"), description: Some(err.to_string()) }); } - + sender.input(DownloadComponentsAppMsg::CreatePrefix); }, - + _ => () } - + progress_bar_input.send(ProgressBarMsg::UpdateFromState(update)); }); } - + Err(err) => { tracing::error!("Failed to initialize wine installer: {err}"); - + sender.output(Self::Output::Toast { title: tr("wine-install-failed"), description: Some(err.to_string()) @@ -477,29 +492,29 @@ impl SimpleAsyncComponent for DownloadComponentsApp { std::thread::spawn(move || { // Install DXVK tracing::info!("Installing DXVK: {}", dxvk.name); - + match get_installer(&dxvk.uri, config.launcher.temp.as_ref(), config.launcher.speed_limit) { Ok(mut installer) => { let progress_bar_input = progress_bar_input.clone(); let sender = sender.clone(); - + // Create DXVK builds folder if config.game.dxvk.builds.exists() { std::fs::create_dir_all(&config.game.dxvk.builds) .expect("Failed to create DXVK builds directory"); } - + installer.install(&config.game.dxvk.builds, move |update| { match &update { InstallerUpdate::DownloadingError(err) => { tracing::error!("Failed to download dxvk: {err}"); - + sender.output(Self::Output::Toast { title: tr("dxvk-download-error"), description: Some(err.to_string()) }); } - + InstallerUpdate::UnpackingError(err) => { tracing::error!("Failed to unpack dxvk: {err}"); @@ -508,22 +523,22 @@ impl SimpleAsyncComponent for DownloadComponentsApp { description: Some(err.clone()) }); } - + // Apply DXVK InstallerUpdate::UnpackingFinished => { sender.input(DownloadComponentsAppMsg::ApplyDXVK); } - + _ => () } - + progress_bar_input.send(ProgressBarMsg::UpdateFromState(update)); }); } - + Err(err) => { tracing::error!("Failed to initialize dxvk installer: {err}"); - + sender.output(Self::Output::Toast { title: tr("dxvk-install-failed"), description: Some(err.to_string()) diff --git a/src/ui/first_run/main.rs b/src/ui/first_run/main.rs index ec4f166..3973f8d 100644 --- a/src/ui/first_run/main.rs +++ b/src/ui/first_run/main.rs @@ -161,7 +161,7 @@ impl SimpleComponent for FirstRunApp { toast_overlay, carousel, - loading: Some(None), + loading: None, title: tr("welcome") }; @@ -172,70 +172,16 @@ impl SimpleComponent for FirstRunApp { unsafe { MAIN_WINDOW = Some(widgets.window.clone()); + + crate::READY = true; } - tracing::info!("First run window initialized"); - - let components_sender = model.download_components.sender().clone(); - - // Initialize some heavy tasks - #[allow(unused_must_use)] - std::thread::spawn(move || { - tracing::info!("Initializing heavy tasks"); - - // Update components index - - sender.input(FirstRunAppMsg::SetLoadingStatus(Some(Some(tr("updating-components-index"))))); - - let components = ComponentsLoader::new(&CONFIG.components.path); - - match components.is_sync(&CONFIG.components.servers) { - Ok(true) => (), - - Ok(false) => { - for host in &CONFIG.components.servers { - match components.sync(host) { - Ok(true) => break, - Ok(false) => continue, - - Err(err) => { - tracing::error!("Failed to sync components index"); - - sender.input(FirstRunAppMsg::Toast { - title: tr("components-index-sync-failed"), - description: Some(err.to_string()) - }); - } - } - } - } - - Err(err) => { - tracing::error!("Failed to verify that components index synced"); - - sender.input(FirstRunAppMsg::Toast { - title: tr("components-index-verify-failed"), - description: Some(err.to_string()) - }); - } - } - - // Update versions lists in download components page and hide status page - components_sender.send(DownloadComponentsAppMsg::UpdateVersionsLists); - sender.input(FirstRunAppMsg::SetLoadingStatus(None)); - - // Mark app as loaded - unsafe { - crate::READY = true; - } - - tracing::info!("App is ready"); - }); + tracing::info!("First run window initialized. App is ready"); ComponentParts { model, widgets } // will return soon } - fn update(&mut self, msg: Self::Input, _sender: ComponentSender) { + fn update(&mut self, msg: Self::Input, sender: ComponentSender) { tracing::debug!("Called first run window event: {:?}", msg); match msg { @@ -268,6 +214,54 @@ impl SimpleComponent for FirstRunApp { } FirstRunAppMsg::ScrollToDownloadComponents => { + // Update components index + sender.input(FirstRunAppMsg::SetLoadingStatus(Some(Some(tr("updating-components-index"))))); + + let components_sender = self.download_components.sender().clone(); + let components = ComponentsLoader::new(&CONFIG.components.path); + + #[allow(unused_must_use)] + std::thread::spawn(move || { + match components.is_sync(&CONFIG.components.servers) { + Ok(true) => (), + + Ok(false) => { + for host in &CONFIG.components.servers { + match components.sync(host) { + Ok(true) => break, + Ok(false) => continue, + + Err(err) => { + tracing::error!("Failed to sync components index"); + + sender.input(FirstRunAppMsg::Toast { + title: tr("components-index-sync-failed"), + description: Some(err.to_string()) + }); + } + } + } + } + + Err(err) => { + tracing::error!("Failed to verify that components index synced"); + + sender.input(FirstRunAppMsg::Toast { + title: tr("components-index-verify-failed"), + description: Some(err.to_string()) + }); + } + } + + // Update versions lists in download components page + components_sender.send(DownloadComponentsAppMsg::UpdateVersionsLists); + + // Hide status page + sender.input(FirstRunAppMsg::SetLoadingStatus(None)); + }); + + // Scroll to download components page + // This will happen in background behind StatusPage self.title = tr("download-components"); self.carousel.scroll_to(self.download_components.widget(), true);