2025-10-02 00:03:41 +08:00
|
|
|
|
import type { MessageAnalysisMode } from '@buster/server-shared/chats';
|
2025-09-30 03:52:00 +08:00
|
|
|
|
import type { ListShortcutsResponse } from '@buster/server-shared/shortcuts';
|
|
|
|
|
import type { GetSuggestedPromptsResponse } from '@buster/server-shared/user';
|
2025-09-30 10:24:58 +08:00
|
|
|
|
import React, { useMemo, useRef, useState } from 'react';
|
|
|
|
|
import {
|
|
|
|
|
useCreateShortcutsMentionsSuggestions,
|
|
|
|
|
useShortcutsSuggestions,
|
|
|
|
|
} from '@/components/features/input/Mentions/ShortcutsSuggestions/ShortcutsSuggestions';
|
2025-09-30 10:39:22 +08:00
|
|
|
|
import type {
|
|
|
|
|
MentionArrayItem,
|
|
|
|
|
MentionSuggestionExtension,
|
|
|
|
|
} from '@/components/ui/inputs/MentionInput';
|
2025-09-30 05:37:50 +08:00
|
|
|
|
import type {
|
|
|
|
|
MentionInputSuggestionsProps,
|
|
|
|
|
MentionInputSuggestionsRef,
|
|
|
|
|
} from '@/components/ui/inputs/MentionInputSuggestions';
|
2025-09-30 03:52:00 +08:00
|
|
|
|
import { MentionInputSuggestions } from '@/components/ui/inputs/MentionInputSuggestions';
|
2025-10-01 00:25:03 +08:00
|
|
|
|
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
2025-09-30 11:41:32 +08:00
|
|
|
|
import { useMount } from '@/hooks/useMount';
|
2025-09-30 08:59:49 +08:00
|
|
|
|
import { NewShortcutModal } from '../../modals/NewShortcutModal';
|
2025-10-02 00:03:41 +08:00
|
|
|
|
import { BusterChatInputButtons } from './BusterChatInputButtons';
|
2025-10-01 12:13:06 +08:00
|
|
|
|
import { useUniqueSuggestions } from './useUniqueSuggestions';
|
2025-09-30 03:52:00 +08:00
|
|
|
|
|
2025-09-30 11:41:32 +08:00
|
|
|
|
export type BusterChatInputProps = {
|
2025-09-30 03:52:00 +08:00
|
|
|
|
defaultValue: string;
|
2025-09-30 10:39:22 +08:00
|
|
|
|
onSubmit: (d: {
|
|
|
|
|
transformedValue: string;
|
|
|
|
|
arrayValue: MentionArrayItem[];
|
|
|
|
|
editorText: string;
|
2025-10-02 00:03:41 +08:00
|
|
|
|
mode: MessageAnalysisMode;
|
2025-09-30 10:39:22 +08:00
|
|
|
|
}) => void;
|
2025-09-30 03:52:00 +08:00
|
|
|
|
onStop: () => void;
|
|
|
|
|
submitting: boolean;
|
|
|
|
|
disabled: boolean;
|
|
|
|
|
shortcuts: ListShortcutsResponse['shortcuts'];
|
|
|
|
|
suggestedPrompts: GetSuggestedPromptsResponse['suggestedPrompts'];
|
2025-09-30 11:41:32 +08:00
|
|
|
|
autoSubmit?: boolean;
|
2025-09-30 03:52:00 +08:00
|
|
|
|
};
|
|
|
|
|
|
2025-09-30 11:41:32 +08:00
|
|
|
|
export const BusterChatInputBase: React.FC<BusterChatInputProps> = React.memo(
|
|
|
|
|
({
|
|
|
|
|
defaultValue,
|
|
|
|
|
onSubmit,
|
|
|
|
|
onStop,
|
|
|
|
|
autoSubmit,
|
|
|
|
|
submitting,
|
|
|
|
|
disabled,
|
|
|
|
|
shortcuts,
|
|
|
|
|
suggestedPrompts,
|
|
|
|
|
}) => {
|
2025-09-30 05:37:50 +08:00
|
|
|
|
const mentionInputSuggestionsRef = useRef<MentionInputSuggestionsRef>(null);
|
2025-09-30 03:52:00 +08:00
|
|
|
|
const uniqueSuggestions = useUniqueSuggestions(suggestedPrompts);
|
2025-09-30 08:38:20 +08:00
|
|
|
|
const [openCreateShortcutModal, setOpenCreateShortcutModal] = useState(false);
|
2025-10-02 00:03:41 +08:00
|
|
|
|
const [mode, setMode] = useState<MessageAnalysisMode>('auto');
|
2025-09-30 09:58:03 +08:00
|
|
|
|
|
2025-09-30 10:24:58 +08:00
|
|
|
|
const shortcutsSuggestions = useShortcutsSuggestions(
|
2025-09-30 09:15:32 +08:00
|
|
|
|
shortcuts,
|
|
|
|
|
setOpenCreateShortcutModal,
|
2025-09-30 09:58:03 +08:00
|
|
|
|
mentionInputSuggestionsRef
|
2025-09-30 09:15:32 +08:00
|
|
|
|
);
|
2025-09-30 05:37:50 +08:00
|
|
|
|
|
2025-09-30 03:52:00 +08:00
|
|
|
|
const suggestionItems: MentionInputSuggestionsProps['suggestionItems'] = useMemo(() => {
|
|
|
|
|
const items: MentionInputSuggestionsProps['suggestionItems'] = [...uniqueSuggestions];
|
|
|
|
|
|
|
|
|
|
if (items.length > 0 && shortcutsSuggestions.length > 0) {
|
|
|
|
|
items.push({
|
|
|
|
|
type: 'separator',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shortcutsSuggestions.length > 0) {
|
|
|
|
|
items.push(...shortcutsSuggestions);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items;
|
|
|
|
|
}, [uniqueSuggestions, shortcutsSuggestions]);
|
|
|
|
|
|
2025-09-30 08:38:20 +08:00
|
|
|
|
const shortcutsMentionsSuggestions = useCreateShortcutsMentionsSuggestions(
|
|
|
|
|
shortcuts,
|
|
|
|
|
setOpenCreateShortcutModal
|
|
|
|
|
);
|
|
|
|
|
|
2025-09-30 03:52:00 +08:00
|
|
|
|
const mentions: MentionSuggestionExtension[] = useMemo(() => {
|
2025-09-30 08:38:20 +08:00
|
|
|
|
return [shortcutsMentionsSuggestions];
|
|
|
|
|
}, [shortcutsMentionsSuggestions]);
|
2025-09-30 03:52:00 +08:00
|
|
|
|
|
2025-09-30 10:39:22 +08:00
|
|
|
|
const onSubmitPreflight = (valueProp?: ReturnType<MentionInputSuggestionsRef['getValue']>) => {
|
2025-09-30 03:52:00 +08:00
|
|
|
|
if (submitting) {
|
|
|
|
|
console.warn('Input is submitting');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-09-30 10:39:22 +08:00
|
|
|
|
|
|
|
|
|
const value = valueProp || mentionInputSuggestionsRef.current?.getValue?.();
|
|
|
|
|
if (!value) {
|
|
|
|
|
console.warn('Value is not defined');
|
2025-09-30 03:52:00 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-30 10:39:22 +08:00
|
|
|
|
if (disabled || !value) {
|
|
|
|
|
console.warn('Input is disabled or value is not defined');
|
|
|
|
|
return;
|
2025-09-30 03:52:00 +08:00
|
|
|
|
}
|
2025-10-02 00:58:34 +08:00
|
|
|
|
|
2025-09-30 10:39:22 +08:00
|
|
|
|
onSubmit({ ...value, mode });
|
|
|
|
|
};
|
2025-09-30 03:52:00 +08:00
|
|
|
|
|
2025-10-02 03:52:19 +08:00
|
|
|
|
const onSuggestionItemClick = useMemoizedFn(() => {
|
|
|
|
|
onSubmitPreflight();
|
|
|
|
|
});
|
|
|
|
|
|
2025-10-01 00:25:03 +08:00
|
|
|
|
const onCloseCreateShortcutModal = useMemoizedFn(() => {
|
|
|
|
|
setOpenCreateShortcutModal(false);
|
|
|
|
|
});
|
|
|
|
|
|
2025-09-30 11:41:32 +08:00
|
|
|
|
useMount(() => {
|
|
|
|
|
if (autoSubmit && defaultValue) {
|
|
|
|
|
onSubmitPreflight({
|
|
|
|
|
transformedValue: defaultValue,
|
|
|
|
|
arrayValue: [],
|
|
|
|
|
editorText: defaultValue,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-09-30 03:52:00 +08:00
|
|
|
|
return (
|
2025-09-30 08:59:49 +08:00
|
|
|
|
<React.Fragment>
|
|
|
|
|
<MentionInputSuggestions
|
|
|
|
|
defaultValue={defaultValue}
|
2025-09-30 10:39:22 +08:00
|
|
|
|
onPressEnter={onSubmitPreflight}
|
2025-10-02 03:52:19 +08:00
|
|
|
|
onSuggestionItemClick={onSuggestionItemClick}
|
2025-09-30 08:59:49 +08:00
|
|
|
|
mentions={mentions}
|
|
|
|
|
suggestionItems={suggestionItems}
|
2025-10-02 02:01:27 +08:00
|
|
|
|
disabled={disabled}
|
2025-09-30 08:59:49 +08:00
|
|
|
|
placeholder="Ask a question or type ‘/’ for shortcuts..."
|
|
|
|
|
ref={mentionInputSuggestionsRef}
|
2025-09-30 11:58:59 +08:00
|
|
|
|
inputContainerClassName="px-5 pt-4"
|
2025-10-01 06:17:16 +08:00
|
|
|
|
inputClassName="text-md"
|
2025-10-01 06:21:56 +08:00
|
|
|
|
behavior="open-on-focus"
|
2025-09-30 08:59:49 +08:00
|
|
|
|
>
|
|
|
|
|
<BusterChatInputButtons
|
2025-09-30 09:58:03 +08:00
|
|
|
|
onSubmit={onSubmitPreflight}
|
2025-09-30 08:59:49 +08:00
|
|
|
|
onStop={onStop}
|
|
|
|
|
submitting={submitting}
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
mode={mode}
|
|
|
|
|
onModeChange={setMode}
|
|
|
|
|
/>
|
|
|
|
|
</MentionInputSuggestions>
|
|
|
|
|
|
2025-10-01 00:25:03 +08:00
|
|
|
|
<NewShortcutModal open={openCreateShortcutModal} onClose={onCloseCreateShortcutModal} />
|
2025-09-30 08:59:49 +08:00
|
|
|
|
</React.Fragment>
|
2025-09-30 03:52:00 +08:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
BusterChatInputBase.displayName = 'BusterChatInputBase';
|