diff --git a/src/App.jsx b/src/App.jsx index eb3237f..5024680 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -33,6 +33,7 @@ import { TasksSettingsProvider } from './contexts/TasksSettingsContext'; import { WebSocketProvider, useWebSocketContext } from './contexts/WebSocketContext'; import ProtectedRoute from './components/ProtectedRoute'; import { useVersionCheck } from './hooks/useVersionCheck'; +import useLocalStorage from './hooks/useLocalStorage'; import { api, authenticatedFetch } from './utils/api'; @@ -54,22 +55,10 @@ function AppContent() { const [isInputFocused, setIsInputFocused] = useState(false); const [showSettings, setShowSettings] = useState(false); const [showQuickSettings, setShowQuickSettings] = useState(false); - const [autoExpandTools, setAutoExpandTools] = useState(() => { - const saved = localStorage.getItem('autoExpandTools'); - return saved !== null ? JSON.parse(saved) : false; - }); - const [showRawParameters, setShowRawParameters] = useState(() => { - const saved = localStorage.getItem('showRawParameters'); - return saved !== null ? JSON.parse(saved) : false; - }); - const [autoScrollToBottom, setAutoScrollToBottom] = useState(() => { - const saved = localStorage.getItem('autoScrollToBottom'); - return saved !== null ? JSON.parse(saved) : true; - }); - const [sendByCtrlEnter, setSendByCtrlEnter] = useState(() => { - const saved = localStorage.getItem('sendByCtrlEnter'); - return saved !== null ? JSON.parse(saved) : false; - }); + const [autoExpandTools, setAutoExpandTools] = useLocalStorage('autoExpandTools', false); + const [showRawParameters, setShowRawParameters] = useLocalStorage('showRawParameters', false); + const [autoScrollToBottom, setAutoScrollToBottom] = useLocalStorage('autoScrollToBottom', true); + const [sendByCtrlEnter, setSendByCtrlEnter] = useLocalStorage('sendByCtrlEnter', false); // Session Protection System: Track sessions with active conversations to prevent // automatic project updates from interrupting ongoing chats. When a user sends // a message, the session is marked as "active" and project updates are paused @@ -491,9 +480,10 @@ function AppContent() { return (
{/* Backdrop */} -
setShowVersionModal(false)} + aria-label="Close version upgrade modal" /> {/* Modal */} @@ -604,7 +594,7 @@ function AppContent() {
-
{ e.stopPropagation(); @@ -615,6 +605,7 @@ function AppContent() { e.stopPropagation(); setSidebarOpen(false); }} + aria-label="Close sidebar" />
{ - setAutoExpandTools(value); - localStorage.setItem('autoExpandTools', JSON.stringify(value)); - }} + onAutoExpandChange={setAutoExpandTools} showRawParameters={showRawParameters} - onShowRawParametersChange={(value) => { - setShowRawParameters(value); - localStorage.setItem('showRawParameters', JSON.stringify(value)); - }} + onShowRawParametersChange={setShowRawParameters} autoScrollToBottom={autoScrollToBottom} - onAutoScrollChange={(value) => { - setAutoScrollToBottom(value); - localStorage.setItem('autoScrollToBottom', JSON.stringify(value)); - }} + onAutoScrollChange={setAutoScrollToBottom} sendByCtrlEnter={sendByCtrlEnter} - onSendByCtrlEnterChange={(value) => { - setSendByCtrlEnter(value); - localStorage.setItem('sendByCtrlEnter', JSON.stringify(value)); - }} + onSendByCtrlEnterChange={setSendByCtrlEnter} isMobile={isMobile} /> )} diff --git a/src/hooks/useLocalStorage.jsx b/src/hooks/useLocalStorage.jsx new file mode 100644 index 0000000..2a42df9 --- /dev/null +++ b/src/hooks/useLocalStorage.jsx @@ -0,0 +1,41 @@ +import { useState } from 'react'; + +/** + * Custom hook to persist state in localStorage. + * + * @param {string} key The key to use for localStorage. + * @param {any} initialValue The initial value to use if nothing is in localStorage. + * @returns {[any, Function]} A tuple containing the stored value and a setter function. + */ +function useLocalStorage(key, initialValue) { + const [storedValue, setStoredValue] = useState(() => { + if (typeof window === 'undefined') { + return initialValue; + } + try { + const item = window.localStorage.getItem(key); + return item ? JSON.parse(item) : initialValue; + } catch (error) { + console.log(error); + return initialValue; + } + }); + + const setValue = (value) => { + if (typeof window === 'undefined') { + return; + } + try { + const valueToStore = + value instanceof Function ? value(storedValue) : value; + window.localStorage.setItem(key, JSON.stringify(valueToStore)); + setStoredValue(valueToStore); + } catch (error) { + console.log(error); + } + }; + + return [storedValue, setValue]; +} + +export default useLocalStorage;