From ee85aacd088c42261e5adf6995a3c5bb59bf797b Mon Sep 17 00:00:00 2001 From: printfn Date: Fri, 6 Dec 2024 06:02:54 +0000 Subject: [PATCH] Extract useHistory hook --- web/src/App.tsx | 15 ++++----------- web/src/hooks/useHistory.ts | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 web/src/hooks/useHistory.ts diff --git a/web/src/App.tsx b/web/src/App.tsx index 542b55fa..6de9c0b0 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,6 +1,7 @@ import { type FormEvent, type KeyboardEvent, type ReactNode, useCallback, useEffect, useRef, useState } from 'react'; import { ThreeDotsScale } from 'react-svg-spinners'; import { fend } from './lib/fend'; +import { useHistory } from './hooks/useHistory'; const examples = ` > 5'10" to cm @@ -40,16 +41,10 @@ function NewTabLink({ children, href }: { children: ReactNode; href: string }) { ); } -const initialHistory = JSON.parse(localStorage.getItem('fend_history') || '[]') as string[]; - export default function App({ widget = false }: { widget?: boolean }) { const [currentInput, setCurrentInput] = useState(''); const [output, setOutput] = useState(widget ? <> : exampleContent); - const [history, setHistory] = useState(initialHistory); - useEffect(() => { - const history100 = history.slice(-100); - localStorage.setItem('fend_history', JSON.stringify(history100)); - }, [history]); + const { history, addToHistory } = useHistory(); const [variables, setVariables] = useState(''); const [navigation, setNavigation] = useState(0); const [hint, setHint] = useState(''); @@ -93,9 +88,7 @@ export default function App({ widget = false }: { widget?: boolean }) { return; } const request =

{`> ${currentInput}`}

; - if (currentInput.trim().length > 0) { - setHistory(h => [...h, currentInput]); - } + addToHistory(currentInput); setNavigation(0); setPending(p => p + 1); const fendResult = await fend(currentInput, 1000000000, variables); @@ -119,7 +112,7 @@ export default function App({ widget = false }: { widget?: boolean }) { inputHint.current?.scrollIntoView(); })(); }, - [currentInput, variables], + [currentInput, addToHistory, variables], ); const navigate = useCallback( (event: KeyboardEvent) => { diff --git a/web/src/hooks/useHistory.ts b/web/src/hooks/useHistory.ts new file mode 100644 index 00000000..fc0ecafd --- /dev/null +++ b/web/src/hooks/useHistory.ts @@ -0,0 +1,20 @@ +import { useCallback, useState } from 'react'; + +const initialHistory = JSON.parse(localStorage.getItem('fend_history') || '[]') as string[]; + +export function useHistory() { + const [history, setHistory] = useState(initialHistory); + + const addToHistory = useCallback((newEntry: string) => { + if (newEntry.startsWith(' ')) return; + if (newEntry.trim().length === 0) return; + setHistory(prevHistory => { + const updatedHistory = [...prevHistory, newEntry] + .filter((entry, idx, array) => idx === 0 || entry !== array[idx - 1]); + localStorage.setItem('fend_history', JSON.stringify(updatedHistory.slice(-100))); + return updatedHistory; + }); + }, []); + + return { history, addToHistory }; +}