add useIpc hook
This commit is contained in:
parent
cc2babdadc
commit
479bafdde5
12 changed files with 161 additions and 75 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,6 +9,7 @@ crash.log
|
||||||
# local env files
|
# local env files
|
||||||
.env.local
|
.env.local
|
||||||
.env.*.local
|
.env.*.local
|
||||||
|
.env
|
||||||
|
|
||||||
# Log files
|
# Log files
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
"animejs": "^3.2.0",
|
"animejs": "^3.2.0",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
"dotenv": "^10.0.0",
|
||||||
"electron-is-dev": "^2.0.0",
|
"electron-is-dev": "^2.0.0",
|
||||||
"electron-store": "^8.0.0",
|
"electron-store": "^8.0.0",
|
||||||
"electron-updater": "^4.3.8",
|
"electron-updater": "^4.3.8",
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export const logout =
|
||||||
export const fetchProfile = async(email: string, token: string) => (
|
export const fetchProfile = async(email: string, token: string) => (
|
||||||
|
|
||||||
await axios({
|
await axios({
|
||||||
url: "http://127.0.0.1:3010/api/account/profile",
|
url: "http://127.0.0.1:3000/api/account/profile",
|
||||||
headers: {
|
headers: {
|
||||||
Cookie: `jwt=${token}`
|
Cookie: `jwt=${token}`
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import { ipcMain } from "electron";
|
|
||||||
import { backgroundMitt } from '@/modules/emitter';
|
import { backgroundMitt } from '@/modules/emitter';
|
||||||
|
|
||||||
const portAudio = require('naudiodon');
|
const portAudio = require('naudiodon');
|
||||||
|
|
||||||
// Audio in and out stream objects.
|
// Audio in and out stream objects.
|
||||||
|
|
@ -26,27 +24,22 @@ const audioOptions = {
|
||||||
closeOnError: false,
|
closeOnError: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggles record to true to begin capturing chunks.
|
export const toggleRecord = (): void => { record = !record };
|
||||||
const onRecordingStart = (_event: any, _payload: any) => {
|
|
||||||
console.log("AUDIO: Beginning audio capture.")
|
|
||||||
record = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns recorded audio to frontend and sets record to false.
|
|
||||||
const onRecordingEnd = async (_event: any, payload: any) => {
|
|
||||||
console.log("AUDIO:Sending audio to browser.")
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
export const fetchAudioInput = (): Promise<Error | string> => (
|
||||||
|
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
resolve(audioContainer.input);
|
resolve(audioContainer.input);
|
||||||
record = false;
|
toggleRecord();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject()
|
reject(new Error('Failed to fetch the audio.'))
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
})
|
||||||
};
|
)
|
||||||
|
|
||||||
|
|
||||||
// Main audio function run by run.ts module.
|
// Main audio function run by run.ts module.
|
||||||
|
|
@ -86,15 +79,6 @@ export function initAudioIO(): void {
|
||||||
ao.start();
|
ao.start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen to record.
|
|
||||||
console.log("AUDIO:Adding recording listeners.")
|
|
||||||
|
|
||||||
ipcMain.removeAllListeners("start-recording");
|
|
||||||
ipcMain.on("start-recording", onRecordingStart);
|
|
||||||
|
|
||||||
ipcMain.removeHandler("stop-recording");
|
|
||||||
ipcMain.handle("stop-recording", onRecordingEnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import { app, dialog, ipcMain, IpcMainInvokeEvent } from "electron";
|
import { app, dialog } from "electron";
|
||||||
import { createWindow } from './window';
|
import { createWindow } from './window';
|
||||||
import { initSession, onAppMounted } from './session';
|
import { stopStream } from './audio';
|
||||||
import { initAudioIO, stopStream } from './audio';
|
|
||||||
import { backgroundMitt } from '@/modules/emitter';
|
import { backgroundMitt } from '@/modules/emitter';
|
||||||
import { initAccountListener } from "@/background/ipc/account";
|
import useIpc from "@/background/ipc/index";
|
||||||
|
const { autoUpdater } = require('electron-updater');
|
||||||
|
|
||||||
let win: boolean;
|
let win: boolean;
|
||||||
|
|
||||||
|
|
@ -16,7 +16,6 @@ backgroundMitt.on('window-active', (state: boolean) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Auto updating.
|
// Auto updating.
|
||||||
const { autoUpdater } = require('electron-updater');
|
|
||||||
autoUpdater.requestHeaders = { 'PRIVATE-TOKEN': 'mvvgWYwWnot4bisiQMh_' }
|
autoUpdater.requestHeaders = { 'PRIVATE-TOKEN': 'mvvgWYwWnot4bisiQMh_' }
|
||||||
|
|
||||||
autoUpdater.on('update-available', (info: any) => {
|
autoUpdater.on('update-available', (info: any) => {
|
||||||
|
|
@ -40,29 +39,13 @@ autoUpdater.on('update-downloaded', (info: any) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const onSessionInit = (_event: IpcMainInvokeEvent, cid: string) => {
|
|
||||||
// Instantiate socket session with crimata-platorm.
|
|
||||||
initSession(cid);
|
|
||||||
|
|
||||||
// Begin audio stream.
|
|
||||||
initAudioIO();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Run when electron app is initialized.
|
// Run when electron app is initialized.
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
|
|
||||||
console.log("MAIN:Initializing Electron App.");
|
console.log("MAIN:Initializing Electron App.");
|
||||||
|
|
||||||
// Attack browser window init listener.
|
useIpc();
|
||||||
ipcMain.removeAllListeners("app-mounted");
|
|
||||||
ipcMain.on("app-mounted", onAppMounted);
|
|
||||||
|
|
||||||
ipcMain.removeAllListeners("init-session");
|
|
||||||
ipcMain.on("init-session", onSessionInit);
|
|
||||||
|
|
||||||
// handler user auth, login, and logout asynchrounously
|
|
||||||
initAccountListener();
|
|
||||||
|
|
||||||
// Must wait til window is created.
|
// Must wait til window is created.
|
||||||
await createWindow();
|
await createWindow();
|
||||||
|
|
@ -74,7 +57,7 @@ export function initApp(dev: boolean): void {
|
||||||
|
|
||||||
// On initial startup.
|
// On initial startup.
|
||||||
app.on("ready", () => {
|
app.on("ready", () => {
|
||||||
autoUpdater.checkForUpdates()
|
// autoUpdater.checkForUpdates()
|
||||||
main()
|
main()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import { Profile } from "@/types";
|
import { Profile } from "@/types";
|
||||||
import { submit, fetchProfile, logout } from "@/api/account";
|
import { submit, fetchProfile, logout } from "@/api/account";
|
||||||
import { ipcMain } from "electron";
|
import { ipcMain, IpcMainInvokeEvent } from "electron";
|
||||||
import { store } from "@/background/store";
|
import { store } from "@/background/store";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -17,9 +17,10 @@ const parseAuthRes = (authRes: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const onProfile = async (_event: any, _payload: string) => (
|
const onProfile = async (_event: IpcMainInvokeEvent, _payload: string) => (
|
||||||
|
|
||||||
new Promise(async (resolve, reject) => {
|
new Promise(async (resolve, reject) => {
|
||||||
|
console.log('[IPC]: user-profile');
|
||||||
|
|
||||||
// get jwt token and crimataId from store
|
// get jwt token and crimataId from store
|
||||||
const token = store.get('key');
|
const token = store.get('key');
|
||||||
|
|
@ -43,9 +44,10 @@ const onProfile = async (_event: any, _payload: string) => (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
const onLogin = async (_event: any, payload: string) => (
|
const onLogin = async (_event: IpcMainInvokeEvent, payload: string) => (
|
||||||
|
|
||||||
new Promise(async (resolve, reject) => {
|
new Promise(async (resolve, reject) => {
|
||||||
|
console.log('[IPC]: user-login');
|
||||||
|
|
||||||
const account = JSON.parse(payload);
|
const account = JSON.parse(payload);
|
||||||
|
|
||||||
|
|
@ -69,9 +71,10 @@ const onLogin = async (_event: any, payload: string) => (
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const onLogout = async (_event: any, _payload: string) => (
|
const onLogout = async (_event: IpcMainInvokeEvent, _payload: string) => (
|
||||||
|
|
||||||
new Promise(async (resolve, reject) => {
|
new Promise(async (resolve, reject) => {
|
||||||
|
console.log('[IPC]: user-logout');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// post logout to backend
|
// post logout to backend
|
||||||
|
|
@ -91,7 +94,7 @@ const onLogout = async (_event: any, _payload: string) => (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
export const initAccountListener = () => {
|
export default function useAccountListeners(): void {
|
||||||
|
|
||||||
ipcMain.removeHandler("user-profile");
|
ipcMain.removeHandler("user-profile");
|
||||||
ipcMain.handle("user-profile", onProfile);
|
ipcMain.handle("user-profile", onProfile);
|
||||||
|
|
|
||||||
39
src/background/ipc/audio.ts
Normal file
39
src/background/ipc/audio.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import { ipcMain, IpcMainInvokeEvent, IpcMainEvent } from "electron";
|
||||||
|
import { fetchAudioInput, toggleRecord } from "@/background/audio";
|
||||||
|
|
||||||
|
|
||||||
|
// Toggles record to true to begin capturing chunks.
|
||||||
|
const onRecordingStart = (
|
||||||
|
_event: IpcMainEvent,
|
||||||
|
_payload: null): void => {
|
||||||
|
|
||||||
|
console.log('[IPC]: start-recording');
|
||||||
|
|
||||||
|
toggleRecord();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Returns recorded audio to frontend and sets record to false.
|
||||||
|
const onRecordingStop = async (
|
||||||
|
_event: IpcMainInvokeEvent,
|
||||||
|
_payload: null
|
||||||
|
): Promise<Error | string> => {
|
||||||
|
|
||||||
|
console.log('[IPC]: stop-recording');
|
||||||
|
|
||||||
|
return await fetchAudioInput()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default function useAudioListeners(): void {
|
||||||
|
|
||||||
|
ipcMain.removeAllListeners("start-recording");
|
||||||
|
ipcMain.on("start-recording", onRecordingStart);
|
||||||
|
|
||||||
|
ipcMain.removeHandler("stop-recording");
|
||||||
|
ipcMain.handle("stop-recording", onRecordingStop);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import useAccountListeners from "./account";
|
||||||
|
import useSessionListeners from "./session";
|
||||||
|
import useAudioListeners from "./audio";
|
||||||
|
|
||||||
|
|
||||||
|
export default function useIpc(): void {
|
||||||
|
|
||||||
|
useAccountListeners();
|
||||||
|
|
||||||
|
useSessionListeners();
|
||||||
|
|
||||||
|
useAudioListeners();
|
||||||
|
|
||||||
|
}
|
||||||
61
src/background/ipc/session.ts
Normal file
61
src/background/ipc/session.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import { initSession, emitNewMessages, sendMessage } from '@/background/session';
|
||||||
|
import { ipcMain, IpcMainInvokeEvent, IpcMainEvent } from "electron";
|
||||||
|
import { initAudioIO } from "@/background/audio";
|
||||||
|
|
||||||
|
|
||||||
|
// Instantiate socket session with crimata-platorm.
|
||||||
|
const onSessionInit = (
|
||||||
|
_event: IpcMainInvokeEvent,
|
||||||
|
cid: string
|
||||||
|
): void => {
|
||||||
|
|
||||||
|
console.log('[IPC]: init-session');
|
||||||
|
|
||||||
|
initSession(cid);
|
||||||
|
|
||||||
|
initAudioIO();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const onAppMounted = (
|
||||||
|
_event: IpcMainInvokeEvent,
|
||||||
|
_payload: any
|
||||||
|
): void => {
|
||||||
|
|
||||||
|
console.log('[IPC]: app-mounted');
|
||||||
|
|
||||||
|
emitNewMessages()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Handle messages from window/client.
|
||||||
|
const onClientMessage = async (
|
||||||
|
_event: IpcMainEvent,
|
||||||
|
payload: Record<string, any>
|
||||||
|
): Promise<void> => {
|
||||||
|
|
||||||
|
console.log('[IPC]: client-message');
|
||||||
|
|
||||||
|
sendMessage(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function useSessionListeners(): void {
|
||||||
|
|
||||||
|
console.log('[IPC]: Init session listeners.');
|
||||||
|
|
||||||
|
// Attach listeners for frontend.
|
||||||
|
ipcMain.removeAllListeners("client-message");
|
||||||
|
ipcMain.on("client-message", onClientMessage);
|
||||||
|
|
||||||
|
// Attack browser window init listener.
|
||||||
|
ipcMain.removeAllListeners("app-mounted");
|
||||||
|
ipcMain.on("app-mounted", onAppMounted);
|
||||||
|
|
||||||
|
ipcMain.removeAllListeners("init-session");
|
||||||
|
ipcMain.on("init-session", onSessionInit);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -9,8 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { backgroundMitt } from "@/modules/emitter";
|
import { backgroundMitt } from "@/modules/emitter";
|
||||||
import { ipcEmit, loadState, saveToJson } from './helpers';
|
import { ipcEmit, loadState } from './helpers';
|
||||||
import { ipcMain, IpcMainEvent, IpcMainInvokeEvent } from "electron";
|
|
||||||
|
|
||||||
import useWebSockets from "./websockets";
|
import useWebSockets from "./websockets";
|
||||||
|
|
||||||
|
|
@ -23,17 +22,9 @@ let win = true;
|
||||||
// Info saved to json on quit (key, newMessages).
|
// Info saved to json on quit (key, newMessages).
|
||||||
let state: SessionState;
|
let state: SessionState;
|
||||||
|
|
||||||
// Send state on new window.
|
|
||||||
export const onAppMounted = (_event: IpcMainInvokeEvent, _payload: any) => {
|
|
||||||
|
|
||||||
ipcEmit("update-state", {
|
|
||||||
newMessages: state.newMessages,
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls appropriate endpoint for a server message.
|
// Calls appropriate endpoint for a server message.
|
||||||
const onMessage = (data: string) => {
|
const onMessage = (data: string): void => {
|
||||||
let message = JSON.parse(data);
|
let message = JSON.parse(data);
|
||||||
console.log('received new message', message);
|
console.log('received new message', message);
|
||||||
|
|
||||||
|
|
@ -74,13 +65,18 @@ const onMessage = (data: string) => {
|
||||||
// Websockets module.
|
// Websockets module.
|
||||||
const { createSocket, send } = useWebSockets(onMessage);
|
const { createSocket, send } = useWebSockets(onMessage);
|
||||||
|
|
||||||
// Handle messages from window/client.
|
|
||||||
const onClientMessage = async (_event: IpcMainEvent, payload: any): Promise<void> => {
|
|
||||||
console.log("New client message")
|
|
||||||
|
|
||||||
if (payload.hasOwnProperty("key")) {
|
export const emitNewMessages = (): void => {
|
||||||
return
|
if (state) {
|
||||||
|
ipcEmit("update-state", {
|
||||||
|
newMessages: state.newMessages,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const sendMessage = (payload: Record<string, any>): void => {
|
||||||
try {
|
try {
|
||||||
send(payload)
|
send(payload)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|
@ -91,7 +87,7 @@ const onClientMessage = async (_event: IpcMainEvent, payload: any): Promise<void
|
||||||
|
|
||||||
|
|
||||||
// Call this to initialize session with Crimata servers.
|
// Call this to initialize session with Crimata servers.
|
||||||
export const initSession = (cid: string) => {
|
export const initSession = (cid: string): void => {
|
||||||
console.log("SESS:Creating new session.")
|
console.log("SESS:Creating new session.")
|
||||||
|
|
||||||
// Load Json or createState.
|
// Load Json or createState.
|
||||||
|
|
@ -100,10 +96,6 @@ export const initSession = (cid: string) => {
|
||||||
// Open socket connection.
|
// Open socket connection.
|
||||||
createSocket();
|
createSocket();
|
||||||
|
|
||||||
// Attach listeners for frontend.
|
|
||||||
ipcMain.removeAllListeners("client-message");
|
|
||||||
ipcMain.on("client-message", onClientMessage);
|
|
||||||
|
|
||||||
// Keep win up-to-date.
|
// Keep win up-to-date.
|
||||||
backgroundMitt.on('window-active', (state: boolean) => {
|
backgroundMitt.on('window-active', (state: boolean) => {
|
||||||
win = state;
|
win = state;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import axios, { AxiosRequestConfig } from 'axios';
|
import axios, { AxiosRequestConfig } from 'axios';
|
||||||
|
|
||||||
const baseURL = 'http://127.0.0.1:3010/api';
|
const baseURL = 'http://127.0.0.1:3000/api';
|
||||||
|
|
||||||
|
|
||||||
interface Request {
|
interface Request {
|
||||||
|
|
|
||||||
|
|
@ -4898,6 +4898,11 @@ dotenv-expand@^5.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
|
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
|
||||||
integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
|
integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
|
||||||
|
|
||||||
|
dotenv@^10.0.0:
|
||||||
|
version "10.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
|
||||||
|
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
|
||||||
|
|
||||||
dotenv@^8.2.0:
|
dotenv@^8.2.0:
|
||||||
version "8.2.0"
|
version "8.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue