From f2a04f5ebef9f068360a15c6302623164889499e Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Wed, 22 Feb 2023 22:10:37 +0200 Subject: [PATCH] main window: added initial states system support --- assets/locales/en/errors.ftl | 2 + assets/locales/en/main.ftl | 4 ++ assets/locales/ru/errors.ftl | 2 + assets/locales/ru/main.ftl | 10 +++ src/ui/main.rs | 116 +++++++++++++++++++++++++---------- 5 files changed, 101 insertions(+), 33 deletions(-) diff --git a/assets/locales/en/errors.ftl b/assets/locales/en/errors.ftl index 42f62c3..68634ab 100644 --- a/assets/locales/en/errors.ftl +++ b/assets/locales/en/errors.ftl @@ -2,6 +2,8 @@ launcher-folder-opening-error = Failed to open launcher folder game-folder-opening-error = Failed to open game folder config-file-opening-error = Failed to open config file +game-launching-failed = Failed to launch game + config-flush-error = Failed to flush config wine-prefix-update-failed = Failed to update wine prefix dxvk-install-failed = Failed to install DXVK diff --git a/assets/locales/en/main.ftl b/assets/locales/en/main.ftl index 96d198e..e72a898 100644 --- a/assets/locales/en/main.ftl +++ b/assets/locales/en/main.ftl @@ -8,6 +8,10 @@ save = Save loading-game-version = Loading game version loading-patch-status = Loading patch status +loading-launcher-state = Loading launcher state +loading-launcher-state--game = Loading launcher state: verifying game version +loading-launcher-state--voice = Loading launcher state: verifying {$locale} voiceover +loading-launcher-state--patch = Loading launcher state: verifying installed patch checking-free-space = Checking free space diff --git a/assets/locales/ru/errors.ftl b/assets/locales/ru/errors.ftl index ba43189..92a5d79 100644 --- a/assets/locales/ru/errors.ftl +++ b/assets/locales/ru/errors.ftl @@ -2,6 +2,8 @@ launcher-folder-opening-error = Не удалось открыть папку л game-folder-opening-error = Не удалось открыть папку игры config-file-opening-error = Не удалось открыть файл настроек +game-launching-failed = Не удалось запустить игру + config-flush-error = Ошибка сохранения настроек wine-prefix-update-failed = Ошибка обновления префикса Wine dxvk-install-failed = Ошибка установки DXVK diff --git a/assets/locales/ru/main.ftl b/assets/locales/ru/main.ftl index bf203d0..4200abc 100644 --- a/assets/locales/ru/main.ftl +++ b/assets/locales/ru/main.ftl @@ -8,6 +8,16 @@ save = Сохранить loading-game-version = Загрузка версии игры loading-patch-status = Загрузка статуса патча +loading-launcher-state = Загрузка статуса лаунчера +loading-launcher-state--game = Загрузка статуса лаунчера: проверка версии игры +loading-launcher-state--voice = Загрузка статуса лаунчера: проверка {$locale -> + [English] английского + [Japanese] японского + [Korean] корейского + [Chinese] китайского + *[other] $locale +} языкового пакета +loading-launcher-state--patch = Загрузка статуса лаунчера: проверка установленного патча checking-free-space = Проверка свободного места diff --git a/src/ui/main.rs b/src/ui/main.rs index d4f8494..ea686f5 100644 --- a/src/ui/main.rs +++ b/src/ui/main.rs @@ -11,9 +11,10 @@ use adw::prelude::*; use gtk::glib::clone; use anime_launcher_sdk::config::launcher::LauncherStyle; +use anime_launcher_sdk::states::LauncherState; use crate::*; -use crate::i18n::tr; +use crate::i18n::*; use super::preferences::main::*; use super::about::*; @@ -34,7 +35,8 @@ pub struct App { toast_overlay: adw::ToastOverlay, loading: Option>, - style: LauncherStyle + style: LauncherStyle, + state: Option } #[derive(Debug)] @@ -47,16 +49,19 @@ pub enum AppMsg { /// was retrieved from remote repos UpdatePatch(Option), + /// Supposed to be called automatically on app's run when the launcher state was chosen + UpdateLauncherState(Option), + Toast { title: String, description: Option }, UpdateLoadingStatus(Option>), - PerformAction, OpenPreferences, ClosePreferences, - UpdateLauncherStyle(LauncherStyle) + UpdateLauncherStyle(LauncherStyle), + PerformAction } #[relm4::component(pub)] @@ -241,8 +246,10 @@ impl SimpleComponent for App { let model = App { toast_overlay: adw::ToastOverlay::new(), + loading: Some(None), - style: CONFIG.launcher.style + style: CONFIG.launcher.style, + state: None }; let toast_overlay = &model.toast_overlay; @@ -274,13 +281,7 @@ impl SimpleComponent for App { group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| { if let Some(dir) = anime_launcher_sdk::consts::launcher_dir() { - let child = std::process::Command::new("xdg-open") - .arg(dir) - .stdout(std::process::Stdio::null()) - .stderr(std::process::Stdio::null()) - .spawn(); - - if let Err(err) = child { + if let Err(err) = std::process::Command::new("xdg-open").arg(dir).spawn() { sender.input(AppMsg::Toast { title: tr("launcher-folder-opening-error"), description: Some(err.to_string()) @@ -292,13 +293,7 @@ impl SimpleComponent for App { }))); group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| { - let child = std::process::Command::new("xdg-open") - .arg(&CONFIG.game.path) - .stdout(std::process::Stdio::null()) - .stderr(std::process::Stdio::null()) - .spawn(); - - if let Err(err) = child { + if let Err(err) = std::process::Command::new("xdg-open").arg(&CONFIG.game.path).spawn() { sender.input(AppMsg::Toast { title: tr("game-folder-opening-error"), description: Some(err.to_string()) @@ -310,13 +305,7 @@ impl SimpleComponent for App { group.add_action::(&RelmAction::new_stateless(clone!(@strong sender => move |_| { if let Some(file) = anime_launcher_sdk::consts::config_file() { - let child = std::process::Command::new("xdg-open") - .arg(file) - .stdout(std::process::Stdio::null()) - .stderr(std::process::Stdio::null()) - .spawn(); - - if let Err(err) = child { + if let Err(err) = std::process::Command::new("xdg-open").arg(file).spawn() { sender.input(AppMsg::Toast { title: tr("config-file-opening-error"), description: Some(err.to_string()) @@ -347,7 +336,7 @@ impl SimpleComponent for App { Ok(diff) => Some(diff), Err(err) => { tracing::error!("Failed to get game diff: {err}"); - + None } })); @@ -362,13 +351,48 @@ impl SimpleComponent for App { Ok(patch) => Some(patch), Err(err) => { tracing::error!("Failed to fetch patch info: {err}"); - + None } })); tracing::info!("Updated patch status"); + // Update launcher state + + let updater = clone!(@strong sender => move |state| { + use anime_launcher_sdk::states::StateUpdating; + + match state { + StateUpdating::Game => { + sender.input(AppMsg::UpdateLoadingStatus(Some(Some(tr("loading-launcher-state--game"))))); + } + + StateUpdating::Voice(locale) => { + sender.input(AppMsg::UpdateLoadingStatus(Some(Some(tr_args("loading-launcher-state--voice", [ + ("locale", locale.to_name().to_owned().into()) + ]))))); + } + + StateUpdating::Patch => { + sender.input(AppMsg::UpdateLoadingStatus(Some(Some(tr("loading-launcher-state--patch"))))); + } + } + }); + + sender.input(AppMsg::UpdateLoadingStatus(Some(Some(tr("loading-launcher-state"))))); + + sender.input(AppMsg::UpdateLauncherState(match LauncherState::get_from_config(updater) { + Ok(state) => Some(state), + Err(err) => { + tracing::error!("Failed to fetch patch info: {err}"); + + None + } + })); + + tracing::info!("Updated launcher state"); + // Hide loading page sender.input(AppMsg::UpdateLoadingStatus(None)); @@ -383,7 +407,7 @@ impl SimpleComponent for App { ComponentParts { model, widgets } } - fn update(&mut self, msg: Self::Input, _sender: ComponentSender) { + fn update(&mut self, msg: Self::Input, sender: ComponentSender) { tracing::debug!("Called main window event: {:?}", msg); match msg { @@ -397,6 +421,10 @@ impl SimpleComponent for App { PREFERENCES_WINDOW.as_ref().unwrap_unchecked().sender().send(PreferencesAppMsg::UpdatePatch(patch)); } + AppMsg::UpdateLauncherState(state) => { + self.state = state; + } + AppMsg::Toast { title, description } => unsafe { let toast = adw::Toast::new(&title); @@ -435,10 +463,6 @@ impl SimpleComponent for App { self.loading = status; } - AppMsg::PerformAction => { - anime_launcher_sdk::game::run().expect("Failed to run the game"); - } - AppMsg::OpenPreferences => unsafe { PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widget().show(); } @@ -450,6 +474,32 @@ impl SimpleComponent for App { AppMsg::UpdateLauncherStyle(style) => { self.style = style; } + + AppMsg::PerformAction => unsafe { + match self.state.as_ref().unwrap_unchecked() { + LauncherState::Launch => { + if let Err(err) = anime_launcher_sdk::game::run() { + sender.input(AppMsg::Toast { + title: tr("game-launching-failed"), + description: Some(err.to_string()) + }); + + tracing::error!("Failed to launch game: {err}"); + } + } + + LauncherState::PredownloadAvailable { .. } => todo!(), + LauncherState::PatchAvailable(_) => todo!(), + LauncherState::WineNotInstalled => todo!(), + LauncherState::PrefixNotExists => todo!(), + LauncherState::VoiceUpdateAvailable(_) => todo!(), + LauncherState::VoiceOutdated(_) => todo!(), + LauncherState::VoiceNotInstalled(_) => todo!(), + LauncherState::GameUpdateAvailable(_) => todo!(), + LauncherState::GameOutdated(_) => todo!(), + LauncherState::GameNotInstalled(_) => todo!(), + } + } } } }