mirror of
https://github.com/13hannes11/toolbx-tuner.git
synced 2024-09-03 23:21:00 +02:00
periodically update toolboxes and show spinner when this is happening
This commit is contained in:
76
src/app.rs
76
src/app.rs
@@ -1,5 +1,7 @@
|
|||||||
use crate::gtk::Align;
|
use crate::gtk::Align;
|
||||||
|
use crate::gtk::Spinner;
|
||||||
use crate::util::toolbox::ToolbxContainer;
|
use crate::util::toolbox::ToolbxContainer;
|
||||||
|
use relm4::adw::prelude::PreferencesGroupExt;
|
||||||
use relm4::factory::FactoryHashMap;
|
use relm4::factory::FactoryHashMap;
|
||||||
use relm4::gtk::PolicyType;
|
use relm4::gtk::PolicyType;
|
||||||
use relm4::RelmWidgetExt;
|
use relm4::RelmWidgetExt;
|
||||||
@@ -8,6 +10,9 @@ use relm4::{
|
|||||||
adw, gtk, main_application, Component, ComponentController, ComponentParts, ComponentSender,
|
adw, gtk, main_application, Component, ComponentController, ComponentParts, ComponentSender,
|
||||||
Controller,
|
Controller,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use gtk::prelude::{
|
use gtk::prelude::{
|
||||||
ApplicationExt, ApplicationWindowExt, GtkWindowExt, OrientableExt, SettingsExt, WidgetExt,
|
ApplicationExt, ApplicationWindowExt, GtkWindowExt, OrientableExt, SettingsExt, WidgetExt,
|
||||||
@@ -24,6 +29,7 @@ pub(super) struct App {
|
|||||||
unsupported_dialog: Controller<UnsupportedDialog>,
|
unsupported_dialog: Controller<UnsupportedDialog>,
|
||||||
about_dialog: Controller<AboutDialog>,
|
about_dialog: Controller<AboutDialog>,
|
||||||
containers: FactoryHashMap<String, Container>,
|
containers: FactoryHashMap<String, Container>,
|
||||||
|
refresh_spinner: Spinner,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -34,6 +40,7 @@ pub enum AppMsg {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) enum AppCommandMsg {
|
pub(super) enum AppCommandMsg {
|
||||||
PrerequisitsInstalled(bool),
|
PrerequisitsInstalled(bool),
|
||||||
|
UpdateToolboxes(Vec<ToolbxContainer>),
|
||||||
}
|
}
|
||||||
|
|
||||||
relm4::new_action_group!(pub(super) WindowActionGroup, "win");
|
relm4::new_action_group!(pub(super) WindowActionGroup, "win");
|
||||||
@@ -100,13 +107,22 @@ impl Component for App {
|
|||||||
set_vexpand: true,
|
set_vexpand: true,
|
||||||
set_hscrollbar_policy: PolicyType::Never,
|
set_hscrollbar_policy: PolicyType::Never,
|
||||||
|
|
||||||
#[local_ref]
|
adw::PreferencesGroup{
|
||||||
container_box -> gtk::ListBox {
|
set_title: "Toolboxes",
|
||||||
set_size_request: (200, -1),
|
|
||||||
set_selection_mode: gtk::SelectionMode::None,
|
|
||||||
set_valign: Align::Start,
|
|
||||||
set_margin_all: 30,
|
set_margin_all: 30,
|
||||||
set_css_classes: &["boxed-list"],
|
|
||||||
|
|
||||||
|
set_header_suffix: Some(
|
||||||
|
&model.refresh_spinner
|
||||||
|
),
|
||||||
|
|
||||||
|
#[local_ref]
|
||||||
|
container_box -> gtk::ListBox {
|
||||||
|
set_size_request: (200, -1),
|
||||||
|
set_selection_mode: gtk::SelectionMode::None,
|
||||||
|
set_valign: Align::Start,
|
||||||
|
set_css_classes: &["boxed-list"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -132,22 +148,15 @@ impl Component for App {
|
|||||||
UnsupportedDialogOutput::CloseApplication => AppMsg::Quit,
|
UnsupportedDialogOutput::CloseApplication => AppMsg::Quit,
|
||||||
});
|
});
|
||||||
|
|
||||||
let toolboxes = ToolbxContainer::get_toolboxes();
|
let containers = FactoryHashMap::builder().launch_default().detach();
|
||||||
|
|
||||||
let mut containers = FactoryHashMap::builder().launch_default().detach();
|
let refresh_spinner = gtk::Spinner::new();
|
||||||
toolboxes.iter().for_each(|toolbox| {
|
|
||||||
&containers.insert(
|
|
||||||
toolbox.id.clone(),
|
|
||||||
ContainerInit {
|
|
||||||
name: toolbox.name.clone(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let model = Self {
|
let model = Self {
|
||||||
about_dialog,
|
about_dialog,
|
||||||
unsupported_dialog,
|
unsupported_dialog,
|
||||||
containers,
|
containers,
|
||||||
|
refresh_spinner,
|
||||||
};
|
};
|
||||||
|
|
||||||
let container_box = model.containers.widget();
|
let container_box = model.containers.widget();
|
||||||
@@ -192,15 +201,48 @@ impl Component for App {
|
|||||||
fn update_cmd(
|
fn update_cmd(
|
||||||
&mut self,
|
&mut self,
|
||||||
message: Self::CommandOutput,
|
message: Self::CommandOutput,
|
||||||
_sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
_: &Self::Root,
|
_: &Self::Root,
|
||||||
) {
|
) {
|
||||||
match message {
|
match message {
|
||||||
AppCommandMsg::PrerequisitsInstalled(false) => {
|
AppCommandMsg::PrerequisitsInstalled(false) => {
|
||||||
self.unsupported_dialog.sender().clone().send(()).unwrap()
|
self.unsupported_dialog.sender().clone().send(()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
AppCommandMsg::PrerequisitsInstalled(true) => {
|
AppCommandMsg::PrerequisitsInstalled(true) => {
|
||||||
// TODO: start process of fetching toolboxes
|
// TODO: start process of fetching toolboxes
|
||||||
|
self.refresh_spinner.set_spinning(true);
|
||||||
|
sender.spawn_oneshot_command(|| {
|
||||||
|
AppCommandMsg::UpdateToolboxes(ToolbxContainer::get_toolboxes())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
AppCommandMsg::UpdateToolboxes(toolboxes) => {
|
||||||
|
let mut updated_containers = HashSet::<String>::new();
|
||||||
|
toolboxes.iter().for_each(|toolbox| {
|
||||||
|
self.containers.insert(
|
||||||
|
toolbox.id.clone(),
|
||||||
|
ContainerInit {
|
||||||
|
name: toolbox.name.clone(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
updated_containers.insert(toolbox.id.clone());
|
||||||
|
});
|
||||||
|
let obsolete_containers: Vec<String> = self
|
||||||
|
.containers
|
||||||
|
.iter()
|
||||||
|
.map(|(hash, _)| hash.clone())
|
||||||
|
.filter(|hash| !updated_containers.contains(hash))
|
||||||
|
.collect();
|
||||||
|
obsolete_containers.into_iter().for_each(|hash| {
|
||||||
|
self.containers.remove(&hash);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.refresh_spinner.set_spinning(false);
|
||||||
|
|
||||||
|
sender.spawn_oneshot_command(|| {
|
||||||
|
sleep(Duration::from_millis(2000));
|
||||||
|
AppCommandMsg::PrerequisitsInstalled(true)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fmt::Display, iter::zip, process::Command, str::FromStr, string::ParseError, sync::Arc};
|
use std::{fmt::Display, process::Command, str::FromStr};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum ToolbxError {
|
pub enum ToolbxError {
|
||||||
|
|||||||
Reference in New Issue
Block a user