From c27c750c3e00b5bf6860d2d6d0013410dbb4c59d Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Sat, 19 Aug 2023 00:36:37 +0530 Subject: [PATCH] feat: preferences local storage and electron sync --- .../components/Preferences/General/index.js | 37 ++++++++- packages/bruno-app/src/pages/_app.js | 9 ++- .../src/providers/Preferences/index.js | 80 +++++++++++++++++++ .../bruno-electron/src/app/preferences.js | 22 +++++ packages/bruno-electron/src/ipc/collection.js | 5 ++ 5 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 packages/bruno-app/src/providers/Preferences/index.js create mode 100644 packages/bruno-electron/src/app/preferences.js diff --git a/packages/bruno-app/src/components/Preferences/General/index.js b/packages/bruno-app/src/components/Preferences/General/index.js index e5e51080..b6d068f1 100644 --- a/packages/bruno-app/src/components/Preferences/General/index.js +++ b/packages/bruno-app/src/components/Preferences/General/index.js @@ -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 (
- + SSL Certificate Verification
diff --git a/packages/bruno-app/src/pages/_app.js b/packages/bruno-app/src/pages/_app.js index 79cd4523..14daefdc 100644 --- a/packages/bruno-app/src/pages/_app.js +++ b/packages/bruno-app/src/pages/_app.js @@ -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 }) { - - - + + + + + diff --git a/packages/bruno-app/src/providers/Preferences/index.js b/packages/bruno-app/src/providers/Preferences/index.js new file mode 100644 index 00000000..2ebd5227 --- /dev/null +++ b/packages/bruno-app/src/providers/Preferences/index.js @@ -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 ( + + <> + {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; diff --git a/packages/bruno-electron/src/app/preferences.js b/packages/bruno-electron/src/app/preferences.js new file mode 100644 index 00000000..9240bd78 --- /dev/null +++ b/packages/bruno-electron/src/app/preferences.js @@ -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 +}; diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js index b82e56f2..d5b2f5fe 100644 --- a/packages/bruno-electron/src/ipc/collection.js +++ b/packages/bruno-electron/src/ipc/collection.js @@ -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) => {