aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2024-08-18 13:40:12 +0530
committerGitHub <noreply@github.com>2024-08-18 08:10:12 +0000
commit71161e20f8610b989e7a0d803249e17362e10ddc (patch)
treedf45bc53ac65e3ec00739af3a7a93d6348f03032
parent919f708df28c98a8a124554717710e149b138a1b (diff)
fix: rework Crowdin integration (#3175)
* chore: set up Crowdin configuration * fix(app): sync strings from Crowdin Closes #3174 * fix(ci): use crowdin/github-action instead of homebrew setup * fix(build): remove obsolete Crowdin plugin
-rw-r--r--.github/workflows/sync_crowdin.yml40
-rw-r--r--app/build.gradle.kts6
-rw-r--r--app/src/main/res/values-de/strings.xml257
-rw-r--r--app/src/main/res/values-fr/strings.xml1
-rw-r--r--app/src/main/res/values-it/strings.xml1
-rw-r--r--app/src/main/res/values-pt-rBR/strings.xml13
-rw-r--r--app/src/main/res/values-ru/strings.xml1
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml1
-rw-r--r--app/src/nonFree/res/values-ar/strings.xml8
-rw-r--r--app/src/nonFree/res/values-es/strings.xml8
-rw-r--r--app/src/nonFree/res/values-fi/strings.xml8
-rw-r--r--app/src/nonFree/res/values-gl-rES/strings.xml8
-rw-r--r--app/src/nonFree/res/values-hu/strings.xml8
-rw-r--r--app/src/nonFree/res/values-ko/strings.xml8
-rw-r--r--app/src/nonFree/res/values-pl/strings.xml8
-rw-r--r--app/src/nonFree/res/values-uk/strings.xml3
-rw-r--r--build-logic/build.gradle.kts4
-rw-r--r--build-logic/src/main/kotlin/app/passwordstore/gradle/OkHttp.kt6
-rw-r--r--build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/BuildOnApiTask.kt64
-rw-r--r--build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinExtension.kt22
-rw-r--r--build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinPlugin.kt70
-rw-r--r--build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/StringCleanupTask.kt66
-rw-r--r--build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/api/ListProjects.kt14
-rw-r--r--crowdin.yml90
24 files changed, 320 insertions, 395 deletions
diff --git a/.github/workflows/sync_crowdin.yml b/.github/workflows/sync_crowdin.yml
index b0917893..9931d7f8 100644
--- a/.github/workflows/sync_crowdin.yml
+++ b/.github/workflows/sync_crowdin.yml
@@ -11,35 +11,27 @@ jobs:
- name: Setup build environment
uses: android-password-store/android-password-store/.github/reusable-workflows/setup-gradle@develop
- - name: Download new translations from Crowdin
- shell: bash
- run: ./gradlew --no-configuration-cache crowdin
- env:
- CROWDIN_LOGIN: ${{ secrets.CROWDIN_LOGIN }}
- CROWDIN_PROJECT_KEY: ${{ secrets.CROWDIN_PROJECT_KEY }}
-
- - name: Check if PR is required
- run: if [[ $(git status -s) != '' ]]; then echo "UPDATED=true" >> $GITHUB_ENV; fi
-
- - name: Create Pull Request
- id: cpr
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
- if: "env.UPDATED == 'true'"
+ - name: Sync translations to/from Crowdin
+ id: crowdin
+ uses: crowdin/github-action@v2
with:
- author: GitHub Actions <noreply@github.com>
- base: develop
- body: This is an automated pull request to sync localisations from Crowdin.
- branch: bot/crowdin-sync
- commit-message: "strings: sync with crowdin"
- labels: A-localisation, S-automerge
- title: Sync localisations from Crowdin
- token: ${{ secrets.PSL_UPDATE_TOKEN }}
+ upload_sources: true
+ upload_translations: false
+ download_translations: true
+ localization_branch_name: l10n_crowdin_translations
+ create_pull_request: true
+ pull_request_title: 'New Crowdin Translations'
+ pull_request_body: 'New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action)'
+ pull_request_base_branch_name: 'develop'
+ env:
+ GITHUB_TOKEN: ${{ secrets.PSL_UPDATE_TOKEN }}
+ CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_LOGIN }}
+ CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PROJECT_KEY }}
- name: Enable automerge for PR
- if: "${{ steps.cpr.outputs.pull-request-operation == 'created' }}"
shell: bash
run: |
gh pr merge --squash --auto "${PR_URL}"
env:
GITHUB_TOKEN: ${{ secrets.PSL_UPDATE_TOKEN }}
- PR_URL: ${{ steps.cpr.outputs.pull-request-url }}
+ PR_URL: ${{ steps.crowdin.outputs.pull-request-url }}
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 42c88c14..4e6b1b0b 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -6,7 +6,6 @@
plugins {
id("com.github.android-password-store.android-application")
- id("com.github.android-password-store.crowdin-plugin")
id("com.github.android-password-store.kotlin-android")
id("com.github.android-password-store.kotlin-kapt")
id("com.github.android-password-store.versioning-plugin")
@@ -16,11 +15,6 @@ plugins {
alias(libs.plugins.kotlin.composeCompiler)
}
-crowdin {
- crowdinIdentifier = "android-password-store"
- skipCleanup = false
-}
-
android {
compileOptions { isCoreLibraryDesugaringEnabled = true }
namespace = "app.passwordstore"
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 9ae38196..03576885 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -10,15 +10,19 @@
</plurals>
<!-- Activity names -->
<string name="action_settings">Einstellungen</string>
- <string name="dialog_delete_title">Ordner existiert bereits</string>
- <string name="dialog_delete_msg">Zielordner existiert bereits. Aktuelle Version unterstützt nur eine einzige Datenquelle. Möchtest du die aktuelle Datenquelle löschen?\n(%1$s)</string>
+ <string name="dialog_delete_title">Ordner existiert bereits.</string>
+ <string name="dialog_delete_msg">Zielordner existiert bereits. Die aktuelle Version unterstützt nur eine einzige Datenquelle. Möchten Sie die aktuelle Datenquelle löschen?\n(%1$s)</string>
<string name="dialog_delete">Ordner löschen</string>
<string name="dialog_do_not_delete">Abbruch</string>
- <string name="title_activity_git_clone">Repository Informationen</string>
+ <string name="title_activity_git_clone">Repository-Informationen</string>
<string name="title_activity_git_log">Commit-Log</string>
<!-- Password Store -->
- <string name="creation_dialog_text">Bitte klone oder erstelle ein neues Repository, bevor du versuchst ein Passwort hinzuzufügen oder jegliche Synchronisation-Operation durchführst.</string>
- <string name="delete_directory_progress_text">Lösche…</string>
+ <string name="creation_dialog_text">Bitte klonen oder erstellen Sie ein neues Repository, bevor Sie ein Passwort hinzufügen oder eine Synchronisations-Operation durchführen wollen.</string>
+ <plurals name="delete_dialog_text">
+ <item quantity="one">Möchten Sie das Passwort wirklich löschen?</item>
+ <item quantity="other">Möchten Sie die %d Passwörter wirklich löschen?</item>
+ </plurals>
+ <string name="delete_directory_progress_text">Wird gelöscht</string>
<string name="move">Verschieben</string>
<string name="edit">Bearbeiten</string>
<string name="delete">Löschen</string>
@@ -27,38 +31,39 @@
<string name="password_move_error_title">Fehler beim Verschieben von Passwörtern</string>
<string name="password_move_error_message">Verschieben von %1$s nach %2$s fehlgeschlagen</string>
<!-- git commits -->
- <string name="git_commit_add_text">Füge generiertes Passwort für %1$s mittels Android Passwort Store hinzu.</string>
+ <string name="git_commit_add_text">Füge erstelltes Passwort für %1$s mittels Android Password Store hinzu.</string>
<string name="git_commit_edit_text">Bearbeite das Passwort für %1$s mittels Android Password Store.</string>
<string name="git_commit_remove_text">%1$s aus dem Speicher entfernen.</string>
<string name="git_commit_move_text">Benenne %1$s in %2$s um.</string>
<string name="git_commit_move_multiple_text">Verschiebe mehrere Passwörter nach %1$s.</string>
+ <string name="git_commit_gpg_id">Initialisiere PGP-IDs in %1$s.</string>
<!-- PGPHandler -->
<string name="clipboard_copied_text">In die Zwischenablage kopiert</string>
- <string name="file_toast_text">Bitte setze einen Pfad</string>
- <string name="path_toast_text">Bitte setze einen Pfad</string>
- <string name="empty_toast_text">Du kannst kein leeres Passwort setzen oder leere Extra-Angaben</string>
+ <string name="file_toast_text">Bitte setzen Sie einen Dateinamen.</string>
+ <string name="path_toast_text">Bitte setzen Sie einen Pfad.</string>
+ <string name="empty_toast_text">Sie können kein leeres Passwort oder leere Extra-Angaben setzen.</string>
<!-- Git Async Task -->
- <string name="jgit_error_dialog_title">Internal Exception occurred</string>
+ <string name="jgit_error_dialog_title">Es ist ein Fehler während der Git-Operation aufgetreten.</string>
<!-- Git Handler -->
- <string name="ssh_preferences_dialog_text">Bitte importieren oder generieren Sie Ihre SSH-Schlüsseldatei in den Einstellungen</string>
- <string name="ssh_preferences_dialog_title">Kein SSH-Key angegeben</string>
+ <string name="ssh_preferences_dialog_text">Bitte importieren oder erstellen Sie Ihre SSH-Schlüsseldatei in den Einstellungen.</string>
+ <string name="ssh_preferences_dialog_title">Kein SSH-Schlüssel angegeben</string>
<string name="button_label_import">Importieren</string>
- <string name="ssh_preferences_dialog_generate">Generieren</string>
+ <string name="ssh_preferences_dialog_generate">Erstellen</string>
<string name="passphrase_dialog_title">Authentifizieren</string>
- <string name="passphrase_dialog_text">Bitte setze ein Passwort für deinen SSH-Key. Lasse das Feld leer, wenn kein Passwort vergeben werden soll.</string>
- <string name="password_dialog_text">Bitte setze ein Passwort für dieses Repository</string>
+ <string name="passphrase_dialog_text">Bitte geben Sie das Passwort für Ihren SSH-Schlüssel ein.</string>
+ <string name="password_dialog_text">Bitte geben Sie das Passwort für dieses Repository ein.</string>
<!-- Clone fragment -->
<string name="server_url">Repository-URL</string>
<string name="connection_mode">Authentifizierungsmethode</string>
<!-- Git Config fragment -->
- <string name="git_user_name_hint">Nutzername</string>
+ <string name="git_user_name_hint">Benutzername</string>
<string name="git_user_email">E-Mail-Adresse</string>
- <string name="invalid_email_dialog_text">Bitte valide Email eingeben</string>
+ <string name="invalid_email_dialog_text">Bitte eine gültige E-Mail-Adresse eingeben</string>
<string name="clone_button">Klone!</string>
<!-- PGP Handler -->
<string name="crypto_name_hint">Name</string>
<string name="crypto_pass_label">Passwort</string>
- <string name="crypto_extra_label">Extra</string>
+ <string name="crypto_extra_label">Zusätzliche Angaben</string>
<string name="crypto_encrypt_username_label">Benutzername verschlüsseln</string>
<string name="crypto_select">Auswählen</string>
<string name="crypto_save">Speichern</string>
@@ -66,51 +71,61 @@
<!-- DECRYPT Layout -->
<string name="action_search">Suche</string>
<string name="password">Passwort:</string>
- <string name="username">Benutzername:</string>
+ <string name="username">Benutzername</string>
+ <string name="copy_label">Kopieren</string>
<string name="edit_password">Passwort bearbeiten</string>
<string name="copy_password">Passwort kopieren</string>
<string name="share_as_plaintext">Als Klartext teilen</string>
<!-- Preferences -->
<string name="pref_category_repository_title">Repository</string>
- <string name="pref_edit_git_server_settings">Git-Server Einstellungen</string>
- <string name="pref_edit_git_config">Lokale Git Konfiguration &amp; Dienstprogramme</string>
- <string name="pref_import_ssh_key_title">Importiere SSH-Key</string>
- <string name="pref_ssh_keygen_title">Erstelle SSH-Schlüsselpaar</string>
- <string name="pref_ssh_see_key_title">Zeige erstellten öffentlichen SSH-Key</string>
+ <string name="pref_edit_git_server_settings">Git-Server-Einstellungen</string>
+ <string name="pref_edit_git_config">Lokale Git-Konfiguration &amp; Dienstprogramme</string>
+ <string name="pref_import_ssh_key_title">Importiere SSH-Schlüssel.</string>
+ <string name="pref_ssh_keygen_title">Erstelle SSH-Schlüsselpaar.</string>
+ <string name="pref_ssh_see_key_title">Zeige erstellten öffentlichen SSH-Schlüssel an.</string>
<string name="pref_git_delete_repo_title">Repository löschen</string>
<string name="pref_dialog_delete_title">Repository löschen</string>
<string name="pref_category_general_title">Allgemein</string>
<string name="pref_category_passwords_title">Passwörter</string>
<string name="pref_clipboard_timeout_title">Timeout für das Kopieren des Passwortes</string>
- <string name="pref_clipboard_timeout_summary">Legen Sie die Zeit (in Sekunden) fest, die das Passwort in der Zwischenablage liegen soll. 0 bedeutet für immer. Aktueller Wert: %1$s</string>
- <string name="pref_copy_title">Kopiere Passwort automatisch</string>
- <string name="pref_copy_summary">Kopiert das Passwort in die Zwischenablage, wenn der Eintrag entschlüsselt wurde.</string>
+ <string name="pref_clipboard_timeout_summary">Legen Sie die Zeitspanne (in Sekunden) fest, wie lange das Passwort in der Zwischenablage liegen soll. 0 bedeutet für immer. Aktueller Wert: %1$s</string>
+ <string name="pref_copy_title">Kopiere Passwort automatisch.</string>
+ <string name="pref_copy_summary">Kopiert das Passwort in die Zwischenablage, nachdem es entschlüsselt wurde.</string>
<string name="ssh_key_import_error_not_an_ssh_key_message">Die ausgewählte Datei scheint kein privater SSH-Schlüssel zu sein.</string>
- <string name="ssh_key_success_dialog_title">SSH-Key importiert</string>
+ <string name="ssh_key_success_dialog_title">SSH-Schlüssel importiert</string>
<string name="ssh_key_error_dialog_title">Schlüssel-Importfehler</string>
<string name="ssh_key_error_dialog_text">Nachricht : \n</string>
<string name="pref_recursive_filter_title">Suche in Unterordnern</string>
<string name="pref_recursive_filter_summary">Findet Passwörter auch in Unterordnern.</string>
- <string name="pref_directory_structure">Passwort-Datei-Organisation</string>
<string name="pref_sort_order_title">Passwortsortierung</string>
<string name="pref_folder_first_sort_order">Ordner zuerst</string>
<string name="pref_file_first_sort_order">Dateien zuerst</string>
- <string name="pref_type_independent_sort_order">Typ unabhängig</string>
+ <string name="pref_type_independent_sort_order">typunabhängig</string>
<string name="pref_recently_used_sort_order">Zuletzt verwendet</string>
<string name="pref_category_autofill_title">Automatisch ausfüllen</string>
<string name="pref_autofill_enable_title">Autofill aktivieren</string>
<string name="pref_category_misc_title">Verschiedenes</string>
<string name="pref_clear_clipboard_title">Zwischenablagenverlauf umgehen</string>
- <string name="pref_clear_clipboard_summary">Zwischenablage mit aufeinanderfolgenden Zahlen überschwemmen, um ggf. bestehende Passwörter zu leeren</string>
- <string name="pref_git_delete_repo_summary">Lösche das lokale (versteckte) Repository</string>
+ <string name="pref_clear_clipboard_summary">Auf Geräten mit Zwischenablagenverlauf diesen mit Zufallszahlen überschwemmen, um ggf. bestehende Passwörter zu entfernen</string>
+ <string name="pref_git_delete_repo_summary">Lösche das lokale (versteckte) Repository.</string>
<string name="prefs_export_passwords_title">Passwörter exportieren</string>
- <string name="prefs_export_passwords_summary">Exportiert die verschlüsselten Passwörter in ein externes Verzeichnis</string>
+ <string name="prefs_export_passwords_summary">Exportiert die verschlüsselten Passwörter in ein externes Verzeichnis.</string>
<string name="pref_rebase_on_pull_title">Rebase beim Pullen</string>
<string name="pref_rebase_on_pull_summary">Ein Merge-Commit mit Upstream-Änderungen beim Pullen oder Synchronisieren erstellen</string>
- <string name="pref_rebase_on_pull_summary_on">Beim Pullen oder Synchronisieren, Commits rebasen, die nicht im Remote-Repository vorhanden sind</string>
+ <string name="pref_rebase_on_pull_summary_on">Beim Pullen oder Synchronisieren Commits rebasen, die nicht im Remote-Repository vorhanden sind</string>
+ <string name="pref_disable_sync_on_pull_title">Kein Synchronisieren durch Abwärtswischen</string>
+ <string name="pref_disable_sync_on_pull_summary">Beim Wischen über die Passwortliste keine Git-Synchronisation mit dem Repository anstoßen</string>
+ <string name="pref_import_pgp_key_title">Importiere PGP-Schlüssel.</string>
+ <string name="pref_pgp_key_manager_title">Schlüsselmanager</string>
+ <string name="pref_pgp_ascii_armor_title">Im ASCII-Armor-Modus verschlüsseln</string>
+ <string name="pref_passphrase_cache_title">Zwischenspeicher für Passphrase aktivieren</string>
+ <string name="pref_passphrase_cache_summary">WARNUNG: Dieses Feature ist funktionsbereit, befindet sich jedoch noch in der Erprobungsphase. Erfordert eine aktive Bildschirmsperre.</string>
+ <string name="pref_passphrase_cache_authenticate_enable">Zwischenspeicher für Passphrase aktivieren</string>
+ <string name="pref_passphrase_cache_auto_clear_title">Automatische Löschung des Zwischenspeichers</string>
+ <string name="pref_passphrase_cache_auto_clear_summary">Löscht die Passphrase aus dem Zwischenspeicher nach Abschalten des Bildschirms.</string>
<!-- PasswordGenerator fragment -->
- <string name="pwgen_title">Passwort generieren</string>
- <string name="pwgen_generate">Generieren</string>
+ <string name="pwgen_title">Passwort erstellen</string>
+ <string name="pwgen_generate">Erstellen</string>
<string name="pwgen_include">Einschließen</string>
<string name="pwgen_length">Länge</string>
<string name="pwgen_numerals">Nummern</string>
@@ -120,33 +135,33 @@
<string name="pwgen_ambiguous">Zweideutig</string>
<string name="pwgen_pronounceable">Aussprechbar</string>
<string name="pwgen_no_chars_error">Keine Zeichen hinzugefügt</string>
- <string name="pwgen_length_too_short_error">Länge zu kurz für ausgewählte Kriterien</string>
- <string name="pwgen_max_iterations_exceeded">Fehler beim Generieren eines Passworts, das die Einschränkungen erfüllt. Versuchen Sie, die Länge zu erhöhen.</string>
+ <string name="pwgen_length_too_short_error">Länge zu kurz für die gewählten Kriterien</string>
+ <string name="pwgen_max_iterations_exceeded">Fehler beim Erstellen eines Passworts, das den Anforderungen genügt. Versuchen Sie es mit einem längeren Passwort.</string>
<string name="pwgen_separator">Trennzeichen</string>
<!-- Password generator prefs -->
<string name="pref_password_generator_type_title">Passwortgenerator</string>
<!-- ssh keygen fragment -->
<string name="ssh_keygen_passphrase">Passwort</string>
- <string name="ssh_keygen_generate">Generieren</string>
+ <string name="ssh_keygen_generate">Erstellen</string>
<string name="ssh_keygen_share">Teilen</string>
<string name="ssh_keygen_later">Später</string>
- <string name="ssh_keygen_message">%1$s\n\nFüge den Public-Key zu Deinem Git-Server hinzu.</string>
- <string name="ssh_key_gen_generating_progress">Schlüssel werden generiert…</string>
+ <string name="ssh_keygen_message">%1$s\n\nFügen Sie den öffentlichen Schlüssel Ihrem Git-Server hinzu.</string>
+ <string name="ssh_key_gen_generating_progress">Schlüssel werden erstellt…</string>
<string name="ssh_keygen_require_authentication">Mit Anmeldedaten für Bildschirmsperre schützen</string>
<string name="ssh_keygen_label_rsa">RSA</string>
<string name="ssh_keygen_label_ecdsa">ECDSA</string>
<string name="ssh_keygen_label_ed25519">Ed25519</string>
<string name="ssh_keygen_explanation_rsa"><b>RSA (3072 Bit)</b>\nWird von allen Servern unterstützt, allerdings ist die Authentifizierung recht langsam.</string>
- <string name="ssh_keygen_explanation_ecdsa"><b>ECDSA (NIST P-256)</b>\nSchnelle Authentifizierung und unterstützt von den meisten Servern, die noch Updates erhalten.</string>
- <string name="ssh_keygen_explanation_ed25519"><b>Ed25519</b>\nSchnelle Authentifizierung, aber nur von eher modernen Servern unterstützt.</string>
+ <string name="ssh_keygen_explanation_ecdsa"><b>ECDSA (NIST P-256)</b>\nSchnelle Authentifizierung, unterstützt von den meisten Servern, die noch Updates erhalten.</string>
+ <string name="ssh_keygen_explanation_ed25519"><b>Ed25519</b>\nSchnelle Authentifizierung, aber nur von moderneren Servern unterstützt</string>
<string name="ssh_keygen_existing_title">SSH-Schlüssel</string>
<string name="ssh_keygen_existing_message">Existierenden SSH-Schlüssel ersetzen? Möglicherweise verlieren Sie den Zugriff auf Ihren Server.</string>
<string name="ssh_keygen_existing_replace">Ersetzen</string>
<string name="ssh_keygen_existing_keep">Behalten</string>
<!-- SSH Android Keystore auth -->
- <string name="biometric_auth_generic_failure">Authentifizierung der Bildschirmsperre fehlgeschlagen</string>
+ <string name="biometric_auth_generic_failure">Authentifizierung über Bildschirmsperre fehlgeschlagen</string>
<string name="biometric_prompt_title_ssh_auth">SSH-Schlüssel freischalten</string>
- <string name="biometric_prompt_title_ssh_keygen">SSH-Schlüssel generieren</string>
+ <string name="biometric_prompt_title_ssh_keygen">SSH-Schlüssel erstellen</string>
<!-- Misc -->
<string name="dialog_ok">OK</string>
<string name="dialog_yes">Ja</string>
@@ -158,27 +173,27 @@
<string name="git_push">Git Push</string>
<string name="git_push_up_to_date">Alles aktuell</string>
<string name="git_log">Commit-Log anzeigen</string>
- <string name="show_password_pref_title">Zeige das Passwort</string>
+ <string name="show_password_pref_title">Zeige das Passwort.</string>
<string name="show_password_pref_summary">Soll das entschlüsselte Passwort sichtbar sein? Dies deaktiviert nicht das Kopieren.</string>
- <string name="pwd_generate_button">Generieren</string>
- <string name="refresh_list">Aktualisieren</string>
+ <string name="pwd_generate_button">Erstellen</string>
+ <string name="refresh_list">Liste aktualisieren</string>
<string name="send_plaintext_password_to">Passwort unverschlüsselt senden an…</string>
- <string name="app_icon_hint">App Icon</string>
+ <string name="app_icon_hint">App-Icon</string>
<!-- Oreo Autofill -->
<string name="oreo_autofill_select_and_fill_into">Eintrag zum Ausfüllen auswählen</string>
<string name="oreo_autofill_strict_domain_search">Phishing-resistente Suche</string>
<string name="oreo_autofill_match_with">Übereinstimmung mit %1$s</string>
<string name="oreo_autofill_matches_clear_existing">Bestehende Übereinstimmungen löschen</string>
- <string name="oreo_autofill_filter_no_results">Keine Ergebnisse.</string>
+ <string name="oreo_autofill_filter_no_results">Keine Ergebnisse</string>
<string name="oreo_autofill_search_in_store">Eintrag suchen</string>
<string name="oreo_autofill_save_internal_error">Speichern aufgrund eines internen Fehlers fehlgeschlagen</string>
- <string name="oreo_autofill_save_app_not_supported">Diese App wird derzeit nicht unterstützt</string>
- <string name="oreo_autofill_save_passwords_dont_match">Die Passwörter stimmen nicht überein</string>
- <string name="oreo_autofill_generate_password">Passwort generieren…</string>
+ <string name="oreo_autofill_save_app_not_supported">Diese App wird derzeit nicht unterstützt.</string>
+ <string name="oreo_autofill_save_passwords_dont_match">Die Passwörter stimmen nicht überein.</string>
+ <string name="oreo_autofill_generate_password">Passwort erstellen…</string>
<string name="oreo_autofill_fill_otp_from_sms">Code aus SMS extrahieren…</string>
- <string name="oreo_autofill_max_matches_reached">Maximale Anzahl an Übereinstimmungen (%1$d) erreicht; Lösche Übereinstimmungen, bevor neue hinzugefügt werden.</string>
+ <string name="oreo_autofill_max_matches_reached">Maximale Anzahl an Übereinstimmungen (%1$d) erreicht; lösche Übereinstimmungen, bevor neue hinzugefügt werden.</string>
<string name="oreo_autofill_warning_publisher_header">Der Hersteller dieser App hat sich geändert, seit Sie einen Eintrag zum Passwort-Speicher mit ihr verknüpft haben:</string>
- <string name="oreo_autofill_warning_publisher_footer"><b>Die derzeit installierte App versucht, Ihre Anmeldeinformationen zu stehlen, indem sie vorgibt, eine vertrauenswürdige App zu sein.</b>\n\nVersuchen Sie die App zu deinstallieren und installieren Sie sie erneut aus einer vertrauenswürdigen Quelle wie dem Play Store, Amazon Appstore, F-Droid oder dem Shop Ihres Telefonherstellers.</string>
+ <string name="oreo_autofill_warning_publisher_footer"><b>Die derzeit installierte App versucht, Ihre Anmeldeinformationen zu stehlen, indem sie vorgibt, eine vertrauenswürdige App zu sein.</b>\n\nVersuchen Sie, die App zu deinstallieren und installieren Sie sie erneut aus einer vertrauenswürdigen Quelle wie dem Play Store, Amazon Appstore, F-Droid oder dem Shop Ihres Telefonherstellers.</string>
<string name="oreo_autofill_warning_publisher_install_time">Installiert: %1$s</string>
<string name="oreo_autofill_warning_publisher_advanced_info_button">Erweiterte Informationen</string>
<string name="oreo_autofill_warning_publisher_changed_disable_autofill_button">Autofill deaktiviert lassen</string>
@@ -189,13 +204,13 @@
<string name="oreo_autofill_general_fill_and_save_support">Anmeldedaten ausfüllen und speichern</string>
<string name="oreo_autofill_general_fill_support">Anmeldedaten ausfüllen</string>
<string name="oreo_autofill_password_fill_support">Passwörter ausfüllen</string>
- <string name="oreo_autofill_flaky_fill_support">Passwörter ausfüllen (kann manchmal sein, dass Sie den Browser neu starten müssen)</string>
+ <string name="oreo_autofill_flaky_fill_support">Passwörter ausfüllen (manchmal kann ein Neustart des Browsers erforderlich sein)</string>
<string name="oreo_autofill_no_support">Kein Support</string>
<string name="oreo_autofill_enable_dialog_description">Password Store kann das Ausfüllen von Anmeldeformularen und sogar das Speichern von Anmeldedaten in Apps oder auf Webseiten übernehmen.</string>
- <string name="oreo_autofill_enable_dialog_instructions">Um diese Funktion zu aktivieren, tippen Sie auf OK, um zu Autofill-Einstellungen zu gelangen. Dort wählen Sie \"Password Store\" aus der Liste und bestätigen Sie die Bestätigungsaufforderung mit \"OK\".</string>
+ <string name="oreo_autofill_enable_dialog_instructions">Tippen Sie auf OK, um diese Funktion zu aktivieren und um zu den Autofill-Einstellungen zu gelangen. Dort wählen Sie \"Password Store\" aus der Liste und bestätigen mit \"OK\".</string>
<string name="oreo_autofill_enable_dialog_installed_browsers">Autofill-Unterstützung mit installierten Browsern:</string>
<!-- Autofill -->
- <string name="ssh_key_does_not_exist">Der private SSH-Schlüssel konnte nicht geöffnet werden. Bitte überprüfen Sie, ob die Datei existiert</string>
+ <string name="ssh_key_does_not_exist">Der private SSH-Schlüssel konnte nicht geöffnet werden. Bitte überprüfen Sie, ob die Datei existiert.</string>
<string name="new_password_title">Neues Passwort</string>
<string name="clear_saved_passphrase_ssh">Gespeicherte Passphrase für lokalen SSH-Schlüssel löschen</string>
<string name="clear_saved_passphrase_https">Gespeichertes HTTPS-Passwort löschen</string>
@@ -206,29 +221,29 @@
<string name="git_head_on_branch">Auf Branch %1$s</string>
<string name="git_head_detached">HEAD abgelöst bei %1$s</string>
<string name="git_head_missing">Kann HEAD nicht lokalisieren</string>
- <string name="git_abort_and_push_title">Abbrechen und hochladen</string>
+ <string name="git_abort_and_push_title">Abbrechen und pushen</string>
<string name="biometric_prompt_title">Biometrische Abfrage</string>
<string name="biometric_auth_error_reason">Authentifizierungsfehler: %s</string>
- <string name="pref_biometric_auth_title">Biometrische Authentifizierung aktivieren</string>
- <string name="pref_biometric_auth_summary">Wenn aktiviert, werden Sie beim Starten der App nach Ihrem Fingerabdruck gefragt</string>
- <string name="pref_biometric_auth_summary_error">Fingerabdrucksensor fehlt oder ist nicht ansprechbar</string>
- <string name="pref_title_openkeystore_clear_keyid">Lösche gespeicherte OpenKeystore SSH-Schlüssel-ID</string>
+ <string name="pref_biometric_auth_title">Biometrische Authentifizierung</string>
+ <string name="pref_biometric_auth_summary">Falls aktiviert, werden Sie beim Starten der App nach Ihrem Fingerabdruck gefragt.</string>
+ <string name="pref_biometric_auth_summary_error">Fingerabdrucksensor fehlt oder ist nicht ansprechbar.</string>
+ <string name="pref_title_openkeystore_clear_keyid">Lösche gespeicherte OpenKeystore SSH-Schlüssel-ID.</string>
<string name="your_public_key">Ihr öffentlicher Schlüssel</string>
- <string name="error_generate_ssh_key">Fehler beim Generieren des SSH-Schlüssels</string>
- <string name="pref_show_hidden_title">Dateien und Ordner anzeigen</string>
- <string name="pref_show_hidden_summary">Nicht-Passwort Dateien und Ordner in der Passwortliste mit einbeziehen</string>
+ <string name="error_generate_ssh_key">Fehler beim Erstellen des SSH-Schlüssels</string>
+ <string name="pref_show_hidden_title">Alle Dateien und Ordner anzeigen</string>
+ <string name="pref_show_hidden_summary">Nichtpasswort-Dateien und -Ordner in der Passwortliste anzeigen</string>
<string name="title_create_folder">Ordner erstellen</string>
<string name="title_rename_folder">Ordner umbenennen</string>
- <string name="message_category_error_empty_field">Der Name der Kategorie darf nicht leer sein</string>
- <string name="message_category_error_category_exists">Der Kategoriename existiert bereits</string>
- <string name="message_error_destination_outside_repo">Ziel muss innerhalb des repository sein</string>
+ <string name="message_category_error_empty_field">Der Name der Kategorie darf nicht leer sein.</string>
+ <string name="message_category_error_category_exists">Der Kategoriename existiert bereits.</string>
+ <string name="message_error_destination_outside_repo">Ziel muss innerhalb des Repositorys sein.</string>
<string name="message_rename_folder">Ziel für %1$s angeben</string>
<string name="button_create">Erstellen</string>
<string name="pref_search_on_start_title">Suchfeld beim Start öffnen</string>
<string name="pref_search_on_start_summary">Suchleiste beim Start der App anzeigen</string>
<string name="tap_clear_clipboard">Hier tippen, um die Zwischenablage zu löschen</string>
- <string name="clone_git_repo">Das Repository muss geklont werden, bevor Änderungen synchronisert werden können.</string>
- <string name="pref_app_theme_title">App Farbthema</string>
+ <string name="clone_git_repo">Das Repository muss geklont werden, bevor Änderungen synchronisiert werden können.</string>
+ <string name="pref_app_theme_title">App-Farbthema</string>
<string name="pref_app_theme_value_light">Hell</string>
<string name="pref_app_theme_value_dark">Dunkel</string>
<string name="pref_app_theme_value_battery_saver">Durch Energiesparmodus gesetzt</string>
@@ -236,83 +251,99 @@
<string name="connection_mode_ssh_key">SSH-Schlüssel</string>
<string name="connection_mode_basic_authentication">Passwort</string>
<string name="git_server_config_save_success">Konfiguration erfolgreich gespeichert</string>
- <string name="git_server_config_save_error">Die angegebene Repository URL ist ungültig</string>
- <string name="git_server_config_save_missing_username_https">Bitte geben Sie den HTTPS Benutzernamen in der Form https://username@example.com/… an</string>
- <string name="git_server_config_save_missing_username_ssh">Bitte geben Sie den SSH Benutzernamen in der Form username@example.com:… an</string>
+ <string name="git_server_config_save_error">Die angegebene Repository-URL ist ungültig.</string>
+ <string name="git_server_config_save_missing_username_https">Bitte geben Sie den HTTPS-Benutzernamen in der Form https://username@example.com/… an.</string>
+ <string name="git_server_config_save_missing_username_ssh">Bitte geben Sie den SSH-Benutzernamen in der Form username@example.com:… an.</string>
<string name="git_server_config_save_auth_mode_mismatch">Gültige Authentifizierungsarten für %1$s: %2$s</string>
<string name="git_operation_wrong_passphrase">Falsches Kennwort</string>
<string name="git_operation_wrong_password">Falsches Passwort</string>
<string name="bottom_sheet_create_new_folder">Neuen Ordner erstellen</string>
<string name="bottom_sheet_create_new_password">Neues Passwort erstellen</string>
- <string name="pref_debug_logging_summary">Debug logging aktivieren (Erfordert Neustart der App)</string>
- <string name="pref_debug_logging_title">Debug logging</string>
- <string name="preference_default_username_summary">Wenn Autofill den Benutzernamen nicht aus der Passwortdatei oder dem Ordner herleiten kann, wird der hier festgelegte Wert verwendet</string>
- <string name="preference_default_username_title">Standard Benutzername</string>
+ <string name="pref_debug_logging_summary">Debug-Ausgaben aktivieren (Erfordert Neustart der App)</string>
+ <string name="pref_debug_logging_title">Debug-Logging</string>
+ <string name="preference_default_username_summary">Wenn Autofill den Benutzernamen nicht aus der Passwortdatei oder dem Ordner herleiten kann, wird der hier festgelegte Wert verwendet.</string>
+ <string name="preference_default_username_title">Standard-Benutzername</string>
<string name="git_operation_remember_password">Passwort merken</string>
<string name="git_operation_hint_password">Passwort</string>
<string name="preference_custom_public_suffixes_title">Benutzerdefinierte Domains</string>
- <string name="preference_custom_public_suffixes_summary">Autofill wird Subdomains dieser Domains unterscheiden</string>
+ <string name="preference_custom_public_suffixes_summary">Autofill wird Subdomains dieser Domains unterscheiden.</string>
<string name="preference_custom_public_suffixes_hint">company.com\npersonal.com</string>
<!-- Password creation failure -->
<string name="password_creation_file_fail_title">Fehler</string>
- <string name="password_creation_file_write_fail_message">Fehler beim Speichern der Passwortdatei auf dem Speicher, bitte versuchen Sie es erneut.</string>
- <string name="password_creation_file_delete_fail_message">Fehler beim Löschen der Passwortdatei %1$s vom Speicher, bitte löschen Sie die Datei von Hand.</string>
- <string name="password_creation_duplicate_error">Datei existiert bereits, bitte benutzen Sie einen anderen Dateinamen</string>
+ <string name="password_creation_file_write_fail_message">Fehler beim Speichern der Passwortdatei im Password Store, bitte versuchen Sie es erneut.</string>
+ <string name="password_creation_file_delete_fail_message">Fehler beim Löschen der Passwortdatei %1$s aus dem Password Store, bitte löschen Sie die Datei von Hand.</string>
+ <string name="password_creation_duplicate_error">Datei existiert bereits, bitte benutzen Sie einen anderen Dateinamen.</string>
<string name="add_otp">OTP hinzufügen</string>
<string name="otp_import_success">TOTP-Konfiguration erfolgreich importiert</string>
<string name="otp_import_failure_generic">Import der TOTP-Konfiguration fehlgeschlagen</string>
- <string name="exporting_passwords">Exportiere Passwörter…</string>
- <string name="invalid_filename_text">Dateiname darf nicht \'/\' enthalten, Verzeichnis oben setzen</string>
+ <string name="otp_import_failure_no_selection">Keine Bilddatei ausgewählt</string>
+ <string name="exporting_passwords">Passwörter werden exportiert.</string>
+ <string name="invalid_gpg_id">.gpg-id wurde gefunden, enthält jedoch ungültige Schlüssel-ID, Fingerabdruck oder Benutzer-ID.</string>
+ <string name="short_gpg_id">.gpg-id wurde gefunden, enthält jedoch eine kurze Hex-ID, die nicht unterstützt wird.</string>
+ <string name="invalid_filename_text">Dateiname darf kein \'/\' enthalten; Verzeichnis oben setzen</string>
<string name="directory_hint">Ordner</string>
- <string name="new_folder_set_gpg_key">GPG Schlüssel für Ordner festlegen</string>
+ <string name="new_folder_set_gpg_key">PGP-Schlüssel für Ordner festlegen</string>
<!-- GitException messages -->
<string name="git_unknown_error">Unbekannter Fehler</string>
- <string name="git_pull_rebase_fail_error">Pull fehlgeschlagen. Du befindest dich in einem abgelösten Head. Speichere die Änderungen in \"Einstellungen &gt; Git-Werkzeuge\" auf das Remote-Repository in einem neuen Branch und löse den Konflikt auf deinem Computer auf.</string>
- <string name="git_pull_merge_fail_error">Merge fehlgeschlagen, du bist in einem Konflikt. TODO: Wiederherstellungsmethode hinzufügen.</string>
- <string name="git_push_nff_error">Push wurde vom Remote abgelehnt. Führe den Pull vor dem Push aus. Du kannst \"Synchronisieren\" statt Pull/Push nutzen, da es beides implementiert</string>
+ <string name="git_pull_rebase_fail_error">Pull fehlgeschlagen. Sie befinden sich in einem abgelösten Head. Speichern Sie die Änderungen in \"Einstellungen &gt; Lokale Git-Konfiguration &amp; Dienstprogramme\" auf das Remote-Repository in einem neuen Branch und lösen Sie den Konflikt auf Ihrem Computer auf.</string>
+ <string name="git_pull_merge_fail_error">Merge fehlgeschlagen, Sie befinden sich in einem Konflikt. TODO: Wiederherstellungsmethode hinzufügen.</string>
+ <string name="git_push_nff_error">Push wurde vom Remote abgelehnt. Führen Sie den Pull vor dem Push aus. Sie können \"Synchronisieren\" statt Pull/Push nutzen, da es beides implementiert</string>
<string name="git_push_generic_error">Push wurde von Remote abgelehnt, Grund: %1$s</string>
- <string name="git_push_other_error">Remote hat den Push abgelehnt. Prüfe die Variable receive.denyNonFastForwards in der Konfigurationsdatei des Ziel-Projektarchivs.</string>
+ <string name="git_push_other_error">Remote hat den Push abgelehnt. Prüfen Sie die Variable receive.denyNonFastForwards in der Konfigurationsdatei des Ziel-Repositorys.</string>
<string name="git_unknown_host">Unbekannter Host: %1$s</string>
<string name="git_operation_running">Git-Operation wird ausgeführt…</string>
- <string name="git_break_out_of_detached_success">Es gab einen Klonflikt während des rebase-Prozesses. Dein lokaler %1$s branch wurde auf einen anderen Branch namens %2$s gepusht.\nNutze diesen Branch um Konflikte auf deinem Computer zu beheben</string>
- <string name="git_break_out_of_detached_unneeded">Das Repository befindet sich nicht im Rebase-Prozess, es ist nicht nötig, den Zustand auf einen weiteren Branch zu pushen</string>
+ <string name="git_break_out_of_detached_success">Es gab einen Konflikt während des Rebase-Prozesses. Ihr lokaler Branch %1$s wurde auf einen anderen Branch namens %2$s gepusht.\nNutzen Sie diesen Branch, um den Konflikt auf dem Server zu beheben</string>
+ <string name="git_break_out_of_detached_unneeded">Das Repository befindet sich nicht im Rebase-Prozess; es ist nicht nötig, den Zustand auf einen weiteren Branch zu pushen.</string>
<!-- GPG key selection in folder creation -->
+ <string name="gpg_key_select_mandatory">Um fortzufahren, muss ein PGP-Schlüssel ausgewählt werden.</string>
<string name="folder_creation_err_file_exists">Dateiname bereits vergeben</string>
- <string name="folder_creation_err_folder_exists">Ein Ordner mit diesem Namen existiert bereits</string>
+ <string name="folder_creation_err_folder_exists">Ein Ordner mit diesem Namen existiert bereits.</string>
<!-- Onboarding flow -->
<string name="let_s_go">Los geht\'s</string>
- <string name="select_n_repository_type">Wähle\nRepository Art</string>
- <string name="select_repo_type_text">Wählen Sie aus, ob sie ein lokales Repository, oder ein remote Repository anlegen möchten.</string>
- <string name="clone_remote_repo">Remote Repository klonen</string>
+ <string name="select_n_repository_type">Wählen Sie einen \nRepository-Typ.</string>
+ <string name="select_repo_type_text">Wählen Sie aus, ob Sie ein lokales Repository anlegen, oder ein Remote-Repository klonen möchten.</string>
+ <string name="clone_remote_repo">Remote-Repository klonen</string>
<string name="create_local_repo">Lokales Repository anlegen</string>
- <string name="select_gpg_key_title">Wähle\nGPG Key</string>
- <string name="select_gpg_key_message">Wähle einen GPG-Key, mit dem du den Store initialisieren willst</string>
+ <string name="select_gpg_key_title">Wählen Sie einen\nPGP-Schlüssel.</string>
+ <string name="select_gpg_key_message">Wählen einen PGP-Schlüssel, mit dem der Store initialisiert werden soll.</string>
<string name="gpg_key_select">Schlüssel auswählen</string>
<!-- SSH port validation -->
<string name="ssh_scheme_needed_title">Möglicherweise inkorrekte URL</string>
- <string name="ssh_scheme_needed_message">Es sieht so aus, als ob Sie einen benutzerdefinierten Port in Ihrer URL angegeben haben, aber nicht in dem ssh://-Schema.\nDas kann dazu führen, dass Ihr Port als Teil des Pfades betrachtet wird. Drücken Sie hier auf OK um die URL zu korrigieren.</string>
- <string name="https_scheme_with_port_title">HTTPS URL mit nutzerdefiniertem Port</string>
- <string name="https_scheme_with_port_message">Es sieht aus, als nutzt du eine HTTPS-URL mit nutzerdefiniertem Port. Das ist nicht unterstützt und wird auf lange Sicht zu Problemen führen. Drücke OK, um den Port aus der URL zu entfernen.</string>
- <string name="git_scheme_disallowed_title">Es wird davon abgeraten, das git://-Protokoll zu nutzen</string>
- <string name="git_scheme_disallowed_message">Das git-Protokoll des git-Daemons untersützt keine verschlüsselten Verbindungen und ist für einen sicheren Betrieb nicht geeignet.</string>
+ <string name="ssh_scheme_needed_message">Es sieht so aus, als ob Sie einen benutzerdefinierten Port in Ihrer URL angegeben haben, aber nicht im ssh://-Schema.\nDas kann dazu führen, dass Ihr Port als Teil des Pfades betrachtet wird. Drücken Sie hier auf OK, um die URL zu korrigieren.</string>
+ <string name="https_scheme_with_port_title">HTTPS-URL mit benutzerdefiniertem Port</string>
+ <string name="https_scheme_with_port_message">Es sieht so aus, als nutzen Sie eine HTTPS-URL mit benutzerdefiniertem Port. Das ist nicht unterstützt und wird auf lange Sicht zu Problemen führen. Drücken Sie OK, um den Port aus der URL zu entfernen.</string>
+ <string name="git_scheme_disallowed_title">Es wird davon abgeraten, das git://-Protokoll zu nutzen.</string>
+ <string name="git_scheme_disallowed_message">Das Git-Protokoll des Git-Daemons unterstützt keine verschlüsselten Verbindungen und ist für einen sicheren Betrieb nicht geeignet.</string>
<!-- Proxy configuration activity -->
- <string name="proxy_hostname">Proxy Hostname</string>
+ <string name="activity_proxy_label">Proxy-Einstellungen</string>
+ <string name="proxy_hostname">Proxy-Hostname</string>
<string name="port">Port</string>
- <string name="pref_edit_proxy_settings">HTTP(S) Proxy Einstellungen</string>
+ <string name="pref_edit_proxy_settings">HTTP(S)-Proxy-Einstellungen</string>
<string name="invalid_proxy_url">Ungültige URL</string>
- <string name="clear_saved_host_key">Gespeicherten Host-Key löschen</string>
- <string name="clear_saved_host_key_success">Host-Key erfolgreich gelöscht!</string>
+ <string name="oreo_autofill_password_fill_and_conditional_save_support">Passwörter ausfüllen und speichern (Für das Speichern dürfen keine Dienste zur Barrierefreiheit aktiviert sein.)</string>
+ <string name="clear_saved_host_key">Gespeicherten Host-Schlüssel löschen</string>
+ <string name="clear_saved_host_key_success">Host-Schlüssel erfolgreich gelöscht!</string>
<string name="otp_import_qr_code">QR-Code scannen</string>
- <string name="otp_import_from_file">Wähle ein Bild</string>
+ <string name="otp_import_from_file">Wählen Sie ein Bild.</string>
<string name="otp_import_manual_entry">Manuell eingeben</string>
<string name="otp_import_manual_hint_secret">Schlüssel</string>
- <string name="otp_import_manual_hint_account">Account</string>
+ <string name="otp_import_manual_hint_account">Benutzer-Konto</string>
<string name="place_shortcut_on_home_screen">Verknüpfung auf dem Home-Screen erstellen</string>
<string name="password_list_fab_content_description">Neues Passwort oder neuen Ordner erstellen</string>
- <string name="pgp_key_import_failed">Fehler beim Import des PGP-Keys</string>
- <string name="pgp_key_import_succeeded">PGP-Key erfolgreich importiert</string>
- <string name="pgp_key_import_succeeded_message">Die Schlüssel-ID des importierten Schlüssels ist unten angegeben. Bitte überprüfe sie auf Korrektheit:\n%1$s</string>
- <string name="pref_category_pgp_title">PGP Einstellungen</string>
- <string name="pwgen_some_error_occurred">Ein Fehler ist aufgetreten</string>
+ <string name="pgp_key_import_failed">Fehler beim Import des PGP-Schlüssels</string>
+ <string name="pgp_key_import_failed_replace_message">Ein bestehender Schlüssel mit dieser ID wurde gefunden. Möchten Sie ihn ersetzen?</string>
+ <string name="pgp_key_import_succeeded">PGP-Schlüssel erfolgreich importiert</string>
+ <string name="pgp_key_import_succeeded_message">Die ID des importierten Schlüssels ist unten angegeben. Bitte überprüfen Sie deren Korrektheit:\n%1$s</string>
+ <string name="pref_category_pgp_title">PGP-Einstellungen</string>
+ <string name="pwgen_some_error_occurred">Ein Fehler ist aufgetreten.</string>
<string name="git_run_gc_job">Garbage Collection ausführen</string>
+ <string name="activity_label_pgp_key_manager">PGP-Schlüsselmanager</string>
+ <string name="pgp_key_manager_delete_confirmation_dialog_title">Schlüssel löschen?</string>
+ <string name="git_utils_reset_remote_branch_title">Name des Remote-Branchs</string>
+ <string name="pgp_key_manager_no_keys_guidance">Importieren Sie einen Schlüssel über die unten befindliche Schaltfläche \"+\".</string>
+ <string name="no_keys_imported_dialog_title">Keine Schlüssel importiert</string>
+ <string name="no_keys_imported_dialog_message">Es wurden noch keine PGP-Schlüssel in die App importiert. Wählen Sie eine Schlüsseldatei über die Schaltfläche \"Importieren\" aus.</string>
+ <string name="biometric_prompt_title_gpg_passphrase_cache">Freischalten des Passphrase-Zwischenspeichers</string>
+ <string name="aead_detect_title">AEAD-Verschlüsselung festgestellt</string>
+ <string name="aead_detect_message">%1$s, siehe https://passwordstore.app/fix-aead für weiterführende Informationen.</string>
</resources>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 21c50a19..d6edd7b8 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -95,7 +95,6 @@
<string name="ssh_key_error_dialog_text">Message : \n</string>
<string name="pref_recursive_filter_title">Filtrage récursif</string>
<string name="pref_recursive_filter_summary">Cherche le mot de passe dans tous les sous-répertoires du répertoire actuel.</string>
- <string name="pref_directory_structure">Organisation des fichiers de mot de passe</string>
<string name="pref_sort_order_title">Ordre de tri des mots de passe</string>
<string name="pref_folder_first_sort_order">Dossiers en premier</string>
<string name="pref_file_first_sort_order">Fichiers en premier</string>
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 2b56ae8c..728fc6ae 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -95,7 +95,6 @@
<string name="ssh_key_error_dialog_text">Messaggio : \n</string>
<string name="pref_recursive_filter_title">Filtro ricorsivo</string>
<string name="pref_recursive_filter_summary">Trova ricorsivamente le password della directory corrente.</string>
- <string name="pref_directory_structure">Organizzazione dei file di password</string>
<string name="pref_sort_order_title">Ordine password</string>
<string name="pref_folder_first_sort_order">Prima le cartelle</string>
<string name="pref_file_first_sort_order">Prima i file</string>
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 6ce154d6..6f4b9ed9 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -36,6 +36,7 @@
<string name="git_commit_remove_text">Remova %1$s do armazenamento.</string>
<string name="git_commit_move_text">Renomear %1$s para %2$s.</string>
<string name="git_commit_move_multiple_text">Mova múltiplas senhas para %1$s.</string>
+ <string name="git_commit_gpg_id">Inicializar IDs GPG em %1$s.</string>
<!-- PGPHandler -->
<string name="clipboard_copied_text">Copiado para a área de transferência</string>
<string name="file_toast_text">Por favor, informe um nome de arquivo</string>
@@ -71,6 +72,7 @@
<string name="action_search">Pesquisar</string>
<string name="password">Senha:</string>
<string name="username">Usuário:</string>
+ <string name="copy_label">Copiar</string>
<string name="edit_password">Editar senha</string>
<string name="copy_password">Copiar senha</string>
<string name="share_as_plaintext">Compartilhar como texto</string>
@@ -95,7 +97,6 @@
<string name="ssh_key_error_dialog_text">Mensagem : \n</string>
<string name="pref_recursive_filter_title">Filtragem recursiva</string>
<string name="pref_recursive_filter_summary">Encontrar senhas do diretório corrente recursivamente.</string>
- <string name="pref_directory_structure">Organização do arquivo de senha</string>
<string name="pref_sort_order_title">Ordenação da Senha</string>
<string name="pref_folder_first_sort_order">Pastas primeiro</string>
<string name="pref_file_first_sort_order">Arquivos primeiro</string>
@@ -117,6 +118,11 @@
<string name="pref_import_pgp_key_title">Importar chave PGP</string>
<string name="pref_pgp_key_manager_title">Gerenciador de Chaves</string>
<string name="pref_pgp_ascii_armor_title">Criptografar no modo de proteção ASCII</string>
+ <string name="pref_passphrase_cache_title">Ativar cache da senha</string>
+ <string name="pref_passphrase_cache_summary">AVISO: este recurso é funcional mas muito experimental. Requer um bloqueio de tela ativo.</string>
+ <string name="pref_passphrase_cache_authenticate_enable">Autenticar para ativar o cache</string>
+ <string name="pref_passphrase_cache_auto_clear_title">Limpar automaticamente cache de senha</string>
+ <string name="pref_passphrase_cache_auto_clear_summary">Limpa o cache de senha quando a tela está desligada</string>
<!-- PasswordGenerator fragment -->
<string name="pwgen_title">Gerar Senha</string>
<string name="pwgen_generate">Gerar</string>
@@ -273,6 +279,7 @@
<string name="otp_import_failure_no_selection">Nenhum arquivo de imagem foi selecionado</string>
<string name="exporting_passwords">Exportando senhas…</string>
<string name="invalid_gpg_id">Encontrado .gpg-id, mas contém um ID de chave, fingerprint ou ID de usuário inválidos</string>
+ <string name="short_gpg_id">Encontrado .gpg-id, mas contém uma ID hexadecimal curta, que não é suportada</string>
<string name="invalid_filename_text">Nome do arquivo não deve conter \'/\', defina o diretório acima</string>
<string name="directory_hint">Diretório</string>
<string name="new_folder_set_gpg_key">Definir chave GPG para diretório</string>
@@ -288,6 +295,7 @@
<string name="git_break_out_of_detached_success">Houve um conflito ao executar o rebase. Houve um push de branch %1$s local para outra branch chamada %2$s\n Use esta branch para resolver o conflito no seu computador</string>
<string name="git_break_out_of_detached_unneeded">O repositório não está sendo rebased, não há necessidade de fazer push para outro branch</string>
<!-- GPG key selection in folder creation -->
+ <string name="gpg_key_select_mandatory">A seleção de uma chave GPG é necessária para prosseguir</string>
<string name="folder_creation_err_file_exists">Já existe um arquivo com esse nome</string>
<string name="folder_creation_err_folder_exists">Já existe uma pasta com esse nome</string>
<!-- Onboarding flow -->
@@ -335,4 +343,7 @@
<string name="pgp_key_manager_no_keys_guidance">Importar uma chave usando o botão Adicionar abaixo</string>
<string name="no_keys_imported_dialog_title">Nenhuma chave importada</string>
<string name="no_keys_imported_dialog_message">Não há chaves PGP importadas no aplicativo ainda, pressione o botão abaixo para escolher um arquivo de chave</string>
+ <string name="biometric_prompt_title_gpg_passphrase_cache">Desbloquear cache da senha</string>
+ <string name="aead_detect_title">Criptografia AEAD detectada</string>
+ <string name="aead_detect_message">%1$s, consulte https://passwordstore.app/fix-aead para obter mais informações</string>
</resources>
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index be12a681..223abe2c 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -100,7 +100,6 @@
<string name="ssh_key_error_dialog_text">Сообщение: \n</string>
<string name="pref_recursive_filter_title">Рекурсивная фильтрация</string>
<string name="pref_recursive_filter_summary">Рекурсивный поиск паролей в текущей директории</string>
- <string name="pref_directory_structure">Организация файла паролей</string>
<string name="pref_sort_order_title">Порядок сортировки паролей</string>
<string name="pref_folder_first_sort_order">Сначала папки</string>
<string name="pref_file_first_sort_order">Сначала файлы</string>
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 420092d0..d2f3ac6c 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -96,7 +96,6 @@
<string name="ssh_key_error_dialog_text">消息: </string>
<string name="pref_recursive_filter_title">递归过滤</string>
<string name="pref_recursive_filter_summary">递归式寻找当前目录的密码</string>
- <string name="pref_directory_structure">密码文件组</string>
<string name="pref_sort_order_title">密码排序顺序</string>
<string name="pref_folder_first_sort_order">目录优先</string>
<string name="pref_file_first_sort_order">文件优先</string>
diff --git a/app/src/nonFree/res/values-ar/strings.xml b/app/src/nonFree/res/values-ar/strings.xml
new file mode 100644
index 00000000..7a6a3cb6
--- /dev/null
+++ b/app/src/nonFree/res/values-ar/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
+ ~ SPDX-License-Identifier: GPL-3.0-only
+ -->
+<resources>
+ <string name="oreo_autofill_waiting_for_sms">في انتظار الرسائل القصيرة…</string>
+</resources>
diff --git a/app/src/nonFree/res/values-es/strings.xml b/app/src/nonFree/res/values-es/strings.xml
new file mode 100644
index 00000000..a80f9454
--- /dev/null
+++ b/app/src/nonFree/res/values-es/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
+ ~ SPDX-License-Identifier: GPL-3.0-only
+ -->
+<resources>
+ <string name="oreo_autofill_waiting_for_sms">Esperando por SMS…</string>
+</resources>
diff --git a/app/src/nonFree/res/values-fi/strings.xml b/app/src/nonFree/res/values-fi/strings.xml
new file mode 100644
index 00000000..a57feb73
--- /dev/null
+++ b/app/src/nonFree/res/values-fi/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
+ ~ SPDX-License-Identifier: GPL-3.0-only
+ -->
+<resources>
+ <string name="oreo_autofill_waiting_for_sms">Odotetaan SMS-viestiä…</string>
+</resources>
diff --git a/app/src/nonFree/res/values-gl-rES/strings.xml b/app/src/nonFree/res/values-gl-rES/strings.xml
new file mode 100644
index 00000000..b68283db
--- /dev/null
+++ b/app/src/nonFree/res/values-gl-rES/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
+ ~ SPDX-License-Identifier: GPL-3.0-only
+ -->
+<resources>
+ <string name="oreo_autofill_waiting_for_sms">Agardando polo SMS…</string>
+</resources>
diff --git a/app/src/nonFree/res/values-hu/strings.xml b/app/src/nonFree/res/values-hu/strings.xml
new file mode 100644
index 00000000..6ebce291
--- /dev/null
+++ b/app/src/nonFree/res/values-hu/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
+ ~ SPDX-License-Identifier: GPL-3.0-only
+ -->
+<resources>
+ <string name="oreo_autofill_waiting_for_sms">SMS-re várakozás…</string>
+</resources>
diff --git a/app/src/nonFree/res/values-ko/strings.xml b/app/src/nonFree/res/values-ko/strings.xml
new file mode 100644
index 00000000..d98dca63
--- /dev/null
+++ b/app/src/nonFree/res/values-ko/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
+ ~ SPDX-License-Identifier: GPL-3.0-only
+ -->
+<resources>
+ <string name="oreo_autofill_waiting_for_sms">SMS를 기다리는 중입니다…</string>
+</resources>
diff --git a/app/src/nonFree/res/values-pl/strings.xml b/app/src/nonFree/res/values-pl/strings.xml
new file mode 100644
index 00000000..ba2f05ed
--- /dev/null
+++ b/app/src/nonFree/res/values-pl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
+ ~ SPDX-License-Identifier: GPL-3.0-only
+ -->
+<resources>
+ <string name="oreo_autofill_waiting_for_sms">Oczekiwanie na SMS…</string>
+</resources>
diff --git a/app/src/nonFree/res/values-uk/strings.xml b/app/src/nonFree/res/values-uk/strings.xml
index 60c52f48..86d935ee 100644
--- a/app/src/nonFree/res/values-uk/strings.xml
+++ b/app/src/nonFree/res/values-uk/strings.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
~ Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
~ SPDX-License-Identifier: GPL-3.0-only
-->
diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts
index e4d082ea..4be841d2 100644
--- a/build-logic/build.gradle.kts
+++ b/build-logic/build.gradle.kts
@@ -17,10 +17,6 @@ gradlePlugin {
id = "com.github.android-password-store.android-library"
implementationClass = "app.passwordstore.gradle.LibraryPlugin"
}
- register("crowdin") {
- id = "com.github.android-password-store.crowdin-plugin"
- implementationClass = "app.passwordstore.gradle.crowdin.CrowdinDownloadPlugin"
- }
register("git-hooks") {
id = "com.github.android-password-store.git-hooks"
implementationClass = "app.passwordstore.gradle.GitHooksPlugin"
diff --git a/build-logic/src/main/kotlin/app/passwordstore/gradle/OkHttp.kt b/build-logic/src/main/kotlin/app/passwordstore/gradle/OkHttp.kt
index e3d33432..7f26d427 100644
--- a/build-logic/src/main/kotlin/app/passwordstore/gradle/OkHttp.kt
+++ b/build-logic/src/main/kotlin/app/passwordstore/gradle/OkHttp.kt
@@ -13,12 +13,6 @@ object OkHttp {
private val certificatePinner =
CertificatePinner.Builder()
.add(
- "api.crowdin.com",
- "sha256/qKpGqFXXIteblI82BcMyRX0eC2o7lpL9XVInWKIG7rc=",
- "sha256/DxH4tt40L+eduF6szpY6TONlxhZhBd+pJ9wbHlQ2fuw=",
- "sha256/++MBgDH5WGvL9Bcn5Be30cRcL0f5O+NyoXuWtQdX1aI=",
- )
- .add(
"publicsuffix.org",
"sha256/Ov/MkC2OkVtTp9MdY+uXOKAuV2Birfdeazval8seMZM=",
"sha256/jQJTbIh0grw0/1TkHSumWb+Fs0Ggogr621gT3PvPKG0=",
diff --git a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/BuildOnApiTask.kt b/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/BuildOnApiTask.kt
deleted file mode 100644
index 0fc143d1..00000000
--- a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/BuildOnApiTask.kt
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.gradle.crowdin
-
-import app.passwordstore.gradle.OkHttp
-import app.passwordstore.gradle.crowdin.api.ListProjects
-import com.squareup.moshi.Moshi
-import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
-import okhttp3.MediaType.Companion.toMediaType
-import okhttp3.Request
-import okhttp3.RequestBody.Companion.toRequestBody
-import org.gradle.api.DefaultTask
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.Internal
-import org.gradle.api.tasks.TaskAction
-import org.gradle.work.DisableCachingByDefault
-
-@DisableCachingByDefault(because = "This calls into a remote API and has nothing to cache")
-abstract class BuildOnApiTask : DefaultTask() {
-
- @get:Input abstract val crowdinIdentifier: Property<String>
- @get:Internal abstract val crowdinLogin: Property<String>
- @get:Internal abstract val crowdinKey: Property<String>
-
- @TaskAction
- fun doWork() {
- val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
- val projectAdapter = moshi.adapter(ListProjects::class.java)
- val projectRequest =
- Request.Builder()
- .url("$CROWDIN_BASE_URL/projects")
- .header("Authorization", "Bearer ${crowdinKey.get()}")
- .get()
- .build()
- OkHttp.CLIENT.newCall(projectRequest).execute().use { response ->
- val projects = projectAdapter.fromJson(response.body.source())
- if (projects != null) {
- val identifier =
- projects.projects
- .first { data -> data.project.identifier == crowdinIdentifier.get() }
- .project
- .id
- .toString()
- val buildRequest =
- Request.Builder()
- .url(CROWDIN_BUILD_API_URL.format(identifier))
- .header("Authorization", "Bearer ${crowdinKey.get()}")
- .post("{}".toRequestBody("application/json".toMediaType()))
- .build()
- OkHttp.CLIENT.newCall(buildRequest).execute().close()
- }
- }
- }
-
- private companion object {
-
- private const val CROWDIN_BASE_URL = "https://api.crowdin.com/api/v2"
- private const val CROWDIN_BUILD_API_URL = "$CROWDIN_BASE_URL/projects/%s/translations/builds"
- }
-}
diff --git a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinExtension.kt b/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinExtension.kt
deleted file mode 100644
index b78d66d3..00000000
--- a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinExtension.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.gradle.crowdin
-
-import org.gradle.api.provider.Property
-
-/** Extension for configuring [CrowdinDownloadPlugin] */
-interface CrowdinExtension {
-
- /** Configure the project name on Crowdin */
- val crowdinIdentifier: Property<String>
-
- /**
- * Don't delete downloaded and extracted translation archives from build directory.
- *
- * Useful for debugging.
- */
- val skipCleanup: Property<Boolean>
-}
diff --git a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinPlugin.kt b/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinPlugin.kt
deleted file mode 100644
index f127507a..00000000
--- a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/CrowdinPlugin.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.gradle.crowdin
-
-import de.undercouch.gradle.tasks.download.Download
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.tasks.Copy
-import org.gradle.api.tasks.Delete
-import org.gradle.kotlin.dsl.create
-import org.gradle.kotlin.dsl.register
-
-@Suppress("Unused")
-class CrowdinDownloadPlugin : Plugin<Project> {
-
- override fun apply(project: Project) {
- with(project) {
- val extension = extensions.create<CrowdinExtension>("crowdin")
- val login = providers.environmentVariable("CROWDIN_LOGIN")
- val key = providers.environmentVariable("CROWDIN_PROJECT_KEY")
- val buildOnApi =
- if (login.isPresent && key.isPresent) {
- tasks.register<BuildOnApiTask>("buildOnApi") {
- crowdinIdentifier.set(extension.crowdinIdentifier)
- crowdinLogin.set(login)
- crowdinKey.set(key)
- }
- } else {
- null
- }
- val downloadCrowdin =
- tasks.register<Download>("downloadCrowdin") {
- if (buildOnApi != null) dependsOn(buildOnApi)
- src(
- "https://crowdin.com/backend/download/project/${extension.crowdinIdentifier.get()}.zip"
- )
- dest(layout.buildDirectory.file("translations.zip"))
- overwrite(true)
- }
- val extractCrowdin =
- tasks.register<Copy>("extractCrowdin") {
- from(zipTree(downloadCrowdin.map { it.outputFiles.first() }))
- into(layout.buildDirectory.dir("translations"))
- }
- val extractStrings =
- tasks.register<Copy>("extractStrings") {
- from(extractCrowdin.map { it.destinationDir })
- into(layout.projectDirectory.dir("src"))
- }
- val removeIncompleteStrings =
- tasks.register<StringCleanupTask>("removeIncompleteStrings") {
- sourceDirectory.set(
- objects.directoryProperty().fileProvider(extractStrings.map { it.destinationDir })
- )
- }
- tasks.register<Delete>("crowdin") {
- dependsOn(removeIncompleteStrings)
- delete =
- if (extension.skipCleanup.getOrElse(false)) {
- emptySet()
- } else {
- setOf(extractStrings.map { it.source }, downloadCrowdin.map { it.outputFiles })
- }
- }
- }
- }
-}
diff --git a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/StringCleanupTask.kt b/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/StringCleanupTask.kt
deleted file mode 100644
index 7f91368c..00000000
--- a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/StringCleanupTask.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.gradle.crowdin
-
-import java.io.File
-import javax.xml.parsers.DocumentBuilderFactory
-import org.gradle.api.DefaultTask
-import org.gradle.api.GradleException
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.TaskAction
-import org.gradle.work.DisableCachingByDefault
-import org.w3c.dom.Document
-
-@DisableCachingByDefault(because = "The task runs quickly and has complicated semantics")
-abstract class StringCleanupTask : DefaultTask() {
-
- @get:InputDirectory abstract val sourceDirectory: DirectoryProperty
-
- @TaskAction
- fun clean() {
- val sourceSets = arrayOf("main", "nonFree")
- for (sourceSet in sourceSets) {
- val fileTreeWalk = sourceDirectory.dir("$sourceSet/res").get().asFile.walkTopDown()
- val valuesDirectories =
- fileTreeWalk.filter { it.isDirectory }.filter { it.name.startsWith("values") }
- val stringFiles = fileTreeWalk.filter { it.name == "strings.xml" }
- val sourceFile =
- stringFiles.firstOrNull { it.path.endsWith("values/strings.xml") }
- ?: throw GradleException("No root strings.xml found in '$sourceSet' sourceSet")
- val sourceDoc = parseDocument(sourceFile)
- val baselineStringCount = countStrings(sourceDoc)
- val threshold = 0.80 * baselineStringCount
- stringFiles.forEach { file ->
- if (file != sourceFile) {
- val doc = parseDocument(file)
- val stringCount = countStrings(doc)
- if (stringCount < threshold) {
- file.delete()
- }
- }
- }
- valuesDirectories.forEach { dir ->
- if (dir.listFiles().isNullOrEmpty()) {
- dir.delete()
- }
- }
- }
- }
-
- private fun parseDocument(file: File): Document {
- val dbFactory = DocumentBuilderFactory.newInstance()
- val documentBuilder = dbFactory.newDocumentBuilder()
- return documentBuilder.parse(file)
- }
-
- private fun countStrings(document: Document): Int {
- // Normalization is beneficial for us
- // https://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
- document.documentElement.normalize()
- return document.getElementsByTagName("string").length
- }
-}
diff --git a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/api/ListProjects.kt b/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/api/ListProjects.kt
deleted file mode 100644
index 933d7e02..00000000
--- a/build-logic/src/main/kotlin/app/passwordstore/gradle/crowdin/api/ListProjects.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright © 2014-2024 The Android Password Store Authors. All Rights Reserved.
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-package app.passwordstore.gradle.crowdin.api
-
-import com.squareup.moshi.Json
-
-data class ListProjects(@Json(name = "data") val projects: List<ProjectData>)
-
-data class ProjectData(@Json(name = "data") val project: Project)
-
-data class Project(val id: Long, val identifier: String)
diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 00000000..116a2194
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,90 @@
+"api_token_env": "CROWDIN_PERSONAL_TOKEN"
+"project_id_env": "CROWDIN_PROJECT_ID"
+"preserve_hierarchy": true
+"files": [
+ {
+ "source": "/app/src/main/res/values/strings.xml",
+ "dest": "/main_strings.xml",
+ "translation": "/app/src/main/res/values-%android_code%/strings.xml",
+ "languages_mapping": &stringmapping {
+ "android_code": {
+ "ar": "ar",
+ "am": "am",
+ "hy-AM": "hy-rAM",
+ "az": "az",
+ "be": "be",
+ "bn": "bn-rBD",
+ "bg": "bg",
+ "ca": "ca",
+ "cs": "cs",
+ "da": "da",
+ "de": "de",
+ "el": "el",
+ "es-ES": "es",
+ "es-AR": "es-rAR",
+ "es-MX": "es-rMX",
+ "es-VE": "es-rVE",
+ "et": "et-rEE",
+ "eu": "eu-rES",
+ "fa": "fa",
+ "fil": "fil",
+ "fi": "fi",
+ "fr": "fr",
+ "gl": "gl-rES",
+ "hr": "hr",
+ "hu": "hu",
+ "is": "is",
+ "id": "in",
+ "it": "it",
+ "he": "iw",
+ "ja": "ja",
+ "ka": "ka-rGE",
+ "km": "km-rKH",
+ "kn": "kn-rIN",
+ "ko": "ko",
+ "ky": "ky-rKG",
+ "lt": "lt",
+ "lv": "lv",
+ "lo": "lo-rLA",
+ "ms": "ms",
+ "ml-IN": "ml-rIN",
+ "mn": "mn-rMN",
+ "mr": "mr-rIN",
+ "my": "my-rMM",
+ "ne-NP": "ne-rNP",
+ "nl": "nl",
+ "no": "nb",
+ "pl": "pl",
+ "pt-PT": "pt",
+ "pt-BR": "pt-rBR",
+ "ro": "ro",
+ "ru": "ru",
+ "rm-CH": "rm",
+ "si-LK": "si-rLK",
+ "sk": "sk",
+ "sl": "sl",
+ "sr": "sr",
+ "sv-SE": "sv",
+ "sw": "sw",
+ "th": "th",
+ "ta": "ta-rIN",
+ "te": "te-rIN",
+ "tr": "tr",
+ "uk": "uk",
+ "ur-IN": "ur-rIN",
+ "uz": "uz",
+ "vi": "vi",
+ "zh-CN": "zh-rCN",
+ "zh-HK": "zh-rHK",
+ "zh-TW": "zh-rTW",
+ "zu": "zu"
+ }
+ }
+ },
+ {
+ "source": "/app/src/nonFree/res/values/strings.xml",
+ "dest": "/nonFree_strings.xml",
+ "translation": "/app/src/nonFree/res/values-%android_code%/strings.xml",
+ "languages_mapping": *stringmapping
+ }
+]