mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-11-28 09:58:46 +03:00
Several changes
- updated core library and components library - added (likely working) updates pre-downloading functionality - moved to `anyhow::Result` in lots of places
This commit is contained in:
parent
7ac3935ab1
commit
002c77a9c1
23 changed files with 160 additions and 58 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -31,7 +31,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anime-game-core"
|
name = "anime-game-core"
|
||||||
version = "1.1.0"
|
version = "1.1.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bzip2",
|
"bzip2",
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6adbca88936bcb16d10063fe58688cc7b10813b2
|
Subproject commit e2140cea392560ac685088d6cc6295ad1172cb72
|
|
@ -64,6 +64,16 @@ Adw.ApplicationWindow window {
|
||||||
margin-top: 64;
|
margin-top: 64;
|
||||||
spacing: 8;
|
spacing: 8;
|
||||||
|
|
||||||
|
Gtk.Button predownload_game {
|
||||||
|
icon-name: "document-save-symbolic";
|
||||||
|
tooltip-text: "Pre-download 3.1.0 update (15 GB)";
|
||||||
|
|
||||||
|
hexpand: false;
|
||||||
|
visible: false;
|
||||||
|
|
||||||
|
styles ["warning"]
|
||||||
|
}
|
||||||
|
|
||||||
Gtk.Button launch_game {
|
Gtk.Button launch_game {
|
||||||
label: "Launch";
|
label: "Launch";
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 59f7158df2b9a339fd62d4ee124f0ece47751e6b
|
Subproject commit 6ae731151cf1562877e5cb84896f3b5d3f001c6c
|
|
@ -1,7 +1,7 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::io::{Error, ErrorKind, Write};
|
use std::io::Write;
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::Value as JsonValue;
|
||||||
|
@ -39,7 +39,7 @@ static mut CONFIG: Option<Config> = None;
|
||||||
/// This method will load config from file once and store it into the memory.
|
/// This method will load config from file once and store it into the memory.
|
||||||
/// If you know that the config file was updated - you should run `get_raw` method
|
/// If you know that the config file was updated - you should run `get_raw` method
|
||||||
/// that always loads config directly from the file. This will also update in-memory config
|
/// that always loads config directly from the file. This will also update in-memory config
|
||||||
pub fn get() -> Result<Config, Error> {
|
pub fn get() -> anyhow::Result<Config> {
|
||||||
unsafe {
|
unsafe {
|
||||||
match &CONFIG {
|
match &CONFIG {
|
||||||
Some(config) => Ok(config.clone()),
|
Some(config) => Ok(config.clone()),
|
||||||
|
@ -51,7 +51,7 @@ pub fn get() -> Result<Config, Error> {
|
||||||
/// Get config data
|
/// Get config data
|
||||||
///
|
///
|
||||||
/// This method will always load data directly from the file and update in-memory config
|
/// This method will always load data directly from the file and update in-memory config
|
||||||
pub fn get_raw() -> Result<Config, Error> {
|
pub fn get_raw() -> anyhow::Result<Config> {
|
||||||
match config_file() {
|
match config_file() {
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
// Try to read config if the file exists
|
// Try to read config if the file exists
|
||||||
|
@ -71,7 +71,7 @@ pub fn get_raw() -> Result<Config, Error> {
|
||||||
|
|
||||||
Ok(config)
|
Ok(config)
|
||||||
},
|
},
|
||||||
Err(err) => Err(Error::new(ErrorKind::InvalidData, format!("Failed to decode data from json format: {}", err.to_string())))
|
Err(err) => Err(anyhow::anyhow!("Failed to decode data from json format: {}", err.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ pub fn get_raw() -> Result<Config, Error> {
|
||||||
Ok(Config::default())
|
Ok(Config::default())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Err(Error::new(ErrorKind::NotFound, format!("Failed to get config file path")))
|
None => Err(anyhow::anyhow!("Failed to get config file path"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ pub fn update(config: Config) {
|
||||||
/// Update config file
|
/// Update config file
|
||||||
///
|
///
|
||||||
/// This method will also update in-memory config data
|
/// This method will also update in-memory config data
|
||||||
pub fn update_raw(config: Config) -> Result<(), Error> {
|
pub fn update_raw(config: Config) -> anyhow::Result<()> {
|
||||||
update(config.clone());
|
update(config.clone());
|
||||||
|
|
||||||
match config_file() {
|
match config_file() {
|
||||||
|
@ -111,19 +111,19 @@ pub fn update_raw(config: Config) -> Result<(), Error> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
Err(err) => Err(Error::new(ErrorKind::InvalidData, format!("Failed to encode data into json format: {}", err.to_string())))
|
Err(err) => Err(anyhow::anyhow!("Failed to encode data into json format: {}", err.to_string()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Err(Error::new(ErrorKind::NotFound, format!("Failed to get config file path")))
|
None => Err(anyhow::anyhow!("Failed to get config file path"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update config file from the in-memory saved config
|
/// Update config file from the in-memory saved config
|
||||||
pub fn flush() -> Result<(), Error> {
|
pub fn flush() -> anyhow::Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
match &CONFIG {
|
match &CONFIG {
|
||||||
Some(config) => update_raw(config.clone()),
|
Some(config) => update_raw(config.clone()),
|
||||||
None => Err(Error::new(ErrorKind::Other, "Config wasn't loaded into the memory"))
|
None => Err(anyhow::anyhow!("Config wasn't loaded into the memory"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl Version {
|
||||||
std::path::Path::new(&format!("{}/{}", folder.to_string(), self.name)).exists()
|
std::path::Path::new(&format!("{}/{}", folder.to_string(), self.name)).exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply<T: ToString>(&self, dxvks_folder: T, prefix_path: T) -> std::io::Result<Output> {
|
pub fn apply<T: ToString>(&self, dxvks_folder: T, prefix_path: T) -> anyhow::Result<Output> {
|
||||||
let apply_path = format!("{}/{}/setup_dxvk.sh", dxvks_folder.to_string(), self.name);
|
let apply_path = format!("{}/{}/setup_dxvk.sh", dxvks_folder.to_string(), self.name);
|
||||||
let config = config::get()?;
|
let config = config::get()?;
|
||||||
|
|
||||||
|
@ -95,13 +95,18 @@ impl Version {
|
||||||
None => (String::from("wine64"), String::from("wineserver"), String::from("wineboot"))
|
None => (String::from("wine64"), String::from("wineserver"), String::from("wineboot"))
|
||||||
};
|
};
|
||||||
|
|
||||||
Dxvk::install(
|
let result = Dxvk::install(
|
||||||
PathBuf::from(apply_path),
|
PathBuf::from(apply_path),
|
||||||
PathBuf::from(prefix_path.to_string()),
|
PathBuf::from(prefix_path.to_string()),
|
||||||
PathBuf::from(&wine_path),
|
PathBuf::from(&wine_path),
|
||||||
PathBuf::from(wine_path),
|
PathBuf::from(wine_path),
|
||||||
PathBuf::from(wineboot_path),
|
PathBuf::from(wineboot_path),
|
||||||
PathBuf::from(wineserver_path)
|
PathBuf::from(wineserver_path)
|
||||||
)
|
);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(output) => Ok(output),
|
||||||
|
Err(err) => Err(err.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl DxvkRow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply<T: ToString>(&self, dxvks_folder: T, prefix_path: T) -> std::io::Result<std::process::Output> {
|
pub fn apply<T: ToString>(&self, dxvks_folder: T, prefix_path: T) -> anyhow::Result<std::process::Output> {
|
||||||
self.button.set_sensitive(false);
|
self.button.set_sensitive(false);
|
||||||
self.apply_button.set_sensitive(false);
|
self.apply_button.set_sensitive(false);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new(window: gtk::Window) -> Result<Self, String> {
|
pub fn new(window: gtk::Window) -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/default_paths.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/default_paths.ui");
|
||||||
|
|
||||||
let result = Self {
|
let result = Self {
|
||||||
|
@ -62,10 +62,7 @@ impl Page {
|
||||||
exit_button: get_object(&builder, "exit_button")?
|
exit_button: get_object(&builder, "exit_button")?
|
||||||
};
|
};
|
||||||
|
|
||||||
let config = match config::get() {
|
let config = config::get()?;
|
||||||
Ok(config) => config,
|
|
||||||
Err(err) => return Err(err.to_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add paths to subtitles
|
// Add paths to subtitles
|
||||||
result.runners_folder.set_subtitle(&config.game.wine.builds);
|
result.runners_folder.set_subtitle(&config.game.wine.builds);
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/dependencies.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/dependencies.ui");
|
||||||
|
|
||||||
let result = Self {
|
let result = Self {
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/download_components.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/download_components.ui");
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/finish.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/finish.ui");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub struct AppWidgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWidgets {
|
impl AppWidgets {
|
||||||
pub fn try_get() -> Result<Self, String> {
|
pub fn try_get() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run.ui");
|
||||||
|
|
||||||
let result = Self {
|
let result = Self {
|
||||||
|
@ -131,7 +131,7 @@ pub struct App {
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
/// Create new application
|
/// Create new application
|
||||||
pub fn new(app: >k::Application) -> Result<Self, String> {
|
pub fn new(app: >k::Application) -> anyhow::Result<Self> {
|
||||||
// Get default widgets from ui file and add events to them
|
// Get default widgets from ui file and add events to them
|
||||||
let result = Self {
|
let result = Self {
|
||||||
widgets: AppWidgets::try_get()?,
|
widgets: AppWidgets::try_get()?,
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/tos_warning.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/tos_warning.ui");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/voice_packages.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/voice_packages.ui");
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub struct Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/welcome.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/first_run/welcome.ui");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
105
src/ui/main.rs
105
src/ui/main.rs
|
@ -30,6 +30,7 @@ use crate::lib::wine::{
|
||||||
Version as WineVersion,
|
Version as WineVersion,
|
||||||
List as WineList
|
List as WineList
|
||||||
};
|
};
|
||||||
|
use crate::lib::prettify_bytes::prettify_bytes;
|
||||||
|
|
||||||
/// This structure is used to describe widgets used in application
|
/// This structure is used to describe widgets used in application
|
||||||
///
|
///
|
||||||
|
@ -49,6 +50,7 @@ pub struct AppWidgets {
|
||||||
pub launcher_content: adw::PreferencesPage,
|
pub launcher_content: adw::PreferencesPage,
|
||||||
|
|
||||||
pub icon: gtk::Image,
|
pub icon: gtk::Image,
|
||||||
|
pub predownload_game: gtk::Button,
|
||||||
pub launch_game: gtk::Button,
|
pub launch_game: gtk::Button,
|
||||||
pub open_preferences: gtk::Button,
|
pub open_preferences: gtk::Button,
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ pub struct AppWidgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWidgets {
|
impl AppWidgets {
|
||||||
pub fn try_get() -> Result<Self, String> {
|
pub fn try_get() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/main.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/main.ui");
|
||||||
|
|
||||||
let window = get_object::<adw::ApplicationWindow>(&builder, "window")?;
|
let window = get_object::<adw::ApplicationWindow>(&builder, "window")?;
|
||||||
|
@ -76,6 +78,7 @@ impl AppWidgets {
|
||||||
launcher_content: get_object(&builder, "launcher_content")?,
|
launcher_content: get_object(&builder, "launcher_content")?,
|
||||||
|
|
||||||
icon: get_object(&builder, "icon")?,
|
icon: get_object(&builder, "icon")?,
|
||||||
|
predownload_game: get_object(&builder, "predownload_game")?,
|
||||||
launch_game: get_object(&builder, "launch_game")?,
|
launch_game: get_object(&builder, "launch_game")?,
|
||||||
open_preferences: get_object(&builder, "open_preferences")?,
|
open_preferences: get_object(&builder, "open_preferences")?,
|
||||||
|
|
||||||
|
@ -150,6 +153,7 @@ pub enum Actions {
|
||||||
OpenPreferencesPage,
|
OpenPreferencesPage,
|
||||||
PreferencesGoBack,
|
PreferencesGoBack,
|
||||||
PerformButtonEvent,
|
PerformButtonEvent,
|
||||||
|
PredownloadUpdate,
|
||||||
RepairGame,
|
RepairGame,
|
||||||
ShowProgressBar,
|
ShowProgressBar,
|
||||||
UpdateProgress { fraction: Rc<f64>, title: Rc<String> },
|
UpdateProgress { fraction: Rc<f64>, title: Rc<String> },
|
||||||
|
@ -195,7 +199,7 @@ pub struct App {
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
/// Create new application
|
/// Create new application
|
||||||
pub fn new(app: >k::Application) -> Result<Self, String> {
|
pub fn new(app: >k::Application) -> anyhow::Result<Self> {
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
widgets: AppWidgets::try_get()?,
|
widgets: AppWidgets::try_get()?,
|
||||||
values: Default::default(),
|
values: Default::default(),
|
||||||
|
@ -256,6 +260,9 @@ impl App {
|
||||||
// Go back button for preferences page
|
// Go back button for preferences page
|
||||||
self.widgets.preferences_stack.preferences_go_back.connect_clicked(Actions::PreferencesGoBack.into_fn(&self));
|
self.widgets.preferences_stack.preferences_go_back.connect_clicked(Actions::PreferencesGoBack.into_fn(&self));
|
||||||
|
|
||||||
|
// Predownload update
|
||||||
|
self.widgets.predownload_game.connect_clicked(Actions::PredownloadUpdate.into_fn(&self));
|
||||||
|
|
||||||
// Launch game
|
// Launch game
|
||||||
self.widgets.launch_game.connect_clicked(Actions::PerformButtonEvent.into_fn(&self));
|
self.widgets.launch_game.connect_clicked(Actions::PerformButtonEvent.into_fn(&self));
|
||||||
|
|
||||||
|
@ -593,6 +600,61 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Actions::PredownloadUpdate => {
|
||||||
|
let values = this.values.take();
|
||||||
|
let state = values.state.clone();
|
||||||
|
|
||||||
|
this.values.set(values);
|
||||||
|
|
||||||
|
match config::get() {
|
||||||
|
Ok(config) => {
|
||||||
|
match state {
|
||||||
|
LauncherState::PredownloadAvailable { game, mut voices } => {
|
||||||
|
let (sender, receiver) = glib::MainContext::channel::<InstallerUpdate>(glib::PRIORITY_DEFAULT);
|
||||||
|
|
||||||
|
let mut diffs: Vec<VersionDiff> = vec![game];
|
||||||
|
|
||||||
|
diffs.append(&mut voices);
|
||||||
|
|
||||||
|
this.widgets.progress_bar.show();
|
||||||
|
|
||||||
|
std::thread::spawn(clone!(@strong this => move || {
|
||||||
|
for mut diff in diffs {
|
||||||
|
let sender = sender.clone();
|
||||||
|
|
||||||
|
#[allow(unused_must_use)]
|
||||||
|
let result = diff.download_in(config.launcher.temp.as_ref().unwrap(), move |curr, total| {
|
||||||
|
sender.send(InstallerUpdate::DownloadingProgress(curr, total));
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Err(err) = result {
|
||||||
|
let err: Error = err.into();
|
||||||
|
|
||||||
|
this.update(Actions::Toast(Rc::new((
|
||||||
|
String::from("Downloading failed"), err.to_string()
|
||||||
|
)))).unwrap();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.update(Actions::HideProgressBar).unwrap();
|
||||||
|
}));
|
||||||
|
|
||||||
|
receiver.attach(None, clone!(@strong this => move |state| {
|
||||||
|
this.widgets.progress_bar.update_from_state(state);
|
||||||
|
|
||||||
|
glib::Continue(true)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => this.toast("Failed to load config", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Actions::RepairGame => {
|
Actions::RepairGame => {
|
||||||
match config::get() {
|
match config::get() {
|
||||||
Ok(config) => {
|
Ok(config) => {
|
||||||
|
@ -812,14 +874,49 @@ impl App {
|
||||||
self.widgets.launch_game.remove_css_class("warning");
|
self.widgets.launch_game.remove_css_class("warning");
|
||||||
self.widgets.launch_game.remove_css_class("destructive-action");
|
self.widgets.launch_game.remove_css_class("destructive-action");
|
||||||
|
|
||||||
|
self.widgets.predownload_game.hide();
|
||||||
|
|
||||||
match &state {
|
match &state {
|
||||||
LauncherState::Launch => {
|
LauncherState::Launch => {
|
||||||
self.widgets.launch_game.set_label("Launch");
|
self.widgets.launch_game.set_label("Launch");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
LauncherState::PredownloadAvailable { game, voices } => {
|
||||||
LauncherState::PredownloadAvailable { .. } => {
|
|
||||||
self.widgets.launch_game.set_label("Launch");
|
self.widgets.launch_game.set_label("Launch");
|
||||||
|
|
||||||
|
// Calculate size of the update
|
||||||
|
let size =
|
||||||
|
game.size().unwrap_or((0, 0)).0 +
|
||||||
|
voices.into_iter().fold(0, |acc, voice| acc + voice.size().unwrap_or((0, 0)).0);
|
||||||
|
|
||||||
|
// Update tooltip
|
||||||
|
self.widgets.predownload_game.set_tooltip_text(Some(&format!("Pre-download {} update ({})", game.latest(), prettify_bytes(size))));
|
||||||
|
|
||||||
|
// Prepare button's color
|
||||||
|
self.widgets.predownload_game.remove_css_class("success");
|
||||||
|
self.widgets.predownload_game.add_css_class("warning");
|
||||||
|
self.widgets.predownload_game.set_sensitive(true);
|
||||||
|
|
||||||
|
if let Ok(config) = config::get() {
|
||||||
|
if let Some(temp) = config.launcher.temp {
|
||||||
|
let tmp = PathBuf::from(temp);
|
||||||
|
|
||||||
|
// If all the files were downloaded
|
||||||
|
let downloaded =
|
||||||
|
tmp.join(game.file_name().unwrap()).exists() &&
|
||||||
|
voices.into_iter().fold(true, move |acc, voice| acc && tmp.join(voice.file_name().unwrap()).exists());
|
||||||
|
|
||||||
|
if downloaded {
|
||||||
|
self.widgets.predownload_game.remove_css_class("warning");
|
||||||
|
self.widgets.predownload_game.add_css_class("success");
|
||||||
|
self.widgets.predownload_game.set_sensitive(false);
|
||||||
|
|
||||||
|
self.widgets.predownload_game.set_tooltip_text(Some(&format!("{} update is predownloaded ({})", game.latest(), prettify_bytes(size))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.widgets.predownload_game.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
LauncherState::PatchAvailable(patch) => {
|
LauncherState::PatchAvailable(patch) => {
|
||||||
|
|
|
@ -11,10 +11,10 @@ pub use first_run::App as FirstRunApp;
|
||||||
pub use main::App as MainApp;
|
pub use main::App as MainApp;
|
||||||
|
|
||||||
/// This function loads object from builder or panics if it doesn't exist
|
/// This function loads object from builder or panics if it doesn't exist
|
||||||
pub fn get_object<T: IsA<gtk::glib::Object>>(builder: >k::Builder, name: &str) -> Result<T, String> {
|
pub fn get_object<T: IsA<gtk::glib::Object>>(builder: >k::Builder, name: &str) -> anyhow::Result<T> {
|
||||||
match builder.object::<T>(name) {
|
match builder.object::<T>(name) {
|
||||||
Some(object) => Ok(object),
|
Some(object) => Ok(object),
|
||||||
None => Err(format!("Failed to parse object '{}'", name))
|
None => Err(anyhow::anyhow!("Failed to parse object '{name}'"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub struct AppWidgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWidgets {
|
impl AppWidgets {
|
||||||
fn try_get(window: &adw::ApplicationWindow) -> Result<Self, String> {
|
fn try_get(window: &adw::ApplicationWindow) -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/enhancements.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/enhancements.ui");
|
||||||
|
|
||||||
let result = Self {
|
let result = Self {
|
||||||
|
@ -123,7 +123,7 @@ pub struct App {
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
/// Create new application
|
/// Create new application
|
||||||
pub fn new(window: &adw::ApplicationWindow) -> Result<Self, String> {
|
pub fn new(window: &adw::ApplicationWindow) -> anyhow::Result<Self> {
|
||||||
let result = Self {
|
let result = Self {
|
||||||
widgets: AppWidgets::try_get(window)?
|
widgets: AppWidgets::try_get(window)?
|
||||||
}.init_events();
|
}.init_events();
|
||||||
|
@ -301,7 +301,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method is being called by the `PreferencesStack::update`
|
/// This method is being called by the `PreferencesStack::update`
|
||||||
pub fn prepare(&self, status_page: &adw::StatusPage) -> std::io::Result<()> {
|
pub fn prepare(&self, status_page: &adw::StatusPage) -> anyhow::Result<()> {
|
||||||
let config = config::get()?;
|
let config = config::get()?;
|
||||||
|
|
||||||
status_page.set_description(Some("Loading enhancements..."));
|
status_page.set_description(Some("Loading enhancements..."));
|
||||||
|
|
|
@ -7,7 +7,6 @@ use gtk::glib::clone;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::io::Error;
|
|
||||||
|
|
||||||
use crate::ui::get_object;
|
use crate::ui::get_object;
|
||||||
use crate::lib::config;
|
use crate::lib::config;
|
||||||
|
@ -31,7 +30,7 @@ pub struct AppWidgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWidgets {
|
impl AppWidgets {
|
||||||
fn try_get() -> Result<Self, String> {
|
fn try_get() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/environment.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/environment.ui");
|
||||||
|
|
||||||
let result = Self {
|
let result = Self {
|
||||||
|
@ -89,7 +88,7 @@ pub struct App {
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
/// Create new application
|
/// Create new application
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let result = Self {
|
let result = Self {
|
||||||
widgets: AppWidgets::try_get()?,
|
widgets: AppWidgets::try_get()?,
|
||||||
values: Default::default(),
|
values: Default::default(),
|
||||||
|
@ -225,7 +224,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method is being called by the `PreferencesStack::update`
|
/// This method is being called by the `PreferencesStack::update`
|
||||||
pub fn prepare(&self, status_page: &adw::StatusPage) -> Result<(), Error> {
|
pub fn prepare(&self, status_page: &adw::StatusPage) -> anyhow::Result<()> {
|
||||||
let config = config::get()?;
|
let config = config::get()?;
|
||||||
|
|
||||||
status_page.set_description(Some("Loading environment..."));
|
status_page.set_description(Some("Loading environment..."));
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub struct AppWidgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWidgets {
|
impl AppWidgets {
|
||||||
fn try_get(window: &adw::ApplicationWindow) -> Result<Self, String> {
|
fn try_get(window: &adw::ApplicationWindow) -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/gamescope.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/gamescope.ui");
|
||||||
|
|
||||||
let result = Self {
|
let result = Self {
|
||||||
|
@ -79,7 +79,7 @@ pub struct App {
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
/// Create new application
|
/// Create new application
|
||||||
pub fn new(window: &adw::ApplicationWindow) -> Result<Self, String> {
|
pub fn new(window: &adw::ApplicationWindow) -> anyhow::Result<Self> {
|
||||||
let result = Self {
|
let result = Self {
|
||||||
widgets: AppWidgets::try_get(window)?
|
widgets: AppWidgets::try_get(window)?
|
||||||
}.init_events();
|
}.init_events();
|
||||||
|
@ -221,7 +221,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method is being called by the `EnhancementsPage::prepare`
|
/// This method is being called by the `EnhancementsPage::prepare`
|
||||||
pub fn prepare(&self, status_page: &adw::StatusPage) -> std::io::Result<()> {
|
pub fn prepare(&self, status_page: &adw::StatusPage) -> anyhow::Result<()> {
|
||||||
let config = config::get()?;
|
let config = config::get()?;
|
||||||
|
|
||||||
status_page.set_description(Some("Loading gamescope..."));
|
status_page.set_description(Some("Loading gamescope..."));
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub struct AppWidgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWidgets {
|
impl AppWidgets {
|
||||||
pub fn try_get() -> Result<Self, String> {
|
pub fn try_get() -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/general.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/preferences/general.ui");
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
|
@ -84,16 +84,10 @@ impl AppWidgets {
|
||||||
dxvk_components: Default::default()
|
dxvk_components: Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let config = match config::get() {
|
let config = config::get()?;
|
||||||
Ok(config) => config,
|
|
||||||
Err(err) => return Err(err.to_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update voiceovers list
|
// Update voiceovers list
|
||||||
let voice_packages = match VoicePackage::list_latest() {
|
let voice_packages = VoicePackage::list_latest()?;
|
||||||
Ok(voice_packages) => voice_packages,
|
|
||||||
Err(err) => return Err(err.to_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut components = Vec::new();
|
let mut components = Vec::new();
|
||||||
|
|
||||||
|
@ -197,7 +191,7 @@ pub struct App {
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
/// Create new application
|
/// Create new application
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let result = Self {
|
let result = Self {
|
||||||
app: Default::default(),
|
app: Default::default(),
|
||||||
widgets: AppWidgets::try_get()?,
|
widgets: AppWidgets::try_get()?,
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub struct PreferencesStack {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PreferencesStack {
|
impl PreferencesStack {
|
||||||
pub fn new(window: &adw::ApplicationWindow) -> Result<Self, String> {
|
pub fn new(window: &adw::ApplicationWindow) -> anyhow::Result<Self> {
|
||||||
let builder = gtk::Builder::from_resource("/org/app/ui/preferences.ui");
|
let builder = gtk::Builder::from_resource("/org/app/ui/preferences.ui");
|
||||||
|
|
||||||
let result = Self {
|
let result = Self {
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub trait DownloadComponent {
|
||||||
Path::new(&self.get_component_path(installation_path)).exists()
|
Path::new(&self.get_component_path(installation_path)).exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn download<T: ToString>(&self, installation_path: T) -> std::io::Result<Await<DownloadingResult>> {
|
fn download<T: ToString>(&self, installation_path: T) -> anyhow::Result<Await<DownloadingResult>> {
|
||||||
let (sender, receiver) = glib::MainContext::channel::<InstallerUpdate>(glib::PRIORITY_DEFAULT);
|
let (sender, receiver) = glib::MainContext::channel::<InstallerUpdate>(glib::PRIORITY_DEFAULT);
|
||||||
let (progress_bar, button) = self.get_downloading_widgets();
|
let (progress_bar, button) = self.get_downloading_widgets();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue