import { backgroundMitt } from './emitter';
import { ipcMain } from "electron";
import { play } from './audio';
-import { UserCreds, ClientMessage } from "@/types/message/index";
-import { clientMessage } from '@/modules/message';
+import { UserCreds, ClientMessage, RenderMessage, Annotation } from "@/types/message/index";
+import { clientMessage, initRenderMessageFromString } from '@/modules/message';
import { v4 as uuidv4 } from 'uuid';
const ip = 'ws://127.0.0.1';
let success = false;
let auth = false;
-const onAuthSession = async (_event, payload: string | UserCreds | null): Promise<string> => {
+const onAuthSession = async (e: any, payload: string | UserCreds | null): Promise<string> => {
return new Promise((resolve, reject) => {
console.log('authenticating...');
});
};
-const onMessage = (message: string): void => {
+const onMessage = (message_str: string): void => {
while (!auth) {
- backgroundMitt.emit('auth-res', message);
+ backgroundMitt.emit('auth-res', message_str);
return;
}
- // Parse the message.
- const m = JSON.parse(message);
+ // Decode the message.
+ const m = JSON.parse(message_str)
+ let message: RenderMessage | Annotation;
- // check to see if this is a Render Message.
+ // Check to see if this is a Render Message.
if (m.content) {
+ message = initRenderMessageFromString(message_str)
- // If there is audio, play it.
- if (m.content.audio) {
+ // Play audio if any.
+ if (message.content.audio) {
const audioBytes = Buffer.from(m.content.audio as string, 'hex');
m.content.audio = true;
play(audioBytes);
- } else {
- m.content.audio = false;
}
- // if there is no unique id, add it.
- if(!m.uid) m.uid = uuidv4();
}
+ else {
+ message = m // Annotation
+ }
+
+ // Send it to the frontend.
backgroundMitt.emit('ipc-renderer', {
endpoint: 'render-message',
- message: m
+ message: message
});
};
-const onClientMessage = (_event, payload: ClientMessage): void => {
+const onClientMessage = (e: any, payload: ClientMessage): void => {
console.log('sending message');
socket.send(JSON.stringify(payload));
}
}
-export function sendAudio(content: string, uid: string): void {
- const m = clientMessage("", content, uid);
+export function sendAudio(audio: string, uid: string): void {
+ const m = clientMessage("", audio, uid);
socket.send(JSON.stringify(m));
-}
-
+}
\ No newline at end of file
import { BrowserWindow, ipcMain } from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import { backgroundMitt } from './emitter';
+import { RenderMessage } from "@/types/message/index";
import * as path from "path";
interface WindowSettings {
resizable: boolean;
}
-interface RenderMessage {
- content: string;
- context: string;
- subContext: string;
- modifiers: string;
- time: string;
- id: string;
-}
-
interface IpcRendererPayload {
endpoint: string;
message: RenderMessage | null;
import keyboardCharMap from "./keyBoardMaps/keyboardCharMap";
import { RenderMessage, ClientMessage } from "@/types/message/index";
import { v4 as uuidv4 } from 'uuid';
-import {clientMessage, renderMessage} from '@/modules/message';
+import {clientMessage, initRenderMessage} from '@/modules/message';
let textInput: HTMLInputElement | null;
-let m: RenderMessage | ClientMessage;
let uid: string;
export default function useInputController() {
// remove first character of input.
const text = input.value.substring(1);
- uid = uuidv4();
+ // Render the message immediately.
+ const message = initRenderMessage(text, "", "", "sf");
+ emitter.emit("self-message", message);
- m = renderMessage(text, false, "sf", uid);
+ // Then send it to the backend for processing.
+ const clientMm = clientMessage(text, false, message.uid);
+ post('client-message', message);
- // render user message.
- emitter.emit("self-message", m);
-
- m = clientMessage(m.content.text, m.content.audio, uid);
-
- // send message to backend.
- post('client-message', m);
-
- // reset text input.
+ // Reset the text input.
if (textInput) textInput.value = '';
input.value = " ";
}
isRecording.value = false;
- uid = uuidv4();
-
- // render audio message.
- m = renderMessage("", false, "sf", uid);
- emitter.emit("self-message", m);
+ // Render the message immediately.
+ const audioMessage = initRenderMessage("", "", "", "sf")
+ emitter.emit("self-message", audioMessage);
- // stop stream recording.
+ // Notify backend to stop recording and send audio to python backend for audio processing.
post('update-recorder', {
isRecording: isRecording.value,
- uid
+ uid: audioMessage.uid
});
+ // Reset input.
input.value = ''
}
}
// watch keyboard input & update current state.
watch(input, (input, prevInput) => {
- //
if (prevInput !== "" || prevInput.length > 0) {
if (!isRecording.value) {
isTyping.value = true;
return;
}
- //
if (input === " " && isRecording.value === false) {
isTyping.value = false;
isRecording.value = true;
</div>
<!-- message context -->
- <span class="context">
+ <span v-if="message.isChild === false" class="context">
<!-- Render Crimata icon or friend's initials. -->
<div v-if="message.modifier == 'ai'" class="photo">
import {defineComponent, ref, onMounted} from 'vue';
+
export default defineComponent({
name: "MessageItem",
import { RenderMessage, ClientMessage } from "@/types/message/index";
+import { v4 as uuidv4 } from 'uuid';
-export const renderMessage = (text: string, audio: string | boolean, modifier: string, uid: string): RenderMessage => (
- {
+// Create a RenderMessage object directly from json string.
+export function initRenderMessageFromString(message_str: string) {
+
+ // Parse the string.
+ const m = JSON.parse(message_str);
+
+ // Auto set uid and time.
+ let currentdate = new Date();
+
+ const message: RenderMessage = {
+ content: m.content,
+ context: m.context,
+ modifier: m.modifier,
+ time: currentdate.getTime(),
+ uid: uuidv4(),
+ isChild: false
+ }
+
+ return message
+}
+
+// Create a RenderMessage object.
+export function initRenderMessage(text: string, audio: string, context: string, modifier: string) {
+
+ // Auto set uid and time.
+ let currentdate = new Date();
+
+ const message: RenderMessage = {
content: {
- audio,
- text
+ text: text,
+ audio: audio
},
- context: "",
- modifier,
- uid
+ context: context,
+ modifier: modifier,
+ time: currentdate.getTime(),
+ uid: uuidv4(),
+ isChild: false
}
-)
+
+ return message
+}
export const clientMessage = (text: string, audio: string | boolean, uid: string): ClientMessage => (
{
};
context: string;
modifier: string;
+ time: number;
uid: string;
+ isChild: boolean;
}
export interface ClientMessage {
text: string;
context: string;
uid: string;
-}
+}
\ No newline at end of file
<script lang="ts">
import { defineComponent, onMounted, onUnmounted } from "vue";
+import { RenderMessage } from "@/types/message/index";
import MessageItem from "@/components/messageItem.vue";
import InputItem from "@/components/inputItem/inputItem.vue";
import Settings from "@/components/settings.vue";
const { emitter } = useMitt();
const { messages, addMessage, updateMessage } = useMessages();
+ // Reference to previous message for grouping purposes.
+ let prevMessage: RenderMessage;
+
const onRenderMessage = (_event: any, payload: any) => {
+ const message = payload.message; // cleaner
// render message if there is content.
- if (payload.message.content) {
- addMessage(payload.message);
- } else {
- // must be an annotation, update message.
- updateMessage(payload.message);
+ if (message.content) {
+ addMessage(message);
+ }
+
+ // must be an annotation, update message.
+ else {
+ updateMessage(message);
+ }
+
+ // Also want to check if message should be grouped.
+ // Message context and modifier needs to be same as previous message while also having close times (20s).
+ if (message.time < prevMessage.time + 20000 && message.context == prevMessage.context && message.modifier == prevMessage.modifier) {
+
+ prevMessage.isChild = true;
}
}