限制 AI 输入长度不超过 1000 字符,超出时提示用户
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -606,6 +606,7 @@
|
|||||||
"cleared": "Aktueller Chat gelöscht",
|
"cleared": "Aktueller Chat gelöscht",
|
||||||
"clearFailed": "Löschen fehlgeschlagen: {message}",
|
"clearFailed": "Löschen fehlgeschlagen: {message}",
|
||||||
"deviceRequired": "Bitte verbinden Sie zuerst ein Gerät",
|
"deviceRequired": "Bitte verbinden Sie zuerst ein Gerät",
|
||||||
|
"inputTooLong": "Nachricht zu lang, bitte auf maximal {max} Zeichen begrenzen",
|
||||||
"deviceDisconnected": "Gerät getrennt",
|
"deviceDisconnected": "Gerät getrennt",
|
||||||
"loadHistoryFailed": "Laden des Verlaufs fehlgeschlagen: {message}",
|
"loadHistoryFailed": "Laden des Verlaufs fehlgeschlagen: {message}",
|
||||||
"loadChatFailed": "Laden des Chats fehlgeschlagen: {message}",
|
"loadChatFailed": "Laden des Chats fehlgeschlagen: {message}",
|
||||||
|
|||||||
@@ -606,6 +606,7 @@
|
|||||||
"cleared": "Current chat cleared",
|
"cleared": "Current chat cleared",
|
||||||
"clearFailed": "Clear failed: {message}",
|
"clearFailed": "Clear failed: {message}",
|
||||||
"deviceRequired": "Please connect a device first",
|
"deviceRequired": "Please connect a device first",
|
||||||
|
"inputTooLong": "Message too long, please keep it under {max} characters",
|
||||||
"deviceDisconnected": "Device disconnected",
|
"deviceDisconnected": "Device disconnected",
|
||||||
"loadHistoryFailed": "Failed to load history: {message}",
|
"loadHistoryFailed": "Failed to load history: {message}",
|
||||||
"loadChatFailed": "Failed to load chat: {message}",
|
"loadChatFailed": "Failed to load chat: {message}",
|
||||||
|
|||||||
@@ -606,6 +606,7 @@
|
|||||||
"cleared": "Chat actual borrado",
|
"cleared": "Chat actual borrado",
|
||||||
"clearFailed": "Error al borrar: {message}",
|
"clearFailed": "Error al borrar: {message}",
|
||||||
"deviceRequired": "Conecte primero un dispositivo",
|
"deviceRequired": "Conecte primero un dispositivo",
|
||||||
|
"inputTooLong": "Mensaje demasiado largo, límite de {max} caracteres",
|
||||||
"deviceDisconnected": "Dispositivo desconectado",
|
"deviceDisconnected": "Dispositivo desconectado",
|
||||||
"loadHistoryFailed": "Error al cargar el historial: {message}",
|
"loadHistoryFailed": "Error al cargar el historial: {message}",
|
||||||
"loadChatFailed": "Error al cargar el chat: {message}",
|
"loadChatFailed": "Error al cargar el chat: {message}",
|
||||||
|
|||||||
@@ -606,6 +606,7 @@
|
|||||||
"cleared": "Chat actuel effacé",
|
"cleared": "Chat actuel effacé",
|
||||||
"clearFailed": "Échec de l'effacement : {message}",
|
"clearFailed": "Échec de l'effacement : {message}",
|
||||||
"deviceRequired": "Veuillez d'abord connecter un appareil",
|
"deviceRequired": "Veuillez d'abord connecter un appareil",
|
||||||
|
"inputTooLong": "Message trop long, veuillez le limiter à {max} caractères",
|
||||||
"deviceDisconnected": "Appareil déconnecté",
|
"deviceDisconnected": "Appareil déconnecté",
|
||||||
"loadHistoryFailed": "Échec du chargement de l'historique : {message}",
|
"loadHistoryFailed": "Échec du chargement de l'historique : {message}",
|
||||||
"loadChatFailed": "Échec du chargement du chat : {message}",
|
"loadChatFailed": "Échec du chargement du chat : {message}",
|
||||||
|
|||||||
@@ -600,6 +600,7 @@
|
|||||||
"cleared": "已清空目前會話",
|
"cleared": "已清空目前會話",
|
||||||
"clearFailed": "清空失敗:{message}",
|
"clearFailed": "清空失敗:{message}",
|
||||||
"deviceRequired": "請先連接裝置",
|
"deviceRequired": "請先連接裝置",
|
||||||
|
"inputTooLong": "內容過長,請將輸入限制在 {max} 字以內",
|
||||||
"deviceDisconnected": "裝置未連接",
|
"deviceDisconnected": "裝置未連接",
|
||||||
"loadHistoryFailed": "載入歷史失敗:{message}",
|
"loadHistoryFailed": "載入歷史失敗:{message}",
|
||||||
"loadChatFailed": "載入會話失敗:{message}",
|
"loadChatFailed": "載入會話失敗:{message}",
|
||||||
|
|||||||
@@ -601,6 +601,7 @@
|
|||||||
"cleared": "已清空当前会话",
|
"cleared": "已清空当前会话",
|
||||||
"clearFailed": "清空失败:{message}",
|
"clearFailed": "清空失败:{message}",
|
||||||
"deviceRequired": "请先连接设备",
|
"deviceRequired": "请先连接设备",
|
||||||
|
"inputTooLong": "内容过长,请将输入限制在 {max} 字以内",
|
||||||
"deviceDisconnected": "设备未连接",
|
"deviceDisconnected": "设备未连接",
|
||||||
"loadHistoryFailed": "加载历史失败:{message}",
|
"loadHistoryFailed": "加载历史失败:{message}",
|
||||||
"loadChatFailed": "加载会话失败:{message}",
|
"loadChatFailed": "加载会话失败:{message}",
|
||||||
|
|||||||
@@ -202,6 +202,8 @@ function makeId() {
|
|||||||
return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_INPUT_LENGTH = 1000;
|
||||||
|
|
||||||
export type AIPageVariant = "page" | "split";
|
export type AIPageVariant = "page" | "split";
|
||||||
|
|
||||||
export interface AIPageProps {
|
export interface AIPageProps {
|
||||||
@@ -422,6 +424,10 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
|
|||||||
(question: string) => {
|
(question: string) => {
|
||||||
const trimmed = question.trim();
|
const trimmed = question.trim();
|
||||||
if (!trimmed || sending) return;
|
if (!trimmed || sending) return;
|
||||||
|
if (trimmed.length > MAX_INPUT_LENGTH) {
|
||||||
|
toast.error(formatText(aiText.inputTooLong, { max: MAX_INPUT_LENGTH }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!mac || !deviceState || !api) {
|
if (!mac || !deviceState || !api) {
|
||||||
toast.error(aiText.deviceRequired);
|
toast.error(aiText.deviceRequired);
|
||||||
return;
|
return;
|
||||||
@@ -595,12 +601,27 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
|
|||||||
[input, send],
|
[input, send],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
const overLimitToastShown = useRef(false);
|
||||||
setInput(e.target.value);
|
|
||||||
const el = e.target;
|
const onInputChange = useCallback(
|
||||||
el.style.height = "auto";
|
(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
el.style.height = `${Math.min(el.scrollHeight, 160)}px`;
|
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);
|
const [compareMsg, setCompareMsg] = useState<OptimizeUIMessage | null>(null);
|
||||||
@@ -880,6 +901,7 @@ export default function AIPage({ variant = "page", onClose }: AIPageProps = {})
|
|||||||
onChange={onInputChange}
|
onChange={onInputChange}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
rows={1}
|
rows={1}
|
||||||
|
maxLength={MAX_INPUT_LENGTH}
|
||||||
placeholder={aiText.inputPlaceholder}
|
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]"
|
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]"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user