mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-11-21 20:36:01 +03:00
main window: added initial states system support
This commit is contained in:
parent
14067c7bdf
commit
f2a04f5ebe
5 changed files with 101 additions and 33 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = Проверка свободного места
|
||||
|
|
116
src/ui/main.rs
116
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<Option<String>>,
|
||||
style: LauncherStyle
|
||||
style: LauncherStyle,
|
||||
state: Option<LauncherState>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -47,16 +49,19 @@ pub enum AppMsg {
|
|||
/// was retrieved from remote repos
|
||||
UpdatePatch(Option<Patch>),
|
||||
|
||||
/// Supposed to be called automatically on app's run when the launcher state was chosen
|
||||
UpdateLauncherState(Option<LauncherState>),
|
||||
|
||||
Toast {
|
||||
title: String,
|
||||
description: Option<String>
|
||||
},
|
||||
|
||||
UpdateLoadingStatus(Option<Option<String>>),
|
||||
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::<LauncherFolder>(&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::<GameFolder>(&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::<ConfigFile>(&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<Self>) {
|
||||
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue