Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 25 additions & 31 deletions core/src/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,18 @@ pub fn get_tabs(validate: bool) -> (TempDir, Vec<Tab>) {

let tabs: Vec<Tab> = tabs
.into_iter()
.map(
|(
TabEntry {
name,
data,
multi_selectable,
},
directory,
)| {
let mut tree = Tree::new(Rc::new(ListNode {
name: "root".to_string(),
description: String::new(),
command: Command::None,
task_list: String::new(),
}));
let mut root = tree.root_mut();
create_directory(data, &mut root, &directory, validate);
Tab {
name,
tree,
multi_selectable,
}
},
)
.map(|(TabEntry { name, data }, directory)| {
let mut tree = Tree::new(Rc::new(ListNode {
name: "root".to_string(),
description: String::new(),
command: Command::None,
task_list: String::new(),
multi_select: false,
}));
let mut root = tree.root_mut();
create_directory(data, &mut root, &directory, validate, true);
Tab { name, tree }
})
.collect();

if tabs.is_empty() {
Expand All @@ -74,12 +62,6 @@ struct TabList {
struct TabEntry {
name: String,
data: Vec<Entry>,
#[serde(default = "default_multi_selectable")]
multi_selectable: bool,
}

fn default_multi_selectable() -> bool {
true
}

#[derive(Deserialize)]
Expand All @@ -94,6 +76,12 @@ struct Entry {
entry_type: EntryType,
#[serde(default)]
task_list: String,
#[serde(default = "default_true")]
multi_select: bool,
}

fn default_true() -> bool {
true
}

#[derive(Deserialize)]
Expand Down Expand Up @@ -174,24 +162,29 @@ fn create_directory(
node: &mut NodeMut<Rc<ListNode>>,
command_dir: &Path,
validate: bool,
parent_multi_select: bool,
) {
for entry in data {
let multi_select = parent_multi_select && entry.multi_select;

match entry.entry_type {
EntryType::Entries(entries) => {
let mut node = node.append(Rc::new(ListNode {
name: entry.name,
description: entry.description,
command: Command::None,
task_list: String::new(),
multi_select,
}));
create_directory(entries, &mut node, command_dir, validate);
create_directory(entries, &mut node, command_dir, validate, multi_select);
}
EntryType::Command(command) => {
node.append(Rc::new(ListNode {
name: entry.name,
description: entry.description,
command: Command::Raw(command),
task_list: String::new(),
multi_select,
}));
}
EntryType::Script(script) => {
Expand All @@ -210,6 +203,7 @@ fn create_directory(
file: script,
},
task_list: entry.task_list,
multi_select,
}));
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ pub enum Command {
pub struct Tab {
pub name: String,
pub tree: Tree<Rc<ListNode>>,
pub multi_selectable: bool,
}

#[derive(Clone, Hash, Eq, PartialEq)]
Expand All @@ -32,4 +31,5 @@ pub struct ListNode {
pub description: String,
pub command: Command,
pub task_list: String,
pub multi_select: bool,
}
4 changes: 3 additions & 1 deletion core/tabs/system-setup/tab_data.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
name = "System Setup"
multi_selectable = false

[[data]]
name = "Arch Linux"
Expand All @@ -14,6 +13,7 @@ name = "Arch Server Setup"
description = "This command installs a minimal arch server setup under 5 minutes."
script = "arch/server-setup.sh"
task_list = "SI D"
multi_select = false

[[data.entries]]
name = "Paru AUR Helper"
Expand Down Expand Up @@ -82,12 +82,14 @@ name = "Full System Cleanup"
description = "This script is designed to remove unnecessary packages, clean old cache files, remove temporary files, and to empty the trash."
script = "system-cleanup.sh"
task_list = "RP PFM"
multi_select = false

[[data]]
name = "Full System Update"
description = "This command updates your system to the latest packages available for your distro"
script = "system-update.sh"
task_list = "PFM"
multi_select = false

[[data]]
name = "Gaming Dependencies"
Expand Down
5 changes: 4 additions & 1 deletion core/tabs/utils/tab_data.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name = "Utilities"
multi_selectable = false

[[data]]
name = "Monitor Control"
multi_select = false

[[data.preconditions]]
matches = true
Expand Down Expand Up @@ -78,6 +78,7 @@ script = "monitor-control/set_resolutions.sh"

[[data]]
name = "User Account Manager"
multi_select = false

[[data.entries]]
name = "Add User"
Expand All @@ -104,6 +105,7 @@ name = "Auto Mount Drive"
description = "This utility is designed to help with automating the process of mounting a drive on to your system."
script = "auto-mount.sh"
task_list = "PFM"
multi_select = false

[[data]]
name = "Auto Login"
Expand All @@ -120,6 +122,7 @@ name = "Bluetooth Manager"
description = "This utility is designed to manage bluetooth in your system"
script = "bluetooth-control.sh"
task_list = "I SS"
multi_select = false

[[data]]
name = "Bootable USB Creator"
Expand Down
63 changes: 36 additions & 27 deletions tui/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,10 @@ impl AppState {
hints.push(Shortcut::new("Select item below", ["j", "Down"]));
hints.push(Shortcut::new("Next theme", ["t"]));
hints.push(Shortcut::new("Previous theme", ["T"]));

if self.is_current_tab_multi_selectable() {
hints.push(Shortcut::new("Toggle multi-selection mode", ["v"]));
hints.push(Shortcut::new("Multi-selection mode", ["v"]));
if self.multi_select {
hints.push(Shortcut::new("Select multiple commands", ["Space"]));
}

hints.push(Shortcut::new("Next tab", ["Tab"]));
hints.push(Shortcut::new("Previous tab", ["Shift-Tab"]));
hints.push(Shortcut::new("Important actions guide", ["g"]));
Expand Down Expand Up @@ -330,7 +328,12 @@ impl AppState {
let (indicator, style) = if is_selected {
(self.theme.multi_select_icon(), Style::default().bold())
} else {
("", Style::new())
let ms_style = if self.multi_select && !node.multi_select {
Style::default().fg(self.theme.multi_select_disabled_color())
} else {
Style::new()
};
("", ms_style)
};
if *has_children {
Line::from(format!(
Expand All @@ -340,6 +343,7 @@ impl AppState {
indicator
))
.style(self.theme.dir_color())
.patch_style(style)
} else {
Line::from(format!(
"{} {} {}",
Expand All @@ -357,13 +361,21 @@ impl AppState {
|ListEntry {
node, has_children, ..
}| {
let ms_style = if self.multi_select && !node.multi_select {
Style::default().fg(self.theme.multi_select_disabled_color())
} else {
Style::new()
};
if *has_children {
Line::from(" ").style(self.theme.dir_color())
Line::from(" ")
.style(self.theme.dir_color())
.patch_style(ms_style)
} else {
Line::from(format!("{} ", node.task_list))
.alignment(Alignment::Right)
.style(self.theme.cmd_color())
.bold()
.patch_style(ms_style)
}
},
));
Expand Down Expand Up @@ -479,6 +491,13 @@ impl AppState {
// enabled, need to clear it to prevent state corruption
if !self.multi_select {
self.selected_commands.clear()
} else {
// Prevents non multi_selectable cmd from being pushed into the selected list
if let Some(node) = self.get_selected_node() {
if !node.multi_select {
self.selected_commands.retain(|cmd| cmd.name != node.name);
}
}
}
}
ConfirmStatus::Confirm => self.handle_confirm_command(),
Expand Down Expand Up @@ -556,41 +575,31 @@ impl AppState {
}

fn toggle_multi_select(&mut self) {
if self.is_current_tab_multi_selectable() {
self.multi_select = !self.multi_select;
if !self.multi_select {
self.selected_commands.clear();
}
self.multi_select = !self.multi_select;
if !self.multi_select {
self.selected_commands.clear();
}
}

fn toggle_selection(&mut self) {
if let Some(command) = self.get_selected_node() {
if self.selected_commands.contains(&command) {
self.selected_commands.retain(|c| c != &command);
} else {
self.selected_commands.push(command);
if let Some(node) = self.get_selected_node() {
if node.multi_select {
if self.selected_commands.contains(&node) {
self.selected_commands.retain(|c| c != &node);
} else {
self.selected_commands.push(node);
}
}
}
}

pub fn is_current_tab_multi_selectable(&self) -> bool {
let index = self.current_tab.selected().unwrap_or(0);
self.tabs
.get(index)
.map_or(false, |tab| tab.multi_selectable)
}

fn update_items(&mut self) {
self.filter.update_items(
&self.tabs,
self.current_tab.selected().unwrap(),
self.visit_stack.last().unwrap().0,
);
if !self.is_current_tab_multi_selectable() {
self.multi_select = false;
self.selected_commands.clear();
}

let len = self.filter.item_list().len();
if len > 0 {
let current = self.selection.selected().unwrap_or(0);
Expand Down
7 changes: 7 additions & 0 deletions tui/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ impl Theme {
}
}

pub fn multi_select_disabled_color(&self) -> Color {
match self {
Theme::Default => Color::DarkGray,
Theme::Compatible => Color::DarkGray,
}
}

pub fn tab_color(&self) -> Color {
match self {
Theme::Default => Color::Rgb(255, 255, 85),
Expand Down