From f31e31ef812684d3b18e6e6f02e44b32327694a9 Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Mon, 27 Feb 2023 23:19:25 +0200 Subject: [PATCH] feat: added update predownloading support --- assets/locales/de/main.ftl | 1 + assets/locales/en/main.ftl | 1 + assets/locales/ru/main.ftl | 1 + src/ui/main.rs | 83 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+) diff --git a/assets/locales/de/main.ftl b/assets/locales/de/main.ftl index 0c30720..13070c4 100644 --- a/assets/locales/de/main.ftl +++ b/assets/locales/de/main.ftl @@ -31,6 +31,7 @@ download-wine = Wine Herunterladen create-prefix = Prefix erstellen update = Updaten download = Herunterladen +predownload-update = Pre-download {$version} update ({$size}) main-window--patch-unavailable-tooltip = Die Patch-Server sind nicht verfügbar und der Launcher kann den Patch-Status des Spiels nicht überprüfen. Du darfst das Spiel auf eigene Gefahr spielen. main-window--patch-outdated-tooltip = Der Patch ist veraltet oder befindet sich in Vorbereitung und kann daher nicht verwendet werden. Kehren Sie später zurück, um den Status zu sehen. diff --git a/assets/locales/en/main.ftl b/assets/locales/en/main.ftl index c252d24..ae571eb 100644 --- a/assets/locales/en/main.ftl +++ b/assets/locales/en/main.ftl @@ -31,6 +31,7 @@ download-wine = Download wine create-prefix = Create prefix update = Update download = Download +predownload-update = Pre-download {$version} update ({$size}) main-window--patch-unavailable-tooltip = Patch servers are unavailable and launcher can't verify the game's patching status. You're allowed to run the game on your own risk main-window--patch-outdated-tooltip = Patch is outdated or in preparation state, so unavailable for usage. Return back later to see its status diff --git a/assets/locales/ru/main.ftl b/assets/locales/ru/main.ftl index eed7333..865f7fc 100644 --- a/assets/locales/ru/main.ftl +++ b/assets/locales/ru/main.ftl @@ -38,6 +38,7 @@ download-wine = Установить Wine create-prefix = Создать префикс update = Обновить download = Установить +predownload-update = Предустановить обновление {$version} ({$size}) main-window--patch-unavailable-tooltip = Серверы патча недоступны и лаунчер не может проверить статус патча игры. Вам разрешено запустить игру на ваш страх и риск main-window--patch-outdated-tooltip = Патч устарел или находится в процессе разработки, поэтому не может быть применен. Возвращайтесь позже чтобы проверить его статус diff --git a/src/ui/main.rs b/src/ui/main.rs index abb5495..45306a7 100644 --- a/src/ui/main.rs +++ b/src/ui/main.rs @@ -77,6 +77,8 @@ pub enum AppMsg { ClosePreferences, SetDownloading(bool), DisableButtons(bool), + + PredownloadUpdate, PerformAction, Toast { @@ -253,6 +255,46 @@ impl SimpleComponent for App { // TODO: add tooltips + gtk::Button { + #[watch] + set_width_request: match model.style { + LauncherStyle::Modern => -1, + LauncherStyle::Classic => 40 + }, + + #[watch] + set_tooltip_text: Some(&tr_args("predownload-update", [ + ("version", match model.state.as_ref() { + Some(LauncherState::PredownloadAvailable { game, .. }) => game.latest().to_string(), + _ => String::from("?") + }.into()), + + ("size", match model.state.as_ref() { + Some(LauncherState::PredownloadAvailable { game, voices }) => { + let mut size = game.size().unwrap_or((0, 0)).0; + + for voice in voices { + size += voice.size().unwrap_or((0, 0)).0; + } + + prettify_bytes(size) + } + + _ => String::from("?") + }.into()) + ])), + + #[watch] + set_visible: matches!(model.state.as_ref(), Some(LauncherState::PredownloadAvailable { .. })), + + set_icon_name: "document-save-symbolic", + add_css_class: "warning", + + set_hexpand: false, + + connect_clicked => AppMsg::PredownloadUpdate + }, + gtk::Button { #[watch] set_label: &match model.state { @@ -656,6 +698,47 @@ impl SimpleComponent for App { self.disabled_buttons = state; } + #[allow(unused_must_use)] + AppMsg::PredownloadUpdate => { + if let Some(LauncherState::PredownloadAvailable { game, mut voices }) = self.state.clone() { + let tmp = config::get().unwrap().launcher.temp.unwrap_or_else(|| PathBuf::from("/tmp")); + + self.downloading = true; + + let progress_bar_input = self.progress_bar.sender().clone(); + + progress_bar_input.send(ProgressBarMsg::UpdateCaption(Some(tr("downloading")))); + + let mut diffs: Vec = vec![game]; + + diffs.append(&mut voices); + + std::thread::spawn(move || { + for mut diff in diffs { + let result = diff.download_in(&tmp, clone!(@strong progress_bar_input => move |curr, total| { + progress_bar_input.send(ProgressBarMsg::UpdateProgress(curr, total)); + })); + + if let Err(err) = result { + let err: std::io::Error = err.into(); + + sender.input(AppMsg::Toast { + title: tr("downloading-failed"), + description: Some(err.to_string()) + }); + + break; + } + } + + sender.input(AppMsg::UpdateLauncherState { + perform_on_download_needed: false, + show_status_page: true + }); + }); + } + } + AppMsg::PerformAction => unsafe { match self.state.as_ref().unwrap_unchecked() { LauncherState::PatchAvailable(Patch::NotAvailable) |