134 lines
3.1 KiB
TypeScript
134 lines
3.1 KiB
TypeScript
import { Ref, ref, watch, onMounted, onUnmounted } from "vue";
|
|
import { postMessage } from "@/ipc/session";
|
|
import { newMessage, animateTextInput } from "./helpers";
|
|
|
|
|
|
export default function useTextInputController(elementX: Ref) {
|
|
|
|
let textInput: HTMLInputElement | null;
|
|
|
|
const { side, show, hide, switchSide } = animateTextInput();
|
|
|
|
let firstKey = true;
|
|
const typing = ref(false);
|
|
|
|
// Prep inputItem for typing.
|
|
const prepInput = () => {
|
|
show()
|
|
typing.value = true
|
|
}
|
|
|
|
// Clear and hide inputItem after done typing.
|
|
const clearInput = () => {
|
|
|
|
if (textInput) {
|
|
textInput.value = "";
|
|
textInput.blur();
|
|
}
|
|
|
|
hide()
|
|
firstKey = true;
|
|
typing.value = false;
|
|
}
|
|
|
|
// Send a message and clean up after.
|
|
const sendMessage = () => {
|
|
if (textInput) {
|
|
|
|
// Send it to the backend for processing.
|
|
const message = newMessage({
|
|
text: textInput.value
|
|
});
|
|
|
|
postMessage(message);
|
|
|
|
clearInput()
|
|
}
|
|
}
|
|
|
|
// Keys that are capable of opening the text input (numbers and letters).
|
|
const isHotKey = (key: number) => {
|
|
if (key >= 47 && key <= 91) { // a letter
|
|
return true
|
|
}
|
|
}
|
|
|
|
//---Callbacks-----------------------------------------------
|
|
|
|
const onKeyDown = (e: KeyboardEvent) => {
|
|
const key = e.keyCode;
|
|
|
|
if (textInput) {
|
|
|
|
// Only runs on firstKey.
|
|
if (firstKey) {
|
|
|
|
if (!isHotKey(key)) {
|
|
return
|
|
}
|
|
|
|
prepInput()
|
|
}
|
|
|
|
textInput.focus();
|
|
|
|
// Close input when no text or on ESC.
|
|
if ((textInput.value == "") && (!firstKey) && (key === 8)) { // backspace
|
|
clearInput()
|
|
return
|
|
}
|
|
|
|
if (key === 27) { // escape
|
|
clearInput()
|
|
return
|
|
}
|
|
|
|
// Close and send on enter.
|
|
if (key === 13) {
|
|
if (textInput.value) {
|
|
sendMessage()
|
|
return
|
|
}
|
|
}
|
|
|
|
if (firstKey) firstKey = false
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
// Watch parent position and update side.
|
|
watch(elementX, (elementX, _previous) => {
|
|
const winW = window.innerWidth
|
|
|
|
// Logic depends on the side we are on.
|
|
if (side.value === "right") {
|
|
if (winW - elementX < 230) {
|
|
switchSide()
|
|
side.value = "left"
|
|
}
|
|
}
|
|
|
|
else {
|
|
if (winW - elementX > 230) {
|
|
switchSide()
|
|
side.value = "right"
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
onMounted(() => {
|
|
textInput = document.getElementById("textInput") as HTMLInputElement;
|
|
window.addEventListener("keydown", onKeyDown);
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener("keydown", onKeyDown);
|
|
});
|
|
|
|
return {
|
|
typing
|
|
}
|
|
|
|
}
|