Skip to content
This repository was archived by the owner on Jan 2, 2025. It is now read-only.

Commit f87efcf

Browse files
Fix Chinese duplicated characters in chat input (#1237)
* detach input value from chat persistent state * fix ts error
1 parent d156807 commit f87efcf

File tree

4 files changed

+59
-58
lines changed

4 files changed

+59
-58
lines changed

client/src/Project/CurrentTabContent/ChatTab/ChatPersistentState.tsx

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,8 @@ const ChatPersistentState = ({
147147
});
148148
}, [queryIdToEdit]);
149149

150-
const [inputImperativeValue, setInputImperativeValue] = useState<Record<
151-
string,
152-
any
153-
> | null>(null);
150+
const [inputImperativeValue, setInputImperativeValue] =
151+
useState<InputValueType>({ plain: '', parsed: [] });
154152
useEffect(() => {
155153
setChats((prev) => {
156154
return { ...prev, [tabKey]: { ...prev[tabKey], inputImperativeValue } };
@@ -199,34 +197,11 @@ const ChatPersistentState = ({
199197
? { plain: value, parsed: splitUserInputAfterAutocomplete(value) }
200198
: { parsed: value, plain: concatenateParsedQuery(value) },
201199
);
202-
setInputImperativeValue({
203-
type: 'paragraph',
204-
content:
205-
typeof value === 'string'
206-
? [
207-
{
208-
type: 'text',
209-
text: value,
210-
},
211-
]
212-
: value
213-
.filter((pq) =>
214-
['path', 'lang', 'text', 'repo'].includes(pq.type),
215-
)
216-
.map((pq) =>
217-
pq.type === 'text'
218-
? { type: 'text', text: pq.text }
219-
: {
220-
type: 'mention',
221-
attrs: {
222-
id: pq.text,
223-
display: pq.text,
224-
type: pq.type,
225-
isFirst: false,
226-
},
227-
},
228-
),
229-
});
200+
setInputImperativeValue(
201+
typeof value === 'string'
202+
? { plain: value, parsed: splitUserInputAfterAutocomplete(value) }
203+
: { parsed: value, plain: concatenateParsedQuery(value) },
204+
);
230205
focusInput();
231206
},
232207
[],
@@ -247,7 +222,7 @@ const ChatPersistentState = ({
247222
}
248223
eventSource.current?.close();
249224
setInputValue({ plain: '', parsed: [] });
250-
setInputImperativeValue(null);
225+
setInputImperativeValue({ plain: '', parsed: [] });
251226
setLoading(true);
252227
setQueryIdToEdit('');
253228
setHideMessagesFrom(null);
@@ -584,7 +559,7 @@ const ChatPersistentState = ({
584559
const onMessageEditCancel = useCallback(() => {
585560
setQueryIdToEdit('');
586561
setInputValue({ plain: '', parsed: [] });
587-
setInputImperativeValue(null);
562+
setInputImperativeValue({ plain: '', parsed: [] });
588563
setHideMessagesFrom(null);
589564
}, []);
590565
useEffect(() => {

client/src/Project/CurrentTabContent/ChatTab/Input/ReactMentions/index.tsx

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { Trans, useTranslation } from 'react-i18next';
1616
import { getFileExtensionForLang, splitPath } from '../../../../../utils';
1717
import FileIcon from '../../../../../components/FileIcon';
1818
import { FolderIcon, RepositoryIcon } from '../../../../../icons';
19-
import { ParsedQueryType } from '../../../../../types/general';
19+
import { InputValueType } from '../../../../../types/general';
2020
import { blurInput } from '../../../../../utils/domUtils';
2121
import { MentionOptionType } from '../../../../../types/results';
2222

@@ -25,10 +25,11 @@ type Props = {
2525
getDataLang: (s: string) => Promise<MentionOptionType[]>;
2626
getDataPath: (s: string) => Promise<MentionOptionType[]>;
2727
getDataRepo: (s: string) => Promise<MentionOptionType[]>;
28-
value?: { parsed: ParsedQueryType[]; plain: string };
28+
value?: InputValueType;
2929
onChange: (v: string) => void;
30-
onSubmit: (v: { parsed: ParsedQueryType[]; plain: string }) => void;
30+
onSubmit: (v: InputValueType) => void;
3131
isDisabled?: boolean;
32+
initialValue?: InputValueType;
3233
};
3334

3435
const inputStyle = {
@@ -67,10 +68,18 @@ const ReactMentionsInput = ({
6768
getDataLang,
6869
value,
6970
isDisabled,
71+
initialValue,
7072
}: Props) => {
7173
const { t } = useTranslation();
7274
const inputRef = useRef<HTMLTextAreaElement>(null);
7375
const [isComposing, setComposition] = useState(false);
76+
const [inputValue, setInputValue] = useState('');
77+
78+
useEffect(() => {
79+
if (initialValue) {
80+
setInputValue(initialValue.plain);
81+
}
82+
}, [initialValue]);
7483

7584
useEffect(() => {
7685
if (inputRef.current) {
@@ -126,12 +135,12 @@ const ReactMentionsInput = ({
126135
setTimeout(() => setComposition(false), 10);
127136
}, []);
128137

129-
const handleChange = useCallback<OnChangeHandlerFunc>(
130-
(e) => {
131-
onChange(e.target.value);
132-
},
133-
[onChange],
134-
);
138+
const handleChange = useCallback<OnChangeHandlerFunc>((e) => {
139+
setInputValue(e.target.value);
140+
}, []);
141+
useEffect(() => {
142+
onChange(inputValue);
143+
}, [inputValue]);
135144

136145
const renderRepoSuggestion = useCallback(
137146
(
@@ -245,7 +254,7 @@ const ReactMentionsInput = ({
245254
return (
246255
<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">
247256
<MentionsInput
248-
value={value?.plain || ''}
257+
value={inputValue}
249258
// id={id}
250259
onChange={handleChange}
251260
className={`ReactMention w-full bg-transparent rounded-lg outline-none focus:outline-0 resize-none

client/src/Project/CurrentTabContent/ChatTab/Input/index.tsx

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ChatMessageServer,
1616
FileTabType,
1717
InputEditorContent,
18+
InputValueType,
1819
ParsedQueryType,
1920
TabTypesEnum,
2021
} from '../../../../types/general';
@@ -33,25 +34,21 @@ import { mapEditorContentToInputValue } from './ProseMirror/utils';
3334
import ReactMentionsInput from './ReactMentions';
3435

3536
type Props = {
36-
value?: { parsed: ParsedQueryType[]; plain: string };
37-
valueToEdit?: Record<string, any> | null;
37+
value?: InputValueType;
38+
valueToEdit?: InputValueType;
3839
generationInProgress?: boolean;
3940
isStoppable?: boolean;
4041
onStop?: () => void;
41-
setInputValue: Dispatch<
42-
SetStateAction<{ parsed: ParsedQueryType[]; plain: string }>
43-
>;
42+
setInputValue: Dispatch<SetStateAction<InputValueType>>;
4443
selectedLines?: [number, number] | null;
4544
setSelectedLines?: (l: [number, number] | null) => void;
4645
queryIdToEdit?: string;
4746
onMessageEditCancel?: () => void;
4847
conversation: ChatMessage[];
4948
hideMessagesFrom: number | null;
5049
setConversation: Dispatch<SetStateAction<ChatMessage[]>>;
51-
setSubmittedQuery: Dispatch<
52-
SetStateAction<{ parsed: ParsedQueryType[]; plain: string }>
53-
>;
54-
submittedQuery: { parsed: ParsedQueryType[]; plain: string };
50+
setSubmittedQuery: Dispatch<SetStateAction<InputValueType>>;
51+
submittedQuery: InputValueType;
5552
isInputAtBottom?: boolean;
5653
projectId: string;
5754
};
@@ -80,7 +77,7 @@ const ConversationInput = ({
8077
const { isVisible } = useContext(CommandBarContext.General);
8178
const { chatInputType } = useContext(UIContext.ChatInputType);
8279
const { setIsLeftSidebarFocused } = useContext(UIContext.Focus);
83-
const [initialValue, setInitialValue] = useState<
80+
const [initialProseValue, setInitialProseValue] = useState<
8481
Record<string, any> | null | undefined
8582
>({
8683
type: 'paragraph',
@@ -100,6 +97,7 @@ const ConversationInput = ({
10097
},
10198
),
10299
});
100+
const [initialMentionsValue, setInitialMentionsValue] = useState(value);
103101
const [hasRendered, setHasRendered] = useState(false);
104102
const containerRef = useRef<HTMLDivElement>(null);
105103

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

111109
useEffect(() => {
112-
if (hasRendered) {
113-
setInitialValue(valueToEdit);
110+
if (hasRendered && valueToEdit) {
111+
setInitialProseValue({
112+
type: 'paragraph',
113+
content: valueToEdit?.parsed
114+
.filter((pq) => ['path', 'lang', 'text', 'repo'].includes(pq.type))
115+
.map((pq) =>
116+
pq.type === 'text'
117+
? { type: 'text', text: pq.text }
118+
: {
119+
type: 'mention',
120+
attrs: {
121+
id: pq.text,
122+
display: pq.text,
123+
type: pq.type,
124+
isFirst: false,
125+
},
126+
},
127+
),
128+
});
129+
setInitialMentionsValue(valueToEdit);
114130
}
115131
}, [valueToEdit]);
116132

@@ -314,6 +330,7 @@ const ConversationInput = ({
314330
getDataLang={getDataLang}
315331
getDataPath={getDataPath}
316332
getDataRepo={getDataRepo}
333+
initialValue={initialMentionsValue}
317334
/>
318335
) : generationInProgress ? (
319336
<div className="select-none text-label-muted body-base cursor-default">
@@ -324,7 +341,7 @@ const ConversationInput = ({
324341
getDataLang={getDataLang}
325342
getDataPath={getDataPath}
326343
getDataRepo={getDataRepo}
327-
initialValue={initialValue}
344+
initialValue={initialProseValue}
328345
onChange={onChangeProseMirrorInput}
329346
onSubmit={onSubmit}
330347
placeholder={t(

client/src/context/chatsContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type ChatContext = {
1313
isLoading: boolean;
1414
hideMessagesFrom: null | number;
1515
queryIdToEdit: string;
16-
inputImperativeValue: Record<string, any> | null;
16+
inputImperativeValue: InputValueType;
1717
threadId: string;
1818
setThreadId: Dispatch<SetStateAction<string>>;
1919
stopGenerating: () => void;

0 commit comments

Comments
 (0)