175 lines
4.1 KiB
TypeScript
175 lines
4.1 KiB
TypeScript
import anime from "animejs";
|
|
import useMitt from "@/modules/mitt";
|
|
import { useIpc } from '@/modules/ipc';
|
|
import { Ref, ref, watch, onMounted, onUnmounted } from "vue";
|
|
import keyboardNameMap from "../keyBoardMaps/keyboardNameMap";
|
|
import { clientMessage, renderMessage } from '@/modules/message';
|
|
|
|
//---Animations-----------------------------------------------
|
|
|
|
let side = "right"; // Side of parent we are on.
|
|
|
|
function showTextInput () {
|
|
const t1 = (side === "right") ? 50 : -70;
|
|
const t2 = (side === "right") ? 110 : -130;
|
|
|
|
anime({
|
|
targets: '#textInput',
|
|
opacity: [0, 1],
|
|
translateX: [t1, t2],
|
|
scale: [0.3, 1],
|
|
duration: 500,
|
|
easing: 'easeOutExpo',
|
|
})
|
|
|
|
}
|
|
|
|
function hideTextInput() {
|
|
const t = (side === "right") ? 50 : -80;
|
|
|
|
anime({
|
|
targets: '#textInput',
|
|
opacity: [1, 0],
|
|
translateX: t,
|
|
scale: 0.3,
|
|
duration: 500,
|
|
easing: 'easeOutExpo',
|
|
})
|
|
|
|
}
|
|
|
|
function switchSide(currentSide: string) {
|
|
const t = (currentSide === "right") ? -130 : 110;
|
|
|
|
anime({
|
|
targets: '#textInput',
|
|
translateX: t,
|
|
duration: 500,
|
|
easing: 'easeOutExpo',
|
|
})
|
|
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
|
|
|
|
export default function useTextInputController(elementX: Ref) {
|
|
let textInput: HTMLInputElement | null;
|
|
|
|
const { post } = useIpc();
|
|
const { emitter } = useMitt();
|
|
|
|
let firstKey = true;
|
|
const typing = ref(false);
|
|
|
|
// Prep inputItem for typing.
|
|
const prepInput = () => {
|
|
showTextInput()
|
|
typing.value = true
|
|
}
|
|
|
|
// Clear and hide inputItem after done typing.
|
|
const clearInput = () => {
|
|
|
|
if (textInput) {
|
|
textInput.value = "";
|
|
textInput.blur();
|
|
}
|
|
|
|
hideTextInput()
|
|
firstKey = true;
|
|
typing.value = false;
|
|
}
|
|
|
|
// Send a message and clean up after.
|
|
const sendMessage = () => {
|
|
if (textInput) {
|
|
|
|
// Render message
|
|
const message = renderMessage(textInput.value, false, "", "sf")
|
|
emitter.emit("self-message", message);
|
|
|
|
// Send it to the backend for processing.
|
|
const clientM = clientMessage(textInput.value, false, message.uid);
|
|
post('client-message', clientM);
|
|
|
|
clearInput()
|
|
}
|
|
}
|
|
|
|
//---Callbacks-----------------------------------------------
|
|
|
|
const onKeyDown = (e: KeyboardEvent) => {
|
|
const key = keyboardNameMap[e.keyCode]
|
|
console.log(key)
|
|
|
|
if (textInput) {
|
|
|
|
// First-key handler.
|
|
if (firstKey) {
|
|
if (key == "SPACE") return
|
|
prepInput()
|
|
}
|
|
|
|
textInput.focus();
|
|
|
|
// Close input when no text or on ESC.
|
|
if (textInput.value == "" && !firstKey) {
|
|
clearInput()
|
|
return
|
|
}
|
|
|
|
if (key === "ESCAPE") {
|
|
clearInput()
|
|
return
|
|
}
|
|
|
|
// Close and send on enter.
|
|
if (key === "ENTER") {
|
|
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 === "right") {
|
|
if (winW - elementX < 230) {
|
|
switchSide(side)
|
|
side = "left"
|
|
}
|
|
}
|
|
|
|
else {
|
|
if (winW - elementX > 230) {
|
|
switchSide(side)
|
|
side = "right"
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
onMounted(() => {
|
|
textInput = document.getElementById("textInput") as HTMLInputElement;
|
|
window.addEventListener("keydown", onKeyDown);
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener("keydown", onKeyDown);
|
|
});
|
|
|
|
return {
|
|
typing
|
|
}
|
|
|
|
}
|