Add Vietnamese (vi-vn) localisation (#376)

* Add Vietnamese translations

* Update README with Vietnamese language

* Add missing hi-in language code to README
This commit is contained in:
Jason Quach 2026-02-16 01:09:14 +00:00 committed by GitHub
parent a63f2c3fe3
commit 87b181afbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 164 additions and 1 deletions

View File

@ -402,15 +402,17 @@ Partial internationalization (for non-admin, user-facing text) provided for a ha
- `bd-bn`
- `en-gb`
- `en-us`
- `hi-in`
- `id-id`
- `pt-br`
- `pt-pt`
- `tr-tr`
- `vi-vn`
- `zh-cn`
To add support for a new language, open a PR following instructions in [/src/i18n/index.ts](https://github.com/sambecker/exif-photo-blog/blob/main/src/i18n/index.ts), using [en-us.ts](https://github.com/sambecker/exif-photo-blog/blob/main/src/i18n/locales/en-us.ts) as reference.
Thank you ❤️ translators: [@sconetto](https://github.com/sconetto) (`pt-br`, `pt-pt`), [@brandnholl](https://github.com/brandnholl) (`id-id`), [@TongEc](https://github.com/TongEc) (`zh-cn`), [@xahidex](https://github.com/xahidex) (`bd-bn`, `hi-in`), [@mehmetabak](https://github.com/mehmetabak) (`tr-tr`), [@simondeeley](https://github.com/simondeeley) (`en-gb`)
Thank you ❤️ translators: [@sconetto](https://github.com/sconetto) (`pt-br`, `pt-pt`), [@brandnholl](https://github.com/brandnholl) (`id-id`), [@TongEc](https://github.com/TongEc) (`zh-cn`), [@xahidex](https://github.com/xahidex) (`bd-bn`, `hi-in`), [@mehmetabak](https://github.com/mehmetabak) (`tr-tr`), [@simondeeley](https://github.com/simondeeley) (`en-gb`), [@jasonquache](https://github.com/jasonquache) (`vi-vn`)
📖  FAQ
-

View File

@ -25,6 +25,7 @@ const LOCALE_TEXT_IMPORTS: Record<
'pt-br': () => import('./locales/pt-br').then(m => m.TEXT),
'pt-pt': () => import('./locales/pt-pt').then(m => m.TEXT),
'tr-tr': () => import('./locales/tr-tr').then(m => m.TEXT),
'vi-vn': () => import('./locales/vi-vn').then(m => m.TEXT),
'zh-cn': () => import('./locales/zh-cn').then(m => m.TEXT),
};

160
src/i18n/locales/vi-vn.ts Normal file
View File

@ -0,0 +1,160 @@
export { vi as default } from 'date-fns/locale/vi';
export const TEXT = {
photo: {
photo: 'Ảnh',
photoPlural: 'Ảnh',
taken: 'Chụp',
created: 'Tạo',
updated: 'Cập nhật',
copied: 'Đã sao chép liên kết',
},
category: {
camera: 'Máy ảnh',
cameraPlural: 'Máy ảnh',
cameraTitle: 'Chụp bằng {{camera}}',
cameraShare: 'Ảnh chụp bằng {{camera}}',
lens: 'Ống kính',
lensPlural: 'Ống kính',
album: 'Album',
albumPlural: 'Album',
tag: 'Thẻ',
tagPlural: 'Thẻ',
tagged: 'Được gắn thẻ',
taggedPhotos: 'Ảnh được gắn thẻ',
taggedPhrase: 'Ảnh được gắn thẻ {{tag}}',
taggedFavs: 'Ảnh yêu thích',
recipe: 'Công thức',
recipePlural: 'Công thức',
recipeShare: 'Ảnh theo công thức {{recipe}}',
film: 'Phim',
filmPlural: 'Phim',
filmShare: 'Ảnh chụp bằng {{film}}',
focalLength: 'Độ dài tiêu cự',
focalLengthPlural: 'Độ dài tiêu cự',
focalLengthTitle: 'Tiêu cự {{focal}}',
focalLengthShare: 'Ảnh chụp ở tiêu cự {{focal}}',
year: 'Năm',
yearPlural: 'Năm',
yearShare: 'Ảnh năm {{year}}',
yearTitle: 'Ảnh chụp năm {{year}}',
recent: 'Gần đây',
recentPlural: 'Gần đây',
recentTitle: 'Ảnh gần đây',
recentSubhead: 'Được tải lên {{distance}} trước',
},
nav: {
home: 'Trang chủ',
full: 'Toàn bộ',
grid: 'Lưới',
admin: 'Quản trị',
search: 'Tìm kiếm',
prev: 'Trước',
prevShort: 'Trước',
next: 'Tiếp',
nextShort: 'Tiếp',
},
footer: {
madeWith: 'Được tạo bằng',
},
sort: {
sort: 'Sắp xếp',
newest: 'Mới nhất',
oldest: 'Cũ nhất',
descending: 'Giảm dần',
ascending: 'Tăng dần',
newestFirst: 'Mới nhất trước',
oldestFirst: 'Cũ nhất trước',
viewNewest: 'Xem mới nhất',
viewOldest: 'Xem cũ nhất',
takenAt: 'Chụp vào',
byTakenAt: 'Theo thời gian chụp',
uploadedAt: 'Tải lên vào',
byUploadedAt: 'Theo thời gian tải lên',
uploadedAtShort: 'Tải lên',
color: 'Màu sắc',
byColor: 'Theo màu sắc',
clearSort: 'Xóa sắp xếp',
},
cmdk: {
placeholder: 'Tìm kiếm ảnh, chế độ xem, cài đặt...',
searching: 'Đang tìm kiếm...',
noResults: 'Không tìm thấy kết quả',
pages: 'Trang',
},
tooltip: {
'35mm': 'Tương đương 35mm',
zoom: 'Phóng to',
recipeInfo: 'Thông tin công thức',
recipeCopy: 'Sao chép văn bản công thức',
download: 'Tải xuống tệp gốc',
sharePhoto: 'Chia sẻ ảnh',
shareCopy: 'Sao chép liên kết',
shareTo: 'Chia sẻ...',
shareX: 'Chia sẻ trên X',
shareThreads: 'Chia sẻ trên Threads',
shareFacebook: 'Chia sẻ trên Facebook',
shareLinkedIn: 'Chia sẻ trên LinkedIn',
shareQRCode: 'Hiện/ẩn mã QR',
},
theme: {
theme: 'Chủ đề',
system: 'Hệ thống',
light: 'Chế độ sáng',
dark: 'Chế độ tối',
},
auth: {
signIn: 'Đăng nhập',
signOut: 'Đăng xuất',
email: 'Email quản trị',
password: 'Mật khẩu quản trị',
invalidEmailPassword: 'Email/mật khẩu không hợp lệ',
},
admin: {
uploadPhotos: 'Tải lên ảnh',
upload: 'Tải lên',
uploadPlural: 'Tải lên',
uploading: 'Đang tải lên',
update: 'Cập nhật',
updatePlural: 'Cập nhật',
managePhotos: 'Quản lý ảnh',
manageCameras: 'Quản lý máy ảnh',
manageLenses: 'Quản lý ống kính',
manageAlbums: 'Quản lý album',
manageTags: 'Quản lý thẻ',
manageRecipes: 'Quản lý công thức',
selectPhotos: 'Chọn ảnh...',
selectPhotosExit: 'Dừng chọn',
appInsights: 'Thống kê ứng dụng',
appConfig: 'Cấu hình ứng dụng',
edit: 'Chỉnh sửa',
favorite: 'Yêu thích',
unfavorite: 'Bỏ yêu thích',
private: 'Làm riêng tư',
public: 'Làm công khai',
download: 'Tải xuống',
sync: 'Đồng bộ',
reupload: 'Tải lên lại',
delete: 'Xóa',
deleteConfirm: 'Bạn có chắc chắn muốn xóa "{{photoTitle}}?"',
},
onboarding: {
setupComplete: 'Cài đặt hoàn tất!',
setupIncomplete: 'Hoàn tất cài đặt',
setupSignIn: 'Đăng nhập để tải lên ảnh',
setupFirstPhoto: 'Thêm ảnh đầu tiên của bạn',
setupConfig: 'Thay đổi tên trang web và cấu hình khác bằng cách chỉnh sửa các biến môi trường được tham chiếu trong',
},
utility: {
more: 'Thêm',
less: 'Ít hơn',
loadMore: 'Tải thêm',
loading: 'Đang tải...',
tryAgain: 'Thử lại',
finishing: 'Đang hoàn thành...',
uploading: 'Đang tải lên',
copyPhrase: '{{label}} đã sao chép',
paginate: '{{index}} của {{count}}',
paginateAction: '{{action}} {{index}} của {{count}}',
},
};