diff --git a/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx b/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx index 03c8b5b19..e7aed6a69 100644 --- a/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx +++ b/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx @@ -2,7 +2,7 @@ import type { ListShortcutsResponse } from '@buster/server-shared/shortcuts'; import type { GetSuggestedPromptsResponse } from '@buster/server-shared/user'; import type { Editor } from '@tiptap/react'; import sampleSize from 'lodash/sampleSize'; -import React, { useMemo, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import { useCreateShortcutsMentionsSuggestions } from '@/components/features/input/Mentions/ShortcutsSuggestions/ShortcutsSuggestions'; import { Plus } from '@/components/ui/icons'; import CircleQuestion from '@/components/ui/icons/NucleoIconOutlined/circle-question'; @@ -35,10 +35,11 @@ export const BusterChatInputBase: React.FC = React.memo( const uniqueSuggestions = useUniqueSuggestions(suggestedPrompts); const [openCreateShortcutModal, setOpenCreateShortcutModal] = useState(false); const [mode, setMode] = useState('auto'); + const shortcutsSuggestions = useShortcuts( shortcuts, setOpenCreateShortcutModal, - mentionInputSuggestionsRef.current?.onChangeValue + mentionInputSuggestionsRef ); const suggestionItems: MentionInputSuggestionsProps['suggestionItems'] = useMemo(() => { @@ -66,10 +67,6 @@ export const BusterChatInputBase: React.FC = React.memo( return [shortcutsMentionsSuggestions]; }, [shortcutsMentionsSuggestions]); - const onDictate = useMemoizedFn((transcript: string) => { - mentionInputSuggestionsRef.current?.onChangeValue(transcript); - }); - const onSubmitPreflight = (value: string) => { if (submitting) { console.warn('Input is submitting'); @@ -88,14 +85,6 @@ export const BusterChatInputBase: React.FC = React.memo( } ); - const onSubmitButton = useMemoizedFn(() => { - const value = mentionInputSuggestionsRef.current?.getValue(); - - if (value) { - onSubmitPreflight(value.transformedValue); - } - }); - return ( = React.memo( ref={mentionInputSuggestionsRef} > @@ -182,7 +170,7 @@ const useUniqueSuggestions = ( const useShortcuts = ( shortcuts: ListShortcutsResponse['shortcuts'], setOpenCreateShortcutModal: (open: boolean) => void, - onChangeValue: MentionInputSuggestionsRef['onChangeValue'] | undefined + mentionInputSuggestionsRef: React.RefObject ): MentionInputSuggestionsProps['suggestionItems'] => { return useMemo(() => { const shortcutsItems = shortcuts.map((shortcut) => { @@ -193,6 +181,7 @@ const useShortcuts = ( icon: '/', inputValue: `/ ${shortcut.name}`, onClick: () => { + const onChangeValue = mentionInputSuggestionsRef.current?.onChangeValue; onChangeValue?.(shortcut.name); }, }; @@ -218,5 +207,5 @@ const useShortcuts = ( closeOnSelect: true, }, ]; - }, [shortcuts]); + }, [shortcuts, setOpenCreateShortcutModal, mentionInputSuggestionsRef]); }; diff --git a/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx b/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx index 3a2f4bc17..46cd0b1a0 100644 --- a/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx +++ b/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx @@ -2,6 +2,7 @@ import { Command, useCommandState } from 'cmdk'; import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'; import { createContext, useContextSelector } from 'use-context-selector'; import { useMemoizedFn } from '@/hooks/useMemoizedFn'; +import { useMounted } from '@/hooks/useMount'; import { cn } from '@/lib/utils'; import type { MentionInputProps, MentionInputRef } from '../MentionInput'; import type { @@ -157,11 +158,15 @@ export const MentionInputSuggestions = forwardRef< onChangeValue, getValue, }), - [value] + [value, onChangeValue, getValue] ); return ( - + ({ value: '', + onChangeValue: () => {}, + getValue: () => undefined, }); const MentionInputSuggestionsProvider = ({ children, value, + onChangeValue, + getValue, }: { children: React.ReactNode; value: string; + onChangeValue: MentionInputSuggestionsRef['onChangeValue']; + getValue: MentionInputSuggestionsRef['getValue']; }) => { return ( - + {children} ); @@ -237,6 +252,24 @@ export const useMentionInputHasValue = () => { return hasValue; }; +const stableSelectorGetValue = (x: { getValue: MentionInputSuggestionsRef['getValue'] }) => + x.getValue; +export const useMentionInputSuggestionsGetValue = () => { + const getValue = useContextSelector(MentionInputSuggestionsContext, stableSelectorGetValue); + return getValue; +}; + +const stableSelectorOnChangeValue = (x: { + onChangeValue: MentionInputSuggestionsRef['onChangeValue']; +}) => x.onChangeValue; +export const useMentionInputSuggestionsOnChangeValue = () => { + const onChangeValue = useContextSelector( + MentionInputSuggestionsContext, + stableSelectorOnChangeValue + ); + return onChangeValue; +}; + const SuggestionsSeperator = () => { const hasResults = useCommandState((x) => x.filtered.count) > 0; if (!hasResults) return null;