166 lines
4.3 KiB
TypeScript
166 lines
4.3 KiB
TypeScript
/*
|
|
* Creates a websocket session with Crimata Servers.
|
|
*
|
|
* Connects to Servers and attempts key authentication. Server will respond
|
|
* with key and user profile. We send the profile to the browser. We also
|
|
* resend this information on new broser window. We then serve as a
|
|
* communication interface between the window and the servers. It will
|
|
* automatically try to reconnect on websocket disconnect.
|
|
*/
|
|
|
|
import { backgroundMitt } from "@/modules/emitter";
|
|
import { ipcEmit, loadState, saveToJson } from './helpers';
|
|
import { ipcMain, IpcMainEvent, IpcMainInvokeEvent } from "electron";
|
|
|
|
import useWebSockets from "@/modules/websockets";
|
|
|
|
import { play } from "./audio";
|
|
import { renderMessage } from "@/modules/message";
|
|
import { AuthProtocol, SessionState, Profile } from "@/types";
|
|
|
|
let win = true;
|
|
|
|
// Info saved to json on quit (key, newMessages).
|
|
let state: SessionState;
|
|
|
|
// Profile of current user.
|
|
let profile: Profile | boolean;
|
|
|
|
// Called when server sends auth message.
|
|
const updateState = (res: AuthProtocol) => {
|
|
console.log("SESS:Auth message received: \n" +
|
|
` key: ${res.key}\n` +
|
|
` alias: ${res.profile}`)
|
|
|
|
if (state) {
|
|
|
|
// Update key.
|
|
state.key = res.key;
|
|
|
|
// Update the user profile.
|
|
profile = res.profile;
|
|
|
|
// Send upated profile to frontend.
|
|
console.log("SESS:Sending updated user profile to browser.")
|
|
ipcEmit("update-state", {
|
|
profile: profile,
|
|
newMessages: state.newMessages
|
|
})
|
|
|
|
// Save the updated state to json.
|
|
console.log("SESS:Saving session state.")
|
|
saveToJson("session.json", state)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Send state on new window.
|
|
const onNewBrowserWindow = (_event: IpcMainInvokeEvent, _payload: any) => {
|
|
if (typeof profile !== 'undefined') {
|
|
console.log("SESS:Sending user profile to browser.")
|
|
ipcEmit("update-state", {
|
|
profile: profile,
|
|
newMessages: state.newMessages
|
|
})
|
|
}
|
|
}
|
|
|
|
// Calls appropriate endpoint for a server message.
|
|
const onMessage = (data: string) => {
|
|
let message = JSON.parse(data)
|
|
|
|
// AuthProtocol message.
|
|
if (message.hasOwnProperty("key")) {
|
|
updateState(message)
|
|
}
|
|
|
|
// Standard message.
|
|
else if (message.content) {
|
|
|
|
// Convert to render message
|
|
message = renderMessage(
|
|
message.content.text,
|
|
message.content.audio,
|
|
message.context,
|
|
message.modifier
|
|
);
|
|
|
|
if (win) {
|
|
console.log("SESS:Emitting standard message.")
|
|
if (message.audio) {
|
|
play(message.audio)
|
|
}
|
|
ipcEmit("render-message", message)
|
|
}
|
|
|
|
else {
|
|
console.log("SESS:No window: saving message.")
|
|
state.newMessages.push(message);
|
|
}
|
|
}
|
|
|
|
else {
|
|
if (win) {
|
|
ipcEmit("render-message", message)
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
// When socket connects, we update state.
|
|
const onOpen = () => {
|
|
console.log(`SESS:Sending key: ${state.key}`)
|
|
|
|
if (state) {
|
|
sendMessage({
|
|
"key": state.key,
|
|
"usr": false,
|
|
"pwd": false
|
|
})
|
|
}
|
|
}
|
|
|
|
// Websockets module.
|
|
const { createSocket, sendMessage } = useWebSockets(onMessage, onOpen);
|
|
|
|
// Handle messages from window/client.
|
|
const onClientMessage = (_event: IpcMainEvent, payload: any) => {
|
|
console.log("New client message")
|
|
|
|
const success = sendMessage(payload)
|
|
|
|
if (!success) {
|
|
console.log("Unable to send message: ", payload)
|
|
}
|
|
|
|
}
|
|
|
|
// Call this to initialize session with Crimata servers.
|
|
export const initSession = () => {
|
|
console.log("SESS:Creating new session.")
|
|
|
|
// Load Json or createState.
|
|
state = loadState("session.json")
|
|
|
|
console.log("SESS:State loaded: \n" +
|
|
` key: ${state.key}\n` +
|
|
` new: ${state.newMessages}`)
|
|
|
|
// Open socket connection.
|
|
createSocket()
|
|
|
|
// Attack browser window init listener.
|
|
ipcMain.removeAllListeners("app-mounted")
|
|
ipcMain.on("app-mounted", onNewBrowserWindow);
|
|
|
|
// Attach listeners for frontend.
|
|
ipcMain.removeAllListeners("client-message")
|
|
ipcMain.on("client-message", onClientMessage);
|
|
|
|
// Keep win up-to-date.
|
|
backgroundMitt.on('window-active', (state: boolean) => {
|
|
win = state;
|
|
});
|
|
|
|
}
|