Skip to content

Commit

Permalink
Fix Chinese duplicated characters in chat input (#1237)
Browse files Browse the repository at this point in the history
* detach input value from chat persistent state

* fix ts error
  • Loading branch information
anastasiya1155 authored Feb 21, 2024
1 parent d156807 commit f87efcf
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,8 @@ const ChatPersistentState = ({
});
}, [queryIdToEdit]);

const [inputImperativeValue, setInputImperativeValue] = useState<Record<
string,
any
> | null>(null);
const [inputImperativeValue, setInputImperativeValue] =
useState<InputValueType>({ plain: '', parsed: [] });
useEffect(() => {
setChats((prev) => {
return { ...prev, [tabKey]: { ...prev[tabKey], inputImperativeValue } };
Expand Down Expand Up @@ -199,34 +197,11 @@ const ChatPersistentState = ({
? { plain: value, parsed: splitUserInputAfterAutocomplete(value) }
: { parsed: value, plain: concatenateParsedQuery(value) },
);
setInputImperativeValue({
type: 'paragraph',
content:
typeof value === 'string'
? [
{
type: 'text',
text: value,
},
]
: value
.filter((pq) =>
['path', 'lang', 'text', 'repo'].includes(pq.type),
)
.map((pq) =>
pq.type === 'text'
? { type: 'text', text: pq.text }
: {
type: 'mention',
attrs: {
id: pq.text,
display: pq.text,
type: pq.type,
isFirst: false,
},
},
),
});
setInputImperativeValue(
typeof value === 'string'
? { plain: value, parsed: splitUserInputAfterAutocomplete(value) }
: { parsed: value, plain: concatenateParsedQuery(value) },
);
focusInput();
},
[],
Expand All @@ -247,7 +222,7 @@ const ChatPersistentState = ({
}
eventSource.current?.close();
setInputValue({ plain: '', parsed: [] });
setInputImperativeValue(null);
setInputImperativeValue({ plain: '', parsed: [] });
setLoading(true);
setQueryIdToEdit('');
setHideMessagesFrom(null);
Expand Down Expand Up @@ -584,7 +559,7 @@ const ChatPersistentState = ({
const onMessageEditCancel = useCallback(() => {
setQueryIdToEdit('');
setInputValue({ plain: '', parsed: [] });
setInputImperativeValue(null);
setInputImperativeValue({ plain: '', parsed: [] });
setHideMessagesFrom(null);
}, []);
useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Trans, useTranslation } from 'react-i18next';
import { getFileExtensionForLang, splitPath } from '../../../../../utils';
import FileIcon from '../../../../../components/FileIcon';
import { FolderIcon, RepositoryIcon } from '../../../../../icons';
import { ParsedQueryType } from '../../../../../types/general';
import { InputValueType } from '../../../../../types/general';
import { blurInput } from '../../../../../utils/domUtils';
import { MentionOptionType } from '../../../../../types/results';

Expand All @@ -25,10 +25,11 @@ type Props = {
getDataLang: (s: string) => Promise<MentionOptionType[]>;
getDataPath: (s: string) => Promise<MentionOptionType[]>;
getDataRepo: (s: string) => Promise<MentionOptionType[]>;
value?: { parsed: ParsedQueryType[]; plain: string };
value?: InputValueType;
onChange: (v: string) => void;
onSubmit: (v: { parsed: ParsedQueryType[]; plain: string }) => void;
onSubmit: (v: InputValueType) => void;
isDisabled?: boolean;
initialValue?: InputValueType;
};

const inputStyle = {
Expand Down Expand Up @@ -67,10 +68,18 @@ const ReactMentionsInput = ({
getDataLang,
value,
isDisabled,
initialValue,
}: Props) => {
const { t } = useTranslation();
const inputRef = useRef<HTMLTextAreaElement>(null);
const [isComposing, setComposition] = useState(false);
const [inputValue, setInputValue] = useState('');

useEffect(() => {
if (initialValue) {
setInputValue(initialValue.plain);
}
}, [initialValue]);

useEffect(() => {
if (inputRef.current) {
Expand Down Expand Up @@ -126,12 +135,12 @@ const ReactMentionsInput = ({
setTimeout(() => setComposition(false), 10);
}, []);

const handleChange = useCallback<OnChangeHandlerFunc>(
(e) => {
onChange(e.target.value);
},
[onChange],
);
const handleChange = useCallback<OnChangeHandlerFunc>((e) => {
setInputValue(e.target.value);
}, []);
useEffect(() => {
onChange(inputValue);
}, [inputValue]);

const renderRepoSuggestion = useCallback(
(
Expand Down Expand Up @@ -245,7 +254,7 @@ const ReactMentionsInput = ({
return (
<div className="w-full body-base pb-4 !leading-[24px] bg-transparent outline-none focus:outline-0 resize-none flex-grow-0 flex flex-col justify-center">
<MentionsInput
value={value?.plain || ''}
value={inputValue}
// id={id}
onChange={handleChange}
className={`ReactMention w-full bg-transparent rounded-lg outline-none focus:outline-0 resize-none
Expand Down
43 changes: 30 additions & 13 deletions client/src/Project/CurrentTabContent/ChatTab/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ChatMessageServer,
FileTabType,
InputEditorContent,
InputValueType,
ParsedQueryType,
TabTypesEnum,
} from '../../../../types/general';
Expand All @@ -33,25 +34,21 @@ import { mapEditorContentToInputValue } from './ProseMirror/utils';
import ReactMentionsInput from './ReactMentions';

type Props = {
value?: { parsed: ParsedQueryType[]; plain: string };
valueToEdit?: Record<string, any> | null;
value?: InputValueType;
valueToEdit?: InputValueType;
generationInProgress?: boolean;
isStoppable?: boolean;
onStop?: () => void;
setInputValue: Dispatch<
SetStateAction<{ parsed: ParsedQueryType[]; plain: string }>
>;
setInputValue: Dispatch<SetStateAction<InputValueType>>;
selectedLines?: [number, number] | null;
setSelectedLines?: (l: [number, number] | null) => void;
queryIdToEdit?: string;
onMessageEditCancel?: () => void;
conversation: ChatMessage[];
hideMessagesFrom: number | null;
setConversation: Dispatch<SetStateAction<ChatMessage[]>>;
setSubmittedQuery: Dispatch<
SetStateAction<{ parsed: ParsedQueryType[]; plain: string }>
>;
submittedQuery: { parsed: ParsedQueryType[]; plain: string };
setSubmittedQuery: Dispatch<SetStateAction<InputValueType>>;
submittedQuery: InputValueType;
isInputAtBottom?: boolean;
projectId: string;
};
Expand Down Expand Up @@ -80,7 +77,7 @@ const ConversationInput = ({
const { isVisible } = useContext(CommandBarContext.General);
const { chatInputType } = useContext(UIContext.ChatInputType);
const { setIsLeftSidebarFocused } = useContext(UIContext.Focus);
const [initialValue, setInitialValue] = useState<
const [initialProseValue, setInitialProseValue] = useState<
Record<string, any> | null | undefined
>({
type: 'paragraph',
Expand All @@ -100,6 +97,7 @@ const ConversationInput = ({
},
),
});
const [initialMentionsValue, setInitialMentionsValue] = useState(value);
const [hasRendered, setHasRendered] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);

Expand All @@ -109,8 +107,26 @@ const ConversationInput = ({
}, []);

useEffect(() => {
if (hasRendered) {
setInitialValue(valueToEdit);
if (hasRendered && valueToEdit) {
setInitialProseValue({
type: 'paragraph',
content: valueToEdit?.parsed
.filter((pq) => ['path', 'lang', 'text', 'repo'].includes(pq.type))
.map((pq) =>
pq.type === 'text'
? { type: 'text', text: pq.text }
: {
type: 'mention',
attrs: {
id: pq.text,
display: pq.text,
type: pq.type,
isFirst: false,
},
},
),
});
setInitialMentionsValue(valueToEdit);
}
}, [valueToEdit]);

Expand Down Expand Up @@ -314,6 +330,7 @@ const ConversationInput = ({
getDataLang={getDataLang}
getDataPath={getDataPath}
getDataRepo={getDataRepo}
initialValue={initialMentionsValue}
/>
) : generationInProgress ? (
<div className="select-none text-label-muted body-base cursor-default">
Expand All @@ -324,7 +341,7 @@ const ConversationInput = ({
getDataLang={getDataLang}
getDataPath={getDataPath}
getDataRepo={getDataRepo}
initialValue={initialValue}
initialValue={initialProseValue}
onChange={onChangeProseMirrorInput}
onSubmit={onSubmit}
placeholder={t(
Expand Down
2 changes: 1 addition & 1 deletion client/src/context/chatsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type ChatContext = {
isLoading: boolean;
hideMessagesFrom: null | number;
queryIdToEdit: string;
inputImperativeValue: Record<string, any> | null;
inputImperativeValue: InputValueType;
threadId: string;
setThreadId: Dispatch<SetStateAction<string>>;
stopGenerating: () => void;
Expand Down

0 comments on commit f87efcf

Please sign in to comment.