diff --git a/src/components/TranslateButton/index.tsx b/src/components/TranslateButton/index.tsx index 7c95788e..20a486fd 100644 --- a/src/components/TranslateButton/index.tsx +++ b/src/components/TranslateButton/index.tsx @@ -49,16 +49,23 @@ export default function TranslateButton({ return false } - const hasChinese = /[\u4e00-\u9fff]/.test(cleanText) - const hasJapanese = /[\u3040-\u309f\u30a0-\u30ff]/.test(cleanText) - const hasArabic = /[\u0600-\u06ff]/.test(cleanText) - const hasRussian = /[\u0400-\u04ff]/.test(cleanText) + if (/[\u3040-\u309f\u30a0-\u30ff]/.test(cleanText)) { + return i18n.language !== 'ja' + } + if (/[\u0e00-\u0e7f]/.test(cleanText)) { + return i18n.language !== 'th' + } + if (/[\u4e00-\u9fff]/.test(cleanText)) { + return i18n.language !== 'zh' + } - if (hasJapanese) return i18n.language !== 'ja' - if (hasChinese && !hasJapanese) return i18n.language !== 'zh' + if (/[\u0600-\u06ff]/.test(cleanText)) { + return i18n.language !== 'ar' + } - if (hasArabic) return i18n.language !== 'ar' - if (hasRussian) return i18n.language !== 'ru' + if (/[\u0400-\u04ff]/.test(cleanText)) { + return i18n.language !== 'ru' + } try { const detectedLang = franc(cleanText) diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 2a5ed5ac..92a3abd6 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -13,6 +13,7 @@ import pl from './locales/pl' import pt_BR from './locales/pt-BR' import pt_PT from './locales/pt-PT' import ru from './locales/ru' +import th from './locales/th' import zh from './locales/zh' const languages = { @@ -27,6 +28,7 @@ const languages = { 'pt-BR': { resource: pt_BR, name: 'Português (Brasil)' }, 'pt-PT': { resource: pt_PT, name: 'Português (Portugal)' }, ru: { resource: ru, name: 'Русский' }, + th: { resource: th, name: 'ไทย' }, zh: { resource: zh, name: '简体中文' } } as const @@ -73,6 +75,7 @@ i18n.services.formatter?.add('date', (timestamp, lng) => { case 'pt-BR': case 'pt-PT': case 'ar': + case 'th': return dayjs(timestamp).format('DD/MM/YYYY') default: return dayjs(timestamp).format('MMM D, YYYY') diff --git a/src/i18n/locales/th.ts b/src/i18n/locales/th.ts new file mode 100644 index 00000000..8b5b1198 --- /dev/null +++ b/src/i18n/locales/th.ts @@ -0,0 +1,277 @@ +export default { + translation: { + 'Welcome! 🥳': 'ยินดีต้อนรับ! 🥳', + About: 'เกี่ยวกับ', + 'New Note': 'โน้ตใหม่', + Post: 'โพสต์', + Home: 'หน้าหลัก', + 'Relay settings': 'การตั้งค่ารีเลย์', + Settings: 'การตั้งค่า', + SidebarRelays: 'รีเลย์', + Refresh: 'รีเฟรช', + Profile: 'โปรไฟล์', + Logout: 'ออกจากระบบ', + Following: 'กำลังติดตาม', + followings: 'กำลังติดตาม', + reposted: 'รีโพสต์', + 'just now': 'เมื่อสักครู่', + 'n minutes ago': '{{n}} นาทีที่แล้ว', + 'n m': '{{n}}น', + 'n hours ago': '{{n}} ชั่วโมงที่แล้ว', + 'n h': '{{n}}ชม', + 'n days ago': '{{n}} วันที่แล้ว', + 'n d': '{{n}}วัน', + date: '{{timestamp, date}}', + Follow: 'ติดตาม', + Unfollow: 'เลิกติดตาม', + 'Follow failed': 'ติดตามไม่สำเร็จ', + 'Unfollow failed': 'เลิกติดตามไม่สำเร็จ', + 'show new notes': 'แสดงโน้ตใหม่', + 'loading...': 'กำลังโหลด...', + 'no more notes': 'ไม่มีโน้ตเพิ่มเติม', + 'reply to': 'ตอบกลับถึง', + reply: 'ตอบกลับ', + Reply: 'ตอบกลับ', + 'load more older replies': 'โหลดการตอบกลับเพิ่มเติม', + 'Write something...': 'เขียนอะไรบางอย่าง...', + Cancel: 'ยกเลิก', + Mentions: 'การกล่าวถึง', + 'Failed to post': 'โพสต์ไม่สำเร็จ', + 'Post successful': 'โพสต์สำเร็จ', + 'Your post has been published': 'โพสต์ของคุณถูกเผยแพร่แล้ว', + Repost: 'รีโพสต์', + Quote: 'อ้างอิง', + 'Copy event ID': 'คัดลอก ID เหตุการณ์', + 'Copy user ID': 'คัดลอก ID ผู้ใช้', + 'View raw event': 'ดูเหตุการณ์ดิบ', + Like: 'ถูกใจ', + 'switch to light theme': 'เปลี่ยนเป็นธีมสว่าง', + 'switch to dark theme': 'เปลี่ยนเป็นธีมมืด', + 'switch to system theme': 'เปลี่ยนเป็นธีมระบบ', + Note: 'โน้ต', + note: 'โน้ต', + "username's following": 'ผู้ที่ {{username}} กำลังติดตาม', + "username's used relays": 'รีเลย์ที่ {{username}} ใช้งาน', + "username's muted": 'ผู้ที่ {{username}} ปิดเสียง', + Login: 'เข้าสู่ระบบ', + 'Follows you': 'ติดตามคุณ', + 'Relay Settings': 'การตั้งค่ารีเลย์', + 'Relay set name': 'ชื่อชุดรีเลย์', + 'Add a new relay set': 'เพิ่มชุดรีเลย์ใหม่', + Add: 'เพิ่ม', + 'n relays': '{{n}} รีเลย์', + Rename: 'เปลี่ยนชื่อ', + 'Copy share link': 'คัดลอกลิงก์แชร์', + Delete: 'ลบ', + 'Relay already exists': 'รีเลย์มีอยู่แล้ว', + 'invalid relay URL': 'URL รีเลย์ไม่ถูกต้อง', + 'Add a new relay': 'เพิ่มรีเลย์ใหม่', + back: 'ย้อนกลับ', + 'Lost in the void': 'หลงอยู่ในความว่างเปล่า', + 'Carry me home': 'พาฉันกลับบ้าน', + 'no replies': 'ไม่มีการตอบกลับ', + 'Reply to': 'ตอบกลับถึง', + Search: 'ค้นหา', + 'The relays you are connected to do not support search': + 'รีเลย์ที่คุณเชื่อมต่อไม่รองรับการค้นหา', + 'Show more...': 'แสดงเพิ่มเติม...', + 'All users': 'ผู้ใช้ทั้งหมด', + 'Display replies': 'แสดงการตอบกลับ', + Notes: 'โน้ต', + Replies: 'การตอบกลับ', + Notifications: 'การแจ้งเตือน', + 'no more notifications': 'ไม่มีการแจ้งเตือนเพิ่มเติม', + 'Using private key login is insecure. It is recommended to use a browser extension for login, such as alby, nostr-keyx or nos2x.': + 'การเข้าสู่ระบบด้วยคีย์ส่วนตัวไม่ปลอดภัย แนะนำให้ใช้ส่วนขยายเบราว์เซอร์ เช่น alby, nostr-keyx หรือ nos2x', + 'Login with Browser Extension': 'เข้าสู่ระบบด้วยส่วนขยายเบราว์เซอร์', + 'Login with Bunker': 'เข้าสู่ระบบด้วย Bunker', + 'Login with Private Key': 'เข้าสู่ระบบด้วยคีย์ส่วนตัว', + 'reload notes': 'โหลดโน้ตใหม่', + 'Logged in Accounts': 'บัญชีที่เข้าสู่ระบบ', + 'Add an Account': 'เพิ่มบัญชี', + 'More options': 'ตัวเลือกเพิ่มเติม', + 'Add client tag': 'เพิ่มแท็กไคลเอนต์', + 'Show others this was sent via Jumble': 'แสดงให้ผู้อื่นเห็นว่าส่งผ่าน Jumble', + 'Are you sure you want to logout?': 'คุณแน่ใจหรือไม่ว่าต้องการออกจากระบบ?', + 'relay sets': 'ชุดรีเลย์', + edit: 'แก้ไข', + Languages: 'ภาษา', + Theme: 'ธีม', + System: 'ระบบ', + Light: 'สว่าง', + Dark: 'มืด', + Temporary: 'ชั่วคราว', + 'Choose a relay set': 'เลือกชุดรีเลย์', + 'Switch account': 'สลับบัญชี', + Pictures: 'รูปภาพ', + 'Picture note': 'โน้ตรูปภาพ', + 'A special note for picture-first clients like Olas': + 'หมายเหตุพิเศษสำหรับไคลเอนต์ที่เน้นรูปภาพเช่น Olas', + 'Picture note requires images': 'โน้ตรูปภาพต้องมีรูปภาพ', + Relays: 'รีเลย์', + image: 'รูปภาพ', + 'R & W': 'อ่าน & เขียน', + Read: 'อ่าน', + Write: 'เขียน', + 'Pull relay sets': 'ดึงชุดรีเลย์', + 'Select the relay sets you want to pull': 'เลือกชุดรีเลย์ที่ต้องการดึง', + 'No relay sets found': 'ไม่พบชุดรีเลย์', + 'Pull n relay sets': 'ดึงชุดรีเลย์ {{n}} ชุด', + Pull: 'ดึง', + 'Select all': 'เลือกทั้งหมด', + 'Relay Sets': 'ชุดรีเลย์', + 'Read & Write Relays': 'รีเลย์อ่านและเขียน', + 'read relays description': + 'รีเลย์อ่านใช้สำหรับค้นหาเหตุการณ์เกี่ยวกับคุณ ผู้ใช้อื่นจะเผยแพร่เหตุการณ์ที่ต้องการให้คุณเห็นไปยังรีเลย์อ่านของคุณ', + 'write relays description': + 'รีเลย์เขียนใช้สำหรับเผยแพร่เหตุการณ์ของคุณ ผู้ใช้อื่นจะค้นหาเหตุการณ์ของคุณจากรีเลย์เขียนของคุณ', + 'read & write relays notice': 'จำนวนเซิร์ฟเวอร์อ่านและเขียนควรอยู่ระหว่าง 2 ถึง 4', + "Don't have an account yet?": 'ยังไม่มีบัญชี?', + 'or simply generate a private key': 'หรือสร้างคีย์ส่วนตัว', + 'This is a private key. Do not share it with anyone. Keep it safe and secure. You will not be able to recover it if you lose it.': + 'นี่คือคีย์ส่วนตัว อย่าแบ่งปันกับใคร เก็บไว้ให้ปลอดภัย หากสูญหายจะไม่สามารถกู้คืนได้', + Edit: 'แก้ไข', + Save: 'บันทึก', + 'Display Name': 'ชื่อที่แสดง', + Bio: 'ประวัติ', + 'Nostr Address (NIP-05)': 'ที่อยู่ Nostr (NIP-05)', + 'Invalid NIP-05 address': 'ที่อยู่ NIP-05 ไม่ถูกต้อง', + 'Copy private key': 'คัดลอกคีย์ส่วนตัว', + 'Enter the password to decrypt your ncryptsec': 'กรอกรหัสผ่านเพื่อถอดรหัส ncryptsec ของคุณ', + Back: 'ย้อนกลับ', + 'optional: encrypt nsec': 'ตัวเลือก: เข้ารหัส nsec', + password: 'รหัสผ่าน', + 'Sign up': 'สมัครสมาชิก', + 'Save to': 'บันทึกไปที่', + 'Enter a name for the new relay set': 'กรอกชื่อชุดรีเลย์ใหม่', + 'Save to a new relay set': 'บันทึกไปยังชุดรีเลย์ใหม่', + Mute: 'ปิดเสียง', + Muted: 'ปิดเสียงแล้ว', + Unmute: 'ยกเลิกปิดเสียง', + 'Unmute user': 'ยกเลิกปิดเสียงผู้ใช้', + 'Append n relays': 'เพิ่มรีเลย์ {{n}}', + Append: 'เพิ่ม', + 'Select relays to append': 'เลือกรีเลย์ที่จะเพิ่ม', + 'calculating...': 'กำลังคำนวณ...', + 'Calculate optimal read relays': 'คำนวณรีเลย์อ่านที่เหมาะสม', + 'Login to set': 'เข้าสู่ระบบเพื่อกำหนด', + 'Please login to view following feed': 'กรุณาเข้าสู่ระบบเพื่อดูฟีดที่ติดตาม', + 'Send only to r': 'ส่งเฉพาะไปยัง {{r}}', + 'Send only to these relays': 'ส่งเฉพาะไปยังรีเลย์เหล่านี้', + Explore: 'สำรวจ', + 'Search relays': 'ค้นหารีเลย์', + relayInfoBadgeAuth: 'ยืนยันตัวตน', + relayInfoBadgeSearch: 'ค้นหา', + relayInfoBadgePayment: 'ชำระเงิน', + Operator: 'ผู้ดำเนินการ', + Contact: 'ติดต่อ', + Software: 'ซอฟต์แวร์', + Version: 'เวอร์ชัน', + 'Random Relays': 'รีเลย์สุ่ม', + randomRelaysRefresh: 'รีเฟรช', + 'Explore more': 'สำรวจเพิ่มเติม', + 'Payment page': 'หน้าชำระเงิน', + 'Supported NIPs': 'NIP ที่รองรับ', + 'Open in a': 'เปิดใน {{a}}', + 'Cannot handle event of kind k': 'ไม่สามารถจัดการเหตุการณ์ประเภท {{k}}', + 'Sorry! The note cannot be found 😔': 'ขออภัย! ไม่พบโน้ต 😔', + 'This user has been muted': 'ผู้ใช้นี้ถูกปิดเสียง', + Wallet: 'กระเป๋าสตางค์', + Sats: 'ซาตส์', + sats: 'ซาตส์', + 'Zap to': 'ส่งซาตส์ไปยัง', + 'Zap n sats': 'ส่ง {{n}} ซาตส์', + zapComment: 'ความคิดเห็น', + 'Default zap amount': 'จำนวนซาตส์เริ่มต้น', + 'Default zap comment': 'ความคิดเห็นเริ่มต้น', + 'Lightning Address (or LNURL)': 'ที่อยู่ Lightning (หรือ LNURL)', + 'Quick zap': 'ส่งซาตส์ด่วน', + 'If enabled, you can zap with a single click. Click and hold for custom amounts': + 'หากเปิดใช้งาน คุณสามารถส่งซาตส์ด้วยคลิกเดียว กดค้างเพื่อกำหนดจำนวนเอง', + All: 'ทั้งหมด', + Reactions: 'ปฏิกิริยา', + Zaps: 'ซาตส์', + 'Enjoying Jumble?': 'ชอบ Jumble ไหม?', + 'Your donation helps me maintain Jumble and make it better! 😊': + 'การบริจาคของคุณช่วยให้ฉันดูแลและพัฒนา Jumble ให้ดีขึ้น! 😊', + 'Earlier notifications': 'การแจ้งเตือนก่อนหน้า', + 'Temporarily display this note': 'แสดงโน้ตนี้ชั่วคราว', + buttonFollowing: 'กำลังติดตาม', + 'Are you sure you want to unfollow this user?': 'คุณแน่ใจหรือไม่ว่าต้องการเลิกติดตามผู้ใช้นี้?', + 'Recent Supporters': 'ผู้สนับสนุนล่าสุด', + 'Seen on': 'เห็นเมื่อ', + 'Temporarily display this reply': 'แสดงการตอบกลับนี้ชั่วคราว', + 'Not found the note': 'ไม่พบโน้ต', + 'no more replies': 'ไม่มีการตอบกลับเพิ่มเติม', + 'Relay sets': 'ชุดรีเลย์', + 'Favorite Relays': 'รีเลย์โปรด', + "Following's Favorites": 'รายการโปรดของผู้ที่ติดตาม', + 'no more relays': 'ไม่มีรีเลย์เพิ่มเติม', + 'Favorited by': 'ถูกเพิ่มเป็นรายการโปรดโดย', + 'Post settings': 'การตั้งค่าโพสต์', + 'Media upload service': 'บริการอัปโหลดสื่อ', + 'Choose a relay': 'เลือกรีเลย์', + 'no relays found': 'ไม่พบรีเลย์', + video: 'วิดีโอ', + 'Show n new notes': 'แสดงโน้ตใหม่ {{n}} รายการ', + YouTabName: 'คุณ', + Bookmark: 'บุ๊กมาร์ก', + 'Remove bookmark': 'ลบบุ๊กมาร์ก', + 'no bookmarks found': 'ไม่พบบุ๊กมาร์ก', + 'no more bookmarks': 'ไม่มีบุ๊กมาร์กเพิ่มเติม', + Bookmarks: 'บุ๊กมาร์ก', + 'Show more': 'แสดงเพิ่มเติม', + General: 'ทั่วไป', + Autoplay: 'เล่นอัตโนมัติ', + 'Enable video autoplay on this device': 'เปิดใช้งานเล่นวิดีโออัตโนมัติบนอุปกรณ์นี้', + 'Paste or drop media files to upload': 'วางหรือหย่อนไฟล์สื่อเพื่ออัปโหลด', + Preview: 'ดูตัวอย่าง', + 'You are about to publish an event signed by [{{eventAuthorName}}]. You are currently logged in as [{{currentUsername}}]. Are you sure?': + 'คุณกำลังจะเผยแพร่เหตุการณ์ที่ลงนามโดย [{{eventAuthorName}}] ขณะนี้คุณเข้าสู่ระบบเป็น [{{currentUsername}}] คุณแน่ใจหรือไม่?', + 'Platinum Sponsors': 'ผู้สนับสนุนระดับแพลตินัม', + From: 'จาก', + 'Comment on': 'แสดงความคิดเห็นใน', + 'View on njump.me': 'ดูบน njump.me', + 'Hide content from untrusted users': 'ซ่อนเนื้อหาจากผู้ใช้ที่ไม่น่าเชื่อถือ', + 'Only show content from your followed users and the users they follow': + 'แสดงเฉพาะเนื้อหาจากผู้ใช้ที่คุณติดตามและผู้ใช้ที่พวกเขาติดตาม', + 'Followed by': 'ติดตามโดย', + 'Mute user privately': 'ปิดเสียงผู้ใช้แบบส่วนตัว', + 'Mute user publicly': 'ปิดเสียงผู้ใช้แบบสาธารณะ', + Quotes: 'คำพูด', + 'Lightning Invoice': 'ใบแจ้งหนี้ Lightning', + 'Bookmark failed': 'บุ๊กมาร์กไม่สำเร็จ', + 'Remove bookmark failed': 'ลบบุ๊กมาร์กไม่สำเร็จ', + Translation: 'การแปล', + Balance: 'ยอดคงเหลือ', + characters: 'ตัวอักษร', + jumbleTranslateApiKeyDescription: + 'คุณสามารถใช้ API key นี้กับที่อื่นที่รองรับ LibreTranslate ที่อยู่บริการคือ {{serviceUrl}}', + 'Top up': 'เติมเงิน', + 'Will receive: {n} characters': 'จะได้รับ: {{n}} ตัวอักษร', + 'Top up {n} sats': 'เติมเงิน {{n}} ซาตส์', + 'Minimum top up is {n} sats': 'เติมเงินขั้นต่ำ {{n}} ซาตส์', + Service: 'บริการ', + 'Reset API key': 'รีเซ็ต API key', + 'Are you sure you want to reset your API key? This action cannot be undone.': + 'คุณแน่ใจหรือไม่ว่าต้องการรีเซ็ต API key? การกระทำนี้ไม่สามารถย้อนกลับได้', + Warning: 'คำเตือน', + 'Your current API key will become invalid immediately, and any applications using it will stop working until you update them with the new key.': + 'API key ปัจจุบันของคุณจะใช้ไม่ได้ทันที และแอปพลิเคชันที่ใช้งานจะหยุดทำงานจนกว่าคุณจะอัปเดตด้วยคีย์ใหม่', + 'Service address': 'ที่อยู่บริการ', + Pay: 'ชำระเงิน', + interactions: 'การโต้ตอบ', + notifications: 'การแจ้งเตือน', + 'Show untrusted {type}': 'แสดง {{type}} ที่ไม่น่าเชื่อถือ', + 'Hide untrusted {type}': 'ซ่อน {{type}} ที่ไม่น่าเชื่อถือ', + 'Currently hiding {type} from untrusted users.': + 'ขณะนี้กำลังซ่อน {{type}} จากผู้ใช้ที่ไม่น่าเชื่อถือ', + 'Currently showing all {type}.': 'ขณะนี้แสดง {{type}} ทั้งหมด', + 'Click continue to show all {type}.': 'คลิกดำเนินการต่อเพื่อแสดง {{type}} ทั้งหมด', + 'Click continue to hide {type} from untrusted users.': + 'คลิกดำเนินการต่อเพื่อซ่อน {{type}} จากผู้ใช้ที่ไม่น่าเชื่อถือ', + 'Trusted users include people you follow and people they follow.': + 'ผู้ใช้ที่เชื่อถือได้รวมถึงผู้ที่คุณติดตามและผู้ที่พวกเขาติดตาม', + Continue: 'ดำเนินการต่อ' + } +}