feat: integrated jadeite patch
This commit is contained in:
parent
cd50870a0e
commit
21772ff735
11 changed files with 144 additions and 211 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -48,8 +48,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anime-game-core"
|
||||
version = "1.11.8"
|
||||
source = "git+https://github.com/an-anime-team/anime-game-core?tag=1.11.8#eaa07d40c321a6285ca81892d32b6e0f7b056fc6"
|
||||
version = "1.12.0"
|
||||
source = "git+https://github.com/an-anime-team/anime-game-core?tag=1.12.0#71dd691d1698c3f8d23744c364b24824c43a6e33"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bzip2",
|
||||
|
@ -73,8 +73,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anime-launcher-sdk"
|
||||
version = "1.6.7"
|
||||
source = "git+https://github.com/an-anime-team/anime-launcher-sdk?tag=1.6.7#60d800a23d2359d40aaf3b1d62e0b953e9c08062"
|
||||
version = "1.7.0"
|
||||
source = "git+https://github.com/an-anime-team/anime-launcher-sdk?tag=1.7.0#40708d6b1072e5699ffa46acbe200289adb34a05"
|
||||
dependencies = [
|
||||
"anime-game-core",
|
||||
"anyhow",
|
||||
|
|
|
@ -17,8 +17,8 @@ glib-build-tools = "0.17"
|
|||
|
||||
[dependencies.anime-launcher-sdk]
|
||||
git = "https://github.com/an-anime-team/anime-launcher-sdk"
|
||||
tag = "1.6.7"
|
||||
features = ["all", "star-rail"]
|
||||
tag = "1.7.0"
|
||||
features = ["all", "star-rail", "star-rail-patch"]
|
||||
|
||||
# path = "../anime-launcher-sdk" # ! for dev purposes only
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ fn main() {
|
|||
}
|
||||
|
||||
LauncherState::PredownloadAvailable { .. } |
|
||||
LauncherState::MainPatchAvailable(MainPatch { status: PatchStatus::NotAvailable, .. }) => {
|
||||
LauncherState::PatchUpdateAvailable => {
|
||||
if just_run_game {
|
||||
anime_launcher_sdk::star_rail::game::run().expect("Failed to run the game");
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
use relm4::prelude::*;
|
||||
|
||||
use crate::*;
|
||||
use crate::i18n::*;
|
||||
use super::{App, AppMsg};
|
||||
|
||||
pub fn apply_patch(sender: ComponentSender<App>, patch: MainPatch) {
|
||||
match patch.status() {
|
||||
PatchStatus::NotAvailable |
|
||||
PatchStatus::Outdated { .. } => unreachable!(),
|
||||
|
||||
PatchStatus::Testing { .. } |
|
||||
PatchStatus::Available { .. } => {
|
||||
sender.input(AppMsg::DisableButtons(true));
|
||||
|
||||
let config = Config::get().unwrap();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let mut apply_patch_if_needed = true;
|
||||
|
||||
let game_path = config.game.path.for_edition(config.launcher.edition);
|
||||
|
||||
if let Err(err) = patch.apply(game_path, config.patch.root) {
|
||||
tracing::error!("Failed to patch the game");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("game-patching-error"),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
|
||||
// Don't try to apply the patch after state updating
|
||||
// because we just failed to do it
|
||||
apply_patch_if_needed = false;
|
||||
}
|
||||
|
||||
sender.input(AppMsg::DisableButtons(false));
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
apply_patch_if_needed,
|
||||
show_status_page: true
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,7 +34,6 @@ pub fn create_prefix(sender: ComponentSender<App>) {
|
|||
sender.input(AppMsg::DisableButtons(false));
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
apply_patch_if_needed: false,
|
||||
show_status_page: true
|
||||
});
|
||||
});
|
||||
|
|
|
@ -68,7 +68,6 @@ pub fn download_diff(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
|
|||
sender.input(AppMsg::SetDownloading(false));
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed,
|
||||
apply_patch_if_needed: false,
|
||||
show_status_page: false
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,7 +25,6 @@ pub fn download_wine(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
|
|||
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
apply_patch_if_needed: false,
|
||||
show_status_page: true
|
||||
});
|
||||
}
|
||||
|
@ -89,7 +88,6 @@ pub fn download_wine(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
|
|||
sender.input(AppMsg::SetDownloading(false));
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
apply_patch_if_needed: false,
|
||||
show_status_page: true
|
||||
});
|
||||
}));
|
||||
|
|
|
@ -10,7 +10,7 @@ use adw::prelude::*;
|
|||
|
||||
use gtk::glib::clone;
|
||||
|
||||
mod apply_patch;
|
||||
mod update_patch;
|
||||
mod download_wine;
|
||||
mod create_prefix;
|
||||
mod download_diff;
|
||||
|
@ -67,9 +67,6 @@ pub enum AppMsg {
|
|||
/// Needed for chained executions (e.g. update one voice after another)
|
||||
perform_on_download_needed: bool,
|
||||
|
||||
/// Automatically start patch applying if possible and needed
|
||||
apply_patch_if_needed: bool,
|
||||
|
||||
/// Show status gathering progress page
|
||||
show_status_page: bool
|
||||
},
|
||||
|
@ -80,7 +77,7 @@ pub enum AppMsg {
|
|||
|
||||
/// Supposed to be called automatically on app's run when the latest main patch version
|
||||
/// was retrieved from remote repos
|
||||
SetMainPatch(Option<MainPatch>),
|
||||
SetMainPatch(Option<(Version, JadeitePatchStatusVariant)>),
|
||||
|
||||
/// Supposed to be called automatically on app's run when the launcher state was chosen
|
||||
SetLauncherState(Option<LauncherState>),
|
||||
|
@ -359,32 +356,36 @@ impl SimpleComponent for App {
|
|||
#[watch]
|
||||
set_icon_name: match &model.state {
|
||||
Some(LauncherState::Launch) |
|
||||
Some(LauncherState::PatchNotVerified) |
|
||||
Some(LauncherState::PredownloadAvailable { .. }) => "media-playback-start-symbolic",
|
||||
|
||||
Some(LauncherState::PatchNotInstalled) |
|
||||
Some(LauncherState::PatchUpdateAvailable) => "document-save-symbolic",
|
||||
|
||||
Some(LauncherState::WineNotInstalled) |
|
||||
Some(LauncherState::PrefixNotExists) => "document-save-symbolic",
|
||||
|
||||
Some(LauncherState::GameUpdateAvailable(_)) |
|
||||
Some(LauncherState::GameNotInstalled(_)) => "document-save-symbolic",
|
||||
|
||||
Some(LauncherState::MainPatchAvailable(MainPatch { status, .. })) => match status {
|
||||
PatchStatus::NotAvailable |
|
||||
PatchStatus::Outdated { .. } => "window-close-symbolic",
|
||||
|
||||
PatchStatus::Testing { .. } |
|
||||
PatchStatus::Available { .. } => "document-save-symbolic"
|
||||
}
|
||||
|
||||
Some(LauncherState::GameOutdated(_)) |
|
||||
Some(LauncherState::PatchBroken) |
|
||||
Some(LauncherState::PatchUnsafe) |
|
||||
None => "window-close-symbolic"
|
||||
},
|
||||
|
||||
#[watch]
|
||||
set_label: &match &model.state {
|
||||
Some(LauncherState::Launch) |
|
||||
Some(LauncherState::PatchNotVerified) |
|
||||
Some(LauncherState::PredownloadAvailable { .. }) => tr("launch"),
|
||||
|
||||
Some(LauncherState::MainPatchAvailable(_)) => tr("apply-patch"),
|
||||
// TODO: add localization
|
||||
Some(LauncherState::PatchNotInstalled) |
|
||||
Some(LauncherState::PatchUpdateAvailable) => String::from("Download patch"),
|
||||
|
||||
Some(LauncherState::PatchBroken) => String::from("Patch is broken"),
|
||||
Some(LauncherState::PatchUnsafe) => String::from("Patch is unsafe"),
|
||||
|
||||
Some(LauncherState::WineNotInstalled) => tr("download-wine"),
|
||||
Some(LauncherState::PrefixNotExists) => tr("create-prefix"),
|
||||
|
@ -416,15 +417,9 @@ impl SimpleComponent for App {
|
|||
|
||||
#[watch]
|
||||
set_sensitive: !model.disabled_buttons && match &model.state {
|
||||
Some(LauncherState::GameOutdated { .. }) => false,
|
||||
|
||||
Some(LauncherState::MainPatchAvailable(MainPatch { status, .. })) => match status {
|
||||
PatchStatus::NotAvailable |
|
||||
PatchStatus::Outdated { .. } => false,
|
||||
|
||||
PatchStatus::Testing { .. } |
|
||||
PatchStatus::Available { .. } => true
|
||||
},
|
||||
Some(LauncherState::GameOutdated { .. }) |
|
||||
Some(LauncherState::PatchBroken) |
|
||||
Some(LauncherState::PatchUnsafe) => false,
|
||||
|
||||
Some(_) => true,
|
||||
|
||||
|
@ -433,15 +428,11 @@ impl SimpleComponent for App {
|
|||
|
||||
#[watch]
|
||||
set_css_classes: match &model.state {
|
||||
Some(LauncherState::GameOutdated { .. }) => &["warning", "pill"],
|
||||
Some(LauncherState::GameOutdated { .. }) |
|
||||
Some(LauncherState::PatchNotVerified) => &["warning", "pill"],
|
||||
|
||||
Some(LauncherState::MainPatchAvailable(MainPatch { status, .. })) => match status {
|
||||
PatchStatus::NotAvailable |
|
||||
PatchStatus::Outdated { .. } => &["error", "pill"],
|
||||
|
||||
PatchStatus::Testing { .. } => &["warning", "pill"],
|
||||
PatchStatus::Available { .. } => &["suggested-action", "pill"]
|
||||
},
|
||||
Some(LauncherState::PatchBroken) |
|
||||
Some(LauncherState::PatchUnsafe) => &["error", "pill"],
|
||||
|
||||
Some(_) => &["suggested-action", "pill"],
|
||||
|
||||
|
@ -452,12 +443,9 @@ impl SimpleComponent for App {
|
|||
set_tooltip_text: Some(&match &model.state {
|
||||
Some(LauncherState::GameOutdated { .. }) => tr("main-window--version-outdated-tooltip"),
|
||||
|
||||
Some(LauncherState::MainPatchAvailable(MainPatch { status, .. })) => match status {
|
||||
PatchStatus::NotAvailable => tr("main-window--patch-unavailable-tooltip"),
|
||||
PatchStatus::Outdated { .. } => tr("main-window--patch-outdated-tooltip"),
|
||||
|
||||
_ => String::new()
|
||||
},
|
||||
// TODO: add localization
|
||||
Some(LauncherState::PatchBroken) => String::from("Current patch version is broken and doesn't work properly"),
|
||||
Some(LauncherState::PatchUnsafe) => String::from("Current patch version is unsafe and should not be used"),
|
||||
|
||||
_ => String::new()
|
||||
}),
|
||||
|
@ -751,45 +739,31 @@ impl SimpleComponent for App {
|
|||
// Update initial patch status
|
||||
|
||||
tasks.push(std::thread::spawn(clone!(@strong sender => move || {
|
||||
// Sync local patch repo
|
||||
let patch = Patch::new(&CONFIG.patch.path, CONFIG.launcher.edition);
|
||||
|
||||
match patch.is_sync(&CONFIG.patch.servers) {
|
||||
Ok(Some(_)) => (),
|
||||
|
||||
Ok(None) => {
|
||||
for server in &CONFIG.patch.servers {
|
||||
match patch.sync(server) {
|
||||
Ok(_) => break,
|
||||
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to sync patch folder with remote: {server}: {err}");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("patch-sync-failed"),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to compare local patch folder with remote: {err}");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("patch-state-check-failed"),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get main patch status
|
||||
sender.input(AppMsg::SetMainPatch(match patch.main_patch() {
|
||||
Ok(patch) => Some(patch),
|
||||
sender.input(AppMsg::SetMainPatch(match jadeite::get_latest() {
|
||||
Ok(latest) => match jadeite::get_metadata() {
|
||||
Ok(metadata) => {
|
||||
let status = GAME.get_version()
|
||||
.map(|version| metadata.hsr.global.get_status(version))
|
||||
.unwrap_or(metadata.hsr.global.status);
|
||||
|
||||
Some((latest.version, status))
|
||||
}
|
||||
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to fetch main patch info: {err}");
|
||||
tracing::error!("Failed to fetch patch metadata: {err}");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("patch-info-fetching-error"),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
|
||||
None
|
||||
}
|
||||
},
|
||||
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to fetch latest patch version: {err}");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("patch-info-fetching-error"),
|
||||
|
@ -831,7 +805,6 @@ impl SimpleComponent for App {
|
|||
// Update launcher state
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
apply_patch_if_needed: false,
|
||||
show_status_page: true
|
||||
});
|
||||
|
||||
|
@ -851,7 +824,7 @@ impl SimpleComponent for App {
|
|||
|
||||
match msg {
|
||||
// TODO: make function from this message like with toast
|
||||
AppMsg::UpdateLauncherState { perform_on_download_needed, apply_patch_if_needed, show_status_page } => {
|
||||
AppMsg::UpdateLauncherState { perform_on_download_needed, show_status_page } => {
|
||||
if show_status_page {
|
||||
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr("loading-launcher-state")))));
|
||||
} else {
|
||||
|
@ -898,10 +871,6 @@ impl SimpleComponent for App {
|
|||
sender.input(AppMsg::PerformAction);
|
||||
}
|
||||
|
||||
LauncherState::MainPatchAvailable(_) if apply_patch_if_needed => {
|
||||
sender.input(AppMsg::PerformAction);
|
||||
}
|
||||
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
@ -969,7 +938,6 @@ impl SimpleComponent for App {
|
|||
sender.input(AppMsg::SetDownloading(false));
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
apply_patch_if_needed: false,
|
||||
show_status_page: true
|
||||
});
|
||||
});
|
||||
|
@ -978,11 +946,13 @@ impl SimpleComponent for App {
|
|||
|
||||
AppMsg::PerformAction => unsafe {
|
||||
match self.state.as_ref().unwrap_unchecked() {
|
||||
LauncherState::MainPatchAvailable(MainPatch { status: PatchStatus::NotAvailable, .. }) |
|
||||
LauncherState::PatchNotVerified |
|
||||
LauncherState::PredownloadAvailable { .. } |
|
||||
LauncherState::Launch => launch::launch(sender),
|
||||
|
||||
LauncherState::MainPatchAvailable(patch) => apply_patch::apply_patch(sender, patch.to_owned()),
|
||||
LauncherState::PatchNotInstalled |
|
||||
LauncherState::PatchUpdateAvailable => update_patch::update_patch(sender, self.progress_bar.sender().to_owned()),
|
||||
|
||||
LauncherState::WineNotInstalled => download_wine::download_wine(sender, self.progress_bar.sender().to_owned()),
|
||||
LauncherState::PrefixNotExists => create_prefix::create_prefix(sender),
|
||||
|
||||
|
@ -990,7 +960,7 @@ impl SimpleComponent for App {
|
|||
LauncherState::GameNotInstalled(diff) =>
|
||||
download_diff::download_diff(sender, self.progress_bar.sender().to_owned(), diff.to_owned()),
|
||||
|
||||
LauncherState::GameOutdated(_) => ()
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
64
src/ui/main/update_patch.rs
Normal file
64
src/ui/main/update_patch.rs
Normal file
|
@ -0,0 +1,64 @@
|
|||
use relm4::{
|
||||
prelude::*,
|
||||
Sender
|
||||
};
|
||||
|
||||
use gtk::glib::clone;
|
||||
|
||||
use crate::*;
|
||||
use crate::i18n::*;
|
||||
use crate::ui::components::*;
|
||||
|
||||
use super::{App, AppMsg};
|
||||
|
||||
pub fn update_patch(sender: ComponentSender<App>, progress_bar_input: Sender<ProgressBarMsg>) {
|
||||
sender.input(AppMsg::SetDownloading(true));
|
||||
|
||||
let config = Config::get().unwrap();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let result = jadeite::get_latest()
|
||||
.and_then(|patch| patch.install(config.patch.path, clone!(@strong sender => move |state| {
|
||||
match &state {
|
||||
InstallerUpdate::DownloadingError(err) => {
|
||||
tracing::error!("Downloading failed: {err}");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("downloading-failed"),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
}
|
||||
|
||||
InstallerUpdate::UnpackingError(err) => {
|
||||
tracing::error!("Unpacking failed: {err}");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("unpacking-failed"),
|
||||
description: Some(err.clone())
|
||||
});
|
||||
}
|
||||
|
||||
_ => ()
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)] {
|
||||
progress_bar_input.send(ProgressBarMsg::UpdateFromState(state.into()));
|
||||
}
|
||||
})));
|
||||
|
||||
if let Err(err) = result {
|
||||
tracing::error!("Failed to download latest patch");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
title: String::from("Failed to download latest patch"), // TODO: add localization
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
}
|
||||
|
||||
sender.input(AppMsg::SetDownloading(false));
|
||||
sender.input(AppMsg::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
show_status_page: true
|
||||
});
|
||||
});
|
||||
}
|
|
@ -4,10 +4,11 @@ use relm4::component::*;
|
|||
use gtk::prelude::*;
|
||||
use adw::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::anime_game_core::star_rail::consts::GameEdition;
|
||||
|
||||
use anime_launcher_sdk::wincompatlib::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::anime_game_core::prelude::*;
|
||||
use anime_launcher_sdk::anime_game_core::star_rail::consts::GameEdition;
|
||||
|
||||
use anime_launcher_sdk::config::ConfigExt;
|
||||
use anime_launcher_sdk::star_rail::config::Config;
|
||||
use anime_launcher_sdk::star_rail::config::schema::launcher::LauncherStyle;
|
||||
|
@ -27,7 +28,7 @@ pub struct GeneralApp {
|
|||
components_page: AsyncController<ComponentsPage>,
|
||||
|
||||
game_diff: Option<VersionDiff>,
|
||||
main_patch: Option<MainPatch>,
|
||||
main_patch: Option<(Version, JadeitePatchStatusVariant)>,
|
||||
|
||||
style: LauncherStyle,
|
||||
|
||||
|
@ -42,7 +43,7 @@ pub enum GeneralAppMsg {
|
|||
|
||||
/// Supposed to be called automatically on app's run when the latest UnityPlayer patch version
|
||||
/// was retrieved from remote repos
|
||||
SetMainPatch(Option<MainPatch>),
|
||||
SetMainPatch(Option<(Version, JadeitePatchStatusVariant)>),
|
||||
|
||||
UpdateDownloadedWine,
|
||||
UpdateDownloadedDxvk,
|
||||
|
@ -301,36 +302,17 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
add_suffix = >k::Label {
|
||||
#[watch]
|
||||
set_text: &match model.main_patch.as_ref() {
|
||||
Some(patch) => match patch.status() {
|
||||
PatchStatus::NotAvailable => tr("patch-not-available"),
|
||||
PatchStatus::Outdated { current, .. } => tr_args("patch-outdated", [("current", current.to_string().into())]),
|
||||
PatchStatus::Testing { version, .. } |
|
||||
PatchStatus::Available { version, .. } => version.to_string()
|
||||
}
|
||||
|
||||
Some((version, _)) => version.to_string(),
|
||||
None => String::from("?")
|
||||
},
|
||||
|
||||
#[watch]
|
||||
set_css_classes: match model.main_patch.as_ref() {
|
||||
Some(patch) => match patch.status() {
|
||||
PatchStatus::NotAvailable => &["error"],
|
||||
|
||||
PatchStatus::Outdated { .. } |
|
||||
PatchStatus::Testing { .. } => &["warning"],
|
||||
|
||||
PatchStatus::Available { .. } => unsafe {
|
||||
let path = match Config::get() {
|
||||
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(),
|
||||
};
|
||||
|
||||
if let Ok(true) = model.main_patch.as_ref().unwrap_unchecked().is_applied(path) {
|
||||
&["success"]
|
||||
} else {
|
||||
&["warning"]
|
||||
}
|
||||
}
|
||||
Some((_, status)) => match status {
|
||||
JadeitePatchStatusVariant::Verified => &["success"],
|
||||
JadeitePatchStatusVariant::Unverified => &["warning"],
|
||||
JadeitePatchStatusVariant::Broken => &["error"],
|
||||
JadeitePatchStatusVariant::Unsafe => &["error"]
|
||||
}
|
||||
|
||||
None => &[]
|
||||
|
@ -338,25 +320,14 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
|
||||
#[watch]
|
||||
set_tooltip_text: Some(&match model.main_patch.as_ref() {
|
||||
Some(patch) => match patch.status() {
|
||||
PatchStatus::NotAvailable => tr("patch-not-available-tooltip"),
|
||||
PatchStatus::Outdated { current, latest, .. } => tr_args("patch-outdated-tooltip", [
|
||||
("current", current.to_string().into()),
|
||||
("latest", latest.to_string().into())
|
||||
]),
|
||||
PatchStatus::Testing { .. } => tr("patch-testing-tooltip"),
|
||||
PatchStatus::Available { .. } => unsafe {
|
||||
let path = match Config::get() {
|
||||
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(),
|
||||
};
|
||||
Some((_, status)) => match status {
|
||||
JadeitePatchStatusVariant::Unverified => tr("patch-testing-tooltip"),
|
||||
|
||||
if let Ok(true) = model.main_patch.as_ref().unwrap_unchecked().is_applied(path) {
|
||||
String::new()
|
||||
} else {
|
||||
tr("patch-not-applied-tooltip")
|
||||
}
|
||||
}
|
||||
// TODO: add localizaion
|
||||
JadeitePatchStatusVariant::Broken => String::from("Current patch version doesn't work"),
|
||||
JadeitePatchStatusVariant::Unsafe => String::from("Current patch version is unsafe to use"),
|
||||
|
||||
_ => String::new()
|
||||
}
|
||||
|
||||
None => String::new()
|
||||
|
@ -365,29 +336,6 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
}
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
adw::ActionRow {
|
||||
set_title: &tr("ask-superuser-permissions"),
|
||||
set_subtitle: &tr("ask-superuser-permissions-description"),
|
||||
|
||||
add_suffix = >k::Switch {
|
||||
set_valign: gtk::Align::Center,
|
||||
|
||||
set_state: CONFIG.patch.root,
|
||||
|
||||
connect_state_notify => |switch| {
|
||||
if is_ready() {
|
||||
if let Ok(mut config) = Config::get() {
|
||||
config.patch.root = switch.state();
|
||||
|
||||
Config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_title: &tr("options"),
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ use relm4::component::*;
|
|||
use gtk::prelude::*;
|
||||
use adw::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::anime_game_core::prelude::*;
|
||||
use anime_launcher_sdk::anime_game_core::star_rail::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::config::ConfigExt;
|
||||
|
@ -30,7 +31,7 @@ pub enum PreferencesAppMsg {
|
|||
|
||||
/// Supposed to be called automatically on app's run when the latest main patch version
|
||||
/// was retrieved from remote repos
|
||||
SetMainPatch(Option<MainPatch>),
|
||||
SetMainPatch(Option<(Version, JadeitePatchStatusVariant)>),
|
||||
|
||||
SetLauncherStyle(LauncherStyle),
|
||||
|
||||
|
@ -131,7 +132,6 @@ impl SimpleAsyncComponent for PreferencesApp {
|
|||
PreferencesAppMsg::UpdateLauncherState => {
|
||||
sender.output(Self::Output::UpdateLauncherState {
|
||||
perform_on_download_needed: false,
|
||||
apply_patch_if_needed: false,
|
||||
show_status_page: false
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue