From 2a763d2ff00e9f65705d2ae0830a75d802069f43 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Mon, 5 Aug 2024 21:25:47 +0200 Subject: [PATCH 01/11] First attempt at fixing #119 --- leptos_hotkeys/src/context.rs | 28 +++++++++---- leptos_hotkeys/src/hotkey.rs | 18 +++++++- leptos_hotkeys/src/use_hotkeys.rs | 70 ++++++++++++++++++------------- 3 files changed, 79 insertions(+), 37 deletions(-) diff --git a/leptos_hotkeys/src/context.rs b/leptos_hotkeys/src/context.rs index fbb720a..c69f935 100644 --- a/leptos_hotkeys/src/context.rs +++ b/leptos_hotkeys/src/context.rs @@ -7,7 +7,7 @@ use wasm_bindgen::JsCast; #[derive(Clone, Copy)] pub struct HotkeysContext { #[cfg(not(feature = "ssr"))] - pub(crate) pressed_keys: RwSignal>, + pub(crate) pressed_keys: RwSignal, #[cfg(not(feature = "ssr"))] pub active_ref_target: RwSignal>, @@ -20,6 +20,12 @@ pub struct HotkeysContext { pub disable_scope: Callback, pub toggle_scope: Callback, } +#[derive(Debug, Default, Clone)] +#[cfg_attr(feature = "ssr", allow(dead_code))] +pub struct KeyPresses { + pub keys: std::collections::HashMap, + pub last_key: Option, +} pub fn provide_hotkeys_context( #[cfg_attr(feature = "ssr", allow(unused_variables))] node_ref: NodeRef, @@ -38,8 +44,7 @@ where }); #[cfg(not(feature = "ssr"))] - let pressed_keys: RwSignal> = - RwSignal::new(std::collections::HashMap::new()); + let pressed_keys: RwSignal = RwSignal::new(KeyPresses::default()); let active_scopes: RwSignal> = RwSignal::new(initially_active_scopes); @@ -81,7 +86,14 @@ where #[cfg(all(feature = "debug", not(feature = "ssr")))] create_effect(move |_| { - let pressed_keys_list = move || pressed_keys.get().keys().cloned().collect::>(); + let pressed_keys_list = move || { + pressed_keys + .get() + .keys + .keys() + .cloned() + .collect::>() + }; logging::log!("keys pressed: {:?}", pressed_keys_list()); }); @@ -91,19 +103,21 @@ where if cfg!(feature = "debug") { logging::log!("Window lost focus"); } - pressed_keys.set_untracked(std::collections::HashMap::new()); + pressed_keys.set_untracked(KeyPresses::default()); }) as Box); let keydown_listener = wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { pressed_keys.update(|keys| { - keys.insert(event.code().to_lowercase(), event); + let code = event.code().to_lowercase(); + keys.keys.insert(code.clone(), event); + keys.last_key = Some(code); }); }) as Box); let keyup_listener = wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { pressed_keys.update(|keys| { - keys.remove(&event.code().to_lowercase()); + keys.keys.remove(&event.code().to_lowercase()); }); }) as Box); diff --git a/leptos_hotkeys/src/hotkey.rs b/leptos_hotkeys/src/hotkey.rs index 6181ea1..a8af9b1 100644 --- a/leptos_hotkeys/src/hotkey.rs +++ b/leptos_hotkeys/src/hotkey.rs @@ -1,6 +1,7 @@ -use crate::types::Keys; use crate::KeyboardModifiers; +use crate::{context::KeyPresses, types::Keys}; use core::str::FromStr; +use std::collections::HashSet; use std::fmt::{Display, Formatter}; #[derive(Debug, PartialEq, Hash, Eq)] @@ -75,6 +76,21 @@ impl FromStr for Hotkey { } } +fn includes_key(hotkey: &Hotkey, key: &String) -> bool { + hotkey.keys.iter().any(|k| k == key) +} + +#[cfg_attr(feature = "ssr", allow(dead_code))] +pub(crate) fn is_last_key_match(pressed_keys: &KeyPresses, parsed_keys: &HashSet) -> bool { + if let Some(ref last_key) = pressed_keys.last_key { + parsed_keys + .iter() + .any(|hotkey| includes_key(hotkey, last_key)) + } else { + false + } +} + #[cfg_attr(feature = "ssr", allow(dead_code))] pub(crate) fn is_hotkey_match( hotkey: &Hotkey, diff --git a/leptos_hotkeys/src/use_hotkeys.rs b/leptos_hotkeys/src/use_hotkeys.rs index 001a1b2..969e844 100644 --- a/leptos_hotkeys/src/use_hotkeys.rs +++ b/leptos_hotkeys/src/use_hotkeys.rs @@ -7,7 +7,7 @@ pub fn use_hotkeys_scoped( ) { #[cfg(not(feature = "ssr"))] { - use crate::hotkey::is_hotkey_match; + use crate::hotkey::{is_hotkey_match, is_last_key_match}; use crate::{use_hotkeys_context, Hotkey}; use std::collections::HashSet; @@ -20,21 +20,27 @@ pub fn use_hotkeys_scoped( let active_scopes = hotkeys_context.active_scopes.get(); let within_scope = scopes.iter().any(|scope| active_scopes.contains(scope)); - if within_scope { - let mut pressed_keyset = pressed_keys.get(); - if let Some(matching_hotkey) = parsed_keys - .iter() - .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keyset)) - { - if cfg!(feature = "debug") { - let message = format!("%cfiring hotkey: {}", &matching_hotkey); - web_sys::console::log_2( - &wasm_bindgen::JsValue::from_str(&message), - &wasm_bindgen::JsValue::from_str("color: #39FF14;"), - ); - } - Callable::call(&on_triggered, ()); + if !within_scope { + return; + } + + let mut pressed_keyset = pressed_keys.get(); + if !is_last_key_match(&pressed_keyset, &parsed_keys) { + return; + } + + if let Some(matching_hotkey) = parsed_keys + .iter() + .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keyset.keys)) + { + if cfg!(feature = "debug") { + let message = format!("%cfiring hotkey: {}", &matching_hotkey); + web_sys::console::log_2( + &wasm_bindgen::JsValue::from_str(&message), + &wasm_bindgen::JsValue::from_str("color: #39FF14;"), + ); } + Callable::call(&on_triggered, ()); } }); } @@ -50,7 +56,7 @@ pub fn use_hotkeys_ref( { #[cfg(not(feature = "ssr"))] create_effect(move |_| { - use crate::hotkey::is_hotkey_match; + use crate::hotkey::{is_hotkey_match, is_last_key_match}; use crate::{use_hotkeys_context, Hotkey}; use leptos::ev::DOMEventResponder; use std::collections::HashSet; @@ -64,20 +70,26 @@ pub fn use_hotkeys_ref( let mut pressed_keys = hotkeys_context.pressed_keys.get(); let within_scope = scopes.iter().any(|scope| active_scopes.contains(scope)); - if within_scope { - if let Some(matching_hotkey) = parsed_keys - .iter() - .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keys)) - { - if cfg!(feature = "debug") { - let message = format!("%cfiring hotkey: {}", &matching_hotkey); - web_sys::console::log_2( - &wasm_bindgen::JsValue::from_str(&message), - &wasm_bindgen::JsValue::from_str("color: #39FF14;"), - ); - } - Callable::call(&on_triggered, ()); + if !within_scope { + return; + } + + if !is_last_key_match(&pressed_keys, &parsed_keys) { + return; + } + + if let Some(matching_hotkey) = parsed_keys + .iter() + .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keys.keys)) + { + if cfg!(feature = "debug") { + let message = format!("%cfiring hotkey: {}", &matching_hotkey); + web_sys::console::log_2( + &wasm_bindgen::JsValue::from_str(&message), + &wasm_bindgen::JsValue::from_str("color: #39FF14;"), + ); } + Callable::call(&on_triggered, ()); } }; From c226f11dcf2f65649f76c198edc124093f234c99 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Mon, 5 Aug 2024 21:59:02 +0200 Subject: [PATCH 02/11] Reset last_pressed on key up + refactor --- leptos_hotkeys/src/context.rs | 11 ++++++----- leptos_hotkeys/src/hotkey.rs | 2 +- leptos_hotkeys/src/use_hotkeys.rs | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/leptos_hotkeys/src/context.rs b/leptos_hotkeys/src/context.rs index c69f935..425519d 100644 --- a/leptos_hotkeys/src/context.rs +++ b/leptos_hotkeys/src/context.rs @@ -1,6 +1,6 @@ use leptos::html::ElementDescriptor; use leptos::*; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; #[cfg(not(feature = "ssr"))] use wasm_bindgen::JsCast; @@ -23,7 +23,7 @@ pub struct HotkeysContext { #[derive(Debug, Default, Clone)] #[cfg_attr(feature = "ssr", allow(dead_code))] pub struct KeyPresses { - pub keys: std::collections::HashMap, + pub key_map: HashMap, pub last_key: Option, } @@ -89,7 +89,7 @@ where let pressed_keys_list = move || { pressed_keys .get() - .keys + .key_map .keys() .cloned() .collect::>() @@ -110,14 +110,15 @@ where wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { pressed_keys.update(|keys| { let code = event.code().to_lowercase(); - keys.keys.insert(code.clone(), event); + keys.key_map.insert(code.clone(), event); keys.last_key = Some(code); }); }) as Box); let keyup_listener = wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { pressed_keys.update(|keys| { - keys.keys.remove(&event.code().to_lowercase()); + keys.key_map.remove(&event.code().to_lowercase()); + keys.last_key = None; }); }) as Box); diff --git a/leptos_hotkeys/src/hotkey.rs b/leptos_hotkeys/src/hotkey.rs index a8af9b1..fa5633a 100644 --- a/leptos_hotkeys/src/hotkey.rs +++ b/leptos_hotkeys/src/hotkey.rs @@ -81,7 +81,7 @@ fn includes_key(hotkey: &Hotkey, key: &String) -> bool { } #[cfg_attr(feature = "ssr", allow(dead_code))] -pub(crate) fn is_last_key_match(pressed_keys: &KeyPresses, parsed_keys: &HashSet) -> bool { +pub(crate) fn is_last_key_match(parsed_keys: &HashSet, pressed_keys: &KeyPresses) -> bool { if let Some(ref last_key) = pressed_keys.last_key { parsed_keys .iter() diff --git a/leptos_hotkeys/src/use_hotkeys.rs b/leptos_hotkeys/src/use_hotkeys.rs index 969e844..9b1176c 100644 --- a/leptos_hotkeys/src/use_hotkeys.rs +++ b/leptos_hotkeys/src/use_hotkeys.rs @@ -25,13 +25,13 @@ pub fn use_hotkeys_scoped( } let mut pressed_keyset = pressed_keys.get(); - if !is_last_key_match(&pressed_keyset, &parsed_keys) { + if !is_last_key_match(&parsed_keys, &pressed_keyset) { return; } if let Some(matching_hotkey) = parsed_keys .iter() - .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keyset.keys)) + .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keyset.key_map)) { if cfg!(feature = "debug") { let message = format!("%cfiring hotkey: {}", &matching_hotkey); @@ -74,13 +74,13 @@ pub fn use_hotkeys_ref( return; } - if !is_last_key_match(&pressed_keys, &parsed_keys) { + if !is_last_key_match(&parsed_keys, &pressed_keys) { return; } if let Some(matching_hotkey) = parsed_keys .iter() - .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keys.keys)) + .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keys.key_map)) { if cfg!(feature = "debug") { let message = format!("%cfiring hotkey: {}", &matching_hotkey); From ebff790b46b1ee0001a41c6150aa7f55e8b9d01b Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Sat, 17 Aug 2024 21:23:16 +0200 Subject: [PATCH 03/11] Refactor key handling logic --- leptos_hotkeys/src/context.rs | 8 ++++---- leptos_hotkeys/src/hotkey.rs | 12 ++++++------ leptos_hotkeys/src/use_hotkeys.rs | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/leptos_hotkeys/src/context.rs b/leptos_hotkeys/src/context.rs index 425519d..e1df8dd 100644 --- a/leptos_hotkeys/src/context.rs +++ b/leptos_hotkeys/src/context.rs @@ -1,13 +1,13 @@ use leptos::html::ElementDescriptor; use leptos::*; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashSet}; #[cfg(not(feature = "ssr"))] use wasm_bindgen::JsCast; #[derive(Clone, Copy)] pub struct HotkeysContext { #[cfg(not(feature = "ssr"))] - pub(crate) pressed_keys: RwSignal, + pub(crate) keys_pressed: RwSignal, #[cfg(not(feature = "ssr"))] pub active_ref_target: RwSignal>, @@ -23,7 +23,7 @@ pub struct HotkeysContext { #[derive(Debug, Default, Clone)] #[cfg_attr(feature = "ssr", allow(dead_code))] pub struct KeyPresses { - pub key_map: HashMap, + pub key_map: BTreeMap, pub last_key: Option, } @@ -165,7 +165,7 @@ where let hotkeys_context = HotkeysContext { #[cfg(not(feature = "ssr"))] - pressed_keys, + keys_pressed: pressed_keys, #[cfg(not(feature = "ssr"))] active_ref_target, diff --git a/leptos_hotkeys/src/hotkey.rs b/leptos_hotkeys/src/hotkey.rs index fa5633a..db1310a 100644 --- a/leptos_hotkeys/src/hotkey.rs +++ b/leptos_hotkeys/src/hotkey.rs @@ -30,6 +30,10 @@ impl Hotkey { pub fn new(key_combination: &str) -> Self { key_combination.parse().unwrap() } + + fn includes_key(&self, key: &String) -> bool { + self.keys.iter().any(|k| k == key) + } } impl FromStr for Hotkey { @@ -76,16 +80,12 @@ impl FromStr for Hotkey { } } -fn includes_key(hotkey: &Hotkey, key: &String) -> bool { - hotkey.keys.iter().any(|k| k == key) -} - #[cfg_attr(feature = "ssr", allow(dead_code))] pub(crate) fn is_last_key_match(parsed_keys: &HashSet, pressed_keys: &KeyPresses) -> bool { if let Some(ref last_key) = pressed_keys.last_key { parsed_keys .iter() - .any(|hotkey| includes_key(hotkey, last_key)) + .any(|hotkey| hotkey.includes_key(last_key)) } else { false } @@ -94,7 +94,7 @@ pub(crate) fn is_last_key_match(parsed_keys: &HashSet, pressed_keys: &Ke #[cfg_attr(feature = "ssr", allow(dead_code))] pub(crate) fn is_hotkey_match( hotkey: &Hotkey, - pressed_keyset: &mut std::collections::HashMap, + pressed_keyset: &mut std::collections::BTreeMap, ) -> bool { let mut modifiers_match = true; diff --git a/leptos_hotkeys/src/use_hotkeys.rs b/leptos_hotkeys/src/use_hotkeys.rs index 9b1176c..e47f3ef 100644 --- a/leptos_hotkeys/src/use_hotkeys.rs +++ b/leptos_hotkeys/src/use_hotkeys.rs @@ -14,7 +14,7 @@ pub fn use_hotkeys_scoped( let parsed_keys: HashSet = key_combination.split(',').map(Hotkey::new).collect(); let hotkeys_context = use_hotkeys_context(); - let pressed_keys = hotkeys_context.pressed_keys; + let pressed_keys = hotkeys_context.keys_pressed; create_effect(move |_| { let active_scopes = hotkeys_context.active_scopes.get(); @@ -67,7 +67,7 @@ pub fn use_hotkeys_ref( let keydown_closure = move |_event: web_sys::KeyboardEvent| { let hotkeys_context = use_hotkeys_context(); let active_scopes = hotkeys_context.active_scopes.get(); - let mut pressed_keys = hotkeys_context.pressed_keys.get(); + let mut pressed_keys = hotkeys_context.keys_pressed.get(); let within_scope = scopes.iter().any(|scope| active_scopes.contains(scope)); if !within_scope { From ff2f084c85fb658d83fcbb83922f04bb3dc1310e Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Sat, 17 Aug 2024 21:36:36 +0200 Subject: [PATCH 04/11] Handle conflict with #127 --- leptos_hotkeys/src/context.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/leptos_hotkeys/src/context.rs b/leptos_hotkeys/src/context.rs index e1df8dd..699c601 100644 --- a/leptos_hotkeys/src/context.rs +++ b/leptos_hotkeys/src/context.rs @@ -109,15 +109,16 @@ where let keydown_listener = wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { pressed_keys.update(|keys| { - let code = event.code().to_lowercase(); - keys.key_map.insert(code.clone(), event); - keys.last_key = Some(code); + let key = clean_key(&event); + keys.key_map.insert(key.clone(), event); + keys.last_key = Some(key); }); }) as Box); let keyup_listener = wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { pressed_keys.update(|keys| { - keys.key_map.remove(&event.code().to_lowercase()); + let key = clean_key(&event); + keys.key_map.remove(&key); keys.last_key = None; }); }) as Box); @@ -186,3 +187,10 @@ where pub fn use_hotkeys_context() -> HotkeysContext { use_context::().expect("expected hotkeys context") } + +fn clean_key(event: &web_sys::KeyboardEvent) -> String { + match event.key().as_str() { + " " => "spacebar".to_string(), + _ => event.key().to_lowercase(), + } +} From 968df44afed344ef927c9ba72bc070296206aa47 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Mon, 19 Aug 2024 20:31:39 +0200 Subject: [PATCH 05/11] Temporary debug message for last key match --- leptos_hotkeys/src/use_hotkeys.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/leptos_hotkeys/src/use_hotkeys.rs b/leptos_hotkeys/src/use_hotkeys.rs index e47f3ef..df5d569 100644 --- a/leptos_hotkeys/src/use_hotkeys.rs +++ b/leptos_hotkeys/src/use_hotkeys.rs @@ -28,6 +28,13 @@ pub fn use_hotkeys_scoped( if !is_last_key_match(&parsed_keys, &pressed_keyset) { return; } + if cfg!(feature = "debug") { + let message = "%cfound last key match".to_string(); + web_sys::console::log_2( + &wasm_bindgen::JsValue::from_str(&message), + &wasm_bindgen::JsValue::from_str("color: #39FF14;"), + ); + } if let Some(matching_hotkey) = parsed_keys .iter() From 4b9aab3a4cfc46efc826e238558adcd0f450fc4c Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Mon, 19 Aug 2024 20:39:26 +0200 Subject: [PATCH 06/11] Another temporary debug message --- leptos_hotkeys/src/use_hotkeys.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/leptos_hotkeys/src/use_hotkeys.rs b/leptos_hotkeys/src/use_hotkeys.rs index df5d569..8d06eba 100644 --- a/leptos_hotkeys/src/use_hotkeys.rs +++ b/leptos_hotkeys/src/use_hotkeys.rs @@ -25,6 +25,18 @@ pub fn use_hotkeys_scoped( } let mut pressed_keyset = pressed_keys.get(); + if cfg!(feature = "debug") { + let message = format!("%cpressed keys: {:?}", &pressed_keyset); + web_sys::console::log_2( + &wasm_bindgen::JsValue::from_str(&message), + &wasm_bindgen::JsValue::from_str("color: #39FF14;"), + ); + let message = format!("%cparsed keys: {:?}", &parsed_keys); + web_sys::console::log_2( + &wasm_bindgen::JsValue::from_str(&message), + &wasm_bindgen::JsValue::from_str("color: #39FF14;"), + ); + } if !is_last_key_match(&parsed_keys, &pressed_keyset) { return; } From 0f59d2268e7a377dd74c87b309d2ed50e93d6f97 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Mon, 19 Aug 2024 21:05:30 +0200 Subject: [PATCH 07/11] Remove temporary logs + refactor --- leptos_hotkeys/src/context.rs | 17 +++++++++-------- leptos_hotkeys/src/hotkey.rs | 6 ++---- leptos_hotkeys/src/use_hotkeys.rs | 26 +++----------------------- 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/leptos_hotkeys/src/context.rs b/leptos_hotkeys/src/context.rs index 699c601..ac89fac 100644 --- a/leptos_hotkeys/src/context.rs +++ b/leptos_hotkeys/src/context.rs @@ -44,7 +44,7 @@ where }); #[cfg(not(feature = "ssr"))] - let pressed_keys: RwSignal = RwSignal::new(KeyPresses::default()); + let keys_pressed: RwSignal = RwSignal::new(KeyPresses::default()); let active_scopes: RwSignal> = RwSignal::new(initially_active_scopes); @@ -86,15 +86,15 @@ where #[cfg(all(feature = "debug", not(feature = "ssr")))] create_effect(move |_| { - let pressed_keys_list = move || { - pressed_keys + let keys_pressed_list = move || { + keys_pressed .get() .key_map .keys() .cloned() .collect::>() }; - logging::log!("keys pressed: {:?}", pressed_keys_list()); + logging::log!("keys pressed: {:?}", keys_pressed_list()); }); #[cfg(not(feature = "ssr"))] @@ -103,12 +103,12 @@ where if cfg!(feature = "debug") { logging::log!("Window lost focus"); } - pressed_keys.set_untracked(KeyPresses::default()); + keys_pressed.set_untracked(KeyPresses::default()); }) as Box); let keydown_listener = wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { - pressed_keys.update(|keys| { + keys_pressed.update(|keys| { let key = clean_key(&event); keys.key_map.insert(key.clone(), event); keys.last_key = Some(key); @@ -116,7 +116,7 @@ where }) as Box); let keyup_listener = wasm_bindgen::closure::Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| { - pressed_keys.update(|keys| { + keys_pressed.update(|keys| { let key = clean_key(&event); keys.key_map.remove(&key); keys.last_key = None; @@ -166,7 +166,7 @@ where let hotkeys_context = HotkeysContext { #[cfg(not(feature = "ssr"))] - keys_pressed: pressed_keys, + keys_pressed, #[cfg(not(feature = "ssr"))] active_ref_target, @@ -188,6 +188,7 @@ pub fn use_hotkeys_context() -> HotkeysContext { use_context::().expect("expected hotkeys context") } +#[cfg(not(feature = "ssr"))] fn clean_key(event: &web_sys::KeyboardEvent) -> String { match event.key().as_str() { " " => "spacebar".to_string(), diff --git a/leptos_hotkeys/src/hotkey.rs b/leptos_hotkeys/src/hotkey.rs index 2b7e4eb..a180529 100644 --- a/leptos_hotkeys/src/hotkey.rs +++ b/leptos_hotkeys/src/hotkey.rs @@ -84,13 +84,11 @@ impl FromStr for Hotkey { #[cfg_attr(feature = "ssr", allow(dead_code))] pub(crate) fn is_last_key_match(parsed_keys: &HashSet, pressed_keys: &KeyPresses) -> bool { - if let Some(ref last_key) = pressed_keys.last_key { + pressed_keys.last_key.as_ref().is_some_and(|last_key| { parsed_keys .iter() .any(|hotkey| hotkey.includes_key(last_key)) - } else { - false - } + }) } #[cfg_attr(feature = "ssr", allow(dead_code))] diff --git a/leptos_hotkeys/src/use_hotkeys.rs b/leptos_hotkeys/src/use_hotkeys.rs index 8d06eba..1a62d54 100644 --- a/leptos_hotkeys/src/use_hotkeys.rs +++ b/leptos_hotkeys/src/use_hotkeys.rs @@ -14,7 +14,6 @@ pub fn use_hotkeys_scoped( let parsed_keys: HashSet = key_combination.split(',').map(Hotkey::new).collect(); let hotkeys_context = use_hotkeys_context(); - let pressed_keys = hotkeys_context.keys_pressed; create_effect(move |_| { let active_scopes = hotkeys_context.active_scopes.get(); @@ -24,33 +23,14 @@ pub fn use_hotkeys_scoped( return; } - let mut pressed_keyset = pressed_keys.get(); - if cfg!(feature = "debug") { - let message = format!("%cpressed keys: {:?}", &pressed_keyset); - web_sys::console::log_2( - &wasm_bindgen::JsValue::from_str(&message), - &wasm_bindgen::JsValue::from_str("color: #39FF14;"), - ); - let message = format!("%cparsed keys: {:?}", &parsed_keys); - web_sys::console::log_2( - &wasm_bindgen::JsValue::from_str(&message), - &wasm_bindgen::JsValue::from_str("color: #39FF14;"), - ); - } - if !is_last_key_match(&parsed_keys, &pressed_keyset) { + let mut keys_pressed = hotkeys_context.keys_pressed.get(); + if !is_last_key_match(&parsed_keys, &keys_pressed) { return; } - if cfg!(feature = "debug") { - let message = "%cfound last key match".to_string(); - web_sys::console::log_2( - &wasm_bindgen::JsValue::from_str(&message), - &wasm_bindgen::JsValue::from_str("color: #39FF14;"), - ); - } if let Some(matching_hotkey) = parsed_keys .iter() - .find(|hotkey| is_hotkey_match(hotkey, &mut pressed_keyset.key_map)) + .find(|hotkey| is_hotkey_match(hotkey, &mut keys_pressed.key_map)) { if cfg!(feature = "debug") { let message = format!("%cfiring hotkey: {}", &matching_hotkey); From f1e5410888eb572cce13b70265c047cc45c6c3b9 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Sun, 25 Aug 2024 13:54:42 +0200 Subject: [PATCH 08/11] Add feature for using event key --- leptos_hotkeys/Cargo.toml | 8 +++++++- leptos_hotkeys/src/context.rs | 10 ++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/leptos_hotkeys/Cargo.toml b/leptos_hotkeys/Cargo.toml index dc01da4..873b5f2 100644 --- a/leptos_hotkeys/Cargo.toml +++ b/leptos_hotkeys/Cargo.toml @@ -6,7 +6,12 @@ description = "A library that declaratively pairs keybindings with callbacks for license = "MIT" repository = "https://github.com/gaucho-labs/leptos-hotkeys" readme = "../README.md" -authors = ["Matthew Kim", "Álvaro Mondéjar Rubio", "Robert Junkins", "Zak Stucke"] +authors = [ + "Matthew Kim", + "Álvaro Mondéjar Rubio", + "Robert Junkins", + "Zak Stucke", +] keywords = ["leptos", "hotkeys", "wasm"] [dependencies] @@ -18,3 +23,4 @@ web-sys.workspace = true [features] debug = ["dep:log"] ssr = [] +event_key = [] diff --git a/leptos_hotkeys/src/context.rs b/leptos_hotkeys/src/context.rs index ac89fac..2c214ef 100644 --- a/leptos_hotkeys/src/context.rs +++ b/leptos_hotkeys/src/context.rs @@ -190,8 +190,14 @@ pub fn use_hotkeys_context() -> HotkeysContext { #[cfg(not(feature = "ssr"))] fn clean_key(event: &web_sys::KeyboardEvent) -> String { - match event.key().as_str() { + let key = if cfg!(feature = "event_key") { + event.key() + } else { + event.code() + }; + + match key.as_str() { " " => "spacebar".to_string(), - _ => event.key().to_lowercase(), + key => key.to_lowercase(), } } From f721c9b66211e1315a6b4ee64d8519a7da095e65 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Sun, 25 Aug 2024 21:29:46 +0200 Subject: [PATCH 09/11] Update README with feature flag description --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 409eb1b..d046f03 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,26 @@ Just simply: leptos_hotkeys = { path = "0.2.1", features = ["debug"] } ``` +## The `event_key` feature flag + +For improved accessibility options, this crate supports using either the event code or the event key for triggering events. This should improve compatibility with e.g. Dvorak keyboard layout. Note that this currently requires slight modification of hotkey definitions for alphanumeric keys. + +```rust +// with event code (without event_key feature flag) +use_hotkeys!(("keyw") => move |_| logging::log!("w has been pressed")); +use_hotkeys!(("digit1") => move |_| logging::log!("1 has been pressed")); + +// with event_key feature flag +use_hotkeys!(("w") => move |_| logging::log!("w has been pressed")); +use_hotkeys!(("1") => move |_| logging::log!("1 has been pressed")); +``` + +To use event key as the identifier instead of event code, use: + +```toml +leptos_hotkeys = { path = "0.2.1", features = ["event_key"] } +``` + ## Contributors From c7104e039d91ebd50b25e174c343c9149b3259f5 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Thu, 29 Aug 2024 20:29:52 +0200 Subject: [PATCH 10/11] Revert "Update README with feature flag description" This reverts commit f721c9b66211e1315a6b4ee64d8519a7da095e65. --- README.md | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/README.md b/README.md index d046f03..409eb1b 100644 --- a/README.md +++ b/README.md @@ -223,26 +223,6 @@ Just simply: leptos_hotkeys = { path = "0.2.1", features = ["debug"] } ``` -## The `event_key` feature flag - -For improved accessibility options, this crate supports using either the event code or the event key for triggering events. This should improve compatibility with e.g. Dvorak keyboard layout. Note that this currently requires slight modification of hotkey definitions for alphanumeric keys. - -```rust -// with event code (without event_key feature flag) -use_hotkeys!(("keyw") => move |_| logging::log!("w has been pressed")); -use_hotkeys!(("digit1") => move |_| logging::log!("1 has been pressed")); - -// with event_key feature flag -use_hotkeys!(("w") => move |_| logging::log!("w has been pressed")); -use_hotkeys!(("1") => move |_| logging::log!("1 has been pressed")); -``` - -To use event key as the identifier instead of event code, use: - -```toml -leptos_hotkeys = { path = "0.2.1", features = ["event_key"] } -``` - ## Contributors From f3db65128573b79c865d403289dd2b0bd86b9dc1 Mon Sep 17 00:00:00 2001 From: Max Bergmark Date: Thu, 29 Aug 2024 20:30:30 +0200 Subject: [PATCH 11/11] Revert "Add feature for using event key" This reverts commit f1e5410888eb572cce13b70265c047cc45c6c3b9. --- leptos_hotkeys/Cargo.toml | 8 +------- leptos_hotkeys/src/context.rs | 10 ++-------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/leptos_hotkeys/Cargo.toml b/leptos_hotkeys/Cargo.toml index 873b5f2..dc01da4 100644 --- a/leptos_hotkeys/Cargo.toml +++ b/leptos_hotkeys/Cargo.toml @@ -6,12 +6,7 @@ description = "A library that declaratively pairs keybindings with callbacks for license = "MIT" repository = "https://github.com/gaucho-labs/leptos-hotkeys" readme = "../README.md" -authors = [ - "Matthew Kim", - "Álvaro Mondéjar Rubio", - "Robert Junkins", - "Zak Stucke", -] +authors = ["Matthew Kim", "Álvaro Mondéjar Rubio", "Robert Junkins", "Zak Stucke"] keywords = ["leptos", "hotkeys", "wasm"] [dependencies] @@ -23,4 +18,3 @@ web-sys.workspace = true [features] debug = ["dep:log"] ssr = [] -event_key = [] diff --git a/leptos_hotkeys/src/context.rs b/leptos_hotkeys/src/context.rs index 2c214ef..ac89fac 100644 --- a/leptos_hotkeys/src/context.rs +++ b/leptos_hotkeys/src/context.rs @@ -190,14 +190,8 @@ pub fn use_hotkeys_context() -> HotkeysContext { #[cfg(not(feature = "ssr"))] fn clean_key(event: &web_sys::KeyboardEvent) -> String { - let key = if cfg!(feature = "event_key") { - event.key() - } else { - event.code() - }; - - match key.as_str() { + match event.key().as_str() { " " => "spacebar".to_string(), - key => key.to_lowercase(), + _ => event.key().to_lowercase(), } }