Browse Source

chore: group types locale

dongchengjie 11 tháng trước cách đây
mục cha
commit
78c32d51db

+ 1 - 1
src/components/base/base-search-box.tsx

@@ -26,7 +26,7 @@ type SearchProps = {
 export const BaseSearchBox = styled((props: SearchProps) => {
   const { t } = useTranslation();
   const inputRef = useRef<HTMLInputElement>(null);
-  const [matchCase, setMatchCase] = useState(props.matchCase ?? true);
+  const [matchCase, setMatchCase] = useState(props.matchCase ?? false);
   const [matchWholeWord, setMatchWholeWord] = useState(
     props.matchWholeWord ?? false
   );

+ 47 - 26
src/components/profile/groups-editor-viewer.tsx

@@ -23,6 +23,7 @@ import {
   DialogActions,
   DialogContent,
   DialogTitle,
+  InputAdornment,
   List,
   ListItem,
   ListItemText,
@@ -273,7 +274,7 @@ export const GroupsEditorViewer = (props: Props) => {
   const validateGroup = () => {
     let group = formIns.getValues();
     if (group.name === "") {
-      throw new Error(t("Group Name Cannot Be Empty"));
+      throw new Error(t("Group Name Required"));
     }
   };
 
@@ -342,6 +343,11 @@ export const GroupsEditorViewer = (props: Props) => {
                           "relay",
                         ]}
                         value={field.value}
+                        renderOption={(props, option) => (
+                          <li {...props} title={t(option)}>
+                            {option}
+                          </li>
+                        )}
                         onChange={(_, value) => value && field.onChange(value)}
                         renderInput={(params) => <TextField {...params} />}
                       />
@@ -370,7 +376,7 @@ export const GroupsEditorViewer = (props: Props) => {
                   control={control}
                   render={({ field }) => (
                     <Item>
-                      <ListItemText primary={t("Icon")} />
+                      <ListItemText primary={t("Proxy Group Icon")} />
                       <TextField
                         autoComplete="new-password"
                         size="small"
@@ -418,7 +424,6 @@ export const GroupsEditorViewer = (props: Props) => {
                     </Item>
                   )}
                 />
-
                 <Controller
                   name="url"
                   control={control}
@@ -427,6 +432,7 @@ export const GroupsEditorViewer = (props: Props) => {
                       <ListItemText primary={t("Health Check Url")} />
                       <TextField
                         autoComplete="new-password"
+                        placeholder="https://www.gstatic.com/generate_204"
                         size="small"
                         sx={{ width: "calc(100% - 150px)" }}
                         {...field}
@@ -434,6 +440,24 @@ export const GroupsEditorViewer = (props: Props) => {
                     </Item>
                   )}
                 />
+                <Controller
+                  name="expected-status"
+                  control={control}
+                  render={({ field }) => (
+                    <Item>
+                      <ListItemText primary={t("Expected Status")} />
+                      <TextField
+                        autoComplete="new-password"
+                        placeholder="*"
+                        size="small"
+                        sx={{ width: "calc(100% - 150px)" }}
+                        onChange={(e) => {
+                          field.onChange(parseInt(e.target.value));
+                        }}
+                      />
+                    </Item>
+                  )}
+                />
                 <Controller
                   name="interval"
                   control={control}
@@ -442,12 +466,20 @@ export const GroupsEditorViewer = (props: Props) => {
                       <ListItemText primary={t("Interval")} />
                       <TextField
                         autoComplete="new-password"
+                        placeholder="300"
                         type="number"
                         size="small"
                         sx={{ width: "calc(100% - 150px)" }}
                         onChange={(e) => {
                           field.onChange(parseInt(e.target.value));
                         }}
+                        InputProps={{
+                          endAdornment: (
+                            <InputAdornment position="end">
+                              {t("seconds")}
+                            </InputAdornment>
+                          ),
+                        }}
                       />
                     </Item>
                   )}
@@ -460,12 +492,20 @@ export const GroupsEditorViewer = (props: Props) => {
                       <ListItemText primary={t("Timeout")} />
                       <TextField
                         autoComplete="new-password"
+                        placeholder="5000"
                         type="number"
                         size="small"
                         sx={{ width: "calc(100% - 150px)" }}
                         onChange={(e) => {
                           field.onChange(parseInt(e.target.value));
                         }}
+                        InputProps={{
+                          endAdornment: (
+                            <InputAdornment position="end">
+                              {t("millis")}
+                            </InputAdornment>
+                          ),
+                        }}
                       />
                     </Item>
                   )}
@@ -478,6 +518,7 @@ export const GroupsEditorViewer = (props: Props) => {
                       <ListItemText primary={t("Max Failed Times")} />
                       <TextField
                         autoComplete="new-password"
+                        placeholder="5"
                         type="number"
                         size="small"
                         sx={{ width: "calc(100% - 150px)" }}
@@ -599,23 +640,6 @@ export const GroupsEditorViewer = (props: Props) => {
                     </Item>
                   )}
                 />
-                <Controller
-                  name="expected-status"
-                  control={control}
-                  render={({ field }) => (
-                    <Item>
-                      <ListItemText primary={t("Expected Status")} />
-                      <TextField
-                        autoComplete="new-password"
-                        size="small"
-                        sx={{ width: "calc(100% - 150px)" }}
-                        onChange={(e) => {
-                          field.onChange(parseInt(e.target.value));
-                        }}
-                      />
-                    </Item>
-                  )}
-                />
                 <Controller
                   name="include-all"
                   control={control}
@@ -684,7 +708,7 @@ export const GroupsEditorViewer = (props: Props) => {
                   onClick={() => {
                     try {
                       validateGroup();
-                      for (const item of prependSeq) {
+                      for (const item of [...prependSeq, ...groupList]) {
                         if (item.name === formIns.getValues().name) {
                           throw new Error(t("Group Name Already Exists"));
                         }
@@ -705,7 +729,7 @@ export const GroupsEditorViewer = (props: Props) => {
                   onClick={() => {
                     try {
                       validateGroup();
-                      for (const item of appendSeq) {
+                      for (const item of [...appendSeq, ...groupList]) {
                         if (item.name === formIns.getValues().name) {
                           throw new Error(t("Group Name Already Exists"));
                         }
@@ -727,10 +751,7 @@ export const GroupsEditorViewer = (props: Props) => {
                 padding: "0 10px",
               }}
             >
-              <BaseSearchBox
-                matchCase={false}
-                onSearch={(match) => setMatch(() => match)}
-              />
+              <BaseSearchBox onSearch={(match) => setMatch(() => match)} />
               <Virtuoso
                 style={{ height: "calc(100% - 24px)", marginTop: "8px" }}
                 totalCount={

+ 1 - 4
src/components/profile/proxies-editor-viewer.tsx

@@ -298,10 +298,7 @@ export const ProxiesEditorViewer = (props: Props) => {
                 padding: "0 10px",
               }}
             >
-              <BaseSearchBox
-                matchCase={false}
-                onSearch={(match) => setMatch(() => match)}
-              />
+              <BaseSearchBox onSearch={(match) => setMatch(() => match)} />
               <Virtuoso
                 style={{ height: "calc(100% - 24px)", marginTop: "8px" }}
                 totalCount={

+ 1 - 0
src/components/profile/proxy-item.tsx

@@ -56,6 +56,7 @@ export const ProxyItem = (props: Props) => {
         sx={{ cursor: sortable ? "move" : "" }}
         primary={
           <StyledPrimary
+            title={proxy.name}
             sx={{ textDecoration: type === "delete" ? "line-through" : "" }}
           >
             {proxy.name}

+ 1 - 0
src/components/profile/rule-item.tsx

@@ -59,6 +59,7 @@ export const RuleItem = (props: Props) => {
         sx={{ cursor: sortable ? "move" : "" }}
         primary={
           <StyledPrimary
+            title={ruleContent || "-"}
             sx={{ textDecoration: type === "delete" ? "line-through" : "" }}
           >
             {ruleContent || "-"}

+ 1 - 4
src/components/profile/rules-editor-viewer.tsx

@@ -573,10 +573,7 @@ export const RulesEditorViewer = (props: Props) => {
                 padding: "0 10px",
               }}
             >
-              <BaseSearchBox
-                matchCase={false}
-                onSearch={(match) => setMatch(() => match)}
-              />
+              <BaseSearchBox onSearch={(match) => setMatch(() => match)} />
               <Virtuoso
                 style={{ height: "calc(100% - 24px)", marginTop: "8px" }}
                 totalCount={

+ 10 - 2
src/locales/en.json

@@ -1,5 +1,6 @@
 {
   "millis": "millis",
+  "seconds": "seconds",
   "mins": "mins",
   "Back": "Back",
   "Close": "Close",
@@ -54,7 +55,7 @@
   "Create Profile": "Create Profile",
   "Edit Profile": "Edit Profile",
   "Edit Proxies": "Edit Proxies",
-  "Use newlines for multiple uri": "Use newlines for multiple uri",
+  "Use newlines for multiple uri": "Use newlines for multiple uri(Base64 encoding supported)",
   "Edit Rules": "Edit Rules",
   "Rule Type": "Rule Type",
   "Rule Content": "Rule Content",
@@ -109,10 +110,16 @@
   "PASS": "Skips this rule when matched",
   "Edit Groups": "Edit Proxy Groups",
   "Group Type": "Group Type",
+  "select": "Select proxy manually",
+  "url-test": "Select proxy based on URL test delay",
+  "fallback": "Switch to another proxy on error",
+  "load-balance": "Distribute proxy based on load balancing",
+  "relay": "Pass through the defined proxy chain",
   "Group Name": "Group Name",
   "Use Proxies": "Use Proxies",
   "Use Provider": "Use Provider",
   "Health Check Url": "Health Check Url",
+  "Expected Status": "Expected Status",
   "Interval": "Interval",
   "Lazy": "Lazy",
   "Timeout": "Timeout",
@@ -124,9 +131,10 @@
   "Include All Proxies": "Include All Proxies",
   "Exclude Filter": "Exclude Filter",
   "Exclude Type": "Exclude Type",
-  "Expected Status": "Expected Status",
   "Disable UDP": "Disable UDP",
   "Hidden": "Hidden",
+  "Group Name Required": "Group Name Required",
+  "Group Name Already Exists": "Group Name Already Exists",
   "Extend Config": "Extend Config",
   "Extend Script": "Extend Script",
   "Global Merge": "Global Extend Config",

+ 10 - 2
src/locales/fa.json

@@ -1,5 +1,6 @@
 {
   "millis": "میلی‌ثانیه",
+  "seconds": "ثانیه‌ها",
   "mins": "دقیقه",
   "Back": "بازگشت",
   "Close": "بستن",
@@ -54,7 +55,7 @@
   "Create Profile": "ایجاد پروفایل",
   "Edit Profile": "ویرایش پروفایل",
   "Edit Proxies": "ویرایش پروکسی‌ها",
-  "Use newlines for multiple uri": "استفاده از خطوط جدید برای چندین آدرس",
+  "Use newlines for multiple uri": "استفاده از خطوط جدید برای چندین آدرس (پشتیبانی از رمزگذاری Base64)",
   "Edit Rules": "ویرایش قوانین",
   "Rule Type": "نوع قانون",
   "Rule Content": "محتوای قانون",
@@ -107,10 +108,16 @@
   "PASS": "این قانون را در صورت تطابق نادیده می‌گیرد",
   "Edit Groups": "ویرایش گروه‌های پروکسی",
   "Group Type": "نوع گروه",
+  "select": "انتخاب پروکسی به صورت دستی",
+  "url-test": "انتخاب پروکسی بر اساس تأخیر آزمایش URL",
+  "fallback": "تعویض به پروکسی دیگر در صورت بروز خطا",
+  "load-balance": "توزیع پروکسی بر اساس توازن بار",
+  "relay": "عبور از زنجیره پروکسی تعریف شده",
   "Group Name": "نام گروه",
   "Use Proxies": "استفاده از پروکسی‌ها",
   "Use Provider": "استفاده از ارائه‌دهنده",
   "Health Check Url": "آدرس بررسی سلامت",
+  "Expected Status": "وضعیت مورد انتظار",
   "Interval": "فاصله زمانی",
   "Lazy": "تنبل",
   "Timeout": "زمان قطع",
@@ -122,9 +129,10 @@
   "Include All Proxies": "شامل همه پروکسی‌ها",
   "Exclude Filter": "فیلتر استثناء",
   "Exclude Type": "نوع استثناء",
-  "Expected Status": "وضعیت مورد انتظار",
   "Disable UDP": "غیرفعال کردن UDP",
   "Hidden": "مخفی",
+  "Group Name Required": "نام گروه مورد نیاز است",
+  "Group Name Already Exists": "نام گروه قبلا وجود دارد",
   "Extend Config": "توسعه پیکربندی",
   "Extend Script": "ادغام اسکریپت",
   "Global Merge": "تنظیمات گسترده‌ی سراسری",

+ 10 - 2
src/locales/ru.json

@@ -1,5 +1,6 @@
 {
   "millis": "миллисекунды",
+  "seconds": "секунды",
   "mins": "минуты",
   "Back": "Назад",
   "Close": "Закрыть",
@@ -54,7 +55,7 @@
   "Create Profile": "Создать профиль",
   "Edit Profile": "Изменить профиль",
   "Edit Proxies": "Редактировать прокси",
-  "Use newlines for multiple uri": "Используйте новые строки для нескольких URI",
+  "Use newlines for multiple uri": "Используйте символы новой строки для нескольких URI (поддерживается кодировка Base64)",
   "Edit Rules": "Редактировать правила",
   "Rule Type": "Тип правила",
   "Rule Content": "Содержимое правила",
@@ -107,10 +108,16 @@
   "PASS": "Пропускает это правило при совпадении",
   "Edit Groups": "Редактировать группы прокси",
   "Group Type": "Тип группы",
+  "select": "Выбор прокси вручную",
+  "url-test": "Выбор прокси на основе задержки теста URL",
+  "fallback": "Переключение на другой прокси при ошибке",
+  "load-balance": "Распределение прокси на основе балансировки нагрузки",
+  "relay": "Передача через определенную цепочку прокси",
   "Group Name": "Имя группы",
   "Use Proxies": "Использовать прокси",
   "Use Provider": "Использовать провайдера",
   "Health Check Url": "URL проверки здоровья",
+  "Expected Status": "Ожидаемый статус",
   "Interval": "Интервал",
   "Lazy": "Ленивый",
   "Timeout": "Таймаут",
@@ -122,9 +129,10 @@
   "Include All Proxies": "Включить все прокси",
   "Exclude Filter": "Исключить фильтр",
   "Exclude Type": "Тип исключения",
-  "Expected Status": "Ожидаемый статус",
   "Disable UDP": "Отключить UDP",
   "Hidden": "Скрытый",
+  "Group Name Required": "Требуется имя группы",
+  "Group Name Already Exists": "Имя группы уже существует",
   "Extend Config": "Изменить Merge.",
   "Extend Script": "Изменить Script",
   "Global Merge": "Глобальный расширенный Настройки",

+ 12 - 4
src/locales/zh.json

@@ -1,6 +1,7 @@
 {
   "millis": "毫秒",
   "mins": "分钟",
+  "seconds": "秒",
   "Back": "返回",
   "Close": "关闭",
   "Cancel": "取消",
@@ -54,7 +55,7 @@
   "Create Profile": "新建配置",
   "Edit Profile": "编辑配置",
   "Edit Proxies": "编辑节点",
-  "Use newlines for multiple uri": "多条URI请使用换行分隔",
+  "Use newlines for multiple uri": "多条URI请使用换行分隔(支持Base64编码)",
   "Edit Rules": "编辑规则",
   "Rule Type": "规则类型",
   "Rule Content": "规则内容",
@@ -109,25 +110,32 @@
   "PASS": "跳过此规则",
   "Edit Groups": "编辑代理组",
   "Group Type": "代理组类型",
+  "select": "手动选择代理",
+  "url-test": "根据URL测试延迟选择代理",
+  "fallback": "不可用时切换到另一个代理",
+  "load-balance": "根据负载均衡分配代理",
+  "relay": "根据定义的代理链传递",
   "Group Name": "代理组组名",
   "Use Proxies": "引入代理",
   "Use Provider": "引入代理集合",
   "Health Check Url": "健康检查测试地址",
+  "Expected Status": "期望状态码",
   "Interval": "检查间隔",
   "Lazy": "懒惰状态",
   "Timeout": "超时时间",
   "Max Failed Times": "最大失败次数",
   "Interface Name": "出站接口",
   "Routing Mark": "路由标记",
-  "Include All": "引入所有出站代理以及代理集合",
+  "Include All": "引入所有出站代理代理集合",
   "Include All Providers": "引入所有代理集合",
   "Include All Proxies": "引入所有出站代理",
   "Exclude Filter": "排除节点",
   "Exclude Type": "排除节点类型",
-  "Expected Status": "期望状态码",
   "Disable UDP": "禁用UDP",
-  "Hidden": "隐藏组",
+  "Hidden": "隐藏代理组",
   "Extend Config": "扩展配置",
+  "Group Name Required": "代理组名称不能为空",
+  "Group Name Already Exists": "代理组名称已存在",
   "Extend Script": "扩展脚本",
   "Global Merge": "全局扩展配置",
   "Global Script": "全局扩展脚本",