mime-chat/src/components/inputItem/controllers/textCtrl.ts
Andrew Gundersen a6ebab0dea improvments
2021-03-17 09:32:32 -05:00

173 lines
4.1 KiB
TypeScript

import anime from "animejs";
import useMitt from "@/modules/mitt";
import { useIpc } from '@/modules/ipc';
import { Ref, watch, onMounted } from "vue";
import keyboardNameMap from "../keyBoardMaps/keyboardNameMap";
import { clientMessage, renderMessage } from '@/modules/message';
// Post a message to the backend.
const { post } = useIpc();
//---Animations-----------------------------------------------
let side = "right"; // Side of parent we are on.
let visible = false; // Whether textInput is visible.
function showTextInput () {
let t1 = (side === "right") ? 50 : -70;
let t2 = (side === "right") ? 110 : -130;
anime({
targets: '#textInput',
opacity: [0, 1],
translateX: [t1, t2],
scale: [0.3, 1],
duration: 500,
easing: 'easeOutExpo',
})
visible = true
}
function hideTextInput() {
let t = (side === "right") ? 50 : -80;
anime({
targets: '#textInput',
opacity: 0,
translateX: t,
scale: 0.3,
duration: 500,
easing: 'easeOutExpo',
})
visible = false
}
function switchSide(currentSide: string) {
let t = (currentSide === "right") ? -130 : 110;
anime({
targets: '#textInput',
translateX: t,
duration: 500,
easing: 'easeOutExpo',
})
}
//------------------------------------------------------------
export default function useTextInputController(elementX: Ref) {
let textInput: HTMLInputElement | null;
let length: number;
// For sending messages.
const { post } = useIpc();
const { emitter } = useMitt();
// Keep track of first key press.
let firstKey = true;
// Clear text input.
const clearInput = () => {
if (textInput) textInput.value = "";
hideTextInput()
firstKey = true;
}
// Utility function to render message.
const render = (text: string, audio: boolean | string, context: string, modifier: string): string => {
const m = renderMessage({ text, audio, context, modifier });
emitter.emit("self-message", m);
return m.uid;
}
// Send a message and clean up after.
const sendMessage = () => {
if (textInput) {
// Render message
const uid = render(textInput.value, false, "", "sf");
// Send it to the backend for processing.
const clientM = clientMessage(textInput.value, false, uid);
post('client-message', clientM);
}
}
//---Callbacks-----------------------------------------------
const onKeyDown = (e: KeyboardEvent) => {
if (textInput) {
const key = keyboardNameMap[e.keyCode]
// Reveal textInput on first key press.
if (firstKey) {
// Handle for space bar
if (key == "SPACE") {
return
}
showTextInput()
firstKey = false
}
textInput.focus();
if (textInput.value == "" && !firstKey) {
clearInput()
}
if (key == "ENTER") {
if (textInput.value) {
sendMessage()
clearInput()
}
}
if (key == "ESCAPE") {
clearInput()
}
}
}
//-----------------------------------------------------------
// 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);
})
return {
}
}