diff --git a/src/config/i18n.js b/src/config/i18n.js
index 70dd6f7..13f1006 100644
--- a/src/config/i18n.js
+++ b/src/config/i18n.js
@@ -1579,9 +1579,9 @@ export const I18N = {
zh_TW: `AI智慧斷句`,
},
ai_chunk_length: {
- zh: `AI处理切割长度`,
- en: `AI processing chunk length`,
- zh_TW: `AI处理切割长度`,
+ zh: `AI处理切割长度(200-20000)`,
+ en: `AI processing chunk length(200-20000)`,
+ zh_TW: `AI处理切割长度(200-20000)`,
},
subtitle_helper_1: {
zh: `1、目前仅支持Youtube,且仅支持浏览器扩展。`,
diff --git a/src/hooks/ValidationInput.js b/src/hooks/ValidationInput.js
new file mode 100644
index 0000000..1c873f7
--- /dev/null
+++ b/src/hooks/ValidationInput.js
@@ -0,0 +1,51 @@
+import { useState, useEffect } from "react";
+import TextField from "@mui/material/TextField";
+import { limitNumber } from "../libs/utils";
+
+function ValidationInput({ value, onChange, name, min, max, ...props }) {
+ const [localValue, setLocalValue] = useState(value);
+
+ useEffect(() => {
+ setLocalValue(value);
+ }, [value]);
+
+ const handleLocalChange = (e) => {
+ setLocalValue(e.target.value);
+ };
+
+ const handleBlur = () => {
+ const numValue = Number(localValue);
+
+ if (isNaN(numValue)) {
+ setLocalValue(value);
+ return;
+ }
+
+ const validatedValue = limitNumber(numValue, min, max);
+
+ if (validatedValue !== numValue) {
+ setLocalValue(validatedValue);
+ }
+
+ onChange({
+ target: {
+ name: name,
+ value: validatedValue,
+ },
+ preventDefault: () => {},
+ });
+ };
+
+ return (
+
+ );
+}
+
+export default ValidationInput;
diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js
index f5b27f5..4d93ebb 100644
--- a/src/views/Options/Apis.js
+++ b/src/views/Options/Apis.js
@@ -22,7 +22,6 @@ import { useApiList, useApiItem } from "../../hooks/Api";
import { useConfirm } from "../../hooks/Confirm";
import { apiTranslate } from "../../apis";
import Box from "@mui/material/Box";
-import { limitNumber, limitFloat } from "../../libs/utils";
import ReusableAutocomplete from "./ReusableAutocomplete";
import ShowMoreButton from "./ShowMoreButton";
import {
@@ -45,6 +44,7 @@ import {
BUILTIN_PLACETAGS,
OPT_TRANS_AZUREAI,
} from "../../config";
+import ValidationInput from "../../hooks/ValidationInput";
function TestButton({ api }) {
const i18n = useI18n();
@@ -134,44 +134,12 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
}, [api, formData]);
const handleChange = (e) => {
+ e.preventDefault();
let { name, value, type, checked } = e.target;
if (type === "checkbox" || type === "switch") {
value = checked;
}
- // if (value === "true") value = true;
- // if (value === "false") value = false;
-
- switch (name) {
- case "fetchLimit":
- value = limitNumber(value, 1, 100);
- break;
- case "fetchInterval":
- value = limitNumber(value, 0, 5000);
- break;
- case "httpTimeout":
- value = limitNumber(value, 5000, 60000);
- break;
- case "temperature":
- value = limitFloat(value, 0, 2);
- break;
- case "maxTokens":
- value = limitNumber(value, 0, 2 ** 15);
- break;
- case "batchInterval":
- value = limitNumber(value, 100, 10000);
- break;
- case "batchSize":
- value = limitNumber(value, 1, 100);
- break;
- case "batchLength":
- value = limitNumber(value, 1000, 100000);
- break;
- case "contextSize":
- value = limitNumber(value, 1, 20);
- break;
- default:
- }
setFormData((prevData) => ({
...prevData,
@@ -323,7 +291,7 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
/>
-
-
@@ -479,7 +451,7 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
-
-
-
@@ -544,6 +522,8 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
name="contextSize"
value={contextSize}
onChange={handleChange}
+ min={1}
+ max={20}
/>
@@ -554,7 +534,7 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
-
-
-
diff --git a/src/views/Options/InputSetting.js b/src/views/Options/InputSetting.js
index e940fc8..70994a2 100644
--- a/src/views/Options/InputSetting.js
+++ b/src/views/Options/InputSetting.js
@@ -14,8 +14,8 @@ import Switch from "@mui/material/Switch";
import { useInputRule } from "../../hooks/InputRule";
import { useCallback } from "react";
import Grid from "@mui/material/Grid";
-import { limitNumber } from "../../libs/utils";
import { useApiList } from "../../hooks/Api";
+import ValidationInput from "../../hooks/ValidationInput";
export default function InputSetting() {
const i18n = useI18n();
@@ -25,12 +25,6 @@ export default function InputSetting() {
const handleChange = (e) => {
e.preventDefault();
let { name, value } = e.target;
- switch (name) {
- case "triggerTime":
- value = limitNumber(value, 10, 1000);
- break;
- default:
- }
updateInputRule({
[name]: value,
});
@@ -175,7 +169,7 @@ export default function InputSetting() {
-
diff --git a/src/views/Options/Setting.js b/src/views/Options/Setting.js
index 970e1dd..5ae228e 100644
--- a/src/views/Options/Setting.js
+++ b/src/views/Options/Setting.js
@@ -4,7 +4,6 @@ import TextField from "@mui/material/TextField";
import MenuItem from "@mui/material/MenuItem";
import Link from "@mui/material/Link";
import { useSetting } from "../../hooks/Setting";
-import { limitNumber } from "../../libs/utils";
import { useI18n } from "../../hooks/I18n";
import { useAlert } from "../../hooks/Alert";
import { isExt } from "../../libs/client";
@@ -34,6 +33,7 @@ import { kissLog } from "../../libs/log";
import UploadButton from "./UploadButton";
import DownloadButton from "./DownloadButton";
import { getSettingOld } from "../../libs/storage";
+import ValidationInput from "../../hooks/ValidationInput";
function ShortcutItem({ action, label }) {
const { shortcut, setShortcut } = useShortcut(action);
@@ -52,30 +52,6 @@ export default function Settings() {
e.preventDefault();
let { name, value } = e.target;
switch (name) {
- case "fetchLimit":
- value = limitNumber(value, 1, 100);
- break;
- case "fetchInterval":
- value = limitNumber(value, 0, 5000);
- break;
- case "transInterval":
- value = limitNumber(value, 10, 2000);
- break;
- case "minLength":
- value = limitNumber(value, 1, 100);
- break;
- case "maxLength":
- value = limitNumber(value, 100, 100000);
- break;
- case "newlineLength":
- value = limitNumber(value, 1, 1000);
- break;
- case "httpTimeout":
- value = limitNumber(value, 5000, 60000);
- break;
- case "touchTranslate":
- value = limitNumber(value, 0, 4);
- break;
case "contextMenuType":
isExt && sendBgMsg(MSG_CONTEXT_MENUS, value);
break;
@@ -219,7 +195,7 @@ export default function Settings() {
-
-
-
-
-
diff --git a/src/views/Options/Subtitle.js b/src/views/Options/Subtitle.js
index bd5b4a2..8df4214 100644
--- a/src/views/Options/Subtitle.js
+++ b/src/views/Options/Subtitle.js
@@ -10,7 +10,7 @@ import Alert from "@mui/material/Alert";
import Switch from "@mui/material/Switch";
import { useSubtitle } from "../../hooks/Subtitle";
import { useApiList } from "../../hooks/Api";
-import { limitNumber } from "../../libs/utils";
+import ValidationInput from "../../hooks/ValidationInput";
export default function SubtitleSetting() {
const i18n = useI18n();
@@ -20,12 +20,6 @@ export default function SubtitleSetting() {
const handleChange = (e) => {
e.preventDefault();
let { name, value } = e.target;
- switch (name) {
- case "chunkLength":
- value = limitNumber(value, 200, 20000);
- break;
- default:
- }
updateSubtitle({
[name]: value,
});
@@ -105,7 +99,7 @@ export default function SubtitleSetting() {
-
diff --git a/src/views/Options/Tranbox.js b/src/views/Options/Tranbox.js
index 0b1fe8e..37e529f 100644
--- a/src/views/Options/Tranbox.js
+++ b/src/views/Options/Tranbox.js
@@ -22,6 +22,7 @@ import { limitNumber } from "../../libs/utils";
import { useTranbox } from "../../hooks/Tranbox";
import { isExt } from "../../libs/client";
import { useApiList } from "../../hooks/Api";
+import ValidationInput from "../../hooks/ValidationInput";
export default function Tranbox() {
const i18n = useI18n();
@@ -278,7 +279,7 @@ export default function Tranbox() {
-
-
-
-
{!isExt && (