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

Also loading icon was replaced by a `GtkSpinner` in components downloading page
This commit is contained in:
Observer KRypt0n_ 2023-02-24 19:23:49 +02:00
parent 7e2059a33e
commit 6024ef885e
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
4 changed files with 142 additions and 5 deletions

View file

@ -13,6 +13,7 @@ use std::path::PathBuf;
use super::main::FirstRunAppMsg;
use crate::ui::components::*;
use crate::i18n::*;
use crate::FIRST_RUN_FILE;
fn get_installer(uri: &str, temp: Option<&PathBuf>, speed_limit: u64) -> anyhow::Result<Installer> {
let mut installer = Installer::new(uri)?;
@ -159,8 +160,15 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[watch]
set_icon_name: match model.downloading_wine {
Some(true) => Some("emblem-ok"),
Some(false) => Some("process-working"),
Some(false) => None, // Some("process-working"),
None => None
},
add_prefix = &gtk::Spinner {
set_spinning: true,
#[watch]
set_visible: model.downloading_wine == Some(false),
}
},
@ -170,8 +178,15 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[watch]
set_icon_name: match model.creating_prefix {
Some(true) => Some("emblem-ok"),
Some(false) => Some("process-working"),
Some(false) => None, // Some("process-working"),
None => None
},
add_prefix = &gtk::Spinner {
set_spinning: true,
#[watch]
set_visible: model.creating_prefix == Some(false),
}
},
@ -181,8 +196,15 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[watch]
set_icon_name: match model.downloading_dxvk {
Some(true) => Some("emblem-ok"),
Some(false) => Some("process-working"),
Some(false) => None, // Some("process-working"),
None => None
},
add_prefix = &gtk::Spinner {
set_spinning: true,
#[watch]
set_visible: model.downloading_dxvk == Some(false),
}
},
@ -192,8 +214,15 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[watch]
set_icon_name: match model.applying_dxvk {
Some(true) => Some("emblem-ok"),
Some(false) => Some("process-working"),
Some(false) => None, // Some("process-working"),
None => None
},
add_prefix = &gtk::Spinner {
set_spinning: true,
#[watch]
set_visible: model.applying_dxvk == Some(false),
}
}
},
@ -480,6 +509,8 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[allow(unused_must_use)]
DownloadComponentsAppMsg::Continue => {
std::fs::remove_file(FIRST_RUN_FILE.as_path());
sender.output(Self::Output::ScrollToFinish);
}

View file

@ -0,0 +1,98 @@
use relm4::prelude::*;
use relm4::component::*;
use adw::prelude::*;
use crate::i18n::*;
use super::main::*;
pub struct FinishApp;
#[derive(Debug, Clone)]
pub enum FinishAppMsg {
Restart,
Exit
}
#[relm4::component(async, pub)]
impl SimpleAsyncComponent for FinishApp {
type Init = ();
type Input = FinishAppMsg;
type Output = FirstRunAppMsg;
view! {
adw::PreferencesPage {
set_hexpand: true,
add = &adw::PreferencesGroup {
set_valign: gtk::Align::Center,
set_vexpand: true,
gtk::Label {
set_label: "Everything's done!",
add_css_class: "title-1"
},
gtk::Label {
set_label: "All the basic components were downloaded. Now you can restart the launcher and download the game. Welcome to our club!",
set_justify: gtk::Justification::Center,
set_wrap: true,
set_margin_top: 32
}
},
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: "Restart",
set_css_classes: &["suggested-action", "pill"],
connect_clicked => FinishAppMsg::Restart
},
gtk::Button {
set_label: "Exit",
add_css_class: "pill",
connect_clicked => FinishAppMsg::Exit
}
}
}
}
}
async fn init(
_init: Self::Init,
root: Self::Root,
_sender: AsyncComponentSender<Self>,
) -> AsyncComponentParts<Self> {
let model = Self;
let widgets = view_output!();
AsyncComponentParts { model, widgets }
}
async fn update(&mut self, msg: Self::Input, _sender: AsyncComponentSender<Self>) {
match msg {
FinishAppMsg::Restart => {
std::process::Command::new(std::env::current_exe().unwrap()).spawn().unwrap();
// TODO: relm4 has some function for it
std::process::exit(0);
}
FinishAppMsg::Exit => {
// TODO: relm4 has some function for it
std::process::exit(0);
}
}
}
}

View file

@ -12,6 +12,7 @@ use super::dependencies::*;
use super::default_paths::*;
use super::select_voiceovers::*;
use super::download_components::*;
use super::finish::*;
pub static mut MAIN_WINDOW: Option<adw::Window> = None;
@ -22,6 +23,7 @@ pub struct FirstRunApp {
default_paths: AsyncController<DefaultPathsApp>,
select_voiceovers: AsyncController<SelectVoiceoversApp>,
download_components: AsyncController<DownloadComponentsApp>,
finish: AsyncController<FinishApp>,
toast_overlay: adw::ToastOverlay,
carousel: adw::Carousel,
@ -76,6 +78,7 @@ impl SimpleComponent for FirstRunApp {
append = model.default_paths.widget(),
append = model.select_voiceovers.widget(),
append = model.download_components.widget(),
append = model.finish.widget(),
},
adw::CarouselIndicatorDots {
@ -122,6 +125,10 @@ impl SimpleComponent for FirstRunApp {
.launch(())
.forward(sender.input_sender(), std::convert::identity),
finish: FinishApp::builder()
.launch(())
.forward(sender.input_sender(), std::convert::identity),
toast_overlay,
carousel,
@ -179,7 +186,7 @@ impl SimpleComponent for FirstRunApp {
FirstRunAppMsg::ScrollToFinish => {
self.title = String::from("Finish");
self.carousel.scroll_to(self.welcome.widget(), true);
self.carousel.scroll_to(self.finish.widget(), true);
}
FirstRunAppMsg::Toast { title, description } => unsafe {

View file

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