mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-11-22 04:46:08 +03:00
feat: made migrate installation button work
This commit is contained in:
parent
285195954e
commit
567df16610
4 changed files with 153 additions and 35 deletions
|
@ -42,6 +42,7 @@ components-index = Components index
|
|||
patch-folder = Patch folder
|
||||
temp-folder = Temp folder
|
||||
|
||||
migrate = Migrate
|
||||
|
||||
select-voice-packages = Select voice packages
|
||||
|
||||
|
|
|
@ -5,14 +5,19 @@ use adw::prelude::*;
|
|||
|
||||
use anime_launcher_sdk::config;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::*;
|
||||
use crate::i18n::*;
|
||||
use super::main::*;
|
||||
use crate::ui::components::progress_bar::*;
|
||||
|
||||
pub struct DefaultPathsApp {
|
||||
progress_bar: AsyncController<ProgressBar>,
|
||||
|
||||
show_additional: bool,
|
||||
migrate_installation: bool,
|
||||
show_progress: bool,
|
||||
|
||||
launcher: PathBuf,
|
||||
runners: PathBuf,
|
||||
|
@ -50,7 +55,8 @@ pub enum DefaultPathsAppMsg {
|
|||
|
||||
#[relm4::component(async, pub)]
|
||||
impl SimpleAsyncComponent for DefaultPathsApp {
|
||||
type Init = ();
|
||||
/// If `true`, then use migrate installation mode
|
||||
type Init = bool;
|
||||
type Input = DefaultPathsAppMsg;
|
||||
type Output = FirstRunAppMsg;
|
||||
|
||||
|
@ -72,6 +78,9 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
set_valign: gtk::Align::End,
|
||||
set_vexpand: true,
|
||||
|
||||
#[watch]
|
||||
set_sensitive: !model.show_progress,
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: &tr("launcher-folder"),
|
||||
set_icon_name: Some("folder-symbolic"),
|
||||
|
@ -107,6 +116,9 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
#[watch]
|
||||
set_visible: model.show_additional,
|
||||
|
||||
#[watch]
|
||||
set_sensitive: !model.show_progress,
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: &tr("runners-folder"),
|
||||
set_icon_name: Some("folder-symbolic"),
|
||||
|
@ -211,36 +223,75 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
#[watch]
|
||||
set_visible: !model.show_progress,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_halign: gtk::Align::Center,
|
||||
set_spacing: 8,
|
||||
|
||||
gtk::Button {
|
||||
set_label: &tr("continue"),
|
||||
set_label: &if model.migrate_installation {
|
||||
tr("migrate")
|
||||
} else {
|
||||
tr("continue")
|
||||
},
|
||||
|
||||
set_css_classes: &["suggested-action", "pill"],
|
||||
|
||||
connect_clicked => DefaultPathsAppMsg::Continue
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: &tr("exit"),
|
||||
set_label: &if model.migrate_installation {
|
||||
tr("close")
|
||||
} else {
|
||||
tr("exit")
|
||||
},
|
||||
|
||||
add_css_class: "pill",
|
||||
|
||||
connect_clicked => DefaultPathsAppMsg::Exit
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_vexpand: true,
|
||||
|
||||
#[watch]
|
||||
set_visible: model.show_progress,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_halign: gtk::Align::Center,
|
||||
|
||||
append = model.progress_bar.widget(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn init(
|
||||
_init: Self::Init,
|
||||
init: Self::Init,
|
||||
root: Self::Root,
|
||||
_sender: AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
let model = Self {
|
||||
progress_bar: ProgressBar::builder()
|
||||
.launch(ProgressBarInit {
|
||||
caption: None,
|
||||
display_progress: true,
|
||||
display_fraction: false,
|
||||
visible: false
|
||||
})
|
||||
.detach(),
|
||||
|
||||
show_additional: false,
|
||||
migrate_installation: init,
|
||||
show_progress: false,
|
||||
|
||||
launcher: LAUNCHER_FOLDER.to_path_buf(),
|
||||
runners: CONFIG.game.wine.builds.clone(),
|
||||
|
@ -256,6 +307,9 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
temp: CONFIG.launcher.temp.clone().unwrap_or(std::env::temp_dir())
|
||||
};
|
||||
|
||||
// Set progress bar width
|
||||
model.progress_bar.widget().set_width_request(400);
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
AsyncComponentParts { model, widgets }
|
||||
|
@ -303,17 +357,95 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
|
||||
#[allow(unused_must_use)]
|
||||
DefaultPathsAppMsg::Continue => {
|
||||
match self.update_config() {
|
||||
Ok(_) => sender.output(Self::Output::ScrollToSelectVoiceovers),
|
||||
let old_config = config::get().unwrap_or_else(|_| CONFIG.clone());
|
||||
|
||||
Err(err) => sender.output(Self::Output::Toast {
|
||||
title: tr("config-update-error"),
|
||||
description: Some(err.to_string())
|
||||
})
|
||||
};
|
||||
match self.update_config() {
|
||||
Ok(_) => {
|
||||
if self.migrate_installation {
|
||||
self.progress_bar.sender().send(ProgressBarMsg::SetVisible(true));
|
||||
|
||||
self.show_progress = true;
|
||||
|
||||
let folders = [
|
||||
(old_config.game.wine.builds, &self.runners),
|
||||
(old_config.game.dxvk.builds, &self.dxvks),
|
||||
(old_config.game.wine.prefix, &self.prefix),
|
||||
(old_config.game.path.global, &self.game_global),
|
||||
(old_config.game.path.china, &self.game_china),
|
||||
(old_config.components.path, &self.components),
|
||||
(old_config.patch.path, &self.patch),
|
||||
|
||||
(old_config.game.enhancements.fps_unlocker.path, &self.fps_unlocker)
|
||||
];
|
||||
|
||||
fn move_folder(from: &Path, to: &Path) -> std::io::Result<()> {
|
||||
if !to.exists() {
|
||||
std::fs::create_dir_all(to);
|
||||
}
|
||||
|
||||
for entry in from.read_dir()?.flatten() {
|
||||
let to_path = to.join(entry.file_name());
|
||||
|
||||
if entry.metadata()?.is_dir() {
|
||||
move_folder(&entry.path(), &to_path)?;
|
||||
}
|
||||
|
||||
else if entry.metadata()?.is_file() {
|
||||
std::fs::copy(entry.path(), &to_path);
|
||||
}
|
||||
|
||||
// TODO: symlinks?
|
||||
}
|
||||
|
||||
std::fs::remove_dir_all(from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::expect_fun_call)]
|
||||
for (i, (from, to)) in folders.iter().enumerate() {
|
||||
self.progress_bar.sender().send(ProgressBarMsg::UpdateCaption(Some(
|
||||
from.to_str().map(|str| str.to_string()).unwrap_or_else(|| format!("{:?}", from))
|
||||
)));
|
||||
|
||||
if &from != to && from.exists() {
|
||||
move_folder(from, to).expect(&format!("Failed to move folder: {:?} -> {:?}", from, to));
|
||||
}
|
||||
|
||||
self.progress_bar.sender().send(ProgressBarMsg::UpdateProgress(i as u64 + 1, folders.len() as u64));
|
||||
}
|
||||
|
||||
// Restart the app
|
||||
|
||||
std::process::Command::new(std::env::current_exe().unwrap()).spawn().unwrap();
|
||||
|
||||
relm4::main_application().quit();
|
||||
}
|
||||
|
||||
else {
|
||||
sender.output(Self::Output::ScrollToSelectVoiceovers);
|
||||
}
|
||||
}
|
||||
|
||||
Err(err) => {
|
||||
sender.output(Self::Output::Toast {
|
||||
title: tr("config-update-error"),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefaultPathsAppMsg::Exit => relm4::main_application().quit()
|
||||
DefaultPathsAppMsg::Exit => {
|
||||
if self.migrate_installation {
|
||||
// TODO: this shit should return message to general preferences component somehow to close MigrateInstallation window
|
||||
todo!();
|
||||
}
|
||||
|
||||
else {
|
||||
relm4::main_application().quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ impl SimpleComponent for FirstRunApp {
|
|||
.forward(sender.input_sender(), std::convert::identity),
|
||||
|
||||
default_paths: DefaultPathsApp::builder()
|
||||
.launch(())
|
||||
.launch(false)
|
||||
.forward(sender.input_sender(), std::convert::identity),
|
||||
|
||||
select_voiceovers: SelectVoiceoversApp::builder()
|
||||
|
|
|
@ -2,9 +2,6 @@ use relm4::prelude::*;
|
|||
use relm4::component::*;
|
||||
|
||||
use gtk::prelude::*;
|
||||
use adw::prelude::*;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use super::first_run::default_paths::DefaultPathsApp;
|
||||
|
||||
|
@ -12,21 +9,17 @@ pub struct MigrateInstallationApp {
|
|||
default_paths: AsyncController<DefaultPathsApp>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MigrateInstallationAppMsg {
|
||||
Migrate
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for MigrateInstallationApp {
|
||||
type Init = ();
|
||||
type Input = MigrateInstallationAppMsg;
|
||||
type Input = ();
|
||||
type Output = ();
|
||||
|
||||
view! {
|
||||
adw::Window {
|
||||
set_default_size: (780, 560),
|
||||
set_modal: true,
|
||||
set_hide_on_close: true,
|
||||
|
||||
#[watch]
|
||||
set_title: Some("Migrate installation"),
|
||||
|
@ -46,13 +39,13 @@ impl SimpleComponent for MigrateInstallationApp {
|
|||
fn init(
|
||||
_init: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
_sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
tracing::info!("Initializing migration window");
|
||||
|
||||
let model = Self {
|
||||
default_paths: DefaultPathsApp::builder()
|
||||
.launch(())
|
||||
.launch(true)
|
||||
.detach()
|
||||
};
|
||||
|
||||
|
@ -60,12 +53,4 @@ impl SimpleComponent for MigrateInstallationApp {
|
|||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
|
||||
match msg {
|
||||
MigrateInstallationAppMsg::Migrate => {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue