Skip to content

Commit 9b7b987

Browse files
committed
fix: improve chat window buttons
1 parent 83bbd9f commit 9b7b987

5 files changed

Lines changed: 132 additions & 87 deletions

File tree

object/text_to_speech.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ func createProviderChat(chatId string, provider *Provider) (*Chat, error) {
6969
}
7070
chat := &Chat{
7171
Name: chatName,
72-
Type: "Provider",
7372
Owner: provider.Owner,
7473
CreatedTime: util.GetCurrentTime(),
7574
UpdatedTime: util.GetCurrentTime(),

web/src/chat/MessageActions.js

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const MessageActions = ({
5252
account,
5353
setIsRegenerating,
5454
isRegenerating,
55+
hideInput,
5556
}) => {
5657
const isCurrentMessageBeingRead = readingMessage === message.name;
5758
const isCurrentMessageBeingLoaded = isLoadingTTS && isCurrentMessageBeingRead;
@@ -89,23 +90,27 @@ const MessageActions = ({
8990
>
9091
<CopyButton message={message} onCopy={onCopy} />
9192

92-
<Tooltip title={i18next.t("general:Like")} arrow={false}>
93-
<Button
94-
icon={message.likeUsers?.includes(account.name) ? <LikeFilled /> : <LikeOutlined />}
95-
color="primary"
96-
variant="text"
97-
onClick={() => onLike(message, "like")}
98-
/>
99-
</Tooltip>
93+
{!hideInput && (
94+
<Tooltip title={i18next.t("general:Like")} arrow={false}>
95+
<Button
96+
icon={message.likeUsers?.includes(account.name) ? <LikeFilled /> : <LikeOutlined />}
97+
color="primary"
98+
variant="text"
99+
onClick={() => onLike(message, "like")}
100+
/>
101+
</Tooltip>
102+
)}
100103

101-
<Tooltip title={i18next.t("general:Dislike")} arrow={false}>
102-
<Button
103-
icon={message.dislikeUsers?.includes(account.name) ? <DislikeFilled /> : <DislikeOutlined />}
104-
color="primary"
105-
variant="text"
106-
onClick={() => onLike(message, "dislike")}
107-
/>
108-
</Tooltip>
104+
{!hideInput && (
105+
<Tooltip title={i18next.t("general:Dislike")} arrow={false}>
106+
<Button
107+
icon={message.dislikeUsers?.includes(account.name) ? <DislikeFilled /> : <DislikeOutlined />}
108+
color="primary"
109+
variant="text"
110+
onClick={() => onLike(message, "dislike")}
111+
/>
112+
</Tooltip>
113+
)}
109114

110115
<Tooltip title={getTtsTooltip()} arrow={false}>
111116
<Button
@@ -117,7 +122,7 @@ const MessageActions = ({
117122
/>
118123
</Tooltip>
119124

120-
{!isLastMessage ? null : (
125+
{!hideInput && isLastMessage && (
121126
<Tooltip title={i18next.t("general:Regenerate")} arrow={false}>
122127
<Button
123128
icon={<ReloadOutlined />}

web/src/chat/MessageEdit.js

Lines changed: 90 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,23 @@
1313
// limitations under the License.
1414

1515
import React, {useState} from "react";
16-
import {Button, Input, Space, Tooltip} from "antd";
16+
import {Button, Input, Tooltip} from "antd";
1717
import {CheckOutlined, CloseOutlined, EditOutlined} from "@ant-design/icons";
1818
import i18next from "i18next";
1919

20-
// Styles for edit components
21-
export const editStyles = {
22-
// Edit form styles
23-
editForm: {
24-
width: "100%",
25-
},
26-
27-
// TextArea styles in edit form
28-
editTextArea: {
29-
marginBottom: "8px",
30-
},
31-
32-
// Button container in edit form
33-
editFormButtons: {
34-
display: "flex",
35-
justifyContent: "flex-end",
36-
},
37-
};
38-
3920
const MessageEdit = ({
4021
message,
4122
isLastMessage,
4223
disableInput,
24+
hideInput,
4325
index,
4426
onEditMessage,
27+
isDark,
4528
}) => {
4629
const [isEditing, setIsEditing] = useState(false);
4730
const [editedText, setEditedText] = useState("");
4831
const [isHovering, setIsHovering] = useState(false);
4932

50-
// Edit action handlers
5133
const handleEditActions = {
5234
start: () => {
5335
setIsEditing(true);
@@ -65,44 +47,99 @@ const MessageEdit = ({
6547
if (e.key === "Enter" && !e.shiftKey) {
6648
e.preventDefault();
6749
handleEditActions.save();
50+
} else if (e.key === "Escape") {
51+
handleEditActions.cancel();
6852
}
6953
},
7054
};
7155

72-
// Edit form component
73-
const renderEditForm = () => (
74-
<div style={editStyles.editForm}>
75-
<Input.TextArea
76-
value={editedText}
77-
onChange={e => setEditedText(e.target.value)}
78-
onKeyDown={handleEditActions.keyDown}
79-
autoSize={{minRows: 1, maxRows: 6}}
80-
style={editStyles.editTextArea}
81-
autoFocus
82-
/>
83-
<Space style={editStyles.editFormButtons}>
84-
<Button
85-
icon={<CloseOutlined />}
86-
onClick={handleEditActions.cancel}
87-
size="small"
88-
>
89-
{i18next.t("general:Cancel")}
90-
</Button>
91-
<Button
92-
type="primary"
93-
icon={<CheckOutlined />}
94-
onClick={handleEditActions.save}
95-
size="small"
96-
>
97-
{i18next.t("general:Save")}
98-
</Button>
99-
</Space>
100-
</div>
101-
);
56+
const renderEditForm = () => {
57+
const containerStyle = {
58+
width: "100%",
59+
maxWidth: "480px",
60+
marginLeft: "auto",
61+
background: isDark ? "#1e2130" : "#ffffff",
62+
border: isDark ? "1px solid #2e3347" : "1px solid #e2e8f0",
63+
borderRadius: "14px 14px 4px 14px",
64+
padding: "12px 14px",
65+
boxShadow: isDark
66+
? "0 4px 16px rgba(0,0,0,0.45)"
67+
: "0 4px 16px rgba(0,0,0,0.08)",
68+
};
69+
70+
const textareaStyle = {
71+
background: isDark ? "#252a3a" : "#f7f9fc",
72+
borderColor: isDark ? "#363d52" : "#dde3ed",
73+
color: isDark ? "#dde3f0" : "#2d3748",
74+
borderRadius: "8px",
75+
fontSize: "14px",
76+
lineHeight: "1.6",
77+
resize: "none",
78+
transition: "border-color 0.2s",
79+
};
80+
81+
return (
82+
<div style={containerStyle}>
83+
<Input.TextArea
84+
value={editedText}
85+
onChange={e => setEditedText(e.target.value)}
86+
onKeyDown={handleEditActions.keyDown}
87+
autoSize={{minRows: 2, maxRows: 8}}
88+
style={textareaStyle}
89+
autoFocus
90+
/>
91+
<div style={{
92+
display: "flex",
93+
justifyContent: "space-between",
94+
alignItems: "center",
95+
marginTop: "10px",
96+
}}>
97+
<span style={{
98+
fontSize: "11px",
99+
color: isDark ? "#5a6480" : "#a0aec0",
100+
userSelect: "none",
101+
}}>
102+
Enter {i18next.t("general:Save")} · Esc {i18next.t("general:Cancel")}
103+
</span>
104+
<div style={{display: "flex", gap: "8px"}}>
105+
<Button
106+
size="small"
107+
icon={<CloseOutlined style={{fontSize: "11px"}} />}
108+
onClick={handleEditActions.cancel}
109+
style={{
110+
borderRadius: "20px",
111+
paddingInline: "12px",
112+
height: "28px",
113+
background: "transparent",
114+
borderColor: isDark ? "#3d4560" : "#d1d8e4",
115+
color: isDark ? "#8896b0" : "#718096",
116+
fontSize: "12px",
117+
}}
118+
>
119+
{i18next.t("general:Cancel")}
120+
</Button>
121+
<Button
122+
type="primary"
123+
size="small"
124+
icon={<CheckOutlined style={{fontSize: "11px"}} />}
125+
onClick={handleEditActions.save}
126+
style={{
127+
borderRadius: "20px",
128+
paddingInline: "12px",
129+
height: "28px",
130+
fontSize: "12px",
131+
}}
132+
>
133+
{i18next.t("general:Save")}
134+
</Button>
135+
</div>
136+
</div>
137+
</div>
138+
);
139+
};
102140

103-
// Edit button component
104141
const renderEditButton = () => {
105-
if (message.author !== "AI" && !isEditing && (disableInput === false || index !== isLastMessage)) {
142+
if (message.author !== "AI" && !isEditing && !hideInput && (disableInput === false || index !== isLastMessage)) {
106143
return (
107144
<Tooltip title={i18next.t("general:Edit")} arrow={false}>
108145
<Button
@@ -117,7 +154,6 @@ const MessageEdit = ({
117154
return null;
118155
};
119156

120-
// Return the editing state and render functions
121157
return {
122158
isEditing,
123159
isHovering,

web/src/chat/MessageItem.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ const MessageItem = ({
4242
onToggleRead,
4343
onEditMessage,
4444
disableInput,
45+
hideInput,
4546
isReading,
46-
isLoadingTTS, // Added new prop for TTS loading state
47+
isLoadingTTS,
4748
readingMessage,
4849
sendMessage,
4950
hideThinking,
@@ -154,8 +155,10 @@ const MessageItem = ({
154155
message,
155156
isLastMessage,
156157
disableInput,
158+
hideInput,
157159
index,
158160
onEditMessage,
161+
isDark,
159162
});
160163

161164
useEffect(() => {
@@ -168,12 +171,8 @@ const MessageItem = ({
168171
};
169172

170173
const renderMessageContent = () => {
171-
if (isEditing && message.author !== "AI") {
172-
return renderEditForm();
173-
}
174-
175174
if (message.errorText !== "") {
176-
const regenerateButton = (
175+
const regenerateButton = !hideInput ? (
177176
<Button
178177
danger
179178
type="primary"
@@ -187,7 +186,7 @@ const MessageItem = ({
187186
? i18next.t("general:Regenerating...")
188187
: i18next.t("general:Regenerate")}
189188
</Button>
190-
);
189+
) : null;
191190
return Setting.isMobile() ? (
192191
<div>
193192
<Alert
@@ -197,17 +196,19 @@ const MessageItem = ({
197196
showIcon
198197
style={{whiteSpace: "normal", wordWrap: "break-word"}}
199198
/>
200-
<Row justify="center" style={{marginTop: 16}}>
201-
<Col>{regenerateButton}</Col>
202-
</Row>
199+
{regenerateButton && (
200+
<Row justify="center" style={{marginTop: 16}}>
201+
<Col>{regenerateButton}</Col>
202+
</Row>
203+
)}
203204
</div>
204205
) : (
205206
<Alert
206207
message={Setting.getRefinedErrorText(message.errorText)}
207208
description={message.errorText}
208209
type="error"
209210
showIcon
210-
action={<div style={{marginLeft: 16}}>{regenerateButton}</div>}
211+
action={regenerateButton ? <div style={{marginLeft: 16}}>{regenerateButton}</div> : null}
211212
/>
212213
);
213214
}
@@ -335,6 +336,10 @@ const MessageItem = ({
335336

336337
const isUserMessage = message.author !== "AI";
337338

339+
if (isEditing && isUserMessage) {
340+
return renderEditForm();
341+
}
342+
338343
return (
339344
<div style={{
340345
display: "flex",
@@ -345,7 +350,7 @@ const MessageItem = ({
345350
{isUserMessage && !isEditing && (
346351
<Space size="small" style={{opacity: isHovering ? 0.8 : 0, transition: "opacity 0.2s ease-in-out"}}>
347352
<CopyButton message={message} onCopy={onCopy} />
348-
{renderEditButton()}
353+
{!hideInput && renderEditButton()}
349354
</Space>
350355
)}
351356

@@ -370,11 +375,12 @@ const MessageItem = ({
370375
onToggleRead={onToggleRead}
371376
onEdit={() => setIsHovering(true)}
372377
isReading={isReading}
373-
isLoadingTTS={isLoadingTTS} // Pass loading state to MessageActions
378+
isLoadingTTS={isLoadingTTS}
374379
readingMessage={readingMessage}
375380
account={account}
376381
setIsRegenerating={setIsRegenerating}
377382
isRegenerating={isRegenerating}
383+
hideInput={hideInput}
378384
/>
379385
{mergedSearchResults.length > 0 && (
380386
<Button
@@ -427,13 +433,11 @@ const MessageItem = ({
427433
padding: "11px 16px",
428434
backgroundColor: themeColor,
429435
color: "#fff",
430-
minWidth: isEditing ? "300px" : "auto",
431436
} : {
432437
borderRadius: "4px 18px 18px 18px",
433438
padding: "11px 16px",
434439
backgroundColor: aiBubbleBg,
435440
border: aiBubbleBorder,
436-
minWidth: isEditing ? "300px" : "auto",
437441
},
438442
}}
439443
/>

web/src/chat/MessageList.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class MessageList extends React.Component {
7373
onToggleRead={onToggleRead}
7474
onEditMessage={onEditMessage}
7575
disableInput={disableInput}
76+
hideInput={hideInput}
7677
isReading={isReading}
7778
isLoadingTTS={isLoadingTTS}
7879
readingMessage={readingMessage}

0 commit comments

Comments
 (0)