mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 18:25:30 +00:00
160 lines
3.8 KiB
TypeScript
160 lines
3.8 KiB
TypeScript
import {
|
|
play,
|
|
pause,
|
|
stop,
|
|
adjustVolume,
|
|
toggleRepeat,
|
|
toggleShuffle,
|
|
openMediaFileDialog,
|
|
seekForward,
|
|
seekBackward,
|
|
reverseList,
|
|
nextN,
|
|
next,
|
|
previous,
|
|
toggleDoubleSizeMode,
|
|
toggleWindow
|
|
} from "./actionCreators";
|
|
|
|
import { TOGGLE_TIME_MODE, TOGGLE_LLAMA_MODE } from "./actionTypes";
|
|
|
|
import { arraysAreEqual } from "./utils";
|
|
import { Dispatch } from "./types";
|
|
|
|
const IGNORE_EVENTS_FROM_TAGS = new Set(["input", "textarea", "select"]);
|
|
|
|
export function bindHotkeys(dispatch: Dispatch): () => void {
|
|
let keylog: number[] = [];
|
|
const trigger = [
|
|
78, // N
|
|
85, // U
|
|
76, // L
|
|
76, // L
|
|
83, // S
|
|
79, // O
|
|
70, // F
|
|
84 // T
|
|
];
|
|
|
|
const listener = (e: KeyboardEvent) => {
|
|
if (
|
|
e.target instanceof Element &&
|
|
IGNORE_EVENTS_FROM_TAGS.has(e.target.tagName.toLowerCase())
|
|
) {
|
|
return;
|
|
}
|
|
if (e.ctrlKey) {
|
|
switch (e.keyCode) {
|
|
case 68: // CTRL+D
|
|
dispatch(toggleDoubleSizeMode());
|
|
e.preventDefault(); // Supress the "Bookmark" action on windows.
|
|
break;
|
|
case 76: // CTRL+L FIXME
|
|
break;
|
|
case 82: // CTRL+R
|
|
dispatch(reverseList());
|
|
break;
|
|
case 84: // CTRL+T
|
|
dispatch({ type: TOGGLE_TIME_MODE });
|
|
break;
|
|
}
|
|
} else if (e.altKey) {
|
|
switch (e.keyCode) {
|
|
case 87: // ALT+W
|
|
dispatch(toggleWindow("main"));
|
|
break;
|
|
case 69: // ALT+E
|
|
dispatch(toggleWindow("playlist"));
|
|
break;
|
|
case 71: // ALT+G
|
|
dispatch(toggleWindow("equalizer"));
|
|
break;
|
|
}
|
|
} else {
|
|
switch (e.keyCode) {
|
|
case 37: // left arrow
|
|
dispatch(seekBackward(5));
|
|
break;
|
|
case 38: // up arrow
|
|
dispatch(adjustVolume(1));
|
|
break;
|
|
case 39: // right arrow
|
|
dispatch(seekForward(5));
|
|
break;
|
|
case 40: // down arrow
|
|
dispatch(adjustVolume(-1));
|
|
break;
|
|
case 66: // B
|
|
dispatch(next());
|
|
break;
|
|
case 67: // C
|
|
dispatch(pause());
|
|
break;
|
|
case 76: // L
|
|
dispatch(openMediaFileDialog());
|
|
break;
|
|
case 82: // R
|
|
dispatch(toggleRepeat());
|
|
break;
|
|
case 83: // S
|
|
dispatch(toggleShuffle());
|
|
break;
|
|
case 86: // V
|
|
dispatch(stop());
|
|
break;
|
|
case 88: // X
|
|
dispatch(play());
|
|
break;
|
|
case 90: // Z
|
|
dispatch(previous());
|
|
break;
|
|
case 96: // numpad 0
|
|
dispatch(openMediaFileDialog());
|
|
break;
|
|
case 97: // numpad 1
|
|
dispatch(nextN(-10));
|
|
break;
|
|
case 98: // numpad 2
|
|
dispatch(adjustVolume(-1));
|
|
break;
|
|
case 99: // numpad 3
|
|
dispatch(nextN(10));
|
|
break;
|
|
case 100: // numpad 4
|
|
dispatch(previous());
|
|
break;
|
|
case 101: // numpad 5
|
|
dispatch(play());
|
|
break;
|
|
case 102: // numpad 6
|
|
dispatch(next());
|
|
break;
|
|
case 103: // numpad 7
|
|
dispatch(seekBackward(5));
|
|
break;
|
|
case 104: // numpad 8
|
|
dispatch(adjustVolume(1));
|
|
break;
|
|
case 105: // numpad 9
|
|
dispatch(seekForward(5));
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Easter Egg
|
|
|
|
// Ignore escape. Usually this gets swallowed by the browser, but not always.
|
|
if (e.keyCode !== 27) {
|
|
keylog.push(e.keyCode);
|
|
keylog = keylog.slice(-8);
|
|
if (arraysAreEqual(keylog, trigger)) {
|
|
dispatch({ type: TOGGLE_LLAMA_MODE });
|
|
}
|
|
}
|
|
};
|
|
document.addEventListener("keydown", listener);
|
|
|
|
return () => {
|
|
document.removeEventListener("keydown", listener);
|
|
};
|
|
}
|