Open Ishu1998 opened 1 year ago
use electron-store
to store and persist the data.
Check this out for more. https://www.npmjs.com/package/electron-store
Hey @Ishu1998, as @dhineshtp suggested, you will use electron-store to do it. Would you want to have a basic usage example?
Server-Side (IpcMain)
Constants
export const WINDOW_NAME_APP = 'my_awesome_application'
export const IPC_EVENT_CONFIG = 'event:config'
export const IPC_EVENTS = [
IPC_EVENT_CONFIG,
] as const
export type IpcEvent = typeof IPC_EVENTS[number]
export const IPC_PROMISE_CONFIG = 'promise:config'
export const IPC_PROMISES = [
IPC_PROMISE_CONFIG,
] as const
export type IpcPromise = typeof IPC_PROMISES[number]
export const STORE_KEY_CONFIG= 'system'
export const STORE_KEYS = [
STORE_KEY_CONFIG,
] as const
export type StoreKey = typeof STORE_KEYS[number]
index.ts (background.ts)
import { app } from 'electron'
import { createWindow } from '#server/window'
import serve from 'electron-serve'
const is_prod: boolean = process.env.NODE_ENV === 'production'
if (is_prod) {
serve({ directory: 'app' })
} else {
app.setPath('userData', `${app.getPath('userData')}-development`)
}
(async () => {
await app.whenReady()
const mainWindow = createWindow(app)
if (is_prod) return mainWindow.loadURL('app://./index.html')
const port = process.argv[2]
await mainWindow.loadURL(`http://localhost:${port}/`)
mainWindow.webContents.openDevTools()
})()
app.on('window-all-closed', () => app.quit())
window.ts
import { getConfig } from '#server/config'
import { BrowserWindow, ipcMain } from 'electron'
import { IPC_EVENT_CONFIG, IPC_PROMISE_CONFIG, WINDOW_NAME_APP } from '#constants'
import Store from 'electron-store'
export function createWindow (app: Electron.App): BrowserWindow {
const name = WINDOW_NAME_APP
const store = new Store({ name })
store.set(STORE_KEY_CONFIG, {
arch: process.arch,
user_path: app.getPath('userData'),
})
const application = new BrowserWindow({
width: 875,
height: 585,
center: true,
frame: false,
transparent: true,
resizable: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
})
// IPC_EVENTS
ipcMain.on(IPC_EVENT_CONFIG, (event) => getConfig(store))
// IPC_PROMISES
ipcMain.handle(IPC_PROMISE_CONFIG, async () => getConfig(store))
return application
}
config.ts
import { STORE_KEY_CONFIG } from '#constants'
export type User = {
name?: string
email?: string
}
export type ConfigProps = {
user?: User
}
export async function getConfigPromise(store: Store<ConfigProps>): Promise<ConfigProps> {
const system = store.get(STORE_KEY_CONFIG)
return { user }
}
And finally in the client you can implement a class service like the folowing:
import { IPC_EVENT_CONFIG, IPC_PROMISE_CONFIG} from '#constants'
import { ConfigProps } from '#server/config'
import { IpcRenderer } from 'electron'
export class Service {
ipcRenderer: IpcRenderer
constructor(ipcRenderer: IpcRenderer) {
this.ipcRenderer = ipcRenderer
}
async getConfig(): Promise<void> {
return this.ipcRenderer.send(IPC_EVENT_CONFIG)
}
async getConfigPromise(): Promise<ConfigProps> {
return this.ipcRenderer.invoke(IPC_PROMISE_CONFIG)
}
}
You can also use a hook to catch an event payload:
import { IpcEvent } from '#constants'
import { useMemo, useState } from 'react'
import electron from 'electron'
export function useEvent <T> (event_name: IpcEvent): T {
const [ state, setState ] = useState<T>()
electron?.ipcRenderer?.removeAllListeners(event_name)
electron?.ipcRenderer?.on(event_name, (_event, args) => setState(args))
return useMemo(() => state, [ state ])
}
Usage in a component
import { User as TUser } from '#server/config'
import React, { useEffect, useState } from 'react'
export const User: React.FC = () => {
const { service } = useHelpers()
const payload = useEvent<ConfigProps>(IPC_EVENT_CONFIG)
const [ state, setState ] = useState<TUser>()
useEffect(() => {
if (payload?.user) setState(payload?.user)
getConfig()
}, [ payload ])
return (
<>
<span>{state?.name}</span>
<span>{state?.email}</span>
</>
)
async function getConfig(): Promise<void> {
const config = await service.getConfig()
setState(config?.user)
}
}
helper context
import { Service } from '#service'
import { ConfigProps } from '#types'
import React, { createContext, PropsWithChildren, useContext } from 'react'
export interface Helpers {
service?: Service
}
export type ProviderProps = {
helpers: Helpers
}
export const HelpersContext = createContext<Helpers>({})
export const HelpersProvider: React.FC<PropsWithChildren<ProviderProps>> = (
{ helpers, children }: PropsWithChildren<ProviderProps>
) => (
<HelpersContext.Provider value={helpers}>{children}</HelpersContext.Provider>
)
export function useHelpers(): Helpers {
return useContext<Helpers>(HelpersContext)
}
_app.tsx
import { AppProps } from 'next/app'
import { Helpers, HelpersProvider } from '#shared/hooks/helper'
import { Service } from '#service'
import electron from 'electron'
import React, { useEffect, useMemo, useState } from 'react'
export default (
{ Component, pageProps }: AppProps
) => {
const service = useMemo<Helpers['service']>(() => (
new Service(electron.ipcRenderer)
), [ electron.ipcRenderer ])
const [ helpers, setHelpers ] = useState<Helpers>({ service })
return (
<HelpersProvider helpers={helpers}>
<Component {...pageProps}/>
</HelpersProvider>
)
}
I hope it will help you, do not hesitate to give me a feedback. Good luck and have fun dude!
Ive added my suggest in the discussions section 😘
Ah and of course If our suggests solve your issue, could you close it ASAP? 😘
@Ishu1998 , are you still alive? ❤️
Even with using electron-store it doesn't help with cookies that are necessary for 3rd party libraries (Supabase)
Cookies work in Dev but not in Prod
Same issue - https://github.com/electron-userland/electron-builder/issues/5278
Please let me know how to solve this. Thanks