File size: 2,048 Bytes
5710dd0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import { useState, useCallback } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { bridge } from "@/services";
interface UseInputHistoryOptions {
text: string;
setText: (text: string) => void;
onHeightChange?: () => void;
}
const INPUT_HISTORY_KEY = ["inputHistory"] as const;
const NO_HISTORY: string[] = [];
export function useInputHistory({ text, setText, onHeightChange }: UseInputHistoryOptions) {
const queryClient = useQueryClient();
const { data: history = NO_HISTORY } = useQuery({
queryKey: INPUT_HISTORY_KEY,
queryFn: () => bridge.getInputHistory(),
});
const [index, setIndex] = useState(-1);
const add = useCallback((input: string) => {
const trimmed = input.trim();
if (!trimmed) {
return;
}
void bridge.addInputHistory(trimmed);
queryClient.setQueryData<string[]>(INPUT_HISTORY_KEY, (prev) => (prev?.[prev.length - 1] === trimmed ? prev : [...(prev ?? []), trimmed]));
setIndex(-1);
}, [queryClient]);
const handleKey = useCallback(
(e: React.KeyboardEvent): boolean => {
// Ignore if any modifier key is pressed
if (e.ctrlKey || e.metaKey || e.altKey) {
return false;
}
if (e.key === "ArrowUp" && history.length > 0 && (!text || index >= 0)) {
const newIndex = Math.min(index + 1, history.length - 1);
if (newIndex !== index) {
e.preventDefault();
setIndex(newIndex);
setText(history[history.length - 1 - newIndex]);
onHeightChange?.();
return true;
}
}
if (e.key === "ArrowDown" && index >= 0) {
e.preventDefault();
const newIndex = index - 1;
setIndex(newIndex);
setText(newIndex === -1 ? "" : history[history.length - 1 - newIndex]);
onHeightChange?.();
return true;
}
return false;
},
[history, index, text, setText, onHeightChange],
);
const reset = useCallback(() => setIndex(-1), []);
return { handleKey, add, reset };
}
|