瀏覽代碼

Merge master

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 1 年之前
父節點
當前提交
b14206ef33
共有 79 個文件被更改,包括 2252 次插入496 次删除
  1. 1 1
      .github/workflows/analysis.yml
  2. 3 3
      .github/workflows/codeql.yml
  3. 1 1
      .github/workflows/scorecard.yml
  4. 1 1
      .github/workflows/unit-tests.yml
  5. 1 1
      app/build.gradle
  6. 1161 0
      app/schemas/com.nextcloud.client.database.NextcloudDatabase/74.json
  7. 二進制
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileAllShareTypes.png
  8. 二進制
      app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileNone.png
  9. 0 2
      app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.kt
  10. 3 3
      app/src/androidTest/java/com/owncloud/android/UploadIT.java
  11. 2 0
      app/src/androidTest/java/com/owncloud/android/datamodel/OCCapabilityIT.kt
  12. 3 2
      app/src/huawei/java/com/owncloud/android/ui/activity/HuaweiCommunityActivity.kt
  13. 11 4
      app/src/main/java/com/nextcloud/android/sso/InputStreamBinder.java
  14. 4 3
      app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt
  15. 3 1
      app/src/main/java/com/nextcloud/client/database/entity/CapabilityEntity.kt
  16. 11 0
      app/src/main/java/com/nextcloud/client/database/migrations/DatabaseMigrationUtil.kt
  17. 0 38
      app/src/main/java/com/nextcloud/client/database/migrations/Migration70to71.kt
  18. 2 2
      app/src/main/java/com/nextcloud/client/di/ComponentsModule.java
  19. 1 0
      app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt
  20. 4 0
      app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt
  21. 21 6
      app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt
  22. 32 0
      app/src/main/java/com/nextcloud/utils/extensions/TextViewExtensions.kt
  23. 2 0
      app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
  24. 2 1
      app/src/main/java/com/owncloud/android/db/ProviderMeta.java
  25. 36 22
      app/src/main/java/com/owncloud/android/files/services/FileUploader.java
  26. 0 128
      app/src/main/java/com/owncloud/android/ui/activity/CommunityActivity.java
  27. 146 0
      app/src/main/java/com/owncloud/android/ui/activity/CommunityActivity.kt
  28. 10 16
      app/src/main/java/com/owncloud/android/ui/activity/CopyToClipboardActivity.kt
  29. 1 1
      app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
  30. 18 29
      app/src/main/java/com/owncloud/android/ui/activity/FilePickerActivity.kt
  31. 2 1
      app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt
  32. 4 5
      app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java
  33. 4 4
      app/src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java
  34. 0 105
      app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalConfirmationDialog.kt
  35. 194 0
      app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalDialog.kt
  36. 101 13
      app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
  37. 1 1
      app/src/main/java/com/owncloud/android/ui/fragment/FileDetailsSharingProcessFragment.kt
  38. 28 33
      app/src/main/java/com/owncloud/android/utils/ClipboardUtil.kt
  39. 13 0
      app/src/main/java/com/owncloud/android/utils/FilesUploadHelper.kt
  40. 26 0
      app/src/main/res/drawable/ic_contact_book.xml
  41. 154 0
      app/src/main/res/layout/account_removal_dialog.xml
  42. 36 21
      app/src/main/res/layout/file_details_sharing_fragment.xml
  43. 2 1
      app/src/main/res/values-ar/strings.xml
  44. 6 1
      app/src/main/res/values-b+en+001/strings.xml
  45. 2 1
      app/src/main/res/values-cs-rCZ/strings.xml
  46. 0 1
      app/src/main/res/values-da/strings.xml
  47. 2 1
      app/src/main/res/values-de/strings.xml
  48. 9 0
      app/src/main/res/values-eo/strings.xml
  49. 1 0
      app/src/main/res/values-es-rCL/strings.xml
  50. 1 0
      app/src/main/res/values-es-rSV/strings.xml
  51. 4 0
      app/src/main/res/values-es/strings.xml
  52. 1 0
      app/src/main/res/values-et-rEE/strings.xml
  53. 2 0
      app/src/main/res/values-eu/strings.xml
  54. 2 0
      app/src/main/res/values-fa/strings.xml
  55. 2 0
      app/src/main/res/values-fi-rFI/strings.xml
  56. 1 1
      app/src/main/res/values-fr/strings.xml
  57. 2 1
      app/src/main/res/values-gl/strings.xml
  58. 0 1
      app/src/main/res/values-hu-rHU/strings.xml
  59. 39 1
      app/src/main/res/values-in/strings.xml
  60. 3 0
      app/src/main/res/values-is/strings.xml
  61. 15 0
      app/src/main/res/values-nb-rNO/strings.xml
  62. 2 1
      app/src/main/res/values-pl/strings.xml
  63. 8 6
      app/src/main/res/values-ro/strings.xml
  64. 0 1
      app/src/main/res/values-ru/strings.xml
  65. 45 0
      app/src/main/res/values-sl/strings.xml
  66. 2 1
      app/src/main/res/values-sr/strings.xml
  67. 2 1
      app/src/main/res/values-sv/strings.xml
  68. 3 2
      app/src/main/res/values-tr/strings.xml
  69. 1 1
      app/src/main/res/values-uk/strings.xml
  70. 2 1
      app/src/main/res/values-zh-rCN/strings.xml
  71. 5 0
      app/src/main/res/values-zh-rHK/strings.xml
  72. 2 1
      app/src/main/res/values-zh-rTW/strings.xml
  73. 7 2
      app/src/main/res/values/strings.xml
  74. 1 1
      build.gradle
  75. 7 2
      gradle.properties
  76. 1 1
      scripts/analysis/lint-results.txt
  77. 6 0
      settings.gradle
  78. 17 15
      src/generic/fastlane/metadata/android/ro-RO/full_description.txt
  79. 4 3
      src/versionDev/fastlane/metadata/android/ro-RO/full_description.txt

+ 1 - 1
.github/workflows/analysis.yml

@@ -38,7 +38,7 @@ jobs:
                     repository: ${{ steps.get-vars.outputs.repo }}
                     ref: ${{ steps.get-vars.outputs.branch }}
             -   name: Set up JDK 17
-                uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
+                uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
                 with:
                     distribution: "temurin"
                     java-version: 17

+ 3 - 3
.github/workflows/codeql.yml

@@ -32,11 +32,11 @@ jobs:
         with:
           swap-size-gb: 10
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@66b90a5db151a8042fa97405c6cf843bbe433f7b # v2.22.7
+        uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
         with:
           languages: ${{ matrix.language }}
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
         with:
           distribution: "temurin"
           java-version: 17
@@ -46,4 +46,4 @@ jobs:
           echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
           ./gradlew assembleDebug
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@66b90a5db151a8042fa97405c6cf843bbe433f7b # v2.22.7
+        uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8

+ 1 - 1
.github/workflows/scorecard.yml

@@ -37,6 +37,6 @@ jobs:
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@66b90a5db151a8042fa97405c6cf843bbe433f7b # v2.22.7
+        uses: github/codeql-action/upload-sarif@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
         with:
           sarif_file: results.sarif

+ 1 - 1
.github/workflows/unit-tests.yml

@@ -30,7 +30,7 @@ jobs:
                 if: ${{ always() }}
                 run: scripts/deleteOldComments.sh "test" "Unit" ${{github.event.number}}
             -   name: Run unit tests with coverage
-                uses: gradle/gradle-build-action@842c587ad8aa4c68eeba24c396e15af4c2e9f30a # v2.9.0
+                uses: gradle/gradle-build-action@87a9a15658c426a54dd469d4fc7dc1a73ca9d4a6 # v2.10.0
                 with:
                     arguments: jacocoTestGplayDebugUnitTest
             -   name: Upload failing results

+ 1 - 1
app/build.gradle

@@ -377,7 +377,7 @@ dependencies {
     gplayImplementation "com.google.firebase:firebase-messaging:23.2.1"
     gplayImplementation 'com.google.android.play:review-ktx:2.0.1'
 
-    implementation 'com.github.nextcloud.android-common:ui:0.12.0'
+    implementation 'com.github.nextcloud.android-common:ui:0.13.0'
 
     implementation "androidx.room:room-runtime:$roomVersion"
     ksp "androidx.room:room-compiler:$roomVersion"

+ 1161 - 0
app/schemas/com.nextcloud.client.database.NextcloudDatabase/74.json

@@ -0,0 +1,1161 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 74,
+    "identityHash": "7e73c045ac6d52d6c7c1626eefbc21e9",
+    "entities": [
+      {
+        "tableName": "arbitrary_data",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `cloud_id` TEXT, `key` TEXT, `value` TEXT)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "cloudId",
+            "columnName": "cloud_id",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "key",
+            "columnName": "key",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "value",
+            "columnName": "value",
+            "affinity": "TEXT",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "capabilities",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` TEXT, `version_mayor` INTEGER, `version_minor` INTEGER, `version_micro` INTEGER, `version_string` TEXT, `version_edition` TEXT, `extended_support` INTEGER, `core_pollinterval` INTEGER, `sharing_api_enabled` INTEGER, `sharing_public_enabled` INTEGER, `sharing_public_password_enforced` INTEGER, `sharing_public_expire_date_enabled` INTEGER, `sharing_public_expire_date_days` INTEGER, `sharing_public_expire_date_enforced` INTEGER, `sharing_public_send_mail` INTEGER, `sharing_public_upload` INTEGER, `sharing_user_send_mail` INTEGER, `sharing_resharing` INTEGER, `sharing_federation_outgoing` INTEGER, `sharing_federation_incoming` INTEGER, `files_bigfilechunking` INTEGER, `files_undelete` INTEGER, `files_versioning` INTEGER, `external_links` INTEGER, `server_name` TEXT, `server_color` TEXT, `server_text_color` TEXT, `server_element_color` TEXT, `server_slogan` TEXT, `server_logo` TEXT, `background_url` TEXT, `end_to_end_encryption` INTEGER, `end_to_end_encryption_keys_exist` INTEGER, `activity` INTEGER, `background_default` INTEGER, `background_plain` INTEGER, `richdocument` INTEGER, `richdocument_mimetype_list` TEXT, `richdocument_direct_editing` INTEGER, `richdocument_direct_templates` INTEGER, `richdocument_optional_mimetype_list` TEXT, `sharing_public_ask_for_optional_password` INTEGER, `richdocument_product_name` TEXT, `direct_editing_etag` TEXT, `user_status` INTEGER, `user_status_supports_emoji` INTEGER, `etag` TEXT, `files_locking_version` TEXT, `groupfolders` INTEGER, `drop_account` INTEGER)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "accountName",
+            "columnName": "account",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "versionMajor",
+            "columnName": "version_mayor",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "versionMinor",
+            "columnName": "version_minor",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "versionMicro",
+            "columnName": "version_micro",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "versionString",
+            "columnName": "version_string",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "versionEditor",
+            "columnName": "version_edition",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "extendedSupport",
+            "columnName": "extended_support",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "corePollinterval",
+            "columnName": "core_pollinterval",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingApiEnabled",
+            "columnName": "sharing_api_enabled",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicEnabled",
+            "columnName": "sharing_public_enabled",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicPasswordEnforced",
+            "columnName": "sharing_public_password_enforced",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicExpireDateEnabled",
+            "columnName": "sharing_public_expire_date_enabled",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicExpireDateDays",
+            "columnName": "sharing_public_expire_date_days",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicExpireDateEnforced",
+            "columnName": "sharing_public_expire_date_enforced",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicSendMail",
+            "columnName": "sharing_public_send_mail",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicUpload",
+            "columnName": "sharing_public_upload",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingUserSendMail",
+            "columnName": "sharing_user_send_mail",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingResharing",
+            "columnName": "sharing_resharing",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingFederationOutgoing",
+            "columnName": "sharing_federation_outgoing",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingFederationIncoming",
+            "columnName": "sharing_federation_incoming",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "filesBigfilechunking",
+            "columnName": "files_bigfilechunking",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "filesUndelete",
+            "columnName": "files_undelete",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "filesVersioning",
+            "columnName": "files_versioning",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "externalLinks",
+            "columnName": "external_links",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverName",
+            "columnName": "server_name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverColor",
+            "columnName": "server_color",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverTextColor",
+            "columnName": "server_text_color",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverElementColor",
+            "columnName": "server_element_color",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverSlogan",
+            "columnName": "server_slogan",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverLogo",
+            "columnName": "server_logo",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverBackgroundUrl",
+            "columnName": "background_url",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "endToEndEncryption",
+            "columnName": "end_to_end_encryption",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "endToEndEncryptionKeysExist",
+            "columnName": "end_to_end_encryption_keys_exist",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "activity",
+            "columnName": "activity",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverBackgroundDefault",
+            "columnName": "background_default",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "serverBackgroundPlain",
+            "columnName": "background_plain",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "richdocument",
+            "columnName": "richdocument",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "richdocumentMimetypeList",
+            "columnName": "richdocument_mimetype_list",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "richdocumentDirectEditing",
+            "columnName": "richdocument_direct_editing",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "richdocumentTemplates",
+            "columnName": "richdocument_direct_templates",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "richdocumentOptionalMimetypeList",
+            "columnName": "richdocument_optional_mimetype_list",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharingPublicAskForOptionalPassword",
+            "columnName": "sharing_public_ask_for_optional_password",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "richdocumentProductName",
+            "columnName": "richdocument_product_name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "directEditingEtag",
+            "columnName": "direct_editing_etag",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "userStatus",
+            "columnName": "user_status",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "userStatusSupportsEmoji",
+            "columnName": "user_status_supports_emoji",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "etag",
+            "columnName": "etag",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "filesLockingVersion",
+            "columnName": "files_locking_version",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "groupfolders",
+            "columnName": "groupfolders",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "dropAccount",
+            "columnName": "drop_account",
+            "affinity": "INTEGER",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "external_links",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `icon_url` TEXT, `language` TEXT, `type` INTEGER, `name` TEXT, `url` TEXT, `redirect` INTEGER)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "iconUrl",
+            "columnName": "icon_url",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "language",
+            "columnName": "language",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "type",
+            "columnName": "type",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "url",
+            "columnName": "url",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "redirect",
+            "columnName": "redirect",
+            "affinity": "INTEGER",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "filelist",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `filename` TEXT, `encrypted_filename` TEXT, `path` TEXT, `path_decrypted` TEXT, `parent` INTEGER, `created` INTEGER, `modified` INTEGER, `content_type` TEXT, `content_length` INTEGER, `media_path` TEXT, `file_owner` TEXT, `last_sync_date` INTEGER, `last_sync_date_for_data` INTEGER, `modified_at_last_sync_for_data` INTEGER, `etag` TEXT, `etag_on_server` TEXT, `share_by_link` INTEGER, `permissions` TEXT, `remote_id` TEXT, `local_id` INTEGER NOT NULL DEFAULT -1, `update_thumbnail` INTEGER, `is_downloading` INTEGER, `favorite` INTEGER, `is_encrypted` INTEGER, `etag_in_conflict` TEXT, `shared_via_users` INTEGER, `mount_type` INTEGER, `has_preview` INTEGER, `unread_comments_count` INTEGER, `owner_id` TEXT, `owner_display_name` TEXT, `note` TEXT, `sharees` TEXT, `rich_workspace` TEXT, `metadata_size` TEXT, `locked` INTEGER, `lock_type` INTEGER, `lock_owner` TEXT, `lock_owner_display_name` TEXT, `lock_owner_editor` TEXT, `lock_timestamp` INTEGER, `lock_timeout` INTEGER, `lock_token` TEXT, `tags` TEXT, `metadata_gps` TEXT)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "filename",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "encryptedName",
+            "columnName": "encrypted_filename",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "path",
+            "columnName": "path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "pathDecrypted",
+            "columnName": "path_decrypted",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "parent",
+            "columnName": "parent",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "creation",
+            "columnName": "created",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "modified",
+            "columnName": "modified",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "contentType",
+            "columnName": "content_type",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "contentLength",
+            "columnName": "content_length",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "storagePath",
+            "columnName": "media_path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "accountOwner",
+            "columnName": "file_owner",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lastSyncDate",
+            "columnName": "last_sync_date",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lastSyncDateForData",
+            "columnName": "last_sync_date_for_data",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "modifiedAtLastSyncForData",
+            "columnName": "modified_at_last_sync_for_data",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "etag",
+            "columnName": "etag",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "etagOnServer",
+            "columnName": "etag_on_server",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharedViaLink",
+            "columnName": "share_by_link",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "permissions",
+            "columnName": "permissions",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "remoteId",
+            "columnName": "remote_id",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "localId",
+            "columnName": "local_id",
+            "affinity": "INTEGER",
+            "notNull": true,
+            "defaultValue": "-1"
+          },
+          {
+            "fieldPath": "updateThumbnail",
+            "columnName": "update_thumbnail",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "isDownloading",
+            "columnName": "is_downloading",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "favorite",
+            "columnName": "favorite",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "isEncrypted",
+            "columnName": "is_encrypted",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "etagInConflict",
+            "columnName": "etag_in_conflict",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharedWithSharee",
+            "columnName": "shared_via_users",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "mountType",
+            "columnName": "mount_type",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "hasPreview",
+            "columnName": "has_preview",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "unreadCommentsCount",
+            "columnName": "unread_comments_count",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "ownerId",
+            "columnName": "owner_id",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "ownerDisplayName",
+            "columnName": "owner_display_name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "note",
+            "columnName": "note",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharees",
+            "columnName": "sharees",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "richWorkspace",
+            "columnName": "rich_workspace",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "metadataSize",
+            "columnName": "metadata_size",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "locked",
+            "columnName": "locked",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lockType",
+            "columnName": "lock_type",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lockOwner",
+            "columnName": "lock_owner",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lockOwnerDisplayName",
+            "columnName": "lock_owner_display_name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lockOwnerEditor",
+            "columnName": "lock_owner_editor",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lockTimestamp",
+            "columnName": "lock_timestamp",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lockTimeout",
+            "columnName": "lock_timeout",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lockToken",
+            "columnName": "lock_token",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "tags",
+            "columnName": "tags",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "metadataGPS",
+            "columnName": "metadata_gps",
+            "affinity": "TEXT",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "filesystem",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `local_path` TEXT, `is_folder` INTEGER, `found_at` INTEGER, `upload_triggered` INTEGER, `syncedfolder_id` TEXT, `crc32` TEXT, `modified_at` INTEGER)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "localPath",
+            "columnName": "local_path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "fileIsFolder",
+            "columnName": "is_folder",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "fileFoundRecently",
+            "columnName": "found_at",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "fileSentForUpload",
+            "columnName": "upload_triggered",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "syncedFolderId",
+            "columnName": "syncedfolder_id",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "crc32",
+            "columnName": "crc32",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "fileModified",
+            "columnName": "modified_at",
+            "affinity": "INTEGER",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "ocshares",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `file_source` INTEGER, `item_source` INTEGER, `share_type` INTEGER, `shate_with` TEXT, `path` TEXT, `permissions` INTEGER, `shared_date` INTEGER, `expiration_date` INTEGER, `token` TEXT, `shared_with_display_name` TEXT, `is_directory` INTEGER, `user_id` INTEGER, `id_remote_shared` INTEGER, `owner_share` TEXT, `is_password_protected` INTEGER, `note` TEXT, `hide_download` INTEGER, `share_link` TEXT, `share_label` TEXT)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "fileSource",
+            "columnName": "file_source",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "itemSource",
+            "columnName": "item_source",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "shareType",
+            "columnName": "share_type",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "shareWith",
+            "columnName": "shate_with",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "path",
+            "columnName": "path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "permissions",
+            "columnName": "permissions",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "sharedDate",
+            "columnName": "shared_date",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "expirationDate",
+            "columnName": "expiration_date",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "token",
+            "columnName": "token",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "shareWithDisplayName",
+            "columnName": "shared_with_display_name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "isDirectory",
+            "columnName": "is_directory",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "user_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "idRemoteShared",
+            "columnName": "id_remote_shared",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "accountOwner",
+            "columnName": "owner_share",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "isPasswordProtected",
+            "columnName": "is_password_protected",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "note",
+            "columnName": "note",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "hideDownload",
+            "columnName": "hide_download",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "shareLink",
+            "columnName": "share_link",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "shareLabel",
+            "columnName": "share_label",
+            "affinity": "TEXT",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "synced_folders",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `local_path` TEXT, `remote_path` TEXT, `wifi_only` INTEGER, `charging_only` INTEGER, `existing` INTEGER, `enabled` INTEGER, `enabled_timestamp_ms` INTEGER, `subfolder_by_date` INTEGER, `account` TEXT, `upload_option` INTEGER, `name_collision_policy` INTEGER, `type` INTEGER, `hidden` INTEGER, `sub_folder_rule` INTEGER)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "localPath",
+            "columnName": "local_path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "remotePath",
+            "columnName": "remote_path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "wifiOnly",
+            "columnName": "wifi_only",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "chargingOnly",
+            "columnName": "charging_only",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "existing",
+            "columnName": "existing",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "enabled",
+            "columnName": "enabled",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "enabledTimestampMs",
+            "columnName": "enabled_timestamp_ms",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "subfolderByDate",
+            "columnName": "subfolder_by_date",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "account",
+            "columnName": "account",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "uploadAction",
+            "columnName": "upload_option",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "nameCollisionPolicy",
+            "columnName": "name_collision_policy",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "type",
+            "columnName": "type",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "hidden",
+            "columnName": "hidden",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "subFolderRule",
+            "columnName": "sub_folder_rule",
+            "affinity": "INTEGER",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "list_of_uploads",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `local_path` TEXT, `remote_path` TEXT, `account_name` TEXT, `file_size` INTEGER, `status` INTEGER, `local_behaviour` INTEGER, `upload_time` INTEGER, `name_collision_policy` INTEGER, `is_create_remote_folder` INTEGER, `upload_end_timestamp` INTEGER, `last_result` INTEGER, `is_while_charging_only` INTEGER, `is_wifi_only` INTEGER, `created_by` INTEGER, `folder_unlock_token` TEXT)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "localPath",
+            "columnName": "local_path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "remotePath",
+            "columnName": "remote_path",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "accountName",
+            "columnName": "account_name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "fileSize",
+            "columnName": "file_size",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "status",
+            "columnName": "status",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "localBehaviour",
+            "columnName": "local_behaviour",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "uploadTime",
+            "columnName": "upload_time",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "nameCollisionPolicy",
+            "columnName": "name_collision_policy",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "isCreateRemoteFolder",
+            "columnName": "is_create_remote_folder",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "uploadEndTimestamp",
+            "columnName": "upload_end_timestamp",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lastResult",
+            "columnName": "last_result",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "isWhileChargingOnly",
+            "columnName": "is_while_charging_only",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "isWifiOnly",
+            "columnName": "is_wifi_only",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "createdBy",
+            "columnName": "created_by",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "folderUnlockToken",
+            "columnName": "folder_unlock_token",
+            "affinity": "TEXT",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "virtual",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `type` TEXT, `ocfile_id` INTEGER)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "type",
+            "columnName": "type",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "ocFileId",
+            "columnName": "ocfile_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "_id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7e73c045ac6d52d6c7c1626eefbc21e9')"
+    ]
+  }
+}

二進制
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileAllShareTypes.png


二進制
app/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileNone.png


+ 0 - 2
app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.kt

@@ -26,7 +26,6 @@ import androidx.test.espresso.Espresso
 import androidx.test.espresso.Espresso.onView
 import androidx.test.espresso.action.ViewActions.click
 import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
-import androidx.test.espresso.action.ViewActions.scrollTo
 import androidx.test.espresso.assertion.ViewAssertions.matches
 import androidx.test.espresso.contrib.DrawerActions
 import androidx.test.espresso.contrib.NavigationViewActions
@@ -241,7 +240,6 @@ class FileDisplayActivityIT : AbstractOnServerIT() {
 
         // browse into folder
         onView(withId(R.id.list_root))
-            .perform(scrollTo())
             .perform(closeSoftKeyboard())
             .perform(
                 RecyclerViewActions.actionOnItemAtPosition<OCFileListItemViewHolder>(

+ 3 - 3
app/src/androidTest/java/com/owncloud/android/UploadIT.java

@@ -460,7 +460,7 @@ public class UploadIT extends AbstractOnServerIT {
         testOnlyOnServer(NextcloudVersion.nextcloud_27);
 
         File file = getFile("gps.jpg");
-        String remotePath = "/gps.jpg";
+        String remotePath = "/metadata.jpg";
         OCUpload ocUpload = new OCUpload(file.getAbsolutePath(), remotePath, account.name);
 
         assertTrue(
@@ -497,7 +497,7 @@ public class UploadIT extends AbstractOnServerIT {
 
         OCFile ocFile = null;
         for (OCFile f : files) {
-            if (f.getFileName().equals("gps.jpg")) {
+            if (f.getFileName().equals("metadata.jpg")) {
                 ocFile = f;
                 break;
             }
@@ -505,8 +505,8 @@ public class UploadIT extends AbstractOnServerIT {
 
         assertNotNull(ocFile);
         assertEquals(remotePath, ocFile.getRemotePath());
-        assertEquals(new ImageDimension(300f, 200f), ocFile.getImageDimension());
         assertEquals(new GeoLocation(64, -46), ocFile.getGeoLocation());
+        assertEquals(new ImageDimension(300f, 200f), ocFile.getImageDimension());
     }
 
     private void verifyStoragePath(OCFile file) {

+ 2 - 0
app/src/androidTest/java/com/owncloud/android/datamodel/OCCapabilityIT.kt

@@ -37,6 +37,7 @@ class OCCapabilityIT : AbstractIT() {
         capability.etag = "123"
         capability.userStatus = CapabilityBooleanType.TRUE
         capability.userStatusSupportsEmoji = CapabilityBooleanType.TRUE
+        capability.dropAccount = CapabilityBooleanType.TRUE
 
         fileDataStorageManager.saveCapabilities(capability)
 
@@ -45,5 +46,6 @@ class OCCapabilityIT : AbstractIT() {
         assertEquals(capability.etag, newCapability.etag)
         assertEquals(capability.userStatus, newCapability.userStatus)
         assertEquals(capability.userStatusSupportsEmoji, newCapability.userStatusSupportsEmoji)
+        assertEquals(capability.dropAccount, newCapability.dropAccount)
     }
 }

+ 3 - 2
app/src/huawei/java/com/owncloud/android/ui/activity/HuaweiCommunityActivity.kt

@@ -20,14 +20,15 @@
  */
 package com.owncloud.android.ui.activity
 
+import android.os.Bundle
 import android.view.View
 
 /**
  * Activity providing information about ways to participate in the app's development.
  */
 class HuaweiCommunityActivity : CommunityActivity() {
-    override fun setupContent() {
-        super.setupContent()
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
         binding.communityReleaseCandidatePlaystore.visibility = View.GONE
     }
 }

+ 11 - 4
app/src/main/java/com/nextcloud/android/sso/InputStreamBinder.java

@@ -457,16 +457,23 @@ public class InputStreamBinder extends IInputStreamService.Stub {
     }
 
     private boolean isValid(NextcloudRequest request) {
-        String callingPackageName = context.getPackageManager().getNameForUid(Binder.getCallingUid());
+        String[] callingPackageNames = context.getPackageManager().getPackagesForUid(Binder.getCallingUid());
 
         SharedPreferences sharedPreferences = context.getSharedPreferences(SSO_SHARED_PREFERENCE,
                                                                            Context.MODE_PRIVATE);
-        String hash = sharedPreferences.getString(callingPackageName + DELIMITER + request.getAccountName(), "");
-        return validateToken(hash, request.getToken());
+        for (String callingPackageName : callingPackageNames) {
+            String hash = sharedPreferences.getString(callingPackageName + DELIMITER + request.getAccountName(), "");
+            if (hash.isEmpty())
+                continue;
+            if (validateToken(hash, request.getToken())) {
+                return true;
+            }
+        }
+        return false;
     }
 
     private boolean validateToken(String hash, String token) {
-        if (hash.isEmpty() || !hash.contains("$")) {
+        if (!hash.contains("$")) {
             throw new IllegalStateException(EXCEPTION_INVALID_TOKEN);
         }
 

+ 4 - 3
app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt

@@ -40,8 +40,8 @@ import com.nextcloud.client.database.entity.ShareEntity
 import com.nextcloud.client.database.entity.SyncedFolderEntity
 import com.nextcloud.client.database.entity.UploadEntity
 import com.nextcloud.client.database.entity.VirtualEntity
+import com.nextcloud.client.database.migrations.DatabaseMigrationUtil
 import com.nextcloud.client.database.migrations.Migration67to68
-import com.nextcloud.client.database.migrations.Migration70to71
 import com.nextcloud.client.database.migrations.RoomMigration
 import com.nextcloud.client.database.migrations.addLegacyMigrations
 import com.owncloud.android.db.ProviderMeta
@@ -64,8 +64,10 @@ import com.owncloud.android.db.ProviderMeta
         AutoMigration(from = 66, to = 67),
         AutoMigration(from = 68, to = 69),
         AutoMigration(from = 69, to = 70),
+        AutoMigration(from = 70, to = 71, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
         AutoMigration(from = 71, to = 72),
-        AutoMigration(from = 72, to = 73)
+        AutoMigration(from = 72, to = 73),
+        AutoMigration(from = 73, to = 74, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class)
     ],
     exportSchema = true
 )
@@ -95,7 +97,6 @@ abstract class NextcloudDatabase : RoomDatabase() {
                     .addLegacyMigrations(clock, context)
                     .addMigrations(RoomMigration())
                     .addMigrations(Migration67to68())
-                    .addMigrations(Migration70to71())
                     .fallbackToDestructiveMigration()
                     .build()
             }

+ 3 - 1
app/src/main/java/com/nextcloud/client/database/entity/CapabilityEntity.kt

@@ -129,5 +129,7 @@ data class CapabilityEntity(
     @ColumnInfo(name = ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION)
     val filesLockingVersion: String?,
     @ColumnInfo(name = ProviderTableMeta.CAPABILITIES_GROUPFOLDERS)
-    val groupfolders: Int?
+    val groupfolders: Int?,
+    @ColumnInfo(name = ProviderTableMeta.CAPABILITIES_DROP_ACCOUNT)
+    val dropAccount: Int?
 )

+ 11 - 0
app/src/main/java/com/nextcloud/client/database/migrations/DatabaseMigrationUtil.kt

@@ -22,6 +22,7 @@
 
 package com.nextcloud.client.database.migrations
 
+import androidx.room.migration.AutoMigrationSpec
 import androidx.sqlite.db.SupportSQLiteDatabase
 
 object DatabaseMigrationUtil {
@@ -102,4 +103,14 @@ object DatabaseMigrationUtil {
         database.execSQL("DROP TABLE $tableName")
         database.execSQL("ALTER TABLE $newTableTempName RENAME TO $tableName")
     }
+
+    /**
+     * Room AutoMigrationSpec to reset capabilities post migration.
+     */
+    class ResetCapabilitiesPostMigration : AutoMigrationSpec {
+        override fun onPostMigrate(db: SupportSQLiteDatabase) {
+            resetCapabilities(db)
+            super.onPostMigrate(db)
+        }
+    }
 }

+ 0 - 38
app/src/main/java/com/nextcloud/client/database/migrations/Migration70to71.kt

@@ -1,38 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- *  @author Álvaro Brey
- *  Copyright (C) 2023 Álvaro Brey
- *  Copyright (C) 2023 Nextcloud GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.nextcloud.client.database.migrations
-
-import androidx.room.migration.Migration
-import androidx.sqlite.db.SupportSQLiteDatabase
-
-/**
- * Migration from version 70 to 71.
- *
- * resets capabilities to show groupfolder
- */
-@Suppress("MagicNumber")
-class Migration70to71 : Migration(70, 71) {
-    override fun migrate(database: SupportSQLiteDatabase) {
-        DatabaseMigrationUtil.resetCapabilities(database)
-    }
-}

+ 2 - 2
app/src/main/java/com/nextcloud/client/di/ComponentsModule.java

@@ -81,7 +81,7 @@ import com.owncloud.android.ui.activity.ToolbarActivity;
 import com.owncloud.android.ui.activity.UploadFilesActivity;
 import com.owncloud.android.ui.activity.UploadListActivity;
 import com.owncloud.android.ui.activity.UserInfoActivity;
-import com.owncloud.android.ui.dialog.AccountRemovalConfirmationDialog;
+import com.owncloud.android.ui.dialog.AccountRemovalDialog;
 import com.owncloud.android.ui.dialog.ChooseRichDocumentsTemplateDialogFragment;
 import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@ -270,7 +270,7 @@ abstract class ComponentsModule {
     abstract ChooseTemplateDialogFragment chooseTemplateDialogFragment();
 
     @ContributesAndroidInjector
-    abstract AccountRemovalConfirmationDialog accountRemovalConfirmationDialog();
+    abstract AccountRemovalDialog accountRemovalDialog();
 
     @ContributesAndroidInjector
     abstract ChooseRichDocumentsTemplateDialogFragment chooseRichDocumentsTemplateDialogFragment();

+ 1 - 0
app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt

@@ -137,6 +137,7 @@ interface BackgroundJobManager {
     fun startAccountRemovalJob(accountName: String, remoteWipe: Boolean)
     fun startFilesUploadJob(user: User)
     fun getFileUploads(user: User): LiveData<List<JobInfo>>
+    fun cancelFilesUploadJob(user: User)
 
     fun startPdfGenerateAndUploadWork(user: User, uploadFolder: String, imagePaths: List<String>, pdfPath: String)
 

+ 4 - 0
app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt

@@ -461,6 +461,10 @@ internal class BackgroundJobManagerImpl(
         return workInfo.map { it -> it.map { fromWorkInfo(it) ?: JobInfo() } }
     }
 
+    override fun cancelFilesUploadJob(user: User) {
+        workManager.cancelJob(JOB_FILES_UPLOAD, user)
+    }
+
     override fun startPdfGenerateAndUploadWork(
         user: User,
         uploadFolder: String,

+ 21 - 6
app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt

@@ -76,6 +76,7 @@ class FilesUploadWorker(
     private val notificationManager: NotificationManager =
         context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
     private val fileUploaderDelegate = FileUploaderDelegate()
+    private var currentUploadFileOperation: UploadFileOperation? = null
 
     override fun doWork(): Result {
         val accountName = inputData.getString(ACCOUNT)
@@ -89,7 +90,7 @@ class FilesUploadWorker(
          * they will be present in the pages that follow.
          */
         var currentPage = uploadsStorageManager.getCurrentAndPendingUploadsForAccountPageAscById(-1, accountName)
-        while (currentPage.isNotEmpty()) {
+        while (currentPage.isNotEmpty() && !isStopped) {
             Log_OC.d(TAG, "Handling ${currentPage.size} uploads for account $accountName")
             val lastId = currentPage.last().uploadId
             handlePendingUploads(currentPage, accountName)
@@ -105,11 +106,16 @@ class FilesUploadWorker(
         val user = userAccountManager.getUser(accountName)
 
         for (upload in uploads) {
+            if (isStopped) {
+                break
+            }
             // create upload file operation
             if (user.isPresent) {
                 val uploadFileOperation = createUploadFileOperation(upload, user.get())
 
+                currentUploadFileOperation = uploadFileOperation
                 val result = upload(uploadFileOperation, user.get())
+                currentUploadFileOperation = null
 
                 fileUploaderDelegate.sendBroadcastUploadFinished(
                     uploadFileOperation,
@@ -172,13 +178,16 @@ class FilesUploadWorker(
             Log_OC.e(TAG, "Error uploading", e)
             uploadResult = RemoteOperationResult<Any?>(e)
         } finally {
-            uploadsStorageManager.updateDatabaseUploadResult(uploadResult, uploadFileOperation)
+            // only update db if operation finished and worker didn't get canceled
+            if (!(isStopped && uploadResult.isCancelled)) {
+                uploadsStorageManager.updateDatabaseUploadResult(uploadResult, uploadFileOperation)
 
-            // / notify result
-            notifyUploadResult(uploadFileOperation, uploadResult)
+                // / notify result
+                notifyUploadResult(uploadFileOperation, uploadResult)
 
-            // cancel notification
-            notificationManager.cancel(FOREGROUND_SERVICE_ID)
+                // cancel notification
+                notificationManager.cancel(FOREGROUND_SERVICE_ID)
+            }
         }
 
         return uploadResult
@@ -357,6 +366,12 @@ class FilesUploadWorker(
         lastPercent = percent
     }
 
+    override fun onStopped() {
+        super.onStopped()
+        currentUploadFileOperation?.cancel(null)
+        notificationManager.cancel(FOREGROUND_SERVICE_ID)
+    }
+
     companion object {
         val TAG: String = FilesUploadWorker::class.java.simpleName
         private const val FOREGROUND_SERVICE_ID: Int = 412

+ 32 - 0
app/src/main/java/com/nextcloud/utils/extensions/TextViewExtensions.kt

@@ -0,0 +1,32 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Alper Ozturk
+ * Copyright (C) 2023 Alper Ozturk
+ * Copyright (C) 2023 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.utils.extensions
+
+import android.text.method.LinkMovementMethod
+import android.widget.TextView
+import androidx.core.text.HtmlCompat
+
+@Suppress("NewLineAtEndOfFile")
+fun TextView.setHtmlContent(value: String) {
+    movementMethod = LinkMovementMethod.getInstance()
+    text = HtmlCompat.fromHtml(value, HtmlCompat.FROM_HTML_MODE_LEGACY)
+}

+ 2 - 0
app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -1947,6 +1947,7 @@ public class FileDataStorageManager {
         contentValues.put(ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION,
                           capability.getFilesLockingVersion());
         contentValues.put(ProviderTableMeta.CAPABILITIES_GROUPFOLDERS, capability.getGroupfolders().getValue());
+        contentValues.put(ProviderTableMeta.CAPABILITIES_DROP_ACCOUNT, capability.getDropAccount().getValue());
 
         return contentValues;
     }
@@ -2103,6 +2104,7 @@ public class FileDataStorageManager {
             capability.setFilesLockingVersion(
                 getString(cursor, ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION));
             capability.setGroupfolders(getBoolean(cursor, ProviderTableMeta.CAPABILITIES_GROUPFOLDERS));
+            capability.setDropAccount(getBoolean(cursor, ProviderTableMeta.CAPABILITIES_DROP_ACCOUNT));
         }
         return capability;
     }

+ 2 - 1
app/src/main/java/com/owncloud/android/db/ProviderMeta.java

@@ -35,7 +35,7 @@ import java.util.List;
  */
 public class ProviderMeta {
     public static final String DB_NAME = "filelist";
-    public static final int DB_VERSION = 73;
+    public static final int DB_VERSION = 74;
 
     private ProviderMeta() {
         // No instance
@@ -259,6 +259,7 @@ public class ProviderMeta {
         public static final String CAPABILITIES_USER_STATUS = "user_status";
         public static final String CAPABILITIES_USER_STATUS_SUPPORTS_EMOJI = "user_status_supports_emoji";
         public static final String CAPABILITIES_GROUPFOLDERS = "groupfolders";
+        public static final String CAPABILITIES_DROP_ACCOUNT = "drop_account";
 
         //Columns of Uploads table
         public static final String UPLOADS_LOCAL_PATH = "local_path";

+ 36 - 22
app/src/main/java/com/owncloud/android/files/services/FileUploader.java

@@ -89,6 +89,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 
 import javax.annotation.Nullable;
 import javax.inject.Inject;
@@ -1152,24 +1153,34 @@ public class FileUploader extends Service
          * @param remotePath  Remote target of the upload
          * @param resultCode  Setting result code will pause rather than cancel the job
          */
-        private void cancel(String accountName, String remotePath, @Nullable ResultCode resultCode) {
-            Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(accountName, remotePath);
-            UploadFileOperation upload = removeResult.first;
-            if (upload == null && mCurrentUpload != null && mCurrentAccount != null &&
-                mCurrentUpload.getRemotePath().startsWith(remotePath) && accountName.equals(mCurrentAccount.name)) {
+        public void cancel(String accountName, String remotePath, @Nullable ResultCode resultCode) {
+            // Cancel for Android version >= Android 11
+            if (useFilesUploadWorker(getApplicationContext())){
+                try{
+                    new FilesUploadHelper().cancelFileUpload(remotePath, accountManager.getUser(accountName).get());
+                }catch(NoSuchElementException e){
+                    Log_OC.e(TAG,"Error cancelling current upload because user does not exist!");
+                }
+            } else {
+                // Cancel for Android version <= Android 10
+                Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(accountName, remotePath);
+                UploadFileOperation upload = removeResult.first;
+                if (upload == null && mCurrentUpload != null && mCurrentAccount != null &&
+                    mCurrentUpload.getRemotePath().startsWith(remotePath) && accountName.equals(mCurrentAccount.name)) {
 
-                upload = mCurrentUpload;
-            }
+                    upload = mCurrentUpload;
+                }
 
-            if (upload != null) {
-                upload.cancel(resultCode);
-                // need to update now table in mUploadsStorageManager,
-                // since the operation will not get to be run by FileUploader#uploadFile
-                if (resultCode != null) {
-                    mUploadsStorageManager.updateDatabaseUploadResult(new RemoteOperationResult(resultCode), upload);
-                    notifyUploadResult(upload, new RemoteOperationResult(resultCode));
-                } else {
-                    mUploadsStorageManager.removeUpload(accountName, remotePath);
+                if (upload != null) {
+                    upload.cancel(resultCode);
+                    // need to update now table in mUploadsStorageManager,
+                    // since the operation will not get to be run by FileUploader#uploadFile
+                    if (resultCode != null) {
+                        mUploadsStorageManager.updateDatabaseUploadResult(new RemoteOperationResult(resultCode), upload);
+                        notifyUploadResult(upload, new RemoteOperationResult(resultCode));
+                    } else {
+                        mUploadsStorageManager.removeUpload(accountName, remotePath);
+                    }
                 }
             }
         }
@@ -1180,16 +1191,19 @@ public class FileUploader extends Service
          * @param user Nextcloud user
          */
         public void cancel(User user) {
-            if (mCurrentUpload != null && mCurrentUpload.getUser().nameEquals(user)) {
-                mCurrentUpload.cancel(ResultCode.CANCELLED);
-            }
-            cancelPendingUploads(user.getAccountName());
+            cancel(user.getAccountName());
         }
 
         public void cancel(String accountName) {
-            if (mCurrentUpload != null && mCurrentUpload.getUser().nameEquals(accountName)) {
-                mCurrentUpload.cancel(ResultCode.CANCELLED);
+            cancelPendingUploads(accountName);
+            if (useFilesUploadWorker(getApplicationContext())) {
+                new FilesUploadHelper().restartUploadJob(accountManager.getUser(accountName).get());
+            }else{
+                if (mCurrentUpload != null && mCurrentUpload.getUser().nameEquals(accountName)) {
+                    mCurrentUpload.cancel(ResultCode.CANCELLED);
+                }
             }
+
         }
 
         public void clearListeners() {

+ 0 - 128
app/src/main/java/com/owncloud/android/ui/activity/CommunityActivity.java

@@ -1,128 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- * @author Andy Scherzinger
- * @author Tobias Kaminsky
- * Copyright (C) 2016 Andy Scherzinger
- * Copyright (C) 2016 Nextcloud
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.owncloud.android.ui.activity;
-
-import android.os.Bundle;
-import android.text.Html;
-import android.text.method.LinkMovementMethod;
-import android.view.MenuItem;
-import android.widget.TextView;
-
-import com.google.android.material.button.MaterialButton;
-import com.owncloud.android.R;
-import com.owncloud.android.databinding.CommunityLayoutBinding;
-import com.owncloud.android.utils.DisplayUtils;
-
-/**
- * Activity providing information about ways to participate in the app's development.
- */
-public class CommunityActivity extends DrawerActivity {
-
-    protected CommunityLayoutBinding binding;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        binding = CommunityLayoutBinding.inflate(getLayoutInflater());
-        setContentView(binding.getRoot());
-
-        // setup toolbar
-        setupToolbar();
-
-        updateActionBarTitleAndHomeButtonByString(getString(R.string.drawer_community));
-
-        // setup drawer
-        setupDrawer(R.id.nav_community);
-
-        setupContent();
-    }
-
-    protected void setupContent() {
-        binding.communityReleaseCandidateText.setMovementMethod(LinkMovementMethod.getInstance());
-
-        TextView contributeForumView = binding.communityContributeForumText;
-        contributeForumView.setMovementMethod(LinkMovementMethod.getInstance());
-        contributeForumView.setText(Html.fromHtml(getString(R.string.community_contribute_forum_text) + " " +
-                                                      getString(R.string.community_contribute_forum_text_link,
-                                                                viewThemeUtils
-                                                                    .files
-                                                                    .primaryColorToHexString(this),
-                                                                getString(R.string.help_link),
-                                                                getString(R.string.community_contribute_forum_forum))));
-
-        TextView contributeTranslationView = binding.communityContributeTranslateText;
-        contributeTranslationView.setMovementMethod(LinkMovementMethod.getInstance());
-        contributeTranslationView.setText(Html.fromHtml(
-            getString(R.string.community_contribute_translate_link,
-                      viewThemeUtils.files.primaryColorToHexString(this),
-                      getString(R.string.translation_link),
-                      getString(R.string.community_contribute_translate_translate)) + " " +
-                getString(R.string.community_contribute_translate_text)));
-
-        TextView contributeGithubView = binding.communityContributeGithubText;
-        contributeGithubView.setMovementMethod(LinkMovementMethod.getInstance());
-        contributeGithubView.setText(Html.fromHtml(
-            getString(R.string.community_contribute_github_text,
-                      getString(R.string.community_contribute_github_text_link,
-                                viewThemeUtils.files.primaryColorToHexString(this),
-                                getString(R.string.contributing_link)))));
-
-        MaterialButton reportButton = binding.communityTestingReport;
-        viewThemeUtils.material.colorMaterialButtonPrimaryFilled(reportButton);
-        reportButton.setOnClickListener(v -> DisplayUtils.startLinkIntent(this, R.string.report_issue_empty_link));
-
-        binding.communityBetaFdroid.setOnClickListener(
-            l -> DisplayUtils.startLinkIntent(this, R.string.fdroid_beta_link));
-
-        binding.communityReleaseCandidateFdroid.setOnClickListener(
-            l -> DisplayUtils.startLinkIntent(this, R.string.fdroid_link));
-
-        binding.communityReleaseCandidatePlaystore.setOnClickListener(
-            l -> DisplayUtils.startLinkIntent(this, R.string.play_store_register_beta));
-
-        binding.communityBetaApk.setOnClickListener(
-            l -> DisplayUtils.startLinkIntent(this, R.string.beta_apk_link));
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        boolean retval = true;
-        if (item.getItemId() == android.R.id.home) {
-            if (isDrawerOpen()) {
-                closeDrawer();
-            } else {
-                openDrawer();
-            }
-        } else {
-            retval = super.onOptionsItemSelected(item);
-        }
-        return retval;
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        setDrawerMenuItemChecked(R.id.nav_community);
-    }
-}

+ 146 - 0
app/src/main/java/com/owncloud/android/ui/activity/CommunityActivity.kt

@@ -0,0 +1,146 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Andy Scherzinger
+ * @author Tobias Kaminsky
+ * Copyright (C) 2016 Andy Scherzinger
+ * Copyright (C) 2016 Nextcloud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.ui.activity
+
+import android.os.Bundle
+import android.text.method.LinkMovementMethod
+import android.view.MenuItem
+import com.nextcloud.utils.extensions.setHtmlContent
+import com.owncloud.android.R
+import com.owncloud.android.databinding.CommunityLayoutBinding
+import com.owncloud.android.utils.DisplayUtils
+
+/**
+ * Activity providing information about ways to participate in the app's development.
+ */
+open class CommunityActivity : DrawerActivity() {
+    lateinit var binding: CommunityLayoutBinding
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        binding = CommunityLayoutBinding.inflate(layoutInflater)
+        setContentView(binding.root)
+
+        setupToolbar()
+        updateActionBarTitleAndHomeButtonByString(getString(R.string.drawer_community))
+
+        setupDrawer(R.id.nav_community)
+        binding.communityReleaseCandidateText.movementMethod = LinkMovementMethod.getInstance()
+        setupContributeForumView()
+        setupContributeTranslationView()
+        setupContributeGithubView()
+        setupReportButton()
+        setOnClickListeners()
+    }
+
+    private fun setupContributeForumView() {
+        val htmlContent = getString(R.string.community_contribute_forum_text) + " " +
+            getString(
+                R.string.community_contribute_forum_text_link,
+                viewThemeUtils.files
+                    .primaryColorToHexString(this),
+                getString(R.string.help_link),
+                getString(R.string.community_contribute_forum_forum)
+            )
+        binding.communityContributeForumText.setHtmlContent(htmlContent)
+    }
+
+    private fun setupContributeTranslationView() {
+        val htmlContent = getString(
+            R.string.community_contribute_translate_link,
+            viewThemeUtils.files.primaryColorToHexString(this),
+            getString(R.string.translation_link),
+            getString(R.string.community_contribute_translate_translate)
+        ) + " " +
+            getString(R.string.community_contribute_translate_text)
+        binding.communityContributeTranslateText.setHtmlContent(htmlContent)
+    }
+
+    private fun setupContributeGithubView() {
+        val htmlContent = getString(
+            R.string.community_contribute_github_text,
+            getString(
+                R.string.community_contribute_github_text_link,
+                viewThemeUtils.files.primaryColorToHexString(this),
+                getString(R.string.contributing_link)
+            )
+        )
+        binding.communityContributeGithubText.setHtmlContent(htmlContent)
+    }
+
+    private fun setupReportButton() {
+        val reportButton = binding.communityTestingReport
+        viewThemeUtils.material.colorMaterialButtonPrimaryFilled(reportButton)
+        reportButton.setOnClickListener {
+            DisplayUtils.startLinkIntent(
+                this,
+                R.string.report_issue_empty_link
+            )
+        }
+    }
+
+    private fun setOnClickListeners() {
+        binding.communityBetaFdroid.setOnClickListener {
+            DisplayUtils.startLinkIntent(
+                this,
+                R.string.fdroid_beta_link
+            )
+        }
+        binding.communityReleaseCandidateFdroid.setOnClickListener {
+            DisplayUtils.startLinkIntent(
+                this,
+                R.string.fdroid_link
+            )
+        }
+        binding.communityReleaseCandidatePlaystore.setOnClickListener {
+            DisplayUtils.startLinkIntent(
+                this,
+                R.string.play_store_register_beta
+            )
+        }
+        binding.communityBetaApk.setOnClickListener {
+            DisplayUtils.startLinkIntent(
+                this,
+                R.string.beta_apk_link
+            )
+        }
+    }
+
+    override fun onOptionsItemSelected(item: MenuItem): Boolean {
+        var retval = true
+        if (item.itemId == android.R.id.home) {
+            if (isDrawerOpen) {
+                closeDrawer()
+            } else {
+                openDrawer()
+            }
+        } else {
+            retval = super.onOptionsItemSelected(item)
+        }
+        return retval
+    }
+
+    override fun onResume() {
+        super.onResume()
+        setDrawerMenuItemChecked(R.id.nav_community)
+    }
+}

+ 10 - 16
app/src/main/java/com/owncloud/android/ui/activity/CopyToClipboardActivity.java → app/src/main/java/com/owncloud/android/ui/activity/CopyToClipboardActivity.kt

@@ -18,26 +18,20 @@
  *   You should have received a copy of the GNU General Public License
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+package com.owncloud.android.ui.activity
 
-package com.owncloud.android.ui.activity;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-import com.owncloud.android.utils.ClipboardUtil;
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import com.owncloud.android.utils.ClipboardUtil
 
 /**
  * Activity copying the text of the received Intent into the system clipboard.
  */
-public class CopyToClipboardActivity extends Activity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        ClipboardUtil.copyToClipboard(this, getIntent().getCharSequenceExtra(Intent.EXTRA_TEXT).toString());
-
-        finish();
+class CopyToClipboardActivity : Activity() {
+    public override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        ClipboardUtil.copyToClipboard(this, intent.getCharSequenceExtra(Intent.EXTRA_TEXT).toString())
+        finish()
     }
 }

+ 1 - 1
app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java

@@ -527,7 +527,7 @@ public abstract class DrawerActivity extends ToolbarActivity
             menuItem.setChecked(false);
             final Optional<User> optionalUser = getUser();
             if (optionalUser.isPresent()) {
-                UserInfoActivity.openAccountRemovalConfirmationDialog(optionalUser.get(), getSupportFragmentManager());
+                UserInfoActivity.openAccountRemovalDialog(optionalUser.get(), getSupportFragmentManager());
             }
         } else if (itemId == R.id.nav_shared) {
             startSharedSearch(menuItem);

+ 18 - 29
app/src/main/java/com/owncloud/android/ui/activity/FilePickerActivity.java → app/src/main/java/com/owncloud/android/ui/activity/FilePickerActivity.kt

@@ -18,40 +18,29 @@
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
+package com.owncloud.android.ui.activity
 
-package com.owncloud.android.ui.activity;
-
-import android.os.Bundle;
-import android.view.View;
-
-import com.owncloud.android.R;
-import com.owncloud.android.ui.fragment.OCFileListFragment;
-
-import androidx.fragment.app.FragmentTransaction;
+import android.os.Bundle
+import com.owncloud.android.R
+import com.owncloud.android.ui.fragment.OCFileListFragment
 
 /**
  * File picker of remote files
  */
-public class FilePickerActivity extends FolderPickerActivity {
-
-    @Override
-    public void onClick(View v) {
-        super.onClick(v);
-    }
+class FilePickerActivity : FolderPickerActivity() {
 
-    @Override
-    protected void createFragments() {
-        OCFileListFragment listOfFiles = new OCFileListFragment();
-        Bundle args = new Bundle();
-        args.putBoolean(OCFileListFragment.ARG_ONLY_FOLDERS_CLICKABLE, true);
-        args.putBoolean(OCFileListFragment.ARG_HIDE_FAB, true);
-        args.putBoolean(OCFileListFragment.ARG_HIDE_ITEM_OPTIONS, true);
-        args.putBoolean(OCFileListFragment.ARG_SEARCH_ONLY_FOLDER, false);
-        args.putBoolean(OCFileListFragment.ARG_FILE_SELECTABLE, true);
-        args.putString(OCFileListFragment.ARG_MIMETYPE, getIntent().getStringExtra(OCFileListFragment.ARG_MIMETYPE));
-        listOfFiles.setArguments(args);
-        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-        transaction.add(R.id.fragment_container, listOfFiles, TAG_LIST_OF_FOLDERS);
-        transaction.commit();
+    override fun createFragments() {
+        val listOfFiles = OCFileListFragment()
+        val args = Bundle()
+        args.putBoolean(OCFileListFragment.ARG_ONLY_FOLDERS_CLICKABLE, true)
+        args.putBoolean(OCFileListFragment.ARG_HIDE_FAB, true)
+        args.putBoolean(OCFileListFragment.ARG_HIDE_ITEM_OPTIONS, true)
+        args.putBoolean(OCFileListFragment.ARG_SEARCH_ONLY_FOLDER, false)
+        args.putBoolean(OCFileListFragment.ARG_FILE_SELECTABLE, true)
+        args.putString(OCFileListFragment.ARG_MIMETYPE, intent.getStringExtra(OCFileListFragment.ARG_MIMETYPE))
+        listOfFiles.arguments = args
+        val transaction = supportFragmentManager.beginTransaction()
+        transaction.add(R.id.fragment_container, listOfFiles, TAG_LIST_OF_FOLDERS)
+        transaction.commit()
     }
 }

+ 2 - 1
app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt

@@ -616,6 +616,7 @@ open class FolderPickerActivity :
         const val MOVE_OR_COPY = "MOVE_OR_COPY"
         const val CHOOSE_LOCATION = "CHOOSE_LOCATION"
         private val TAG = FolderPickerActivity::class.java.simpleName
-        protected const val TAG_LIST_OF_FOLDERS = "LIST_OF_FOLDERS"
+
+        const val TAG_LIST_OF_FOLDERS = "LIST_OF_FOLDERS"
     }
 }

+ 4 - 5
app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -58,7 +58,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.ui.adapter.UserListAdapter;
 import com.owncloud.android.ui.adapter.UserListItem;
-import com.owncloud.android.ui.dialog.AccountRemovalConfirmationDialog;
+import com.owncloud.android.ui.dialog.AccountRemovalDialog;
 import com.owncloud.android.ui.events.AccountRemovedEvent;
 import com.owncloud.android.ui.helpers.FileOperationsHelper;
 
@@ -470,9 +470,8 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
         }
     }
 
-    public static void openAccountRemovalConfirmationDialog(User user, FragmentManager fragmentManager) {
-        AccountRemovalConfirmationDialog dialog =
-            AccountRemovalConfirmationDialog.newInstance(user);
+    public static void openAccountRemovalDialog(User user, FragmentManager fragmentManager) {
+        AccountRemovalDialog dialog = AccountRemovalDialog.newInstance(user);
         dialog.show(fragmentManager, "dialog");
     }
 
@@ -509,7 +508,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
                 if (itemId == R.id.action_open_account) {
                     accountClicked(user.hashCode());
                 } else if (itemId == R.id.action_delete_account) {
-                    openAccountRemovalConfirmationDialog(user, getSupportFragmentManager());
+                    openAccountRemovalDialog(user, getSupportFragmentManager());
                 } else {
                     openAccount(user);
                 }

+ 4 - 4
app/src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java

@@ -56,7 +56,7 @@ import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.users.GetUserInfoRemoteOperation;
-import com.owncloud.android.ui.dialog.AccountRemovalConfirmationDialog;
+import com.owncloud.android.ui.dialog.AccountRemovalDialog;
 import com.owncloud.android.ui.events.TokenPushEvent;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.PushUtils;
@@ -173,7 +173,7 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
         } else if (itemId == R.id.action_open_account) {
             accountClicked(user.hashCode());
         } else if (itemId == R.id.action_delete_account) {
-            openAccountRemovalConfirmationDialog(user, getSupportFragmentManager());
+            openAccountRemovalDialog(user, getSupportFragmentManager());
         } else {
             retval = super.onOptionsItemSelected(item);
         }
@@ -302,8 +302,8 @@ public class UserInfoActivity extends DrawerActivity implements Injectable {
         }
     }
 
-    public static void openAccountRemovalConfirmationDialog(User user, FragmentManager fragmentManager) {
-        AccountRemovalConfirmationDialog dialog = AccountRemovalConfirmationDialog.newInstance(user);
+    public static void openAccountRemovalDialog(User user, FragmentManager fragmentManager) {
+        AccountRemovalDialog dialog = AccountRemovalDialog.newInstance(user);
         dialog.show(fragmentManager, "dialog");
     }
 

+ 0 - 105
app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalConfirmationDialog.kt

@@ -1,105 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- * @author Tobias Kaminsky
- * Copyright (C) 2020 Tobias Kaminsky
- * Copyright (C) 2020 Nextcloud GmbH
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-package com.owncloud.android.ui.dialog
-
-import android.app.Dialog
-import android.content.DialogInterface
-import android.os.Build
-import android.os.Bundle
-import androidx.appcompat.app.AlertDialog
-import androidx.fragment.app.DialogFragment
-import com.google.android.material.button.MaterialButton
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.nextcloud.client.account.User
-import com.nextcloud.client.di.Injectable
-import com.nextcloud.client.jobs.BackgroundJobManager
-import com.owncloud.android.R
-import com.owncloud.android.utils.theme.ViewThemeUtils
-import javax.inject.Inject
-
-class AccountRemovalConfirmationDialog : DialogFragment(), Injectable {
-    @JvmField
-    @Inject
-    var backgroundJobManager: BackgroundJobManager? = null
-
-    @JvmField
-    @Inject
-    var viewThemeUtils: ViewThemeUtils? = null
-
-    private var user: User? = null
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        user = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
-            requireArguments().getParcelable(KEY_USER, User::class.java)
-        } else {
-            @Suppress("DEPRECATION")
-            requireArguments().getParcelable(KEY_USER)
-        }
-    }
-
-    override fun onStart() {
-        super.onStart()
-
-        val alertDialog = dialog as AlertDialog?
-
-        if (alertDialog != null) {
-            val positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE) as MaterialButton
-            viewThemeUtils?.material?.colorMaterialButtonPrimaryTonal(positiveButton)
-
-            val negativeButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE) as MaterialButton
-            viewThemeUtils?.material?.colorMaterialButtonPrimaryBorderless(negativeButton)
-        }
-    }
-
-    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
-        val builder = MaterialAlertDialogBuilder(requireActivity())
-            .setTitle(R.string.delete_account)
-            .setMessage(resources.getString(R.string.delete_account_warning, user!!.accountName))
-            .setIcon(R.drawable.ic_warning)
-            .setPositiveButton(R.string.common_ok) { _: DialogInterface?, _: Int ->
-                backgroundJobManager?.startAccountRemovalJob(
-                    user!!.accountName,
-                    false
-                )
-            }
-            .setNegativeButton(R.string.common_cancel, null)
-
-        viewThemeUtils?.dialog?.colorMaterialAlertDialogBackground(requireActivity(), builder)
-
-        return builder.create()
-    }
-
-    companion object {
-
-        private const val KEY_USER = "USER"
-
-        @JvmStatic
-        fun newInstance(user: User?): AccountRemovalConfirmationDialog {
-            val bundle = Bundle()
-            bundle.putParcelable(KEY_USER, user)
-            val dialog = AccountRemovalConfirmationDialog()
-            dialog.arguments = bundle
-            return dialog
-        }
-    }
-}

+ 194 - 0
app/src/main/java/com/owncloud/android/ui/dialog/AccountRemovalDialog.kt

@@ -0,0 +1,194 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author ZetaTom
+ * @author Tobias Kaminsky
+ * Copyright (C) 2023 ZetaTom
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.dialog
+
+import android.app.Dialog
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.view.View
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.nextcloud.client.account.User
+import com.nextcloud.client.account.UserAccountManager
+import com.nextcloud.client.di.Injectable
+import com.nextcloud.client.jobs.BackgroundJobManager
+import com.nextcloud.utils.extensions.getParcelableArgument
+import com.owncloud.android.R
+import com.owncloud.android.databinding.AccountRemovalDialogBinding
+import com.owncloud.android.datamodel.FileDataStorageManager
+import com.owncloud.android.utils.DisplayUtils
+import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener
+import com.owncloud.android.utils.theme.ViewThemeUtils
+import javax.inject.Inject
+
+class AccountRemovalDialog : DialogFragment(), AvatarGenerationListener, Injectable {
+
+    @Inject
+    lateinit var backgroundJobManager: BackgroundJobManager
+
+    @Inject
+    lateinit var viewThemeUtils: ViewThemeUtils
+
+    private var user: User? = null
+    private lateinit var alertDialog: AlertDialog
+    private var _binding: AccountRemovalDialogBinding? = null
+    private val binding get() = _binding!!
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        user = requireArguments().getParcelableArgument(KEY_USER, User::class.java)
+    }
+
+    override fun onStart() {
+        super.onStart()
+
+        // disable positive button and apply theming
+        alertDialog = dialog as AlertDialog
+        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
+
+        viewThemeUtils.platform.themeRadioButton(binding.radioLocalRemove)
+        viewThemeUtils.platform.themeRadioButton(binding.radioRequestDeletion)
+        viewThemeUtils.material.colorMaterialButtonPrimaryTonal(
+            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE) as MaterialButton
+        )
+        viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(
+            alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE) as MaterialButton
+        )
+
+        binding.userName.text = UserAccountManager.getDisplayName(user)
+        binding.account.text = user?.let { DisplayUtils.convertIdn(it.accountName, false) }
+    }
+
+    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+        _binding = AccountRemovalDialogBinding.inflate(layoutInflater)
+
+        // start avatar generation
+        setAvatar()
+
+        // hide second option when plug-in isn't installed
+        if (hasDropAccount()) {
+            binding.requestDeletion.visibility = View.VISIBLE
+        }
+
+        val builder =
+            MaterialAlertDialogBuilder(requireActivity())
+                .setTitle(R.string.delete_account)
+                .setView(binding.root)
+                .setNegativeButton(R.string.common_cancel) { _, _ -> }
+                .setPositiveButton(R.string.delete_account) { _, _ -> removeAccount() }
+
+        // allow selection by clicking on list element
+        binding.localRemove.setOnClickListener {
+            binding.radioLocalRemove.performClick()
+        }
+        binding.requestDeletion.setOnClickListener {
+            binding.radioRequestDeletion.performClick()
+        }
+
+        // set listeners for custom radio button list
+        binding.radioLocalRemove.setOnClickListener {
+            binding.radioRequestDeletion.isChecked = false
+            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).apply {
+                text = getText(R.string.delete_account)
+                isEnabled = true
+            }
+        }
+        binding.radioRequestDeletion.setOnClickListener {
+            binding.radioLocalRemove.isChecked = false
+            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).apply {
+                text = getString(R.string.request_account_deletion_button)
+                isEnabled = true
+            }
+        }
+
+        viewThemeUtils.dialog.colorMaterialAlertDialogBackground(requireActivity(), builder)
+
+        return builder.create()
+    }
+
+    /**
+     * Get value of `drop-account` capability.
+     */
+    private fun hasDropAccount(): Boolean {
+        val capability = FileDataStorageManager(user, context?.contentResolver).getCapability(user)
+        return capability.dropAccount.isTrue
+    }
+
+    /**
+     * Start removal of account. Depending on which option is checked, either a browser will open to request deletion,
+     * or the local account will be removed immediately.
+     */
+    private fun removeAccount() {
+        user?.let { user ->
+            if (binding.radioRequestDeletion.isChecked) {
+                DisplayUtils.startLinkIntent(activity, user.server.uri.toString() + DROP_ACCOUNT_URI)
+            } else {
+                backgroundJobManager.startAccountRemovalJob(user.accountName, false)
+            }
+        }
+    }
+
+    /**
+     * Start avatar generation.
+     */
+    private fun setAvatar() {
+        try {
+            val imageView = binding.userIcon
+            imageView.tag = user!!.accountName
+            DisplayUtils.setAvatar(
+                user!!,
+                this,
+                resources.getDimension(R.dimen.list_item_avatar_icon_radius),
+                resources,
+                imageView,
+                context
+            )
+        } catch (_: Exception) {
+        }
+    }
+
+    override fun avatarGenerated(avatarDrawable: Drawable?, callContext: Any?) {
+        avatarDrawable?.let {
+            binding.userIcon.setImageDrawable(it)
+        }
+    }
+
+    override fun shouldCallGeneratedCallback(tag: String?, callContext: Any?): Boolean {
+        return binding.userIcon.tag == tag
+    }
+
+    companion object {
+        private const val KEY_USER = "USER"
+        private const val DROP_ACCOUNT_URI = "/settings/user/drop_account"
+
+        @JvmStatic
+        fun newInstance(user: User) = AccountRemovalDialog().apply {
+            arguments = Bundle().apply {
+                putParcelable(KEY_USER, user)
+            }
+        }
+    }
+}

+ 101 - 13
app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java

@@ -7,7 +7,7 @@
  *
  * Copyright (C) 2018 Andy Scherzinger
  * Copyright (C) 2020 Chris Narkiewicz <hello@ezaquarii.com>
- * Copyright (C) 2020 TSI-mc
+ * Copyright (C) 2023 TSI-mc
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -25,11 +25,17 @@
 
 package com.owncloud.android.ui.fragment;
 
+import android.Manifest;
 import android.accounts.AccountManager;
+import android.app.Activity;
 import android.app.SearchManager;
 import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Bundle;
+import android.provider.ContactsContract;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
@@ -46,6 +52,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.NextcloudVersion;
@@ -61,6 +68,7 @@ import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper;
 import com.owncloud.android.ui.helpers.FileOperationsHelper;
 import com.owncloud.android.utils.ClipboardUtil;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.PermissionUtil;
 import com.owncloud.android.utils.theme.ViewThemeUtils;
 
 import java.util.ArrayList;
@@ -68,6 +76,8 @@ import java.util.List;
 
 import javax.inject.Inject;
 
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
@@ -81,7 +91,6 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
 
     private static final String ARG_FILE = "FILE";
     private static final String ARG_USER = "USER";
-    public static final int PERMISSION_EDITING_ALLOWED = 17;
 
     private OCFile file;
     private User user;
@@ -118,8 +127,8 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         } else {
             Bundle arguments = getArguments();
             if (arguments != null) {
-                file = getArguments().getParcelable(ARG_FILE);
-                user = getArguments().getParcelable(ARG_USER);
+                file = arguments.getParcelable(ARG_FILE);
+                user = arguments.getParcelable(ARG_USER);
             }
         }
 
@@ -149,12 +158,11 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         binding = FileDetailsSharingFragmentBinding.inflate(inflater, container, false);
-        View view = binding.getRoot();
 
         fileOperationsHelper = fileActivity.getFileOperationsHelper();
         fileDataStorageManager = fileActivity.getStorageManager();
 
-        AccountManager accountManager = AccountManager.get(getContext());
+        AccountManager accountManager = AccountManager.get(requireContext());
         String userId = accountManager.getUserData(user.toPlatformAccount(),
                                                    com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
 
@@ -165,11 +173,14 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
                                                             user,
                                                             viewThemeUtils,
                                                             file.isEncrypted()));
-        binding.sharesList.setLayoutManager(new LinearLayoutManager(getContext()));
+
+        binding.sharesList.setLayoutManager(new LinearLayoutManager(requireContext()));
+
+        binding.pickContactEmailBtn.setOnClickListener(v -> checkContactPermission());
 
         setupView();
 
-        return view;
+        return binding.getRoot();
     }
 
     @Override
@@ -208,6 +219,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
             } else {
                 binding.searchView.setQueryHint(getResources().getString(R.string.reshare_not_allowed));
                 binding.searchView.setInputType(InputType.TYPE_NULL);
+                binding.pickContactEmailBtn.setVisibility(View.GONE);
                 disableSearchView(binding.searchView);
             }
         }
@@ -216,9 +228,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
     private void disableSearchView(View view) {
         view.setEnabled(false);
 
-        if (view instanceof ViewGroup) {
-            ViewGroup viewGroup = (ViewGroup) view;
-
+        if (view instanceof ViewGroup viewGroup) {
             for (int i = 0; i < viewGroup.getChildCount(); i++) {
                 disableSearchView(viewGroup.getChildAt(i));
             }
@@ -302,7 +312,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
             if (TextUtils.isEmpty(share.getShareLink())) {
                 fileOperationsHelper.getFileWithLink(file, viewThemeUtils);
             } else {
-                ClipboardUtil.copyToClipboard(getActivity(), share.getShareLink());
+                ClipboardUtil.copyToClipboard(requireActivity(), share.getShareLink());
             }
         }
     }
@@ -460,6 +470,52 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         adapter.addShares(publicShares);
     }
 
+    private void checkContactPermission() {
+        if (PermissionUtil.checkSelfPermission(requireActivity(), Manifest.permission.READ_CONTACTS)) {
+            pickContactEmail();
+        } else {
+            requestContactPermissionLauncher.launch(Manifest.permission.READ_CONTACTS);
+        }
+    }
+
+    private void pickContactEmail() {
+        Intent intent = new Intent(Intent.ACTION_PICK);
+        intent.setDataAndType(ContactsContract.Contacts.CONTENT_URI, ContactsContract.CommonDataKinds.Email.CONTENT_TYPE);
+        onContactSelectionResultLauncher.launch(intent);
+    }
+
+    private void handleContactResult(@NonNull Uri contactUri) {
+        // Define the projection to get all email addresses.
+        String[] projection = {ContactsContract.CommonDataKinds.Email.ADDRESS};
+
+        Cursor cursor = fileActivity.getContentResolver().query(contactUri, projection, null, null, null);
+
+        if (cursor != null) {
+            if (cursor.moveToFirst()) {
+                // The contact has only one email address, use it.
+                int columnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
+                if (columnIndex != -1) {
+                    // Use the email address as needed.
+                    // email variable contains the selected contact's email address.
+                    String email = cursor.getString(columnIndex);
+                    binding.searchView.post(() -> {
+                        binding.searchView.setQuery(email, false);
+                        binding.searchView.requestFocus();
+                    });
+                } else {
+                    DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+                    Log_OC.e(FileDetailSharingFragment.class.getSimpleName(), "Failed to pick email address.");
+                }
+            } else {
+                DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+                Log_OC.e(FileDetailSharingFragment.class.getSimpleName(), "Failed to pick email address as no Email found.");
+            }
+            cursor.close();
+        } else {
+            DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+            Log_OC.e(FileDetailSharingFragment.class.getSimpleName(), "Failed to pick email address as Cursor is null.");
+        }
+    }
 
     private boolean containsNoNewPublicShare(List<OCShare> shares) {
         for (OCShare share : shares) {
@@ -496,7 +552,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
 
     @VisibleForTesting
     public void search(String query) {
-        SearchView searchView = getView().findViewById(R.id.searchView);
+        SearchView searchView = requireView().findViewById(R.id.searchView);
         searchView.setQuery(query, true);
     }
 
@@ -546,6 +602,38 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         fileOperationsHelper.setPermissionsToShare(share, permission);
     }
 
+    //launcher for contact permission
+    private final ActivityResultLauncher<String> requestContactPermissionLauncher =
+        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
+            if (isGranted) {
+                pickContactEmail();
+            } else {
+                DisplayUtils.showSnackMessage(binding.getRoot(), R.string.contact_no_permission);
+            }
+        });
+
+    //launcher to handle contact selection
+    private final ActivityResultLauncher<Intent> onContactSelectionResultLauncher =
+        registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
+                                  result -> {
+                                      if (result.getResultCode() == Activity.RESULT_OK) {
+                                          Intent intent = result.getData();
+                                          if (intent == null) {
+                                              DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+                                              return;
+                                          }
+
+                                          Uri contactUri = intent.getData();
+                                          if (contactUri == null) {
+                                              DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+                                              return;
+                                          }
+
+                                          handleContactResult(contactUri);
+
+                                      }
+                                  });
+
     public interface OnEditShareListener {
         void editExistingShare(OCShare share, int screenTypePermission, boolean isReshareShown,
                                boolean isExpiryDateShown);

+ 1 - 1
app/src/main/java/com/owncloud/android/ui/fragment/FileDetailsSharingProcessFragment.kt

@@ -545,7 +545,7 @@ class FileDetailsSharingProcessFragment :
         )
         // copy the share link if available
         if (!TextUtils.isEmpty(share?.shareLink)) {
-            ClipboardUtil.copyToClipboard(activity, share?.shareLink)
+            ClipboardUtil.copyToClipboard(requireActivity(), share?.shareLink)
         }
     }
 

+ 28 - 33
app/src/main/java/com/owncloud/android/utils/ClipboardUtil.java → app/src/main/java/com/owncloud/android/utils/ClipboardUtil.kt

@@ -17,51 +17,46 @@
  * You should have received a copy of the GNU Affero General Public
  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+package com.owncloud.android.utils
 
-package com.owncloud.android.utils;
-
-import android.app.Activity;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.text.TextUtils;
-import android.widget.Toast;
-
-import com.owncloud.android.R;
-import com.owncloud.android.lib.common.utils.Log_OC;
+import android.app.Activity
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.text.TextUtils
+import android.widget.Toast
+import com.owncloud.android.R
+import com.owncloud.android.lib.common.utils.Log_OC
 
 /**
  * Helper implementation to copy a string into the system clipboard.
  */
-public final class ClipboardUtil {
-    private static final String TAG = ClipboardUtil.class.getName();
-
-    private ClipboardUtil() {
-    }
+object ClipboardUtil {
+    private val TAG = ClipboardUtil::class.java.name
 
-    public static void copyToClipboard(Activity activity, String text) {
-        copyToClipboard(activity, text, true);
-    }
-
-    public static void copyToClipboard(Activity activity, String text, boolean showToast) {
+    @JvmStatic
+    @JvmOverloads
+    @Suppress("TooGenericExceptionCaught")
+    fun copyToClipboard(activity: Activity, text: String?, showToast: Boolean = true) {
         if (!TextUtils.isEmpty(text)) {
             try {
-                ClipData clip = ClipData.newPlainText(
-                        activity.getString(
-                                R.string.clipboard_label, activity.getString(R.string.app_name)),
-                        text
-                );
-                ((ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(clip);
-
+                val clip = ClipData.newPlainText(
+                    activity.getString(
+                        R.string.clipboard_label,
+                        activity.getString(R.string.app_name)
+                    ),
+                    text
+                )
+                (activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).setPrimaryClip(clip)
                 if (showToast) {
-                    Toast.makeText(activity, R.string.clipboard_text_copied, Toast.LENGTH_SHORT).show();
+                    Toast.makeText(activity, R.string.clipboard_text_copied, Toast.LENGTH_SHORT).show()
                 }
-            } catch (Exception e) {
-                Toast.makeText(activity, R.string.clipboard_unexpected_error, Toast.LENGTH_SHORT).show();
-                Log_OC.e(TAG, "Exception caught while copying to clipboard", e);
+            } catch (e: Exception) {
+                Toast.makeText(activity, R.string.clipboard_unexpected_error, Toast.LENGTH_SHORT).show()
+                Log_OC.e(TAG, "Exception caught while copying to clipboard", e)
             }
         } else {
-            Toast.makeText(activity, R.string.clipboard_no_text_to_copy, Toast.LENGTH_SHORT).show();
+            Toast.makeText(activity, R.string.clipboard_no_text_to_copy, Toast.LENGTH_SHORT).show()
         }
     }
 }

+ 13 - 0
app/src/main/java/com/owncloud/android/utils/FilesUploadHelper.kt

@@ -70,6 +70,19 @@ class FilesUploadHelper {
         backgroundJobManager.startFilesUploadJob(user)
     }
 
+    fun cancelFileUpload(remotePath: String, user: User) {
+        // need to update now table in mUploadsStorageManager,
+        // since the operation will not get to be run by FileUploader#uploadFile
+        uploadsStorageManager.removeUpload(user.accountName, remotePath)
+
+        restartUploadJob(user)
+    }
+
+    fun restartUploadJob(user: User) {
+        backgroundJobManager.cancelFilesUploadJob(user)
+        backgroundJobManager.startFilesUploadJob(user)
+    }
+
     fun uploadUpdatedFile(
         user: User,
         existingFiles: Array<OCFile>,

+ 26 - 0
app/src/main/res/drawable/ic_contact_book.xml

@@ -0,0 +1,26 @@
+<!--
+    @author Google LLC
+    Copyright (C) 2023 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="#666666"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,0L4,0v2h16L20,0zM4,24h16v-2L4,22v2zM20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM12,6.75c1.24,0 2.25,1.01 2.25,2.25s-1.01,2.25 -2.25,2.25S9.75,10.24 9.75,9 10.76,6.75 12,6.75zM17,17L7,17v-1.5c0,-1.67 3.33,-2.5 5,-2.5s5,0.83 5,2.5L17,17z" />
+</vector>

+ 154 - 0
app/src/main/res/layout/account_removal_dialog.xml

@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Nextcloud Android client application
+
+ @author ZetaTom
+ Copyright (C) 2023 ZetaTom
+ Copyright (C) 2023 Nextcloud GmbH
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:padding="12dp"
+        android:paddingHorizontal="24dp">
+
+        <ImageView
+            android:id="@+id/user_icon"
+            android:layout_width="@dimen/user_icon_size"
+            android:layout_height="@dimen/user_icon_size"
+            android:layout_margin="6dp"
+            android:contentDescription="@string/avatar"
+            android:src="@drawable/ic_user" />
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dp"
+            android:orientation="vertical">
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/user_name"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ellipsize="middle"
+                android:textAppearance="@style/TextAppearance.Material3.LabelLarge"
+                tools:text="Alice Muster" />
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:id="@+id/account"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ellipsize="middle"
+                tools:text="alice@cloud.nextcloud.com" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <com.google.android.material.divider.MaterialDivider
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <LinearLayout
+        android:id="@+id/local_remove"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="?attr/selectableItemBackground"
+        android:clickable="true"
+        android:focusable="true"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:paddingHorizontal="24dp"
+        android:paddingVertical="8dp">
+
+        <androidx.appcompat.widget.AppCompatRadioButton
+            android:id="@+id/radio_local_remove"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            tools:checked="true" />
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/remove_local_account"
+                android:textAppearance="@style/TextAppearance.Material3.LabelLarge" />
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/remove_local_account_details" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/request_deletion"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="?attr/selectableItemBackground"
+        android:clickable="true"
+        android:focusable="true"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:paddingHorizontal="24dp"
+        android:paddingVertical="8dp"
+        android:visibility="gone"
+        tools:visibility="visible">
+
+        <androidx.appcompat.widget.AppCompatRadioButton
+            android:id="@+id/radio_request_deletion"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/request_account_deletion"
+                android:textAppearance="@style/TextAppearance.Material3.LabelLarge" />
+
+            <androidx.appcompat.widget.AppCompatTextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/request_account_deletion_details" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <com.google.android.material.divider.MaterialDivider
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>

+ 36 - 21
app/src/main/res/layout/file_details_sharing_fragment.xml

@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?><!--
   Nextcloud Android client application
 
+  @author TSI-mc
+
   Copyright (C) 2018 Andy Scherzinger
+  Copyright (C) 2023 TSI-mc
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -29,83 +32,94 @@
         android:id="@+id/search_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:orientation="horizontal"
         android:paddingStart="@dimen/standard_padding"
         android:paddingEnd="@dimen/zero">
 
         <ImageView
             android:id="@+id/searchViewIcon"
-            android:layout_height="@dimen/user_icon_size"
             android:layout_width="@dimen/user_icon_size"
-            android:padding="@dimen/standard_half_padding"
-            android:contentDescription="@string/avatar"
+            android:layout_height="@dimen/user_icon_size"
             android:layout_gravity="center_vertical"
+            android:contentDescription="@string/avatar"
+            android:padding="@dimen/standard_half_padding"
             android:src="@drawable/ic_search_grey" />
 
         <androidx.appcompat.widget.SearchView
             android:id="@+id/searchView"
             style="@style/ownCloud.SearchView"
-            android:layout_width="match_parent"
+            android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/zero"
             android:layout_marginEnd="@dimen/standard_quarter_margin"
+            android:layout_weight="1"
             android:hint="@string/share_search"
             app:searchIcon="@null" />
 
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/pick_contact_email_btn"
+            android:layout_width="@dimen/minimum_size_for_touchable_area"
+            android:layout_height="@dimen/minimum_size_for_touchable_area"
+            android:layout_gravity="center_vertical"
+            android:padding="12dp"
+            android:layout_marginEnd="@dimen/standard_quarter_margin"
+            android:src="@drawable/ic_contact_book" />
+
     </LinearLayout>
 
     <LinearLayout
         android:id="@+id/shared_with_you_container"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/standard_half_margin"
-        android:layout_width="match_parent"
         android:orientation="horizontal"
         android:paddingLeft="@dimen/standard_padding"
-        android:paddingRight="@dimen/standard_padding"
-        android:paddingTop="@dimen/standard_padding">
+        android:paddingTop="@dimen/standard_padding"
+        android:paddingRight="@dimen/standard_padding">
 
         <ImageView
-            android:contentDescription="@string/avatar"
             android:id="@+id/shared_with_you_avatar"
-            android:layout_height="@dimen/user_icon_size"
             android:layout_width="@dimen/user_icon_size"
+            android:layout_height="@dimen/user_icon_size"
+            android:contentDescription="@string/avatar"
             android:src="@drawable/ic_user" />
 
         <LinearLayout
-            android:layout_height="wrap_content"
             android:layout_width="match_parent"
+            android:layout_height="wrap_content"
             android:orientation="vertical"
             android:paddingLeft="@dimen/standard_padding"
-            android:paddingRight="@dimen/standard_padding"
-            android:paddingTop="@dimen/standard_half_padding">
+            android:paddingTop="@dimen/standard_half_padding"
+            android:paddingRight="@dimen/standard_padding">
 
             <TextView
                 android:id="@+id/shared_with_you_username"
-                android:layout_height="wrap_content"
                 android:layout_width="match_parent"
+                android:layout_height="wrap_content"
                 android:text="@string/shared_with_you_by"
                 android:textSize="@dimen/two_line_primary_text_size" />
 
             <LinearLayout
                 android:id="@+id/shared_with_you_note_container"
-                android:layout_height="match_parent"
                 android:layout_width="match_parent"
+                android:layout_height="match_parent"
                 android:orientation="horizontal"
                 android:paddingTop="@dimen/standard_half_padding"
                 tools:ignore="UseCompoundDrawables">
 
                 <ImageView
-                    android:contentDescription="@string/note_icon_hint"
-                    android:layout_height="16dp"
                     android:layout_width="16dp"
+                    android:layout_height="16dp"
+                    android:contentDescription="@string/note_icon_hint"
                     android:src="@drawable/file_text" />
 
                 <TextView
                     android:id="@+id/shared_with_you_note"
+                    android:layout_width="0dp"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
-                    android:layout_width="0dp"
-                    android:paddingEnd="@dimen/standard_half_padding"
                     android:paddingStart="@dimen/standard_half_padding"
+                    android:paddingEnd="@dimen/standard_half_padding"
                     android:textSize="16sp" />
             </LinearLayout>
 
@@ -113,10 +127,11 @@
     </LinearLayout>
 
     <androidx.recyclerview.widget.RecyclerView
-        android:divider="@drawable/divider"
-        android:dividerHeight="1dp"
         android:id="@+id/sharesList"
+        android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_width="match_parent" />
+        android:divider="@drawable/divider"
+        android:dividerHeight="1dp"
+        tools:listitem="@layout/file_details_share_link_share_item" />
 
 </LinearLayout>

+ 2 - 1
app/src/main/res/values-ar/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">إذا قمت باختيار كلا الاصدارين, الملف المحلي سيحتوي على رقم ملحق باسم الملف.</string>
     <string name="conflict_server_file">ملف على الخادم</string>
     <string name="contact_backup_title">نسخ احتياطي لجهات الاتصال</string>
+    <string name="contact_no_permission">إذن الاتصال بالجهة لازم.</string>
     <string name="contactlist_item_icon">أيقونة المستخدمين المتواجدين في قائمة جهات الإتصال</string>
     <string name="contactlist_no_permission">لا يوجد إذن، لم يتم استيراد أي شيء</string>
     <string name="contacts">جهات الاتصال</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">المزيد من تطبيقات نكست كلاود</string>
     <string name="ecosystem_apps_notes">ملاحظات Notes نيكست كلاود</string>
     <string name="ecosystem_apps_talk">تطبيق \"المحادثة\" talk من نكست كلاود</string>
+    <string name="email_pick_failed">تعذّر التقاط عنوان الإيميل.</string>
     <string name="encrypted">عيّنه كَمشفر</string>
     <string name="end_to_end_encryption_confirm_button">تنصيب التشفير</string>
     <string name="end_to_end_encryption_decrypting">جارِ فك التشفير …</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">حذف </string>
     <string name="file_detail_activity_error">خطأ في استرداد النشاطات للملف</string>
     <string name="file_details_no_content">حدث خطأ في تحميل التفاصيل</string>
-    <string name="file_downloader_notification_title_prefix">تنزيل \u0020</string>
     <string name="file_icon">الملف</string>
     <string name="file_keep">حفظ</string>
     <string name="file_list_empty">قم برفع بعض المحتوى أو زامن مع أجهزتك</string>

+ 6 - 1
app/src/main/res/values-b+en+001/strings.xml

@@ -18,6 +18,7 @@
     <string name="actionbar_copy">Copy</string>
     <string name="actionbar_mkdir">New folder</string>
     <string name="actionbar_move">Move</string>
+    <string name="actionbar_move_or_copy">Move or Copy</string>
     <string name="actionbar_open_with">Open with</string>
     <string name="actionbar_search">Search</string>
     <string name="actionbar_see_details">Details</string>
@@ -159,6 +160,7 @@
     <string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string>
     <string name="conflict_server_file">Server file</string>
     <string name="contact_backup_title">Contacts backup</string>
+    <string name="contact_no_permission">Contact permission is required.</string>
     <string name="contactlist_item_icon">User icon for contact list</string>
     <string name="contactlist_no_permission">No permission given, nothing imported.</string>
     <string name="contacts">Contacts</string>
@@ -257,6 +259,7 @@
     <string name="ecosystem_apps_more">More Nextcloud Apps</string>
     <string name="ecosystem_apps_notes">Nextcloud Notes</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">Failed to pick email address.</string>
     <string name="encrypted">Set as encrypted</string>
     <string name="end_to_end_encryption_confirm_button">Set up encryption</string>
     <string name="end_to_end_encryption_decrypting">Decrypting…</string>
@@ -287,7 +290,7 @@
     <string name="error_report_issue_text">Report issue to tracker? (requires a GitHub account)</string>
     <string name="error_retrieving_file">Error retrieving file</string>
     <string name="error_retrieving_templates">Error retrieving templates</string>
-    <string name="error_showing_encryption_dialog">Error showing encryption setup dialog!</string>
+    <string name="error_showing_encryption_dialog">Error showing encryption setup dialogue!</string>
     <string name="error_starting_direct_camera_upload">Error starting camera</string>
     <string name="error_starting_doc_scan">Error starting document scan</string>
     <string name="etm_accounts">Accounts</string>
@@ -944,7 +947,9 @@
     <string name="wait_a_moment">Wait a moment…</string>
     <string name="wait_checking_credentials">Checking stored credentials</string>
     <string name="wait_for_tmp_copy_from_private_storage">Copying file from private storage</string>
+    <string name="webview_version_check_alert_dialog_message">Please update the Android System WebView app for a login</string>
     <string name="webview_version_check_alert_dialog_positive_button_title">Update</string>
+    <string name="webview_version_check_alert_dialog_title">Update Android System WebView</string>
     <string name="what_s_new_image">What\'s new image</string>
     <string name="whats_new_skip">Skip</string>
     <string name="whats_new_title">New in %1$s</string>

+ 2 - 1
app/src/main/res/values-cs-rCZ/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Pokud zvolíte obě verze, k názvu místního souboru bude připojeno číslo.</string>
     <string name="conflict_server_file">Soubor na serveru</string>
     <string name="contact_backup_title">Záloha kontaktů</string>
+    <string name="contact_no_permission">Je vyžadováno oprávnění pro přístup ke kontaktům.</string>
     <string name="contactlist_item_icon">Ikona uživatele v seznamu kontaktů</string>
     <string name="contactlist_no_permission">Nejsou udělena oprávnění, proto nebylo nic naimportováno.</string>
     <string name="contacts">Kontakty</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Další Nextcloud aplikace</string>
     <string name="ecosystem_apps_notes">Nextcloud poznámky</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">Nepodařilo se vybrat e-mailovou adresu.</string>
     <string name="encrypted">Nastavit jako šifrované</string>
     <string name="end_to_end_encryption_confirm_button">Nastavit šifrování</string>
     <string name="end_to_end_encryption_decrypting">Rozšifrovávání…</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">Smazat</string>
     <string name="file_detail_activity_error">Při načítání aktivit u souboru došlo k chybě</string>
     <string name="file_details_no_content">Nepodařilo se načíst podrobnosti.</string>
-    <string name="file_downloader_notification_title_prefix">Stahování \u0020</string>
     <string name="file_icon">Soubor</string>
     <string name="file_keep">Ponechat</string>
     <string name="file_list_empty">Nahrajte nějaký obsah, nebo synchronizujte s vašimi zařízeními.</string>

+ 0 - 1
app/src/main/res/values-da/strings.xml

@@ -325,7 +325,6 @@
     <string name="file_delete">Slet</string>
     <string name="file_detail_activity_error">Fejl ved indlæsning af aktiviteter for fil</string>
     <string name="file_details_no_content">Fejl ved indlæsning af detaljer</string>
-    <string name="file_downloader_notification_title_prefix">Downloader \u0020</string>
     <string name="file_icon">Fil</string>
     <string name="file_keep">Behold</string>
     <string name="file_list_empty">Upload indhold eller synkronisér med dine enheder.</string>

+ 2 - 1
app/src/main/res/values-de/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Falls beide Versionen gewählt werden, wird bei der lokalen Datei eine Zahl am Ende des Dateinamens hinzugefügt.</string>
     <string name="conflict_server_file">Server-Datei</string>
     <string name="contact_backup_title">Kontakte-Backup</string>
+    <string name="contact_no_permission">Eine Kontakterlaubnis ist erforderlich.</string>
     <string name="contactlist_item_icon">Nutzericon für Kontaktliste</string>
     <string name="contactlist_no_permission">Keine Berechtigung vergeben, es wurde nichts importiert.</string>
     <string name="contacts">Kontakte</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Weitere Nextcloud-Apps</string>
     <string name="ecosystem_apps_notes">Nextcloud Notizen</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">E-Mail-Adresse konnte nicht ausgewählt werden.</string>
     <string name="encrypted">Als verschlüsselt festlegen</string>
     <string name="end_to_end_encryption_confirm_button">Verschlüsselung einrichten</string>
     <string name="end_to_end_encryption_decrypting">Entschlüssele…</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">Löschen</string>
     <string name="file_detail_activity_error">Fehler beim Abrufen der Aktivitäten für die Datei</string>
     <string name="file_details_no_content">Fehler beim Laden der Details</string>
-    <string name="file_downloader_notification_title_prefix">Herunterladen \u0020</string>
     <string name="file_icon">Datei</string>
     <string name="file_keep">Behalten</string>
     <string name="file_list_empty">Laden Sie Inhalt hoch oder synchronisieren Sie mit Ihren Geräten.</string>

+ 9 - 0
app/src/main/res/values-eo/strings.xml

@@ -10,12 +10,14 @@
     <string name="action_clear_failed_uploads">Vakigi malsukcesajn alŝutojn</string>
     <string name="action_edit">Modifi</string>
     <string name="action_empty_notifications">Forviŝi ĉiujn sciigojn</string>
+    <string name="action_empty_trashbin">Malpleni rubujon</string>
     <string name="action_send_share">Sendi aŭ kunhavigi</string>
     <string name="action_switch_grid_view">Krada vido</string>
     <string name="action_switch_list_view">Lista vido</string>
     <string name="actionbar_copy">Kopii</string>
     <string name="actionbar_mkdir">Nova dosierujo</string>
     <string name="actionbar_move">Movi</string>
+    <string name="actionbar_move_or_copy">Movi aŭ Kopii</string>
     <string name="actionbar_open_with">Malfermi per</string>
     <string name="actionbar_search">Serĉi</string>
     <string name="actionbar_see_details">Detaloj</string>
@@ -77,6 +79,8 @@
     <string name="choose_local_folder">Elekti lokan dosierujon...</string>
     <string name="choose_remote_folder">Elekti foran dosierujon...</string>
     <string name="clear_notifications_failed">Malsukcesis forviŝi sciigojn.</string>
+    <string name="clear_status_message">Forviŝi statusan mesaĝon</string>
+    <string name="clear_status_message_after">Forviŝos statusan mesaĝon poste</string>
     <string name="clipboard_label">Teksto kopiita el %1$s</string>
     <string name="clipboard_no_text_to_copy">Neniu teksto ricevita por kopii tondujen</string>
     <string name="clipboard_text_copied">Ligilo kopiita</string>
@@ -103,6 +107,8 @@
     <string name="common_send">Sendi</string>
     <string name="common_share">Kunhavigi</string>
     <string name="common_skip">Preterpasi</string>
+    <string name="common_switch_account">Interŝanĝi konton</string>
+    <string name="common_switch_to_account">Ŝanĝi al konto</string>
     <string name="common_yes">Jes</string>
     <string name="community_beta_headline">Testu la beta-version</string>
     <string name="community_beta_text">Ĝi enhavas ĉiujn venontajn funkciojn, kaj ĝi estas freŝfreŝa. Eraroj povas okazi: se kaj kiam tio okazas, bonvolu raporti ilin.</string>
@@ -126,6 +132,8 @@
     <string name="confirmation_remove_folder_alert">Ĉu vi ja volas forigi %1$s kaj ĝian enhavon?</string>
     <string name="confirmation_remove_folders_alert">Ĉu vi ja volas forigi la elektitajn elementojn kaj ilian enhavon?</string>
     <string name="confirmation_remove_local">Nur loka</string>
+    <string name="conflict_local_file">Loka dosiero</string>
+    <string name="contact_backup_title">Savkopii kontaktojn</string>
     <string name="contactlist_item_icon">Uzanto-piktogramo por la kontaktlisto</string>
     <string name="contactlist_no_permission">Permeso ne donita, nenio importiĝis.</string>
     <string name="contacts">Kontaktoj</string>
@@ -143,6 +151,7 @@
     <string name="copy_to">Kopii al...</string>
     <string name="create">Krei</string>
     <string name="create_dir_fail_msg">Ne eblis krei dosierujon</string>
+    <string name="create_new">Krei nove</string>
     <string name="create_new_document">Krei novan dokumenton</string>
     <string name="create_new_folder">Krei novan dosierujon</string>
     <string name="create_new_presentation">Krei novan prezentaĵon</string>

+ 1 - 0
app/src/main/res/values-es-rCL/strings.xml

@@ -239,6 +239,7 @@
     <string name="folder_confirm_create">Crear</string>
     <string name="folder_list_empty_headline">No hay carpetas aquí</string>
     <string name="folder_picker_choose_button_text">Seleccionar</string>
+    <string name="folder_picker_move_button_text">Mover</string>
     <string name="forbidden_permissions">No se te permite %s</string>
     <string name="forbidden_permissions_copy">para copiar este archivo</string>
     <string name="forbidden_permissions_create">para crear este archivo</string>

+ 1 - 0
app/src/main/res/values-es-rSV/strings.xml

@@ -540,6 +540,7 @@
     <string name="wait_a_moment">Aguarda un momento…</string>
     <string name="wait_checking_credentials">Verificando credenciales almacenadas</string>
     <string name="wait_for_tmp_copy_from_private_storage">Copiando el archivo desde almacenamiento privado</string>
+    <string name="webview_version_check_alert_dialog_positive_button_title">Actualizar</string>
     <string name="what_s_new_image">Imagen de qué es nuevo</string>
     <string name="whats_new_skip">Omitir</string>
     <string name="whats_new_title">Nuevo en %1$s</string>

+ 4 - 0
app/src/main/res/values-es/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Si seleccionas ambas versiones, el archivo local tendrá un número añadido a su nombre.</string>
     <string name="conflict_server_file">Archivo del servidor</string>
     <string name="contact_backup_title">Respaldo de contactos</string>
+    <string name="contact_no_permission">Se requiere el permiso de contactos.</string>
     <string name="contactlist_item_icon">Icono de usuario para lista de contactos</string>
     <string name="contactlist_no_permission">No se han concedido permisos, por lo que no se ha importado nada</string>
     <string name="contacts">Contactos</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Más apps de Nextcloud</string>
     <string name="ecosystem_apps_notes">Nextcloud Notas</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">Error al seleccionar dirección de correo.</string>
     <string name="encrypted">Establecer como cifrado</string>
     <string name="end_to_end_encryption_confirm_button">Configurar cifrado</string>
     <string name="end_to_end_encryption_decrypting">Descifrando…</string>
@@ -945,7 +947,9 @@
     <string name="wait_a_moment">Espera un momento…</string>
     <string name="wait_checking_credentials">Comprobando las credenciales guardadas</string>
     <string name="wait_for_tmp_copy_from_private_storage">Copiando el archivo desde el almacenamiento privado.</string>
+    <string name="webview_version_check_alert_dialog_message">Por favor actualiza la aplicación WebView de Sistema Android para iniciar sesión</string>
     <string name="webview_version_check_alert_dialog_positive_button_title">Actualizar</string>
+    <string name="webview_version_check_alert_dialog_title">Actualiza WebView de Sistema Android</string>
     <string name="what_s_new_image">Imagen de Qué hay de nuevo</string>
     <string name="whats_new_skip">Omitir</string>
     <string name="whats_new_title">Nuevo en %1$s</string>

+ 1 - 0
app/src/main/res/values-et-rEE/strings.xml

@@ -525,6 +525,7 @@
     <string name="version_dev_download">Lae alla</string>
     <string name="wait_a_moment">Oota üks hetk…</string>
     <string name="wait_for_tmp_copy_from_private_storage">Faili kopeerimine privaatsest salvestusalast</string>
+    <string name="webview_version_check_alert_dialog_positive_button_title">Uuenda</string>
     <string name="whats_new_skip">Jäta vahele</string>
     <string name="whats_your_status">Mis on su staatus?</string>
     <string name="write_email">Saada kiri</string>

+ 2 - 0
app/src/main/res/values-eu/strings.xml

@@ -393,6 +393,7 @@
     <string name="folder_list_empty_headline">Ez dago karpetarik hemen</string>
     <string name="folder_picker_choose_button_text">Aukeratu</string>
     <string name="folder_picker_choose_caption_text">Aukeratu helburuko karpeta</string>
+    <string name="folder_picker_copy_button_text">Kopiatu</string>
     <string name="folder_picker_move_button_text">Mugitu</string>
     <string name="forbidden_permissions">Ez daukazu baimenik %s</string>
     <string name="forbidden_permissions_copy">fitxategi hau kopiatzeko</string>
@@ -943,6 +944,7 @@
     <string name="wait_a_moment">Itxaron momentu bat…</string>
     <string name="wait_checking_credentials">Gordetako nortasun-datuak konprobatzen</string>
     <string name="wait_for_tmp_copy_from_private_storage">Fitxategia biltegiratze pribatutik kopiatzen</string>
+    <string name="webview_version_check_alert_dialog_positive_button_title">Eguneratu</string>
     <string name="what_s_new_image">Zer da irudi berria</string>
     <string name="whats_new_skip">Salto egin</string>
     <string name="whats_new_title">Berria %1$s-n</string>

+ 2 - 0
app/src/main/res/values-fa/strings.xml

@@ -393,6 +393,7 @@
     <string name="folder_list_empty_headline">هیچ  پوشه ای اینجا وجود ندارد</string>
     <string name="folder_picker_choose_button_text">انتخاب کردن</string>
     <string name="folder_picker_choose_caption_text">پوشهٔ هدف را انتخاب کنید</string>
+    <string name="folder_picker_copy_button_text">رونوشت</string>
     <string name="folder_picker_move_button_text">انتقال</string>
     <string name="forbidden_permissions">شما مجاز نیستید%s</string>
     <string name="forbidden_permissions_copy">کپی این فایل</string>
@@ -943,6 +944,7 @@
     <string name="wait_a_moment">یک لحظه صبر کنید...</string>
     <string name="wait_checking_credentials">بررسی اعتبارنامه‌های ذخیره شده</string>
     <string name="wait_for_tmp_copy_from_private_storage">کپی کردن فایل از حافظه خصوصی</string>
+    <string name="webview_version_check_alert_dialog_positive_button_title">به‌روز رسانی</string>
     <string name="what_s_new_image">چه تصویر جدیدی است</string>
     <string name="whats_new_skip">رد شدن</string>
     <string name="whats_new_title">جدید در %1$s</string>

+ 2 - 0
app/src/main/res/values-fi-rFI/strings.xml

@@ -381,6 +381,7 @@
     <string name="folder_list_empty_headline">Ei kansioita täällä</string>
     <string name="folder_picker_choose_button_text">Valitse</string>
     <string name="folder_picker_choose_caption_text">Valitse kohdekansio</string>
+    <string name="folder_picker_copy_button_text">Kopioi</string>
     <string name="folder_picker_move_button_text">Siirrä</string>
     <string name="forbidden_permissions">Sinulla ei ole oikeutta %s</string>
     <string name="forbidden_permissions_copy">kopioida tämä tiedosto</string>
@@ -906,6 +907,7 @@ GNU yleinen lisenssi, versio 2</string>
     <string name="wait_a_moment">Odota hetki…</string>
     <string name="wait_checking_credentials">Tarkistetaan tallennettuja tilitietoja</string>
     <string name="wait_for_tmp_copy_from_private_storage">Kopioidaan tiedostoa yksityisestä tallennustilasta</string>
+    <string name="webview_version_check_alert_dialog_positive_button_title">Päivitä</string>
     <string name="what_s_new_image">Mitä uutta -kuva</string>
     <string name="whats_new_skip">Ohita</string>
     <string name="whats_new_title">Uutta versiossa %1$s</string>

+ 1 - 1
app/src/main/res/values-fr/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Si vous sélectionnez les deux versions, le fichier local aura un numéro ajouté à son nom.</string>
     <string name="conflict_server_file">Fichier serveur</string>
     <string name="contact_backup_title">Sauvegarde des contacts</string>
+    <string name="contact_no_permission">La permission d\'accès à vos contacts est requise</string>
     <string name="contactlist_item_icon">L\'icône de l\'utilisateur pour la liste des contacts</string>
     <string name="contactlist_no_permission">Pas de permission donnée, rien n\'a été importé.</string>
     <string name="contacts">Contacts</string>
@@ -327,7 +328,6 @@ Attention, la suppression est irréversible.</string>
     <string name="file_delete">Supprimer</string>
     <string name="file_detail_activity_error">Erreur lors de la récupération de l’activité du fichier</string>
     <string name="file_details_no_content">Impossible de charger les détails</string>
-    <string name="file_downloader_notification_title_prefix">Téléchargement de \u0020</string>
     <string name="file_icon">Fichier</string>
     <string name="file_keep">Conserver</string>
     <string name="file_list_empty">Déposez du contenu ou synchronisez vos appareils.</string>

+ 2 - 1
app/src/main/res/values-gl/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Se selecciona ambas versións, o ficheiro local terá un número engadido ao nome.</string>
     <string name="conflict_server_file">Ficheiro do servidor</string>
     <string name="contact_backup_title">Copia de seguranza dos contactos</string>
+    <string name="contact_no_permission">Precisase de permiso de contacto.</string>
     <string name="contactlist_item_icon">Icona do usuario para a lista de contactos</string>
     <string name="contactlist_no_permission">Non se concederon permisos. Non se importou nada!</string>
     <string name="contacts">Contactos</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Máis aplicacións de Nextcloud</string>
     <string name="ecosystem_apps_notes">Notas de Nextcloud</string>
     <string name="ecosystem_apps_talk">Talk de Nextcloud</string>
+    <string name="email_pick_failed">Produciuse un fallo ao escoller o enderezo de correo.</string>
     <string name="encrypted">Estabelecer como cifrado</string>
     <string name="end_to_end_encryption_confirm_button">Configurar o cifrado</string>
     <string name="end_to_end_encryption_decrypting">Descifrando…</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">Eliminar</string>
     <string name="file_detail_activity_error">Produciuse un erro ao recuperar actividades para o ficheiro</string>
     <string name="file_details_no_content">Produciuse un fallo ao cargar os detalles</string>
-    <string name="file_downloader_notification_title_prefix">Descargando \u0020</string>
     <string name="file_icon">Ficheiro</string>
     <string name="file_keep">Conservar</string>
     <string name="file_list_empty">Envíe algún contido ou sincronice cos seus dispositivos.</string>

+ 0 - 1
app/src/main/res/values-hu-rHU/strings.xml

@@ -325,7 +325,6 @@
     <string name="file_delete">Törlés</string>
     <string name="file_detail_activity_error">Hiba a fájl tevékenységeinek lekérésekor</string>
     <string name="file_details_no_content">A részletek betöltése sikertelen</string>
-    <string name="file_downloader_notification_title_prefix">Letöltés \u0020</string>
     <string name="file_icon">Fájl</string>
     <string name="file_keep">Megtartás</string>
     <string name="file_list_empty">Töltsön fel új tartalmat vagy szinkronizáljon az eszközeivel</string>

+ 39 - 1
app/src/main/res/values-in/strings.xml

@@ -18,6 +18,7 @@
     <string name="actionbar_copy">Salin</string>
     <string name="actionbar_mkdir">Folder baru</string>
     <string name="actionbar_move">Pindah</string>
+    <string name="actionbar_move_or_copy">Pindah atau Salin</string>
     <string name="actionbar_open_with">Buka dengan</string>
     <string name="actionbar_search">Cari</string>
     <string name="actionbar_see_details">Rincian</string>
@@ -88,7 +89,7 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="calendars">Kalender</string>
     <string name="certificate_load_problem">Terjadi permasalahan memuat sertifikat.</string>
     <string name="changelog_dev_version">Perubahan versi dev</string>
-    <string name="checkbox">Kotak check</string>
+    <string name="checkbox">Kotak centang</string>
     <string name="choose_local_folder">Pilih folder lokal…</string>
     <string name="choose_location">Pilih lokasi</string>
     <string name="choose_remote_folder">Pilih folder remot…</string>
@@ -152,7 +153,11 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="conflict_dialog_error">Galat saat membuat dialog konflik!</string>
     <string name="conflict_file_headline">File konflik %1$s</string>
     <string name="conflict_local_file">File lokal</string>
+    <string name="conflict_message_description">Jika Anda memilih kedua versi, nama dari berkas lokal akan ditambahi angka.</string>
     <string name="conflict_server_file">File server</string>
+    <string name="contact_backup_title">Pencadangan kontak</string>
+    <string name="contact_no_permission">Izin kontak diperlukan.</string>
+    <string name="contactlist_item_icon">Ikon pengguna untuk daftar kontak</string>
     <string name="contactlist_no_permission">Tidak ada perizinan diberikan, tidak ada yang terimpor</string>
     <string name="contacts">Kontak</string>
     <string name="contacts_backup_button">Cadangkan sekarang.</string>
@@ -166,6 +171,7 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="copy_file_invalid_overwrite">Berkas sudah ada didalam folder tujuan</string>
     <string name="copy_file_not_found">Tidak dapat menyalin. Silakan periksa apakah berkas eksis.</string>
     <string name="copy_link">Salin tautan</string>
+    <string name="copy_move_to_encrypted_folder_not_supported">Menyalin/memindah ke folder terenkripsi saat ini tidak didukung.</string>
     <string name="copy_to">Salin ke…</string>
     <string name="could_not_download_image">Tidak bisa unduh gambar penuh</string>
     <string name="could_not_retrieve_url">Tidak dapat mengambil URL</string>
@@ -192,16 +198,24 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="dev_version_no_information_available">Informasi tidak tersedia</string>
     <string name="dev_version_no_new_version_available">Tidak ada versi baru tersedia</string>
     <string name="dialog_close">Tutup</string>
+    <string name="did_not_check_for_dupes">Tidak mengecek duplikat.</string>
     <string name="digest_algorithm_not_available">Algoritma ini tidak tersedia di ponsel Anda.</string>
     <string name="direct_login_failed">Login melalui tautan langsung gagal!</string>
+    <string name="direct_login_text">Masuk dengan %1$s ke %2$s</string>
     <string name="disable_new_media_folder_detection_notifications">Nonaktifkan</string>
     <string name="dismiss">Batal</string>
     <string name="dismiss_notification_description">Abaikan notifikasi</string>
+    <string name="displays_mnemonic">Menampilkan sandi 12 kata Anda</string>
     <string name="dnd">Jangan diganggu</string>
     <string name="document_scan_export_dialog_images">Banyak gambar</string>
+    <string name="document_scan_export_dialog_pdf">Berkas PDF</string>
+    <string name="document_scan_export_dialog_title">Pilih jenis ekspor</string>
+    <string name="document_scan_pdf_generation_failed">Gagal membuat PDF</string>
     <string name="document_scan_pdf_generation_in_progress">Membuat PDF…</string>
     <string name="done">Selesai</string>
     <string name="dontClear">Jangan dihapus</string>
+    <string name="download_cannot_create_file">Tidak dapat membuat berkas lokal</string>
+    <string name="download_download_invalid_local_file_name">Nama berkas tidak valid untuk berkas lokal</string>
     <string name="download_latest_dev_version">Unduh versi dev terbaru</string>
     <string name="downloader_download_failed_content">Tidak bisa mengunduh %1$s</string>
     <string name="downloader_download_failed_credentials_error">Unduhan gagal, coba masuk kembali</string>
@@ -214,10 +228,12 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="downloader_not_downloaded_yet">Belum diunduh</string>
     <string name="drawer_close">Tutup jendela samping</string>
     <string name="drawer_community">Komunitas</string>
+    <string name="drawer_header_background">Gambar latar belakang tajuk laci</string>
     <string name="drawer_item_activities">Aktivitas</string>
     <string name="drawer_item_all_files">Semua berkas</string>
     <string name="drawer_item_favorites">Disukai</string>
     <string name="drawer_item_gallery">Media</string>
+    <string name="drawer_item_groupfolders">Folder kelompok</string>
     <string name="drawer_item_home">Beranda</string>
     <string name="drawer_item_notifications">Pemberitahuan</string>
     <string name="drawer_item_on_device">Dalam perangkat</string>
@@ -230,8 +246,14 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="drawer_quota">%1$s dari %2$s sudah digunakan</string>
     <string name="drawer_quota_unlimited">%1$s digunakan</string>
     <string name="drawer_synced_folders">Unggah otomatis.</string>
+    <string name="e2e_not_yet_setup">E2E belum dipersiapkan</string>
+    <string name="e2e_offline">Tidak bisa dilakukan tanpa koneksi internet</string>
+    <string name="ecosystem_apps_display_more">Lainnya</string>
+    <string name="ecosystem_apps_display_notes">Catatan</string>
     <string name="ecosystem_apps_display_talk">Talk</string>
+    <string name="ecosystem_apps_more">Aplikasi Nextcloud Lainnya</string>
     <string name="ecosystem_apps_notes">Catatan Nextcloud</string>
+    <string name="email_pick_failed">Gagal memilih alamat surel.</string>
     <string name="encrypted">Atur sebagai terenkripsi</string>
     <string name="end_to_end_encryption_confirm_button">Buat enkripsi</string>
     <string name="end_to_end_encryption_decrypting">Mendekripsi...</string>
@@ -239,11 +261,14 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="end_to_end_encryption_enter_password">Silakan masukkan password untuk mendekripsi kunci pribadi</string>
     <string name="end_to_end_encryption_folder_not_empty">Folder ini tidak kosong.</string>
     <string name="end_to_end_encryption_generating_keys">Membuat kunci baru...</string>
+    <string name="end_to_end_encryption_keywords_description">Seluruh 12 kata menghasilkan sandi yang sangat kuat, memungkinkan Anda melihat dan mempergunakan berkas-berkas Anda yang terenkripsi. Harap tulis sandi tersebut dan simpan di tempat aman.</string>
     <string name="end_to_end_encryption_not_enabled">Enkripsi end-to-end dinonaktifkan di server</string>
+    <string name="end_to_end_encryption_passphrase_title">Catatlah sandi enkripsi 12 kata Anda</string>
     <string name="end_to_end_encryption_password">Kata Sandi…</string>
     <string name="end_to_end_encryption_retrieving_keys">Menerima kunci...</string>
     <string name="end_to_end_encryption_storing_keys">Menyimpan kunci</string>
     <string name="end_to_end_encryption_title">Buat enkripsi</string>
+    <string name="end_to_end_encryption_unsuccessful">Tidak dapat menyimpan kunci, harap coba lagi.</string>
     <string name="end_to_end_encryption_wrong_password">Error saat mendekripsi. Kata sandi salah?</string>
     <string name="enter_destination_filename">Masukkan nama file tujuan</string>
     <string name="enter_filename">Tolong masukan nama berkas baru</string>
@@ -251,10 +276,12 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="error_cant_bind_to_operations_service">Kesalahan fatal: tidak dapat melakukan operasi</string>
     <string name="error_choosing_date">Terjadi kesalahan dalam memilih tanggal</string>
     <string name="error_comment_file">Error saat mengomentari file</string>
+    <string name="error_creating_file_from_template">Galat saat membuat berkas dari templat</string>
     <string name="error_file_lock">Error saat mengubah status kunci file</string>
     <string name="error_report_issue_action">Laporan</string>
     <string name="error_retrieving_file">Galat saat menerima file</string>
     <string name="error_retrieving_templates">Error saat mengambil template</string>
+    <string name="error_showing_encryption_dialog">Galat saat menampilkan dialog penyiapan enkripsi!</string>
     <string name="error_starting_direct_camera_upload">Galat saat mengaktifkan kamera</string>
     <string name="error_starting_doc_scan">Galat memulai pemindaian dokumen</string>
     <string name="etm_accounts">Akun</string>
@@ -266,34 +293,44 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="etm_background_job_uuid">UUID</string>
     <string name="etm_background_jobs">Pekerjaan latar belakang</string>
     <string name="etm_background_jobs_cancel_all">Batalkan semua pekerjaan</string>
+    <string name="etm_background_jobs_prune">Pangkas pekerjaan yang tidak aktif</string>
     <string name="etm_preferences">Preferensi</string>
     <string name="etm_transfer_type">Transfer</string>
     <string name="etm_transfer_type_download">Unduh</string>
     <string name="etm_transfer_type_upload">Unggah</string>
     <string name="fab_label">Tambahkan atau unggah</string>
+    <string name="failed_to_download">Gagal memberikan berkas ke pengelola unduhan</string>
+    <string name="failed_to_print">Gagal mencetak berkas</string>
+    <string name="failed_to_start_editor">Gagal memulai editor</string>
     <string name="failed_update_ui">Gagal memperbarui UI</string>
     <string name="favorite">Tambah ke favorit</string>
     <string name="favorite_icon">Favorit</string>
     <string name="file_already_exists">Berkas sudah ada</string>
     <string name="file_delete">Hapus</string>
+    <string name="file_detail_activity_error">Gagal mendapatkan aktivitas untuk berkas</string>
     <string name="file_details_no_content">Gagal memuat detil</string>
     <string name="file_icon">Berkas</string>
     <string name="file_keep">Simpan</string>
     <string name="file_list_empty">Unggah beberapa berkas atau sinkronisasi dengan perangkat anda.</string>
     <string name="file_list_empty_favorite_headline">Belum ada yang disukai.</string>
     <string name="file_list_empty_favorites_filter_list">Berkas dan folder yang Anda tandai sebagai favorit akan ditampilkan di sini.</string>
+    <string name="file_list_empty_gallery">Tidak menemukan gambar atau video</string>
     <string name="file_list_empty_headline">Tidak ada berkas</string>
     <string name="file_list_empty_headline_search">Tidak ada hasil di folder ini</string>
     <string name="file_list_empty_headline_server_search">Tidak ada hasil.</string>
     <string name="file_list_empty_moving">Kosong. Anda dapat menambahkan folder</string>
+    <string name="file_list_empty_on_device">Berkas dan folder yang diunduh akan muncul di sini.</string>
     <string name="file_list_empty_recently_modified">Tidak ditemukan berkas yang diubah 7 hari terakhir</string>
     <string name="file_list_empty_search">Mungkin ada di folder yang berbeda?</string>
+    <string name="file_list_empty_shared">Berkas dan folder yang Anda bagikan akan muncul di sini.</string>
     <string name="file_list_empty_shared_headline">Belum ada yang dibagikan.</string>
+    <string name="file_list_empty_unified_search_no_results">Tidak ada hasil yang ditemukan untuk kueri Anda</string>
     <string name="file_list_folder">folder</string>
     <string name="file_list_loading">Memuat…</string>
     <string name="file_list_no_app_for_file_type">Tidak ada aplikasi untuk membuka jenis berkas ini.</string>
     <string name="file_list_seconds_ago">beberapa detik yang lalu</string>
     <string name="file_management_permission">Hak akses diperlukan</string>
+    <string name="file_management_permission_optional">Izin penyimpanan</string>
     <string name="file_migration_checking_destination">Memeriksa tujuan…</string>
     <string name="file_migration_cleaning">Membersihkan…</string>
     <string name="file_migration_failed_dir_already_exists">Direktori NextCloud sudah ada</string>
@@ -600,6 +637,7 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="unset_favorite">Hapus dari favorit</string>
     <string name="unshare_link_forbidden_permissions">untuk batal membagikan berkas ini</string>
     <string name="update_link_forbidden_permissions">untuk memperbarui pembagian ini</string>
+    <string name="upload_cannot_create_file">Tidak dapat membuat berkas lokal</string>
     <string name="upload_chooser_title">Unggah dari…</string>
     <string name="upload_content_from_other_apps">Unggah konten dari aplikasi lain</string>
     <string name="upload_direct_camera_upload">Unggah dari kamera</string>

+ 3 - 0
app/src/main/res/values-is/strings.xml

@@ -373,6 +373,7 @@
     <string name="link">Tengill</string>
     <string name="link_share_allow_upload_and_editing">Leyfa innsendingu og breytingar</string>
     <string name="link_share_file_drop">Slepping skráa (einungis innsending)</string>
+    <string name="link_share_view_only">Einungis skoða</string>
     <string name="list_layout">Framsetning sem listi</string>
     <string name="load_more_results">Hlaða inn fleiri niðurstöðum</string>
     <string name="local_file_list_empty">Það eru engar skrár í þessari möppu.</string>
@@ -588,6 +589,8 @@
     <string name="share_no_password_title">Skrá lykilorð</string>
     <string name="share_password_title">Verja með lykilorði</string>
     <string name="share_permission_can_edit">Getur breytt</string>
+    <string name="share_permission_file_drop">Slepping skráa</string>
+    <string name="share_permission_view_only">Einungis skoða</string>
     <string name="share_remote_clarification">%1$s (fjartengt)</string>
     <string name="share_room_clarification">%1$s (samtal)</string>
     <string name="share_send_note">Minnispunktur til viðtakanda</string>

+ 15 - 0
app/src/main/res/values-nb-rNO/strings.xml

@@ -18,6 +18,7 @@
     <string name="actionbar_copy">Kopier</string>
     <string name="actionbar_mkdir">Ny mappe</string>
     <string name="actionbar_move">Flytt</string>
+    <string name="actionbar_move_or_copy">Flytt eller kopier</string>
     <string name="actionbar_open_with">Åpne med</string>
     <string name="actionbar_search">Søk</string>
     <string name="actionbar_see_details">Detaljer</string>
@@ -425,6 +426,13 @@
     <string name="image_editor_rotate_ccw">Roter mot klokken</string>
     <string name="image_editor_rotate_cw">Roter med klokken</string>
     <string name="image_editor_unable_to_edit_image">Kan ikke endre bildet.</string>
+    <string name="image_preview_filedetails">Fildetaljer</string>
+    <string name="image_preview_image_taking_conditions">Betingelser for å ta bilder</string>
+    <string name="image_preview_unit_fnumber">ƒ/%s</string>
+    <string name="image_preview_unit_iso">ISO %s</string>
+    <string name="image_preview_unit_megapixel">%s MP</string>
+    <string name="image_preview_unit_millimetres">%s mm</string>
+    <string name="image_preview_unit_seconds">%s s</string>
     <string name="in_folder">i mappen %1$s</string>
     <string name="instant_upload_existing">Last også opp eksisterende filer</string>
     <string name="instant_upload_on_charging">Bare last opp under lading</string>
@@ -505,6 +513,7 @@
     <string name="no_calendar_exists">Ingen kalender finnes</string>
     <string name="no_email_app_available">Ingen program for å behandle e-post adresse</string>
     <string name="no_items">Ingen gjenstander</string>
+    <string name="no_map_app_availble">Ingen app tilgjengelig for å håndtere kart</string>
     <string name="no_mutliple_accounts_allowed">Kun én konto er tillatt</string>
     <string name="no_pdf_app_available">Ingen app tilgjengelig for å håndtere PDF</string>
     <string name="no_send_app">Ingen program for å sende valgt fil</string>
@@ -591,7 +600,9 @@
     <string name="prefs_imprint">Avtrykk</string>
     <string name="prefs_instant_behaviour_dialogTitle">Opprinnelig fil vil bli…</string>
     <string name="prefs_instant_behaviour_title">Opprinnelig fil vil bli…</string>
+    <string name="prefs_instant_upload_path_use_date_subfolders_summary">Lagre i undermapper basert på dato</string>
     <string name="prefs_instant_upload_path_use_subfolders_title">Bruk undermapper</string>
+    <string name="prefs_instant_upload_subfolder_rule_title">Alternativer for undermappe</string>
     <string name="prefs_keys_exist">Legg til ende-til-ende -kryptering på denne klienten</string>
     <string name="prefs_license">Lisens</string>
     <string name="prefs_lock">Appsikkerhet</string>
@@ -781,6 +792,8 @@
     <string name="stream_not_possible_headline">Intern strøming ikke mulig</string>
     <string name="stream_not_possible_message">Vennligst last ned media i stedet, eller bruk ekstern app.</string>
     <string name="strict_mode">Streng modus: ingen HTTP-tilkobling tillatt!</string>
+    <string name="sub_folder_rule_day">År/Måned/Dag</string>
+    <string name="sub_folder_rule_month">År/Måned</string>
     <string name="sub_folder_rule_year">År</string>
     <string name="subject_shared_with_you">\"%1$s\" er blitt delt med deg</string>
     <string name="subject_user_shared_with_you">%1$s delte \"%2$s\" med deg</string>
@@ -932,7 +945,9 @@
     <string name="wait_a_moment">Vent et øyeblikk…</string>
     <string name="wait_checking_credentials">Sjekker lagrede påloggingsdetaljer</string>
     <string name="wait_for_tmp_copy_from_private_storage">Kopierer fil fra privat lager</string>
+    <string name="webview_version_check_alert_dialog_message">Vennligst oppdater Android systemets WebView-app for pålogging</string>
     <string name="webview_version_check_alert_dialog_positive_button_title">Oppdater</string>
+    <string name="webview_version_check_alert_dialog_title">Oppdater Android systemets WebView</string>
     <string name="what_s_new_image">Hva er nytt-bilde</string>
     <string name="whats_new_skip">Hopp over</string>
     <string name="whats_new_title">Nytt i %1$s</string>

+ 2 - 1
app/src/main/res/values-pl/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Jeśli wybierzesz obie wersje, to do nazwy pliku lokalnego zostanie dodany numer.</string>
     <string name="conflict_server_file">Plik z serwera</string>
     <string name="contact_backup_title">Kopia zapasowa kontaktów</string>
+    <string name="contact_no_permission">Wymagane jest pozwolenie na lokalizację</string>
     <string name="contactlist_item_icon">Ikona użytkownika w liście kontaktów</string>
     <string name="contactlist_no_permission">Brak nadanych uprawnień, nic nie zaimportowano.</string>
     <string name="contacts">Kontakty</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Więcej aplikacji Nextcloud</string>
     <string name="ecosystem_apps_notes">Nextcloud Notes</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">Nie udało się wybrać adresu e-mail.</string>
     <string name="encrypted">Ustaw jako zaszyfrowane</string>
     <string name="end_to_end_encryption_confirm_button">Włącz szyfrowanie</string>
     <string name="end_to_end_encryption_decrypting">Odszyfrowywanie…</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">Usuń</string>
     <string name="file_detail_activity_error">Błąd podczas pobierania aktywności dla pliku</string>
     <string name="file_details_no_content">Nie udało się załadować szczegółów</string>
-    <string name="file_downloader_notification_title_prefix">Pobieranie \u0020</string>
     <string name="file_icon">Plik</string>
     <string name="file_keep">Zachowaj</string>
     <string name="file_list_empty">Wyślij lub zsynchronizuj pliki z urządzeniami.</string>

+ 8 - 6
app/src/main/res/values-ro/strings.xml

@@ -157,7 +157,7 @@
     <string name="conflict_local_file">Fișier local</string>
     <string name="conflict_message_description">Dacă selectezi ambele variante, atunci fișierul local va avea un număr adăugat la numele său.</string>
     <string name="conflict_server_file">Fișier pe server</string>
-    <string name="contact_backup_title">Backup (copie de rezervă) contacte</string>
+    <string name="contact_backup_title">Copie de rezervă contacte</string>
     <string name="contactlist_item_icon">Iconiță utilizator pentru lista de contacte</string>
     <string name="contactlist_no_permission">Nu sunt acordate permisiuni, nu s-a importat nimic.</string>
     <string name="contacts">Contacte</string>
@@ -203,6 +203,7 @@
     <string name="did_not_check_for_dupes">Nu s-au verificat duplicatele.</string>
     <string name="digest_algorithm_not_available">Algoritmul \'digest\' nu este disponibil pe telefonul tău.</string>
     <string name="direct_login_failed">Eroare la autentificare prin legătură directă!</string>
+    <string name="direct_login_text">Autentificare cu %1$s la %2$s</string>
     <string name="disable_new_media_folder_detection_notifications">Dezactivează</string>
     <string name="dismiss">Elimină</string>
     <string name="dismiss_notification_description">Elimină notificarea</string>
@@ -440,6 +441,7 @@
     <string name="locked_by_app">Blocat de aplicația%1$s </string>
     <string name="log_send_mail_subject">%1$s înregistrările app-ului Android</string>
     <string name="log_send_no_mail_app">Nu există nici o aplicație pentru a trimite fisiere log. Vă rugăm instalați un client de email.</string>
+    <string name="logged_in_as">Autentificat ca %1$s</string>
     <string name="login">Autentificare</string>
     <string name="login_url_helper_text">Linkul către %1$s interfața web atunci când deschizi linkul în browser.</string>
     <string name="logs_menu_delete">Șterge fișiere log</string>
@@ -569,7 +571,7 @@
     <string name="prefs_daily_contact_backup_summary">Salvarea zilnică a contactelor dvs.</string>
     <string name="prefs_e2e_active">Encripția end-to-end este setata!</string>
     <string name="prefs_e2e_mnemonic">E2E mnemonic</string>
-    <string name="prefs_e2e_no_device_credentials">Pentru a arăta fraza de memorare (mnemonic) vă rugăm activați acreditările dispozitivului.</string>
+    <string name="prefs_e2e_no_device_credentials">Pentru a arăta mnemonica activați credențialele pentru dispozitiv.</string>
     <string name="prefs_enable_media_scan_notifications">Afișează notificări despre scanarea media</string>
     <string name="prefs_enable_media_scan_notifications_summary">Notifică despre dosare media noi găsite</string>
     <string name="prefs_gpl_v2">Licența Publică Generală GNU, versiunea 2</string>
@@ -754,8 +756,8 @@
     <string name="storage_permission_full_access">Acces complet</string>
     <string name="storage_permission_media_read_only">Media read-only</string>
     <string name="storage_pictures">Poze</string>
-    <string name="store_full_desc">Platforma de productivitate ce îți oferă ție ontrolul și poate fi găzduită de tine.\n\Caracteristici:\n* Interfață facilă, modernă, complet personalizată in aliniere cu tema serverului tău\n* Încarcă fișiere pe serverul tău Nextcloud\n* Partajează fișierele tale cu alții\n* Păstrează-ți fișierele și folderele preferate sincronizate\n* Căutare în toate folderele de pe serverul tău\n* Încărcare automată a fotografiilor și videoclipurilor făcute cu dispozitivul tău\n* Fii la curent cu toate notificările\n* Suport pentru conturi multiple\n* Acces securizat la datele tale prin amprentă sau PIN\n* Integrare cu DAVx5 (în trecut cunoscut ca DAVdroid) pentru configurarea ușoară a sincronizarii Calendarelor si Contactelor. \nTe rugăm să anunți orice fel de probleme la https://github.com/nextcloud/android/issues și discuți despre această aplicație la https://help.nextcloud.com/c/clients/android\n\nEști nou la Nextcloud? Nextcloud este un server privat pentru comunicare, sincronizare &amp; și partajare de fișiere. Este în întregime open-source și îl poți găzdui tu, sau poți plăti o companie să facă asta pentru tine. În acest fel, ești pe deplin în control asupra fotografiilor tale, a calendarului și informațiilor de contact, a documentelor și a orice altceva.\n\nAflă mai multe despre Nextcloud la https://nextcloud.com</string>
-    <string name="store_full_dev_desc">Poți găzdui propriile tale instrumente de productivitate, tu avînd controlul total.\nAceasta este versiunea oficială ce prezintă o mostră zilnică de funcționalități netestate, ce ar putea cauza instabilități șî pierdere de date. Aplicația este pentru utilizatori ce sunt dispuși să testeze și să raporteze eventualele erori sau probleme de funcționare. Nu folosiți această aplicație pentru muncă productivă!\n]nAmbele versiuni pentru dezvoltatori și versiunea normală sunt disponibile pe F-Droid, și pot fii instalate în același timp.</string>
+    <string name="store_full_desc">Platfoma locală de productivitate care vă menține în control.\n\nCaracteristici:\n* Interfață simplă, modernă, adaptată temei serverului\n* Încărcați fișiere în serverul Nextcloud\n* Partajați-le cu alții\n* Țineți fișierele și folderele preferate sincronizate\n* Căutați prin toate folderele de pe server\n* Auto Încărcarea fotografiilor și clipurilor video făcute de dispozitivul personal\n* Fiți la curent cu notificările\n* Suport pentru Multi-account\n* Acces sigur la date cu amprentă sau PIN\n* Integrae cu DAVx5 (anterior DAVdroid) pentru setarea simplă a sincronizării calendarului &amp; Contactelor\n\nRaportați orice problemă la https://github.com/nextcloud/android/issues și discutați despre această aplicație la https://help.nextcloud.com/c/clients/android\n\nNew cu Nextcloud? Nextcloud este un server privat de sincronizare fișiere &amp; partajare și de comunicație. Este un software gratuit și puteți să-l găzduiți sau să plătiți o companie să o facă pentru dumneavoastră. Aveți astfel control asupra fotografiilor, datelor calendarului și despre contacte, documentelor și orice altceva.\n\nVizitați Nextcloud la https://nextcloud.com</string>
+    <string name="store_full_dev_desc">Platforma de productivitate locală care vă menține în control.\nAceasta este versiunea de dezvoltare oficială, cuprinzând exemple zilnice de funcționalități netestate, care pot crea instabilitate sau pierderi de date. Aplicația este pentru utilizatori care doresc să testeze și să raporteze bug-uri dacă acestea apar. Nu folosiți în producție!\n\n Și versiunea oficială de dezvoltare și cea stabilă sunt disponibile pe F-droid și pot fi instalate în același timp.</string>
     <string name="store_short_desc">Platforma găzduită și controlată de tine</string>
     <string name="store_short_dev_desc">Platforma găzduită și controlată de tine(versiunea pentru dezvoltatori)</string>
     <string name="stream">Transmite cu...</string>
@@ -815,7 +817,7 @@
     <string name="unread_comments">Există comentarii necitite</string>
     <string name="unset_encrypted">Dezactivați criptarea</string>
     <string name="unset_favorite">Ștergeți din favorite</string>
-    <string name="unshare_link_file_error">A apărut o eroare în timp ce încerca să se elimine partajarea (unshare) pentru acest fișier sau folder.</string>
+    <string name="unshare_link_file_error">A apărut o eroare la eliminarea partajării acestui fișier sau folder.</string>
     <string name="unshare_link_file_no_exist">Imposibil de șters partajarea. Te rugăm să verifici dacă există fișierul.</string>
     <string name="unshare_link_forbidden_permissions">de a nu permite accesul la acest fisier</string>
     <string name="unsharing_failed">Ștergerea partajării a eșuat</string>
@@ -843,7 +845,6 @@
     <string name="upload_local_storage_full">Stocarea locală este plină</string>
     <string name="upload_local_storage_not_copied">Fișierul nu a putut fi copiat în memoria locală</string>
     <string name="upload_lock_failed">Blocarea dosarului a eșuat</string>
-    <string name="upload_old_android">Criptarea este posibilă numai cu > = Android 5.0</string>
     <string name="upload_query_move_foreign_files">Nu există spațiu suficient pentru a copia fișierele selectate în dosarul %1$s. Doriți să le mutați în schimb?</string>
     <string name="upload_scan_doc_upload">Scanați documentul cu camera foto</string>
     <string name="upload_sync_conflict">Conflict de sincronizare, vă rugăm rezolvați  problema manual</string>
@@ -913,6 +914,7 @@
     <string name="wait_a_moment">Așteaptă un moment…</string>
     <string name="wait_checking_credentials">Se verifică datele de autentificare stocate</string>
     <string name="wait_for_tmp_copy_from_private_storage">Copiere fișier din stocare privată</string>
+    <string name="webview_version_check_alert_dialog_message">Pentru a vă autentifica, actualizați componenta WebView a sistemului Android</string>
     <string name="webview_version_check_alert_dialog_positive_button_title">Actualizare</string>
     <string name="what_s_new_image">Ce imagine este nouă</string>
     <string name="whats_new_skip">Sari peste</string>

+ 0 - 1
app/src/main/res/values-ru/strings.xml

@@ -325,7 +325,6 @@
     <string name="file_delete">Удалить</string>
     <string name="file_detail_activity_error">Ошибка получения истории событий, связанных с файлом</string>
     <string name="file_details_no_content">Не удалось получить подробные сведения</string>
-    <string name="file_downloader_notification_title_prefix">Скачивание \u0020</string>
     <string name="file_icon">Файл</string>
     <string name="file_keep">Сохранить</string>
     <string name="file_list_empty">Добавьте что-нибудь или синхронизируйте со своими устройствами!</string>

+ 45 - 0
app/src/main/res/values-sl/strings.xml

@@ -18,6 +18,7 @@
     <string name="actionbar_copy">Kopiraj</string>
     <string name="actionbar_mkdir">Nova mapa</string>
     <string name="actionbar_move">Premakni</string>
+    <string name="actionbar_move_or_copy">Premakni ali Kopiraj</string>
     <string name="actionbar_open_with">Odpri s programom</string>
     <string name="actionbar_search">Iskanje</string>
     <string name="actionbar_see_details">Podrobnosti</string>
@@ -159,6 +160,7 @@
     <string name="conflict_message_description">Če izberete obe različici, bo k imenu krajevne datoteke dodana številka.</string>
     <string name="conflict_server_file">Strežniška datoteka</string>
     <string name="contact_backup_title">Varnostna kopija stikov</string>
+    <string name="contact_no_permission">Potrebno je dovoljeno do stikov.</string>
     <string name="contactlist_item_icon">Ikona uporabnika za seznam stikov</string>
     <string name="contactlist_no_permission">Ni ustreznih dovoljenj, uvoz je prekinjen.</string>
     <string name="contacts">Stiki</string>
@@ -204,6 +206,7 @@
     <string name="did_not_check_for_dupes">Ne preverjaj za podvojene.</string>
     <string name="digest_algorithm_not_available">Ta algoritem na tej napravi ni podprt.</string>
     <string name="direct_login_failed">Prijava prek neposredne povezave je spodletela.</string>
+    <string name="direct_login_text">Prijava z %1$s v %2$s</string>
     <string name="disable_new_media_folder_detection_notifications">Onemogoči</string>
     <string name="dismiss">Opusti</string>
     <string name="dismiss_notification_description">Opusti obvestilo</string>
@@ -253,7 +256,10 @@
     <string name="ecosystem_apps_display_more">Več</string>
     <string name="ecosystem_apps_display_notes">Beležke</string>
     <string name="ecosystem_apps_display_talk">Pogovor Talk</string>
+    <string name="ecosystem_apps_more">Več Nexcloud Aplikacij</string>
     <string name="ecosystem_apps_notes">Nextcloud Beležke</string>
+    <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">E-poštnega naslova ni bilo mogoče izbrati.</string>
     <string name="encrypted">Nastavi kot šifrirano</string>
     <string name="end_to_end_encryption_confirm_button">Nastavitev šifriranja</string>
     <string name="end_to_end_encryption_decrypting">Poteka odšifriranje…</string>
@@ -416,8 +422,14 @@
     <string name="icon_for_empty_list">Ikona za prazen seznam</string>
     <string name="icon_of_dashboard_widget">Ikona gradnika nadzorne plošče</string>
     <string name="icon_of_widget_entry">Ikona vnosa gradnikov</string>
+    <string name="image_editor_file_edited_suffix">urejeno</string>
+    <string name="image_editor_flip_horizontal">Obrni vodoravno</string>
+    <string name="image_editor_flip_vertical">Obrni navpično</string>
+    <string name="image_editor_rotate_ccw">Zavrti v levo</string>
+    <string name="image_editor_rotate_cw">Zavrti v desno</string>
     <string name="image_editor_unable_to_edit_image">Slike ni mogoče urediti.</string>
     <string name="image_preview_filedetails">Podrobnosti datoteke</string>
+    <string name="image_preview_image_taking_conditions">Pogoji fotografiranja</string>
     <string name="image_preview_unit_fnumber">ƒ/%s</string>
     <string name="image_preview_unit_iso">ISO %s</string>
     <string name="image_preview_unit_megapixel">%s MP</string>
@@ -450,6 +462,7 @@
     <string name="locked_by_app">Zaklenjeno s strani %1$s</string>
     <string name="log_send_mail_subject">%1$s dnevniki programa</string>
     <string name="log_send_no_mail_app">Ni nameščenega programa za pošiljanje dnevnikov. Namestiti je treba program za elektronsko pošto.</string>
+    <string name="logged_in_as">Prijavljen kot %1$s</string>
     <string name="login">Prijava</string>
     <string name="login_url_helper_text">Povezava do spletnega vmesnika %1$s, ki se odpre v brskalniku.</string>
     <string name="logs_menu_delete">Izbriši dnevnike</string>
@@ -502,6 +515,7 @@
     <string name="no_calendar_exists">Ni nobenega koledarja</string>
     <string name="no_email_app_available">Ni nameščenega programa, ki upravlja elektronskimi naslovi.</string>
     <string name="no_items">Ni predmetov</string>
+    <string name="no_map_app_availble">Ni nameščenega programa za odpiranje zemljevidov</string>
     <string name="no_mutliple_accounts_allowed">Dovoljen je le en račun</string>
     <string name="no_pdf_app_available">Ni nameščenega programa za odpiranje datotek PDF</string>
     <string name="no_send_app">Na voljo ni nobenega programa za pošiljanje izbranih datotek</string>
@@ -588,6 +602,7 @@
     <string name="prefs_imprint">Natis</string>
     <string name="prefs_instant_behaviour_dialogTitle">Izvorna datoteka bo…</string>
     <string name="prefs_instant_behaviour_title">Izvorna datoteka bo…</string>
+    <string name="prefs_instant_upload_path_use_date_subfolders_summary">Shranjevanje v podmape glede na datum</string>
     <string name="prefs_instant_upload_path_use_subfolders_title">Uporabi podmape</string>
     <string name="prefs_instant_upload_subfolder_rule_title">Možnosti podmape</string>
     <string name="prefs_keys_exist">Dodaj celovito šifriranje E2E na to napravo</string>
@@ -604,6 +619,7 @@
     <string name="prefs_remove_e2e">Krajevno odstrani šifriranje</string>
     <string name="prefs_setup_e2e">Nastavi celovito šifriranje E2E</string>
     <string name="prefs_show_ecosystem_apps">Pokaži preklopnika programov</string>
+    <string name="prefs_show_ecosystem_apps_summary">Predlogi aplikacij Nextcloud v navigacijskem naslovu</string>
     <string name="prefs_show_hidden_files">Pokaži skrite datoteke</string>
     <string name="prefs_sourcecode">Pridobi izvorno kodo</string>
     <string name="prefs_storage_path">Mapa podatkovne shrambe</string>
@@ -632,6 +648,7 @@
     <string name="remote">(oddaljeno) </string>
     <string name="remote_file_fetch_failed">Iskanje datoteke je spodletelo!</string>
     <string name="remove_e2e">Na tej napravi lahko odstranite krajevno celovito šifriranje E2E</string>
+    <string name="remove_e2e_message">V tem odjemalcu lahko lokalno odstranite šifriranje E2E. Šifrirane datoteke bodo ostale na strežniku, vendar ne bodo več sinhronizirane s tem računalnikom.</string>
     <string name="remove_fail_msg">Brisanje je spodletelo</string>
     <string name="remove_notification_failed">Odstranjevanje obvestil je spodletelo.</string>
     <string name="remove_push_notification">Odstrani</string>
@@ -669,12 +686,14 @@
     <string name="select_template">Izbor predloge</string>
     <string name="send">Pošlji</string>
     <string name="send_note">Pošlji sporočilo prejemniku</string>
+    <string name="send_share">Pošlji souporabo</string>
     <string name="sendbutton_description">Ikona gumba za pošiljanje</string>
     <string name="set_as">Nastavi kot</string>
     <string name="set_note">Nastavi sporočilo</string>
     <string name="set_picture_as">Uporabi sliko kot</string>
     <string name="set_status">Nastavi stanje</string>
     <string name="set_status_message">Nastavi sporočilo stanja</string>
+    <string name="setup_e2e">Med nastavitvijo šifriranja E2E boste prejeli naključno 12-mestno sporočilo, ki ga boste morali odpreti na drugih napravah. To bo shranjeno samo na tej napravi in ga je mogoče ponovno prikazati na tem zaslonu. Prosimo, zabeležite ga na varnem mestu!</string>
     <string name="share">Souporaba</string>
     <string name="share_copy_link">Omogoči souporabo &amp; Kopiraj povezavo</string>
     <string name="share_dialog_title">Souporaba</string>
@@ -928,7 +947,9 @@
     <string name="wait_a_moment">Počakajte trenutek …</string>
     <string name="wait_checking_credentials">Poteka preverjanje shranjenih poveril</string>
     <string name="wait_for_tmp_copy_from_private_storage">Kopiranje datoteke iz zasebne shrambe</string>
+    <string name="webview_version_check_alert_dialog_message">Prosimo, posodobite aplikacijo Android System WebView za prijavo</string>
     <string name="webview_version_check_alert_dialog_positive_button_title">Posodobi</string>
+    <string name="webview_version_check_alert_dialog_title">Posodobite Android System WebView</string>
     <string name="what_s_new_image">Kaj je nova slika</string>
     <string name="whats_new_skip">Preskoči</string>
     <string name="whats_new_title">Novo v %1$s</string>
@@ -950,6 +971,12 @@
         <item quantity="few">Spodletelo je kopiranje %1$d datotek iz mape %2$s v</item>
         <item quantity="other">Spodletelo je kopiranje %1$d datotek iz mape %2$s v</item>
     </plurals>
+    <plurals name="wrote_n_events_to">
+        <item quantity="one">%1$d zapisan dogodek v %2$s</item>
+        <item quantity="two">%1$d zapisana dogodka v %2$s</item>
+        <item quantity="few">%1$d zapisanih dogodkov v %2$s</item>
+        <item quantity="other">%1$d zapisanih dogodkov v %2$s</item>
+    </plurals>
     <plurals name="created_n_uids_to">
         <item quantity="one">Ustvarjeno je %1$d novo določilo UID</item>
         <item quantity="two">Ustvarjeni sta %1$d novi določili UID</item>
@@ -974,6 +1001,24 @@
         <item quantity="few">Izvožene so %d datoteke.</item>
         <item quantity="other">Izvoženih je %d datotek.</item>
     </plurals>
+    <plurals name="export_failed">
+        <item quantity="one">Napaka pri izvažanju %d datoteke</item>
+        <item quantity="two">Napaka pri izvažanju %d datotek</item>
+        <item quantity="few">Napaka pri izvažanju %d datotek</item>
+        <item quantity="other">Napaka pri izvažanju %d datotek</item>
+    </plurals>
+    <plurals name="export_partially_failed">
+        <item quantity="one">Izvožena %d datoteka, ostale so bile preskočene zaradi napake</item>
+        <item quantity="two">Izvoženi %d datoteki, ostale so bile preskočene zaradi napake</item>
+        <item quantity="few">Izvoženih %d datotek, ostale so bile preskočene zaradi napake</item>
+        <item quantity="other">Izvoženih %d datotek, ostale so bile preskočene zaradi napake</item>
+    </plurals>
+    <plurals name="export_start">
+        <item quantity="one">Izvožena bo %d datoteka. Za podrobnosti glejte obvestilo.</item>
+        <item quantity="two">Izvožena bosta %d datoteki. Za podrobnosti glejte obvestilo.</item>
+        <item quantity="few">Izvoženih bo %d datotek. Za podrobnosti glejte obvestilo.</item>
+        <item quantity="other">Izvoženih bo %d datotek. Za podrobnosti glejte obvestilo.</item>
+    </plurals>
     <plurals name="file_list__footer__folder">
         <item quantity="one">%1$d mapa</item>
         <item quantity="two">%1$d mapi</item>

+ 2 - 1
app/src/main/res/values-sr/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Ако изаберете обе верзије, локални фајл имаће број придодат свом називу.</string>
     <string name="conflict_server_file">Серверски фајл</string>
     <string name="contact_backup_title">Резервна копија контаката</string>
+    <string name="contact_no_permission">Неопходна је дозвола контакта.</string>
     <string name="contactlist_item_icon">Икона корисника за листу контаката</string>
     <string name="contactlist_no_permission">Није дата дозвола. Ништа није увезено.</string>
     <string name="contacts">Контакти</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Још Nextcloud апликација</string>
     <string name="ecosystem_apps_notes">Некстклауд Белешке</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">Није успело бирање и-мејл адресе.</string>
     <string name="encrypted">Постави као шифровано</string>
     <string name="end_to_end_encryption_confirm_button">Подесите шифровање</string>
     <string name="end_to_end_encryption_decrypting">Дешифрујем…</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">Обриши</string>
     <string name="file_detail_activity_error">Грешка при добављању активности за фајл</string>
     <string name="file_details_no_content">Грешка при учитавању детаља</string>
-    <string name="file_downloader_notification_title_prefix">Преузима се \u0020</string>
     <string name="file_icon">Фајл</string>
     <string name="file_keep">Задржи</string>
     <string name="file_list_empty">Отпремите неки садржај или синхронизујте са вашим уређајима.</string>

+ 2 - 1
app/src/main/res/values-sv/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Om du väljer båda versionerna kommer den lokala filen få ett nummer tillagt i filnamnet.</string>
     <string name="conflict_server_file">Serverfil</string>
     <string name="contact_backup_title">Backup av kontakter</string>
+    <string name="contact_no_permission">Rättighet till kontakt krävs.</string>
     <string name="contactlist_item_icon">Användarikon för kontaktlista</string>
     <string name="contactlist_no_permission">Ingen tillstått givet, ingen importerat!</string>
     <string name="contacts">Kontakter</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Fler Nextcloud-appar</string>
     <string name="ecosystem_apps_notes">Nextcloud anteckningar</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">Det gick inte att välja e-postadress.</string>
     <string name="encrypted">Sätt som krypterad</string>
     <string name="end_to_end_encryption_confirm_button">Aktivera kryptering</string>
     <string name="end_to_end_encryption_decrypting">Dekrypterar…</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">Ta bort</string>
     <string name="file_detail_activity_error">Fel vid hämtning av aktiviteter för fil</string>
     <string name="file_details_no_content">Kunde inte läsa in detaljer</string>
-    <string name="file_downloader_notification_title_prefix">Laddar ner \u0020</string>
     <string name="file_icon">Fil</string>
     <string name="file_keep">Behåll</string>
     <string name="file_list_empty">Ladda upp något eller synkronisera med dina enheter</string>

+ 3 - 2
app/src/main/res/values-tr/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">İki sürümü de saklamayı seçerseniz, yerel dosyanın adına bir numara eklenecek.</string>
     <string name="conflict_server_file">Sunucu dosyası</string>
     <string name="contact_backup_title">Kişiler yedeği</string>
+    <string name="contact_no_permission">Kişi izinleri gerekli.</string>
     <string name="contactlist_item_icon">Kişi listesi kullanıcı simgesi</string>
     <string name="contactlist_no_permission">Herhangi bir izin verilmemiş olduğundan hiçbir şey içe aktarılamadı.</string>
     <string name="contacts">Kişiler</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">Diğer Nextcloud uygulamaları</string>
     <string name="ecosystem_apps_notes">Nextcloud Notlar</string>
     <string name="ecosystem_apps_talk">Nextcloud Sohbet</string>
+    <string name="email_pick_failed">E-posta adresi alınamadı.</string>
     <string name="encrypted">Şifrelensin</string>
     <string name="end_to_end_encryption_confirm_button">Şifreleme kurulumu</string>
     <string name="end_to_end_encryption_decrypting">Şifre çözülüyor …</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">Sil</string>
     <string name="file_detail_activity_error">Dosya işlemleri alınırken sorun çıktı</string>
     <string name="file_details_no_content">Ayrıntılar yüklenemedi</string>
-    <string name="file_downloader_notification_title_prefix">İndiriliyor \u0020</string>
     <string name="file_icon">Dosya</string>
     <string name="file_keep">Tut</string>
     <string name="file_list_empty">Bazı içerikler yükleyin ya da aygıtlarınızla eşitleyin.</string>
@@ -712,7 +713,7 @@
     <string name="share_link_optional_password_title">İsteğe bağlı olarak parola yazın</string>
     <string name="share_link_password_title">Bir parola yazın</string>
     <string name="share_link_with_label">Bağlantı paylaş (%1$s)</string>
-    <string name="share_no_expiration_date_label">Son kullanma tarihini ayarla</string>
+    <string name="share_no_expiration_date_label">Geçerlilik sonu tarihini ayarla</string>
     <string name="share_no_password_title">Parolayı ayarla</string>
     <string name="share_password_title">Parola korumalı</string>
     <string name="share_permission_can_edit">Düzenleyebilir</string>

+ 1 - 1
app/src/main/res/values-uk/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">Якщо ви виберете обидві версії, то до назви локального файлу буде додано порядковий номер.</string>
     <string name="conflict_server_file">Файл у хмарі</string>
     <string name="contact_backup_title">Резервне копіювання контактів</string>
+    <string name="contact_no_permission">Потрібний доступ до контактів.</string>
     <string name="contactlist_item_icon">Іконка списку контактів</string>
     <string name="contactlist_no_permission">Не надано дозволів, дані не імпортовано</string>
     <string name="contacts">Контакти</string>
@@ -323,7 +324,6 @@
     <string name="file_delete">Вилучити</string>
     <string name="file_detail_activity_error">Помилка з отриманням дії для файлу</string>
     <string name="file_details_no_content">Не вдалося завантажити подробиці</string>
-    <string name="file_downloader_notification_title_prefix">Звантаження \u0020</string>
     <string name="file_icon">Файл</string>
     <string name="file_keep">Зберегти</string>
     <string name="file_list_empty">Додати дані або синхронізувати з вашими пристроями.</string>

+ 2 - 1
app/src/main/res/values-zh-rCN/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">如果您选择两个版本,则本地文件的名称后面将附加一个数字。</string>
     <string name="conflict_server_file">服务器文件</string>
     <string name="contact_backup_title">联系人备份</string>
+    <string name="contact_no_permission">需要联系人权限</string>
     <string name="contactlist_item_icon">联系人列表的用户图标</string>
     <string name="contactlist_no_permission">未授予权限,没有文件被导入</string>
     <string name="contacts">联系人</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">更多Nextcloud应用</string>
     <string name="ecosystem_apps_notes">Nextcloud 笔记</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">未能选择电子邮箱地址</string>
     <string name="encrypted">设置为加密</string>
     <string name="end_to_end_encryption_confirm_button">设置加密</string>
     <string name="end_to_end_encryption_decrypting">正在解密…</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">删除</string>
     <string name="file_detail_activity_error">获取文件动态时出错</string>
     <string name="file_details_no_content">加载详情失败</string>
-    <string name="file_downloader_notification_title_prefix">下载中 \u0020</string>
     <string name="file_icon">文件</string>
     <string name="file_keep">保留</string>
     <string name="file_list_empty">上传一些内容或与您的设备同步。</string>

+ 5 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -18,6 +18,7 @@
     <string name="actionbar_copy">複製</string>
     <string name="actionbar_mkdir">新資料夾</string>
     <string name="actionbar_move">移動</string>
+    <string name="actionbar_move_or_copy">移動或複製</string>
     <string name="actionbar_open_with">開啟方式</string>
     <string name="actionbar_search">搜尋</string>
     <string name="actionbar_see_details">詳細資料</string>
@@ -159,6 +160,7 @@
     <string name="conflict_message_description">若您同時選擇兩個版本,近端的檔案會在檔名後附加編號。</string>
     <string name="conflict_server_file">伺服器檔案</string>
     <string name="contact_backup_title">聯絡人備份</string>
+    <string name="contact_no_permission">需要聯絡人權限。</string>
     <string name="contactlist_item_icon">聯絡清單的用戶圖示</string>
     <string name="contactlist_no_permission">匯入失敗,權限不足。</string>
     <string name="contacts">通訊錄</string>
@@ -257,6 +259,7 @@
     <string name="ecosystem_apps_more">更多 Nextcloud 應用程式</string>
     <string name="ecosystem_apps_notes">Nextcloud 筆記</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">無法挑選電郵地址。</string>
     <string name="encrypted">設為已加密的</string>
     <string name="end_to_end_encryption_confirm_button">設定加密</string>
     <string name="end_to_end_encryption_decrypting">解密中…</string>
@@ -944,7 +947,9 @@
     <string name="wait_a_moment">請稍候…</string>
     <string name="wait_checking_credentials">檢查儲存的身分驗證</string>
     <string name="wait_for_tmp_copy_from_private_storage">從私有儲存空間複製檔案中</string>
+    <string name="webview_version_check_alert_dialog_message">請更新 Android System WebView 應用程式以進行登入</string>
     <string name="webview_version_check_alert_dialog_positive_button_title">更新</string>
+    <string name="webview_version_check_alert_dialog_title">更新 Android System WebView</string>
     <string name="what_s_new_image">有什麼新圖像?</string>
     <string name="whats_new_skip">略過</string>
     <string name="whats_new_title">新增到 %1$s </string>

+ 2 - 1
app/src/main/res/values-zh-rTW/strings.xml

@@ -160,6 +160,7 @@
     <string name="conflict_message_description">若您同時選擇兩個版本,本機的檔案會在檔名後附加編號。</string>
     <string name="conflict_server_file">伺服器檔案</string>
     <string name="contact_backup_title">聯絡人備份</string>
+    <string name="contact_no_permission">需要聯絡人權限。</string>
     <string name="contactlist_item_icon">聯絡人列表的使用者圖示</string>
     <string name="contactlist_no_permission">匯入失敗,權限不足。</string>
     <string name="contacts">聯絡人</string>
@@ -258,6 +259,7 @@
     <string name="ecosystem_apps_more">更多 Nextcloud 應用程式</string>
     <string name="ecosystem_apps_notes">Nextcloud Notes</string>
     <string name="ecosystem_apps_talk">Nextcloud Talk</string>
+    <string name="email_pick_failed">挑選電子郵件地址失敗。</string>
     <string name="encrypted">設為已加密的</string>
     <string name="end_to_end_encryption_confirm_button">設定加密</string>
     <string name="end_to_end_encryption_decrypting">正在解密……</string>
@@ -325,7 +327,6 @@
     <string name="file_delete">刪除</string>
     <string name="file_detail_activity_error">取得檔案活動時發生錯誤</string>
     <string name="file_details_no_content">載入詳細資訊失敗</string>
-    <string name="file_downloader_notification_title_prefix">正在下載 \u0020</string>
     <string name="file_icon">檔案</string>
     <string name="file_keep">保留</string>
     <string name="file_list_empty">上傳一些內容或與您的裝置同步。</string>

+ 7 - 2
app/src/main/res/values/strings.xml

@@ -129,8 +129,12 @@
     <string name="common_skip">Skip</string>
     <string name="common_copy">Copy</string>
     <string name="about_title">About</string>
+    <string name="remove_local_account">Remove local account</string>
+    <string name="remove_local_account_details">Remove account from device and delete all local files</string>
+    <string name="request_account_deletion">Request account deletion</string>
+    <string name="request_account_deletion_button">Request deletion</string>
+    <string name="request_account_deletion_details">Request permanent deletion of account by service provider</string>
     <string name="delete_account">Remove account</string>
-    <string name="delete_account_warning">Remove account %s and delete all local files?\n\nDeletion cannot be undone.</string>
     <string name="avatar">Avatar</string>
     <string name="active_user">Active user</string>
     <string name="upload_chooser_title">Upload from…</string>
@@ -162,7 +166,6 @@
     <string name="uploads_view_upload_status_fetching_server_version">Fetching server version…</string>
     <string name="uploads_view_later_waiting_to_upload">Waiting to upload</string>
     <string name="uploads_view_group_header" translatable="false">%1$s (%2$d)</string>
-    <string name="file_downloader_notification_title_prefix">Downloading \u0020</string>
     <string name="downloader_download_in_progress_ticker">Downloading…</string>
     <string name="downloader_download_in_progress_content">%1$d%% Downloading %2$s</string>
     <string name="downloader_download_succeeded_ticker">Downloaded</string>
@@ -603,6 +606,7 @@
     <string name="actionbar_calendar_contacts_restore">Restore contacts &amp; calendar</string>
     <string name="contacts_backup_button">Back up now</string>
     <string name="contactlist_no_permission">No permission given, nothing imported.</string>
+    <string name="contact_no_permission">Contact permission is required.</string>
     <string name="restore_backup">Restore backup</string>
     <string name="contacts_preferences_no_file_found">No file found</string>
     <string name="contacts_preferences_something_strange_happened">Could not find your last backup!</string>
@@ -940,6 +944,7 @@
     <string name="link_share_file_drop">File drop (upload only)</string>
     <string name="could_not_retrieve_shares">Could not retrieve shares</string>
     <string name="failed_update_ui">Failed to update UI</string>
+    <string name="email_pick_failed">Failed to pick email address.</string>
     <string name="remote">(remote)</string>
     <string name="set_status">Set status</string>
     <string name="online_status">Online status</string>

+ 1 - 1
build.gradle

@@ -1,6 +1,6 @@
 buildscript {
     ext {
-        androidPluginVersion = '8.1.1'
+        androidPluginVersion = '8.1.4'
         appCompatVersion = '1.6.1'
         jacoco_version = '0.8.10'
         kotlin_version = '1.8.22'

+ 7 - 2
gradle.properties

@@ -9,5 +9,10 @@ android.nonTransitiveRClass=false
 android.nonFinalResIds=false
 #android.debug.obsoleteApi=true
 
-# Minimum max heap space to get reliable builds
-org.gradle.jvmargs=-Xmx1g
+
+# JVM arguments to optimize heap usage, enable heap dump on out-of-memory errors, and set the file encoding
+org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+kotlin.daemon.jvmargs=-Xmx4096m
+org.gradle.caching=true
+org.gradle.parallel=true
+org.gradle.configureondemand=true

+ 1 - 1
scripts/analysis/lint-results.txt

@@ -1,2 +1,2 @@
 DO NOT TOUCH; GENERATED BY DRONE
-      <span class="mdl-layout-title">Lint Report: 75 warnings</span>
+      <span class="mdl-layout-title">Lint Report: 74 warnings</span>

+ 6 - 0
settings.gradle

@@ -8,3 +8,9 @@ include ':appscan'
 //        substitute module('com.github.nextcloud.android-common:ui') using project(':ui')
 //    }
 //}
+
+//includeBuild('../android-library') {
+//    dependencySubstitution {
+//        substitute module('com.github.nextcloud:android-library') using project(':library')
+//    }
+//}

+ 17 - 15
src/generic/fastlane/metadata/android/ro-RO/full_description.txt

@@ -1,17 +1,19 @@
-Platforma de productivitate ce îți oferă ție ontrolul și poate fi găzduită de tine.
-\Caracteristici:
-* Interfață facilă, modernă, complet personalizată in aliniere cu tema serverului tău
-* Încarcă fișiere pe serverul tău Nextcloud
-* Partajează fișierele tale cu alții
-* Păstrează-ți fișierele și folderele preferate sincronizate
-* Căutare în toate folderele de pe serverul tău
-* Încărcare automată a fotografiilor și videoclipurilor făcute cu dispozitivul tău
-* Fii la curent cu toate notificările
-* Suport pentru conturi multiple
-* Acces securizat la datele tale prin amprentă sau PIN
-* Integrare cu DAVx5 (în trecut cunoscut ca DAVdroid) pentru configurarea ușoară a sincronizarii Calendarelor si Contactelor. 
-Te rugăm să anunți orice fel de probleme la https://github.com/nextcloud/android/issues și să discuți despre această aplicație la https://help.nextcloud.com/c/clients/android
+Platfoma locală de productivitate care vă menține în control.
 
-Ești nou la Nextcloud? Nextcloud este un server privat pentru comunicare, sincronizare & și partajare de fișiere. Este în întregime open-source și îl poți găzdui tu, sau poți plăti o companie să facă asta pentru tine. În acest fel, ești pe deplin în control asupra fotografiilor tale, a calendarului și informațiilor de contact, a documentelor și a orice altceva.
+Caracteristici:
+* Interfață simplă, modernă, adaptată temei serverului
+* Încărcați fișiere în serverul Nextcloud
+* Partajați-le cu alții
+* Țineți fișierele și folderele preferate sincronizate
+* Căutați prin toate folderele de pe server
+* Auto Încărcarea fotografiilor și clipurilor video făcute de dispozitivul personal
+* Fiți la curent cu notificările
+* Suport pentru Multi-account
+* Acces sigur la date cu amprentă sau PIN
+* Integrae cu DAVx5 (anterior DAVdroid) pentru setarea simplă a sincronizării calendarului & Contactelor
 
-Află mai multe despre Nextcloud la https://nextcloud.com
+Raportați orice problemă la https://github.com/nextcloud/android/issues și discutați despre această aplicație la https://help.nextcloud.com/c/clients/android
+
+New cu Nextcloud? Nextcloud este un server privat de sincronizare fișiere & partajare și de comunicație. Este un software gratuit și puteți să-l găzduiți sau să plătiți o companie să o facă pentru dumneavoastră. Aveți astfel control asupra fotografiilor, datelor calendarului și despre contacte, documentelor și orice altceva.
+
+Vizitați Nextcloud la https://nextcloud.com

+ 4 - 3
src/versionDev/fastlane/metadata/android/ro-RO/full_description.txt

@@ -1,3 +1,4 @@
-Poți găzdui propriile tale instrumente de productivitate, tu avînd controlul total.
-Aceasta este versiunea oficială ce prezintă o mostră zilnică de funcționalități netestate, ce ar putea cauza instabilități șî pierdere de date. Aplicația este pentru utilizatori ce sunt dispuși să testeze și să raporteze eventualele erori sau probleme de funcționare. Nu folosiți această aplicație pentru muncă productivă!
-]nAmbele versiuni pentru dezvoltatori și versiunea normală sunt disponibile pe F-Droid, și pot fii instalate în același timp.
+Platforma de productivitate locală care vă menține în control.
+Aceasta este versiunea de dezvoltare oficială, cuprinzând exemple zilnice de funcționalități netestate, care pot crea instabilitate sau pierderi de date. Aplicația este pentru utilizatori care doresc să testeze și să raporteze bug-uri dacă acestea apar. Nu folosiți în producție!
+
+ Și versiunea oficială de dezvoltare și cea stabilă sunt disponibile pe F-droid și pot fi instalate în același timp.