Skip to content

Commit

Permalink
Further react cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
printfn committed Dec 6, 2024
1 parent 22b2ddc commit cf84ed2
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 36 deletions.
16 changes: 6 additions & 10 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { type KeyboardEvent, type ReactNode, useCallback, useEffect, useRef, useState, useTransition } from 'react';
import { fend } from './lib/fend';
import { useCurrentInput } from './hooks/useCurrentInput';
import NewTabLink from './components/NewTabLink';
import PendingOutput from './components/PendingOutput';
import { useFend } from './hooks/useFend';

const examples = `
> 5'10" to cm
Expand Down Expand Up @@ -36,8 +36,8 @@ const exampleContent = (

export default function App({ widget = false }: { widget?: boolean }) {
const [output, setOutput] = useState<ReactNode>(widget ? <></> : exampleContent);
const { currentInput, submit, onInput, upArrow, downArrow } = useCurrentInput();
const [variables, setVariables] = useState('');
const { evaluate, evaluateHint } = useFend();
const { currentInput, submit, onInput, upArrow, downArrow, hint } = useCurrentInput(evaluateHint);
const inputText = useRef<HTMLTextAreaElement>(null);
const pendingOutput = useRef<HTMLParagraphElement>(null);
const focus = useCallback(() => {
Expand Down Expand Up @@ -86,16 +86,12 @@ export default function App({ widget = false }: { widget?: boolean }) {
startTransition(async () => {
const request = <p>{`> ${currentInput}`}</p>;
submit();
const fendResult = await fend(currentInput, 1000000000, variables);
const fendResult = await evaluate(currentInput);
if (!fendResult.ok && fendResult.message === 'cancelled') {
return;
}
onInput('');
console.log(fendResult);
const result = <p>{fendResult.ok ? fendResult.result : fendResult.message}</p>;
if (fendResult.ok && fendResult.variables.length > 0) {
setVariables(fendResult.variables);
}
setOutput(o => (
<>
{o}
Expand All @@ -106,7 +102,7 @@ export default function App({ widget = false }: { widget?: boolean }) {
pendingOutput.current?.scrollIntoView({ behavior: 'smooth' });
});
},
[currentInput, submit, variables, onInput, downArrow, upArrow],
[currentInput, submit, onInput, downArrow, upArrow, evaluate],
);
useEffect(() => {
document.addEventListener('click', focus);
Expand Down Expand Up @@ -139,7 +135,7 @@ export default function App({ widget = false }: { widget?: boolean }) {
autoFocus
/>
</div>
<PendingOutput ref={pendingOutput} currentInput={currentInput} variables={variables} isPending={isPending} />
<PendingOutput ref={pendingOutput} hint={hint} isPending={isPending} />
</div>
</main>
);
Expand Down
20 changes: 3 additions & 17 deletions web/src/components/PendingOutput.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
import { startTransition, useEffect, useState, type Ref } from 'react';
import type { Ref } from 'react';
import { ThreeDotsScale } from 'react-svg-spinners';
import { fend } from '../lib/fend';

type Props = {
ref: Ref<HTMLParagraphElement>;
currentInput: string;
variables: string;
hint: string;
isPending: boolean;
};

export default function PendingOutput({ ref, currentInput, variables, isPending }: Props) {
const [hint, setHint] = useState('');
useEffect(() => {
startTransition(async () => {
const result = await fend(currentInput, 100, variables);
if (!result.ok) {
setHint('');
} else {
setHint(result.result);
}
});
}, [currentInput, variables]);

export default function PendingOutput({ ref, hint, isPending }: Props) {
return (
<p id="pending-output" ref={ref}>
{hint || (isPending ? <ThreeDotsScale /> : <>&nbsp;</>)}
Expand Down
32 changes: 23 additions & 9 deletions web/src/hooks/useCurrentInput.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { FormEvent, useCallback, useState } from 'react';
import { FormEvent, startTransition, useCallback, useState } from 'react';
import { useHistory } from './useHistory';

export function useCurrentInput() {
export function useCurrentInput(evaluateHint: (input: string) => Promise<string>) {
const { history, addToHistory } = useHistory();
const [currentInput, setCurrentInput] = useState('');
const [currentInput, setCurrentInputInternal] = useState('');
const [navigation, setNavigation] = useState(0);
const [hint, setHint] = useState('');

const setCurrentInput = useCallback(
(value: string) => {
setCurrentInputInternal(value);
startTransition(async () => {
setHint(await evaluateHint(value));
});
},
[evaluateHint],
);

const navigate = useCallback(
(direction: 'up' | 'down') => {
Expand All @@ -27,13 +38,16 @@ export function useCurrentInput() {
return newValue;
});
},
[history],
[history, setCurrentInput],
);

const onInput = useCallback((e: string | FormEvent<HTMLTextAreaElement>) => {
setNavigation(0);
setCurrentInput(typeof e === 'string' ? e : e.currentTarget.value);
}, []);
const onInput = useCallback(
(e: string | FormEvent<HTMLTextAreaElement>) => {
setNavigation(0);
setCurrentInput(typeof e === 'string' ? e : e.currentTarget.value);
},
[setCurrentInput],
);

const upArrow = useCallback(() => {
if (currentInput.trim().length !== 0 && navigation === 0) {
Expand All @@ -52,5 +66,5 @@ export function useCurrentInput() {
setNavigation(0);
}, [currentInput, addToHistory]);

return { currentInput, submit, onInput, downArrow, upArrow };
return { currentInput, submit, onInput, downArrow, upArrow, hint };
}
32 changes: 32 additions & 0 deletions web/src/hooks/useFend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useCallback, useState } from 'react';
import { fend } from '../lib/fend';

export function useFend() {
const [variables, setVariables] = useState('');

const evaluate = useCallback(
async (input: string) => {
const result = await fend(input, 1000000000, variables);
console.log(result);
if (result.ok && result.variables.length > 0) {
setVariables(result.variables);
}
return result;
},
[variables],
);

const evaluateHint = useCallback(
async (input: string) => {
const result = await fend(input, 100, variables);
if (!result.ok) {
return '';
} else {
return result.result;
}
},
[variables],
);

return { evaluate, evaluateHint };
}

0 comments on commit cf84ed2

Please sign in to comment.