170 lines
4 KiB
TypeScript
170 lines
4 KiB
TypeScript
"use strict";
|
|
|
|
import WebSocket from 'ws';
|
|
import { backgroundMitt } from './emitter';
|
|
import { ipcMain } from "electron";
|
|
|
|
interface RenderMessage {
|
|
content: string;
|
|
context: string;
|
|
subContext: string;
|
|
modifier: string;
|
|
time: string;
|
|
id: string;
|
|
}
|
|
|
|
interface UserCreds {
|
|
email: string;
|
|
password: string;
|
|
}
|
|
|
|
interface TextMessage {
|
|
audio: 0;
|
|
content: string;
|
|
}
|
|
|
|
const ip = 'ws://127.0.0.1';
|
|
const port = 8081;
|
|
const reconnectTimeout = 3000; //ms
|
|
let socket: WebSocket;
|
|
let success = false;
|
|
let auth = false;
|
|
|
|
const authSession = async (_event, payload: string | UserCreds | null): Promise<string> => {
|
|
return new Promise((resolve, reject) => {
|
|
|
|
console.log('authenticating...');
|
|
|
|
backgroundMitt.once('auth-res', (res: string) => {
|
|
|
|
if (res === 'locked') {
|
|
reject(res);
|
|
} else {
|
|
console.log('Success!');
|
|
auth = true;
|
|
resolve(res);
|
|
}
|
|
|
|
});
|
|
|
|
if (!payload) {
|
|
socket.send('no-token');
|
|
} else if (payload instanceof String || typeof payload === 'string') {
|
|
socket.send(payload);
|
|
} else {
|
|
socket.send(JSON.stringify(payload));
|
|
}
|
|
|
|
});
|
|
};
|
|
|
|
const receiveMessage = (message: string): void => {
|
|
|
|
while (!auth) {
|
|
backgroundMitt.emit('auth-res', message);
|
|
return;
|
|
}
|
|
|
|
const parsed: RenderMessage = JSON.parse(message);
|
|
if (parsed.modifier === "sf") {
|
|
backgroundMitt.emit('message-res', parsed);
|
|
} else if (parsed.modifier === "ai") {
|
|
backgroundMitt.emit('ipc-renderer', {
|
|
endpoint: 'render-message',
|
|
message: parsed
|
|
});
|
|
}
|
|
|
|
};
|
|
|
|
const asyncSend = (_event?, payload: TextMessage | Buffer): Promise<RenderMessage> => {
|
|
return new Promise((resolve, reject) => {
|
|
|
|
backgroundMitt.once('message-res', (res: RenderMessage) => {
|
|
console.log(res)
|
|
if (res.content) {
|
|
resolve(res);
|
|
} else {
|
|
reject('ERROR: NO MESSAGE');
|
|
}
|
|
|
|
});
|
|
|
|
if (payload instanceof Buffer) {
|
|
socket.send(payload);
|
|
} else if (payload) {
|
|
socket.send(JSON.stringify(payload));
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
export const sendAudio = async (content: Buffer) => {
|
|
|
|
const res = await asyncSend(null, content);
|
|
|
|
backgroundMitt.emit('ipc-renderer', {
|
|
endpoint: 'render-message',
|
|
message: res
|
|
});
|
|
}
|
|
|
|
// Run every time we want to connect to backend.
|
|
export const initSession = () => {
|
|
|
|
// Close existing sockets.
|
|
if (socket) {
|
|
socket.removeAllListeners();
|
|
socket.terminate();
|
|
socket.close();
|
|
success = false;
|
|
}
|
|
|
|
// Init new socket.
|
|
socket = new WebSocket(`${ip}:${port}`);
|
|
socket.binaryType = 'arraybuffer';
|
|
|
|
// handle renderer auth-token event
|
|
ipcMain.removeHandler('auth-session'); // avoid setting duplicate handlers
|
|
ipcMain.handle('auth-session', authSession);
|
|
|
|
// handle renderer send-message event
|
|
ipcMain.removeHandler('message'); // avoid setting duplicate handlers
|
|
ipcMain.handle('message', asyncSend);
|
|
|
|
// Connect to the backend.
|
|
socket.on('open', () => {
|
|
console.log('Connected to Crimata Servers.');
|
|
|
|
// call auth renderer event on connection
|
|
backgroundMitt.emit('ipc-renderer', {
|
|
endpoint: 'auth',
|
|
message: null
|
|
});
|
|
|
|
success = true;
|
|
|
|
});
|
|
|
|
// Handle for failed connect, try again.
|
|
socket.on('error', (_e) => {
|
|
console.log('ERROR: Failed to connect.');
|
|
socket.removeAllListeners();
|
|
socket.close();
|
|
setTimeout(() => {
|
|
if (!success) {
|
|
console.log('Reconnecting...');
|
|
initSession();
|
|
}
|
|
}, reconnectTimeout);
|
|
|
|
});
|
|
|
|
socket.on('close', () => {
|
|
console.log('Connection droped! Restarting...')
|
|
initSession();
|
|
});
|
|
|
|
socket.on("message", receiveMessage);
|
|
};
|
|
|