/** * 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 ( <> {props.children} ); }; 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;