diff --git a/data_json.json b/data_json.json new file mode 100644 index 00000000..4b16ca22 --- /dev/null +++ b/data_json.json @@ -0,0 +1,47 @@ +[ + { + "name": "Default", + "icon": "i", + "macros": [ + { + "name": "Macro Name", + "sequence": [], + "trigger": { + "type": "KeyPressEvent", + "data": [ + { + "keypress": 7, + "press_duration": 0 + } + ] + }, + "active": true + } + ], + "active": true + }, + { + "name": "OMGF", + "icon": "i", + "macros": [], + "active": false + }, + { + "name": "HAHA", + "icon": "i", + "macros": [], + "active": false + }, + { + "name": "test", + "icon": "i", + "macros": [], + "active": false + }, + { + "name": "ADASD", + "icon": "i", + "macros": [], + "active": false + } +] \ No newline at end of file diff --git a/package.json b/package.json index cd589837..1fb1bccf 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,10 @@ "dependencies": { "@chakra-ui/icons": "^2.0.11", "@chakra-ui/react": "^2.3.6", - "@emotion/react": "^11", - "@emotion/styled": "^11", + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", "@tauri-apps/api": "^1.1.0", - "framer-motion": "^6", + "framer-motion": "^7.6.4", "react": "^18.2.0", "react-dom": "^18.2.0", "wouter": "^2.8.0-alpha.2" diff --git a/src-tauri/data_json.json b/src-tauri/data_json.json deleted file mode 100644 index d7b51f85..00000000 --- a/src-tauri/data_json.json +++ /dev/null @@ -1,114 +0,0 @@ -[ - { - "name": "Main group", - "icon": "i", - "macros": [ - { - "name": "TESTING THIS", - "sequence": [ - { - "type": "KeyPressEvent", - "data": { - "keypress": 12, - "press_duration": 50 - } - }, - { - "type": "KeyPressEvent", - "data": { - "keypress": 13, - "press_duration": 50 - } - } - ], - "trigger": { - "type": "KeyPressEvent", - "data": [ - { - "keypress": 14, - "press_duration": 50 - }, - { - "keypress": 16, - "press_duration": 50 - } - ] - }, - "active": true - } - ], - "active": true - }, - { - "name": "Fun macro group", - "icon": "i", - "macros": [ - { - "name": "Havo", - "sequence": [ - { - "type": "KeyPressEvent", - "data": { - "keypress": 14, - "press_duration": 50 - } - - }, - { - - "type": "KeyPressEvent", - "data": { - "keypress": 13, - "press_duration": 50 - } - - }, - { - "type": "KeyPressEvent", - "data": { - "keypress": 12, - "press_duration": 50 - } - - } - ], - "trigger": { - "type": "KeyPressEvent", - "data": [ - { - "keypress": 22, - "press_duration": 50 - } - ] - - }, - "active": true - }, - { - "name": "Svorka", - "sequence": [ - { - "type": "KeyPressEvent", - "data": { - "keypress": 23, - "press_duration": 50 - } - - } - ], - "trigger": { - "type": "KeyPressEvent", - "data": [ - { - "keypress": 24, - "press_duration": 50 - } - ] - - }, - "active": true - } - ], - "active": false - } -] \ No newline at end of file diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 753e34a2..30e101bd 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -8,7 +8,9 @@ extern crate core; use std::fs::File; use std::io::Read; +use std::sync::RwLock; +use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use serde_json; use tauri::App; @@ -27,30 +29,24 @@ pub struct ApplicationConfig { pub startup_delay: u64, } +lazy_static! { + pub static ref APPLICATION_STATE: MacroDataState = { + MacroDataState::new() + }; +} + fn main() { tauri::Builder::default() // This is where you pass in your commands + .manage(MacroDataState::new()) .invoke_handler(tauri::generate_handler![ - export_frontend, - import_frontend, - push_frontend_first + get_configuration, + set_configuration ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); - let mut config: ApplicationConfig = ApplicationConfig { - use_input_grab: false, - startup_delay: 3, - }; - let mut file = match File::open("config.json") { - Ok(T) => T, - Err(E) => { - eprintln!("Error parsing the file {}", E); - println!("Error finding the config.json file.\nPlease place one in the root directory. Using default configuration (safe).\nCreating an empty file.\n"); - File::create("config.json").unwrap() - } - }; // let mut data = String::new(); // // match file.read_to_string(&mut data) { @@ -64,5 +60,26 @@ fn main() { // Err(E) => {} // } - run_this(&config) + + + + run_this(&get_config()) } + + +pub fn get_config() -> ApplicationConfig { + let mut config: ApplicationConfig = ApplicationConfig { + use_input_grab: false, + startup_delay: 3, + }; + + let mut file = match File::open("config.json") { + Ok(T) => T, + Err(E) => { + eprintln!("Error parsing the file {}", E); + println!("Error finding the config.json file.\nPlease place one in the root directory. Using default configuration (safe).\nCreating an empty file.\n"); + File::create("config.json").unwrap() + } + }; + config +} \ No newline at end of file diff --git a/src-tauri/src/wooting_macros_library.rs b/src-tauri/src/wooting_macros_library.rs index b554696f..a1dfe767 100644 --- a/src-tauri/src/wooting_macros_library.rs +++ b/src-tauri/src/wooting_macros_library.rs @@ -5,12 +5,15 @@ use std::fs::File; use std::hash::Hash; use std::str::{Bytes, FromStr}; use std::sync::mpsc::channel; +use std::sync::RwLock; use std::time::Duration; +use lazy_static::lazy_static; use rdev::{Button, Event, EventType, grab, Key, listen, simulate, SimulateError}; use serde::Serialize; +use tauri::State; -use crate::{ApplicationConfig, hid_table}; +use crate::{APPLICATION_STATE, ApplicationConfig, hid_table}; use crate::hid_table::*; #[derive(Debug)] @@ -22,9 +25,9 @@ pub enum MacroType { } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Hash, Eq)] -struct KeyPress { - keypress: u32, - press_duration: Delay, +pub struct KeyPress { + pub keypress: u32, + pub press_duration: Delay, } impl KeyPress { @@ -36,7 +39,7 @@ impl KeyPress { } ///Delay for the sequence -type Delay = u32; +pub type Delay = u32; //TODO: Make a hashmap that links to trigger:¯o @@ -61,7 +64,7 @@ pub enum TriggerEventType { } #[derive(Debug, Clone)] -struct EventList(Vec); +pub struct EventList(Vec); #[derive(Debug, Clone)] pub struct Action { @@ -71,152 +74,254 @@ pub struct Action { #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct Macro { - name: String, - sequence: Vec, - trigger: TriggerEventType, - active: bool, + pub name: String, + pub sequence: Vec, + pub trigger: TriggerEventType, + pub active: bool, } -// get_configuration(): string -// set_configuration(string) - - #[tauri::command] -pub fn export_frontend(data: MacroData) -> String { - let data_return = data.export_data(); - data_return +/// Gets the configuration from current state and sends to frontend. +/// The state gets it from the config file at bootup. +pub fn get_configuration(state: tauri::State) -> MacroData { + let test = state.data.read().unwrap(); + test.clone() } #[tauri::command] -pub fn push_frontend_first() -> MacroData { - let path = "./data_json.json"; - let data = fs::read_to_string(path).expect("Unable to read file"); - let res = serde_json::from_str::(&data).expect("Unable to parse"); +/// Sets the configuration from frontend and updates the state for everything on backend. +pub fn set_configuration(state: tauri::State, frontend_data: Vec) { + let mut tauri_state = state.data.write().unwrap(); + *tauri_state = MacroData { 0: frontend_data.clone() }; + tauri_state.export_data(); - // serde_json::to_string(&res).expect("Unable to serialize") - res + + let mut app_state = APPLICATION_STATE.data.write().unwrap(); + *app_state = MacroData { 0: frontend_data.clone() }; } -fn push_backend_first() -> MacroData { - let path = "./data_json.json"; - let data = fs::read_to_string(path).expect("Unable to read file"); +/// Function for a manual write of config changes from the backend side. Just a test. +/// Not meant to be used. +pub fn set_data_write_manually_backend(frontend_data: MacroData) { + let mut app_state = APPLICATION_STATE.data.write().unwrap(); + *app_state = frontend_data.clone(); + app_state.clone().export_data(); +} - let deserialized: MacroData = serde_json::from_str(&data).unwrap(); - deserialized +fn check_key(incoming_key: &Key) { + let app_state = APPLICATION_STATE.data.read().unwrap(); + + for collections in &app_state.0 { + if collections.active == true { + for macros in &collections.macros { + if macros.active == true { + match ¯os.trigger { + TriggerEventType::KeyPressEvent { data: trigger } => { + for i in trigger { + if SCANCODE_MAP[&i.keypress] == *incoming_key { + println!("FOUND THE TRIGGER, WOULD EXECUTE MACRO: {}", macros.name) + } + } + } + } + } + } + } + } } +// pub fn export_frontend(data: MacroData) -> String { +// let data_return = data.export_data(); +// data_return +// } -#[tauri::command] -pub fn import_frontend(mut data: MacroData, input: MacroData) { - data.import_data(input); +// pub fn push_frontend_first() -> MacroData { +// let path = "./data_json.json"; +// let data = fs::read_to_string(path).expect("Unable to read file"); +// let res = serde_json::from_str::(&data).expect("Unable to parse"); +// +// // serde_json::to_string(&res).expect("Unable to serialize") +// res +// } + +// fn push_backend_first() -> MacroData { +// let path = "./data_json.json"; +// let data = fs::read_to_string(path).expect("Unable to read file"); +// +// let deserialized: MacroData = serde_json::from_str(&data).unwrap(); +// deserialized +// } + +// #[tauri::command] +// pub fn import_frontend(mut data: MacroData, input: MacroData) { +// data.import_data(input); +// } + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +pub struct MacroDataState { + pub data: RwLock, } +impl MacroDataState { + pub fn new() -> Self { + MacroDataState { data: RwLock::from(MacroData::read_data()) } + } +} + + +//type Collections = Vec; + ///MacroData is the main data structure that contains all macro data. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct MacroData(Vec); +pub struct MacroData(pub Vec); + impl MacroData { /// This exports data for the frontend to process it. /// Basically sends the entire struct to the frontend - pub fn export_data(&self) -> String { + pub fn export_data(&self) { std::fs::write( - "./data_json.json", + "../data_json.json", serde_json::to_string_pretty(&self).unwrap(), ) .unwrap(); - - serde_json::to_string_pretty(&self).unwrap() - } - - /// Imports data from the frontend (when updated) to update the background data structure - /// This overwrites the datastructure - pub fn import_data(&mut self, input: MacroData) -> TriggerHash { - *self = input; - self.export_data(); - self.extract_triggers() } - /// Extracts the data - fn extract_triggers(&self) -> TriggerHash { - let mut trigger_hash_list: TriggerHash = HashMap::new(); - - for search in &self.0 { - for trig in &search.macros { - match &trig.trigger { - TriggerEventType::KeyPressEvent { data } => { - trigger_hash_list.insert(data.clone(), &trig); - } + // /// Imports data from the frontend (when updated) to update the background data structure + // /// This overwrites the datastructure + // pub fn import_data(&mut self, input: MacroData) -> TriggerHash { + // *self = input; + // self.export_data(); + // self.extract_triggers() + // } + + // /// Extracts the data + // fn extract_triggers(&self) -> TriggerHash { + // let mut trigger_hash_list: TriggerHash = HashMap::new(); + // + // for search in &self.0 { + // for trig in &search.macros { + // match &trig.trigger { + // TriggerEventType::KeyPressEvent { data } => { + // trigger_hash_list.insert(data.clone(), &trig); + // } + // } + // } + // } + // + // trigger_hash_list + // } + + pub fn read_data() -> MacroData { + let path = "../data_json.json"; + + let incoming_test: MacroData = MacroData(vec![Collection { + name: "Default".to_string(), + icon: 'i'.to_string(), + macros: vec![], + active: true, + }]); + + + //TODO: Make this create a new file when needed. + let data = { + match fs::read_to_string(path) { + Ok(T) => { T } + Err(E) => { + println!("{}", E); + std::fs::write( + "../data_json.json", + serde_json::to_string_pretty(&incoming_test).unwrap(), + ).unwrap(); + + let output = fs::read_to_string(path).unwrap(); + println!("{}", output); + + output } } - } + }; - trigger_hash_list + let deserialized: MacroData = serde_json::from_str(&data).unwrap(); + deserialized } } + ///Hash list -type TriggerHash<'a> = HashMap, &'a Macro>; +pub type TriggerHash<'a> = HashMap, &'a Macro>; #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct Collection { - name: String, + pub name: String, //TODO: base64 encoding - icon: String, - macros: Vec, - active: bool, + pub icon: String, + pub macros: Vec, + pub active: bool, } ///Main loop for now (of the library) /// * `config` - &ApplicationConfig from the parsed JSON config file of the app. pub fn run_this(config: &ApplicationConfig) { - // let mut incoming_test: MacroData = MacroData { - // 0: vec![Collection { - // name: "LOL".to_string(), - // icon: 'i'.to_string(), - // macros: vec![Macro { - // name: "Newer string".to_string(), - // sequence: vec![ - // ActionEventType::KeyPressEvent { - // data: KeyPress { - // keypress: 12, - // - // press_duration: 50, - // }, - // }, - // ActionEventType::KeyPressEvent { - // data: KeyPress { - // keypress: 13, - // - // press_duration: 50, - // }, - // }, - // ], - // trigger: TriggerEventType::KeyPressEvent { - // data: vec![KeyPress { - // keypress: 14, - // - // press_duration: 50, - // }], - // }, - // active: true, - // }], - // active: true, - // }], - // }; + let mut incoming_test: MacroData = MacroData(vec![Collection { + name: "LOL".to_string(), + icon: 'i'.to_string(), + macros: vec![Macro { + name: "Newer string".to_string(), + sequence: vec![ + ActionEventType::KeyPressEvent { + data: KeyPress { + keypress: 12, + + press_duration: 50, + }, + }, + ActionEventType::KeyPressEvent { + data: KeyPress { + keypress: 13, + + press_duration: 50, + }, + }, + ], + trigger: TriggerEventType::KeyPressEvent { + data: vec![KeyPress { + keypress: 5, + + press_duration: 50, + }], + }, + active: true, + }], + active: true, + }]); //testing_macro_full.export_data(); // Get data from the config file. - let mut testing_macro_full: MacroData = push_backend_first(); + println!("READING DATA ORIGINAL:\n{:#?}\n====\nORIGINAL FILE READ.", APPLICATION_STATE.data.read().unwrap()); - // Serve to the frontend. - push_frontend_first(); + //println!("WRITING DATA"); - // Get the triggers linked correctly - let triggers = testing_macro_full.extract_triggers(); + //thread::sleep(time::Duration::from_secs(20)); + //set_data_write_manually_backend(incoming_test); + + //println!("READING MODIFIED DATA:\n{:#?}\n====\nMODIFIED FILE READ.", APPLICATION_STATE.data.read().unwrap()); + + + // let mut testing_macro_full: MacroData = get_configuration(APPLICATION_STATE); + // println!("{:#?}", testing_macro_full); + + // // Serve to the frontend. + // push_frontend_first(); + // + // // Get the triggers linked correctly + // let triggers = testing_macro_full.extract_triggers(); //Print for a check (triggers) - println!("{:#?}", triggers); + //println!("{:#?}", testing_macro_full); + + //println!("{:#?}", &APPLICATION_STATE.read().unwrap().data); //================================================== @@ -228,6 +333,11 @@ pub fn run_this(config: &ApplicationConfig) { // let (schan, rchan) = channel(); let _listener = thread::spawn(move || { + //TESTING + //let trigger_hash = APPLICATION_STATE.data.read().unwrap(); + + //println!("{:#?}", trigger_hash); + listen(move |event| { schan .send(event) @@ -247,7 +357,15 @@ pub fn run_this(config: &ApplicationConfig) { EventType::KeyPress(s) => { //TODO: Make this a hashtable or smth println!("Pressed: {:?}", s); - //testing_macro_full.check_key(&s); + + if s == Key::KpMultiply { + println!("WRITING DATA"); + + set_data_write_manually_backend(incoming_test.clone()); + + println!("NEW CONFIG LOADED?"); + } + check_key(&s); } EventType::KeyRelease(s) => { println!("Released: {:?}", s) diff --git a/src/App.tsx b/src/App.tsx index 7ce607bf..d20882ec 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,31 +1,22 @@ -import { useEffect, useState } from "react"; -import { invoke } from "@tauri-apps/api/tauri"; +import {useEffect, useState} from "react"; +import {invoke} from "@tauri-apps/api/tauri"; import "./App.css"; -import { Flex } from '@chakra-ui/react' -import { Route } from "wouter"; +import {Flex} from '@chakra-ui/react' +import {Route} from "wouter"; import Overview from "./components/Overview"; import AddMacroView from "./components/AddMacroView"; import EditMacroView from "./components/EditMacroView"; -import { Collection } from "./types"; +import {Collection} from "./types"; function App() { const [collections, setCollections] = useState([]) const [isLoading, setLoading] = useState(true); useEffect(() => { - invoke("push_frontend_first").then((res) => { - - // let temp:Collection[] = JSON.parse(res) + invoke("get_configuration").then((res) => { console.log(res) setCollections(res) - if (res.length == 0) { - setCollections([ - {name:"Default", icon: "i", active: true, macros:[]} - ]) - // update backend - } - setLoading(false) }).catch(e => { console.error(e) diff --git a/src/HIDmap.ts b/src/HIDmap.ts index a17fd6b0..00182d01 100644 --- a/src/HIDmap.ts +++ b/src/HIDmap.ts @@ -1,137 +1,149 @@ -enum HidCategory { - General, - LeftModifier, - RightModifier, - Numpad, - Misc, -} - export interface HidInfo { - // -> HID Number - byte: number - // -> displayName - id: string + HIDcode: number + displayString: string webKeyId: string - - // DELETE - category: HidCategory - icon?: string - vkCode?: number } export class Hid { - static get A(): HidInfo { return {byte: 4, id: 'A', category: HidCategory.General, webKeyId: "KeyA" } } - static get B(): HidInfo { return {byte: 2, id: 'B', category: HidCategory.General, webKeyId: "KeyB" } } - static get C(): HidInfo { return {byte: 3, id: 'C', category: HidCategory.General, vkCode: 67, webKeyId: "KeyC" } } - static get D(): HidInfo { return {byte: 4, id: 'D', category: HidCategory.General, vkCode: 68, webKeyId: "KeyD" } } - static get E(): HidInfo { return {byte: 5, id: 'E', category: HidCategory.General, vkCode: 69, webKeyId: "KeyE" } } - static get F(): HidInfo { return {byte: 6, id: 'F', category: HidCategory.General, vkCode: 70, webKeyId: "KeyF" } } - static get G(): HidInfo { return {byte: 7, id: 'G', category: HidCategory.General, vkCode: 71, webKeyId: "KeyG" } } - static get H(): HidInfo { return {byte: 8, id: 'H', category: HidCategory.General, vkCode: 72, webKeyId: "KeyH" } } - static get I(): HidInfo { return {byte: 9, id: 'I', category: HidCategory.General, vkCode: 73, webKeyId: "KeyI" } } - static get J(): HidInfo { return {byte: 10, id: 'J', category: HidCategory.General, vkCode: 74, webKeyId: "KeyJ" } } - static get K(): HidInfo { return {byte: 11, id: 'K', category: HidCategory.General, vkCode: 75, webKeyId: "KeyK" } } - static get L(): HidInfo { return {byte: 12, id: 'L', category: HidCategory.General, vkCode: 76, webKeyId: "KeyL" } } - static get M(): HidInfo { return {byte: 13, id: 'M', category: HidCategory.General, vkCode: 77, webKeyId: "KeyM" } } - static get N(): HidInfo { return {byte: 14, id: 'N', category: HidCategory.General, vkCode: 78, webKeyId: "KeyN" } } - static get O(): HidInfo { return {byte: 15, id: 'O', category: HidCategory.General, vkCode: 79, webKeyId: "KeyO" } } - static get P(): HidInfo { return {byte: 16, id: 'P', category: HidCategory.General, vkCode: 80, webKeyId: "KeyP" } } - static get Q(): HidInfo { return {byte: 17, id: 'Q', category: HidCategory.General, vkCode: 81, webKeyId: "KeyQ" } } - static get R(): HidInfo { return {byte: 18, id: 'R', category: HidCategory.General, vkCode: 82, webKeyId: "KeyR" } } - static get S(): HidInfo { return {byte: 19, id: 'S', category: HidCategory.General, vkCode: 83, webKeyId: "KeyS" } } - static get T(): HidInfo { return {byte: 20, id: 'T', category: HidCategory.General, vkCode: 84, webKeyId: "KeyT" } } - static get U(): HidInfo { return {byte: 21, id: 'U', category: HidCategory.General, vkCode: 85, webKeyId: "KeyU" } } - static get V(): HidInfo { return {byte: 22, id: 'V', category: HidCategory.General, vkCode: 86, webKeyId: "KeyV" } } - static get W(): HidInfo { return {byte: 23, id: 'W', category: HidCategory.General, vkCode: 87, webKeyId: "KeyW" } } - static get X(): HidInfo { return {byte: 24, id: 'X', category: HidCategory.General, vkCode: 88, webKeyId: "KeyX" } } - static get Y(): HidInfo { return {byte: 25, id: 'Y', category: HidCategory.General, vkCode: 89, webKeyId: "KeyY" } } - static get Z(): HidInfo { return {byte: 26, id: 'Z', category: HidCategory.General, vkCode: 90, webKeyId: "KeyZ" } } - - static get N0(): HidInfo { return {byte: 27, id: '0', category: HidCategory.General, vkCode: 48, webKeyId: "Digit0" } } - static get N1(): HidInfo { return {byte: 28, id: '1', category: HidCategory.General, vkCode: 49, webKeyId: "Digit1" } } - static get N2(): HidInfo { return {byte: 29, id: '2', category: HidCategory.General, vkCode: 50, webKeyId: "Digit2" } } - static get N3(): HidInfo { return {byte: 30, id: '3', category: HidCategory.General, vkCode: 51, webKeyId: "Digit3" } } - static get N4(): HidInfo { return {byte: 31, id: '4', category: HidCategory.General, vkCode: 52, webKeyId: "Digit4" } } - static get N5(): HidInfo { return {byte: 32, id: '5', category: HidCategory.General, vkCode: 53, webKeyId: "Digit5" } } - static get N6(): HidInfo { return {byte: 33, id: '6', category: HidCategory.General, vkCode: 54, webKeyId: "Digit6" } } - static get N7(): HidInfo { return {byte: 34, id: '7', category: HidCategory.General, vkCode: 55, webKeyId: "Digit7" } } - static get N8(): HidInfo { return {byte: 35, id: '8', category: HidCategory.General, vkCode: 56, webKeyId: "Digit8" } } - static get N9(): HidInfo { return {byte: 36, id: '9', category: HidCategory.General, vkCode: 57, webKeyId: "Digit9" } } + static get A(): HidInfo { return {HIDcode: 4, displayString: 'A', webKeyId: "KeyA" } } + static get B(): HidInfo { return {HIDcode: 5, displayString: 'B', webKeyId: "KeyB" } } + static get C(): HidInfo { return {HIDcode: 6, displayString: 'C', webKeyId: "KeyC" } } + static get D(): HidInfo { return {HIDcode: 7, displayString: 'D', webKeyId: "KeyD" } } + static get E(): HidInfo { return {HIDcode: 8, displayString: 'E', webKeyId: "KeyE" } } + static get F(): HidInfo { return {HIDcode: 9, displayString: 'F', webKeyId: "KeyF" } } - static get NP0(): HidInfo { return {byte: 37, id: '0', category: HidCategory.Numpad, vkCode: 96, webKeyId: "Numpad0" } } - static get NP1(): HidInfo { return {byte: 38, id: '1', category: HidCategory.Numpad, vkCode: 97, webKeyId: "Numpad1" } } - static get NP2(): HidInfo { return {byte: 39, id: '2', category: HidCategory.Numpad, vkCode: 98, webKeyId: "Numpad2" } } - static get NP3(): HidInfo { return {byte: 40, id: '3', category: HidCategory.Numpad, vkCode: 99, webKeyId: "Numpad3" } } - static get NP4(): HidInfo { return {byte: 41, id: '4', category: HidCategory.Numpad, vkCode: 100, webKeyId: "Numpad4" } } - static get NP5(): HidInfo { return {byte: 42, id: '5', category: HidCategory.Numpad, vkCode: 101, webKeyId: "Numpad5" } } - static get NP6(): HidInfo { return {byte: 43, id: '6', category: HidCategory.Numpad, vkCode: 102, webKeyId: "Numpad6" } } - static get NP7(): HidInfo { return {byte: 44, id: '7', category: HidCategory.Numpad, vkCode: 103, webKeyId: "Numpad7" } } - static get NP8(): HidInfo { return {byte: 45, id: '8', category: HidCategory.Numpad, vkCode: 104, webKeyId: "Numpad8" } } - static get NP9(): HidInfo { return {byte: 46, id: '9', category: HidCategory.Numpad, vkCode: 105, webKeyId: "Numpad9" } } + static get G(): HidInfo { return {HIDcode: 10, displayString: 'G', webKeyId: "KeyG" } } + static get H(): HidInfo { return {HIDcode: 11, displayString: 'H', webKeyId: "KeyH" } } + static get I(): HidInfo { return {HIDcode: 12, displayString: 'I', webKeyId: "KeyI" } } + static get J(): HidInfo { return {HIDcode: 13, displayString: 'J', webKeyId: "KeyJ" } } + static get K(): HidInfo { return {HIDcode: 14, displayString: 'K', webKeyId: "KeyK" } } + static get L(): HidInfo { return {HIDcode: 15, displayString: 'L', webKeyId: "KeyL" } } + static get M(): HidInfo { return {HIDcode: 16, displayString: 'M', webKeyId: "KeyM" } } + static get N(): HidInfo { return {HIDcode: 17, displayString: 'N', webKeyId: "KeyN" } } + static get O(): HidInfo { return {HIDcode: 18, displayString: 'O', webKeyId: "KeyO" } } + static get P(): HidInfo { return {HIDcode: 19, displayString: 'P', webKeyId: "KeyP" } } - static get ENTER(): HidInfo { return {byte: 47, id: 'Enter', category: HidCategory.General, vkCode: 13, webKeyId: "Enter" } } - static get ESCAPE(): HidInfo { return {byte: 48, id: 'Escape', category: HidCategory.General, vkCode: 27, webKeyId: "Escape" } } - static get BACKSPACE(): HidInfo { return {byte: 49, id: 'Backspace', category: HidCategory.General, vkCode: 8, webKeyId: "Backspace" } } - static get TAB(): HidInfo { return {byte: 50, id: 'Tab', category: HidCategory.General, vkCode: 9, webKeyId: "Tab" } } - static get SPACE(): HidInfo { return {byte: 51, id: 'Space', category: HidCategory.General, vkCode: 32, webKeyId: "Space" } } - static get MINUS(): HidInfo { return {byte: 52, id: '-', category: HidCategory.General, vkCode: 189, webKeyId: "Minus" } } - static get EQUAL(): HidInfo { return {byte: 53, id: '=', category: HidCategory.General, vkCode: 187, webKeyId: "Equal" } } - static get BRACKETL(): HidInfo { return {byte: 54, id: '[', category: HidCategory.General, vkCode: 219, webKeyId: "BracketLeft" } } - static get BRACKETR(): HidInfo { return {byte: 55, id: ']', category: HidCategory.General, vkCode: 221, webKeyId: "BracketRight" } } - static get BACKSLASH(): HidInfo { return {byte: 56, id: '\\', category: HidCategory.General, vkCode: 220, webKeyId: "Backslash" } } - static get SEMICOLON(): HidInfo { return {byte: 57, id: ';', category: HidCategory.General, vkCode: 186, webKeyId: "Semicolon" } } - static get QUOTE(): HidInfo { return {byte: 58, id: '"', category: HidCategory.General, vkCode: 222, webKeyId: "Quote" } } - static get BACKQUOTE(): HidInfo { return {byte: 59, id: '`', category: HidCategory.General, vkCode: 192, webKeyId: "Backquote" } } - static get COMMA(): HidInfo { return {byte: 60, id: ',', category: HidCategory.General, vkCode: 188, webKeyId: "Comma" } } - static get PERIOD(): HidInfo { return {byte: 61, id: '.', category: HidCategory.General, vkCode: 190, webKeyId: "Period" } } - static get SLASH(): HidInfo { return {byte: 62, id: '/', category: HidCategory.General, vkCode: 191, webKeyId: "Slash" } } - static get CAPSLOCK(): HidInfo { return {byte: 63, id: 'Caps Lock', category: HidCategory.General, vkCode: 20, webKeyId: "CapsLock" } } + static get Q(): HidInfo { return {HIDcode: 20, displayString: 'Q', webKeyId: "KeyQ" } } + static get R(): HidInfo { return {HIDcode: 21, displayString: 'R', webKeyId: "KeyR" } } + static get S(): HidInfo { return {HIDcode: 22, displayString: 'S', webKeyId: "KeyS" } } + static get T(): HidInfo { return {HIDcode: 23, displayString: 'T', webKeyId: "KeyT" } } + static get U(): HidInfo { return {HIDcode: 24, displayString: 'U', webKeyId: "KeyU" } } + static get V(): HidInfo { return {HIDcode: 25, displayString: 'V', webKeyId: "KeyV" } } + static get W(): HidInfo { return {HIDcode: 26, displayString: 'W', webKeyId: "KeyW" } } + static get X(): HidInfo { return {HIDcode: 27, displayString: 'X', webKeyId: "KeyX" } } + static get Y(): HidInfo { return {HIDcode: 28, displayString: 'Y', webKeyId: "KeyY" } } + static get Z(): HidInfo { return {HIDcode: 29, displayString: 'Z', webKeyId: "KeyZ" } } + + static get N1(): HidInfo { return {HIDcode: 30, displayString: '1', webKeyId: "Digit1" } } + static get N2(): HidInfo { return {HIDcode: 31, displayString: '2', webKeyId: "Digit2" } } + static get N3(): HidInfo { return {HIDcode: 32, displayString: '3', webKeyId: "Digit3" } } + static get N4(): HidInfo { return {HIDcode: 33, displayString: '4', webKeyId: "Digit4" } } + static get N5(): HidInfo { return {HIDcode: 34, displayString: '5', webKeyId: "Digit5" } } + static get N6(): HidInfo { return {HIDcode: 35, displayString: '6', webKeyId: "Digit6" } } + static get N7(): HidInfo { return {HIDcode: 36, displayString: '7', webKeyId: "Digit7" } } + static get N8(): HidInfo { return {HIDcode: 37, displayString: '8', webKeyId: "Digit8" } } + static get N9(): HidInfo { return {HIDcode: 38, displayString: '9', webKeyId: "Digit9" } } + static get N0(): HidInfo { return {HIDcode: 39, displayString: '0', webKeyId: "Digit0" } } - static get F1(): HidInfo { return {byte: 64, id: 'F1', category: HidCategory.General, vkCode: 112, webKeyId: "F1" } } - static get F2(): HidInfo { return {byte: 65, id: 'F2', category: HidCategory.General, vkCode: 113, webKeyId: "F2" } } - static get F3(): HidInfo { return {byte: 66, id: 'F3', category: HidCategory.General, vkCode: 114, webKeyId: "F3" } } - static get F4(): HidInfo { return {byte: 67, id: 'F4', category: HidCategory.General, vkCode: 115, webKeyId: "F4" } } - static get F5(): HidInfo { return {byte: 68, id: 'F5', category: HidCategory.General, vkCode: 116, webKeyId: "F5" } } - static get F6(): HidInfo { return {byte: 69, id: 'F6', category: HidCategory.General, vkCode: 117, webKeyId: "F6" } } - static get F7(): HidInfo { return {byte: 70, id: 'F7', category: HidCategory.General, vkCode: 118, webKeyId: "F7" } } - static get F8(): HidInfo { return {byte: 71, id: 'F8', category: HidCategory.General, vkCode: 119, webKeyId: "F8" } } - static get F9(): HidInfo { return {byte: 72, id: 'F9', category: HidCategory.General, vkCode: 120, webKeyId: "F9" } } - static get F10(): HidInfo { return {byte: 73, id: 'F10', category: HidCategory.General, vkCode: 121, webKeyId: "F10" } } - static get F11(): HidInfo { return {byte: 74, id: 'F11', category: HidCategory.General, vkCode: 122, webKeyId: "F11" } } - static get F12(): HidInfo { return {byte: 75, id: 'F12', category: HidCategory.General, vkCode: 123, webKeyId: "F12" } } + static get ENTER(): HidInfo { return {HIDcode: 40, displayString: 'Enter', webKeyId: "Enter" } } + static get ESCAPE(): HidInfo { return {HIDcode: 41, displayString: 'Escape', webKeyId: "Escape" } } + static get BACKSPACE(): HidInfo { return {HIDcode: 42, displayString: 'Backspace', webKeyId: "Backspace" } } + static get TAB(): HidInfo { return {HIDcode: 43, displayString: 'Tab', webKeyId: "Tab" } } + static get SPACE(): HidInfo { return {HIDcode: 44, displayString: 'Space', webKeyId: "Space" } } + static get MINUS(): HidInfo { return {HIDcode: 45, displayString: '-', webKeyId: "Minus" } } + static get EQUAL(): HidInfo { return {HIDcode: 46, displayString: '=', webKeyId: "Equal" } } + static get BRACKETL(): HidInfo { return {HIDcode: 47, displayString: '[', webKeyId: "BracketLeft" } } + static get BRACKETR(): HidInfo { return {HIDcode: 48, displayString: ']', webKeyId: "BracketRight" } } + static get BACKSLASH(): HidInfo { return {HIDcode: 49, displayString: '\\', webKeyId: "Backslash" } } - static get PRINTSCREEN(): HidInfo { return {byte: 76, id: 'Print Screen', category: HidCategory.General, vkCode: 44, webKeyId: "PrintScreen" } } - static get SCROLLLOCK(): HidInfo { return {byte: 77, id: 'Scroll Lock', category: HidCategory.General, vkCode: 145, webKeyId: "ScrollLock" } } - static get PAUSE(): HidInfo { return {byte: 78, id: 'Pause', category: HidCategory.General, vkCode: 19, webKeyId: "Pause" } } - static get INSERT(): HidInfo { return {byte: 79, id: 'Insert', category: HidCategory.General, vkCode: 45, webKeyId: "Insert" } } - static get HOME(): HidInfo { return {byte: 80, id: 'Home', category: HidCategory.General, vkCode: 36, webKeyId: "Home" } } - static get PAGEUP(): HidInfo { return {byte: 81, id: 'Page Up', category: HidCategory.General, vkCode: 33, webKeyId: "PageUp" } } - static get DELETE(): HidInfo { return {byte: 82, id: 'Delete', category: HidCategory.General, vkCode: 46, webKeyId: "Delete" } } - static get END(): HidInfo { return {byte: 83, id: 'End', category: HidCategory.General, vkCode: 35, webKeyId: "End" } } - static get PAGEDOWN(): HidInfo { return {byte: 84, id: 'Page Down', category: HidCategory.General, vkCode: 34, webKeyId: "PageDown" } } + static get SEMICOLON(): HidInfo { return {HIDcode: 51, displayString: ';', webKeyId: "Semicolon" } } + static get QUOTE(): HidInfo { return {HIDcode: 52, displayString: '"', webKeyId: "Quote" } } + static get BACKQUOTE(): HidInfo { return {HIDcode: 53, displayString: '`', webKeyId: "Backquote" } } + static get COMMA(): HidInfo { return {HIDcode: 54, displayString: ',', webKeyId: "Comma" } } + static get PERIOD(): HidInfo { return {HIDcode: 55, displayString: '.', webKeyId: "Period" } } + static get SLASH(): HidInfo { return {HIDcode: 56, displayString: '/', webKeyId: "Slash" } } + static get CAPSLOCK(): HidInfo { return {HIDcode: 57, displayString: 'Caps Lock', webKeyId: "CapsLock" } } + static get F1(): HidInfo { return {HIDcode: 58, displayString: 'F1', webKeyId: "F1" } } + static get F2(): HidInfo { return {HIDcode: 59, displayString: 'F2', webKeyId: "F2" } } - static get ARROWR(): HidInfo { return {byte: 85, id: 'Right Arrow', category: HidCategory.General, vkCode: 39, webKeyId: "ArrowRight" } } - static get ARROWL(): HidInfo { return {byte: 86, id: 'Left Arrow', category: HidCategory.General, vkCode: 37, webKeyId: "ArrowLeft" } } - static get ARROWD(): HidInfo { return {byte: 87, id: 'Down Arrow', category: HidCategory.General, vkCode: 40, webKeyId: "ArrowDown" } } - static get ARROWU(): HidInfo { return {byte: 88, id: 'Up Arrow', category: HidCategory.General, vkCode: 38, webKeyId: "ArrowUp" } } + static get F3(): HidInfo { return {HIDcode: 60, displayString: 'F3', webKeyId: "F3" } } + static get F4(): HidInfo { return {HIDcode: 61, displayString: 'F4', webKeyId: "F4" } } + static get F5(): HidInfo { return {HIDcode: 62, displayString: 'F5', webKeyId: "F5" } } + static get F6(): HidInfo { return {HIDcode: 63, displayString: 'F6', webKeyId: "F6" } } + static get F7(): HidInfo { return {HIDcode: 64, displayString: 'F7', webKeyId: "F7" } } + static get F8(): HidInfo { return {HIDcode: 65, displayString: 'F8', webKeyId: "F8" } } + static get F9(): HidInfo { return {HIDcode: 66, displayString: 'F9', webKeyId: "F9" } } + static get F10(): HidInfo { return {HIDcode: 67, displayString: 'F10', webKeyId: "F10" } } + static get F11(): HidInfo { return {HIDcode: 68, displayString: 'F11', webKeyId: "F11" } } + static get F12(): HidInfo { return {HIDcode: 69, displayString: 'F12', webKeyId: "F12" } } - static get NUMLOCK(): HidInfo { return {byte: 89, id: 'Num Lock', category: HidCategory.Numpad, vkCode: 44, webKeyId: "NumLock" } } - static get NUMDIVIDE(): HidInfo { return {byte: 90, id: 'Numpad Divide', category: HidCategory.Numpad, vkCode: 111, webKeyId: "NumpadDivide" } } - static get NUMMULTIPLY(): HidInfo { return {byte: 91, id: 'Numpad Multiply', category: HidCategory.Numpad, vkCode: 106, webKeyId: "NumpadMultiply" } } - static get NUMSUBTRACT(): HidInfo { return {byte: 92, id: 'Numpad Subtract', category: HidCategory.Numpad, vkCode: 109, webKeyId: "NumpadSubtract" } } - static get NUMADD(): HidInfo { return {byte: 93, id: 'Numpad Add', category: HidCategory.Numpad, vkCode: 107, webKeyId: "NumpadAdd" } } - static get NUMENTER(): HidInfo { return {byte: 94, id: 'Numpad Enter', category: HidCategory.Numpad, vkCode: 13, webKeyId: "NumpadEnter" } } - static get NUMDECIMAL(): HidInfo { return {byte: 95, id: 'Numpad Decimal', category: HidCategory.Numpad, vkCode: 110, webKeyId: "NumpadDecimal" } } + static get PRINTSCREEN(): HidInfo { return {HIDcode: 70, displayString: 'Print Screen', webKeyId: "PrintScreen" } } + static get SCROLLLOCK(): HidInfo { return {HIDcode: 71, displayString: 'Scroll Lock', webKeyId: "ScrollLock" } } + static get PAUSE(): HidInfo { return {HIDcode: 72, displayString: 'Pause', webKeyId: "Pause" } } + static get INSERT(): HidInfo { return {HIDcode: 73, displayString: 'Insert', webKeyId: "Insert" } } + static get HOME(): HidInfo { return {HIDcode: 74, displayString: 'Home', webKeyId: "Home" } } + static get PAGEUP(): HidInfo { return {HIDcode: 75, displayString: 'Page Up', webKeyId: "PageUp" } } + static get DELETE(): HidInfo { return {HIDcode: 76, displayString: 'Delete', webKeyId: "Delete" } } + static get END(): HidInfo { return {HIDcode: 77, displayString: 'End', webKeyId: "End" } } + static get PAGEDOWN(): HidInfo { return {HIDcode: 78, displayString: 'Page Down', webKeyId: "PageDown" } } + static get ARROWR(): HidInfo { return {HIDcode: 79, displayString: 'Right Arrow', webKeyId: "ArrowRight" } } + + static get ARROWL(): HidInfo { return {HIDcode: 80, displayString: 'Left Arrow', webKeyId: "ArrowLeft" } } + static get ARROWD(): HidInfo { return {HIDcode: 81, displayString: 'Down Arrow', webKeyId: "ArrowDown" } } + static get ARROWU(): HidInfo { return {HIDcode: 82, displayString: 'Up Arrow', webKeyId: "ArrowUp" } } + static get NUMLOCK(): HidInfo { return {HIDcode: 83, displayString: 'Num Lock', webKeyId: "NumLock" } } + static get NUMDIVIDE(): HidInfo { return {HIDcode: 84, displayString: 'Numpad Divide', webKeyId: "NumpadDivide" } } + static get NUMMULTIPLY(): HidInfo { return {HIDcode: 85, displayString: 'Numpad Multiply', webKeyId: "NumpadMultiply" } } + static get NUMSUBTRACT(): HidInfo { return {HIDcode: 86, displayString: 'Numpad Subtract', webKeyId: "NumpadSubtract" } } + static get NUMADD(): HidInfo { return {HIDcode: 87, displayString: 'Numpad Add', webKeyId: "NumpadAdd" } } + static get NUMENTER(): HidInfo { return {HIDcode: 88, displayString: 'Numpad Enter', webKeyId: "NumpadEnter" } } + static get NP1(): HidInfo { return {HIDcode: 89, displayString: '1', webKeyId: "Numpad1" } } + + static get NP2(): HidInfo { return {HIDcode: 90, displayString: '2', webKeyId: "Numpad2" } } + static get NP3(): HidInfo { return {HIDcode: 91, displayString: '3', webKeyId: "Numpad3" } } + static get NP4(): HidInfo { return {HIDcode: 92, displayString: '4', webKeyId: "Numpad4" } } + static get NP5(): HidInfo { return {HIDcode: 93, displayString: '5', webKeyId: "Numpad5" } } + static get NP6(): HidInfo { return {HIDcode: 94, displayString: '6', webKeyId: "Numpad6" } } + static get NP7(): HidInfo { return {HIDcode: 95, displayString: '7', webKeyId: "Numpad7" } } + static get NP8(): HidInfo { return {HIDcode: 96, displayString: '8', webKeyId: "Numpad8" } } + static get NP9(): HidInfo { return {HIDcode: 97, displayString: '9', webKeyId: "Numpad9" } } + static get NP0(): HidInfo { return {HIDcode: 98, displayString: '0', webKeyId: "Numpad0" } } + static get NUMDECIMAL(): HidInfo { return {HIDcode: 99, displayString: 'Numpad Decimal', webKeyId: "NumpadDecimal" } } - static get SHIFTL(): HidInfo { return {byte: 96, id: 'Left Shift', category: HidCategory.LeftModifier, vkCode: 16, webKeyId: "ShiftLeft" } } - static get CONTROLL(): HidInfo { return {byte: 97, id: 'Left Control', category: HidCategory.LeftModifier, vkCode: 17, webKeyId: "ControlLeft" } } - static get ALTL(): HidInfo { return {byte: 98, id: 'Left Alt', category: HidCategory.LeftModifier, vkCode: 18, webKeyId: "AltLeft" } } - static get METAL(): HidInfo { return {byte: 99, id: 'Left Meta', category: HidCategory.LeftModifier, vkCode: 91, webKeyId: "MetaLeft" } } + /** KEYS TO ADD + * Internation Backslash + * Context Menu + * Power + * Numpad Equal + * F13 - 24 + * Open + * Help + * Again + * Undo + * Cut + * Copy + * Paste + * Find + * Volume Mute + * Volume Up + * Volume Down + * Numpad Comma + * International RO + * Kana Mode + * International Yen + * Convert + * NonConvert + * Lang1 - 4 + */ - static get SHIFTR(): HidInfo { return {byte: 100, id: 'Right Shift', category: HidCategory.RightModifier, vkCode: 16, webKeyId: "ShiftRight" } } - static get CONTROLR(): HidInfo { return {byte: 101, id: 'Right Control', category: HidCategory.RightModifier, vkCode: 17, webKeyId: "ControlRight" } } - static get ALTR(): HidInfo { return {byte: 102, id: 'Right Alt', category: HidCategory.RightModifier, vkCode: 18, webKeyId: "AltRight" } } - static get METAR(): HidInfo { return {byte: 103, id: 'Right Meta', category: HidCategory.RightModifier, vkCode: 92, webKeyId: "MetaRight" } } + static get CONTROLL(): HidInfo { return {HIDcode: 224, displayString: 'Left Control', webKeyId: "ControlLeft" } } + static get SHIFTL(): HidInfo { return {HIDcode: 225, displayString: 'Left Shift', webKeyId: "ShiftLeft" } } + static get ALTL(): HidInfo { return {HIDcode: 226, displayString: 'Left Alt', webKeyId: "AltLeft" } } + static get METAL(): HidInfo { return {HIDcode: 227, displayString: 'Left Meta', webKeyId: "MetaLeft" } } + static get CONTROLR(): HidInfo { return {HIDcode: 228, displayString: 'Right Control', webKeyId: "ControlRight" } } + static get SHIFTR(): HidInfo { return {HIDcode: 229, displayString: 'Right Shift', webKeyId: "ShiftRight" } } + static get ALTR(): HidInfo { return {HIDcode: 230, displayString: 'Right Alt', webKeyId: "AltRight" } } + static get METAR(): HidInfo { return {HIDcode: 231, displayString: 'Right Meta', webKeyId: "MetaRight" } } static readonly all: HidInfo[] = [ Hid.A, @@ -247,6 +259,6 @@ export const webCodeHIDLookup = new Map( ) export const HIDLookup = new Map( Hid.all - .filter(hid => hid.byte !== undefined) - .map(hid => [hid.byte!, hid]) + .filter(hid => hid.HIDcode !== undefined) + .map(hid => [hid.HIDcode!, hid]) ) \ No newline at end of file diff --git a/src/components/AddMacroView.tsx b/src/components/AddMacroView.tsx index 4df0d164..4a5a1d82 100644 --- a/src/components/AddMacroView.tsx +++ b/src/components/AddMacroView.tsx @@ -1,9 +1,9 @@ -import { Input, Button, Flex, HStack, useColorMode, VStack, Text, IconButton, Alert, AlertIcon, AlertTitle, AlertDescription, Kbd } from '@chakra-ui/react' -import { EditIcon } from '@chakra-ui/icons' +import { BaseSyntheticEvent, useEffect, useState } from 'react'; import { Link, useLocation, useRoute } from 'wouter'; -import { useEffect, useState } from 'react'; import { Collection, Keypress } from "../types"; import { webCodeHIDLookup, HIDLookup } from '../HIDmap'; +import { Input, Button, Flex, HStack, VStack, Text, Alert, AlertIcon, Kbd } from '@chakra-ui/react' +import { EditIcon } from '@chakra-ui/icons' type Props = { collections: Collection[] @@ -16,13 +16,13 @@ const AddMacroView = ({collections}: Props) => { const [triggerKeys, setTriggerKeys] = useState([]) const [location, setLocation] = useLocation(); - const addTriggerKey = (event:any) => { + const addTriggerKey = (event:KeyboardEvent) => { event.preventDefault() - console.log(event) - let HIDcode = webCodeHIDLookup.get(event.code)?.vkCode + + let HIDcode = webCodeHIDLookup.get(event.code)?.HIDcode if (HIDcode == undefined) { return } - let keypress:Keypress = { keypress:HIDcode, press_duration:0} + let keypress:Keypress = { keypress:HIDcode, press_duration:0 } setTriggerKeys(triggerKeys => [...triggerKeys, keypress]) if (triggerKeys.length == 3) { setRecording(false) } @@ -32,38 +32,35 @@ const AddMacroView = ({collections}: Props) => { if (!recording) { return } // Does not get mouse input for trigger window.addEventListener("keydown", addTriggerKey, false) + // TODO: stop backend trigger listening return () => { window.removeEventListener("keydown", addTriggerKey, false) + // TODO: start backend trigger listening } }, [addTriggerKey]) const onRecordButtonPress = () => { - if (!recording) { - setTriggerKeys([]) - } - + if (!recording) { setTriggerKeys([]) } setRecording(!recording) } const onSaveButtonPress = () => { if (match) { - collections[parseInt(params.cid)].macros.push({name: macroName, active: true, trigger:{ type: "KeyPressEvent", data: triggerKeys }, sequence: ""}) + collections[parseInt(params.cid)].macros.push({name: macroName, active: true, trigger:{ type: "KeyPressEvent", data: triggerKeys }, sequence: []}) } + // update backend here setLocation("/") } - const onMacroNameChange = (event:any) => { + const onMacroNameChange = (event:BaseSyntheticEvent) => { setMacroName(event.target.value) } return ( + {/** Header */} - - - + @@ -78,15 +75,16 @@ const AddMacroView = ({collections}: Props) => { Trigger Key(s) } onClick={onRecordButtonPress} colorScheme={recording ? 'red' : 'gray'}>Record - {recording && - - Input recording in progress. - + {recording && + + + Input recording in progress. + } {triggerKeys.map((key:Keypress, index:number) => - {HIDLookup.get(key.keypress)?.id} + {HIDLookup.get(key.keypress)?.displayString} )} diff --git a/src/components/CollectionButton.tsx b/src/components/CollectionButton.tsx index dce2ff5d..62a1324b 100644 --- a/src/components/CollectionButton.tsx +++ b/src/components/CollectionButton.tsx @@ -1,16 +1,21 @@ -import { Button } from '@chakra-ui/react' +import { Box, Button, Circle } from '@chakra-ui/react' import { Collection } from '../types' type Props = { collection: Collection index: number - onClick: (params:any) => any + isFocused: boolean + setFocus: (index:number) => void + toggleCollection: (index:number) => void } -function CollectionButton({collection, index, onClick}: Props) { +function CollectionButton({collection, index, isFocused, setFocus, toggleCollection}: Props) { return ( - + + + toggleCollection(index)}> + ) } diff --git a/src/components/EditMacroView.tsx b/src/components/EditMacroView.tsx index eb957b92..ab7ba589 100644 --- a/src/components/EditMacroView.tsx +++ b/src/components/EditMacroView.tsx @@ -1,9 +1,9 @@ -import { Input, Button, Flex, HStack, useColorMode, VStack, Text, IconButton, Alert, AlertIcon, AlertTitle, AlertDescription, Kbd } from '@chakra-ui/react' -import { AddIcon, EditIcon } from '@chakra-ui/icons' +import { BaseSyntheticEvent, useEffect, useState } from 'react'; import { Link, useLocation, useRoute } from 'wouter'; -import { useEffect, useState } from 'react'; import { Collection, Keypress, Macro } from "../types"; import { webCodeHIDLookup, HIDLookup } from '../HIDmap'; +import { Input, Button, Flex, HStack, VStack, Text, Alert, AlertIcon, Kbd } from '@chakra-ui/react' +import { EditIcon } from '@chakra-ui/icons' type Props = { collections: Collection[] @@ -16,10 +16,9 @@ const EditMacroView = ({collections}: Props) => { const [triggerKeys, setTriggerKeys] = useState([]) const [location, setLocation] = useLocation(); - let macro:Macro - useEffect(() => { if (match) { + let macro:Macro macro = collections[parseInt(params.cid)].macros[parseInt(params.mid)] setMacroName(macro.name) setTriggerKeys(macro.trigger.data) @@ -29,13 +28,13 @@ const EditMacroView = ({collections}: Props) => { } }, []) - const addTriggerKey = (event:any) => { + const addTriggerKey = (event:KeyboardEvent) => { event.preventDefault() - let HIDcode = webCodeHIDLookup.get(event.code)?.vkCode + let HIDcode = webCodeHIDLookup.get(event.code)?.HIDcode if (HIDcode == undefined) { return } - let keypress:Keypress = { keypress:HIDcode, press_duration:0} + let keypress:Keypress = { keypress:HIDcode, press_duration:0 } setTriggerKeys(triggerKeys => [...triggerKeys, keypress]) if (triggerKeys.length == 3) { setRecording(false) } @@ -45,38 +44,35 @@ const EditMacroView = ({collections}: Props) => { if (!recording) { return } // Does not get mouse input for trigger window.addEventListener("keydown", addTriggerKey, false) + // TODO: stop backend trigger listening return () => { window.removeEventListener("keydown", addTriggerKey, false) + // TODO: start backend trigger listening } }, [addTriggerKey]) const onRecordButtonPress = () => { - if (!recording) { - setTriggerKeys([]) - } - + if (!recording) { setTriggerKeys([]) } setRecording(!recording) } const onSaveButtonPress = () => { if (match) { - collections[parseInt(params.cid)].macros[parseInt(params.mid)] = {name: macroName, active: true, trigger: { type: "KeyPressEvent", data: triggerKeys }, sequence: ""} + collections[parseInt(params.cid)].macros[parseInt(params.mid)] = {name: macroName, active: true, trigger: { type: "KeyPressEvent", data: triggerKeys }, sequence: []} } + // update backend here setLocation("/") } - const onMacroNameChange = (event:any) => { + const onMacroNameChange = (event:BaseSyntheticEvent) => { setMacroName(event.target.value) } return ( + {/** Header */} - - - + @@ -100,7 +96,7 @@ const EditMacroView = ({collections}: Props) => { {triggerKeys.map((key:Keypress, index:number) => - {HIDLookup.get(key.keypress)?.id} + {HIDLookup.get(key.keypress)?.displayString} )} diff --git a/src/components/MacroCard.tsx b/src/components/MacroCard.tsx index 3064ca77..73cf5025 100644 --- a/src/components/MacroCard.tsx +++ b/src/components/MacroCard.tsx @@ -9,27 +9,24 @@ type Props = { macro: Macro index: number collectionIndex: number - onDelete: (index:number) => any + onDelete: (index:number) => void } function MacroCard({macro, index, collectionIndex, onDelete}: Props) { - const [trigger, setTrigger] = useState() + const [trigger, setTrigger] = useState() useEffect(() => { - console.log(macro) - console.log(macro.trigger) - setTrigger(macro.trigger) - let temp:Keypress[] = macro.trigger.data - console.log(temp) - }, []) + setTrigger(macro.trigger.data) + }, [macro.trigger.data]) const onToggle = (event:any) => { macro.active = event.target.checked + // update backend } return ( - {/** Header */} + {/** Top Row */} @@ -47,14 +44,14 @@ function MacroCard({macro, index, collectionIndex, onDelete}: Props) { - {/** Trigger Display */} + {/** Trigger Keys Display */} - {trigger?.data.map((key:Keypress, index:number) => - {HIDLookup.get(key.keypress)?.id} + {trigger?.map((key:Keypress, index:number) => + {HIDLookup.get(key.keypress)?.displayString} )} - {/** Misc */} + {/** Buttons */} diff --git a/src/components/MacroView.tsx b/src/components/MacroView.tsx deleted file mode 100644 index ccf68b38..00000000 --- a/src/components/MacroView.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Box, Button, Flex, HStack, useColorMode, VStack, Text, IconButton } from '@chakra-ui/react' -import { AddIcon, EditIcon } from '@chakra-ui/icons' -import { Link } from 'wouter'; - -type Props = {} - -const MacroView = (props: Props) => { - return ( - - - - - - ) -} - -export default MacroView \ No newline at end of file diff --git a/src/components/Overview.tsx b/src/components/Overview.tsx index 66942b0b..a08e1d27 100644 --- a/src/components/Overview.tsx +++ b/src/components/Overview.tsx @@ -1,10 +1,11 @@ -import { useEffect, useState } from 'react' -import { Box, Button, Flex, HStack, useColorMode, VStack, Text, IconButton, Modal, ModalOverlay, ModalContent, ModalHeader, ModalFooter, ModalBody, ModalCloseButton, useDisclosure, Input } from '@chakra-ui/react' -import { AddIcon, EditIcon } from '@chakra-ui/icons' +import { BaseSyntheticEvent, useEffect, useState } from 'react' +import { invoke } from "@tauri-apps/api/tauri"; import MacroCard from "./MacroCard"; import { Collection, Macro } from "../types"; import { Link } from 'wouter'; import CollectionButton from './CollectionButton'; +import { Box, Button, Flex, HStack, useColorMode, VStack, Text, IconButton, Modal, ModalOverlay, ModalContent, ModalHeader, ModalFooter, ModalBody, ModalCloseButton, useDisclosure, Input } from '@chakra-ui/react' +import { AddIcon, EditIcon } from '@chakra-ui/icons' type Props = { collections: Collection[] @@ -16,6 +17,7 @@ function Overview({collections}: Props) { const { isOpen: isOpenRenameCollection, onOpen: onOpenRenameCollection, onClose: onCloseRenameCollection } = useDisclosure() const [collectionName, setCollectionName] = useState("") const [collectionIndex, setCollectionIndex] = useState(0) + const [canUseCollectionName, setCanUseCollectionName] = useState(false) useEffect(() => { for (let i = 0; i < collections.length; i++) { @@ -27,41 +29,59 @@ function Overview({collections}: Props) { }, []) const onAddCollectionButtonPress = () => { + console.log("add collection button pressed") collections.push({active: false, icon:"i", macros: [], name: collectionName }) + // update backend here + invoke("set_configuration", { frontendData: collections }).then((res) => { + console.log(res) + }).catch(e => { + console.error(e) + }) onCloseNewCollection() } - const onCollectionNameChange = (event:any) => { - setCollectionName(event.target.value) - } + const onCollectionNameChange = (event:BaseSyntheticEvent) => { + let newName:string = event.target.value + newName = newName.trim() - const onCollectionButtonPress = (newActiveIndex:number) => { + setCollectionName(newName) for (let i = 0; i < collections.length; i++) { const collection = collections[i]; - if (i == newActiveIndex) { - collection.active = true - } else { - collection.active = false + if (collection.name.toUpperCase() === newName.toUpperCase()) { + setCanUseCollectionName(false) + return } } + setCanUseCollectionName(true) + } + const onCollectionButtonPress = (newActiveIndex:number) => { setCollectionIndex(newActiveIndex) } + const onCollectionToggle = (index:number) => { + collections[index].active = !collections[index].active + setCanUseCollectionName(!canUseCollectionName) + // update backend here + } + const onRenameCollection = () => { collections[collectionIndex].name = collectionName onCloseRenameCollection() + // update backend here } const onCollectionDelete = () => { collections.splice(collectionIndex, 1) collections[0].active = true setCollectionIndex(0) + // update backend here } const onMacroDelete = (macroIndex:number) => { collections[collectionIndex].macros.splice(macroIndex, 1) setCollectionName("reset") + // update backend here } return ( @@ -69,7 +89,7 @@ function Overview({collections}: Props) { {/** Left Side Panel */} {collections.map((collection:Collection, index:number) => - + )}