diff --git a/src/background/session.ts b/src/background/session.ts index 861eaea..0f71cf9 100644 --- a/src/background/session.ts +++ b/src/background/session.ts @@ -5,8 +5,7 @@ import { backgroundMitt } from './emitter'; import { ipcMain } from "electron"; import { play } from './audio'; import { UserCreds, ClientMessage, RenderMessage, Annotation } from "@/types/message/index"; -import { clientMessage, initRenderMessageFromString } from '@/modules/message'; -import { v4 as uuidv4 } from 'uuid'; +import { clientMessage, renderMessage } from '@/modules/message'; const ip = 'ws://127.0.0.1'; const port = 8760; @@ -43,20 +42,25 @@ const onAuthSession = async (e: any, payload: string | UserCreds | null): Promis }); }; -const onMessage = (message_str: string): void => { +const onMessage = (messageStr: string): void => { while (!auth) { - backgroundMitt.emit('auth-res', message_str); + backgroundMitt.emit('auth-res', messageStr); return; } // Decode the message. - const m = JSON.parse(message_str) + const m = JSON.parse(messageStr) let message: RenderMessage | Annotation; // Check to see if this is a Render Message. if (m.content) { - message = initRenderMessageFromString(message_str) + message = renderMessage({ + text: m.content.text, + audio: m.content.audio, + context: m.context, + modifier: m.modifier, + }); // Play audio if any. if (message.content.audio) { diff --git a/src/components/inputItem/inputController.ts b/src/components/inputItem/inputController.ts index 3b23dd2..0ef68ee 100644 --- a/src/components/inputItem/inputController.ts +++ b/src/components/inputItem/inputController.ts @@ -10,10 +10,33 @@ import useMitt from "@/modules/mitt"; import { useIpc } from '@/modules/ipc'; import keyboardNameMap from "./keyBoardMaps/keyboardNameMap"; import keyboardCharMap from "./keyBoardMaps/keyboardCharMap"; -import {clientMessage, initRenderMessage} from '@/modules/message'; +import anime from "animejs"; +import { clientMessage, renderMessage } from '@/modules/message'; let textInput: HTMLInputElement | null; +// Animation functions for text input element. +function expandInput() { + anime({ + targets: textInput, + width: ['0px', '150px'], + duration: 500, + easing: 'easeOutExpo', + }) +} + +function retractInput() { + anime({ + targets: textInput, + width: ['150px', '0px'], + duration: 500, + easing: 'easeOutExpo', + begin: function() { + if (textInput) textInput.blur(); + } + }) +} + export default function useInputController() { const { emitter } = useMitt(); @@ -21,20 +44,26 @@ export default function useInputController() { const isRecording = ref(false); const isTyping = ref(false); const input = ref(""); + const capsLock = ref(false); + + // 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); + console.log(m.time) + return m.uid; + } // send message on ENTER. const onEnter = () => { if (input.value) { - // remove first character of input. - const text = input.value.substring(1); - // Render the message immediately. - const message = initRenderMessage(text, "", "", "sf"); - emitter.emit("self-message", message); + // Render the message immediately and get its unique id. + const uid = render(input.value, false, "", "sf"); // Then send it to the backend for processing. - const clientM = clientMessage(text, false, message.uid); + const clientM = clientMessage(input.value, false, uid); post('client-message', clientM); // Reset the text input. @@ -46,8 +75,10 @@ export default function useInputController() { // update input on keydown event & listen for special commands. const onKeyDown = (e: KeyboardEvent) => { - - if (textInput) textInput.focus(); + if (textInput) { + textInput.focus(); + textInput.value = input.value; + } // keyboardCharMap is an array of arrays, with each inner // array having 2 columns - un-shifted, and shifted values. @@ -56,7 +87,7 @@ export default function useInputController() { // MODIFY keyboardCharMap to suit your needs if you want // more/less/different characters to be considered "printable". let iCol = 0; - if (e.shiftKey) { + if (e.shiftKey || capsLock.value) { iCol = 1; } @@ -73,13 +104,18 @@ export default function useInputController() { break; case "BACK_SPACE": input.value = input.value.slice(0, -1); - break; + break; + case "CAPS_LOCK": + capsLock.value = true; + break; case "ESCAPE": if (textInput) textInput.value = '' input.value = ""; break; default: input.value += ch; + input.value.trim(); + break; } } @@ -90,19 +126,20 @@ export default function useInputController() { isRecording.value = false; - // Render the message immediately. - const audioMessage = initRenderMessage("", "", "", "sf") - emitter.emit("self-message", audioMessage); - - // Notify backend to stop recording and send audio to python backend for audio processing. + // // Render the message immediately and get its unique id. + const uid = render("", "", "", "sf"); + // Notify main process to stop recording and send send audio to backend for analysis. post('update-recorder', { isRecording: isRecording.value, - uid: audioMessage.uid + uid }); // Reset input. input.value = '' } + else if (e.code === "CapsLock") { + capsLock.value = false; + } } onMounted(() => { @@ -117,19 +154,22 @@ export default function useInputController() { window.removeEventListener("keyup", onKeyUp); }); - // watch keyboard input & update current state. + // watch keyboard input & update inputItem state. watch(input, (input, prevInput) => { + if (isTyping.value && input.length === 0) { + retractInput(); + } + // Do nothing if user is typing. if (prevInput !== "" || prevInput.length > 0) { - if (!isRecording.value) { - isTyping.value = true; - } return; } + // Begin stream recording on space bar. if (input === " " && isRecording.value === false) { isTyping.value = false; isRecording.value = true; + // tell main process to begin stream recording. post('update-recorder', { isRecording: isRecording.value, uid: null @@ -138,11 +178,10 @@ export default function useInputController() { } isTyping.value = true; - + expandInput() }); return { - input, isRecording, isTyping } diff --git a/src/components/inputItem/inputItem.vue b/src/components/inputItem/inputItem.vue index 803b6a7..0e015b0 100644 --- a/src/components/inputItem/inputItem.vue +++ b/src/components/inputItem/inputItem.vue @@ -13,7 +13,7 @@ - + @@ -31,15 +31,14 @@ export default defineComponent({ // Calculate position of inputItem on drag. const { elementX, elementY } = draggify({ elementId: "inputItem" }); - // - const { input, isRecording, isTyping } = useInputController(); + // determine whether the user is typing or recording. + const { isRecording, isTyping } = useInputController(); return { elementX, elementY, isRecording, isTyping, - input, }; }, }); @@ -48,7 +47,7 @@ export default defineComponent({