--- /dev/null
+const portAudio = require('naudiodon');
+
+let audioInput: string[] = [];
+
+function processAudio(audioInput: Array<string>): Buffer {
+ let audio = '';
+ audioInput.forEach(chunk => audio += chunk);
+ return Buffer.from(audio, "base64");
+}
+
+
+const updateRecorder = async (Event: any, record: boolean): void => {
+ if (record) {
+ ia.resume();
+ } else {
+ ia.pause();
+ const audio = processAudio(audioInput);
+ // emmit ws event with audio
+ // sendAudio(audio);
+ audioInput = [];
+ }
+}
+
+
+let ia = new portAudio.AudioIO({
+ inOptions: {
+ channelCount: 1,
+ sampleFormat: 16,
+ sampleRate: 16000,
+ deviceId: -1,
+ closeOnError: false,
+ }
+});
+ia.setEncoding('base64');
+ia.start();
+ia.pause();
+ia.on('error', (e: Error) => {
+ console.log('Error recording audio', + e);
+});
+ia.on('data', (chunk: string) => {
+ audioInput.push(chunk);
+});
+
+export function useIA() {
+ return {
+ ia,
+ processAudio
+ }
+}
import { createWindow } from './createWindow';
-import { Recorder } from './recorder';
-import { ipcMain, BrowserWindow } from "electron";
+import { ipcMain } from "electron";
import WebSocket from 'ws';
import { windowEmitter } from './windowEmitter';
const portAudio = require('naudiodon');
let audioInput: string[] = [];
+ const authUser = (event: any, arg: any) => {
+ let reply;
+ reply = {
+ id: "2",
+ email: "hernandeze@xavier.edu",
+ firstName: "Enrique",
+ lastName: "Hernandez",
+ access_token: "test-token"
+ }
+ if (arg === ['undefined']) {
+ reply = new Error('AUTH-FAILED');
+ }
+ event.reply('auth-user-reply', reply)
+ }
+ ipcMain.on('auth-user', authUser);
+
+ const authLogin = (event: any, arg: any) => {
+ console.log(arg)
+ event.reply('auth-login-reply', true)
+ }
+
// create main window.
const win = createWindow({ width: 350, height: 525, resizable: false });
ia.resume();
} else {
ia.pause();
- const audio = processAudio();
+ const audio = processAudio(audioInput);
sendAudio(audio);
audioInput = [];
}
}
- function processAudio(): Buffer {
+ function processAudio(audioInput: Array<string>): Buffer {
let audio = '';
- audioInput.forEach(s => {
- audio += s;
- });
- const buffer = Buffer.from(audio, "base64");
- return buffer;
+ audioInput.forEach(chunk => audio += chunk);
+ return Buffer.from(audio, "base64");
}
const windowMount = (): void => {
// ipc event handlers
ipcMain.on('update-recorder', updateRecorder);
ipcMain.on('send-message', sendMessage);
+ ipcMain.on('auth-login', authLogin);
}
const windowDismount = (): void => {
windowEmitter.emit('window-active', false);
// TODO: Gracefully close socket connection
- ipcMain.removeListener('update-recorder', updateRecorder);
- ipcMain.removeListener('send-message', sendMessage);
+ ipcMain.removeAllListeners('update-recorder');
+ ipcMain.removeAllListeners('send-message');
+ ipcMain.removeAllListeners('auth-login');
+ ipcMain.removeAllListeners('auth-user');
}
// socket handlers
});
ia.setEncoding('base64');
ia.start();
+ ia.pause();
ia.on('error', (e: Error) => {
- console.log('error recording audio', + e);
+ console.log('Error recording audio', + e);
});
- ia.pause();
ia.on('data', (chunk: string) => {
audioInput.push(chunk);
- console.log('Got %d characters of string data:', chunk.length);
});
}
--- /dev/null
+
+const authUser = (event: any, arg: any) => {
+ let reply;
+ reply = {
+ id: "2",
+ email: "hernandeze@xavier.edu",
+ firstName: "Enrique",
+ lastName: "Hernandez",
+ access_token: "test-token"
+ }
+ if (arg === ['undefined']) {
+ reply = new Error('AUTH-FAILED');
+ }
+ event.reply('auth-user-reply', reply)
+}
+
+ipcMain.on('auth-user', authUser);
+
+const authLogin = (event: any, arg: any) => {
+ console.log(arg)
+ event.reply('auth-login-reply', true)
+}
import useBubbleDrawer from "./bubbleDetails/drawer";
// text wrap composition
-import useTextWrap from "@/composables/textWrap";
+import useTextWrap from "@/modules/textWrap";
import { defineComponent, onMounted, ref, reactive } from "vue";
export default defineComponent({
<script lang="ts">
import useMessageVisualizer from "./viewDetails/visualizer";
-
-import useScrollView from "@/composables/scrollView";
-
+import useScrollView from "@/modules/scrollView";
import MessageItem from "../messageBubble/index.vue";
-
import { Message } from "@/types/message/index";
-
import { Mitt } from "@/types/mitt/index";
import { defineComponent, reactive, inject } from "vue";
+
export default defineComponent({
name: "MessageVisualizer",
components: { MessageItem },
import { ref, watch, onUnmounted, onMounted } from "vue";
-
-import useKeyDownHandler from "@/composables/keyDownHandler/useKeyDownHandler";
-
-import useMediaStream from "@/composables/mediaStream";
-
+import useKeyDownHandler from "@/modules/keyDownHandler/useKeyDownHandler";
+import useMediaStream from "@/modules/mediaStream";
import useAudioVisualizer from './audioDetails/audioVisualizer';
-
import useTextVisualizer from './textDetails/textVisualizer';
/*
--- /dev/null
+import { reactive, watch, toRefs } from 'vue';
+import { useIpc } from './ipc';
+
+interface User {
+ id: string;
+ email: string;
+ firstName: string;
+ lastName: string;
+ access_token: string;
+}
+
+interface AuthState {
+ authenticating: boolean;
+ user?: User;
+ error?: Error;
+}
+
+const state = reactive<AuthState>({
+ authenticating: false,
+ user: undefined,
+ error: undefined,
+});
+
+const AUTH_KEY = 'crimata_token';
+
+const token = window.localStorage.getItem(AUTH_KEY);
+
+if (token) {
+ const { loading, error, data, send } = useIpc('auth-user');
+
+ state.authenticating = true;
+
+ // authenticate token against crimata-platform
+ send([token]);
+
+ watch([loading], () => {
+ if (error.value) {
+ console.log('ERROR: failed authentication')
+ window.localStorage.removeItem(AUTH_KEY);
+ }
+ else if (data.value) {
+ state.user = data.value;
+ }
+
+ state.authenticating = false;
+ })
+}
+
+export const useAuth = () => {
+ const setUser = (payload: User, remember: boolean) => {
+ if (remember) {
+ // Save
+ window.localStorage.setItem(AUTH_KEY, payload.access_token);
+ }
+
+ state.user = payload;
+ state.error = undefined;
+ }
+
+ const logout = (): Promise<void> => {
+ window.localStorage.removeItem(AUTH_KEY);
+ return Promise.resolve(state.user = undefined);
+ }
+
+ return {
+ setUser,
+ logout,
+ ...toRefs(state), // authenticating, user, error
+ }
+}
--- /dev/null
+import { ref, computed } from 'vue'
+
+export const useIpc = (endpoint: string) => {
+ const data = ref();
+ const loading = ref(false);
+ const error = ref();
+ const listener = ref(false);
+
+ const errorMessage = computed(() => {
+ console.log('ERROR', error.value);
+ if (error.value) {
+ return error.value.message
+ }
+ })
+
+ const send = (payload?: Record<string, any>, callback?: (arg: any) => void) => {
+ loading.value = true;
+ error.value = undefined;
+
+ window.ipcRenderer.on(endpoint + '-reply', (event: any, arg: any | Error) => {
+ if (arg instanceof Error) {
+ error.value = arg;
+ throw arg;
+ } else {
+ if (callback) {
+ callback(arg);
+ }
+ data.value = arg;
+ loading.value = false;
+ }
+ });
+ window.ipcRenderer.send(endpoint, payload);
+ };
+
+ const onEvent = (callback: (event: any, arg: any) => void) => {
+ listener.value = true;
+ window.ipcRenderer.on(endpoint, callback);
+ };
+
+ const post = (payload?: Record<string, any>) => {
+ window.postMessage({
+ myTypeField: endpoint,
+ message: payload
+ }, '*')
+ };
+
+ return {
+ loading,
+ data,
+ error,
+ errorMessage,
+ send
+ }
+}
-import {
- createRouter,
- createWebHistory,
- createWebHashHistory,
- RouteRecordRaw
+import {
+ createRouter,
+ createWebHistory,
+ createWebHashHistory,
+ RouteRecordRaw
} from "vue-router";
-
-import Home from "./views/home.vue";
-import Login from "./views/login.vue";
-import Splash from "./views/splash.vue";
+import Home from "@/views/home.vue";
+import { useAuth } from '@/modules/auth';
// Define the routes (/*) for the app here.
const routes: Array<RouteRecordRaw> = [
-
{
- path: "/sdf",
- name: "Splash",
- component: Splash
+ path: "/",
+ name: "home",
+ component: Home,
+ meta: { requiresAuth: true },
},
-
{
- path: "/sdf",
- name: "Home",
- component: Home
+ path: "/login",
+ name: "login",
+ component: () => import("@/views/login.vue"),
+ meta: { requiresAuth: false },
},
-
{
- path: "/",
- name: "Login",
- component: Login
+ path: "/register",
+ name: "register",
+ component: () => import("@/views/register.vue"),
+ meta: { requiresAuth: false },
},
-
];
const router = createRouter({
routes
});
-export default router;
\ No newline at end of file
+router.beforeEach((to, from, next) => {
+ const { user } = useAuth();
+
+ // Not logged into a guarded route?
+ if (to.meta.requiresAuth && !user?.value) next({ name: 'login' });
+
+ // Logged in for an auth route
+ else if ((to.name == 'login' || to.name == 'register') && user!.value) next({ name: 'home' });
+
+ // Carry On...
+ else next();
+})
+
+export default router;
<template>
- <LoginComponent />
+ <form id="login" @submit.prevent="submit">
+ <!-- login title -->
+ <div id="loginTitle">Crimata Messenger</div>
+
+ <!-- username and password forms -->
+ <div id="loginBox">
+ <!-- username -->
+ <input class="input" type="text" v-model="email" placeholder="username" />
+
+ <!-- password -->
+ <input class="input" type="password" v-model="password" placeholder="Password" />
+ </div>
+
+ <!-- submit button -->
+ <button class="button" type="submit">Login</button>
+ </form>
</template>
<script lang="ts">
+import { defineComponent, toRefs, reactive, watch } from "vue";
+import { useAuth } from "@/modules/auth";
+import { useIpc } from "@/modules/ipc";
+import { useRouter } from "vue-router";
-import { defineComponent } from "vue";
-import LoginComponent from "@/components/login/index.vue";
+interface LoginPayload {
+ email: string;
+ password: string;
+ rememberMe: boolean;
+}
export default defineComponent({
-
name: "Login",
- components: { LoginComponent },
+ setup() {
+ const { setUser, user } = useAuth();
+ const router = useRouter();
+
+ const payload = reactive<LoginPayload>({
+ email: "",
+ password: "",
+ rememberMe: true,
+ });
+
+ const { loading, data, send, errorMessage } = useIpc("auth-login");
+ const submit = async () => {
+ // console.log(toRefs(payload));
+ send({
+ email: payload.email,
+ password: payload.password,
+ });
+ console.log(data.value, "login");
+ // setUser(data.value, payload.rememberMe);
+ // router.push({ name: "home" });
+ };
+
+ watch(loading, () => {
+ console.log("loading changed");
+ console.log(data.value, "post laoding");
+ });
+
+ return {
+ loading,
+ submit,
+ errorMessage,
+ ...toRefs(payload),
+ };
+ },
});
+</script>
+
+<style lang="scss" scoped>
+#login {
+ width: 350px;
+ height: 500px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: #e6e6e6;
+}
+
+#loginBox {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+.input {
+ background-color: #B9B9B9;
+ border: none;
+ color: white;
+ padding: 16px;
+ text-decoration: none;
+ margin: 4px 2px;
+ cursor: pointer;
+ border-radius: 10px;
+}
-</script>
\ No newline at end of file
+.button {
+ background-color: #58C4FD;
+ border: none;
+ color: white;
+ padding: 10px 20px;
+ text-decoration: none;
+ border-radius: 20px;
+ font-weight: bold;
+}
+</style>
+<template>
+ <div id="login">
+ <!-- login title -->
+ <div id="loginTitle">Login</div>
+
+ <!-- username and password forms -->
+ <div id="loginBox">
+ <!-- username -->
+ <input class="input" type="text" v-model="login.username" placeholder="username" />
+
+ <!-- password -->
+ <input class="input" type="password" v-model="login.password" placeholder="Password" />
+ </div>
+
+ <!-- submit button -->
+ <button class="button" @click="submitCreds">Submit</button>
+ </div>
+</template>
+
+<script lang="ts">
+import {
+ computed,
+ defineComponent,
+ onErrorCaptured,
+ reactive,
+ ref,
+ toRefs,
+} from "vue";
+import { useRouter } from "vue-router";
+import { useIpc } from "@/modules/ipc";
+import { useAuth } from "@/modules/auth";
+
+interface RegisterPayload {
+ email?: string;
+ password?: string;
+ firstName?: string;
+ lastName?: string;
+}
+
+export default defineComponent({
+ name: "Register",
+ setup() {
+ const payload = reactive<RegisterPayload>({
+ email: undefined,
+ password: undefined,
+ firstName: undefined,
+ lastName: undefined,
+ });
+
+ const { error, loading, send, data, errorMessage } = useIpc(
+ "auth-register"
+ );
+
+ const { setUser } = useAuth();
+ const router = useRouter();
+
+ const submit = async () => {
+ send(payload);
+ setUser(data.value, true);
+ router.push({ name: "home" });
+ };
+
+ return {
+ ...toRefs(payload),
+ submit,
+ loading,
+ errorMessage,
+ };
+ },
+});
+</script>