限制 AI 输入长度不超过 1000 字符,超出时提示用户

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
allen2fuc
2026-07-30 14:03:13 +08:00
parent 56f8db3e75
commit 87a0c3caa0
7 changed files with 34 additions and 6 deletions
+1
View File
@@ -606,6 +606,7 @@
"cleared": "Aktueller Chat gelöscht",
"clearFailed": "Löschen fehlgeschlagen: {message}",
"deviceRequired": "Bitte verbinden Sie zuerst ein Gerät",
"inputTooLong": "Nachricht zu lang, bitte auf maximal {max} Zeichen begrenzen",
"deviceDisconnected": "Gerät getrennt",
"loadHistoryFailed": "Laden des Verlaufs fehlgeschlagen: {message}",
"loadChatFailed": "Laden des Chats fehlgeschlagen: {message}",
+1
View File
@@ -606,6 +606,7 @@
"cleared": "Current chat cleared",
"clearFailed": "Clear failed: {message}",
"deviceRequired": "Please connect a device first",
"inputTooLong": "Message too long, please keep it under {max} characters",
"deviceDisconnected": "Device disconnected",
"loadHistoryFailed": "Failed to load history: {message}",
"loadChatFailed": "Failed to load chat: {message}",
+1
View File
@@ -606,6 +606,7 @@
"cleared": "Chat actual borrado",
"clearFailed": "Error al borrar: {message}",
"deviceRequired": "Conecte primero un dispositivo",
"inputTooLong": "Mensaje demasiado largo, límite de {max} caracteres",
"deviceDisconnected": "Dispositivo desconectado",
"loadHistoryFailed": "Error al cargar el historial: {message}",
"loadChatFailed": "Error al cargar el chat: {message}",
+1
View File
@@ -606,6 +606,7 @@
"cleared": "Chat actuel effacé",
"clearFailed": "Échec de l'effacement : {message}",
"deviceRequired": "Veuillez d'abord connecter un appareil",
"inputTooLong": "Message trop long, veuillez le limiter à {max} caractères",
"deviceDisconnected": "Appareil déconnecté",
"loadHistoryFailed": "Échec du chargement de l'historique : {message}",
"loadChatFailed": "Échec du chargement du chat : {message}",
+1
View File
@@ -600,6 +600,7 @@
"cleared": "已清空目前會話",
"clearFailed": "清空失敗:{message}",
"deviceRequired": "請先連接裝置",
"inputTooLong": "內容過長,請將輸入限制在 {max} 字以內",
"deviceDisconnected": "裝置未連接",
"loadHistoryFailed": "載入歷史失敗:{message}",
"loadChatFailed": "載入會話失敗:{message}",
+1
View File
@@ -601,6 +601,7 @@
"cleared": "已清空当前会话",
"clearFailed": "清空失败:{message}",
"deviceRequired": "请先连接设备",
"inputTooLong": "内容过长,请将输入限制在 {max} 字以内",
"deviceDisconnected": "设备未连接",
"loadHistoryFailed": "加载历史失败:{message}",
"loadChatFailed": "加载会话失败:{message}",
+25 -3
View File
@@ -202,6 +202,8 @@ function makeId() {
return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}
const MAX_INPUT_LENGTH = 1000;
export type AIPageVariant = "page" | "split";
export interface AIPageProps {
@@ -422,6 +424,10 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
(question: string) => {
const trimmed = question.trim();
if (!trimmed || sending) return;
if (trimmed.length > MAX_INPUT_LENGTH) {
toast.error(formatText(aiText.inputTooLong, { max: MAX_INPUT_LENGTH }));
return;
}
if (!mac || !deviceState || !api) {
toast.error(aiText.deviceRequired);
return;
@@ -595,12 +601,27 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
[input, send],
);
const onInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
setInput(e.target.value);
const overLimitToastShown = useRef(false);
const onInputChange = useCallback(
(e: React.ChangeEvent<HTMLTextAreaElement>) => {
const raw = e.target.value;
if (raw.length > MAX_INPUT_LENGTH) {
if (!overLimitToastShown.current) {
toast.error(formatText(aiText.inputTooLong, { max: MAX_INPUT_LENGTH }));
overLimitToastShown.current = true;
}
setInput(raw.slice(0, MAX_INPUT_LENGTH));
} else {
overLimitToastShown.current = false;
setInput(raw);
}
const el = e.target;
el.style.height = "auto";
el.style.height = `${Math.min(el.scrollHeight, 160)}px`;
}, []);
},
[aiText],
);
// ── 优化记录:对比对话框 & 应用/回滚 ──
const [compareMsg, setCompareMsg] = useState<OptimizeUIMessage | null>(null);
@@ -880,6 +901,7 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
onChange={onInputChange}
onKeyDown={onKeyDown}
rows={1}
maxLength={MAX_INPUT_LENGTH}
placeholder={aiText.inputPlaceholder}
className="flex-1 bg-transparent outline-none resize-none text-[15px] text-white placeholder:text-white/35 py-1.5 px-1 max-h-40 leading-[1.4]"
/>