i18n(panel): translate Copy/Cancel buttons, Stream/Sniffing tabs, and All-Inbounds filenames
Some checks are pending
CI / go-test (push) Waiting to run
CI / govulncheck (push) Waiting to run
CI / frontend (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (push) Waiting to run

- TextModal: route the Copy button label and the post-copy toast
  through t('copy')/t('copied') instead of hardcoded English.
- PromptModal: route cancelText through t('cancel') and default okText
  through t('confirm') so the import-inbound prompt stops showing
  "Cancel" in non-English UI.
- InboundsPage: pass the All-Inbounds and All-Inbounds-Subs download
  filenames through t(...) so each locale can localize them.
- en-US.json: add pages.inbounds.exportAllLinksFileName and
  pages.inbounds.exportAllSubsFileName.
- All 12 non-English locales: translate streamTab and sniffingTab
  (previously left as literal English) and add the two new filename
  keys with appropriate translations.

All 13 locale files now have 1541 lines.
This commit is contained in:
MHSanaei 2026-05-28 18:45:59 +02:00
parent bee8288d41
commit c5b5606bf5
No known key found for this signature in database
GPG key ID: 7E4060F2FBE5AB7A
16 changed files with 60 additions and 30 deletions

View file

@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from 'react';
import { Input, Modal } from 'antd';
import type { InputRef } from 'antd';
import { useTranslation } from 'react-i18next';
interface PromptModalProps {
open: boolean;
@ -17,12 +18,13 @@ export default function PromptModal({
open,
onClose,
title,
okText = 'OK',
okText,
type = 'input',
initialValue = '',
loading = false,
onConfirm,
}: PromptModalProps) {
const { t } = useTranslation();
const [value, setValue] = useState('');
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
const inputRef = useRef<InputRef | null>(null);
@ -53,8 +55,8 @@ export default function PromptModal({
<Modal
open={open}
title={title}
okText={okText}
cancelText="Cancel"
okText={okText ?? t('confirm')}
cancelText={t('cancel')}
mask={{ closable: false }}
confirmLoading={loading}
onOk={() => onConfirm(value)}

View file

@ -1,5 +1,6 @@
import { Button, Input, Modal, message } from 'antd';
import { CopyOutlined, DownloadOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
import { ClipboardManager, FileManager } from '@/utils';
@ -12,11 +13,12 @@ interface TextModalProps {
}
export default function TextModal({ open, onClose, title, content, fileName = '' }: TextModalProps) {
const { t } = useTranslation();
const [messageApi, messageContextHolder] = message.useMessage();
async function copy() {
const ok = await ClipboardManager.copyText(content || '');
if (ok) {
messageApi.success('Copied');
messageApi.success(t('copied'));
onClose();
}
}
@ -39,7 +41,7 @@ export default function TextModal({ open, onClose, title, content, fileName = ''
{fileName && (
<Button icon={<DownloadOutlined />} onClick={download}>{fileName}</Button>
)}
<Button type="primary" icon={<CopyOutlined />} onClick={copy}>Copy</Button>
<Button type="primary" icon={<CopyOutlined />} onClick={copy}>{t('copy')}</Button>
</>
)}
>

View file

@ -294,7 +294,7 @@ export default function InboundsPage() {
fallbackHostname: window.location.hostname,
}));
}
openText({ title: t('pages.inbounds.exportAllLinksTitle'), content: out.join('\r\n'), fileName: 'All-Inbounds' });
openText({ title: t('pages.inbounds.exportAllLinksTitle'), content: out.join('\r\n'), fileName: t('pages.inbounds.exportAllLinksFileName') });
}, [dbInbounds, hydrateInbound, checkFallback, remarkModel, hostOverrideFor, openText, t]);
const exportAllSubs = useCallback(async () => {
@ -311,7 +311,7 @@ export default function InboundsPage() {
}
}
}
openText({ title: t('pages.inbounds.exportAllSubsTitle'), content: [...new Set(out)].join('\r\n'), fileName: 'All-Inbounds-Subs' });
openText({ title: t('pages.inbounds.exportAllSubsTitle'), content: [...new Set(out)].join('\r\n'), fileName: t('pages.inbounds.exportAllSubsFileName') });
}, [dbInbounds, hydrateInbound, subSettings, openText, t]);
const importInbound = useCallback(() => {

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "تصدير روابط الاشتراك",
"exportAllLinksTitle": "تصدير كل روابط الإدخالات",
"exportAllSubsTitle": "تصدير كل روابط الاشتراكات",
"exportAllLinksFileName": "جميع-الواردات",
"exportAllSubsFileName": "جميع-الواردات-Subs",
"inboundJsonTitle": "JSON الوارد",
"deleteClient": "حذف العميل",
"deleteClientContent": "متأكد إنك عايز تحذف العميل؟",
@ -368,9 +370,9 @@
"IPLimitlogclear": "امسح السجل",
"setDefaultCert": "استخدم شهادة البانل",
"setDefaultCertEmpty": "لا توجد شهادة معدّة للوحة. عينّ واحدة من الإعدادات أولاً.",
"streamTab": "Stream",
"streamTab": "تدفق",
"securityTab": "الأمان",
"sniffingTab": "Sniffing",
"sniffingTab": "تنصت",
"sniffingMetadataOnly": "البيانات الوصفية فقط",
"sniffingRouteOnly": "التوجيه فقط",
"sniffingIpsExcluded": "IP المستثناة",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Export subscription links",
"exportAllLinksTitle": "Export all inbound links",
"exportAllSubsTitle": "Export all subscription links",
"exportAllLinksFileName": "All-Inbounds",
"exportAllSubsFileName": "All-Inbounds-Subs",
"inboundJsonTitle": "Inbound JSON",
"deleteClient": "Delete Client",
"deleteClientContent": "Are you sure you want to delete this client?",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Exportar enlaces de suscripción",
"exportAllLinksTitle": "Exportar todos los enlaces de inbound",
"exportAllSubsTitle": "Exportar todos los enlaces de suscripción",
"exportAllLinksFileName": "Todas-las-entradas",
"exportAllSubsFileName": "Todas-las-entradas-Subs",
"inboundJsonTitle": "JSON de entrada",
"deleteClient": "Eliminar cliente",
"deleteClientContent": "¿Está seguro de que desea eliminar el cliente?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "Limpiar el Registro",
"setDefaultCert": "Establecer certificado desde el panel",
"setDefaultCertEmpty": "No hay certificado configurado para el panel. Configura uno en Ajustes primero.",
"streamTab": "Stream",
"streamTab": "Transmisión",
"securityTab": "Seguridad",
"sniffingTab": "Sniffing",
"sniffingTab": "Inspección",
"sniffingMetadataOnly": "Solo metadatos",
"sniffingRouteOnly": "Solo enrutamiento",
"sniffingIpsExcluded": "IPs excluidas",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "خروجی لینک‌های ساب",
"exportAllLinksTitle": "خروجی لینک‌های همه اینباندها",
"exportAllSubsTitle": "خروجی لینک‌های ساب همه اینباندها",
"exportAllLinksFileName": "همه-ورودی‌ها",
"exportAllSubsFileName": "همه-ورودی‌ها-Subs",
"inboundJsonTitle": "JSON ورودی",
"deleteClient": "حذف کاربر",
"deleteClientContent": "آیا مطمئن به حذف کاربر هستید؟",
@ -368,9 +370,9 @@
"IPLimitlogclear": "پاک کردن گزارش‌ها",
"setDefaultCert": "استفاده از گواهی پنل",
"setDefaultCertEmpty": "هیچ گواهی‌ای برای پنل پیکربندی نشده. ابتدا از تنظیمات یکی تعیین کنید.",
"streamTab": "Stream",
"streamTab": "انتقال",
"securityTab": "امنیت",
"sniffingTab": "Sniffing",
"sniffingTab": "شنود",
"sniffingMetadataOnly": "فقط متادیتا",
"sniffingRouteOnly": "فقط مسیریابی",
"sniffingIpsExcluded": "IPهای مستثنا",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Ekspor tautan langganan",
"exportAllLinksTitle": "Ekspor semua tautan inbound",
"exportAllSubsTitle": "Ekspor semua tautan langganan",
"exportAllLinksFileName": "Semua-Inbound",
"exportAllSubsFileName": "Semua-Inbound-Subs",
"inboundJsonTitle": "JSON inbound",
"deleteClient": "Hapus Klien",
"deleteClientContent": "Apakah Anda yakin ingin menghapus klien?",
@ -368,7 +370,7 @@
"IPLimitlogclear": "Hapus Log",
"setDefaultCert": "Atur Sertifikat dari Panel",
"setDefaultCertEmpty": "Tidak ada sertifikat yang dikonfigurasi untuk panel. Atur dulu di Pengaturan.",
"streamTab": "Stream",
"streamTab": "Aliran",
"securityTab": "Keamanan",
"sniffingTab": "Sniffing",
"sniffingMetadataOnly": "Hanya metadata",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "サブスクリプションリンクのエクスポート",
"exportAllLinksTitle": "全インバウンドリンクのエクスポート",
"exportAllSubsTitle": "全サブスクリプションリンクのエクスポート",
"exportAllLinksFileName": "全インバウンド",
"exportAllSubsFileName": "全インバウンド-Subs",
"inboundJsonTitle": "インバウンド JSON",
"deleteClient": "クライアント削除",
"deleteClientContent": "クライアントを削除してもよろしいですか?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "ログをクリア",
"setDefaultCert": "パネル設定から証明書を設定",
"setDefaultCertEmpty": "パネル用の証明書が設定されていません。先に設定から指定してください。",
"streamTab": "Stream",
"streamTab": "ストリーム",
"securityTab": "セキュリティ",
"sniffingTab": "Sniffing",
"sniffingTab": "スニッフィング",
"sniffingMetadataOnly": "メタデータのみ",
"sniffingRouteOnly": "ルーティングのみ",
"sniffingIpsExcluded": "除外する IP",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Exportar links de assinatura",
"exportAllLinksTitle": "Exportar todos os links de inbound",
"exportAllSubsTitle": "Exportar todos os links de assinatura",
"exportAllLinksFileName": "Todas-as-entradas",
"exportAllSubsFileName": "Todas-as-entradas-Subs",
"inboundJsonTitle": "JSON da entrada",
"deleteClient": "Excluir Cliente",
"deleteClientContent": "Tem certeza de que deseja excluir o cliente?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "Limpar o Log",
"setDefaultCert": "Definir Certificado pelo Painel",
"setDefaultCertEmpty": "Nenhum certificado configurado para o painel. Configure um em Configurações primeiro.",
"streamTab": "Stream",
"streamTab": "Transmissão",
"securityTab": "Segurança",
"sniffingTab": "Sniffing",
"sniffingTab": "Inspeção",
"sniffingMetadataOnly": "Apenas metadados",
"sniffingRouteOnly": "Apenas roteamento",
"sniffingIpsExcluded": "IPs excluídos",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Экспортировать ссылки подписки",
"exportAllLinksTitle": "Экспортировать все ссылки подключений",
"exportAllSubsTitle": "Экспортировать все ссылки подписок",
"exportAllLinksFileName": "Все-входящие",
"exportAllSubsFileName": "Все-входящие-Subs",
"inboundJsonTitle": "JSON входящего",
"deleteClient": "Удалить клиента",
"deleteClientContent": "Вы уверены, что хотите удалить клиента?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "Очистить лог",
"setDefaultCert": "Установить сертификат панели",
"setDefaultCertEmpty": "Для панели не настроен сертификат. Сначала установите его в Настройках.",
"streamTab": "Stream",
"streamTab": "Поток",
"securityTab": "Безопасность",
"sniffingTab": "Sniffing",
"sniffingTab": "Сниффинг",
"sniffingMetadataOnly": "Только метаданные",
"sniffingRouteOnly": "Только маршрутизация",
"sniffingIpsExcluded": "Исключённые IP",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Abonelik bağlantılarını dışa aktar",
"exportAllLinksTitle": "Tüm inbound bağlantılarını dışa aktar",
"exportAllSubsTitle": "Tüm abonelik bağlantılarını dışa aktar",
"exportAllLinksFileName": "Tum-Gelenler",
"exportAllSubsFileName": "Tum-Gelenler-Subs",
"inboundJsonTitle": "Gelen JSON",
"deleteClient": "Müşteriyi Sil",
"deleteClientContent": "Müşteriyi silmek istediğinizden emin misiniz?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "Günlüğü Temizle",
"setDefaultCert": "Panelden Sertifikayı Ayarla",
"setDefaultCertEmpty": "Panel için sertifika yapılandırılmamış. Önce Ayarlar'dan ayarlayın.",
"streamTab": "Stream",
"streamTab": "Akış",
"securityTab": "Güvenlik",
"sniffingTab": "Sniffing",
"sniffingTab": "Dinleme",
"sniffingMetadataOnly": "Yalnızca üst veri",
"sniffingRouteOnly": "Yalnızca yönlendirme",
"sniffingIpsExcluded": "Hariç tutulan IP'ler",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Експортувати посилання підписок",
"exportAllLinksTitle": "Експортувати всі посилання вхідних",
"exportAllSubsTitle": "Експортувати всі посилання підписок",
"exportAllLinksFileName": "Усі-вхідні",
"exportAllSubsFileName": "Усі-вхідні-Subs",
"inboundJsonTitle": "JSON вхідного",
"deleteClient": "Видалити клієнта",
"deleteClientContent": "Ви впевнені, що хочете видалити клієнт?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "Очистити журнал",
"setDefaultCert": "Установити сертифікат з панелі",
"setDefaultCertEmpty": "Для панелі не налаштовано сертифікат. Спочатку встановіть його в Налаштуваннях.",
"streamTab": "Stream",
"streamTab": "Потік",
"securityTab": "Безпека",
"sniffingTab": "Sniffing",
"sniffingTab": "Сніфінг",
"sniffingMetadataOnly": "Лише метадані",
"sniffingRouteOnly": "Лише маршрутизація",
"sniffingIpsExcluded": "Виключені IP",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "Xuất liên kết đăng ký",
"exportAllLinksTitle": "Xuất tất cả liên kết inbound",
"exportAllSubsTitle": "Xuất tất cả liên kết đăng ký",
"exportAllLinksFileName": "Tat-ca-Inbound",
"exportAllSubsFileName": "Tat-ca-Inbound-Subs",
"inboundJsonTitle": "JSON inbound",
"deleteClient": "Xóa người dùng",
"deleteClientContent": "Bạn có chắc chắn muốn xóa người dùng không?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "Xóa Lịch sử",
"setDefaultCert": "Đặt chứng chỉ từ bảng điều khiển",
"setDefaultCertEmpty": "Không có chứng chỉ nào được cấu hình cho bảng điều khiển. Hãy đặt một chứng chỉ trong Cài đặt trước.",
"streamTab": "Stream",
"streamTab": "Luồng",
"securityTab": "Bảo mật",
"sniffingTab": "Sniffing",
"sniffingTab": "Dò gói",
"sniffingMetadataOnly": "Chỉ siêu dữ liệu",
"sniffingRouteOnly": "Chỉ định tuyến",
"sniffingIpsExcluded": "IP bị loại trừ",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "导出订阅链接",
"exportAllLinksTitle": "导出所有入站链接",
"exportAllSubsTitle": "导出所有订阅链接",
"exportAllLinksFileName": "所有入站",
"exportAllSubsFileName": "所有入站-Subs",
"inboundJsonTitle": "入站 JSON",
"deleteClient": "删除客户端",
"deleteClientContent": "确定要删除客户端吗?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "清除日志",
"setDefaultCert": "从面板设置证书",
"setDefaultCertEmpty": "面板尚未配置证书。请先在“设置”中设置。",
"streamTab": "Stream",
"streamTab": "传输",
"securityTab": "安全",
"sniffingTab": "Sniffing",
"sniffingTab": "嗅探",
"sniffingMetadataOnly": "仅元数据",
"sniffingRouteOnly": "仅路由",
"sniffingIpsExcluded": "排除的 IP",

View file

@ -322,6 +322,8 @@
"exportSubsTitle": "匯出訂閱連結",
"exportAllLinksTitle": "匯出所有入站連結",
"exportAllSubsTitle": "匯出所有訂閱連結",
"exportAllLinksFileName": "所有入站",
"exportAllSubsFileName": "所有入站-Subs",
"inboundJsonTitle": "入站 JSON",
"deleteClient": "刪除客戶端",
"deleteClientContent": "確定要刪除客戶端嗎?",
@ -368,9 +370,9 @@
"IPLimitlogclear": "清除日誌",
"setDefaultCert": "從面板設定證書",
"setDefaultCertEmpty": "面板尚未設定憑證。請先在「設定」中設定。",
"streamTab": "Stream",
"streamTab": "傳輸",
"securityTab": "安全",
"sniffingTab": "Sniffing",
"sniffingTab": "嗅探",
"sniffingMetadataOnly": "僅中繼資料",
"sniffingRouteOnly": "僅路由",
"sniffingIpsExcluded": "排除的 IP",