fix(quick-pane): polish spotlight lifecycle
This commit is contained in:
@@ -77,30 +77,39 @@ export default function QuickPane() {
|
||||
const [extension, setExtension] = useState<Extension>();
|
||||
const runtimeRef = useRef<Runtime | undefined>(undefined);
|
||||
const requestRef = useRef(request);
|
||||
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||
const phaseRef = useRef<"idle" | "starting" | "running">("idle");
|
||||
const invalid = useMemo(() => settingsError(settings), [settings]);
|
||||
|
||||
const dismissPane = () => getCurrentWindow().hide();
|
||||
const focusInput = () => inputRef.current?.focus();
|
||||
|
||||
useEffect(() => {
|
||||
let active = true;
|
||||
invoke<UiState>("load_ui_state")
|
||||
.then((state) => {
|
||||
void (async () => {
|
||||
let nextSettings: QuickPaneSettings;
|
||||
try {
|
||||
const state = await invoke<UiState>("load_ui_state");
|
||||
if (!active) return;
|
||||
const nextSettings = { ...defaults, ...state.quickPane };
|
||||
setSettings(nextSettings);
|
||||
setSettingsLoaded(true);
|
||||
setSelectedModel(`${nextSettings.provider}/${nextSettings.model}`);
|
||||
setStatus("");
|
||||
return invoke<{ models?: Model[] }>("get_model_catalog");
|
||||
})
|
||||
.then((catalog) => {
|
||||
nextSettings = { ...defaults, ...state.quickPane };
|
||||
} catch (reason) {
|
||||
if (active)
|
||||
setError(`Could not load settings: ${String(reason)}`);
|
||||
return;
|
||||
}
|
||||
|
||||
setSettings(nextSettings);
|
||||
setSettingsLoaded(true);
|
||||
setSelectedModel(`${nextSettings.provider}/${nextSettings.model}`);
|
||||
setStatus("");
|
||||
try {
|
||||
const catalog = await invoke<{ models?: Model[] }>("get_model_catalog");
|
||||
if (active) setModels(catalog?.models ?? []);
|
||||
})
|
||||
.catch(
|
||||
(reason) =>
|
||||
active && setError(`Could not load settings: ${String(reason)}`),
|
||||
);
|
||||
} catch (reason) {
|
||||
if (active)
|
||||
setError(`Could not load model catalog: ${String(reason)}`);
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
active = false;
|
||||
const current = runtimeRef.current;
|
||||
@@ -111,6 +120,10 @@ export default function QuickPane() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (settingsLoaded) focusInput();
|
||||
}, [settingsLoaded]);
|
||||
|
||||
useEffect(() => {
|
||||
const paneWindow = getCurrentWindow();
|
||||
const settingsListener = listen<QuickPaneSettings>(
|
||||
@@ -126,12 +139,11 @@ export default function QuickPane() {
|
||||
};
|
||||
window.addEventListener("keydown", onKeyDown);
|
||||
const focusListener = paneWindow.onFocusChanged((event) => {
|
||||
if (
|
||||
!event.payload &&
|
||||
phaseRef.current === "idle" &&
|
||||
!requestRef.current.trim()
|
||||
)
|
||||
if (event.payload) {
|
||||
focusInput();
|
||||
} else if (phaseRef.current === "idle" && !requestRef.current.trim()) {
|
||||
void dismissPane();
|
||||
}
|
||||
});
|
||||
const closeListener = paneWindow.onCloseRequested((event) => {
|
||||
event.preventDefault();
|
||||
@@ -299,11 +311,22 @@ export default function QuickPane() {
|
||||
</header>
|
||||
<textarea
|
||||
autoFocus
|
||||
ref={inputRef}
|
||||
value={request}
|
||||
onChange={(e) => {
|
||||
requestRef.current = e.target.value;
|
||||
setRequest(e.target.value);
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (
|
||||
event.key === "Enter" &&
|
||||
!event.shiftKey &&
|
||||
!event.nativeEvent.isComposing
|
||||
) {
|
||||
event.preventDefault();
|
||||
void run();
|
||||
}
|
||||
}}
|
||||
placeholder="Ask a quick question or give a quick instruction"
|
||||
style={{ width: "100%", minHeight: 90, marginTop: 14 }}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user