fix: Update locked folder text and improve translations (#18622)

* Update locked folder text and remove unused translations

* uppercase Locked folder in Menu

* convert some translates to icu and improve

* add iOS debug info translations for background processes

* fix lint

---------

Co-authored-by: dvbthien <dvbthien@gmail.com>
This commit is contained in:
Thien Dang 2025-05-30 03:06:08 +07:00 committed by GitHub
parent dbdb64f6c5
commit 0f42babb6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 57 additions and 84 deletions

View File

@ -26,7 +26,6 @@
"add_to_album": "Add to album", "add_to_album": "Add to album",
"add_to_album_bottom_sheet_added": "Added to {album}", "add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}", "add_to_album_bottom_sheet_already_exists": "Already in {album}",
"add_to_locked_folder": "Add to locked folder",
"add_to_shared_album": "Add to shared album", "add_to_shared_album": "Add to shared album",
"add_url": "Add URL", "add_url": "Add URL",
"added_to_archive": "Added to archive", "added_to_archive": "Added to archive",
@ -45,8 +44,6 @@
"backup_keep_last_amount": "Amount of previous dumps to keep", "backup_keep_last_amount": "Amount of previous dumps to keep",
"backup_settings": "Database Dump Settings", "backup_settings": "Database Dump Settings",
"backup_settings_description": "Manage database dump settings. Note: These jobs are not monitored and you will not be notified of failure.", "backup_settings_description": "Manage database dump settings. Note: These jobs are not monitored and you will not be notified of failure.",
"check_all": "Check All",
"cleanup": "Cleanup",
"cleared_jobs": "Cleared jobs for: {job}", "cleared_jobs": "Cleared jobs for: {job}",
"config_set_by_file": "Config is currently set by a config file", "config_set_by_file": "Config is currently set by a config file",
"confirm_delete_library": "Are you sure you want to delete {library} library?", "confirm_delete_library": "Are you sure you want to delete {library} library?",
@ -62,14 +59,12 @@
"disable_login": "Disable login", "disable_login": "Disable login",
"duplicate_detection_job_description": "Run machine learning on assets to detect similar images. Relies on Smart Search", "duplicate_detection_job_description": "Run machine learning on assets to detect similar images. Relies on Smart Search",
"exclusion_pattern_description": "Exclusion patterns lets you ignore files and folders when scanning your library. This is useful if you have folders that contain files you don't want to import, such as RAW files.", "exclusion_pattern_description": "Exclusion patterns lets you ignore files and folders when scanning your library. This is useful if you have folders that contain files you don't want to import, such as RAW files.",
"external_library_created_at": "External library (created on {date})",
"external_library_management": "External Library Management", "external_library_management": "External Library Management",
"face_detection": "Face detection", "face_detection": "Face detection",
"face_detection_description": "Detect the faces in assets using machine learning. For videos, only the thumbnail is considered. \"Refresh\" (re-)processes all assets. \"Reset\" additionally clears all current face data. \"Missing\" queues assets that haven't been processed yet. Detected faces will be queued for Facial Recognition after Face Detection is complete, grouping them into existing or new people.", "face_detection_description": "Detect the faces in assets using machine learning. For videos, only the thumbnail is considered. \"Refresh\" (re-)processes all assets. \"Reset\" additionally clears all current face data. \"Missing\" queues assets that haven't been processed yet. Detected faces will be queued for Facial Recognition after Face Detection is complete, grouping them into existing or new people.",
"facial_recognition_job_description": "Group detected faces into people. This step runs after Face Detection is complete. \"Reset\" (re-)clusters all faces. \"Missing\" queues faces that don't have a person assigned.", "facial_recognition_job_description": "Group detected faces into people. This step runs after Face Detection is complete. \"Reset\" (re-)clusters all faces. \"Missing\" queues faces that don't have a person assigned.",
"failed_job_command": "Command {command} failed for job: {job}", "failed_job_command": "Command {command} failed for job: {job}",
"force_delete_user_warning": "WARNING: This will immediately remove the user and all assets. This cannot be undone and the files cannot be recovered.", "force_delete_user_warning": "WARNING: This will immediately remove the user and all assets. This cannot be undone and the files cannot be recovered.",
"forcing_refresh_library_files": "Forcing refresh of all library files",
"image_format": "Format", "image_format": "Format",
"image_format_description": "WebP produces smaller files than JPEG, but is slower to encode.", "image_format_description": "WebP produces smaller files than JPEG, but is slower to encode.",
"image_fullsize_description": "Full-size image with stripped metadata, used when zoomed in", "image_fullsize_description": "Full-size image with stripped metadata, used when zoomed in",
@ -210,8 +205,6 @@
"oauth_storage_quota_default_description": "Quota in GiB to be used when no claim is provided (Enter 0 for unlimited quota).", "oauth_storage_quota_default_description": "Quota in GiB to be used when no claim is provided (Enter 0 for unlimited quota).",
"oauth_timeout": "Request Timeout", "oauth_timeout": "Request Timeout",
"oauth_timeout_description": "Timeout for requests in milliseconds", "oauth_timeout_description": "Timeout for requests in milliseconds",
"offline_paths": "Offline Paths",
"offline_paths_description": "These results may be due to manual deletion of files that are not part of an external library.",
"password_enable_description": "Login with email and password", "password_enable_description": "Login with email and password",
"password_settings": "Password Login", "password_settings": "Password Login",
"password_settings_description": "Manage password login settings", "password_settings_description": "Manage password login settings",
@ -221,9 +214,6 @@
"refreshing_all_libraries": "Refreshing all libraries", "refreshing_all_libraries": "Refreshing all libraries",
"registration": "Admin Registration", "registration": "Admin Registration",
"registration_description": "Since you are the first user on the system, you will be assigned as the Admin and are responsible for administrative tasks, and additional users will be created by you.", "registration_description": "Since you are the first user on the system, you will be assigned as the Admin and are responsible for administrative tasks, and additional users will be created by you.",
"repair_all": "Repair All",
"repair_matched_items": "Matched {count, plural, one {# item} other {# items}}",
"repaired_items": "Repaired {count, plural, one {# item} other {# items}}",
"require_password_change_on_login": "Require user to change password on first login", "require_password_change_on_login": "Require user to change password on first login",
"reset_settings_to_default": "Reset settings to default", "reset_settings_to_default": "Reset settings to default",
"reset_settings_to_recent_saved": "Reset settings to the recent saved settings", "reset_settings_to_recent_saved": "Reset settings to the recent saved settings",
@ -264,7 +254,6 @@
"template_email_invite_album": "Invite Album Template", "template_email_invite_album": "Invite Album Template",
"template_email_preview": "Preview", "template_email_preview": "Preview",
"template_email_settings": "Email Templates", "template_email_settings": "Email Templates",
"template_email_settings_description": "Manage custom email notification templates",
"template_email_update_album": "Update Album Template", "template_email_update_album": "Update Album Template",
"template_email_welcome": "Welcome email template", "template_email_welcome": "Welcome email template",
"template_settings": "Notification Templates", "template_settings": "Notification Templates",
@ -273,7 +262,6 @@
"theme_custom_css_settings_description": "Cascading Style Sheets allow the design of Immich to be customized.", "theme_custom_css_settings_description": "Cascading Style Sheets allow the design of Immich to be customized.",
"theme_settings": "Theme Settings", "theme_settings": "Theme Settings",
"theme_settings_description": "Manage customization of the Immich web interface", "theme_settings_description": "Manage customization of the Immich web interface",
"these_files_matched_by_checksum": "These files are matched by their checksums",
"thumbnail_generation_job": "Generate Thumbnails", "thumbnail_generation_job": "Generate Thumbnails",
"thumbnail_generation_job_description": "Generate large, small and blurred thumbnails for each asset, as well as thumbnails for each person", "thumbnail_generation_job_description": "Generate large, small and blurred thumbnails for each asset, as well as thumbnails for each person",
"transcoding_acceleration_api": "Acceleration API", "transcoding_acceleration_api": "Acceleration API",
@ -341,8 +329,6 @@
"trash_number_of_days_description": "Number of days to keep the assets in trash before permanently removing them", "trash_number_of_days_description": "Number of days to keep the assets in trash before permanently removing them",
"trash_settings": "Trash Settings", "trash_settings": "Trash Settings",
"trash_settings_description": "Manage trash settings", "trash_settings_description": "Manage trash settings",
"untracked_files": "Untracked Files",
"untracked_files_description": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug",
"user_cleanup_job": "User cleanup", "user_cleanup_job": "User cleanup",
"user_delete_delay": "<b>{user}</b>'s account and assets will be scheduled for permanent deletion in {delay, plural, one {# day} other {# days}}.", "user_delete_delay": "<b>{user}</b>'s account and assets will be scheduled for permanent deletion in {delay, plural, one {# day} other {# days}}.",
"user_delete_delay_settings": "Delete delay", "user_delete_delay_settings": "Delete delay",
@ -401,10 +387,6 @@
"album_remove_user": "Remove user?", "album_remove_user": "Remove user?",
"album_remove_user_confirmation": "Are you sure you want to remove {user}?", "album_remove_user_confirmation": "Are you sure you want to remove {user}?",
"album_share_no_users": "Looks like you have shared this album with all users or you don't have any user to share with.", "album_share_no_users": "Looks like you have shared this album with all users or you don't have any user to share with.",
"album_thumbnail_card_item": "1 item",
"album_thumbnail_card_items": "{count} items",
"album_thumbnail_card_shared": " · Shared",
"album_thumbnail_shared_by": "Shared by {user}",
"album_updated": "Album updated", "album_updated": "Album updated",
"album_updated_setting_description": "Receive an email notification when a shared album has new assets", "album_updated_setting_description": "Receive an email notification when a shared album has new assets",
"album_user_left": "Left {album}", "album_user_left": "Left {album}",
@ -576,21 +558,17 @@
"bulk_keep_duplicates_confirmation": "Are you sure you want to keep {count, plural, one {# duplicate asset} other {# duplicate assets}}? This will resolve all duplicate groups without deleting anything.", "bulk_keep_duplicates_confirmation": "Are you sure you want to keep {count, plural, one {# duplicate asset} other {# duplicate assets}}? This will resolve all duplicate groups without deleting anything.",
"bulk_trash_duplicates_confirmation": "Are you sure you want to bulk trash {count, plural, one {# duplicate asset} other {# duplicate assets}}? This will keep the largest asset of each group and trash all other duplicates.", "bulk_trash_duplicates_confirmation": "Are you sure you want to bulk trash {count, plural, one {# duplicate asset} other {# duplicate assets}}? This will keep the largest asset of each group and trash all other duplicates.",
"buy": "Purchase Immich", "buy": "Purchase Immich",
"cache_settings_album_thumbnails": "Library page thumbnails ({count} assets)",
"cache_settings_clear_cache_button": "Clear cache", "cache_settings_clear_cache_button": "Clear cache",
"cache_settings_clear_cache_button_title": "Clears the app's cache. This will significantly impact the app's performance until the cache has rebuilt.", "cache_settings_clear_cache_button_title": "Clears the app's cache. This will significantly impact the app's performance until the cache has rebuilt.",
"cache_settings_duplicated_assets_clear_button": "CLEAR", "cache_settings_duplicated_assets_clear_button": "CLEAR",
"cache_settings_duplicated_assets_subtitle": "Photos and videos that are black listed by the app", "cache_settings_duplicated_assets_subtitle": "Photos and videos that are black listed by the app",
"cache_settings_duplicated_assets_title": "Duplicated Assets ({count})", "cache_settings_duplicated_assets_title": "Duplicated Assets ({count})",
"cache_settings_image_cache_size": "Image cache size ({count} assets)",
"cache_settings_statistics_album": "Library thumbnails", "cache_settings_statistics_album": "Library thumbnails",
"cache_settings_statistics_assets": "{count} assets ({size})",
"cache_settings_statistics_full": "Full images", "cache_settings_statistics_full": "Full images",
"cache_settings_statistics_shared": "Shared album thumbnails", "cache_settings_statistics_shared": "Shared album thumbnails",
"cache_settings_statistics_thumbnail": "Thumbnails", "cache_settings_statistics_thumbnail": "Thumbnails",
"cache_settings_statistics_title": "Cache usage", "cache_settings_statistics_title": "Cache usage",
"cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application", "cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application",
"cache_settings_thumbnail_size": "Thumbnail cache size ({count} assets)",
"cache_settings_tile_subtitle": "Control the local storage behaviour", "cache_settings_tile_subtitle": "Control the local storage behaviour",
"cache_settings_tile_title": "Local Storage", "cache_settings_tile_title": "Local Storage",
"cache_settings_title": "Caching Settings", "cache_settings_title": "Caching Settings",
@ -622,7 +600,6 @@
"change_pin_code": "Change PIN code", "change_pin_code": "Change PIN code",
"change_your_password": "Change your password", "change_your_password": "Change your password",
"changed_visibility_successfully": "Changed visibility successfully", "changed_visibility_successfully": "Changed visibility successfully",
"check_all": "Check All",
"check_corrupt_asset_backup": "Check for corrupt asset backups", "check_corrupt_asset_backup": "Check for corrupt asset backups",
"check_corrupt_asset_backup_button": "Perform check", "check_corrupt_asset_backup_button": "Perform check",
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.", "check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
@ -668,7 +645,6 @@
"contain": "Contain", "contain": "Contain",
"context": "Context", "context": "Context",
"continue": "Continue", "continue": "Continue",
"control_bottom_app_bar_album_info_shared": "{count} items · Shared",
"control_bottom_app_bar_create_new_album": "Create new album", "control_bottom_app_bar_create_new_album": "Create new album",
"control_bottom_app_bar_delete_from_immich": "Delete from Immich", "control_bottom_app_bar_delete_from_immich": "Delete from Immich",
"control_bottom_app_bar_delete_from_local": "Delete from device", "control_bottom_app_bar_delete_from_local": "Delete from device",
@ -779,7 +755,6 @@
"download_enqueue": "Download enqueued", "download_enqueue": "Download enqueued",
"download_error": "Download Error", "download_error": "Download Error",
"download_failed": "Download failed", "download_failed": "Download failed",
"download_filename": "file: {filename}",
"download_finished": "Download finished", "download_finished": "Download finished",
"download_include_embedded_motion_videos": "Embedded videos", "download_include_embedded_motion_videos": "Embedded videos",
"download_include_embedded_motion_videos_description": "Include videos embedded in motion photos as a separate file", "download_include_embedded_motion_videos_description": "Include videos embedded in motion photos as a separate file",
@ -855,7 +830,6 @@
"cant_get_number_of_comments": "Can't get number of comments", "cant_get_number_of_comments": "Can't get number of comments",
"cant_search_people": "Can't search people", "cant_search_people": "Can't search people",
"cant_search_places": "Can't search places", "cant_search_places": "Can't search places",
"cleared_jobs": "Cleared jobs for: {job}",
"error_adding_assets_to_album": "Error adding assets to album", "error_adding_assets_to_album": "Error adding assets to album",
"error_adding_users_to_album": "Error adding users to album", "error_adding_users_to_album": "Error adding users to album",
"error_deleting_shared_user": "Error deleting shared user", "error_deleting_shared_user": "Error deleting shared user",
@ -864,7 +838,6 @@
"error_removing_assets_from_album": "Error removing assets from album, check console for more details", "error_removing_assets_from_album": "Error removing assets from album, check console for more details",
"error_selecting_all_assets": "Error selecting all assets", "error_selecting_all_assets": "Error selecting all assets",
"exclusion_pattern_already_exists": "This exclusion pattern already exists.", "exclusion_pattern_already_exists": "This exclusion pattern already exists.",
"failed_job_command": "Command {command} failed for job: {job}",
"failed_to_create_album": "Failed to create album", "failed_to_create_album": "Failed to create album",
"failed_to_create_shared_link": "Failed to create shared link", "failed_to_create_shared_link": "Failed to create shared link",
"failed_to_edit_shared_link": "Failed to edit shared link", "failed_to_edit_shared_link": "Failed to edit shared link",
@ -883,7 +856,6 @@
"paths_validation_failed": "{paths, plural, one {# path} other {# paths}} failed validation", "paths_validation_failed": "{paths, plural, one {# path} other {# paths}} failed validation",
"profile_picture_transparent_pixels": "Profile pictures cannot have transparent pixels. Please zoom in and/or move the image.", "profile_picture_transparent_pixels": "Profile pictures cannot have transparent pixels. Please zoom in and/or move the image.",
"quota_higher_than_disk_size": "You set a quota higher than the disk size", "quota_higher_than_disk_size": "You set a quota higher than the disk size",
"repair_unable_to_check_items": "Unable to check {count, select, one {item} other {items}}",
"unable_to_add_album_users": "Unable to add users to album", "unable_to_add_album_users": "Unable to add users to album",
"unable_to_add_assets_to_shared_link": "Unable to add assets to shared link", "unable_to_add_assets_to_shared_link": "Unable to add assets to shared link",
"unable_to_add_comment": "Unable to add comment", "unable_to_add_comment": "Unable to add comment",
@ -902,7 +874,6 @@
"unable_to_change_visibility": "Unable to change the visibility for {count, plural, one {# person} other {# people}}", "unable_to_change_visibility": "Unable to change the visibility for {count, plural, one {# person} other {# people}}",
"unable_to_complete_oauth_login": "Unable to complete OAuth login", "unable_to_complete_oauth_login": "Unable to complete OAuth login",
"unable_to_connect": "Unable to connect", "unable_to_connect": "Unable to connect",
"unable_to_connect_to_server": "Unable to connect to server",
"unable_to_copy_to_clipboard": "Cannot copy to clipboard, make sure you are accessing the page through https", "unable_to_copy_to_clipboard": "Cannot copy to clipboard, make sure you are accessing the page through https",
"unable_to_create_admin_account": "Unable to create admin account", "unable_to_create_admin_account": "Unable to create admin account",
"unable_to_create_api_key": "Unable to create a new API Key", "unable_to_create_api_key": "Unable to create a new API Key",
@ -926,14 +897,9 @@
"unable_to_hide_person": "Unable to hide person", "unable_to_hide_person": "Unable to hide person",
"unable_to_link_motion_video": "Unable to link motion video", "unable_to_link_motion_video": "Unable to link motion video",
"unable_to_link_oauth_account": "Unable to link OAuth account", "unable_to_link_oauth_account": "Unable to link OAuth account",
"unable_to_load_album": "Unable to load album",
"unable_to_load_asset_activity": "Unable to load asset activity",
"unable_to_load_items": "Unable to load items",
"unable_to_load_liked_status": "Unable to load liked status",
"unable_to_log_out_all_devices": "Unable to log out all devices", "unable_to_log_out_all_devices": "Unable to log out all devices",
"unable_to_log_out_device": "Unable to log out device", "unable_to_log_out_device": "Unable to log out device",
"unable_to_login_with_oauth": "Unable to login with OAuth", "unable_to_login_with_oauth": "Unable to login with OAuth",
"unable_to_move_to_locked_folder": "Unable to move to locked folder",
"unable_to_play_video": "Unable to play video", "unable_to_play_video": "Unable to play video",
"unable_to_reassign_assets_existing_person": "Unable to reassign assets to {name, select, null {an existing person} other {{name}}}", "unable_to_reassign_assets_existing_person": "Unable to reassign assets to {name, select, null {an existing person} other {{name}}}",
"unable_to_reassign_assets_new_person": "Unable to reassign assets to a new person", "unable_to_reassign_assets_new_person": "Unable to reassign assets to a new person",
@ -941,11 +907,9 @@
"unable_to_remove_album_users": "Unable to remove users from album", "unable_to_remove_album_users": "Unable to remove users from album",
"unable_to_remove_api_key": "Unable to remove API Key", "unable_to_remove_api_key": "Unable to remove API Key",
"unable_to_remove_assets_from_shared_link": "Unable to remove assets from shared link", "unable_to_remove_assets_from_shared_link": "Unable to remove assets from shared link",
"unable_to_remove_deleted_assets": "Unable to remove offline files",
"unable_to_remove_library": "Unable to remove library", "unable_to_remove_library": "Unable to remove library",
"unable_to_remove_partner": "Unable to remove partner", "unable_to_remove_partner": "Unable to remove partner",
"unable_to_remove_reaction": "Unable to remove reaction", "unable_to_remove_reaction": "Unable to remove reaction",
"unable_to_repair_items": "Unable to repair items",
"unable_to_reset_password": "Unable to reset password", "unable_to_reset_password": "Unable to reset password",
"unable_to_reset_pin_code": "Unable to reset PIN code", "unable_to_reset_pin_code": "Unable to reset PIN code",
"unable_to_resolve_duplicate": "Unable to resolve duplicate", "unable_to_resolve_duplicate": "Unable to resolve duplicate",
@ -1118,6 +1082,12 @@
"invalid_date_format": "Invalid date format", "invalid_date_format": "Invalid date format",
"invite_people": "Invite People", "invite_people": "Invite People",
"invite_to_album": "Invite to album", "invite_to_album": "Invite to album",
"ios_debug_info_fetch_ran_at": "Fetch ran {dateTime}",
"ios_debug_info_last_sync_at": "Last sync {dateTime}",
"ios_debug_info_no_processes_queued": "No background processes queued",
"ios_debug_info_no_sync_yet": "No background sync job has run yet",
"ios_debug_info_processes_queued": "{count, plural, one {{count} background process queued} other {{count} background processes queued}}",
"ios_debug_info_processing_ran_at": "Processing ran {dateTime}",
"items_count": "{count, plural, one {# item} other {# items}}", "items_count": "{count, plural, one {# item} other {# items}}",
"jobs": "Jobs", "jobs": "Jobs",
"keep": "Keep", "keep": "Keep",
@ -1161,7 +1131,7 @@
"location_picker_longitude_error": "Enter a valid longitude", "location_picker_longitude_error": "Enter a valid longitude",
"location_picker_longitude_hint": "Enter your longitude here", "location_picker_longitude_hint": "Enter your longitude here",
"lock": "Lock", "lock": "Lock",
"locked_folder": "Locked folder", "locked_folder": "Locked Folder",
"log_out": "Log out", "log_out": "Log out",
"log_out_all_devices": "Log Out All Devices", "log_out_all_devices": "Log Out All Devices",
"logged_out_all_devices": "Logged out all devices", "logged_out_all_devices": "Logged out all devices",
@ -1319,8 +1289,6 @@
"oauth": "OAuth", "oauth": "OAuth",
"official_immich_resources": "Official Immich Resources", "official_immich_resources": "Official Immich Resources",
"offline": "Offline", "offline": "Offline",
"offline_paths": "Offline paths",
"offline_paths_description": "These results may be due to manual deletion of files that are not part of an external library.",
"ok": "Ok", "ok": "Ok",
"oldest_first": "Oldest first", "oldest_first": "Oldest first",
"on_this_device": "On this device", "on_this_device": "On this device",
@ -1883,8 +1851,6 @@
"unselect_all_duplicates": "Unselect all duplicates", "unselect_all_duplicates": "Unselect all duplicates",
"unstack": "Un-stack", "unstack": "Un-stack",
"unstacked_assets_count": "Un-stacked {count, plural, one {# asset} other {# assets}}", "unstacked_assets_count": "Un-stacked {count, plural, one {# asset} other {# assets}}",
"untracked_files": "Untracked files",
"untracked_files_decription": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug",
"up_next": "Up next", "up_next": "Up next",
"updated_at": "Updated", "updated_at": "Updated",
"updated_password": "Updated password", "updated_password": "Updated password",
@ -1927,11 +1893,6 @@
"version": "Version", "version": "Version",
"version_announcement_closing": "Your friend, Alex", "version_announcement_closing": "Your friend, Alex",
"version_announcement_message": "Hi there! A new version of Immich is available. Please take some time to read the <link>release notes</link> to ensure your setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your Immich instance automatically.", "version_announcement_message": "Hi there! A new version of Immich is available. Please take some time to read the <link>release notes</link> to ensure your setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your Immich instance automatically.",
"version_announcement_overlay_release_notes": "release notes",
"version_announcement_overlay_text_1": "Hi friend, there is a new release of",
"version_announcement_overlay_text_2": "please take your time to visit the ",
"version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
"version_announcement_overlay_title": "New Server Version Available 🎉",
"version_history": "Version History", "version_history": "Version History",
"version_history_item": "Installed {version} on {date}", "version_history_item": "Installed {version} on {date}",
"video": "Video", "video": "Video",

View File

@ -14,6 +14,7 @@ import 'package:immich_mobile/providers/album/album.provider.dart';
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/utils/translation.dart';
import 'package:immich_mobile/widgets/album/album_thumbnail_card.dart'; import 'package:immich_mobile/widgets/album/album_thumbnail_card.dart';
import 'package:immich_mobile/widgets/common/immich_app_bar.dart'; import 'package:immich_mobile/widgets/common/immich_app_bar.dart';
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart'; import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
@ -229,13 +230,11 @@ class AlbumsPage extends HookConsumerWidget {
), ),
subtitle: sorted[index].ownerId != null subtitle: sorted[index].ownerId != null
? Text( ? Text(
'${(sorted[index].assetCount == 1 ? 'album_thumbnail_card_item'.tr() : 'album_thumbnail_card_items'.tr( '${t('items_count', {
namedArgs: { 'count': sorted[index].assetCount,
'count': sorted[index] })} ${sorted[index].ownerId != userId ? t('shared_by_user', {
.assetCount 'user': sorted[index].ownerName!,
.toString(), }) : 'owned'.tr()}',
},
))} ${sorted[index].ownerId != userId ? 'album_thumbnail_shared_by'.tr(namedArgs: {'user': sorted[index].ownerName!}) : 'owned'.tr()}',
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: style:
context.textTheme.bodyMedium?.copyWith( context.textTheme.bodyMedium?.copyWith(

View File

@ -5,6 +5,7 @@ import 'package:immich_mobile/entities/album.entity.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/utils/translation.dart';
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart'; import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
class AlbumThumbnailCard extends ConsumerWidget { class AlbumThumbnailCard extends ConsumerWidget {
@ -61,28 +62,24 @@ class AlbumThumbnailCard extends ConsumerWidget {
if (album.ownerId == ref.read(currentUserProvider)?.id) { if (album.ownerId == ref.read(currentUserProvider)?.id) {
owner = 'owned'.tr(); owner = 'owned'.tr();
} else if (album.ownerName != null) { } else if (album.ownerName != null) {
owner = 'album_thumbnail_shared_by' owner = t('shared_by_user', {'user': album.ownerName!});
.tr(namedArgs: {'user': album.ownerName!});
} }
} }
return RichText( return Text.rich(
overflow: TextOverflow.fade, TextSpan(
text: TextSpan(
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
children: [ children: [
TextSpan( TextSpan(
text: album.assetCount == 1 text: t('items_count', {'count': album.assetCount}),
? 'album_thumbnail_card_item'.tr()
: 'album_thumbnail_card_items'
.tr(namedArgs: {'count': '${album.assetCount}'}),
), ),
if (owner != null) const TextSpan(text: ''), if (owner != null) const TextSpan(text: ''),
if (owner != null) TextSpan(text: owner), if (owner != null) TextSpan(text: owner),
], ],
style: context.textTheme.bodyMedium?.copyWith(
color: context.colorScheme.onSurfaceSecondary,
),
), ),
overflow: TextOverflow.fade,
); );
} }

View File

@ -7,6 +7,7 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/utils/image_url_builder.dart'; import 'package:immich_mobile/utils/image_url_builder.dart';
import 'package:immich_mobile/utils/translation.dart';
import 'package:openapi/api.dart'; import 'package:openapi/api.dart';
class AlbumThumbnailListTile extends StatelessWidget { class AlbumThumbnailListTile extends StatelessWidget {
@ -90,20 +91,25 @@ class AlbumThumbnailListTile extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
album.assetCount == 1 t('items_count', {'count': album.assetCount}),
? 'album_thumbnail_card_item'
: 'album_thumbnail_card_items',
style: const TextStyle( style: const TextStyle(
fontSize: 12, fontSize: 12,
), ),
).tr(namedArgs: {'count': '${album.assetCount}'}), ),
if (album.shared) if (album.shared) ...[
const Text( const Text(
'album_thumbnail_card_shared', '',
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
), ),
).tr(), ),
Text(
'shared'.tr(),
style: const TextStyle(
fontSize: 12,
),
),
],
], ],
), ),
], ],

View File

@ -1,8 +1,9 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/backup/ios_background_settings.provider.dart'; import 'package:immich_mobile/providers/backup/ios_background_settings.provider.dart';
import 'package:intl/intl.dart'; import 'package:immich_mobile/utils/translation.dart';
/// This is a simple debug widget which should be removed later on when we are /// This is a simple debug widget which should be removed later on when we are
/// more confident about background sync /// more confident about background sync
@ -19,26 +20,35 @@ class IosDebugInfoTile extends HookConsumerWidget {
final processing = settings.timeOfLastProcessing; final processing = settings.timeOfLastProcessing;
final processes = settings.numberOfBackgroundTasksQueued; final processes = settings.numberOfBackgroundTasksQueued;
final processOrProcesses = processes == 1 ? 'process' : 'processes'; final String title;
final numberOrZero = processes == 0 ? 'No' : processes.toString(); if (processes == 0) {
final title = '$numberOrZero background $processOrProcesses queued'; title = 'ios_debug_info_no_processes_queued'.tr();
} else {
title = t('ios_debug_info_processes_queued', {'count': processes});
}
final df = DateFormat.yMd().add_jm(); final df = DateFormat.yMd().add_jm();
final String subtitle; final String subtitle;
if (fetch == null && processing == null) { if (fetch == null && processing == null) {
subtitle = 'No background sync job has run yet'; subtitle = 'ios_debug_info_no_sync_yet'.tr();
} else if (fetch != null && processing == null) { } else if (fetch != null && processing == null) {
subtitle = 'Fetch ran ${df.format(fetch)}'; subtitle =
t('ios_debug_info_fetch_ran_at', {'dateTime': df.format(fetch)});
} else if (processing != null && fetch == null) { } else if (processing != null && fetch == null) {
subtitle = 'Processing ran ${df.format(processing)}'; subtitle = t(
'ios_debug_info_processing_ran_at',
{'dateTime': df.format(processing)},
);
} else { } else {
final fetchOrProcessing = final fetchOrProcessing =
fetch!.isAfter(processing!) ? fetch : processing; fetch!.isAfter(processing!) ? fetch : processing;
subtitle = 'Last sync ${df.format(fetchOrProcessing)}'; subtitle = t(
'ios_debug_info_last_sync_at',
{'dateTime': df.format(fetchOrProcessing)},
);
} }
return ListTile( return ListTile(
key: ValueKey(title),
title: Text( title: Text(
title, title,
style: TextStyle( style: TextStyle(

View File

@ -56,6 +56,6 @@
<MenuOption <MenuOption
onClick={() => toggleLockedVisibility()} onClick={() => toggleLockedVisibility()}
text={isLocked ? $t('move_off_locked_folder') : $t('add_to_locked_folder')} text={isLocked ? $t('move_off_locked_folder') : $t('move_to_locked_folder')}
icon={isLocked ? mdiLockOpenVariantOutline : mdiLockOutline} icon={isLocked ? mdiLockOpenVariantOutline : mdiLockOutline}
/> />

View File

@ -55,7 +55,7 @@
{#if menuItem} {#if menuItem}
<MenuOption <MenuOption
onClick={setLockedVisibility} onClick={setLockedVisibility}
text={unlock ? $t('move_off_locked_folder') : $t('add_to_locked_folder')} text={unlock ? $t('move_off_locked_folder') : $t('move_to_locked_folder')}
icon={unlock ? mdiLockOpenVariantOutline : mdiLockOutline} icon={unlock ? mdiLockOpenVariantOutline : mdiLockOutline}
/> />
{:else} {:else}
@ -67,6 +67,6 @@
variant="ghost" variant="ghost"
onclick={setLockedVisibility} onclick={setLockedVisibility}
> >
{unlock ? $t('move_off_locked_folder') : $t('add_to_locked_folder')} {unlock ? $t('move_off_locked_folder') : $t('move_to_locked_folder')}
</Button> </Button>
{/if} {/if}