feat(ui): added voiceover selection page to the first run window

This commit is contained in:
Observer KRypt0n_ 2023-02-24 18:21:03 +02:00
parent 5d1633efe1
commit 7e2059a33e
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
5 changed files with 213 additions and 10 deletions

View file

@ -258,7 +258,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
#[allow(unused_must_use)]
DefaultPathsAppMsg::Continue => {
match self.update_config() {
Ok(_) => sender.output(Self::Output::ScrollToDownloadComponents),
Ok(_) => sender.output(Self::Output::ScrollToSelectVoiceovers),
Err(err) => sender.output(Self::Output::Toast {
title: tr("config-update-error"),

View file

@ -12,6 +12,7 @@ use std::path::PathBuf;
use super::main::FirstRunAppMsg;
use crate::ui::components::*;
use crate::i18n::*;
fn get_installer(uri: &str, temp: Option<&PathBuf>, speed_limit: u64) -> anyhow::Result<Installer> {
let mut installer = Installer::new(uri)?;
@ -302,7 +303,20 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
}
// Create prefix
InstallerUpdate::UnpackingFinished => sender.input(DownloadComponentsAppMsg::CreatePrefix),
InstallerUpdate::UnpackingFinished => {
let mut config = config::get().unwrap_or_default();
config.game.wine.selected = Some(wine.name.clone());
if let Err(err) = config::update_raw(config) {
sender.output(Self::Output::Toast {
title: tr("config-update-error"),
description: Some(err.to_string())
});
}
sender.input(DownloadComponentsAppMsg::CreatePrefix);
},
_ => ()
}
@ -466,7 +480,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[allow(unused_must_use)]
DownloadComponentsAppMsg::Continue => {
sender.output(Self::Output::ScrollToChooseVoiceovers);
sender.output(Self::Output::ScrollToFinish);
}
DownloadComponentsAppMsg::Exit => {

View file

@ -10,6 +10,7 @@ use super::welcome::*;
use super::tos_warning::*;
use super::dependencies::*;
use super::default_paths::*;
use super::select_voiceovers::*;
use super::download_components::*;
pub static mut MAIN_WINDOW: Option<adw::Window> = None;
@ -19,6 +20,7 @@ pub struct FirstRunApp {
tos_warning: AsyncController<TosWarningApp>,
dependencies: AsyncController<DependenciesApp>,
default_paths: AsyncController<DefaultPathsApp>,
select_voiceovers: AsyncController<SelectVoiceoversApp>,
download_components: AsyncController<DownloadComponentsApp>,
toast_overlay: adw::ToastOverlay,
@ -32,8 +34,8 @@ pub enum FirstRunAppMsg {
ScrollToTosWarning,
ScrollToDependencies,
ScrollToDefaultPaths,
ScrollToSelectVoiceovers,
ScrollToDownloadComponents,
ScrollToChooseVoiceovers,
ScrollToFinish,
Toast {
@ -72,6 +74,7 @@ impl SimpleComponent for FirstRunApp {
append = model.tos_warning.widget(),
append = model.dependencies.widget(),
append = model.default_paths.widget(),
append = model.select_voiceovers.widget(),
append = model.download_components.widget(),
},
@ -111,6 +114,10 @@ impl SimpleComponent for FirstRunApp {
.launch(())
.forward(sender.input_sender(), std::convert::identity),
select_voiceovers: SelectVoiceoversApp::builder()
.launch(())
.forward(sender.input_sender(), std::convert::identity),
download_components: DownloadComponentsApp::builder()
.launch(())
.forward(sender.input_sender(), std::convert::identity),
@ -157,18 +164,18 @@ impl SimpleComponent for FirstRunApp {
self.carousel.scroll_to(self.default_paths.widget(), true);
}
FirstRunAppMsg::ScrollToSelectVoiceovers => {
self.title = String::from("Select voiceovers");
self.carousel.scroll_to(self.select_voiceovers.widget(), true);
}
FirstRunAppMsg::ScrollToDownloadComponents => {
self.title = String::from("Download components");
self.carousel.scroll_to(self.download_components.widget(), true);
}
FirstRunAppMsg::ScrollToChooseVoiceovers => {
self.title = String::from("Select voiceovers");
self.carousel.scroll_to(self.welcome.widget(), true);
}
FirstRunAppMsg::ScrollToFinish => {
self.title = String::from("Finish");

View file

@ -3,4 +3,5 @@ pub mod welcome;
pub mod tos_warning;
pub mod dependencies;
pub mod default_paths;
pub mod select_voiceovers;
pub mod download_components;

View file

@ -0,0 +1,181 @@
use relm4::prelude::*;
use relm4::component::*;
use adw::prelude::*;
use anime_launcher_sdk::config;
use crate::i18n::*;
use super::main::*;
pub struct SelectVoiceoversApp {
english: gtk::Switch,
japanese: gtk::Switch,
korean: gtk::Switch,
chinese: gtk::Switch
}
#[derive(Debug, Clone)]
pub enum SelectVoiceoversAppMsg {
Continue,
Exit
}
#[relm4::component(async, pub)]
impl SimpleAsyncComponent for SelectVoiceoversApp {
type Init = ();
type Input = SelectVoiceoversAppMsg;
type Output = FirstRunAppMsg;
view! {
adw::PreferencesPage {
set_hexpand: true,
add = &adw::PreferencesGroup {
set_valign: gtk::Align::Center,
set_vexpand: true,
gtk::Label {
set_label: "Select voice packages",
add_css_class: "title-1"
}
},
add = &adw::PreferencesGroup {
set_valign: gtk::Align::Center,
set_vexpand: true,
adw::ActionRow {
set_title: "English",
#[local_ref]
add_suffix = english -> gtk::Switch {
set_valign: gtk::Align::Center,
set_state: true
}
},
adw::ActionRow {
set_title: "Japanese",
#[local_ref]
add_suffix = japanese -> gtk::Switch {
set_valign: gtk::Align::Center
}
},
adw::ActionRow {
set_title: "Korean",
#[local_ref]
add_suffix = korean -> gtk::Switch {
set_valign: gtk::Align::Center
}
},
adw::ActionRow {
set_title: "Chinese",
#[local_ref]
add_suffix = chinese -> gtk::Switch {
set_valign: gtk::Align::Center
}
}
},
add = &adw::PreferencesGroup {
set_valign: gtk::Align::Center,
set_vexpand: true,
gtk::Box {
set_orientation: gtk::Orientation::Horizontal,
set_halign: gtk::Align::Center,
set_spacing: 8,
gtk::Button {
set_label: "Continue",
set_css_classes: &["suggested-action", "pill"],
connect_clicked => SelectVoiceoversAppMsg::Continue
},
gtk::Button {
set_label: "Exit",
add_css_class: "pill",
connect_clicked => SelectVoiceoversAppMsg::Exit
}
}
}
}
}
async fn init(
_init: Self::Init,
root: Self::Root,
_sender: AsyncComponentSender<Self>,
) -> AsyncComponentParts<Self> {
let model = Self {
english: gtk::Switch::new(),
japanese: gtk::Switch::new(),
korean: gtk::Switch::new(),
chinese: gtk::Switch::new()
};
let english = &model.english;
let japanese = &model.japanese;
let korean = &model.korean;
let chinese = &model.chinese;
let widgets = view_output!();
AsyncComponentParts { model, widgets }
}
async fn update(&mut self, msg: Self::Input, sender: AsyncComponentSender<Self>) {
match msg {
#[allow(unused_must_use)]
SelectVoiceoversAppMsg::Continue => {
match self.update_config() {
Ok(_) => sender.output(Self::Output::ScrollToDownloadComponents),
Err(err) => sender.output(Self::Output::Toast {
title: tr("config-update-error"),
description: Some(err.to_string())
})
};
}
SelectVoiceoversAppMsg::Exit => {
// TODO: relm4 has some function for it
std::process::exit(0);
}
}
}
}
impl SelectVoiceoversApp {
pub fn update_config(&self) -> anyhow::Result<()> {
let mut config = config::get()?;
config.game.voices = Vec::new();
if self.english.state() {
config.game.voices.push(String::from("en-us"));
}
if self.japanese.state() {
config.game.voices.push(String::from("ja-jp"));
}
if self.korean.state() {
config.game.voices.push(String::from("ko-kr"));
}
if self.chinese.state() {
config.game.voices.push(String::from("zh-cn"));
}
config::update_raw(config)
}
}