refactor frontend ipc
This commit is contained in:
parent
c8411d573a
commit
56196bcbcf
13 changed files with 177 additions and 52 deletions
|
|
@ -1,8 +1,9 @@
|
|||
|
||||
import { postAuth, postLogin, postLogout } from "@/api/account";
|
||||
import { endSession, launchSession } from "@/session";
|
||||
import { getToken, clearToken, setToken } from "./store";
|
||||
import { getToken, setToken, setProfile, getProfile, clearStore } from "./store";
|
||||
import { parseAuthRes } from "./auth";
|
||||
import { ipcEmit } from "@/composables/useEmitter";
|
||||
|
||||
export const accountAuth = async (): Promise<Error | AuthState> => {
|
||||
|
||||
|
|
@ -18,6 +19,7 @@ export const accountAuth = async (): Promise<Error | AuthState> => {
|
|||
const parsed = parseAuthRes(res);
|
||||
|
||||
setToken(parsed.token)
|
||||
setProfile(parsed.profile);
|
||||
|
||||
return {
|
||||
profile: parsed.profile,
|
||||
|
|
@ -26,7 +28,7 @@ export const accountAuth = async (): Promise<Error | AuthState> => {
|
|||
|
||||
} catch(e) {
|
||||
console.log('[ACCOUNT]', e);
|
||||
clearToken();
|
||||
clearStore();
|
||||
throw(new Error('Failed to authenticate.'));
|
||||
|
||||
}
|
||||
|
|
@ -45,6 +47,7 @@ export const accountLogin: IpcHandlerCallback<AccountCredentials, Profile> = asy
|
|||
|
||||
// save jwt token and profile
|
||||
setToken(parsed.token);
|
||||
setProfile(parsed.profile);
|
||||
|
||||
// launch session
|
||||
launchSession(parsed.token);
|
||||
|
|
@ -53,6 +56,7 @@ export const accountLogin: IpcHandlerCallback<AccountCredentials, Profile> = asy
|
|||
return parsed.profile;
|
||||
|
||||
} catch(e) {
|
||||
clearStore();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +69,7 @@ export const accountLogout = async (): Promise<Error | void> => {
|
|||
await postLogout();
|
||||
|
||||
// remove key and crimataId
|
||||
clearToken();
|
||||
clearStore();
|
||||
|
||||
// kill crimata platform session
|
||||
endSession();
|
||||
|
|
@ -79,4 +83,13 @@ export const accountLogout = async (): Promise<Error | void> => {
|
|||
|
||||
}
|
||||
|
||||
export const updateAppState = (): void => {
|
||||
|
||||
const profile = getProfile();
|
||||
|
||||
ipcEmit("set-profile", profile);
|
||||
|
||||
// ipcEmit('messages') etc
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
|
||||
import { ipcMain, IpcMainInvokeEvent, IpcMainEvent } from "electron";
|
||||
|
||||
export class IpcHandler<InputType, ReturnType> implements IIpcHandler<InputType, ReturnType> {
|
||||
export class IpcHandler<InputParam, ReturnType> implements IIpcHandler<InputParam, ReturnType> {
|
||||
|
||||
readonly channel: string;
|
||||
|
||||
readonly _handlerCallback: IpcHandlerCallback<InputType, ReturnType>;
|
||||
readonly _handlerCallback: IpcHandlerCallback<InputParam, ReturnType>;
|
||||
|
||||
constructor(options: {
|
||||
channel: string;
|
||||
handlerCallback: IpcHandlerCallback<InputType, ReturnType>;
|
||||
handlerCallback: IpcHandlerCallback<InputParam, ReturnType>;
|
||||
}) {
|
||||
this.channel = options.channel;
|
||||
this._handlerCallback = options.handlerCallback;
|
||||
}
|
||||
|
||||
handle() {
|
||||
console.log(`[IPC] INIT: ${this.channel}`);
|
||||
this.remove();
|
||||
ipcMain.handle(this.channel, this._onInvoke);
|
||||
}
|
||||
|
|
@ -49,22 +48,21 @@ export class IpcHandler<InputType, ReturnType> implements IIpcHandler<InputType,
|
|||
}
|
||||
|
||||
|
||||
export class IpcListener<InputType> implements IIpcListener<InputType> {
|
||||
export class IpcListener<InputParam> implements IIpcListener<InputParam> {
|
||||
|
||||
readonly channel: string;
|
||||
|
||||
readonly _listenerCallback: IpcListenerCallback<InputType>;
|
||||
readonly _listenerCallback: IpcListenerCallback<InputParam>;
|
||||
|
||||
constructor(options: {
|
||||
channel: string;
|
||||
listenerCallback: IpcListenerCallback<InputType>;
|
||||
listenerCallback: IpcListenerCallback<InputParam>;
|
||||
}) {
|
||||
this.channel = options.channel;
|
||||
this._listenerCallback = options.listenerCallback;
|
||||
}
|
||||
|
||||
listen() {
|
||||
console.log(`[IPC] Init: ${this.channel}`);
|
||||
this.remove();
|
||||
ipcMain.on(this.channel, this._onPost);
|
||||
}
|
||||
|
|
@ -82,7 +80,3 @@ export class IpcListener<InputType> implements IIpcListener<InputType> {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
import { accountLogin, accountLogout } from "@/account";
|
||||
import { accountLogin, accountLogout, accountProfile } from "@/account";
|
||||
import { IpcHandler } from "@/composables/useIpcMain";
|
||||
import { flush } from "@/audio";
|
||||
|
||||
|
||||
const LOGIN_CHANNEL = "invoke-account-login";
|
||||
const LOGOUT_CHANNEL = "invoke-account-logout";
|
||||
const GET_AUDIO_CHANNEL = "invoke-audio-flush";
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
import { IpcListener } from "@/composables/useIpcMain"
|
||||
import { sendMessage } from '@/session';
|
||||
import { collect } from "@/audio";
|
||||
import { updateAppState } from "@/account";
|
||||
|
||||
const CLIENT_MESSAGE_CHANNEL = "post-session-send"
|
||||
const GET_AUDIO_CHANNEL = "post-audio-collect";
|
||||
const APP_MOUNT_CHANNEL = "post-app-mount";
|
||||
|
||||
export const messageListener = new IpcListener<Message>({
|
||||
channel: CLIENT_MESSAGE_CHANNEL,
|
||||
|
|
@ -15,3 +17,8 @@ export const audioChunkListener = new IpcListener<ArrayBuffer>({
|
|||
channel: GET_AUDIO_CHANNEL,
|
||||
listenerCallback: collect
|
||||
});
|
||||
|
||||
export const appMountListener = new IpcListener<null>({
|
||||
channel: APP_MOUNT_CHANNEL,
|
||||
listenerCallback: updateAppState
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@
|
|||
*/
|
||||
|
||||
import initIpcMain from "@/ipc/index";
|
||||
import { accountAuth } from "./account";
|
||||
import { accountAuth, updateAppState } from "./account";
|
||||
import { launchSession } from "./session";
|
||||
import { ipcEmit } from "./composables/useEmitter";
|
||||
import createWindow from "./window";
|
||||
|
||||
let authState: AuthState | null;
|
||||
|
|
@ -31,12 +30,10 @@ export default async function main() {
|
|||
console.log('AUTH:', e);
|
||||
authState = null;
|
||||
} finally {
|
||||
let profile = null;
|
||||
if (authState) {
|
||||
launchSession(authState.token as string);
|
||||
profile = authState.profile;
|
||||
}
|
||||
ipcEmit("set-profile", profile);
|
||||
updateAppState();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,14 +23,16 @@
|
|||
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent, onMounted, onUnmounted, Ref, ref } from "vue";
|
||||
import { defineComponent, onMounted } from "vue";
|
||||
import { IpcRendererEvent } from "electron";
|
||||
|
||||
import Splash from "@/render/components/splash.vue";
|
||||
import Messenger from "@/render/components/messenger.vue";
|
||||
import Login from "@/render/components/login.vue";
|
||||
import Header from "@/render/components/header.vue";
|
||||
|
||||
import useProfile from "@/render/composables/useProfile";
|
||||
import { postAppMount } from "@/render/ipc";
|
||||
|
||||
export default defineComponent({
|
||||
|
||||
|
|
@ -43,25 +45,9 @@ export default defineComponent({
|
|||
|
||||
setup() {
|
||||
|
||||
const authComplete = ref(false);
|
||||
const { profile, authComplete } = useProfile();
|
||||
|
||||
const { setProfile, clearProfile, profile } = useProfile();
|
||||
|
||||
onMounted(async () => {
|
||||
console.log("[APP]:mounted.");
|
||||
|
||||
/* listen for auth related messages */
|
||||
window.ipcRenderer.on("set-profile", (_event: IpcRendererEvent, payload: any) => {
|
||||
console.log('progfile', payload.message)
|
||||
payload.message ? setProfile(payload.message) : clearProfile();
|
||||
authComplete.value = true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.ipcRenderer.removeAllListeners("set-profile");
|
||||
});
|
||||
onMounted(() => postAppMount());
|
||||
|
||||
return {
|
||||
authComplete,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,38 @@
|
|||
|
||||
export default function useIpc () {
|
||||
import { IpcRendererEvent } from "electron";
|
||||
|
||||
export class IpcRendererListener<InputParam> implements IIpcListener<InputParam> {
|
||||
|
||||
readonly channel: string;
|
||||
|
||||
readonly _listenerCallback: IpcListenerCallback<InputParam>;
|
||||
|
||||
constructor(options: {
|
||||
channel: string;
|
||||
listenerCallback: IpcListenerCallback<InputParam>;
|
||||
}) {
|
||||
this.channel = options.channel;
|
||||
this._listenerCallback = options.listenerCallback;
|
||||
}
|
||||
|
||||
listen() {
|
||||
this.remove();
|
||||
window.ipcRenderer.on(this.channel, this._onPost);
|
||||
}
|
||||
|
||||
remove() {
|
||||
window.ipcRenderer.removeAllListeners(this.channel);
|
||||
}
|
||||
|
||||
private _onPost = (_e: IpcRendererEvent, payload: IpcEmitPayload<InputParam>): void => {
|
||||
console.log(`[IPC] Post: ${this.channel}`);
|
||||
this._listenerCallback(payload.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default function useIpcRenderer () {
|
||||
|
||||
const invoke = async (endpoint: string, payload: any) => {
|
||||
try {
|
||||
|
|
@ -16,6 +49,6 @@ export default function useIpc () {
|
|||
|
||||
return {
|
||||
invoke,
|
||||
post
|
||||
post,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,30 @@ import { ref } from "vue";
|
|||
|
||||
const profile = ref();
|
||||
|
||||
const authComplete = ref(false);
|
||||
|
||||
const useProfile = () => {
|
||||
|
||||
const setProfile = (payload: Profile) => {
|
||||
profile.value = payload;
|
||||
const setProfile: IpcListenerCallback<Profile | null> = (payload) => {
|
||||
payload ? profile.value = payload : clearProfile();
|
||||
showRender();
|
||||
}
|
||||
|
||||
const clearProfile = () => {
|
||||
profile.value = null;
|
||||
}
|
||||
|
||||
const showRender = () => {
|
||||
authComplete.value = true;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
setProfile,
|
||||
clearProfile,
|
||||
profile
|
||||
profile,
|
||||
showRender,
|
||||
authComplete,
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
import useIpc from "@/render/composables/useIpcRend";
|
||||
import * as rendererListeners from "./listeners";
|
||||
|
||||
const { post, invoke } = useIpc();
|
||||
|
||||
|
|
@ -47,3 +48,33 @@ export const invokeSession = async (cid: string): Promise<Profile | Error> => (
|
|||
export const postMessage = (payload: Message): void => (
|
||||
post('post-session-send', payload)
|
||||
);
|
||||
|
||||
export const postAppMount = (): void => (
|
||||
post('post-app-mount', null)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Ipc Renderer Listeners
|
||||
*
|
||||
*/
|
||||
|
||||
let ipcListeners: IPCListeners = {};
|
||||
|
||||
export const initIpcRendererListeners = () => {
|
||||
for (const [key, listener] of Object.entries(rendererListeners)) {
|
||||
if (!(key in ipcListeners)) {
|
||||
ipcListeners[key] = listener;
|
||||
listener.listen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const removeListeners = () => {
|
||||
for (const [key, listener] of Object.entries(rendererListeners)) {
|
||||
listener.remove();
|
||||
}
|
||||
ipcListeners = {};
|
||||
};
|
||||
|
||||
|
|
|
|||
32
src/render/listeners.ts
Normal file
32
src/render/listeners.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
import { IpcRendererListener } from "./composables/useIpcRend"
|
||||
import useProfile from "./composables/useProfile";
|
||||
|
||||
const { setProfile } = useProfile();
|
||||
|
||||
const SET_PROFILE_CHANNEL = "set-profile";
|
||||
|
||||
const INIT_MESSAGES_CHANNEL = "init-messages";
|
||||
const ADD_MESSAGE_CHANNEL = "add-message";
|
||||
const UPDATE_MESSAGE_CHANNEL = "update-message";
|
||||
|
||||
export const setProfileListener = new IpcRendererListener({
|
||||
channel: SET_PROFILE_CHANNEL,
|
||||
listenerCallback: setProfile
|
||||
});
|
||||
|
||||
export const initMessagesListener = new IpcRendererListener({
|
||||
channel: INIT_MESSAGES_CHANNEL,
|
||||
listenerCallback: () => {}
|
||||
});
|
||||
|
||||
|
||||
export const addMessagesListener = new IpcRendererListener({
|
||||
channel: ADD_MESSAGE_CHANNEL,
|
||||
listenerCallback: () => {}
|
||||
});
|
||||
|
||||
export const updateMessagesListener = new IpcRendererListener({
|
||||
channel: UPDATE_MESSAGE_CHANNEL,
|
||||
listenerCallback: () => {}
|
||||
});
|
||||
|
|
@ -6,11 +6,16 @@ import App from "./App.vue";
|
|||
import mitt from "mitt";
|
||||
import { createApp } from "vue";
|
||||
|
||||
import { initIpcRendererListeners } from "./ipc"
|
||||
|
||||
|
||||
// Handle ipcMain events.
|
||||
initIpcRendererListeners();
|
||||
|
||||
// Handle events.
|
||||
const emitter = mitt();
|
||||
|
||||
const app = createApp(App)
|
||||
const app = createApp(App);
|
||||
|
||||
app.provide("mitt", emitter)
|
||||
app.provide("mitt", emitter);
|
||||
app.mount("#app");
|
||||
|
|
|
|||
14
src/store.ts
14
src/store.ts
|
|
@ -1,9 +1,10 @@
|
|||
const Store = require('electron-store');
|
||||
|
||||
const schema = {
|
||||
key: {
|
||||
token: {
|
||||
type: 'string',
|
||||
},
|
||||
profile: {}
|
||||
};
|
||||
|
||||
const store = new Store({
|
||||
|
|
@ -17,3 +18,14 @@ export const clearToken = (): void => (store.delete("token"));
|
|||
|
||||
export const setToken = (token: string): void => (store.set('token', token));
|
||||
|
||||
export const setProfile = (profile: Profile): Profile => (store.set('profile', profile));
|
||||
|
||||
export const getProfile = (): Profile => (store.get('profile'));
|
||||
|
||||
export const clearProfile = (): void => (store.delete('profile'));
|
||||
|
||||
export const clearStore = (): void => {
|
||||
clearToken();
|
||||
clearProfile();
|
||||
}
|
||||
|
||||
|
|
|
|||
10
src/types.ts
10
src/types.ts
|
|
@ -46,8 +46,8 @@ interface IpcHandlerCallback<I, O> {
|
|||
(payload: I | null): Promise<Error | O>;
|
||||
}
|
||||
|
||||
interface IpcListenerCallback<I> {
|
||||
(payload: I | null): void;
|
||||
interface IpcListenerCallback<T> {
|
||||
(payload: T | null): void;
|
||||
}
|
||||
|
||||
interface IIpcHandler<I, O> {
|
||||
|
|
@ -67,6 +67,10 @@ interface IPCHandlers {
|
|||
}
|
||||
|
||||
interface IPCListeners {
|
||||
[listener: string]: IIpcListener<any>;
|
||||
[listener: string]: IIpcListener<any> | null;
|
||||
}
|
||||
|
||||
interface IpcEmitPayload<T> {
|
||||
message: T | null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue