From e83bbf31212e50c5f44f665348039c23dc6a92dc Mon Sep 17 00:00:00 2001 From: Nguyen Quang Huy <129346683+Perfeitor@users.noreply.github.com> Date: Thu, 7 Aug 2025 18:01:01 +0700 Subject: [PATCH] feat: Added Vietnamese translation (#834) --- i18n.ts | 3 + translations/vi.json | 484 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 487 insertions(+) create mode 100644 translations/vi.json diff --git a/i18n.ts b/i18n.ts index 1825069d..fb95aa07 100644 --- a/i18n.ts +++ b/i18n.ts @@ -22,6 +22,7 @@ import sv from "./translations/sv.json"; import tlh from "./translations/tlh.json"; import tr from "./translations/tr.json"; import uk from "./translations/uk.json"; +import vi from "./translations/vi.json"; import zhCN from "./translations/zh-CN.json"; import zhTW from "./translations/zh-TW.json"; @@ -49,6 +50,7 @@ export const APP_LANGUAGES = [ { label: "Українська", value: "uk" }, { label: "简体中文", value: "zh-CN" }, { label: "繁體中文", value: "zh-TW" }, + { label: "Tiếng Việt", value: "vi" }, ]; i18n.use(initReactI18next).init({ @@ -75,6 +77,7 @@ i18n.use(initReactI18next).init({ tr: { translation: tr }, tlh: { translation: tlh }, uk: { translation: uk }, + vi: { translation: vi }, "zh-CN": { translation: zhCN }, "zh-TW": { translation: zhTW }, }, diff --git a/translations/vi.json b/translations/vi.json new file mode 100644 index 00000000..b0ef4dd9 --- /dev/null +++ b/translations/vi.json @@ -0,0 +1,484 @@ +{ + "login": { + "username_required": "Cần nhập tên người dùng", + "error_title": "Lỗi", + "login_title": "Đăng nhập", + "login_to_title": "Đăng nhập vào", + "username_placeholder": "Tên người dùng", + "password_placeholder": "Mật khẩu", + "login_button": "Đăng nhập", + "quick_connect": "Kết nối nhanh", + "enter_code_to_login": "Nhập mã {{code}} để đăng nhập", + "failed_to_initiate_quick_connect": "Không thể bắt đầu Kết nối nhanh", + "got_it": "Đã hiểu", + "connection_failed": "Kết nối thất bại", + "could_not_connect_to_server": "Không thể kết nối tới máy chủ. Vui lòng kiểm tra URL và kết nối mạng.", + "an_unexpected_error_occured": "Đã xảy ra lỗi không mong muốn", + "change_server": "Đổi máy chủ", + "invalid_username_or_password": "Tên đăng nhập hoặc mật khẩu không đúng", + "user_does_not_have_permission_to_log_in": "Người dùng không có quyền đăng nhập", + "server_is_taking_too_long_to_respond_try_again_later": "Máy chủ phản hồi quá lâu, vui lòng thử lại sau", + "server_received_too_many_requests_try_again_later": "Máy chủ nhận quá nhiều yêu cầu, vui lòng thử lại sau.", + "there_is_a_server_error": "Đã xảy ra lỗi ở máy chủ", + "an_unexpected_error_occured_did_you_enter_the_correct_url": "Đã xảy ra lỗi không mong muốn. Bạn có chắc đã nhập đúng URL máy chủ?" + }, + "server": { + "enter_url_to_jellyfin_server": "Nhập URL máy chủ Jellyfin của bạn", + "server_url_placeholder": "http(s)://your-server.com", + "connect_button": "Kết nối", + "previous_servers": "Máy chủ trước đó", + "clear_button": "Xóa", + "search_for_local_servers": "Tìm máy chủ trong mạng", + "searching": "Đang tìm...", + "servers": "Máy chủ" + }, + "home": { + "no_internet": "Không có Internet", + "no_items": "Không có nội dung", + "no_internet_message": "Không sao, bạn vẫn có thể xem được nội dung đã tải xuống.", + "go_to_downloads": "Tới phần tải về", + "oops": "Ối!", + "error_message": "Có lỗi xảy ra.\nVui lòng đăng xuất rồi đăng nhập lại.", + "continue_watching": "Tiếp tục xem", + "next_up": "Tiếp theo", + "recently_added_in": "Mới thêm trong {{libraryName}}", + "suggested_movies": "Phim gợi ý", + "suggested_episodes": "Tập gợi ý", + "intro": { + "welcome_to_streamyfin": "Chào mừng đến với Streamyfin", + "a_free_and_open_source_client_for_jellyfin": "Một ứng dụng miễn phí và mã nguồn mở cho Jellyfin.", + "features_title": "Tính năng", + "features_description": "Streamyfin có nhiều tính năng và tích hợp với nhiều phần mềm, xem trong mục cài đặt, bao gồm:", + "jellyseerr_feature_description": "Kết nối với Jellyseerr và yêu cầu phim ngay trong ứng dụng.", + "downloads_feature_title": "Tải xuống", + "downloads_feature_description": "Tải phim và chương trình để xem ngoại tuyến. Có thể dùng phương pháp mặc định hoặc cài đặt máy chủ tối ưu để hỗ trợ tải trong nền.", + "chromecast_feature_description": "Phát phim lên Chromecast.", + "centralised_settings_plugin_title": "Plugin cấu hình tập trung", + "centralised_settings_plugin_description": "Cài đặt đồng bộ hóa từ máy chủ Jellyfin. Tất cả cài đặt người dùng sẽ được đồng bộ.", + "done_button": "Xong", + "go_to_settings_button": "Tới cài đặt", + "read_more": "Xem thêm" + }, + "settings": { + "settings_title": "Cài đặt", + "log_out_button": "Đăng xuất", + "user_info": { + "user_info_title": "Thông tin người dùng", + "user": "Người dùng", + "server": "Máy chủ", + "token": "Token", + "app_version": "Phiên bản ứng dụng" + }, + "quick_connect": { + "quick_connect_title": "Kết nối nhanh", + "authorize_button": "Cho phép Kết nối nhanh", + "enter_the_quick_connect_code": "Nhập mã kết nối nhanh...", + "success": "Thành công", + "quick_connect_autorized": "Kết nối nhanh đã được cho phép", + "error": "Lỗi", + "invalid_code": "Mã không hợp lệ", + "authorize": "Cho phép" + }, + "media_controls": { + "media_controls_title": "Điều khiển đa phương tiện", + "forward_skip_length": "Thời gian tua tới", + "rewind_length": "Thời gian tua lui", + "seconds_unit": "s" + }, + "audio": { + "audio_title": "Âm thanh", + "set_audio_track": "Chọn track âm thanh từ mục trước", + "audio_language": "Ngôn ngữ âm thanh", + "audio_hint": "Chọn ngôn ngữ âm thanh mặc định.", + "none": "Không có", + "language": "Ngôn ngữ" + }, + "subtitles": { + "subtitle_title": "Phụ đề", + "subtitle_language": "Ngôn ngữ phụ đề", + "subtitle_mode": "Chế độ phụ đề", + "set_subtitle_track": "Chọn phụ đề từ mục trước", + "subtitle_size": "Cỡ chữ", + "subtitle_hint": "Cấu hình tùy chọn phụ đề.", + "none": "Không có", + "language": "Ngôn ngữ", + "loading": "Đang tải", + "modes": { + "Default": "Mặc định", + "Smart": "Thông minh", + "Always": "Luôn hiện", + "None": "Không hiển thị", + "OnlyForced": "Bắt buộc" + } + }, + "other": { + "other_title": "Khác", + "follow_device_orientation": "Tự xoay màn hình", + "video_orientation": "Hướng video", + "orientation": "Hướng", + "orientations": { + "DEFAULT": "Mặc định", + "ALL": "Tất cả", + "PORTRAIT": "Chân dung", + "PORTRAIT_UP": "Chân dung hướng lên", + "PORTRAIT_DOWN": "Chân dung hướng xuống", + "LANDSCAPE": "Ngang", + "LANDSCAPE_LEFT": "Ngang trái", + "LANDSCAPE_RIGHT": "Ngang phải", + "OTHER": "Khác", + "UNKNOWN": "Không rõ" + }, + "safe_area_in_controls": "Vùng an toàn trong điều khiển", + "video_player": "Trình phát video", + "video_players": { + "VLC_3": "VLC 3", + "VLC_4": "VLC 4 (Thử nghiệm + PiP)" + }, + "show_custom_menu_links": "Hiện liên kết tùy chỉnh", + "hide_libraries": "Ẩn thư viện", + "select_liraries_you_want_to_hide": "Chọn các thư viện muốn ẩn khỏi mục Thư viện và Trang chủ.", + "disable_haptic_feedback": "Tắt phản hồi rung", + "default_quality": "Chất lượng mặc định", + "max_auto_play_episode_count": "Số tập tự chạy tối đa", + "disabled": "Đã tắt" + }, + "downloads": { + "downloads_title": "Tải xuống", + "download_method": "Phương pháp tải", + "remux_max_download": "Giới hạn tải Remux tối đa", + "auto_download": "Tự động tải", + "optimized_versions_server": "Máy chủ phiên bản tối ưu", + "save_button": "Lưu", + "optimized_server": "Máy chủ tối ưu", + "optimized": "Tối ưu", + "default": "Mặc định", + "optimized_version_hint": "Nhập URL máy chủ tối ưu. Phải có http hoặc https và cổng nếu cần.", + "read_more_about_optimized_server": "Tìm hiểu thêm về máy chủ tối ưu.", + "url": "URL", + "server_url_placeholder": "http(s)://domain.org:port" + }, + "plugins": { + "plugins_title": "Plugin", + "jellyseerr": { + "jellyseerr_warning": "Tích hợp đang trong giai đoạn thử nghiệm. Nội dung có thể thay đổi.", + "server_url": "URL máy chủ", + "server_url_hint": "Ví dụ: http(s)://your-host.url (có port nếu cần)", + "server_url_placeholder": "Jellyseerr URL...", + "password": "Mật khẩu", + "password_placeholder": "Nhập mật khẩu cho người dùng {{username}} Jellyfin", + "save_button": "Lưu", + "clear_button": "Xóa", + "login_button": "Đăng nhập", + "total_media_requests": "Tổng số lượt yêu cầu nội dung", + "movie_quota_limit": "Giới hạn phim", + "movie_quota_days": "Số ngày giới hạn yêu cầu phim", + "tv_quota_limit": "Giới hạn TV", + "tv_quota_days": "Số ngày giới hạn yêu cầu TV", + "reset_jellyseerr_config_button": "Đặt lại cấu hình Jellyseerr", + "unlimited": "Không giới hạn", + "plus_n_more": "+{{n}} thêm", + "order_by": { + "DEFAULT": "Mặc định", + "VOTE_COUNT_AND_AVERAGE": "Dựa trên số lượt và điểm đánh giá", + "POPULARITY": "Theo độ phổ biến" + } + }, + "marlin_search": { + "enable_marlin_search": "Bật Marlin Search", + "url": "URL", + "server_url_placeholder": "http(s)://domain.org:port", + "marlin_search_hint": "Nhập URL máy chủ Marlin. Phải có http/https và port nếu cần.", + "read_more_about_marlin": "Tìm hiểu thêm về Marlin.", + "save_button": "Lưu", + "toasts": { + "saved": "Đã lưu" + } + } + }, + "storage": { + "storage_title": "Lưu trữ", + "app_usage": "Ứng dụng sử dụng {{usedSpace}}%", + "device_usage": "Thiết bị sử dụng {{availableSpace}}%", + "size_used": "{{used}} / {{total}} đã dùng", + "delete_all_downloaded_files": "Xóa toàn bộ tập tin đã tải" + }, + "intro": { + "show_intro": "Hiện giới thiệu", + "reset_intro": "Đặt lại giới thiệu" + }, + "logs": { + "logs_title": "Nhật ký", + "export_logs": "Xuất nhật ký", + "click_for_more_info": "Nhấn để xem thêm thông tin", + "level": "Mức độ", + "no_logs_available": "Không có nhật ký", + "delete_all_logs": "Xóa tất cả nhật ký" + }, + "languages": { + "title": "Ngôn ngữ", + "app_language": "Ngôn ngữ ứng dụng", + "app_language_description": "Chọn ngôn ngữ cho ứng dụng.", + "system": "Hệ thống" + }, + "toasts": { + "error_deleting_files": "Lỗi khi xóa tập tin", + "background_downloads_enabled": "Tải trong nền đã bật", + "background_downloads_disabled": "Tải trong nền đã tắt", + "connected": "Đã kết nối", + "could_not_connect": "Không thể kết nối", + "invalid_url": "URL không hợp lệ" + } + }, + "sessions": { + "title": "Phiên hoạt động", + "no_active_sessions": "Không có phiên đang hoạt động" + }, + "downloads": { + "downloads_title": "Tải xuống", + "tvseries": "Chương trình TV", + "movies": "Phim", + "queue": "Hàng đợi", + "queue_hint": "Hàng đợi và tải xuống sẽ bị mất khi khởi động lại ứng dụng", + "no_items_in_queue": "Không có mục trong hàng đợi", + "no_downloaded_items": "Không có mục đã tải", + "delete_all_movies_button": "Xóa tất cả phim", + "delete_all_tvseries_button": "Xóa tất cả chương trình TV", + "delete_all_button": "Xóa tất cả", + "active_download": "Đang tải xuống", + "no_active_downloads": "Không có tải xuống đang diễn ra", + "active_downloads": "Đang tải xuống", + "new_app_version_requires_re_download": "Phiên bản ứng dụng mới yêu cầu tải lại", + "new_app_version_requires_re_download_description": "Cập nhật mới yêu cầu phải tải lại nội dung. Vui lòng xóa toàn bộ nội dung đã tải và thử lại.", + "back": "Quay lại", + "delete": "Xóa", + "something_went_wrong": "Đã xảy ra lỗi", + "could_not_get_stream_url_from_jellyfin": "Không thể lấy URL phát trực tiếp từ Jellyfin", + "eta": "Thời gian còn lại {{eta}}", + "methods": "Phương pháp", + "toasts": { + "you_are_not_allowed_to_download_files": "Bạn không có quyền tải nội dung.", + "deleted_all_movies_successfully": "Đã xóa tất cả phim thành công!", + "failed_to_delete_all_movies": "Xóa phim thất bại", + "deleted_all_tvseries_successfully": "Đã xóa tất cả chương trình TV thành công!", + "failed_to_delete_all_tvseries": "Xóa chương trình TV thất bại", + "download_cancelled": "Tải xuống bị hủy", + "could_not_cancel_download": "Không thể hủy tải xuống", + "download_completed": "Tải xuống hoàn tất", + "download_started_for": "Bắt đầu tải {{item}}", + "item_is_ready_to_be_downloaded": "{{item}} đã sẵn sàng để tải", + "download_stated_for_item": "Bắt đầu tải {{item}}", + "download_failed_for_item": "Tải {{item}} thất bại – {{error}}", + "download_completed_for_item": "Tải xong {{item}}", + "queued_item_for_optimization": "Đã đưa {{item}} vào hàng đợi tối ưu hóa", + "failed_to_start_download_for_item": "Không thể bắt đầu tải {{item}}: {{message}}", + "server_responded_with_status_code": "Máy chủ phản hồi mã {{statusCode}}", + "no_response_received_from_server": "Không nhận được phản hồi từ máy chủ", + "error_setting_up_the_request": "Lỗi khi thiết lập yêu cầu", + "failed_to_start_download_for_item_unexpected_error": "Không thể bắt đầu tải {{item}}: Lỗi không mong muốn", + "all_files_folders_and_jobs_deleted_successfully": "Đã xóa thành công tất cả tập tin, thư mục và công việc", + "an_error_occured_while_deleting_files_and_jobs": "Đã xảy ra lỗi khi xóa tập tin và công việc", + "go_to_downloads": "Tới phần tải về" + } + } + }, + "search": { + "search_here": "Tìm tại đây...", + "search": "Tìm...", + "x_items": "{{count}} mục", + "library": "Thư viện", + "discover": "Khám phá", + "no_results": "Không có kết quả", + "no_results_found_for": "Không tìm thấy kết quả cho", + "movies": "Phim", + "series": "Chương trình", + "episodes": "Tập", + "collections": "Bộ sưu tập", + "actors": "Diễn viên", + "request_movies": "Yêu cầu phim", + "request_series": "Yêu cầu chương trình", + "recently_added": "Mới thêm", + "recent_requests": "Yêu cầu gần đây", + "plex_watchlist": "Danh sách xem Plex", + "trending": "Thịnh hành", + "popular_movies": "Phim phổ biến", + "movie_genres": "Thể loại phim", + "upcoming_movies": "Phim sắp chiếu", + "studios": "Hãng phim", + "popular_tv": "TV phổ biến", + "tv_genres": "Thể loại TV", + "upcoming_tv": "TV sắp chiếu", + "networks": "Mạng phát", + "tmdb_movie_keyword": "Từ khóa phim TMDB", + "tmdb_movie_genre": "Thể loại phim TMDB", + "tmdb_tv_keyword": "Từ khóa TV TMDB", + "tmdb_tv_genre": "Thể loại TV TMDB", + "tmdb_search": "Tìm TMDB", + "tmdb_studio": "Hãng phim TMDB", + "tmdb_network": "Mạng TMDB", + "tmdb_movie_streaming_services": "Dịch vụ streaming phim TMDB", + "tmdb_tv_streaming_services": "Dịch vụ streaming TV TMDB" + }, + "library": { + "no_items_found": "Không tìm thấy nội dung", + "no_results": "Không có kết quả", + "no_libraries_found": "Không tìm thấy thư viện", + "item_types": { + "movies": "phim", + "series": "chương trình", + "boxsets": "bộ sưu tập", + "items": "nội dung" + }, + "options": { + "display": "Hiển thị", + "row": "Hàng ngang", + "list": "Danh sách", + "image_style": "Kiểu hình ảnh", + "poster": "Ảnh bìa dọc", + "cover": "Bìa", + "show_titles": "Hiển thị tiêu đề", + "show_stats": "Hiện thống kê" + }, + "filters": { + "genres": "Thể loại", + "years": "Năm", + "sort_by": "Sắp xếp theo", + "sort_order": "Thứ tự", + "asc": "Tăng dần", + "desc": "Giảm dần", + "tags": "Thẻ" + } + }, + "favorites": { + "series": "Chương trình", + "movies": "Phim", + "episodes": "Tập", + "videos": "Video", + "boxsets": "Bộ sưu tập", + "playlists": "Danh sách phát", + "noDataTitle": "Chưa có mục yêu thích", + "noData": "Đánh dấu mục yêu thích để xem ở đây nhanh hơn." + }, + "custom_links": { + "no_links": "Chưa có liên kết" + }, + "player": { + "error": "Lỗi", + "failed_to_get_stream_url": "Không thể lấy URL phát trực tiếp", + "an_error_occured_while_playing_the_video": "Có lỗi khi phát video. Xem nhật ký trong cài đặt.", + "client_error": "Lỗi phía máy khách", + "could_not_create_stream_for_chromecast": "Không thể tạo luồng cho Chromecast", + "message_from_server": "Thông báo từ máy chủ: {{message}}", + "video_has_finished_playing": "Video đã phát xong!", + "no_video_source": "Không có nguồn video...", + "next_episode": "Tập tiếp theo", + "refresh_tracks": "Làm mới các track", + "subtitle_tracks": "Track phụ đề:", + "audio_tracks": "Track âm thanh:", + "playback_state": "Trạng thái phát:", + "no_data_available": "Không có dữ liệu", + "index": "Chỉ mục:", + "continue_watching": "Tiếp tục xem", + "go_back": "Quay lại" + }, + "item_card": { + "next_up": "Tiếp theo", + "no_items_to_display": "Không có nội dung để hiển thị", + "cast_and_crew": "Diễn viên & Đội ngũ", + "series": "Chương trình", + "seasons": "Mùa", + "season": "Mùa", + "no_episodes_for_this_season": "Không có tập cho mùa này", + "overview": "Giới thiệu", + "more_with": "Thêm với {{name}}", + "similar_items": "Nội dung tương tự", + "no_similar_items_found": "Không tìm thấy nội dung tương tự", + "video": "Video", + "more_details": "Xem thêm chi tiết", + "quality": "Chất lượng", + "audio": "Âm thanh", + "subtitles": "Phụ đề", + "show_more": "Xem thêm", + "show_less": "Thu gọn", + "appeared_in": "Xuất hiện trong", + "could_not_load_item": "Không thể tải nội dung", + "none": "Không có", + "download": { + "download_season": "Tải mùa", + "download_series": "Tải chương trình", + "download_episode": "Tải tập", + "download_movie": "Tải phim", + "download_x_item": "Tải {{item_count}} nội dung", + "download_button": "Tải", + "using_optimized_server": "Đang dùng máy chủ tối ưu", + "using_default_method": "Đang dùng phương pháp mặc định" + } + }, + "live_tv": { + "next": "Tiếp theo", + "previous": "Trước đó", + "live_tv": "TV trực tiếp", + "coming_soon": "Sắp chiếu", + "on_now": "Đang phát", + "shows": "Chương trình", + "movies": "Phim", + "sports": "Thể thao", + "for_kids": "Dành cho trẻ em", + "news": "Tin tức" + }, + "jellyseerr": { + "confirm": "Xác nhận", + "cancel": "Hủy", + "yes": "Có", + "whats_wrong": "Có vấn đề gì?", + "issue_type": "Loại sự cố", + "select_an_issue": "Chọn sự cố", + "types": "Loại", + "describe_the_issue": "(tuỳ chọn) Mô tả sự cố...", + "submit_button": "Gửi", + "report_issue_button": "Báo lỗi", + "request_button": "Yêu cầu", + "are_you_sure_you_want_to_request_all_seasons": "Chắc chắn muốn yêu cầu tất cả các mùa?", + "failed_to_login": "Đăng nhập thất bại", + "cast": "Diễn viên", + "details": "Chi tiết", + "status": "Trạng thái", + "original_title": "Tiêu đề gốc", + "series_type": "Loại chương trình", + "release_dates": "Ngày phát hành", + "first_air_date": "Phát sóng lần đầu", + "next_air_date": "Phát sóng tiếp theo", + "revenue": "Doanh thu", + "budget": "Ngân sách", + "original_language": "Ngôn ngữ gốc", + "production_country": "Quốc gia sản xuất", + "studios": "Hãng sản xuất", + "network": "Đài phát sóng", + "currently_streaming_on": "Đang phát trên", + "advanced": "Nâng cao", + "request_as": "Yêu cầu dưới tên", + "tags": "Thẻ", + "quality_profile": "Hồ sơ chất lượng", + "root_folder": "Thư mục gốc", + "season_all": "Toàn bộ mùa", + "season_number": "Mùa {{season_number}}", + "number_episodes": "{{episode_number}} tập", + "born": "Ngày sinh", + "appearances": "Lần xuất hiện", + "toasts": { + "jellyseer_does_not_meet_requirements": "Máy chủ Jellyseerr không đạt yêu cầu tối thiểu! Vui lòng cập nhật lên ít nhất 2.0.0", + "jellyseerr_test_failed": "Kiểm tra Jellyseerr thất bại. Vui lòng thử lại.", + "failed_to_test_jellyseerr_server_url": "Không thể kiểm tra URL Jellyseerr", + "issue_submitted": "Đã gửi báo lỗi!", + "requested_item": "Đã yêu cầu {{item}}!", + "you_dont_have_permission_to_request": "Bạn không có quyền để yêu cầu!", + "something_went_wrong_requesting_media": "Có lỗi khi thực hiện yêu cầu!" + } + }, + "tabs": { + "home": "Trang chính", + "search": "Tìm kiếm", + "library": "Thư viện", + "custom_links": "Liên kết tùy chỉnh", + "favorites": "Yêu thích" + } +}