2025-07-19 13:54:39 +08:00
|
|
|
import { useCallback, useRef, useMemo, useState, useEffect } from "react";
|
2025-05-27 16:29:43 +08:00
|
|
|
import { cloneDeep, isEmpty } from "lodash-es";
|
|
|
|
|
|
|
|
|
|
import { useSearchStore } from "@/stores/searchStore";
|
|
|
|
|
import { useExtensionsStore } from "@/stores/extensionsStore";
|
|
|
|
|
import platformAdapter from "@/utils/platformAdapter";
|
|
|
|
|
import { Get } from "@/api/axiosRequest";
|
2025-05-28 12:29:28 +08:00
|
|
|
import type { Assistant } from "@/types/chat";
|
|
|
|
|
import { useAppStore } from "@/stores/appStore";
|
|
|
|
|
|
|
|
|
|
interface AssistantManagerProps {
|
|
|
|
|
isChatMode: boolean;
|
2025-06-11 17:49:05 +08:00
|
|
|
inputValue: string;
|
2025-05-28 12:29:28 +08:00
|
|
|
handleSubmit: () => void;
|
|
|
|
|
changeInput: (value: string) => void;
|
|
|
|
|
}
|
2025-05-27 16:29:43 +08:00
|
|
|
|
|
|
|
|
export function useAssistantManager({
|
|
|
|
|
isChatMode,
|
2025-06-11 17:49:05 +08:00
|
|
|
inputValue,
|
2025-05-27 16:29:43 +08:00
|
|
|
handleSubmit,
|
|
|
|
|
changeInput,
|
2025-05-28 12:29:28 +08:00
|
|
|
}: AssistantManagerProps) {
|
|
|
|
|
const isTauri = useAppStore((state) => state.isTauri);
|
|
|
|
|
|
2025-06-26 18:40:33 +08:00
|
|
|
const {
|
|
|
|
|
goAskAi,
|
|
|
|
|
setGoAskAi,
|
|
|
|
|
setAskAiMessage,
|
|
|
|
|
selectedAssistant,
|
|
|
|
|
selectedSearchContent,
|
|
|
|
|
visibleExtensionStore,
|
|
|
|
|
setVisibleExtensionStore,
|
|
|
|
|
setSearchValue,
|
|
|
|
|
visibleExtensionDetail,
|
2025-06-27 19:17:27 +08:00
|
|
|
setVisibleExtensionDetail,
|
|
|
|
|
sourceData,
|
|
|
|
|
setSourceData,
|
2025-06-26 18:40:33 +08:00
|
|
|
} = useSearchStore();
|
2025-05-28 12:29:28 +08:00
|
|
|
|
2025-06-17 15:38:39 +08:00
|
|
|
const { quickAiAccessAssistant, disabledExtensions } = useExtensionsStore();
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-05-28 12:29:28 +08:00
|
|
|
const askAIRef = useRef<Assistant | null>(null);
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-05-28 12:29:28 +08:00
|
|
|
const askAI = useMemo(() => {
|
2025-07-19 13:54:39 +08:00
|
|
|
return selectedAssistant ?? quickAiAccessAssistant;
|
2025-05-27 16:29:43 +08:00
|
|
|
}, [quickAiAccessAssistant, selectedAssistant]);
|
|
|
|
|
|
|
|
|
|
const [assistantDetail, setAssistantDetail] = useState<any>({});
|
|
|
|
|
|
2025-07-19 13:54:39 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (goAskAi) return;
|
|
|
|
|
|
|
|
|
|
askAIRef.current = null;
|
|
|
|
|
}, [goAskAi]);
|
|
|
|
|
|
2025-05-27 16:29:43 +08:00
|
|
|
const assistant_get = useCallback(async () => {
|
2025-05-30 17:18:52 +08:00
|
|
|
if (!askAI?.id) return;
|
2025-06-17 15:38:39 +08:00
|
|
|
if (disabledExtensions.includes("QuickAIAccess")) return;
|
|
|
|
|
|
2025-05-27 16:29:43 +08:00
|
|
|
if (isTauri) {
|
2025-05-30 17:18:52 +08:00
|
|
|
if (!askAI?.querySource?.id) return;
|
2025-05-27 16:29:43 +08:00
|
|
|
const res = await platformAdapter.commands("assistant_get", {
|
2025-05-28 12:29:28 +08:00
|
|
|
serverId: askAI?.querySource?.id,
|
|
|
|
|
assistantId: askAI?.id,
|
2025-05-27 16:29:43 +08:00
|
|
|
});
|
2025-05-28 12:29:28 +08:00
|
|
|
setAssistantDetail(res);
|
2025-05-27 16:29:43 +08:00
|
|
|
} else {
|
2025-05-30 17:18:52 +08:00
|
|
|
const [error, res]: any = await Get(`/assistant/${askAI?.id}`);
|
2025-05-27 16:29:43 +08:00
|
|
|
if (error) {
|
|
|
|
|
console.error("assistant", error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-05-28 12:29:28 +08:00
|
|
|
setAssistantDetail(res);
|
2025-05-27 16:29:43 +08:00
|
|
|
}
|
2025-06-17 15:38:39 +08:00
|
|
|
}, [askAI?.id, askAI?.querySource?.id, disabledExtensions]);
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-06-17 15:38:39 +08:00
|
|
|
const handleAskAi = useCallback(() => {
|
2025-05-30 17:18:52 +08:00
|
|
|
if (!isTauri) return;
|
2025-06-09 18:10:56 +08:00
|
|
|
|
2025-06-17 15:38:39 +08:00
|
|
|
if (disabledExtensions.includes("QuickAIAccess")) return;
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-07-19 13:54:39 +08:00
|
|
|
askAIRef.current ??= cloneDeep(askAI);
|
|
|
|
|
|
2025-05-28 12:29:28 +08:00
|
|
|
if (!askAIRef.current) return;
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-06-13 14:19:27 +08:00
|
|
|
let value = inputValue.trim();
|
|
|
|
|
if (isEmpty(value)) return;
|
|
|
|
|
|
|
|
|
|
if (!goAskAi && selectedAssistant) {
|
|
|
|
|
value = "";
|
|
|
|
|
}
|
2025-05-27 16:29:43 +08:00
|
|
|
|
|
|
|
|
changeInput("");
|
2025-06-13 14:19:27 +08:00
|
|
|
setAskAiMessage(value);
|
2025-05-29 16:01:52 +08:00
|
|
|
setGoAskAi(true);
|
2025-06-17 15:38:39 +08:00
|
|
|
}, [disabledExtensions, askAI, inputValue, goAskAi, selectedAssistant]);
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-06-26 18:40:33 +08:00
|
|
|
const handleKeyDownAutoResizeTextarea = useCallback(
|
|
|
|
|
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
|
|
|
const { key, shiftKey, currentTarget } = e;
|
|
|
|
|
const { value } = currentTarget;
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-06-26 18:40:33 +08:00
|
|
|
if (key === "Backspace" && value === "") {
|
2025-06-27 19:17:27 +08:00
|
|
|
if (goAskAi) {
|
|
|
|
|
return setGoAskAi(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (visibleExtensionDetail) {
|
|
|
|
|
return setVisibleExtensionDetail(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (visibleExtensionStore) {
|
|
|
|
|
return setVisibleExtensionStore(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sourceData) {
|
|
|
|
|
return setSourceData(void 0);
|
|
|
|
|
}
|
2025-06-26 18:40:33 +08:00
|
|
|
}
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-06-26 18:40:33 +08:00
|
|
|
if (key === "Tab" && !isChatMode && isTauri) {
|
|
|
|
|
e.preventDefault();
|
2025-06-13 14:19:27 +08:00
|
|
|
|
2025-06-26 18:40:33 +08:00
|
|
|
if (visibleExtensionStore) return;
|
2025-05-27 16:29:43 +08:00
|
|
|
|
2025-06-27 10:22:51 +08:00
|
|
|
if (selectedSearchContent?.id === "Extension Store") {
|
2025-06-26 18:40:33 +08:00
|
|
|
changeInput("");
|
|
|
|
|
setSearchValue("");
|
|
|
|
|
return setVisibleExtensionStore(true);
|
|
|
|
|
}
|
2025-06-11 17:49:05 +08:00
|
|
|
|
2025-06-26 18:40:33 +08:00
|
|
|
assistant_get();
|
|
|
|
|
return handleAskAi();
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-22 10:13:08 +08:00
|
|
|
if (key === "Enter" && !shiftKey) {
|
2025-06-26 18:40:33 +08:00
|
|
|
e.preventDefault();
|
|
|
|
|
|
2025-07-22 10:13:08 +08:00
|
|
|
if (isTauri && !isChatMode && goAskAi) {
|
2025-07-27 11:52:40 +08:00
|
|
|
if (!isEmpty(value)) {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-22 10:13:08 +08:00
|
|
|
return handleAskAi();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleSubmit();
|
2025-06-26 18:40:33 +08:00
|
|
|
}
|
2025-10-11 15:38:15 +08:00
|
|
|
|
|
|
|
|
if (key === "Home") {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
return currentTarget.setSelectionRange(0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (key === "End") {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
const length = currentTarget.value.length;
|
|
|
|
|
return currentTarget.setSelectionRange(length, length);
|
|
|
|
|
}
|
2025-06-26 18:40:33 +08:00
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
isChatMode,
|
|
|
|
|
goAskAi,
|
|
|
|
|
assistant_get,
|
|
|
|
|
handleAskAi,
|
|
|
|
|
handleSubmit,
|
|
|
|
|
selectedSearchContent,
|
2025-06-27 19:17:27 +08:00
|
|
|
visibleExtensionStore,
|
|
|
|
|
visibleExtensionDetail,
|
|
|
|
|
sourceData,
|
2025-06-26 18:40:33 +08:00
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
|
2025-05-28 12:29:28 +08:00
|
|
|
return {
|
|
|
|
|
askAI,
|
|
|
|
|
askAIRef,
|
|
|
|
|
assistantDetail,
|
|
|
|
|
handleKeyDownAutoResizeTextarea,
|
|
|
|
|
};
|
2025-05-27 16:29:43 +08:00
|
|
|
}
|