feat: checkbox to delete profile dirs along with profile
Some checks failed
/ cargo-fmtcheck (push) Has been cancelled
/ cargo-clippy (push) Has been cancelled
/ cargo-test (push) Has been cancelled
/ appimage (push) Has been cancelled

This commit is contained in:
Gabriele Musco 2025-04-29 14:22:27 +02:00
commit c794037377
3 changed files with 55 additions and 7 deletions

View file

@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fmt::Display,
fs::File,
fs::{remove_dir_all, File},
io::BufReader,
path::{Path, PathBuf},
slice::Iter,
@ -450,6 +450,29 @@ impl Profile {
get_data_dir().join("prefixes").join(uuid)
}
/// deletes files and folders associated to this profile (mostly repo clones)
pub fn delete_files(&self) -> Vec<std::io::Result<()>> {
[
Some(&self.xrservice_path),
Some(&self.ovr_comp.path),
self.features.libsurvive.path.as_ref(),
self.features.basalt.path.as_ref(),
self.features.openhmd.path.as_ref(),
]
.iter()
.map(|dir| match dir {
Some(dir) => {
if dir.try_exists().unwrap_or_default() {
remove_dir_all(dir)
} else {
Ok(())
}
}
None => Ok(()),
})
.collect()
}
pub fn xr_runtime_json_env_var(&self) -> String {
format!(
"XR_RUNTIME_JSON=\"{prefix}/share/openxr/1/openxr_{runtime}.json\"",

View file

@ -113,7 +113,8 @@ pub enum Msg {
StartWithDebug,
RestartXRService,
ProfileSelected(Profile),
DeleteProfile,
/// bool param: delete files
DeleteProfile(bool),
SaveProfile(Profile),
RunSetCap,
OpenLibsurviveSetup,
@ -658,9 +659,16 @@ impl AsyncComponent for App {
w.stop();
}
}
Msg::DeleteProfile => {
Msg::DeleteProfile(delete_files) => {
let todel = self.get_selected_profile();
if todel.editable {
if delete_files {
for res in todel.delete_files() {
if let Err(e) = res {
error!("Error deleting profile directory: {e}");
}
}
}
self.config.user_profiles.retain(|p| p.uuid != todel.uuid);
self.config.save();
self.profiles = self.config.profiles();
@ -1007,7 +1015,7 @@ impl AsyncComponent for App {
MainViewOutMsg::DoStartStopXRService => Msg::DoStartStopXRService,
MainViewOutMsg::RestartXRService => Msg::RestartXRService,
MainViewOutMsg::ProfileSelected(uuid) => Msg::ProfileSelected(uuid),
MainViewOutMsg::DeleteProfile => Msg::DeleteProfile,
MainViewOutMsg::DeleteProfile(delete_files) => Msg::DeleteProfile(delete_files),
MainViewOutMsg::SaveProfile(p) => Msg::SaveProfile(p),
MainViewOutMsg::OpenLibsurviveSetup => Msg::OpenLibsurviveSetup,
MainViewOutMsg::BuildProfile(clean) => Msg::BuildProfile(clean),

View file

@ -112,7 +112,8 @@ pub enum MainViewOutMsg {
DoStartStopXRService,
RestartXRService,
ProfileSelected(Profile),
DeleteProfile,
/// bool param: delete files
DeleteProfile(bool),
SaveProfile(Profile),
OpenLibsurviveSetup,
/// params: clean
@ -931,6 +932,13 @@ impl AsyncComponent for MainView {
let profile_delete_confirm_dialog = adw::AlertDialog::builder()
.heading("Are you sure you want to delete this profile?")
.extra_child(
&gtk::CheckButton::builder()
.label("Delete all files and folders associated with profile")
.halign(gtk::Align::Center)
.hexpand(true)
.build(),
)
.build();
profile_delete_confirm_dialog.add_response("no", "_No");
profile_delete_confirm_dialog.add_response("yes", "_Yes");
@ -942,10 +950,19 @@ impl AsyncComponent for MainView {
clone!(
#[strong]
sender,
move |_, res| {
move |dialog, res| {
let delete_files_checkbox = dialog
.extra_child()
.and_then(|child| child.downcast::<gtk::CheckButton>().ok());
let delete_files = delete_files_checkbox
.as_ref()
.is_some_and(|c| c.is_active());
if let Some(check) = delete_files_checkbox {
check.set_active(false);
}
if res == "yes" {
sender
.output(Self::Output::DeleteProfile)
.output(Self::Output::DeleteProfile(delete_files))
.expect("Sender output failed");
}
}