diff --git a/components/Dropdown.tsx.scss b/components/Dropdown.tsx.scss
index d3fa004..7ca1522 100644
--- a/components/Dropdown.tsx.scss
+++ b/components/Dropdown.tsx.scss
@@ -3,7 +3,7 @@
font-size: 16px;
width: 100%;
- border-radius: 3px;
+ border-radius: 4px;
color: var(--text-normal);
background-color: var(--input-background);
border: none;
diff --git a/components/KeybindInput.tsx b/components/KeybindInput.tsx
new file mode 100644
index 0000000..1f31753
--- /dev/null
+++ b/components/KeybindInput.tsx
@@ -0,0 +1,109 @@
+import { keyToStr, strToKey } from '../util/keyUtil.js'
+import { css, classes } from './KeybindInput.tsx.scss'
+
+const {
+ solid: {
+ createSignal
+ },
+ ui: {
+ Text,
+ injectCss
+ }
+} = shelter
+
+interface Props {
+ onKeybindChange(keybind: number[]): void
+
+ // style overrides
+ style?: string
+ disabled?: boolean
+}
+
+let injectedCss = false
+
+export function KeybindInput(props: Props) {
+ if (!injectedCss) {
+ injectedCss = true
+ injectCss(css)
+ }
+
+ const [recording, setRecording] = createSignal(false)
+ // numbers mean (in order)
+ const [keybind, setKeybind] = createSignal([])
+
+ const keyDown = (e) => {
+ // If the key is already in the keybind, don't add it again
+ if (keybind().includes(e.key) || keybind().includes(e.key.toLowerCase())) {
+ return
+ }
+
+ // if ctrl, alt, or shift, add it to the front of the keybind
+ switch (e.key) {
+ case 'Control':
+ case 'Alt':
+ case 'Shift':
+ case 'Meta':
+ setKeybind([e.key, ...keybind()])
+ break
+ default:
+ setKeybind([...keybind(), e.key.toLowerCase()])
+ }
+ }
+
+ const keyUp = (e) => {
+ setKeybind(keybind().filter((k) => k !== e.key && k !== e.key.toLowerCase()))
+ }
+
+ const setRecordingState = () => {
+ if (recording()) {
+ // Remove all event listeners
+ window.removeEventListener('keydown', keyDown),
+ window.removeEventListener('keyup', keyUp)
+
+ // Set the keybind
+ props.onKeybindChange(keybind())
+
+ setRecording(false)
+
+ return
+ }
+
+ // Clear the keybind
+ setKeybind([])
+
+ // Create event listeners to set the keybind based on what is being held down
+ // Order should be (if they are pressed): Ctrl -> Alt -> Shift -> Everything else
+ // If a key is released, it should be removed from the keybind
+ window.addEventListener('keydown', keyDown),
+ window.addEventListener('keyup', keyUp)
+
+ setRecording(true)
+ }
+
+ return (
+
+
+
+ {
+ keybind().length ? keybind().map((k, i) => {
+ const key = k.length > 1 ? k : k.toUpperCase()
+ return i === keybind().length - 1 ? key : key + ' + '
+ }) : 'No Keybind Set'
+ }
+
+
+
+
{
+ setRecordingState()
+ }}
+ >
+ {recording() ? 'Stop Recording' : 'Edit Keybind'}
+
+
+ )
+}
\ No newline at end of file
diff --git a/components/KeybindInput.tsx.scss b/components/KeybindInput.tsx.scss
new file mode 100644
index 0000000..66419d5
--- /dev/null
+++ b/components/KeybindInput.tsx.scss
@@ -0,0 +1,73 @@
+.keybindContainer {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+
+ width: 100%;
+ height: 40px;
+
+ border-radius: 4px;
+
+ background: var(--input-background);
+ color: var(--text-normal);
+ border: 1px solid transparent;
+
+ padding: 4px;
+
+ transition: all 0.2s;
+}
+
+.keybindContainer:hover {
+ border: 1px solid var(--status-danger);
+}
+
+.recording {
+ .keybindButton {
+ background: hsl(var(--red-400-hsl)/.1);
+ color: var(--status-danger);
+ }
+
+ .keybindButton:hover {
+ background: hsl(var(--red-400-hsl)/.2);
+ }
+
+ border: 1px solid var(--status-danger);
+}
+
+.keybindInput {
+ background: transparent;
+
+ display: flex;
+ align-items: center;
+}
+
+.keybindPlaceholder {
+ color: var(--text-muted) !important;
+}
+
+.keybindButton {
+ height: 30px;
+ width: 50%;
+
+ margin: 0;
+ padding: 4px;
+
+ border-radius: 4px;
+
+ display: flex;
+ align-items: center;
+
+ background: var(--button-secondary-background);
+ color: var(--white-500);
+
+ border: 1px solid transparent;
+
+ cursor: pointer;
+
+ transition: all 0.2s;
+}
+
+.keybindButton:hover {
+ background: var(--button-secondary-background-hover);
+}
\ No newline at end of file
diff --git a/plugins/dorion-custom-keybinds/components/KeybindSection.tsx b/plugins/dorion-custom-keybinds/components/KeybindSection.tsx
index 57af879..54a7337 100644
--- a/plugins/dorion-custom-keybinds/components/KeybindSection.tsx
+++ b/plugins/dorion-custom-keybinds/components/KeybindSection.tsx
@@ -1,5 +1,6 @@
import { css, classes } from './KeybindSection.tsx.scss'
import { Dropdown } from '../../../components/Dropdown'
+import { KeybindInput } from '../../../components/KeybindInput'
const {
ui: {
@@ -38,15 +39,11 @@ export function KeybindSection(props) {
{
- return {
- value: key,
- label: value
- }
- })}
+ options={props.keybindActionTypes}
onChange={(e) => {
console.log(e)
}}
+ style='width: 90%'
>
@@ -54,6 +51,13 @@ export function KeybindSection(props) {
+
+ {
+ console.log(keybind)
+ }}
+ style='width: 90%'
+ />
)
diff --git a/plugins/dorion-custom-keybinds/components/KeybindSection.tsx.scss b/plugins/dorion-custom-keybinds/components/KeybindSection.tsx.scss
index ce643d0..1c79c81 100644
--- a/plugins/dorion-custom-keybinds/components/KeybindSection.tsx.scss
+++ b/plugins/dorion-custom-keybinds/components/KeybindSection.tsx.scss
@@ -10,7 +10,6 @@
.keybindArea {
display: flex;
flex-direction: column;
- align-items
}
.actionSection {
diff --git a/plugins/dorion-ptt/index.ts b/plugins/dorion-ptt/index.ts
index 0f6a002..a1b3595 100644
--- a/plugins/dorion-ptt/index.ts
+++ b/plugins/dorion-ptt/index.ts
@@ -1,4 +1,4 @@
-import { keyToStr } from './keyUtil.js'
+import { keyToStr } from '../../util/keyUtil.js'
import { invoke, event } from '../../api/api.js'
const {
diff --git a/tsconfig.json b/tsconfig.json
index 5712c81..d83b437 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,5 +7,5 @@
"module": "nodenext",
"moduleResolution": "nodenext"
},
- "include": ["plugins/**/*.ts", "plugins/**/*.tsx", "node_modules/@uwu/shelter-defs/**/*.d.ts", "plugins/clean-home/index.tsx"]
+ "include": ["plugins/**/*.ts", "plugins/**/*.tsx", "node_modules/@uwu/shelter-defs/**/*.d.ts", "plugins/clean-home/index.tsx", "util/keyUtil.ts"]
}
\ No newline at end of file
diff --git a/plugins/dorion-ptt/keyUtil.ts b/util/keyUtil.ts
similarity index 66%
rename from plugins/dorion-ptt/keyUtil.ts
rename to util/keyUtil.ts
index 34dce09..f6c7ae2 100644
--- a/plugins/dorion-ptt/keyUtil.ts
+++ b/util/keyUtil.ts
@@ -11,6 +11,7 @@ const Keycode = {
220: 'BackSlash', 186: 'Semicolon', 222: 'Apostrophe', 188: 'Comma', 190: 'Dot', 191: 'Slash'
}
+// Convert a key code to a string
export const keyToStr = (key: number) => {
let keyStr = ''
@@ -35,4 +36,33 @@ export const keyToStr = (key: number) => {
}
return keyStr
+}
+
+// Convert a key string to a key code
+export const strToKey = (str: string) => {
+ let key = 0
+
+ // get char code of uppercase letter
+ if (str >= 'A' && str <= 'Z') {
+ key = str.charCodeAt(0)
+ }
+
+ // get char code of lowercase letter
+ if (str >= 'a' && str <= 'z') {
+ key = str.charCodeAt(0) - 32
+ }
+
+ // get char code of number
+ if (str >= '0' && str <= '9') {
+ key = str.charCodeAt(0)
+ }
+
+ // Get everything else
+ for (const [k, v] of Object.entries(Keycode)) {
+ if (v === str) {
+ key = parseInt(k)
+ }
+ }
+
+ return key
}
\ No newline at end of file