Components list: added on_downloaded / deleted events

This commit is contained in:
Observer KRypt0n_ 2023-02-03 17:23:17 +02:00
parent 7ba025489d
commit 2a96982fd7
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
8 changed files with 86 additions and 35 deletions

View file

@ -13,7 +13,6 @@ pub use prettify_bytes::prettify_bytes;
pub const APP_ID: &str = "moe.launcher.an-anime-game-launcher-gtk";
pub const APP_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const APP_DEBUG: bool = cfg!(debug_assertions);
/// Sets to `true` when the `App` component is ready (fully initialized)
pub static mut READY: bool = false;
@ -25,6 +24,8 @@ pub fn is_ready() -> bool {
}
lazy_static::lazy_static! {
pub static ref APP_DEBUG: bool = cfg!(debug_assertions) || std::env::args().any(|arg| &arg == "--debug");
/// Config loaded on the app's start. Use `config::get()` to get up to date config instead.
/// This one is used to prepare some launcher UI components on start
pub static ref CONFIG: config::Config = config::get().expect("Failed to load config");
@ -58,10 +59,10 @@ lazy_static::lazy_static! {
fn main() {
tracing_subscriber::fmt()
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL)
.with_max_level(if APP_DEBUG {
.with_max_level(if *APP_DEBUG {
tracing::Level::TRACE
} else {
tracing::Level::INFO
tracing::Level::WARN
})
.init();

View file

@ -36,7 +36,7 @@ impl SimpleComponent for AboutDialog {
set_version: &{
// Debug build & build's version doesn't contain any suffix (-dev, -beta, etc)
if crate::APP_DEBUG && !crate::APP_VERSION.contains('-') {
if *crate::APP_DEBUG && !crate::APP_VERSION.contains('-') {
format!("{}-dev", crate::APP_VERSION)
}

View file

@ -13,14 +13,16 @@ pub struct ComponentGroup {
#[derive(Debug)]
pub enum AppMsg {
ShowRecommendedOnly(bool)
ShowRecommendedOnly(bool),
CallOnDownloaded,
CallOnDeleted
}
#[relm4::component(pub)]
impl SimpleComponent for ComponentGroup {
type Init = (super::ComponentsListGroup, PathBuf);
type Input = AppMsg;
type Output = ();
type Output = super::list::AppMsg;
view! {
group = adw::ExpanderRow {
@ -31,7 +33,7 @@ impl SimpleComponent for ComponentGroup {
fn init(
init: Self::Init,
root: &Self::Root,
_sender: ComponentSender<Self>,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = ComponentGroup {
title: init.0.title,
@ -42,7 +44,7 @@ impl SimpleComponent for ComponentGroup {
.map(|version| {
super::ComponentVersion::builder()
.launch((version, init.1.clone()))
.detach()
.forward(sender.input_sender(), std::convert::identity)
})
.collect()
};
@ -56,7 +58,7 @@ impl SimpleComponent for ComponentGroup {
ComponentParts { model, widgets }
}
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
tracing::debug!("Called component group [{}] event: {:?}", self.title, msg);
match msg {
@ -68,6 +70,16 @@ impl SimpleComponent for ComponentGroup {
version.sender().send(super::version::AppMsg::ShowRecommendedOnly(state)).unwrap();
}
}
#[allow(unused_must_use)]
AppMsg::CallOnDownloaded => {
sender.output(super::list::AppMsg::CallOnDownloaded);
}
#[allow(unused_must_use)]
AppMsg::CallOnDeleted => {
sender.output(super::list::AppMsg::CallOnDeleted);
}
}
}
}

View file

@ -2,22 +2,32 @@ use relm4::prelude::*;
use adw::prelude::*;
#[derive(Debug, Clone)]
pub struct ComponentsListInit {
pub pattern: super::ComponentsListPattern,
pub on_downloaded: Option<crate::ui::preferences::main::AppMsg>,
pub on_deleted: Option<crate::ui::preferences::main::AppMsg>
}
pub struct ComponentsList {
pub show_recommended_only: bool,
pub init: ComponentsListInit,
pub groups: Vec<Controller<super::ComponentGroup>>
}
#[derive(Debug)]
pub enum AppMsg {
ShowRecommendedOnly(bool)
ShowRecommendedOnly(bool),
CallOnDownloaded,
CallOnDeleted
}
#[relm4::component(pub)]
impl SimpleComponent for ComponentsList {
type Init = super::ComponentsListPattern;
type Init = ComponentsListInit;
type Input = AppMsg;
type Output = ();
type Output = crate::ui::preferences::main::AppMsg;
view! {
group = adw::PreferencesGroup {}
@ -26,17 +36,20 @@ impl SimpleComponent for ComponentsList {
fn init(
init: Self::Init,
root: &Self::Root,
_sender: ComponentSender<Self>,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let init_copy = init.clone();
let model = ComponentsList {
show_recommended_only: true,
init: init_copy,
groups: init.groups
groups: init.pattern.groups
.into_iter()
.map(|group| {
super::ComponentGroup::builder()
.launch((group, init.download_folder.clone()))
.detach()
.launch((group, init.pattern.download_folder.clone()))
.forward(sender.input_sender(), std::convert::identity)
})
.collect()
};
@ -50,7 +63,7 @@ impl SimpleComponent for ComponentsList {
ComponentParts { model, widgets }
}
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
tracing::debug!("Called components list event: {:?}", msg);
match msg {
@ -62,6 +75,16 @@ impl SimpleComponent for ComponentsList {
group.sender().send(super::group::AppMsg::ShowRecommendedOnly(state)).unwrap();
}
}
#[allow(unused_must_use)]
AppMsg::CallOnDownloaded => if let Some(on_downloaded) = self.init.on_downloaded {
sender.output(on_downloaded);
}
#[allow(unused_must_use)]
AppMsg::CallOnDeleted => if let Some(on_deleted) = self.init.on_deleted {
sender.output(on_deleted);
}
}
}
}

View file

@ -50,7 +50,7 @@ impl SimpleComponent for ProgressBar {
#[watch]
set_text: match model.caption.as_ref() {
Some(caption) => Some({
if let Some((curr, total)) = &model.downloaded {
if let Some((_curr, _total)) = &model.downloaded {
// caption.push_str(&format!(": {:.2}% ({curr} of {total})", model.fraction));
}

View file

@ -44,7 +44,7 @@ pub enum AppMsg {
impl SimpleComponent for ComponentVersion {
type Init = (super::ComponentsListVersion, PathBuf);
type Input = AppMsg;
type Output = ();
type Output = super::group::AppMsg;
view! {
row = adw::ActionRow {
@ -128,8 +128,12 @@ impl SimpleComponent for ComponentVersion {
// todo
std::fs::remove_dir_all(path).expect("Failed to delete component");
}
self.state = VersionState::NotDownloaded;
self.state = VersionState::NotDownloaded;
#[allow(unused_must_use)] {
sender.output(super::group::AppMsg::CallOnDeleted);
}
}
@ -158,11 +162,14 @@ impl SimpleComponent for ComponentVersion {
Update::UnpackingError(_) => {
progress_bar_sender.send(ProgressBarMsg::SetVisible(false));
sender.input(AppMsg::SetState(if let Update::UnpackingFinished = &state {
VersionState::Downloaded
} else {
VersionState::NotDownloaded
}));
if let Update::UnpackingFinished = &state {
sender.input(AppMsg::SetState(VersionState::Downloaded));
sender.output(super::group::AppMsg::CallOnDownloaded);
}
else {
sender.input(AppMsg::SetState(VersionState::NotDownloaded));
}
},
_ => ()

View file

@ -142,7 +142,7 @@ impl SimpleComponent for App {
let widgets = view_output!();
if crate::APP_DEBUG {
if *crate::APP_DEBUG {
widgets.main_window.add_css_class("devel");
}

View file

@ -21,7 +21,7 @@ pub struct App {
selected_dxvk_version: u32
}
#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
pub enum AppMsg {
WineRecommendedOnly(bool),
DxvkRecommendedOnly(bool),
@ -111,18 +111,26 @@ impl SimpleComponent for App {
let model = App {
wine_components: ComponentsList::builder()
.launch(ComponentsListPattern {
download_folder: CONFIG.game.wine.builds.clone(),
groups: wine::get_groups().into_iter().map(|group| group.into()).collect()
.launch(ComponentsListInit {
pattern: ComponentsListPattern {
download_folder: CONFIG.game.wine.builds.clone(),
groups: wine::get_groups().into_iter().map(|group| group.into()).collect()
},
on_downloaded: Some(AppMsg::UpdateDownloadedWine),
on_deleted: Some(AppMsg::UpdateDownloadedWine)
})
.detach(),
.forward(sender.input_sender(), std::convert::identity),
dxvk_components: ComponentsList::builder()
.launch(ComponentsListPattern {
download_folder: CONFIG.game.dxvk.builds.clone(),
groups: dxvk::get_groups().into_iter().map(|group| group.into()).collect()
.launch(ComponentsListInit {
pattern: ComponentsListPattern {
download_folder: CONFIG.game.dxvk.builds.clone(),
groups: dxvk::get_groups().into_iter().map(|group| group.into()).collect()
},
on_downloaded: Some(AppMsg::UpdateDownloadedDxvk),
on_deleted: Some(AppMsg::UpdateDownloadedDxvk)
})
.detach(),
.forward(sender.input_sender(), std::convert::identity),
downloaded_wine_versions: vec![],
downloaded_dxvk_versions: vec![],