mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2025-02-16 15:22:01 +03:00
settings: added patch status displaying
This commit is contained in:
parent
84163c470d
commit
29702782e2
6 changed files with 155 additions and 63 deletions
42
src/main.rs
42
src/main.rs
|
@ -1,6 +1,8 @@
|
|||
use relm4::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::config;
|
||||
use anime_launcher_sdk::anime_game_core::prelude::*;
|
||||
use anime_launcher_sdk::anime_game_core::genshin::prelude::*;
|
||||
|
||||
pub mod i18n;
|
||||
pub mod ui;
|
||||
|
@ -13,6 +15,46 @@ pub const APP_ID: &str = "moe.launcher.an-anime-game-launcher-gtk";
|
|||
pub const APP_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const APP_DEBUG: bool = cfg!(debug_assertions);
|
||||
|
||||
/// Sets to `true` when the `App` component is ready (fully initialized)
|
||||
pub static mut READY: bool = false;
|
||||
|
||||
// TODO: get rid of using this function in all the components' events
|
||||
// e.g. by converting preferences pages into Relm4 Components
|
||||
pub fn is_ready() -> bool {
|
||||
unsafe { READY }
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
/// Config loaded on the app's start. Use `config::get()` to get up to date config instead.
|
||||
/// This one is used to prepare some launcher UI components on start
|
||||
pub static ref CONFIG: config::Config = config::get().expect("Failed to load config");
|
||||
|
||||
pub static ref GAME: Game = Game::new(&CONFIG.game.path);
|
||||
|
||||
// TODO: add loading screen for heavy tasks like this
|
||||
// UPD: tried once. The problem is that I use this variable, as well as ones above,
|
||||
// in the view! macro, which makes it times harder to make the main window load
|
||||
// faster than this variable calculates its value to show StatusPage with loader.
|
||||
// As for now I have no idea how to fix this
|
||||
pub static ref GAME_DIFF: Option<VersionDiff> = match GAME.try_get_diff() {
|
||||
Ok(diff) => Some(diff),
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to get game diff {err}");
|
||||
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
pub static ref PATCH: Option<Patch> = match Patch::try_fetch(&CONFIG.patch.servers, None) {
|
||||
Ok(patch) => Some(patch),
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to fetch patch info {err}");
|
||||
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tracing_subscriber::fmt()
|
||||
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL)
|
||||
|
|
|
@ -55,7 +55,8 @@ impl SimpleComponent for AboutDialog {
|
|||
|
||||
add_credit_section: (Some("An Anime Team"), &[
|
||||
"@Marie https://github.com/Mar0xy",
|
||||
"@lane https://github.com/laurinneff"
|
||||
"@lane https://github.com/laurinneff",
|
||||
"@jiro-too https://github.com/jiro-too"
|
||||
]),
|
||||
|
||||
set_debug_info: &[
|
||||
|
@ -88,6 +89,8 @@ impl SimpleComponent for AboutDialog {
|
|||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
tracing::info!("Initializing about dialog");
|
||||
|
||||
let model = AboutDialog {
|
||||
visible: false
|
||||
};
|
||||
|
|
|
@ -16,20 +16,11 @@ relm4::new_stateless_action!(ConfigFile, WindowActionGroup, "config_file");
|
|||
|
||||
relm4::new_stateless_action!(About, WindowActionGroup, "about");
|
||||
|
||||
/// Sets to `true` when the `App` component is ready (fully initialized)
|
||||
pub static mut READY: bool = false;
|
||||
|
||||
// TODO: get rid of using this function in all the components' events
|
||||
// e.g. by converting preferences pages into Relm4 Components
|
||||
pub fn is_ready() -> bool {
|
||||
unsafe { READY }
|
||||
}
|
||||
static mut PREFERENCES_WINDOW: Option<Controller<PreferencesApp>> = None;
|
||||
static mut ABOUT_DIALOG: Option<Controller<AboutDialog>> = None;
|
||||
|
||||
pub struct App {
|
||||
preferences_window: Controller<PreferencesApp>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
about_dialog: Controller<AboutDialog>
|
||||
loading: Option<Option<String>>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -73,7 +64,25 @@ impl SimpleComponent for App {
|
|||
}
|
||||
},
|
||||
|
||||
adw::StatusPage {
|
||||
set_title: "Loading data",
|
||||
set_icon_name: Some("process-working"),
|
||||
set_vexpand: true,
|
||||
|
||||
#[watch]
|
||||
set_description: match &model.loading {
|
||||
Some(Some(desc)) => Some(desc),
|
||||
Some(None) | None => None
|
||||
},
|
||||
|
||||
#[watch]
|
||||
set_visible: model.loading.is_some()
|
||||
},
|
||||
|
||||
adw::PreferencesPage {
|
||||
#[watch]
|
||||
set_visible: model.loading.is_none(),
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
gtk::Image {
|
||||
set_resource: Some("/org/app/images/icon.png"),
|
||||
|
@ -127,6 +136,10 @@ impl SimpleComponent for App {
|
|||
) -> ComponentParts<Self> {
|
||||
tracing::info!("Initializing main window");
|
||||
|
||||
let model = App {
|
||||
loading: None
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
if crate::APP_DEBUG {
|
||||
|
@ -135,16 +148,16 @@ impl SimpleComponent for App {
|
|||
|
||||
let about_dialog_broker: MessageBroker<AboutDialog> = MessageBroker::new();
|
||||
|
||||
let model = App {
|
||||
preferences_window: PreferencesApp::builder()
|
||||
unsafe {
|
||||
PREFERENCES_WINDOW = Some(PreferencesApp::builder()
|
||||
.launch(widgets.main_window.clone().into())
|
||||
.detach(),
|
||||
.detach());
|
||||
|
||||
about_dialog: AboutDialog::builder()
|
||||
ABOUT_DIALOG = Some(AboutDialog::builder()
|
||||
.transient_for(widgets.main_window.clone())
|
||||
.launch_with_broker((), &about_dialog_broker)
|
||||
.detach()
|
||||
};
|
||||
.detach());
|
||||
}
|
||||
|
||||
let group = RelmActionGroup::<WindowActionGroup>::new();
|
||||
|
||||
|
@ -167,7 +180,7 @@ impl SimpleComponent for App {
|
|||
widgets.main_window.insert_action_group("win", Some(&group.into_action_group()));
|
||||
|
||||
unsafe {
|
||||
READY = true;
|
||||
crate::READY = true;
|
||||
}
|
||||
|
||||
tracing::info!("Main window initialized. App is ready");
|
||||
|
@ -179,12 +192,12 @@ impl SimpleComponent for App {
|
|||
tracing::debug!("Called main window event: {:?}", msg);
|
||||
|
||||
match msg {
|
||||
AppMsg::OpenPreferences => {
|
||||
self.preferences_window.widgets().preferences_window.show();
|
||||
AppMsg::OpenPreferences => unsafe {
|
||||
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widgets().preferences_window.show();
|
||||
}
|
||||
|
||||
AppMsg::ClosePreferences => {
|
||||
self.preferences_window.widgets().preferences_window.hide();
|
||||
AppMsg::ClosePreferences => unsafe {
|
||||
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widgets().preferences_window.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use anime_launcher_sdk::config;
|
|||
use anime_launcher_sdk::config::prelude::*;
|
||||
|
||||
use crate::i18n::tr;
|
||||
use crate::ui::main::is_ready;
|
||||
use crate::*;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref CONFIG: config::Config = config::get().expect("Failed to load config");
|
||||
|
|
|
@ -5,25 +5,9 @@ use adw::prelude::*;
|
|||
|
||||
use anime_launcher_sdk::config;
|
||||
use anime_launcher_sdk::anime_game_core::prelude::*;
|
||||
use anime_launcher_sdk::anime_game_core::genshin::prelude::*;
|
||||
|
||||
use crate::i18n::*;
|
||||
use crate::ui::main::is_ready;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref CONFIG: config::Config = config::get().expect("Failed to load config");
|
||||
|
||||
static ref GAME: Game = Game::new(&CONFIG.game.path);
|
||||
|
||||
static ref GAME_DIFF: Option<VersionDiff> = match GAME.try_get_diff() {
|
||||
Ok(diff) => Some(diff),
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to get game diff {err}");
|
||||
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
use crate::*;
|
||||
|
||||
#[relm4::widget_template(pub)]
|
||||
impl WidgetTemplate for General {
|
||||
|
@ -154,20 +138,24 @@ impl WidgetTemplate for General {
|
|||
None => "success"
|
||||
},
|
||||
|
||||
set_tooltip_text: Some(&match GAME_DIFF.as_ref().unwrap() {
|
||||
VersionDiff::Latest(_) => String::new(),
|
||||
VersionDiff::Predownload { current, latest, .. } => tr_args("game-predownload-available", [
|
||||
("old", current.to_string().into()),
|
||||
("new", latest.to_string().into())
|
||||
]),
|
||||
VersionDiff::Diff { current, latest, .. } => tr_args("game-update-available", [
|
||||
("old", current.to_string().into()),
|
||||
("new", latest.to_string().into())
|
||||
]),
|
||||
VersionDiff::Outdated { latest, ..} => tr_args("game-outdated", [
|
||||
("latest", latest.to_string().into())
|
||||
]),
|
||||
VersionDiff::NotInstalled { .. } => String::new()
|
||||
set_tooltip_text: Some(&match GAME_DIFF.as_ref() {
|
||||
Some(diff) => match diff {
|
||||
VersionDiff::Latest(_) => String::new(),
|
||||
VersionDiff::Predownload { current, latest, .. } => tr_args("game-predownload-available", [
|
||||
("old", current.to_string().into()),
|
||||
("new", latest.to_string().into())
|
||||
]),
|
||||
VersionDiff::Diff { current, latest, .. } => tr_args("game-update-available", [
|
||||
("old", current.to_string().into()),
|
||||
("new", latest.to_string().into())
|
||||
]),
|
||||
VersionDiff::Outdated { latest, ..} => tr_args("game-outdated", [
|
||||
("latest", latest.to_string().into())
|
||||
]),
|
||||
VersionDiff::NotInstalled { .. } => String::new()
|
||||
}
|
||||
|
||||
None => String::new()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -176,8 +164,56 @@ impl WidgetTemplate for General {
|
|||
set_title: &tr("patch-version"),
|
||||
|
||||
add_suffix = >k::Label {
|
||||
set_text: "3.3.0",
|
||||
add_css_class: "success"
|
||||
set_text: &match PATCH.as_ref() {
|
||||
Some(patch) => match patch {
|
||||
Patch::NotAvailable => tr("patch-not-available"),
|
||||
Patch::Outdated { current, .. } => tr_args("patch-outdated", [("current", current.to_string().into())]),
|
||||
Patch::Preparation { .. } => tr("patch-preparation"),
|
||||
Patch::Testing { version, .. } |
|
||||
Patch::Available { version, .. } => version.to_string()
|
||||
}
|
||||
|
||||
None => String::from("?")
|
||||
},
|
||||
|
||||
add_css_class: match PATCH.as_ref() {
|
||||
Some(patch) => match patch {
|
||||
Patch::NotAvailable => "error",
|
||||
Patch::Outdated { .. } |
|
||||
Patch::Preparation { .. } |
|
||||
Patch::Testing { .. } => "warning",
|
||||
Patch::Available { .. } => unsafe {
|
||||
if let Ok(true) = PATCH.as_ref().unwrap_unchecked().is_applied(&CONFIG.game.path) {
|
||||
"success"
|
||||
} else {
|
||||
"warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None => ""
|
||||
},
|
||||
|
||||
set_tooltip_text: Some(&match PATCH.as_ref() {
|
||||
Some(patch) => match patch {
|
||||
Patch::NotAvailable => tr("patch-not-available-tooltip"),
|
||||
Patch::Outdated { current, latest, .. } => tr_args("patch-outdated-tooltip", [
|
||||
("current", current.to_string().into()),
|
||||
("latest", latest.to_string().into())
|
||||
]),
|
||||
Patch::Preparation { .. } => tr("patch-preparation-tooltip"),
|
||||
Patch::Testing { .. } => tr("patch-testing-tooltip"),
|
||||
Patch::Available { .. } => unsafe {
|
||||
if let Ok(true) = PATCH.as_ref().unwrap_unchecked().is_applied(&CONFIG.game.path) {
|
||||
String::new()
|
||||
} else {
|
||||
tr("patch-testing-tooltip")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None => String::new()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -3,16 +3,12 @@ use relm4::prelude::*;
|
|||
use gtk::prelude::*;
|
||||
use adw::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::config;
|
||||
use anime_launcher_sdk::components::*;
|
||||
|
||||
use crate::ui::components::{self, *};
|
||||
|
||||
use crate::i18n::tr;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref CONFIG: config::Config = config::get().expect("Failed to load config");
|
||||
}
|
||||
use crate::CONFIG;
|
||||
|
||||
pub struct App {
|
||||
wine_components: Controller<ComponentsList>,
|
||||
|
@ -85,6 +81,8 @@ impl SimpleComponent for App {
|
|||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
tracing::info!("Initializing preferences window");
|
||||
|
||||
let model = App {
|
||||
wine_components: ComponentsList::builder()
|
||||
.launch(ComponentsListPattern {
|
||||
|
|
Loading…
Add table
Reference in a new issue