feat: add Thai translations for i18n

This commit is contained in:
codytseng
2025-06-24 23:17:07 +08:00
parent 2121ca7556
commit 2298254903
3 changed files with 295 additions and 8 deletions

View File

@@ -49,16 +49,23 @@ export default function TranslateButton({
return false return false
} }
const hasChinese = /[\u4e00-\u9fff]/.test(cleanText) if (/[\u3040-\u309f\u30a0-\u30ff]/.test(cleanText)) {
const hasJapanese = /[\u3040-\u309f\u30a0-\u30ff]/.test(cleanText) return i18n.language !== 'ja'
const hasArabic = /[\u0600-\u06ff]/.test(cleanText) }
const hasRussian = /[\u0400-\u04ff]/.test(cleanText) 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 (/[\u0600-\u06ff]/.test(cleanText)) {
if (hasChinese && !hasJapanese) return i18n.language !== 'zh' return i18n.language !== 'ar'
}
if (hasArabic) return i18n.language !== 'ar' if (/[\u0400-\u04ff]/.test(cleanText)) {
if (hasRussian) return i18n.language !== 'ru' return i18n.language !== 'ru'
}
try { try {
const detectedLang = franc(cleanText) const detectedLang = franc(cleanText)

View File

@@ -13,6 +13,7 @@ import pl from './locales/pl'
import pt_BR from './locales/pt-BR' import pt_BR from './locales/pt-BR'
import pt_PT from './locales/pt-PT' import pt_PT from './locales/pt-PT'
import ru from './locales/ru' import ru from './locales/ru'
import th from './locales/th'
import zh from './locales/zh' import zh from './locales/zh'
const languages = { const languages = {
@@ -27,6 +28,7 @@ const languages = {
'pt-BR': { resource: pt_BR, name: 'Português (Brasil)' }, 'pt-BR': { resource: pt_BR, name: 'Português (Brasil)' },
'pt-PT': { resource: pt_PT, name: 'Português (Portugal)' }, 'pt-PT': { resource: pt_PT, name: 'Português (Portugal)' },
ru: { resource: ru, name: 'Русский' }, ru: { resource: ru, name: 'Русский' },
th: { resource: th, name: 'ไทย' },
zh: { resource: zh, name: '简体中文' } zh: { resource: zh, name: '简体中文' }
} as const } as const
@@ -73,6 +75,7 @@ i18n.services.formatter?.add('date', (timestamp, lng) => {
case 'pt-BR': case 'pt-BR':
case 'pt-PT': case 'pt-PT':
case 'ar': case 'ar':
case 'th':
return dayjs(timestamp).format('DD/MM/YYYY') return dayjs(timestamp).format('DD/MM/YYYY')
default: default:
return dayjs(timestamp).format('MMM D, YYYY') return dayjs(timestamp).format('MMM D, YYYY')

277
src/i18n/locales/th.ts Normal file
View File

@@ -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: 'ดำเนินการต่อ'
}
}