From eff3c808bab84a25f4422042b1dba0f3f79b0616 Mon Sep 17 00:00:00 2001 From: Andrew Gundersen Date: Wed, 17 Mar 2021 15:51:47 -0500 Subject: [PATCH] input item enhancements --- src/App.vue | 102 +++++++++--------- src/background/session.ts | 7 +- .../inputItem/controllers/audioCtrl.ts | 59 +++++++--- .../inputItem/controllers/textCtrl.ts | 86 +++++++-------- src/components/inputItem/inputItem.vue | 27 ++--- src/components/inputItem/textInput.vue | 13 +-- src/modules/draggify.ts | 6 +- src/modules/message.ts | 17 +-- src/modules/messages.ts | 11 +- src/modules/mitt.ts | 4 +- src/types/message/index.ts | 2 +- src/views/messenger.vue | 24 +++++ 12 files changed, 195 insertions(+), 163 deletions(-) diff --git a/src/App.vue b/src/App.vue index 165d108..96593de 100644 --- a/src/App.vue +++ b/src/App.vue @@ -67,76 +67,76 @@ export default defineComponent({ diff --git a/src/background/session.ts b/src/background/session.ts index 0f71cf9..92609db 100644 --- a/src/background/session.ts +++ b/src/background/session.ts @@ -55,12 +55,7 @@ const onMessage = (messageStr: string): void => { // Check to see if this is a Render Message. if (m.content) { - message = renderMessage({ - text: m.content.text, - audio: m.content.audio, - context: m.context, - modifier: m.modifier, - }); + message = renderMessage(m.content.text, m.content.audio, m.context, m.modifier); // Play audio if any. if (message.content.audio) { diff --git a/src/components/inputItem/controllers/audioCtrl.ts b/src/components/inputItem/controllers/audioCtrl.ts index 723d31a..9b2df9f 100644 --- a/src/components/inputItem/controllers/audioCtrl.ts +++ b/src/components/inputItem/controllers/audioCtrl.ts @@ -1,44 +1,62 @@ -import { onMounted } from "vue"; +import anime from "animejs"; +import { onMounted, onUnmounted, ref, Ref } from "vue"; import useMitt from "@/modules/mitt"; import { useIpc } from '@/modules/ipc'; import keyboardNameMap from "../keyBoardMaps/keyboardNameMap"; import { renderMessage } from '@/modules/message'; +function showRecIcon () { + anime({ + targets: '#recIcon', + opacity: [0, 0.75], + scale: [0.0, 1], + duration: 250, + easing: 'linear', + }) + +} +function hideRecIcon () { + anime({ + targets: '#recIcon', + opacity: [0.75, 0], + scale: [1, 0], + duration: 250, + easing: 'linear', + }) + +} -export default function useAudioInputController () { + +export default function useAudioInputController (typing: Ref) { // For sending messages. const { post } = useIpc(); const { emitter } = useMitt(); // Keepp track of when we are recording. - let recording = 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); - return m.uid; - } + const recording = ref(false); //---Callbacks----------------------------------------------- const onKeyDown = (e: KeyboardEvent) => { const cmd = keyboardNameMap[e.keyCode]; + // console.log(cmd) // Start recording on space bar. - if (cmd == "SPACE" && !recording) { + if (cmd == "SPACE" && !recording.value && !typing.value) { post('update-recorder', { isRecording: true, uid: null }); - recording = true; + showRecIcon() + recording.value = true; + console.log("Recording...") } @@ -48,17 +66,20 @@ export default function useAudioInputController () { const cmd = keyboardNameMap[e.keyCode]; // Stop recording on space up. - if (cmd == "SPACE" && recording) { + if (cmd == "SPACE" && recording.value) { // Render audio immediately. - const uid = render("", "", "", "sf"); + const message = renderMessage("", "", "", "sf") + emitter.emit("self-message", message); post('update-recorder', { isRecording: false, - uid: uid + uid: message.uid }); - recording = false; + hideRecIcon() + recording.value = false; + console.log("Stopping record...") } @@ -71,6 +92,12 @@ export default function useAudioInputController () { window.addEventListener("keyup", onKeyUp); }) + onUnmounted(() => { + window.removeEventListener("keydown", onKeyDown); + window.removeEventListener("keyup", onKeyUp); + }); + + return { recording } diff --git a/src/components/inputItem/controllers/textCtrl.ts b/src/components/inputItem/controllers/textCtrl.ts index 115e9c5..1958bad 100644 --- a/src/components/inputItem/controllers/textCtrl.ts +++ b/src/components/inputItem/controllers/textCtrl.ts @@ -1,18 +1,13 @@ import anime from "animejs"; import useMitt from "@/modules/mitt"; import { useIpc } from '@/modules/ipc'; -import { Ref, watch, onMounted } from "vue"; +import { Ref, ref, watch, onMounted, onUnmounted } 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 () { const t1 = (side === "right") ? 50 : -70; @@ -27,7 +22,6 @@ function showTextInput () { easing: 'easeOutExpo', }) - visible = true } function hideTextInput() { @@ -35,14 +29,13 @@ function hideTextInput() { anime({ targets: '#textInput', - opacity: 0, + opacity: [1, 0], translateX: t, scale: 0.3, duration: 500, easing: 'easeOutExpo', }) - visible = false } function switchSide(currentSide: string) { @@ -63,27 +56,29 @@ function switchSide(currentSide: string) { 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; + const typing = ref(false); - // Clear text input. + // Prep inputItem for typing. + const prepInput = () => { + showTextInput() + typing.value = true + } + + // Clear and hide inputItem after done typing. const clearInput = () => { - if (textInput) textInput.value = ""; + + if (textInput) { + textInput.value = ""; + textInput.blur(); + } + 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; + typing.value = false; } // Send a message and clean up after. @@ -91,50 +86,53 @@ export default function useTextInputController(elementX: Ref) { if (textInput) { // Render message - const uid = render(textInput.value, false, "", "sf"); + 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, uid); + 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) { - const key = keyboardNameMap[e.keyCode] - - // Reveal textInput on first key press. + + // First-key handler. if (firstKey) { - - // Handle for space bar - if (key == "SPACE") { - return - } - - showTextInput() - firstKey = false + if (key == "SPACE") return + prepInput() } textInput.focus(); + // Close input when no text or on ESC. if (textInput.value == "" && !firstKey) { clearInput() + return } - if (key == "ENTER") { + if (key === "ESCAPE") { + clearInput() + return + } + + // Close and send on enter. + if (key === "ENTER") { if (textInput.value) { sendMessage() - clearInput() + return } } - if (key == "ESCAPE") { - clearInput() - - } + if (firstKey) firstKey = false } } @@ -166,8 +164,12 @@ export default function useTextInputController(elementX: Ref) { window.addEventListener("keydown", onKeyDown); }) - return { + onUnmounted(() => { + window.removeEventListener("keydown", onKeyDown); + }); + return { + typing } } diff --git a/src/components/inputItem/inputItem.vue b/src/components/inputItem/inputItem.vue index 052e9dd..05b859c 100644 --- a/src/components/inputItem/inputItem.vue +++ b/src/components/inputItem/inputItem.vue @@ -7,14 +7,9 @@ > AG - - - - + - -
-
+ @@ -43,12 +38,19 @@ export default defineComponent({ }, setup() { + // Initial position. + const xStart = 15; + const yStart = window.innerHeight - 200; + // Calculate position of inputItem on drag. - const { elementX, elementY } = draggify({ elementId: "inputItem" }); + const { elementX, elementY } = draggify( + { elementId: "inputItem" }, + { x: xStart, y: yStart } + ); // Controllers for text and audio. - useTextInputController(elementX) - const { recording } = useAudioInputController() + const { typing } = useTextInputController(elementX) + const { recording } = useAudioInputController(typing) return { elementX, @@ -64,8 +66,6 @@ export default defineComponent({ .input-item { position: absolute; - opacity: 1.0; - display: flex; align-items: center; justify-content: center; @@ -80,7 +80,8 @@ export default defineComponent({ // border: 4px solid #C6C6C6; border-radius: 20px; - background-color: #EBEBEB; + // Set opacity here to not affect child. + background-color: rgba(235, 235, 235, 0.75); cursor: pointer; diff --git a/src/components/inputItem/textInput.vue b/src/components/inputItem/textInput.vue index d9c2dad..45e1af7 100644 --- a/src/components/inputItem/textInput.vue +++ b/src/components/inputItem/textInput.vue @@ -8,7 +8,7 @@