diff --git a/ElementX/Resources/Localizations/de.lproj/Localizable.strings b/ElementX/Resources/Localizations/de.lproj/Localizable.strings index df111b224..3b86ead5f 100644 --- a/ElementX/Resources/Localizations/de.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/de.lproj/Localizable.strings @@ -49,6 +49,7 @@ "common_audio" = "Audio"; "common_bubbles" = "Bubbles"; "common_creating_room" = "Creating room…"; +"common_current_user_left_room" = "Left room"; "common_decryption_error" = "Decryption error"; "common_developer_options" = "Developer options"; "common_edited_suffix" = "(edited)"; @@ -276,3 +277,5 @@ "state_event_room_unban" = "%1$@ unbanned %2$@"; "state_event_room_unban_by_you" = "You unbanned %1$@"; "state_event_room_unknown_membership_change" = "%1$@ made an unknown change to their membership"; +"test_language_identifier" = "de"; +"test_untranslated_default_language_identifier" = "en"; diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index 6c634e18e..cb46efeec 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -49,6 +49,7 @@ "common_audio" = "Audio"; "common_bubbles" = "Bubbles"; "common_creating_room" = "Creating room…"; +"common_current_user_left_room" = "Left room"; "common_decryption_error" = "Decryption error"; "common_developer_options" = "Developer options"; "common_edited_suffix" = "(edited)"; @@ -276,3 +277,5 @@ "state_event_room_unban" = "%1$@ unbanned %2$@"; "state_event_room_unban_by_you" = "You unbanned %1$@"; "state_event_room_unknown_membership_change" = "%1$@ made an unknown change to their membership"; +"test_language_identifier" = "en"; +"test_untranslated_default_language_identifier" = "en"; diff --git a/ElementX/Resources/Localizations/fr.lproj/Localizable.strings b/ElementX/Resources/Localizations/fr.lproj/Localizable.strings index f57223b3a..5b5c10533 100644 --- a/ElementX/Resources/Localizations/fr.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/fr.lproj/Localizable.strings @@ -49,6 +49,7 @@ "common_audio" = "Audio"; "common_bubbles" = "Bubbles"; "common_creating_room" = "Creating room…"; +"common_current_user_left_room" = "Left room"; "common_decryption_error" = "Decryption error"; "common_developer_options" = "Developer options"; "common_edited_suffix" = "(edited)"; @@ -276,3 +277,5 @@ "state_event_room_unban" = "%1$@ unbanned %2$@"; "state_event_room_unban_by_you" = "You unbanned %1$@"; "state_event_room_unknown_membership_change" = "%1$@ made an unknown change to their membership"; +"test_language_identifier" = "fr"; +"test_untranslated_default_language_identifier" = "en"; diff --git a/ElementX/Resources/Localizations/it.lproj/Localizable.strings b/ElementX/Resources/Localizations/it.lproj/Localizable.strings index 03344d212..b8da99e1d 100644 --- a/ElementX/Resources/Localizations/it.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/it.lproj/Localizable.strings @@ -1,278 +1,281 @@ -"Notification" = "NOTIFICA"; +"Notification" = "Notifica"; "a11y_hide_password" = "Nascondi password"; -"a11y_send_files" = "Send files"; -"a11y_show_password" = "Show password"; -"a11y_user_menu" = "User menu"; -"action_back" = "Back"; -"action_cancel" = "Cancel"; -"action_clear" = "Clear"; -"action_close" = "Close"; -"action_complete_verification" = "Complete verification"; -"action_confirm" = "Confirm"; -"action_continue" = "Continue"; -"action_copy" = "Copy"; -"action_copy_link" = "Copy link"; -"action_create_a_room" = "Create a room"; -"action_disable" = "Disable"; -"action_done" = "Done"; -"action_edit" = "Edit"; -"action_enable" = "Enable"; -"action_invite" = "Invite"; -"action_invite_friends_to_app" = "Invite friends to %1$@"; -"action_learn_more" = "Learn more"; -"action_leave" = "Leave"; -"action_leave_room" = "Leave room"; -"action_next" = "Next"; +"a11y_send_files" = "Invia file"; +"a11y_show_password" = "Mostra password"; +"a11y_user_menu" = "Menu utente"; +"action_back" = "Indietro"; +"action_cancel" = "Annulla"; +"action_clear" = "Cancella"; +"action_close" = "Chiudi"; +"action_complete_verification" = "Completa verifica"; +"action_confirm" = "Conferma"; +"action_continue" = "Continua"; +"action_copy" = "Copia"; +"action_copy_link" = "Copia collegamento"; +"action_create_a_room" = "Crea una stanza"; +"action_disable" = "Disabilita"; +"action_done" = "Fine"; +"action_edit" = "Modifica"; +"action_enable" = "Attiva"; +"action_invite" = "Invita"; +"action_invite_friends_to_app" = "Invita amici a %1$@"; +"action_learn_more" = "Ulteriori informazioni"; +"action_leave" = "Esci"; +"action_leave_room" = "Esci dalla stanza"; +"action_next" = "Avanti"; "action_no" = "No"; -"action_not_now" = "Not now"; +"action_not_now" = "Non ora"; "action_ok" = "OK"; -"action_quick_reply" = "Quick reply"; -"action_quote" = "Quote"; -"action_remove" = "Remove"; -"action_reply" = "Reply"; -"action_report_bug" = "Report bug"; -"action_report_content" = "Report Content"; -"action_retry" = "Retry"; -"action_retry_decryption" = "Retry decryption"; -"action_save" = "Save"; -"action_search" = "Search"; -"action_send" = "Send"; -"action_share" = "Share"; -"action_share_link" = "Share link"; -"action_skip" = "Skip"; -"action_start" = "Start"; -"action_start_chat" = "Start chat"; -"action_start_verification" = "Start verification"; -"action_view_source" = "View Source"; -"action_yes" = "Yes"; -"common_about" = "About"; +"action_quick_reply" = "Risposta rapida"; +"action_quote" = "Citazione"; +"action_remove" = "Rimuovi"; +"action_reply" = "Rispondi"; +"action_report_bug" = "Segnala un problema"; +"action_report_content" = "Segnala Contenuto"; +"action_retry" = "Riprova"; +"action_retry_decryption" = "Riprova la decrittazione"; +"action_save" = "Salva"; +"action_search" = "Ricerca"; +"action_send" = "Invia"; +"action_share" = "Condividi"; +"action_share_link" = "Condividi collegamento"; +"action_skip" = "Salta"; +"action_start" = "Inizia"; +"action_start_chat" = "Avvia conversazione"; +"action_start_verification" = "Avvia la verifica"; +"action_view_source" = "Vedi Sorgente"; +"action_yes" = "Sì"; +"common_about" = "Informazioni"; "common_audio" = "Audio"; -"common_bubbles" = "Bubbles"; -"common_creating_room" = "Creating room…"; -"common_decryption_error" = "Decryption error"; -"common_developer_options" = "Developer options"; -"common_edited_suffix" = "(edited)"; -"common_editing" = "Editing"; -"common_encryption_enabled" = "Encryption enabled"; -"common_error" = "Error"; +"common_bubbles" = "Fumetti"; +"common_creating_room" = "Creazione stanza..."; +"common_current_user_left_room" = "Hai lasciato la stanza"; +"common_decryption_error" = "Errore di decrittazione"; +"common_developer_options" = "Opzioni sviluppatore"; +"common_edited_suffix" = "(modificato)"; +"common_editing" = "Modifica in corso"; +"common_encryption_enabled" = "Crittografia abilitata"; +"common_error" = "Errore"; "common_file" = "File"; "common_gif" = "GIF"; -"common_image" = "Image"; -"common_link_copied_to_clipboard" = "Link copied to clipboard"; -"common_loading" = "Loading…"; -"common_message" = "Message"; -"common_message_layout" = "Message layout"; -"common_message_removed" = "Message removed"; -"common_modern" = "Modern"; -"common_no_results" = "No results"; -"common_offline" = "Offline"; +"common_image" = "Immagine"; +"common_link_copied_to_clipboard" = "Collegamento copiato negli appunti"; +"common_loading" = "Caricamento…"; +"common_message" = "Messaggio"; +"common_message_layout" = "Layout del messaggio"; +"common_message_removed" = "Messaggio rimosso"; +"common_modern" = "Moderno"; +"common_no_results" = "Nessun risultato"; +"common_offline" = "Non in linea"; "common_password" = "Password"; -"common_people" = "People"; -"common_permalink" = "Permalink"; -"common_reactions" = "Reactions"; -"common_replying_to" = "Replying to %1$@"; -"common_report_a_bug" = "Report a bug"; -"common_report_submitted" = "Report submitted"; -"common_search_for_someone" = "Search for someone"; -"common_security" = "Security"; -"common_select_your_server" = "Select your server"; -"common_sending" = "Sending…"; -"common_server_not_supported" = "Server not supported"; -"common_server_url" = "Server URL"; -"common_settings" = "Settings"; -"common_sticker" = "Sticker"; -"common_success" = "Success"; -"common_suggestions" = "Suggestions"; -"common_topic" = "Topic"; -"common_unable_to_decrypt" = "Unable to decrypt"; -"common_unsupported_event" = "Unsupported event"; -"common_username" = "Username"; -"common_verification_cancelled" = "Verification cancelled"; -"common_verification_complete" = "Verification complete"; +"common_people" = "Persone"; +"common_permalink" = "Collegamento permanente"; +"common_reactions" = "Reazioni"; +"common_replying_to" = "Risposta a %1$@"; +"common_report_a_bug" = "Segnala un problema"; +"common_report_submitted" = "Segnalazione inviata"; +"common_search_for_someone" = "Cerca qualcuno"; +"common_security" = "Sicurezza"; +"common_select_your_server" = "Seleziona il tuo server"; +"common_sending" = "Invio in corso…"; +"common_server_not_supported" = "Server non supportato"; +"common_server_url" = "URL del server"; +"common_settings" = "Impostazioni"; +"common_sticker" = "Adesivo"; +"common_success" = "Operazione riuscita"; +"common_suggestions" = "Suggerimenti"; +"common_topic" = "Oggetto"; +"common_unable_to_decrypt" = "Impossibile decrittografare"; +"common_unsupported_event" = "Evento non supportato"; +"common_username" = "Nome utente"; +"common_verification_cancelled" = "Verifica annullata"; +"common_verification_complete" = "Verifica completata"; "common_video" = "Video"; -"common_waiting" = "Waiting…"; -"crash_detection_dialog_content" = "%1$@ crashed the last time it was used. Would you like to share a crash report with us?"; -"dialog_title_confirmation" = "Confirmation"; -"dialog_title_error" = "Error"; -"dialog_title_success" = "Success"; -"dialog_title_warning" = "Warning"; -"emoji_picker_category_activity" = "Activities"; -"emoji_picker_category_flags" = "Flags"; -"emoji_picker_category_foods" = "Food & Drink"; -"emoji_picker_category_nature" = "Animals & Nature"; -"emoji_picker_category_objects" = "Objects"; -"emoji_picker_category_people" = "Smileys & People"; -"emoji_picker_category_places" = "Travel & Places"; -"emoji_picker_category_symbols" = "Symbols"; -"error_failed_creating_the_permalink" = "Failed creating the permalink"; -"error_failed_loading_messages" = "Failed loading messages"; -"error_no_compatible_app_found" = "No compatible app was found to handle this action."; -"error_some_messages_have_not_been_sent" = "Some messages have not been sent"; -"error_unknown" = "Sorry, an error occurred"; -"invite_friends_text" = "Hey, talk to me on %1$@: %2$@"; -"leave_room_alert_empty_subtitle" = "Are you sure that you want to leave this room? You are the only person here. If you leave, no one will be able to join in the future, including you."; -"leave_room_alert_private_subtitle" = "Are you sure that you want to leave this room? This room is not public and you will not be able to rejoin without an invite."; -"leave_room_alert_subtitle" = "Are you sure that you want to leave the room?"; +"common_waiting" = "In attesa…"; +"crash_detection_dialog_content" = "%1$@ si è chiuso inaspettatamente l'ultima volta che è stato usato. Vuoi condividere con noi un rapporto sull'arresto anomalo?"; +"dialog_title_confirmation" = "Conferma"; +"dialog_title_error" = "Errore"; +"dialog_title_success" = "Operazione riuscita"; +"dialog_title_warning" = "Attenzione"; +"emoji_picker_category_activity" = "Attività"; +"emoji_picker_category_flags" = "Bandiere"; +"emoji_picker_category_foods" = "Cibi & Bevande"; +"emoji_picker_category_nature" = "Animali & Natura"; +"emoji_picker_category_objects" = "Oggetti"; +"emoji_picker_category_people" = "Faccine & Persone"; +"emoji_picker_category_places" = "Viaggi & Luoghi"; +"emoji_picker_category_symbols" = "Simboli"; +"error_failed_creating_the_permalink" = "Impossibile creare il collegamento permanente"; +"error_failed_loading_messages" = "Caricamento dei messaggi non riuscito"; +"error_no_compatible_app_found" = "Non è stata trovata alcuna app compatibile per gestire questa azione."; +"error_some_messages_have_not_been_sent" = "Alcuni messaggi non sono stati inviati"; +"error_unknown" = "Siamo spiacenti, si è verificato un errore"; +"invite_friends_text" = "Ehi, parlami su %1$@: %2$@"; +"leave_room_alert_empty_subtitle" = "Sei sicuro di voler lasciare questa stanza? Sei l'unica persona presente. Se esci, nessuno potrà unirsi in futuro, te compreso."; +"leave_room_alert_private_subtitle" = "Sei sicuro di voler lasciare questa stanza? Questa stanza non è pubblica e non potrai rientrare senza un invito."; +"leave_room_alert_subtitle" = "Sei sicuro di voler lasciare la stanza?"; "login_initial_device_name_ios" = "%1$@ iOS"; -"preference_rageshake" = "Rageshake to report bug"; -"rageshake_detection_dialog_content" = "You seem to be shaking the phone in frustration. Would you like to open the bug report screen?"; -"rageshake_dialog_content" = "You seem to be shaking the phone in frustration. Would you like to open the bug report screen?"; -"report_content_explanation" = "This message will be reported to your homeserver’s administrator. They will not be able to read any encrypted messages."; -"report_content_hint" = "Reason for reporting this content"; -"rich_text_editor_bullet_list" = "Toggle bullet list"; -"rich_text_editor_code_block" = "Toggle code block"; -"rich_text_editor_composer_placeholder" = "Message…"; -"rich_text_editor_format_bold" = "Apply bold format"; -"rich_text_editor_format_italic" = "Apply italic format"; -"rich_text_editor_format_strikethrough" = "Apply strikethrough format"; -"rich_text_editor_format_underline" = "Apply underline format"; -"rich_text_editor_full_screen_toggle" = "Toggle full screen mode"; -"rich_text_editor_indent" = "Indent"; -"rich_text_editor_inline_code" = "Apply inline code format"; -"rich_text_editor_link" = "Set link"; -"rich_text_editor_numbered_list" = "Toggle numbered list"; -"rich_text_editor_quote" = "Toggle quote"; -"rich_text_editor_unindent" = "Unindent"; -"room_timeline_beginning_of_room" = "This is the beginning of %1$@."; -"room_timeline_beginning_of_room_no_name" = "This is the beginning of this conversation."; -"room_timeline_read_marker_title" = "New"; -"screen_bug_report_attach_screenshot" = "Attach screenshot"; -"screen_bug_report_contact_me" = "You may contact me if you have any follow up questions"; -"screen_bug_report_edit_screenshot" = "Edit screenshot"; -"screen_bug_report_editor_description" = "Please describe the bug. What did you do? What did you expect to happen? What actually happened. Please go into as much detail as you can."; -"screen_bug_report_editor_placeholder" = "Describe the bug…"; -"screen_bug_report_editor_supporting" = "If possible, please write the description in English."; -"screen_bug_report_include_crash_logs" = "Send crash logs"; -"screen_bug_report_include_logs" = "Send logs to help"; -"screen_bug_report_include_screenshot" = "Send screenshot"; -"screen_bug_report_logs_description" = "To check things work as intended, logs will be sent with your message. These will be private. To just send your message, turn off this setting."; -"screen_bug_report_rash_logs_alert_title" = "%1$@ crashed the last time it was used. Would you like to share a crash report with us?"; -"screen_change_server_error_invalid_homeserver" = "We couldn't reach this homeserver. Please check that you have entered the homeserver URL correctly. If the URL is correct, contact your homeserver administrator for further help."; -"screen_change_server_error_no_sliding_sync_message" = "This server currently doesn’t support sliding sync."; -"screen_change_server_form_header" = "Homeserver URL"; -"screen_change_server_form_notice" = "You can only connect to an existing server that supports sliding sync. Your homeserver admin will need to configure it. %1$@"; -"screen_change_server_submit" = "Continue"; -"screen_change_server_subtitle" = "What is the address of your server?"; -"screen_change_server_title" = "Select your server"; -"screen_create_room_action_create_room" = "New room"; -"screen_create_room_action_invite_people" = "Invite people"; -"screen_create_room_add_people_title" = "Add people"; -"screen_dm_details_block_alert_action" = "Block"; -"screen_dm_details_block_alert_description" = "Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime."; -"screen_dm_details_block_user" = "Block user"; -"screen_dm_details_unblock_alert_action" = "Unblock"; -"screen_dm_details_unblock_alert_description" = "On unblocking the user, you will be able to see all messages by them again."; -"screen_dm_details_unblock_user" = "Unblock user"; -"screen_login_error_deactivated_account" = "This account has been deactivated."; -"screen_login_error_invalid_credentials" = "Incorrect username and/or password"; -"screen_login_error_invalid_user_id" = "This is not a valid user identifier. Expected format: ‘@user:homeserver.org’"; -"screen_login_error_unsupported_authentication" = "The selected homeserver doesn't support password or OIDC login. Please contact your admin or choose another homeserver."; -"screen_login_form_header" = "Enter your details"; +"preference_rageshake" = "Scuoti per segnalare un problema"; +"rageshake_detection_dialog_content" = "Sembra che tu stia scuotendo il telefono per la frustrazione. Vuoi aprire la schermata di segnalazione dei problemi?"; +"rageshake_dialog_content" = "Sembra che tu stia scuotendo il telefono per la frustrazione. Vuoi aprire la schermata di segnalazione dei problemi?"; +"report_content_explanation" = "Questo messaggio verrà segnalato all'amministratore dell'homeserver. Questi non sarà in grado di leggere i messaggi criptati."; +"report_content_hint" = "Motivo della segnalazione di questo contenuto"; +"rich_text_editor_bullet_list" = "Attiva/disattiva l'elenco puntato"; +"rich_text_editor_code_block" = "Attiva/disattiva il blocco di codice"; +"rich_text_editor_composer_placeholder" = "Messaggio…"; +"rich_text_editor_format_bold" = "Applica il formato in grassetto"; +"rich_text_editor_format_italic" = "Applicare il formato corsivo"; +"rich_text_editor_format_strikethrough" = "Applica il formato barrato"; +"rich_text_editor_format_underline" = "Applicare il formato di sottolineatura"; +"rich_text_editor_full_screen_toggle" = "Attiva/disattiva la modalità a schermo intero"; +"rich_text_editor_indent" = "Rientro a destra"; +"rich_text_editor_inline_code" = "Applicare il formato del codice in linea"; +"rich_text_editor_link" = "Imposta collegamento"; +"rich_text_editor_numbered_list" = "Attiva/disattiva elenco numerato"; +"rich_text_editor_quote" = "Attiva/disattiva citazione"; +"rich_text_editor_unindent" = "Rientro a sinistra"; +"room_timeline_beginning_of_room" = "Questo è l'inizio di %1$@."; +"room_timeline_beginning_of_room_no_name" = "Questo è l'inizio della conversazione."; +"room_timeline_read_marker_title" = "Nuovo"; +"screen_bug_report_attach_screenshot" = "Allega istantanea schermo"; +"screen_bug_report_contact_me" = "Potete contattarmi per qualsiasi altra domanda"; +"screen_bug_report_edit_screenshot" = "Modifica istantanea schermo"; +"screen_bug_report_editor_description" = "Descrivi il bug. Che cosa hai fatto? Cosa ti aspettavi che accadesse? Cosa è effettivamente accaduto. Si prega di inserire il maggior numero di dettagli possibile."; +"screen_bug_report_editor_placeholder" = "Descrivi il problema..."; +"screen_bug_report_editor_supporting" = "Se possibile, scrivere la descrizione in inglese."; +"screen_bug_report_include_crash_logs" = "Invia i log degli arresti anomali"; +"screen_bug_report_include_logs" = "Invia i log per aiutarci"; +"screen_bug_report_include_screenshot" = "Invia istantanea schermo"; +"screen_bug_report_logs_description" = "Per verificare che le cose funzionino come previsto, i log verranno inviati con il tuo messaggio. Questi saranno privati. Per inviare solo il tuo messaggio, disattiva questa impostazione."; +"screen_bug_report_rash_logs_alert_title" = "%1$@ si è chiuso inaspettatamente l'ultima volta che è stato usato. Vuoi condividere con noi un rapporto sull'arresto anomalo?"; +"screen_change_server_error_invalid_homeserver" = "Non siamo riusciti a raggiungere questo homserver. Verifica di aver inserito correttamente l'URL del server domestico. Se l'URL è corretto, contatta l'amministratore del tuo server domestico per ulteriore assistenza."; +"screen_change_server_error_no_sliding_sync_message" = "Questo server attualmente non supporta la sincronizzazione scorrevole."; +"screen_change_server_form_header" = "URL dell'homeserver"; +"screen_change_server_form_notice" = "Puoi connetterti solo a un server esistente che supporta la sincronizzazione scorrevole. L'amministratore del tuo server domestico dovrà configurarlo. %1$@"; +"screen_change_server_submit" = "Continua"; +"screen_change_server_subtitle" = "Qual è l'indirizzo del tuo server?"; +"screen_change_server_title" = "Seleziona il tuo server"; +"screen_create_room_action_create_room" = "Nuova stanza"; +"screen_create_room_action_invite_people" = "Invita persone"; +"screen_create_room_add_people_title" = "Aggiungi persone"; +"screen_dm_details_block_alert_action" = "Blocca"; +"screen_dm_details_block_alert_description" = "Gli utenti bloccati non saranno in grado di inviarti messaggi e tutti i loro messaggi saranno nascosti. Potrai annullare questa azione in qualsiasi momento."; +"screen_dm_details_block_user" = "Blocca utente"; +"screen_dm_details_unblock_alert_action" = "Sblocca"; +"screen_dm_details_unblock_alert_description" = "Dopo aver sbloccato l'utente, potrai vedere nuovamente tutti i suoi messaggi."; +"screen_dm_details_unblock_user" = "Sblocca utente"; +"screen_login_error_deactivated_account" = "Questo profilo è stato disattivato."; +"screen_login_error_invalid_credentials" = "Nome utente e/o password errati"; +"screen_login_error_invalid_user_id" = "Questo non è un identificatore utente valido. Formato previsto: '@user:homeserver.org'"; +"screen_login_error_unsupported_authentication" = "L'homeserver selezionato non supporta la password o l'accesso OIDC. Contatta il tuo amministratore o scegli un altro homeserver."; +"screen_login_form_header" = "Inserisci i tuoi dati"; "screen_login_password_hint" = "Password"; -"screen_login_server_header" = "Where your conversations live"; -"screen_login_submit" = "Continue"; -"screen_login_title" = "Welcome back!"; -"screen_login_username_hint" = "Username"; -"screen_onboarding_welcome_subtitle" = "Welcome to the %1$@ Beta. Supercharged, for speed and simplicity."; -"screen_onboarding_welcome_title" = "Be in your Element"; -"screen_report_content_block_user" = "Block user"; -"screen_report_content_block_user_hint" = "Check if you want to hide all current and future messages from this user"; -"screen_room_details_encryption_enabled_subtitle" = "Messages are secured with locks. Only you and the recipients have the unique keys to unlock them."; -"screen_room_details_encryption_enabled_title" = "Message encryption enabled"; -"screen_room_details_invite_people_title" = "Invite people"; -"screen_room_details_leave_room_title" = "Leave room"; -"screen_room_details_people_title" = "People"; -"screen_room_details_security_title" = "Security"; -"screen_room_details_share_room_title" = "Share room"; -"screen_room_details_topic_title" = "Topic"; -"screen_room_member_details_block_alert_action" = "Block"; -"screen_room_member_details_block_alert_description" = "Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime."; -"screen_room_member_details_block_user" = "Block user"; -"screen_room_member_details_unblock_alert_action" = "Unblock"; -"screen_room_member_details_unblock_alert_description" = "On unblocking the user, you will be able to see all messages by them again."; -"screen_room_member_details_unblock_user" = "Unblock user"; -"screen_roomlist_a11y_create_message" = "Create a new conversation or room"; -"screen_roomlist_main_space_title" = "All Chats"; -"screen_session_verification_cancelled_subtitle" = "Something doesn’t seem right. Either the request timed out or the request was denied."; -"screen_session_verification_cancelled_title" = "Verification cancelled"; -"screen_session_verification_compare_emojis_subtitle" = "Confirm that the emojis below match those shown on your other session."; -"screen_session_verification_compare_emojis_title" = "Compare emojis"; -"screen_session_verification_complete_subtitle" = "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted."; -"screen_session_verification_open_existing_session_subtitle" = "Prove it’s you in order to access your encrypted message history."; -"screen_session_verification_open_existing_session_title" = "Open an existing session"; -"screen_session_verification_positive_button_canceled" = "Retry verification"; -"screen_session_verification_positive_button_initial" = "I am ready"; -"screen_session_verification_positive_button_ready" = "Start"; -"screen_session_verification_positive_button_verifying_ongoing" = "Waiting to match"; -"screen_session_verification_request_accepted_subtitle" = "Compare the unique emoji, ensuring they appear in the same order."; -"screen_session_verification_they_dont_match" = "They don’t match"; -"screen_session_verification_they_match" = "They match"; -"screen_session_verification_waiting_to_accept_subtitle" = "Accept the request to start the verification process in your other session to continue."; -"screen_session_verification_waiting_to_accept_title" = "Waiting to accept request"; -"screen_signout_confirmation_dialog_content" = "Are you sure you want to sign out?"; -"screen_signout_confirmation_dialog_submit" = "Sign out"; -"screen_signout_confirmation_dialog_title" = "Sign out"; -"screen_signout_in_progress_dialog_content" = "Signing out…"; -"screen_signout_preference_item" = "Sign out"; -"screen_start_chat_error_starting_chat" = "An error occurred when trying to start a chat"; -"screen_start_chat_unknown_profile" = "We can’t validate this user’s Matrix ID. The invite might not be received."; -"session_verification_banner_message" = "Looks like you’re using a new device. Verify it’s you to access your encrypted messages."; -"session_verification_banner_title" = "Access your message history"; +"screen_login_server_header" = "Dove vivono le tue conversazioni"; +"screen_login_submit" = "Continua"; +"screen_login_title" = "Bentornato!"; +"screen_login_username_hint" = "Nome utente"; +"screen_onboarding_welcome_subtitle" = "Benvenuto nella beta di %1$@. Potenziato in velocità e semplicità."; +"screen_onboarding_welcome_title" = "Sii nel tuo elemento"; +"screen_report_content_block_user" = "Blocca utente"; +"screen_report_content_block_user_hint" = "Seleziona se vuoi nascondere tutti i messaggi attuali e futuri di questo utente"; +"screen_room_details_encryption_enabled_subtitle" = "I messaggi sono protetti da lucchetti. Solo tu e i destinatari avete le chiavi univoche per sbloccarli."; +"screen_room_details_encryption_enabled_title" = "Crittografia messaggi abilitata"; +"screen_room_details_invite_people_title" = "Invita persone"; +"screen_room_details_leave_room_title" = "Esci dalla stanza"; +"screen_room_details_people_title" = "Persone"; +"screen_room_details_security_title" = "Sicurezza"; +"screen_room_details_share_room_title" = "Condividi stanza"; +"screen_room_details_topic_title" = "Oggetto"; +"screen_room_member_details_block_alert_action" = "Blocca"; +"screen_room_member_details_block_alert_description" = "Gli utenti bloccati non saranno in grado di inviarti nuovi messaggi e tutti quelli già esistenti saranno nascosti. Potrai annullare questa azione in qualsiasi momento."; +"screen_room_member_details_block_user" = "Blocca utente"; +"screen_room_member_details_unblock_alert_action" = "Sblocca"; +"screen_room_member_details_unblock_alert_description" = "Dopo aver sbloccato l'utente, potrai vedere nuovamente tutti i suoi messaggi."; +"screen_room_member_details_unblock_user" = "Sblocca utente"; +"screen_roomlist_a11y_create_message" = "Crea una nuova conversazione o stanza"; +"screen_roomlist_main_space_title" = "Tutte le conversazioni"; +"screen_session_verification_cancelled_subtitle" = "C'è qualcosa che non va. La richiesta è scaduta o è stata rifiutata."; +"screen_session_verification_cancelled_title" = "Verifica annullata"; +"screen_session_verification_compare_emojis_subtitle" = "Verifica che gli emoji sottostanti corrispondano a quelli mostrati nell'altra sessione."; +"screen_session_verification_compare_emojis_title" = "Confronta le emoji"; +"screen_session_verification_complete_subtitle" = "La tua nuova sessione è ora verificata. Ha accesso ai tuoi messaggi crittografati e gli altri utenti la vedranno come attendibile."; +"screen_session_verification_open_existing_session_subtitle" = "Dimostra la tua identità per accedere alla cronologia dei messaggi crittografati."; +"screen_session_verification_open_existing_session_title" = "Apri una sessione esistente"; +"screen_session_verification_positive_button_canceled" = "Riprova la verifica"; +"screen_session_verification_positive_button_initial" = "Sono pronto"; +"screen_session_verification_positive_button_ready" = "Inizia"; +"screen_session_verification_positive_button_verifying_ongoing" = "In attesa di un riscontro"; +"screen_session_verification_request_accepted_subtitle" = "Confronta le emoji uniche, assicurandoti che appaiano nello stesso ordine."; +"screen_session_verification_they_dont_match" = "Non corrispondono"; +"screen_session_verification_they_match" = "Corrispondono"; +"screen_session_verification_waiting_to_accept_subtitle" = "Accetta la richiesta di avviare il processo di verifica nell'altra sessione per continuare."; +"screen_session_verification_waiting_to_accept_title" = "In attesa di accettare la richiesta"; +"screen_signout_confirmation_dialog_content" = "Sei sicuro di voler uscire?"; +"screen_signout_confirmation_dialog_submit" = "Esci"; +"screen_signout_confirmation_dialog_title" = "Esci"; +"screen_signout_in_progress_dialog_content" = "Uscita in corso..."; +"screen_signout_preference_item" = "Esci"; +"screen_start_chat_error_starting_chat" = "Si è verificato un errore durante il tentativo di avviare una chat"; +"screen_start_chat_unknown_profile" = "Non possiamo convalidare l'ID Matrix di questo utente. L'invito potrebbe non essere ricevuto."; +"session_verification_banner_message" = "Sembra che tu stia utilizzando un nuovo dispositivo. Verifica di essere tu per accedere ai tuoi messaggi crittografati."; +"session_verification_banner_title" = "Accedi alla cronologia dei messaggi"; "settings_rageshake" = "Rageshake"; -"settings_rageshake_detection_threshold" = "Detection threshold"; -"settings_title_general" = "General"; -"settings_version_number" = "Version: %1$@ (%2$@)"; -"state_event_avatar_changed_too" = "(avatar was changed too)"; -"state_event_avatar_url_changed" = "%1$@ changed their avatar"; -"state_event_avatar_url_changed_by_you" = "You changed your avatar"; -"state_event_display_name_changed_from" = "%1$@ changed their display name from %2$@ to %3$@"; -"state_event_display_name_changed_from_by_you" = "You changed your display name from %1$@ to %2$@"; -"state_event_display_name_removed" = "%1$@ removed their display name (it was %2$@)"; -"state_event_display_name_removed_by_you" = "You removed your display name (it was %1$@)"; -"state_event_display_name_set" = "%1$@ set their display name to %2$@"; -"state_event_display_name_set_by_you" = "You set your display name to %1$@"; -"state_event_room_avatar_changed" = "%1$@ changed the room avatar"; -"state_event_room_avatar_changed_by_you" = "You changed the room avatar"; -"state_event_room_avatar_removed" = "%1$@ removed the room avatar"; -"state_event_room_avatar_removed_by_you" = "You removed the room avatar"; -"state_event_room_ban" = "%1$@ banned %2$@"; -"state_event_room_ban_by_you" = "You banned %1$@"; -"state_event_room_created" = "%1$@ created the room"; -"state_event_room_created_by_you" = "You created the room"; -"state_event_room_invite" = "%1$@ invited %2$@"; -"state_event_room_invite_accepted" = "%1$@ accepted the invite"; -"state_event_room_invite_accepted_by_you" = "You accepted the invite"; -"state_event_room_invite_by_you" = "You invited %1$@"; -"state_event_room_invite_you" = "%1$@ invited you"; -"state_event_room_join" = "%1$@ joined the room"; -"state_event_room_join_by_you" = "You joined the room"; -"state_event_room_knock" = "%1$@ requested to join"; -"state_event_room_knock_accepted" = "%1$@ allowed %2$@ to join"; -"state_event_room_knock_accepted_by_you" = "%1$@ allowed you to join"; -"state_event_room_knock_by_you" = "You requested to join"; -"state_event_room_knock_denied" = "%1$@ rejected %2$@'s request to join"; -"state_event_room_knock_denied_by_you" = "You rejected %1$@'s request to join"; -"state_event_room_knock_denied_you" = "%1$@ rejected your request to join"; -"state_event_room_knock_retracted" = "%1$@ is no longer interested in joining"; -"state_event_room_knock_retracted_by_you" = "You cancelled your request to join"; -"state_event_room_leave" = "%1$@ left the room"; -"state_event_room_leave_by_you" = "You left the room"; -"state_event_room_name_changed" = "%1$@ changed the room name to: %2$@"; -"state_event_room_name_changed_by_you" = "You changed the room name to: %1$@"; -"state_event_room_name_removed" = "%1$@ removed the room name"; -"state_event_room_name_removed_by_you" = "You removed the room name"; -"state_event_room_reject" = "%1$@ rejected the invitation"; -"state_event_room_reject_by_you" = "You rejected the invitation"; -"state_event_room_remove" = "%1$@ removed %2$@"; -"state_event_room_remove_by_you" = "You removed %1$@"; -"state_event_room_third_party_invite" = "%1$@ sent an invitation to %2$@ to join the room"; -"state_event_room_third_party_invite_by_you" = "You sent an invitation to %1$@ to join the room"; -"state_event_room_third_party_revoked_invite" = "%1$@ revoked the invitation for %2$@ to join the room"; -"state_event_room_third_party_revoked_invite_by_you" = "You revoked the invitation for %1$@ to join the room"; -"state_event_room_topic_changed" = "%1$@ changed the topic to: %2$@"; -"state_event_room_topic_changed_by_you" = "You changed the topic to: %1$@"; -"state_event_room_topic_removed" = "%1$@ removed the room topic"; -"state_event_room_topic_removed_by_you" = "You removed the room topic"; -"state_event_room_unban" = "%1$@ unbanned %2$@"; -"state_event_room_unban_by_you" = "You unbanned %1$@"; -"state_event_room_unknown_membership_change" = "%1$@ made an unknown change to their membership"; +"settings_rageshake_detection_threshold" = "Soglia di rilevamento"; +"settings_title_general" = "Generali"; +"settings_version_number" = "Versione: %1$@ (%2$@)"; +"state_event_avatar_changed_too" = "(anche l'avatar è stato cambiato)"; +"state_event_avatar_url_changed" = "%1$@ ha cambiato il proprio avatar"; +"state_event_avatar_url_changed_by_you" = "Hai cambiato il tuo avatar"; +"state_event_display_name_changed_from" = "%1$@ ha cambiato il proprio nome visualizzato da %2$@ a %3$@"; +"state_event_display_name_changed_from_by_you" = "Hai cambiato il tuo nome visualizzato da %1$@ a %2$@"; +"state_event_display_name_removed" = "%1$@ ha rimosso il proprio nome visualizzato (era %2$@)"; +"state_event_display_name_removed_by_you" = "Hai rimosso il tuo nome visualizzato (era %1$@)"; +"state_event_display_name_set" = "%1$@ ha impostato il proprio nome visualizzato su %2$@"; +"state_event_display_name_set_by_you" = "Hai impostato il tuo nome visualizzato su %1$@"; +"state_event_room_avatar_changed" = "%1$@ ha cambiato l'avatar della stanza"; +"state_event_room_avatar_changed_by_you" = "Hai cambiato l'avatar della stanza"; +"state_event_room_avatar_removed" = "%1$@ ha rimosso l'avatar della stanza"; +"state_event_room_avatar_removed_by_you" = "Hai rimosso l'avatar della stanza"; +"state_event_room_ban" = "%1$@ ha rimosso %2$@"; +"state_event_room_ban_by_you" = "Hai rimosso %1$@"; +"state_event_room_created" = "%1$@ ha creato la stanza"; +"state_event_room_created_by_you" = "Hai creato la stanza"; +"state_event_room_invite" = "%1$@ ha invitato %2$@"; +"state_event_room_invite_accepted" = "%1$@ ha accettato l'invito"; +"state_event_room_invite_accepted_by_you" = "Hai accettato l'invito"; +"state_event_room_invite_by_you" = "Hai invitato %1$@"; +"state_event_room_invite_you" = "%1$@ ti ha invitato"; +"state_event_room_join" = "%1$@ si è unito alla stanza"; +"state_event_room_join_by_you" = "Ti sei unito alla stanza"; +"state_event_room_knock" = "%1$@ ha chiesto di unirsi"; +"state_event_room_knock_accepted" = "%1$@ ha permesso a %2$@ di unirsi"; +"state_event_room_knock_accepted_by_you" = "%1$@ ti ha permesso di unirti"; +"state_event_room_knock_by_you" = "Hai richiesto di unirti"; +"state_event_room_knock_denied" = "%1$@ ha rifiutato la richiesta di unirsi di %2$@"; +"state_event_room_knock_denied_by_you" = "Hai rifiutato la richiesta di unirsi di %1$@"; +"state_event_room_knock_denied_you" = "%1$@ ha rifiutato la tua richiesta di unirti"; +"state_event_room_knock_retracted" = "%1$@ non è più interessato a partecipare"; +"state_event_room_knock_retracted_by_you" = "Hai annullato la tua richiesta di unirti"; +"state_event_room_leave" = "%1$@ ha lasciato la stanza"; +"state_event_room_leave_by_you" = "Hai lasciato la stanza"; +"state_event_room_name_changed" = "%1$@ ha cambiato il nome della stanza in: %2$@"; +"state_event_room_name_changed_by_you" = "Hai cambiato il nome della stanza in: %1$@"; +"state_event_room_name_removed" = "%1$@ ha rimosso il nome della stanza"; +"state_event_room_name_removed_by_you" = "Hai rimosso il nome della stanza"; +"state_event_room_reject" = "%1$@ ha rifiutato l'invito"; +"state_event_room_reject_by_you" = "Hai rifiutato l'invito"; +"state_event_room_remove" = "%1$@ ha rimosso %2$@"; +"state_event_room_remove_by_you" = "Hai rimosso %1$@"; +"state_event_room_third_party_invite" = "%1$@ ha inviato un invito a %2$@ per unirsi alla stanza"; +"state_event_room_third_party_invite_by_you" = "Hai inviato un invito a %1$@ per unirsi alla stanza"; +"state_event_room_third_party_revoked_invite" = "%1$@ ha revocato l'invito di %2$@ ad unirsi alla stanza."; +"state_event_room_third_party_revoked_invite_by_you" = "Hai revocato l'invito a %1$@ a universi alla stanza"; +"state_event_room_topic_changed" = "%1$@ ha cambiato l'oggetto in: %2$@"; +"state_event_room_topic_changed_by_you" = "Hai cambiato l'oggetto in: %1$@"; +"state_event_room_topic_removed" = "%1$@ ha rimosso l'oggetto della stanza"; +"state_event_room_topic_removed_by_you" = "Hai rimosso l'oggetto della stanza"; +"state_event_room_unban" = "%1$@ ha sbloccato %2$@"; +"state_event_room_unban_by_you" = "Hai sbloccato %1$@"; +"state_event_room_unknown_membership_change" = "%1$@ ha apportato una modifica sconosciuta alla propria iscrizione"; +"test_language_identifier" = "it"; +"test_untranslated_default_language_identifier" = "en"; diff --git a/ElementX/Resources/Localizations/it.lproj/Localizable.stringsdict b/ElementX/Resources/Localizations/it.lproj/Localizable.stringsdict new file mode 100644 index 000000000..388709628 --- /dev/null +++ b/ElementX/Resources/Localizations/it.lproj/Localizable.stringsdict @@ -0,0 +1,54 @@ + + + + + common_member_count + + NSStringLocalizedFormatKey + %#@COUNT@ + COUNT + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + %1$d membro + other + %1$d membri + + + room_timeline_state_changes + + NSStringLocalizedFormatKey + %#@COUNT@ + COUNT + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + %1$d modifica alla stanza + other + %1$d modifiche alla stanza + + + screen_room_member_list_header_title + + NSStringLocalizedFormatKey + %#@COUNT@ + COUNT + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + 1 persona + other + %1$d persone + + + + \ No newline at end of file diff --git a/ElementX/Resources/Localizations/ro.lproj/Localizable.strings b/ElementX/Resources/Localizations/ro.lproj/Localizable.strings index a4878d578..aac9a4906 100644 --- a/ElementX/Resources/Localizations/ro.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/ro.lproj/Localizable.strings @@ -9,7 +9,7 @@ "action_close" = "Închide"; "action_complete_verification" = "Verificare completă"; "action_confirm" = "Confirmă"; -"action_continue" = "Continua"; +"action_continue" = "Continuă"; "action_copy" = "Copiază"; "action_copy_link" = "Copiază linkul"; "action_create_a_room" = "Crează o cameră"; @@ -37,7 +37,7 @@ "action_save" = "Salvează"; "action_search" = "Caută"; "action_send" = "Trimite"; -"action_share" = "Share"; +"action_share" = "Partajează"; "action_share_link" = "Partajează linkul"; "action_skip" = "Omite"; "action_start" = "Începe"; @@ -49,6 +49,7 @@ "common_audio" = "Audio"; "common_bubbles" = "Baloane"; "common_creating_room" = "Se creează camera…"; +"common_current_user_left_room" = "Left room"; "common_decryption_error" = "Eroare de decriptare"; "common_developer_options" = "Opțiuni programator"; "common_edited_suffix" = "(editat)"; @@ -140,7 +141,7 @@ "screen_bug_report_contact_me" = "Puteți să mă contactați dacă aveți întrebări suplimentare"; "screen_bug_report_edit_screenshot" = "Editează captura de ecran"; "screen_bug_report_editor_description" = "Te rugăm să descrii eroarea. Ce-ai făcut? Ce te aşteptai să se întâmple? Ce s-a întâmplat de fapt. Te rugam să intri în cât mai multe detalii cu putință."; -"screen_bug_report_editor_placeholder" = "Descrie eroarea..."; +"screen_bug_report_editor_placeholder" = "Descrie eroarea…"; "screen_bug_report_editor_supporting" = "Dacă posibil, te rugăm să scrii descrierea în engleză."; "screen_bug_report_include_crash_logs" = "Trimite log-uri"; "screen_bug_report_include_logs" = "Trimite log-uri pentru a ajuta"; @@ -212,10 +213,10 @@ "screen_signout_confirmation_dialog_content" = "Ești sigur că vrei să te deconectezi?"; "screen_signout_confirmation_dialog_submit" = "Deconectează-te"; "screen_signout_confirmation_dialog_title" = "Deconectează-te"; -"screen_signout_in_progress_dialog_content" = "Deconectare în curs..."; +"screen_signout_in_progress_dialog_content" = "Deconectare în curs…"; "screen_signout_preference_item" = "Deconectează-te"; "screen_start_chat_error_starting_chat" = "A apărut o eroare la încercarea începerii conversației"; -"screen_start_chat_unknown_profile" = "We can’t validate this user’s Matrix ID. The invite might not be received."; +"screen_start_chat_unknown_profile" = "Nu am putut valida ID-ul Matrix al acestui utilizator. Este posibil ca invitația să nu fi fost primită."; "session_verification_banner_message" = "Se pare că folosești un dispozitiv nou. Verifică-ți identitatea pentru acces la mesajele tale criptate."; "session_verification_banner_title" = "Accesează istoricul mesajelor"; "settings_rageshake" = "Rageshake"; @@ -276,3 +277,5 @@ "state_event_room_unban" = "%1$@ a anulat interdicția pentru %2$@"; "state_event_room_unban_by_you" = "Ai anulat interdicția pentru %1$@"; "state_event_room_unknown_membership_change" = "%1$@ a făcut o modificare necunoscută asupra calității sale de membru"; +"test_language_identifier" = "ro"; +"test_untranslated_default_language_identifier" = "en"; diff --git a/ElementX/Sources/Generated/Strings+Untranslated.swift b/ElementX/Sources/Generated/Strings+Untranslated.swift index 08f222a5a..7075215f5 100644 --- a/ElementX/Sources/Generated/Strings+Untranslated.swift +++ b/ElementX/Sources/Generated/Strings+Untranslated.swift @@ -71,24 +71,12 @@ public enum UntranslatedL10n { extension UntranslatedL10n { static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { - let languages = Bundle.preferredLanguages - - for language in languages { - let translation = trIn(language, table, key, args) - if translation != key { - return translation - } - } - return key - } - - private static func trIn(_ language: String, _ table: String, _ key: String, _ args: CVarArg...) -> String { - guard let bundle = Bundle(for: BundleToken.self).lprojBundle(for: language) else { + guard let bundle = Bundle(for: BundleToken.self).lprojBundle(for: "en") else { // no translations for the desired language return key } let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") - return String(format: format, locale: Locale(identifier: language), arguments: args) + return String(format: format, locale: Locale(identifier: "en"), arguments: args) } } diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index 8569a7acf..0435fa395 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -112,6 +112,8 @@ public enum L10n { public static var commonBubbles: String { return L10n.tr("Localizable", "common_bubbles") } /// Creating room… public static var commonCreatingRoom: String { return L10n.tr("Localizable", "common_creating_room") } + /// Left room + public static var commonCurrentUserLeftRoom: String { return L10n.tr("Localizable", "common_current_user_left_room") } /// Decryption error public static var commonDecryptionError: String { return L10n.tr("Localizable", "common_decryption_error") } /// Developer options @@ -680,6 +682,10 @@ public enum L10n { public static func stateEventRoomUnknownMembershipChange(_ p1: Any) -> String { return L10n.tr("Localizable", "state_event_room_unknown_membership_change", String(describing: p1)) } + /// en + public static var testLanguageIdentifier: String { return L10n.tr("Localizable", "test_language_identifier") } + /// en + public static var testUntranslatedDefaultLanguageIdentifier: String { return L10n.tr("Localizable", "test_untranslated_default_language_identifier") } } // swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length // swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces @@ -691,18 +697,22 @@ extension L10n { let languages = Bundle.preferredLanguages for language in languages { - let translation = trIn(language, table, key, args) - if translation != key { + if let translation = trIn(language, table, key, args) { return translation + // If we can't find a translation for this language + // we check if we can find one by stripping the region + } else if let langCode = Locale(identifier: language).language.languageCode?.identifier, + let translation = trIn(langCode, table, key, args) { + return translation + } } - } return key - } + } - private static func trIn(_ language: String, _ table: String, _ key: String, _ args: CVarArg...) -> String { + private static func trIn(_ language: String, _ table: String, _ key: String, _ args: CVarArg...) -> String? { guard let bundle = Bundle(for: BundleToken.self).lprojBundle(for: language) else { // no translations for the desired language - return key + return nil } let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") return String(format: format, locale: Locale(identifier: language), arguments: args) diff --git a/Tools/SwiftGen/Templates/Strings/structured-swift5-element-untranslated.stencil b/Tools/SwiftGen/Templates/Strings/structured-swift5-element-untranslated.stencil new file mode 100644 index 000000000..89209cdb7 --- /dev/null +++ b/Tools/SwiftGen/Templates/Strings/structured-swift5-element-untranslated.stencil @@ -0,0 +1,92 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +{% if tables.count > 0 %} +{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %} +import Foundation + +// swiftlint:disable superfluous_disable_command file_length implicit_return + +// MARK: - Strings + +{% macro parametersBlock types %}{% filter removeNewlines:"leading" %} + {% for type in types %} + {% if type == "String" %} + _ p{{forloop.counter}}: Any + {% else %} + _ p{{forloop.counter}}: {{type}} + {% endif %} + {{ ", " if not forloop.last }} + {% endfor %} +{% endfilter %}{% endmacro %} +{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %} + {% for type in types %} + {% if type == "String" %} + String(describing: p{{forloop.counter}}) + {% elif type == "UnsafeRawPointer" %} + Int(bitPattern: p{{forloop.counter}}) + {% else %} + p{{forloop.counter}} + {% endif %} + {{ ", " if not forloop.last }} + {% endfor %} +{% endfilter %}{% endmacro %} +{% macro recursiveBlock table item %} + {% for string in item.strings %} + {% if not param.noComments %} + {% for line in string.translation|split:"\n" %} + /// {{line}} + {% endfor %} + {% endif %} + {% if string.types %} + {{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String { + return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %}) + } + {% elif param.lookupFunction %} + {# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #} + {{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") } + {% else %} + {{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}") + {% endif %} + {% endfor %} + {% for child in item.children %} + + {{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} { + {% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %} + } + {% endfor %} +{% endmacro %} +// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length +// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces +{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %} +{{accessModifier}} enum {{enumName}} { + {% if tables.count > 1 or param.forceFileNameEnum %} + {% for table in tables %} + {% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %} + {% endfor %} + {% else %} + {% call recursiveBlock tables.first.name tables.first.levels %} + {% endif %} +} +// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length +// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces + +// MARK: - Implementation Details + +extension {{enumName}} { + static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { + // No need to check languages, we always default to en for untranslated strings + guard let bundle = Bundle(for: BundleToken.self).lprojBundle(for: "en") else { + // no translations for the desired language + return key + } + let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") + return String(format: format, locale: Locale(identifier: "en"), arguments: args) + } +} + +private final class BundleToken {} + +{% else %} +// No string found +{% endif %} diff --git a/Tools/SwiftGen/Templates/Strings/structured-swift5-element.stencil b/Tools/SwiftGen/Templates/Strings/structured-swift5-element.stencil index 031dbf118..c6f0ae690 100644 --- a/Tools/SwiftGen/Templates/Strings/structured-swift5-element.stencil +++ b/Tools/SwiftGen/Templates/Strings/structured-swift5-element.stencil @@ -78,18 +78,22 @@ extension {{enumName}} { let languages = Bundle.preferredLanguages for language in languages { - let translation = trIn(language, table, key, args) - if translation != key { + if let translation = trIn(language, table, key, args) { return translation + // If we can't find a translation for this language + // we check if we can find one by stripping the region + } else if let langCode = Locale(identifier: language).language.languageCode?.identifier, + let translation = trIn(langCode, table, key, args) { + return translation + } } - } return key - } + } - private static func trIn(_ language: String, _ table: String, _ key: String, _ args: CVarArg...) -> String { + private static func trIn(_ language: String, _ table: String, _ key: String, _ args: CVarArg...) -> String? { guard let bundle = Bundle(for: BundleToken.self).lprojBundle(for: language) else { // no translations for the desired language - return key + return nil } let format = NSLocalizedString(key, tableName: table, bundle: bundle, comment: "") return String(format: format, locale: Locale(identifier: language), arguments: args) diff --git a/Tools/SwiftGen/swiftgen-config.yml b/Tools/SwiftGen/swiftgen-config.yml index f35e72221..8f1f084c0 100755 --- a/Tools/SwiftGen/swiftgen-config.yml +++ b/Tools/SwiftGen/swiftgen-config.yml @@ -19,7 +19,7 @@ strings: - inputs: Resources/Localizations/en.lproj filter: Untranslated* outputs: - templatePath: Templates/Strings/structured-swift5-element.stencil + templatePath: Templates/Strings/structured-swift5-element-untranslated.stencil output: Strings+Untranslated.swift params: enumName: UntranslatedL10n diff --git a/UnitTests/Sources/LocalizationTests.swift b/UnitTests/Sources/LocalizationTests.swift index ce3d1c5e8..50b4082c4 100644 --- a/UnitTests/Sources/LocalizationTests.swift +++ b/UnitTests/Sources/LocalizationTests.swift @@ -19,87 +19,77 @@ import XCTest class LocalizationTests: XCTestCase { /// Test ElementL10n considers app language changes - func disabled_testAppLanguage() { + func testAppLanguage() { // set app language to English Bundle.elementLanguage = "en" - XCTAssertEqual(L10n.actionOk, "OK") - XCTAssertEqual(L10n.actionContinue, "Continue") - XCTAssertEqual(L10n.screenSessionVerificationWaitingToAcceptTitle, "Waiting to accept request") - XCTAssertEqual(L10n.inviteFriendsText("Element", "element.io"), "Hey, talk to me on Element: element.io") + XCTAssertEqual(L10n.testLanguageIdentifier, "en") - // set app language to Turkish - Bundle.elementLanguage = "tr" + // set app language to Italian + Bundle.elementLanguage = "it" - XCTAssertEqual(L10n.actionOk, "Tamam") - XCTAssertEqual(L10n.actionContinue, "Devam et") - XCTAssertEqual(L10n.screenSessionVerificationWaitingToAcceptTitle, "Github ile kayıt ol") - XCTAssertEqual(L10n.inviteFriendsText("Element", "element.io"), "Yalnızca Söz ve Anahtar Kelimeler") + XCTAssertEqual(L10n.testLanguageIdentifier, "it") } /// Test fallback language for a language not supported at all - func disabled_testFallbackOnNotSupportedLanguage() { - // set app language to something Element don't support at all (chose 'Malay' language) - Bundle.elementLanguage = "ms" + func testStripRegionIfRegionalTranslationIsNotAvailable() { + // set app language to something that includes also a region (it-IT) + Bundle.elementLanguage = "it-IT" + + XCTAssertEqual(L10n.testLanguageIdentifier, "it") + } + + /// Test fallback language for a language not supported at all + func testFallbackOnNotSupportedLanguage() { + // set app language to something Element don't support at all (chose non existing identifier) + Bundle.elementLanguage = "xx" Bundle.elementFallbackLanguage = "en" - XCTAssertEqual(L10n.actionOk, "OK") - XCTAssertEqual(L10n.actionContinue, "Continue") - XCTAssertEqual(L10n.roomTimelineStateChanges(5), "5 room changes") + XCTAssertEqual(L10n.testLanguageIdentifier, "en") } /// Test fallback language for a language supported but poorly translated - func disabled_testFallbackOnNotTranslatedKey() { - // set app language to something Element supports but poorly translated (chose 'Sinhala' language) - Bundle.elementLanguage = "si" + func testFallbackOnNotTranslatedKey() { + // set app language to something Element supports but use a key that is not translated (we have a key that should never be translated) + Bundle.elementLanguage = "it" Bundle.elementFallbackLanguage = "en" - XCTAssertEqual(L10n.actionOk, "OK") - XCTAssertEqual(L10n.actionContinue, "Continue") + XCTAssertEqual(L10n.testLanguageIdentifier, "it") + XCTAssertEqual(L10n.testUntranslatedDefaultLanguageIdentifier, "en") } /// Test plurals that ElementL10n considers app language changes - func disabled_testPlurals() { + func testPlurals() { // set app language to English Bundle.elementLanguage = "en" XCTAssertEqual(L10n.commonMemberCount(1), "1 member") XCTAssertEqual(L10n.commonMemberCount(2), "2 members") - // set app language to Turkish - Bundle.elementLanguage = "tr" + // set app language to Italian + Bundle.elementLanguage = "it" - XCTAssertEqual(L10n.commonMemberCount(1), "1 üyelik değişikliği") - XCTAssertEqual(L10n.commonMemberCount(2), "2 adet üyelik değişikliği") + XCTAssertEqual(L10n.commonMemberCount(1), "1 membro") + XCTAssertEqual(L10n.commonMemberCount(2), "2 membri") - // set app language to Polish - Bundle.elementLanguage = "pl" - - XCTAssertEqual(L10n.commonMemberCount(1), "1 sekunda") // one - XCTAssertEqual(L10n.commonMemberCount(2), "2 sekundy") // few - XCTAssertEqual(L10n.commonMemberCount(3), "5 sekund") // many, other +// // set app language to Polish +// Bundle.elementLanguage = "pl" +// +// XCTAssertEqual(L10n.commonMemberCount(1), "1 sekunda") // one +// XCTAssertEqual(L10n.commonMemberCount(2), "2 sekundy") // few +// XCTAssertEqual(L10n.commonMemberCount(3), "5 sekund") // many, other } /// Test plurals fallback language for a language not supported at all - func disabled_testPluralsFallbackOnNotSupportedLanguage() { - // set app language to something Element don't support at all (chose 'Malay' language) - Bundle.elementLanguage = "ms" + func testPluralsFallbackOnNotSupportedLanguage() { + // set app language to something Element don't support at all ("invalid identifier") + Bundle.elementLanguage = "xx" Bundle.elementFallbackLanguage = "en" XCTAssertEqual(L10n.commonMemberCount(1), "1 member") XCTAssertEqual(L10n.commonMemberCount(2), "2 members") } - /// Test plurals fallback language for a language supported but poorly translated - func disabled_testPluralsFallbackOnNotTranslatedKey() { - // set app language to something Element supports but poorly translated (chose 'Sinhala' language) - Bundle.elementLanguage = "si" - Bundle.elementFallbackLanguage = "en" - - XCTAssertEqual(L10n.roomTimelineStateChanges(1), "1 room change") - XCTAssertEqual(L10n.roomTimelineStateChanges(5), "5 room changes") - } - /// Test untranslated strings func testUntranslated() { XCTAssertEqual(UntranslatedL10n.untranslated, "Untranslated") diff --git a/changelog.d/764.bugfix b/changelog.d/764.bugfix new file mode 100644 index 000000000..a36d7bff1 --- /dev/null +++ b/changelog.d/764.bugfix @@ -0,0 +1 @@ +Fixed a bug that prevented the right localisation to be used when the preferred language locale contained a region identifier. \ No newline at end of file