fix: pos-tracker is search-context aware, panic on no-action

This commit is contained in:
imgurbot12 2023-07-21 16:10:27 -07:00
parent c83febd10b
commit 25ee2f32c4
5 changed files with 32 additions and 19 deletions

View File

@ -52,6 +52,10 @@ div.actions {
padding-left: 5%; padding-left: 5%;
} }
div.action-name {
width: 10%;
}
div.actions.active { div.actions.active {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -75,6 +75,7 @@ impl<'de> Deserialize<'de> for Keybind {
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
pub struct KeyConfig { pub struct KeyConfig {
pub exec: Vec<Keybind>,
pub exit: Vec<Keybind>, pub exit: Vec<Keybind>,
pub move_up: Vec<Keybind>, pub move_up: Vec<Keybind>,
pub move_down: Vec<Keybind>, pub move_down: Vec<Keybind>,
@ -87,6 +88,7 @@ pub struct KeyConfig {
impl Default for KeyConfig { impl Default for KeyConfig {
fn default() -> Self { fn default() -> Self {
return Self { return Self {
exec: vec![Keybind::new(Code::Enter)],
exit: vec![Keybind::new(Code::Escape)], exit: vec![Keybind::new(Code::Escape)],
move_up: vec![Keybind::new(Code::ArrowUp)], move_up: vec![Keybind::new(Code::ArrowUp)],
move_down: vec![Keybind::new(Code::ArrowDown)], move_down: vec![Keybind::new(Code::ArrowDown)],

View File

@ -9,5 +9,6 @@ pub fn execute(action: &Action) {
Ok(args) => args, Ok(args) => args,
Err(err) => panic!("{:?} invalid command {err}", action.exec), Err(err) => panic!("{:?} invalid command {err}", action.exec),
}; };
Command::new(&args[0]).args(&args[1..]).exec(); let err = Command::new(&args[0]).args(&args[1..]).exec();
panic!("Command Error: {err:?}");
} }

View File

@ -156,9 +156,17 @@ fn App(cx: Scope<App>) -> Element {
std::process::exit(0); std::process::exit(0);
} }
// retrieve results and filter based on search
let searchfn = new_searchfn(&cx.props.config, &search);
let results: Vec<&Entry> = cx
.props
.entries
.iter()
.filter(|entry| searchfn(entry))
.collect();
// retrieve results build and build position-tracker // retrieve results build and build position-tracker
let results = &cx.props.entries; let tracker = PosTracker::new(cx, results.clone());
let tracker = PosTracker::new(cx, results);
let (pos, subpos) = tracker.position(); let (pos, subpos) = tracker.position();
log::debug!("pos: {pos}, {subpos}"); log::debug!("pos: {pos}, {subpos}");
@ -168,7 +176,12 @@ fn App(cx: Scope<App>) -> Element {
let key = &evt.code(); let key = &evt.code();
let mods = &evt.modifiers(); let mods = &evt.modifiers();
log::debug!("key: {key:?} mods: {mods:?}"); log::debug!("key: {key:?} mods: {mods:?}");
if matches(&keybinds.exit, mods, key) { if matches(&keybinds.exec, mods, key) {
match tracker.action() {
Some(action) => execute(action),
None => panic!("No Action Configured"),
}
} else if matches(&keybinds.exit, mods, key) {
quit.set(true); quit.set(true);
} else if matches(&keybinds.move_up, mods, key) { } else if matches(&keybinds.move_up, mods, key) {
tracker.shift_up(); tracker.shift_up();
@ -184,10 +197,8 @@ fn App(cx: Scope<App>) -> Element {
}; };
// pre-render results into elements // pre-render results into elements
let searchfn = new_searchfn(&cx.props.config, &search);
let results_rendered: Vec<Element> = results let results_rendered: Vec<Element> = results
.iter() .iter()
.filter(|entry| searchfn(entry))
.enumerate() .enumerate()
.map(|(index, entry)| { .map(|(index, entry)| {
cx.render(rsx! { cx.render(rsx! {

View File

@ -1,6 +1,6 @@
//! GUI Application State Trackers and Utilities //! GUI Application State Trackers and Utilities
use dioxus::prelude::{use_state, Scope, UseState}; use dioxus::prelude::{use_state, Scope, UseState};
use rmenu_plugin::Entry; use rmenu_plugin::{Action, Entry};
use crate::App; use crate::App;
@ -8,21 +8,11 @@ use crate::App;
pub struct PosTracker<'a> { pub struct PosTracker<'a> {
pos: &'a UseState<usize>, pos: &'a UseState<usize>,
subpos: &'a UseState<usize>, subpos: &'a UseState<usize>,
results: &'a Vec<Entry>, results: Vec<&'a Entry>,
}
impl<'a> Clone for PosTracker<'a> {
fn clone(&self) -> Self {
Self {
pos: self.pos,
subpos: self.subpos,
results: self.results,
}
}
} }
impl<'a> PosTracker<'a> { impl<'a> PosTracker<'a> {
pub fn new(cx: Scope<'a, App>, results: &'a Vec<Entry>) -> Self { pub fn new(cx: Scope<'a, App>, results: Vec<&'a Entry>) -> Self {
let pos = use_state(cx, || 0); let pos = use_state(cx, || 0);
let subpos = use_state(cx, || 0); let subpos = use_state(cx, || 0);
Self { Self {
@ -46,6 +36,11 @@ impl<'a> PosTracker<'a> {
pub fn position(&self) -> (usize, usize) { pub fn position(&self) -> (usize, usize) {
(self.pos.get().clone(), self.subpos.get().clone()) (self.pos.get().clone(), self.subpos.get().clone())
} }
/// Get Action Linked To The Current Position
pub fn action(&self) -> Option<&Action> {
let (pos, subpos) = self.position();
self.results[pos].actions.get(subpos)
}
/// Move Position To SubMenu if it Exists /// Move Position To SubMenu if it Exists
pub fn open_menu(&self) { pub fn open_menu(&self) {
let index = *self.pos.get(); let index = *self.pos.get();