feat: preferences local storage and electron sync

This commit is contained in:
Anoop M D 2023-08-19 00:36:37 +05:30
parent 94baee8e25
commit c27c750c3e
5 changed files with 148 additions and 5 deletions

View File

@ -1,11 +1,44 @@
import React from 'react';
import React, { useState } from 'react';
import { usePreferences } from 'providers/Preferences';
import StyledWrapper from './StyledWrapper';
const General = () => {
const {
preferences,
setPreferences,
} = usePreferences();
const [sslVerification, setSslVerification] = useState(
preferences.request.sslVerification
);
const handleCheckboxChange = () => {
const updatedPreferences = {
...preferences,
request: {
...preferences.request,
sslVerification: !sslVerification,
},
};
setPreferences(updatedPreferences)
.then(() => {
setSslVerification(!sslVerification);
})
.catch((err) => {
console.error(err);
});
};
return (
<StyledWrapper>
<div className="flex items-center mt-2">
<input type="checkbox" checked={true} className="mr-3 mousetrap" />
<input
type="checkbox"
checked={sslVerification}
onChange={handleCheckboxChange}
className="mr-3 mousetrap"
/>
SSL Certificate Verification
</div>
</StyledWrapper>

View File

@ -3,6 +3,7 @@ import { Provider } from 'react-redux';
import { AppProvider } from 'providers/App';
import { ToastProvider } from 'providers/Toaster';
import { HotkeysProvider } from 'providers/Hotkeys';
import { PreferencesProvider } from 'providers/Preferences';
import ReduxStore from 'providers/ReduxStore';
import ThemeProvider from 'providers/Theme/index';
@ -46,9 +47,11 @@ function MyApp({ Component, pageProps }) {
<ThemeProvider>
<ToastProvider>
<AppProvider>
<HotkeysProvider>
<Component {...pageProps} />
</HotkeysProvider>
<PreferencesProvider>
<HotkeysProvider>
<Component {...pageProps} />
</HotkeysProvider>
</PreferencesProvider>
</AppProvider>
</ToastProvider>
</ThemeProvider>

View File

@ -0,0 +1,80 @@
/**
* Preferences Provider
*
* This provider is responsible for managing the user's preferences in the app.
* The preferences are stored in the browser local storage.
*
* On start, an IPC event is published to the main process to set the preferences in the electron process.
*/
import { useEffect, createContext, useContext } from 'react';
import * as Yup from 'yup';
import useLocalStorage from 'hooks/useLocalStorage/index';
import toast from 'react-hot-toast';
const defaultPreferences = {
request: {
sslVerification: true
}
};
const preferencesSchema = Yup.object().shape({
request: Yup.object().shape({
sslVerification: Yup.boolean()
})
});
export const PreferencesContext = createContext();
export const PreferencesProvider = (props) => {
const [preferences, setPreferences] = useLocalStorage('bruno.preferences', defaultPreferences);
const { ipcRenderer } = window;
useEffect(() => {
ipcRenderer
.invoke('renderer:set-preferences', preferences)
.catch(err => {
toast.error(err.message || 'Preferences sync error');
});
}, [preferences, toast]);
const validatedSetPreferences = (newPreferences) => {
return new Promise((resolve, reject) => {
preferencesSchema.validate(newPreferences, { abortEarly: true })
.then(validatedPreferences => {
setPreferences(validatedPreferences);
resolve(validatedPreferences);
})
.catch(error => {
let errMsg = error.message || 'Preferences validation error';
toast.error(errMsg);
reject(error);
});
});
};
// todo: setPreferences must validate the preferences object against a schema
const value = {
preferences,
setPreferences: validatedSetPreferences
};
return (
<PreferencesContext.Provider value={value}>
<>
{props.children}
</>
</PreferencesContext.Provider>
);
};
export const usePreferences = () => {
const context = useContext(PreferencesContext);
if (context === undefined) {
throw new Error(`usePreferences must be used within a PreferencesProvider`);
}
return context;
};
export default PreferencesProvider;

View File

@ -0,0 +1,22 @@
/**
* The preferences are stored in the browser local storage.
* When the app is started, an IPC message is published from the renderer process to set the preferences.
* The electron process uses this module to get the preferences.
*/
let preferences = {};
const getPreferences = () => {
return preferences;
}
const setPreferences = (newPreferences) => {
console.log('setting preferences');
console.log(newPreferences);
preferences = newPreferences;
}
module.exports = {
getPreferences,
setPreferences
};

View File

@ -21,6 +21,7 @@ const { stringifyJson } = require('../utils/common');
const { openCollectionDialog, openCollection } = require('../app/collections');
const { generateUidBasedOnHash } = require('../utils/common');
const { moveRequestUid, deleteRequestUid } = require('../cache/requestUids');
const { setPreferences } = require("../app/preferences");
const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollections) => {
// browse directory
@ -431,6 +432,10 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
}
}
});
ipcMain.handle('renderer:set-preferences', async (event, preferences) => {
setPreferences(preferences);
});
};
const registerMainEventHandlers = (mainWindow, watcher, lastOpenedCollections) => {