Explorar o código

Merge branch 'master' into improve-retry-failed-uploads-function

# Conflicts:
#	app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt
Jonas Mayer hai 1 ano
pai
achega
b724f75bcb
Modificáronse 100 ficheiros con 2344 adicións e 1080 borrados
  1. 1 1
      .devcontainer/Dockerfile
  2. 2 2
      .github/workflows/codeql.yml
  3. 1 1
      .github/workflows/gradle-wrapper-validation.yml
  4. 1 1
      .github/workflows/scorecard.yml
  5. 2 2
      .github/workflows/unit-tests.yml
  6. 19 20
      Gemfile.lock
  7. 7 7
      app/build.gradle
  8. 1209 0
      app/schemas/com.nextcloud.client.database.NextcloudDatabase/81.json
  9. 3 1
      app/src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.java
  10. 1 1
      app/src/androidTest/java/com/nextcloud/client/jobs/BackgroundJobManagerTest.kt
  11. 32 0
      app/src/androidTest/java/com/owncloud/android/EncryptionIT.kt
  12. 1 1
      app/src/androidTest/java/com/owncloud/android/util/EncryptionTestIT.java
  13. 28 2
      app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsIT.kt
  14. 19 2
      app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsV2IT.kt
  15. 4 2
      app/src/androidTest/java/com/owncloud/android/utils/SyncedFolderUtilsTest.kt
  16. 2 2
      app/src/main/java/com/nextcloud/client/assistant/AsssistantScreen.kt
  17. 5 0
      app/src/main/java/com/nextcloud/client/assistant/extensions/TaskExtensions.kt
  18. 60 11
      app/src/main/java/com/nextcloud/client/assistant/repository/AssistantMockRepository.kt
  19. 58 0
      app/src/main/java/com/nextcloud/client/assistant/task/TaskStatus.kt
  20. 17 63
      app/src/main/java/com/nextcloud/client/assistant/task/TaskView.kt
  21. 165 0
      app/src/main/java/com/nextcloud/client/assistant/taskDetail/TaskDetailBottomSheet.kt
  22. 1 1
      app/src/main/java/com/nextcloud/client/assistant/taskTypes/TaskTypesRow.kt
  23. 2 1
      app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt
  24. 4 2
      app/src/main/java/com/nextcloud/client/database/entity/SyncedFolderEntity.kt
  25. 1 1
      app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt
  26. 2 0
      app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt
  27. 6 8
      app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt
  28. 4 0
      app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt
  29. 21 20
      app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt
  30. 10 8
      app/src/main/java/com/nextcloud/client/jobs/upload/UploadNotificationManager.kt
  31. 7 10
      app/src/main/java/com/nextcloud/ui/composeActivity/ComposeActivity.kt
  32. 17 0
      app/src/main/java/com/nextcloud/utils/extensions/StringExtensions.kt
  33. 1 1
      app/src/main/java/com/owncloud/android/MainApp.java
  34. 88 0
      app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
  35. 2 1
      app/src/main/java/com/owncloud/android/datamodel/FilesystemDataProvider.java
  36. 13 3
      app/src/main/java/com/owncloud/android/datamodel/SyncedFolder.java
  37. 8 4
      app/src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java
  38. 7 4
      app/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java
  39. 3 2
      app/src/main/java/com/owncloud/android/db/ProviderMeta.java
  40. 119 96
      app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java
  41. 10 6
      app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
  42. 12 6
      app/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.kt
  43. 75 40
      app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
  44. 12 7
      app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java
  45. 10 5
      app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt
  46. 17 1
      app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java
  47. 12 2
      app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java
  48. 11 8
      app/src/main/java/com/owncloud/android/utils/DrawerMenuUtil.java
  49. 6 6
      app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java
  50. 11 0
      app/src/main/java/com/owncloud/android/utils/FileStorageUtils.java
  51. 83 43
      app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java
  52. 0 15
      app/src/main/res/drawable/ic_expand_less.xml
  53. 36 0
      app/src/main/res/layout/toolbar_standard.xml
  54. 3 2
      app/src/main/res/values-ar/strings.xml
  55. 4 2
      app/src/main/res/values-b+en+001/strings.xml
  56. 0 2
      app/src/main/res/values-bg-rBG/strings.xml
  57. 0 2
      app/src/main/res/values-br/strings.xml
  58. 0 2
      app/src/main/res/values-ca/strings.xml
  59. 1 2
      app/src/main/res/values-cs-rCZ/strings.xml
  60. 7 2
      app/src/main/res/values-da/strings.xml
  61. 3 2
      app/src/main/res/values-de/strings.xml
  62. 0 2
      app/src/main/res/values-el/strings.xml
  63. 0 1
      app/src/main/res/values-eo/strings.xml
  64. 0 2
      app/src/main/res/values-es-rAR/strings.xml
  65. 0 1
      app/src/main/res/values-es-rCL/strings.xml
  66. 0 1
      app/src/main/res/values-es-rCO/strings.xml
  67. 0 1
      app/src/main/res/values-es-rCR/strings.xml
  68. 0 1
      app/src/main/res/values-es-rDO/strings.xml
  69. 0 2
      app/src/main/res/values-es-rEC/strings.xml
  70. 0 1
      app/src/main/res/values-es-rGT/strings.xml
  71. 0 2
      app/src/main/res/values-es-rMX/strings.xml
  72. 0 1
      app/src/main/res/values-es-rSV/strings.xml
  73. 2 2
      app/src/main/res/values-es/strings.xml
  74. 0 2
      app/src/main/res/values-et-rEE/strings.xml
  75. 2 2
      app/src/main/res/values-eu/strings.xml
  76. 0 2
      app/src/main/res/values-fa/strings.xml
  77. 0 2
      app/src/main/res/values-fi-rFI/strings.xml
  78. 69 71
      app/src/main/res/values-fr/strings.xml
  79. 0 2
      app/src/main/res/values-gd/strings.xml
  80. 1 2
      app/src/main/res/values-gl/strings.xml
  81. 0 2
      app/src/main/res/values-hr/strings.xml
  82. 0 2
      app/src/main/res/values-hu-rHU/strings.xml
  83. 0 2
      app/src/main/res/values-in/strings.xml
  84. 0 2
      app/src/main/res/values-is/strings.xml
  85. 0 2
      app/src/main/res/values-it/strings.xml
  86. 0 2
      app/src/main/res/values-iw/strings.xml
  87. 0 2
      app/src/main/res/values-ja-rJP/strings.xml
  88. 0 506
      app/src/main/res/values-ka-rGE/strings.xml
  89. 0 2
      app/src/main/res/values-ka/strings.xml
  90. 0 2
      app/src/main/res/values-ko/strings.xml
  91. 0 2
      app/src/main/res/values-lo/strings.xml
  92. 0 2
      app/src/main/res/values-lt-rLT/strings.xml
  93. 0 2
      app/src/main/res/values-lv/strings.xml
  94. 0 2
      app/src/main/res/values-mk/strings.xml
  95. 2 2
      app/src/main/res/values-nb-rNO/strings.xml
  96. 0 2
      app/src/main/res/values-nl/strings.xml
  97. 0 2
      app/src/main/res/values-pl/strings.xml
  98. 2 2
      app/src/main/res/values-pt-rBR/strings.xml
  99. 0 2
      app/src/main/res/values-pt-rPT/strings.xml
  100. 0 2
      app/src/main/res/values-ro/strings.xml

+ 1 - 1
.devcontainer/Dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:jammy@sha256:77906da86b60585ce12215807090eb327e7386c8fafb5402369e421f44eff17e
+FROM ubuntu:jammy@sha256:1b8d8ff4777f36f19bfe73ee4df61e3a0b789caeff29caa019539ec7c9a57f95
 
 ARG DEBIAN_FRONTEND=noninteractive
 ENV ANDROID_HOME=/usr/lib/android-sdk

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

@@ -39,7 +39,7 @@ jobs:
         with:
           swap-size-gb: 10
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
+        uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
         with:
           languages: ${{ matrix.language }}
       - name: Set up JDK 17
@@ -53,4 +53,4 @@ jobs:
           echo "org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
           ./gradlew assembleDebug
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
+        uses: github/codeql-action/analyze@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1

+ 1 - 1
.github/workflows/gradle-wrapper-validation.yml

@@ -26,4 +26,4 @@ jobs:
         runs-on: ubuntu-latest
         steps:
             - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
-            - uses: gradle/wrapper-validation-action@b5418f5a58f5fd2eb486dd7efb368fe7be7eae45 # v2.1.3
+            - uses: gradle/wrapper-validation-action@460a3ca55fc5d559238a0efc7fa9f7465df8585d # v3.3.0

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

@@ -42,6 +42,6 @@ jobs:
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
+        uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
         with:
           sarif_file: results.sarif

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

@@ -33,7 +33,7 @@ jobs:
                 if: ${{ always() }}
                 run: scripts/deleteOldComments.sh "test" "Unit" ${{github.event.number}}
             -   name: Run unit tests with coverage
-                uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e # v3.1.0
+                uses: gradle/gradle-build-action@8baac4c8ef753599f92eeb509c246d09d6250fa6 # v3.3.0
                 with:
                     arguments: jacocoTestGplayDebugUnitTest
             -   name: Upload failing results
@@ -42,7 +42,7 @@ jobs:
                     GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
                 run: scripts/uploadReport.sh "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" ${{github.event.number}} "test" "Unit" ${{github.event.number}}
             -   name: Upload coverage to codecov
-                uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1
+                uses: codecov/codecov-action@84508663e988701840491b86de86b666e8a86bed # v4.3.0
                 with:
                     token: ${{ secrets.CODECOV_TOKEN }}
                     flags: unit

+ 19 - 20
Gemfile.lock

@@ -7,20 +7,19 @@ GEM
       rexml
     addressable (2.8.6)
       public_suffix (>= 2.0.2, < 6.0)
-    artifactory (3.0.15)
+    artifactory (3.0.17)
     atomos (0.1.3)
     aws-eventstream (1.3.0)
-    aws-partitions (1.894.0)
-    aws-sdk-core (3.191.2)
+    aws-partitions (1.913.0)
+    aws-sdk-core (3.191.6)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-partitions (~> 1, >= 1.651.0)
       aws-sigv4 (~> 1.8)
-      base64
       jmespath (~> 1, >= 1.6.1)
-    aws-sdk-kms (1.77.0)
+    aws-sdk-kms (1.78.0)
       aws-sdk-core (~> 3, >= 3.191.0)
       aws-sigv4 (~> 1.1)
-    aws-sdk-s3 (1.143.0)
+    aws-sdk-s3 (1.146.1)
       aws-sdk-core (~> 3, >= 3.191.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.8)
@@ -40,7 +39,7 @@ GEM
     domain_name (0.6.20240107)
     dotenv (2.8.1)
     emoji_regex (3.2.3)
-    excon (0.109.0)
+    excon (0.110.0)
     faraday (1.10.3)
       faraday-em_http (~> 1.0)
       faraday-em_synchrony (~> 1.0)
@@ -69,15 +68,15 @@ GEM
     faraday-retry (1.0.3)
     faraday_middleware (1.2.0)
       faraday (~> 1.0)
-    fastimage (2.3.0)
-    fastlane (2.219.0)
+    fastimage (2.3.1)
+    fastlane (2.220.0)
       CFPropertyList (>= 2.3, < 4.0.0)
       addressable (>= 2.8, < 3.0.0)
       artifactory (~> 3.0)
       aws-sdk-s3 (~> 1.0)
       babosa (>= 1.0.3, < 2.0.0)
       bundler (>= 1.12.0, < 3.0.0)
-      colored
+      colored (~> 1.2)
       commander (~> 4.6)
       dotenv (>= 2.1.1, < 3.0.0)
       emoji_regex (>= 0.1, < 4.0)
@@ -98,10 +97,10 @@ GEM
       mini_magick (>= 4.9.4, < 5.0.0)
       multipart-post (>= 2.0.0, < 3.0.0)
       naturally (~> 2.2)
-      optparse (>= 0.1.1)
+      optparse (>= 0.1.1, < 1.0.0)
       plist (>= 3.1.0, < 4.0.0)
       rubyzip (>= 2.0.0, < 3.0.0)
-      security (= 0.1.3)
+      security (= 0.1.5)
       simctl (~> 1.6.3)
       terminal-notifier (>= 2.0.0, < 3.0.0)
       terminal-table (~> 3)
@@ -110,7 +109,7 @@ GEM
       word_wrap (~> 1.0.0)
       xcodeproj (>= 1.13.0, < 2.0.0)
       xcpretty (~> 0.3.0)
-      xcpretty-travis-formatter (>= 0.0.3)
+      xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
     fastlane-plugin-huawei_appgallery_connect (1.0.28)
       cgi
     gh_inspector (1.1.3)
@@ -130,12 +129,12 @@ GEM
       google-apis-core (>= 0.11.0, < 2.a)
     google-apis-storage_v1 (0.31.0)
       google-apis-core (>= 0.11.0, < 2.a)
-    google-cloud-core (1.6.1)
+    google-cloud-core (1.7.0)
       google-cloud-env (>= 1.0, < 3.a)
       google-cloud-errors (~> 1.0)
     google-cloud-env (1.6.0)
       faraday (>= 0.17.3, < 3.0)
-    google-cloud-errors (1.3.1)
+    google-cloud-errors (1.4.0)
     google-cloud-storage (1.47.0)
       addressable (~> 2.8)
       digest-crc (~> 0.4)
@@ -155,8 +154,8 @@ GEM
       domain_name (~> 0.5)
     httpclient (2.8.3)
     jmespath (1.6.2)
-    json (2.7.1)
-    jwt (2.8.0)
+    json (2.7.2)
+    jwt (2.8.1)
       base64
     mini_magick (4.12.0)
     mini_mime (1.1.5)
@@ -168,8 +167,8 @@ GEM
     optparse (0.4.0)
     os (1.1.4)
     plist (3.7.1)
-    public_suffix (5.0.4)
-    rake (13.1.0)
+    public_suffix (5.0.5)
+    rake (13.2.1)
     representable (3.2.0)
       declarative (< 0.1.0)
       trailblazer-option (>= 0.1.1, < 0.2.0)
@@ -179,7 +178,7 @@ GEM
     rouge (2.0.7)
     ruby2_keywords (0.0.5)
     rubyzip (2.3.2)
-    security (0.1.3)
+    security (0.1.5)
     signet (0.19.0)
       addressable (~> 2.8)
       faraday (>= 0.17.5, < 3.a)

+ 7 - 7
app/build.gradle

@@ -16,7 +16,7 @@ import org.gradle.internal.jvm.Jvm
 buildscript {
     dependencies {
         classpath "com.android.tools.build:gradle:$androidPluginVersion"
-        classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:6.0.9'
+        classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:6.0.12'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
         classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.6"
         classpath "commons-httpclient:commons-httpclient:3.1@jar" // remove after entire switch to lib v2
@@ -29,7 +29,7 @@ buildscript {
 
 plugins {
     id "com.diffplug.spotless" version "6.20.0"
-    id 'com.google.devtools.ksp' version '1.9.23-1.0.19' apply false
+    id 'com.google.devtools.ksp' version '1.9.23-1.0.20' apply false
 }
 
 apply plugin: 'com.android.application'
@@ -77,7 +77,7 @@ configurations.configureEach {
 
 // semantic versioning for version code
 def versionMajor = 3
-def versionMinor = 29
+def versionMinor = 30
 def versionPatch = 0
 def versionBuild = 0 // 0-50=Alpha / 51-98=RC / 90-99=stable
 
@@ -259,7 +259,7 @@ android {
     }
 
     composeOptions {
-        kotlinCompilerExtensionVersion = "1.5.11"
+        kotlinCompilerExtensionVersion = "1.5.12"
     }
 }
 
@@ -271,11 +271,11 @@ dependencies {
     }
 
     // Jetpack Compose
-    implementation(platform("androidx.compose:compose-bom:2024.04.00"))
+    implementation(platform("androidx.compose:compose-bom:2024.04.01"))
     implementation("androidx.compose.ui:ui")
     implementation("androidx.compose.ui:ui-graphics")
     implementation("androidx.compose.material3:material3")
-    implementation("androidx.compose.ui:ui-tooling-preview:1.6.5")
+    implementation("androidx.compose.ui:ui-tooling-preview:1.6.6")
     debugImplementation 'androidx.compose.ui:ui-tooling:1.6.5'
 
     compileOnly 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
@@ -296,7 +296,7 @@ dependencies {
     implementation "androidx.fragment:fragment-ktx:1.6.2"
     implementation 'com.github.albfernandez:juniversalchardet:2.0.3' // need this version for Android <7
     compileOnly 'com.google.code.findbugs:annotations:3.0.1u2'
-    implementation 'commons-io:commons-io:2.16.0'
+    implementation 'commons-io:commons-io:2.16.1'
     implementation 'org.greenrobot:eventbus:3.3.1'
     implementation 'com.googlecode.ez-vcard:ez-vcard:0.12.1'
     implementation 'org.lukhnos:nnio:0.3'

+ 1209 - 0
app/schemas/com.nextcloud.client.database.NextcloudDatabase/81.json

@@ -0,0 +1,1209 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 81,
+    "identityHash": "082a63031678a67879428f688f02d3b5",
+    "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, `assistant` INTEGER, `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, `end_to_end_encryption_api_version` TEXT, `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, `security_guard` INTEGER)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "_id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "assistant",
+            "columnName": "assistant",
+            "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": "endToEndEncryptionApiVersion",
+            "columnName": "end_to_end_encryption_api_version",
+            "affinity": "TEXT",
+            "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
+          },
+          {
+            "fieldPath": "securityGuard",
+            "columnName": "security_guard",
+            "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, `hidden` 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, `metadata_live_photo` 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, `e2e_counter` INTEGER)",
+        "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": "hidden",
+            "columnName": "hidden",
+            "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": "metadataLivePhoto",
+            "columnName": "metadata_live_photo",
+            "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
+          },
+          {
+            "fieldPath": "e2eCounter",
+            "columnName": "e2e_counter",
+            "affinity": "INTEGER",
+            "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` TEXT, `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": "TEXT",
+            "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, `exclude_hidden` INTEGER, `last_scan_timestamp_ms` 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
+          },
+          {
+            "fieldPath": "excludeHidden",
+            "columnName": "exclude_hidden",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "lastScanTimestampMs",
+            "columnName": "last_scan_timestamp_ms",
+            "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, '082a63031678a67879428f688f02d3b5')"
+    ]
+  }
+}

+ 3 - 1
app/src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.java

@@ -14,6 +14,7 @@ import com.nextcloud.client.preferences.SubFolderRule;
 import com.owncloud.android.AbstractIT;
 import com.owncloud.android.databinding.SyncedFoldersLayoutBinding;
 import com.owncloud.android.datamodel.MediaFolderType;
+import com.owncloud.android.datamodel.SyncedFolder;
 import com.owncloud.android.datamodel.SyncedFolderDisplayItem;
 import com.owncloud.android.ui.activity.SyncedFoldersActivity;
 import com.owncloud.android.ui.dialog.SyncedFolderPreferencesDialogFragment;
@@ -63,7 +64,8 @@ public class SyncedFoldersActivityIT extends AbstractIT {
                                                                    MediaFolderType.IMAGE,
                                                                    false,
                                                                    SubFolderRule.YEAR_MONTH,
-                                                                   false);
+                                                                   false,
+                                                                   SyncedFolder.NOT_SCANNED_YET);
         SyncedFolderPreferencesDialogFragment sut = SyncedFolderPreferencesDialogFragment.newInstance(item, 0);
 
         Intent intent = new Intent(targetContext, SyncedFoldersActivity.class);

+ 1 - 1
app/src/androidTest/java/com/nextcloud/client/jobs/BackgroundJobManagerTest.kt

@@ -201,7 +201,7 @@ class BackgroundJobManagerTest {
         fun job_is_unique_and_replaces_previous_job() {
             verify(workManager).enqueueUniqueWork(
                 eq(BackgroundJobManagerImpl.JOB_CONTENT_OBSERVER),
-                eq(ExistingWorkPolicy.APPEND),
+                eq(ExistingWorkPolicy.REPLACE),
                 argThat(IsOneTimeWorkRequest())
             )
         }

+ 32 - 0
app/src/androidTest/java/com/owncloud/android/EncryptionIT.kt

@@ -0,0 +1,32 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.owncloud.android
+
+import com.owncloud.android.datamodel.OCFile
+import java.security.SecureRandom
+
+open class EncryptionIT : AbstractIT() {
+
+    fun testFolder(): OCFile {
+        val rootPath = "/"
+        val folderPath = "/TestFolder/"
+
+        OCFile(rootPath).apply {
+            storageManager.saveFile(this)
+        }
+
+        return OCFile(folderPath).apply {
+            decryptedRemotePath = folderPath
+            isEncrypted = true
+            fileLength = SecureRandom().nextLong()
+            setFolder()
+            parentId = storageManager.getFileByDecryptedRemotePath(rootPath)!!.fileId
+            storageManager.saveFile(this)
+        }
+    }
+}

+ 1 - 1
app/src/androidTest/java/com/owncloud/android/util/EncryptionTestIT.java

@@ -836,7 +836,7 @@ public class EncryptionTestIT extends AbstractIT {
 
         // Encryption
         Cipher encryptorCipher = EncryptionUtils.getCipher(Cipher.ENCRYPT_MODE, key, iv);
-        EncryptionUtils.encryptFile(file, encryptorCipher);
+        EncryptionUtils.encryptFile(user.getAccountName(), file, encryptorCipher);
         String encryptorCipherAuthTag = EncryptionUtils.getAuthenticationTag(encryptorCipher);
 
         // Decryption

+ 28 - 2
app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsIT.kt

@@ -7,13 +7,18 @@
  */
 package com.owncloud.android.utils
 
-import com.owncloud.android.AbstractIT
+import com.owncloud.android.EncryptionIT
 import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
+import com.owncloud.android.datamodel.e2e.v1.decrypted.Data
+import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFile
+import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1
+import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedMetadata
 import com.owncloud.android.lib.resources.e2ee.CsrHelper
+import com.owncloud.android.operations.RefreshFolderOperation
 import org.junit.Assert.assertEquals
 import org.junit.Test
 
-class EncryptionUtilsIT : AbstractIT() {
+class EncryptionUtilsIT : EncryptionIT() {
     @Throws(
         java.security.NoSuchAlgorithmException::class,
         java.io.IOException::class,
@@ -30,4 +35,25 @@ class EncryptionUtilsIT : AbstractIT() {
 
         assertEquals(key, EncryptionUtils.getPublicKey(user, e2eUser, arbitraryDataProvider))
     }
+
+    @Test
+    @Throws(Exception::class)
+    fun testUpdateFileNameForEncryptedFileV1() {
+        val folder = testFolder()
+
+        val decryptedFilename = "image.png"
+        val mockEncryptedFilename = "encrypted_file_name.png"
+
+        val decryptedMetadata = DecryptedMetadata()
+        val filesData = DecryptedFile().apply {
+            encrypted = Data().apply {
+                filename = decryptedFilename
+            }
+        }
+        val files = mapOf(mockEncryptedFilename to filesData)
+        val metadata = DecryptedFolderMetadataFileV1(decryptedMetadata, files)
+
+        RefreshFolderOperation.updateFileNameForEncryptedFileV1(storageManager, metadata, folder)
+        assertEquals(folder.decryptedRemotePath.contains("null"), false)
+    }
 }

+ 19 - 2
app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsV2IT.kt

@@ -10,7 +10,7 @@ package com.owncloud.android.utils
 import com.google.gson.reflect.TypeToken
 import com.nextcloud.client.account.MockUser
 import com.nextcloud.common.User
-import com.owncloud.android.AbstractIT
+import com.owncloud.android.EncryptionIT
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.datamodel.e2e.v1.decrypted.Data
 import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1
@@ -21,13 +21,15 @@ import com.owncloud.android.datamodel.e2e.v2.decrypted.DecryptedUser
 import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFiledrop
 import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFiledropUser
 import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFolderMetadataFile
+import com.owncloud.android.operations.RefreshFolderOperation
 import com.owncloud.android.util.EncryptionTestIT
 import junit.framework.TestCase.assertEquals
 import junit.framework.TestCase.assertTrue
 import org.junit.Assert.assertNotEquals
 import org.junit.Test
 
-class EncryptionUtilsV2IT : AbstractIT() {
+@Suppress("TooManyFunctions", "LargeClass")
+class EncryptionUtilsV2IT : EncryptionIT() {
     private val encryptionTestUtils = EncryptionTestUtils()
     private val encryptionUtilsV2 = EncryptionUtilsV2()
 
@@ -781,6 +783,21 @@ class EncryptionUtilsV2IT : AbstractIT() {
         assertTrue(encryptionUtilsV2.verifySignedMessage(base64Ans, jsonBase64, certs))
     }
 
+    @Test
+    @Throws(Exception::class)
+    fun testUpdateFileNameForEncryptedFile() {
+        val folder = testFolder()
+
+        val metadata = EncryptionTestUtils().generateFolderMetadataV2(
+            client.userId,
+            EncryptionTestIT.publicKey
+        )
+
+        RefreshFolderOperation.updateFileNameForEncryptedFile(storageManager, metadata, folder)
+
+        assertEquals(folder.decryptedRemotePath.contains("null"), false)
+    }
+
     /**
      * DecryptedFolderMetadata -> EncryptedFolderMetadata -> JSON -> encrypt -> decrypt -> JSON ->
      * EncryptedFolderMetadata -> DecryptedFolderMetadata

+ 4 - 2
app/src/androidTest/java/com/owncloud/android/utils/SyncedFolderUtilsTest.kt

@@ -174,7 +174,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
             MediaFolderType.IMAGE,
             false,
             SubFolderRule.YEAR_MONTH,
-            false
+            false,
+            SyncedFolder.NOT_SCANNED_YET
         )
         Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
     }
@@ -198,7 +199,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
             MediaFolderType.IMAGE,
             false,
             SubFolderRule.YEAR_MONTH,
-            false
+            false,
+            SyncedFolder.NOT_SCANNED_YET
         )
         Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
     }

+ 2 - 2
app/src/main/java/com/nextcloud/client/assistant/AsssistantScreen.kt

@@ -42,8 +42,8 @@ import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.nextcloud.client.assistant.component.AddTaskAlertDialog
 import com.nextcloud.client.assistant.component.CenterText
-import com.nextcloud.client.assistant.component.TaskTypesRow
-import com.nextcloud.client.assistant.component.TaskView
+import com.nextcloud.client.assistant.taskTypes.TaskTypesRow
+import com.nextcloud.client.assistant.task.TaskView
 import com.nextcloud.client.assistant.repository.AssistantMockRepository
 import com.nextcloud.ui.composeActivity.ComposeActivity
 import com.nextcloud.ui.composeComponents.alertDialog.SimpleAlertDialog

+ 5 - 0
app/src/main/java/com/nextcloud/client/assistant/extensions/TaskExtensions.kt

@@ -35,3 +35,8 @@ fun Task.statusData(): Pair<Int, Int> {
         }
     }
 }
+
+// TODO add
+fun Task.completionDateRepresentation(): String {
+    return completionExpectedAt ?: "TODO IMPLEMENT IT"
+}

+ 60 - 11
app/src/main/java/com/nextcloud/client/assistant/repository/AssistantMockRepository.kt

@@ -7,12 +7,14 @@
  */
 package com.nextcloud.client.assistant.repository
 
+import com.nextcloud.utils.extensions.getRandomString
 import com.owncloud.android.lib.common.operations.RemoteOperationResult
 import com.owncloud.android.lib.resources.assistant.model.Task
 import com.owncloud.android.lib.resources.assistant.model.TaskList
 import com.owncloud.android.lib.resources.assistant.model.TaskType
 import com.owncloud.android.lib.resources.assistant.model.TaskTypes
 
+@Suppress("MagicNumber")
 class AssistantMockRepository(private val giveEmptyTasks: Boolean = false) : AssistantRepositoryType {
     override fun getTaskTypes(): RemoteOperationResult<TaskTypes> {
         return RemoteOperationResult<TaskTypes>(RemoteOperationResult.ResultCode.OK).apply {
@@ -41,16 +43,8 @@ class AssistantMockRepository(private val giveEmptyTasks: Boolean = false) : Ass
                         null,
                         "12",
                         "",
-                        "Give me some text",
-                        "Lorem Ipsum is simply dummy text of the printing and typesetting industry. " +
-                            "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s," +
-                            " when an unknown printer took a galley of type and scrambled it to make a type" +
-                            " specimen book. It has survived not only five centuries, " +
-                            "but also the leap into electronic typesetting, remaining essentially unchanged." +
-                            " It was popularised in the 1960s with the release of Letraset sheets containing " +
-                            "Lorem Ipsum passages, and more recently with desktop publishing software like Aldus" +
-                            " PageMaker including versions of Lorem Ipsum",
-                        "",
+                        "Give me some long text 1",
+                        "Lorem ipsum".getRandomString(100),
                         ""
                     ),
                     Task(
@@ -60,7 +54,62 @@ class AssistantMockRepository(private val giveEmptyTasks: Boolean = false) : Ass
                         "12",
                         "",
                         "Give me some text 2",
-                        "Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
+                        "Lorem".getRandomString(100),
+                        "",
+                        ""
+                    ),
+                    Task(
+                        3,
+                        "FreePrompt",
+                        null,
+                        "12",
+                        "",
+                        "Give me some text 3",
+                        "Lorem".getRandomString(300),
+                        "",
+                        ""
+                    ),
+                    Task(
+                        4,
+                        "FreePrompt",
+                        null,
+                        "12",
+                        "",
+                        "Give me some text 4",
+                        "Lorem".getRandomString(300),
+                        "",
+                        ""
+                    ),
+                    Task(
+                        5,
+                        "FreePrompt",
+                        null,
+                        "12",
+                        "",
+                        "Give me some text 5",
+                        "Lorem".getRandomString(300),
+                        "",
+                        ""
+                    ),
+                    Task(
+                        6,
+                        "FreePrompt",
+                        null,
+                        "12",
+                        "",
+                        "Give me some text 6",
+                        "Lorem".getRandomString(300),
+                        "",
+                        ""
+                    ),
+                    Task(
+                        7,
+                        "FreePrompt",
+                        null,
+                        "12",
+                        "",
+                        "Give me some text 7",
+                        "Lorem".getRandomString(300),
                         "",
                         ""
                     )

+ 58 - 0
app/src/main/java/com/nextcloud/client/assistant/task/TaskStatus.kt

@@ -0,0 +1,58 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.nextcloud.client.assistant.task
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.nextcloud.client.assistant.extensions.statusData
+import com.owncloud.android.lib.resources.assistant.model.Task
+
+@Composable
+fun TaskStatus(task: Task, foregroundColor: Color) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(vertical = 16.dp),
+        verticalAlignment = Alignment.CenterVertically
+    ) {
+        val (iconId, descriptionId) = task.statusData()
+
+        Image(
+            painter = painterResource(id = iconId),
+            modifier = Modifier.size(16.dp),
+            colorFilter = ColorFilter.tint(foregroundColor),
+            contentDescription = "status icon"
+        )
+
+        Spacer(modifier = Modifier.width(6.dp))
+
+        Text(text = stringResource(id = descriptionId), color = foregroundColor)
+
+        /*
+        Spacer(modifier = Modifier.weight(1f))
+
+        Text(text = task.completionDateRepresentation(), color = foregroundColor)
+
+        Spacer(modifier = Modifier.width(6.dp))
+         */
+    }
+}

+ 17 - 63
app/src/main/java/com/nextcloud/client/assistant/component/TaskView.kt → app/src/main/java/com/nextcloud/client/assistant/task/TaskView.kt

@@ -1,27 +1,22 @@
 /*
  * Nextcloud - Android Client
  *
- * SPDX-FileCopyrightText: 2024 Alper Ozturk <alper_ozturk@proton.me>
- * SPDX-FileCopyrightText: 2024 Nextcloud GmbH
+ * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
-package com.nextcloud.client.assistant.component
+package com.nextcloud.client.assistant.task
 
 import androidx.compose.animation.animateContentSize
 import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.spring
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.HorizontalDivider
 import androidx.compose.material3.MaterialTheme
@@ -31,18 +26,15 @@ import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ColorFilter
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import com.nextcloud.client.assistant.extensions.statusData
+import com.nextcloud.client.assistant.taskDetail.TaskDetailBottomSheet
 import com.nextcloud.ui.composeComponents.bottomSheet.MoreActionsBottomSheet
+import com.nextcloud.utils.extensions.getRandomString
 import com.owncloud.android.R
 import com.owncloud.android.lib.resources.assistant.model.Task
 
@@ -53,7 +45,7 @@ fun TaskView(
     task: Task,
     showDeleteTaskAlertDialog: (Long) -> Unit
 ) {
-    var expanded by remember { mutableStateOf(false) }
+    var showTaskDetailBottomSheet by remember { mutableStateOf(false) }
     var showMoreActionsBottomSheet by remember { mutableStateOf(false) }
 
     Column(
@@ -62,7 +54,7 @@ fun TaskView(
             .clip(RoundedCornerShape(16.dp))
             .background(MaterialTheme.colorScheme.primary)
             .combinedClickable(onClick = {
-                expanded = !expanded
+                showTaskDetailBottomSheet = true
             }, onLongClick = {
                 showMoreActionsBottomSheet = true
             })
@@ -84,10 +76,11 @@ fun TaskView(
             HorizontalDivider(modifier = Modifier.padding(horizontal = 4.dp, vertical = 8.dp))
 
             Text(
-                text = if (expanded) it else it.take(100) + "...",
+                text = it.take(100),
                 fontSize = 12.sp,
                 color = Color.White,
                 modifier = Modifier
+                    .height(100.dp)
                     .animateContentSize(
                         animationSpec = spring(
                             dampingRatio = Spring.DampingRatioLowBouncy,
@@ -97,39 +90,7 @@ fun TaskView(
             )
         }
 
-        Row(
-            modifier = Modifier
-                .fillMaxWidth()
-                .padding(vertical = 16.dp),
-            verticalAlignment = Alignment.CenterVertically
-        ) {
-            val (iconId, descriptionId) = task.statusData()
-
-            Image(
-                painter = painterResource(id = iconId),
-                modifier = Modifier.size(16.dp),
-                colorFilter = ColorFilter.tint(Color.White),
-                contentDescription = "status icon"
-            )
-
-            Spacer(modifier = Modifier.width(6.dp))
-
-            Text(text = stringResource(id = descriptionId), color = Color.White)
-
-            Spacer(modifier = Modifier.weight(1f))
-
-            if ((task.output?.length ?: 0) >= 100) {
-                Image(
-                    painter = painterResource(
-                        id = if (!expanded) R.drawable.ic_expand_more else R.drawable.ic_expand_less
-                    ),
-                    contentDescription = "expand content icon",
-                    colorFilter = ColorFilter.tint(Color.White)
-                )
-            }
-
-            Spacer(modifier = Modifier.width(8.dp))
-        }
+        TaskStatus(task, foregroundColor = Color.White)
 
         if (showMoreActionsBottomSheet) {
             val bottomSheetAction = listOf(
@@ -147,27 +108,20 @@ fun TaskView(
                 dismiss = { showMoreActionsBottomSheet = false }
             )
         }
+
+        if (showTaskDetailBottomSheet) {
+            TaskDetailBottomSheet(task) {
+                showTaskDetailBottomSheet = false
+            }
+        }
     }
 }
 
+@Suppress("MagicNumber")
 @Preview
 @Composable
 private fun TaskViewPreview() {
-    val output =
-        "Lorem Ipsum is simply dummy text of the printing and " +
-            "typesetting industry. Lorem Ipsum has been the " +
-            "industry's standard dummy text ever since the 1500s, " +
-            "when an unknown printer took a galley of type and " +
-            "scrambled it to make a type specimen book. " +
-            "It has survived not only five centuries, but also " +
-            "the leap into electronic typesetting, remaining" +
-            " essentially unchanged. It wLorem Ipsum is simply dummy" +
-            " text of the printing and typesetting industry. " +
-            "Lorem Ipsum has been the industry's standard dummy " +
-            "text ever since the 1500s, when an unknown printer took a" +
-            " galley of type and scrambled it to make a type specimen book. " +
-            "It has survived not only five centuries, but also the leap " +
-            "into electronic typesetting, remaining essentially unchanged."
+    val output = "Lorem".getRandomString(100)
 
     TaskView(
         task = Task(

+ 165 - 0
app/src/main/java/com/nextcloud/client/assistant/taskDetail/TaskDetailBottomSheet.kt

@@ -0,0 +1,165 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.nextcloud.client.assistant.taskDetail
+
+import androidx.compose.animation.animateContentSize
+import androidx.compose.animation.core.Spring
+import androidx.compose.animation.core.spring
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.widthIn
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.nextcloud.client.assistant.task.TaskStatus
+import com.nextcloud.utils.extensions.getRandomString
+import com.owncloud.android.R
+import com.owncloud.android.lib.resources.assistant.model.Task
+
+@Suppress("LongMethod")
+@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
+@Composable
+fun TaskDetailBottomSheet(task: Task, dismiss: () -> Unit) {
+    var showInput by remember { mutableStateOf(true) }
+    val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+
+    ModalBottomSheet(
+        modifier = Modifier.padding(top = 32.dp),
+        containerColor = Color.White,
+        onDismissRequest = {
+            dismiss()
+        },
+        sheetState = sheetState
+    ) {
+        LazyColumn(
+            modifier = Modifier
+                .fillMaxSize()
+                .padding(16.dp)
+        ) {
+            stickyHeader {
+                Row(
+                    modifier = Modifier
+                        .fillMaxWidth()
+                        .background(color = colorResource(id = R.color.light_grey), shape = RoundedCornerShape(8.dp))
+                ) {
+                    TextInputSelectButton(
+                        Modifier.weight(1f),
+                        R.string.assistant_task_detail_screen_input_button_title,
+                        showInput,
+                        onClick = {
+                            showInput = true
+                        }
+                    )
+
+                    TextInputSelectButton(
+                        Modifier.weight(1f),
+                        R.string.assistant_task_detail_screen_output_button_title,
+                        !showInput,
+                        onClick = {
+                            showInput = false
+                        }
+                    )
+                }
+            }
+
+            item {
+                Spacer(modifier = Modifier.height(16.dp))
+
+                Column(
+                    modifier = Modifier
+                        .fillMaxSize()
+                        .background(color = colorResource(id = R.color.light_grey), shape = RoundedCornerShape(8.dp))
+                        .padding(16.dp)
+                ) {
+                    Text(
+                        text = if (showInput) {
+                            task.input ?: ""
+                        } else {
+                            task.output ?: ""
+                        },
+                        fontSize = 12.sp,
+                        color = Color.Black,
+                        modifier = Modifier
+                            .animateContentSize(
+                                animationSpec = spring(
+                                    dampingRatio = Spring.DampingRatioLowBouncy,
+                                    stiffness = Spring.StiffnessLow
+                                )
+                            )
+                    )
+                }
+
+                TaskStatus(task, foregroundColor = Color.Black)
+
+                Spacer(modifier = Modifier.height(32.dp))
+            }
+        }
+    }
+}
+
+@Composable
+private fun TextInputSelectButton(modifier: Modifier, titleId: Int, highlightCondition: Boolean, onClick: () -> Unit) {
+    Button(
+        onClick = onClick,
+        shape = RoundedCornerShape(8.dp),
+        colors = if (highlightCondition) {
+            ButtonDefaults.buttonColors(containerColor = Color.White)
+        } else {
+            ButtonDefaults.buttonColors(containerColor = colorResource(id = R.color.light_grey))
+        },
+        modifier = modifier
+            .widthIn(min = 0.dp, max = 200.dp)
+            .padding(horizontal = 4.dp)
+    ) {
+        Text(text = stringResource(id = titleId), color = Color.Black)
+    }
+}
+
+@Suppress("MagicNumber")
+@Preview
+@Composable
+private fun TaskDetailScreenPreview() {
+    TaskDetailBottomSheet(
+        task = Task(
+            1,
+            "Free Prompt",
+            0,
+            "1",
+            "1",
+            "Give me text".getRandomString(100),
+            "output".getRandomString(300),
+            "",
+            ""
+        )
+    ) {
+    }
+}

+ 1 - 1
app/src/main/java/com/nextcloud/client/assistant/component/TaskTypesRow.kt → app/src/main/java/com/nextcloud/client/assistant/taskTypes/TaskTypesRow.kt

@@ -5,7 +5,7 @@
  * SPDX-FileCopyrightText: 2024 Nextcloud GmbH
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
-package com.nextcloud.client.assistant.component
+package com.nextcloud.client.assistant.taskTypes
 
 import androidx.compose.foundation.horizontalScroll
 import androidx.compose.foundation.layout.Row

+ 2 - 1
app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt

@@ -58,7 +58,8 @@ import com.owncloud.android.db.ProviderMeta
         AutoMigration(from = 76, to = 77),
         AutoMigration(from = 77, to = 78),
         AutoMigration(from = 78, to = 79, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
-        AutoMigration(from = 79, to = 80)
+        AutoMigration(from = 79, to = 80),
+        AutoMigration(from = 80, to = 81)
     ],
     exportSchema = true
 )

+ 4 - 2
app/src/main/java/com/nextcloud/client/database/entity/SyncedFolderEntity.kt

@@ -45,6 +45,8 @@ data class SyncedFolderEntity(
     val hidden: Int?,
     @ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE)
     val subFolderRule: Int?,
-    @ColumnInfo(name = ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN)
-    val excludeHidden: Int?
+    @ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_EXCLUDE_HIDDEN)
+    val excludeHidden: Int?,
+    @ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS)
+    val lastScanTimestampMs: Long?
 )

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

@@ -264,7 +264,7 @@ internal class BackgroundJobManagerImpl(
             .setConstraints(constrains)
             .build()
 
-        workManager.enqueueUniqueWork(JOB_CONTENT_OBSERVER, ExistingWorkPolicy.APPEND, request)
+        workManager.enqueueUniqueWork(JOB_CONTENT_OBSERVER, ExistingWorkPolicy.REPLACE, request)
     }
 
     override fun schedulePeriodicContactsBackup(user: User) {

+ 2 - 0
app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt

@@ -11,6 +11,7 @@ import androidx.work.Worker
 import androidx.work.WorkerParameters
 import com.nextcloud.client.device.PowerManagementService
 import com.owncloud.android.datamodel.SyncedFolderProvider
+import com.owncloud.android.lib.common.utils.Log_OC
 
 /**
  * This work is triggered when OS detects change in media folders.
@@ -31,6 +32,7 @@ class ContentObserverWork(
         backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class))
 
         if (params.triggeredContentUris.size > 0) {
+            Log_OC.d(TAG, "File-sync Content Observer detected files change")
             checkAndStartFileSyncJob()
             backgroundJobManager.startMediaFoldersDetectionJob()
         }

+ 6 - 8
app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt

@@ -62,7 +62,6 @@ class FilesSyncWork(
 
     companion object {
         const val TAG = "FilesSyncJob"
-        const val SKIP_CUSTOM = "skipCustom"
         const val OVERRIDE_POWER_SAVING = "overridePowerSaving"
         const val CHANGED_FILES = "changedFiles"
         const val FOREGROUND_SERVICE_ID = 414
@@ -70,7 +69,7 @@ class FilesSyncWork(
 
     @Suppress("MagicNumber")
     private fun updateForegroundWorker(progressPercent: Int, useForegroundWorker: Boolean) {
-        if (useForegroundWorker) {
+        if (!useForegroundWorker) {
             return
         }
 
@@ -95,6 +94,7 @@ class FilesSyncWork(
     @Suppress("MagicNumber")
     override fun doWork(): Result {
         backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class))
+        Log_OC.d(TAG, "File-sync worker started")
 
         val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
         // If we are in power save mode, better to postpone upload
@@ -114,7 +114,9 @@ class FilesSyncWork(
 
         // Get changed files from ContentObserverWork (only images and videos) or by scanning filesystem
         val changedFiles = inputData.getStringArray(CHANGED_FILES)
+        Log_OC.d(TAG, "File-sync worker changed files from observer: " + changedFiles.contentToString())
         collectChangedFiles(changedFiles)
+        Log_OC.d(TAG, "File-sync worker finished checking files.")
 
         // Create all the providers we'll need
         val filesystemDataProvider = FilesystemDataProvider(contentResolver)
@@ -129,11 +131,7 @@ class FilesSyncWork(
                 (50 + (index.toDouble() / syncedFolders.size.toDouble()) * 50).toInt(),
                 changedFiles.isNullOrEmpty()
             )
-            if (syncedFolder.isEnabled && (
-                    changedFiles.isNullOrEmpty() ||
-                        MediaFolderType.CUSTOM != syncedFolder.type
-                    )
-            ) {
+            if (syncedFolder.isEnabled) {
                 syncFolder(
                     context,
                     resources,
@@ -145,6 +143,7 @@ class FilesSyncWork(
                 )
             }
         }
+        Log_OC.d(TAG, "File-sync worker finished")
         val result = Result.success()
         backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result)
         return result
@@ -222,7 +221,6 @@ class FilesSyncWork(
             needsWifi = syncedFolder.isWifiOnly
             uploadAction = syncedFolder.uploadAction
         }
-
         FileUploadHelper.instance().uploadNewFiles(
             user,
             localPaths,

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

@@ -75,8 +75,10 @@ class FileUploadHelper {
     ) {
         val failedUploads = uploadsStorageManager.failedUploads
         if (failedUploads == null || failedUploads.isEmpty()) {
+            Log_OC.d(TAG, "Failed uploads are empty or null")
             return
         }
+
         retryUploads(
             uploadsStorageManager,
             connectivityService,
@@ -119,6 +121,8 @@ class FileUploadHelper {
         val batteryStatus = powerManagementService.battery
         val charging = batteryStatus.isCharging || batteryStatus.isFull
         val isPowerSaving = powerManagementService.isPowerSavingEnabled
+        var uploadUser = Optional.empty<User>()
+
 
         for (failedUpload in failedUploads) {
 

+ 21 - 20
app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt

@@ -165,16 +165,16 @@ class FileUploadWorker(
             }
 
             if (user.isPresent) {
-                val operation = createUploadFileOperation(upload, user.get())
+                val uploadFileOperation = createUploadFileOperation(upload, user.get())
 
-                currentUploadFileOperation = operation
-                val result = upload(operation, user.get())
+                currentUploadFileOperation = uploadFileOperation
+                val result = upload(uploadFileOperation, user.get())
                 currentUploadFileOperation = null
 
                 fileUploaderDelegate.sendBroadcastUploadFinished(
-                    operation,
+                    uploadFileOperation,
                     result,
-                    operation.oldFile?.storagePath,
+                    uploadFileOperation.oldFile?.storagePath,
                     context,
                     localBroadcastManager
                 )
@@ -205,39 +205,39 @@ class FileUploadWorker(
     }
 
     @Suppress("TooGenericExceptionCaught", "DEPRECATION")
-    private fun upload(operation: UploadFileOperation, user: User): RemoteOperationResult<Any?> {
+    private fun upload(uploadFileOperation: UploadFileOperation, user: User): RemoteOperationResult<Any?> {
         lateinit var result: RemoteOperationResult<Any?>
 
         notificationManager.prepareForStart(
-            operation,
-            intents.startIntent(operation),
-            intents.notificationStartIntent(operation)
+            uploadFileOperation,
+            cancelPendingIntent = intents.startIntent(uploadFileOperation),
+            intents.notificationStartIntent(uploadFileOperation)
         )
 
         try {
-            val storageManager = operation.storageManager
+            val storageManager = uploadFileOperation.storageManager
             val ocAccount = OwnCloudAccount(user.toPlatformAccount(), context)
             val uploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context)
-            result = operation.execute(uploadClient)
+            result = uploadFileOperation.execute(uploadClient)
 
             val task = ThumbnailsCacheManager.ThumbnailGenerationTask(storageManager, user)
-            val file = File(operation.originalStoragePath)
-            val remoteId: String? = operation.file.remoteId
+            val file = File(uploadFileOperation.originalStoragePath)
+            val remoteId: String? = uploadFileOperation.file.remoteId
             task.execute(ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, remoteId))
         } catch (e: Exception) {
             Log_OC.e(TAG, "Error uploading", e)
             result = RemoteOperationResult<Any?>(e)
         } finally {
-            cleanupUploadProcess(result, operation)
+            cleanupUploadProcess(result, uploadFileOperation)
         }
 
         return result
     }
 
-    private fun cleanupUploadProcess(result: RemoteOperationResult<Any?>, operation: UploadFileOperation) {
+    private fun cleanupUploadProcess(result: RemoteOperationResult<Any?>, uploadFileOperation: UploadFileOperation) {
         if (!isStopped || !result.isCancelled) {
-            uploadsStorageManager.updateDatabaseUploadResult(result, operation)
-            notifyUploadResult(operation, result)
+            uploadsStorageManager.updateDatabaseUploadResult(result, uploadFileOperation)
+            notifyUploadResult(uploadFileOperation, result)
             notificationManager.dismissWorkerNotifications()
         }
     }
@@ -315,10 +315,11 @@ class FileUploadWorker(
 
         if (percent != lastPercent) {
             notificationManager.run {
-                updateUploadProgress(fileAbsoluteName, percent, currentUploadFileOperation)
-
                 val accountName = currentUploadFileOperation?.user?.accountName
                 val remotePath = currentUploadFileOperation?.remotePath
+                val filename = currentUploadFileOperation?.fileName ?: ""
+
+                updateUploadProgress(filename, percent, currentUploadFileOperation)
 
                 if (accountName != null && remotePath != null) {
                     val key: String =
@@ -329,7 +330,7 @@ class FileUploadWorker(
                         progressRate,
                         totalTransferredSoFar,
                         totalToTransfer,
-                        fileAbsoluteName
+                        filename
                     )
                 }
 

+ 10 - 8
app/src/main/java/com/nextcloud/client/jobs/upload/UploadNotificationManager.kt

@@ -16,7 +16,6 @@ import android.os.Build
 import androidx.core.app.NotificationCompat
 import com.owncloud.android.R
 import com.owncloud.android.lib.common.operations.RemoteOperationResult
-import com.owncloud.android.lib.resources.files.FileUtils
 import com.owncloud.android.operations.UploadFileOperation
 import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.utils.theme.ViewThemeUtils
@@ -44,14 +43,18 @@ class UploadNotificationManager(private val context: Context, viewThemeUtils: Vi
     }
 
     @Suppress("MagicNumber")
-    fun prepareForStart(upload: UploadFileOperation, pendingIntent: PendingIntent, startIntent: PendingIntent) {
+    fun prepareForStart(
+        uploadFileOperation: UploadFileOperation,
+        cancelPendingIntent: PendingIntent,
+        startIntent: PendingIntent
+    ) {
         notificationBuilder.run {
             setContentTitle(context.getString(R.string.uploader_upload_in_progress_ticker))
             setContentText(
                 String.format(
                     context.getString(R.string.uploader_upload_in_progress),
                     0,
-                    upload.fileName
+                    uploadFileOperation.fileName
                 )
             )
             setTicker(context.getString(R.string.foreground_service_upload))
@@ -62,13 +65,13 @@ class UploadNotificationManager(private val context: Context, viewThemeUtils: Vi
             addAction(
                 R.drawable.ic_action_cancel_grey,
                 context.getString(R.string.common_cancel),
-                pendingIntent
+                cancelPendingIntent
             )
 
             setContentIntent(startIntent)
         }
 
-        if (!upload.isInstantPicture && !upload.isInstantVideo) {
+        if (!uploadFileOperation.isInstantPicture && !uploadFileOperation.isInstantVideo) {
             showNotification()
         }
     }
@@ -138,11 +141,10 @@ class UploadNotificationManager(private val context: Context, viewThemeUtils: Vi
     }
 
     @Suppress("MagicNumber")
-    fun updateUploadProgress(filePath: String, percent: Int, currentOperation: UploadFileOperation?) {
+    fun updateUploadProgress(filename: String, percent: Int, currentOperation: UploadFileOperation?) {
         notificationBuilder.run {
             setProgress(100, percent, false)
-            val fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1)
-            val text = String.format(context.getString(R.string.uploader_upload_in_progress), percent, fileName)
+            val text = String.format(context.getString(R.string.uploader_upload_in_progress), percent, filename)
             setContentText(text)
 
             showNotification()

+ 7 - 10
app/src/main/java/com/nextcloud/ui/composeActivity/ComposeActivity.kt

@@ -36,7 +36,7 @@ import java.lang.ref.WeakReference
 class ComposeActivity : DrawerActivity() {
 
     lateinit var binding: ActivityComposeBinding
-    private var menuItemId: Int? = null
+    private var menuItemId: Int = R.id.nav_all_files
 
     companion object {
         const val DESTINATION = "DESTINATION"
@@ -51,13 +51,12 @@ class ComposeActivity : DrawerActivity() {
 
         val destination = intent.getSerializableArgument(DESTINATION, ComposeDestination::class.java)
         val titleId = intent.getIntExtra(TITLE, R.string.empty)
-        menuItemId = intent.getIntExtra(MENU_ITEM, -1)
+        menuItemId = intent.getIntExtra(MENU_ITEM, R.id.nav_all_files)
 
-        setupToolbar()
-        updateActionBarTitleAndHomeButtonByString(getString(titleId))
+        setupDrawer(menuItemId)
 
-        if (menuItemId != -1) {
-            setupDrawer(menuItemId!!)
+        setupToolbarShowOnlyMenuButtonAndTitle(getString(titleId)) {
+            openDrawer()
         }
 
         binding.composeView.setContent {
@@ -72,15 +71,13 @@ class ComposeActivity : DrawerActivity() {
 
     override fun onResume() {
         super.onResume()
-        if (menuItemId != -1) {
-            setDrawerMenuItemChecked(R.id.nav_assistant)
-        }
+        setDrawerMenuItemChecked(menuItemId)
     }
 
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
         return when (item.itemId) {
             android.R.id.home -> {
-                if (isDrawerOpen) closeDrawer() else openDrawer()
+                toggleDrawer()
                 true
             }
             else -> super.onOptionsItemSelected(item)

+ 17 - 0
app/src/main/java/com/nextcloud/utils/extensions/StringExtensions.kt

@@ -0,0 +1,17 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.nextcloud.utils.extensions
+
+fun String.getRandomString(length: Int): String {
+    val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
+    val result = (1..length)
+        .map { allowedChars.random() }
+        .joinToString("")
+
+    return this + result
+}

+ 1 - 1
app/src/main/java/com/owncloud/android/MainApp.java

@@ -124,7 +124,7 @@ import static com.owncloud.android.ui.activity.ContactsPreferenceActivity.PREFER
  * Contains methods to build the "static" strings. These strings were before constants in different classes.
  */
 public class MainApp extends MultiDexApplication implements HasAndroidInjector {
-    public static final OwnCloudVersion OUTDATED_SERVER_VERSION = NextcloudVersion.nextcloud_23;
+    public static final OwnCloudVersion OUTDATED_SERVER_VERSION = NextcloudVersion.nextcloud_26;
     public static final OwnCloudVersion MINIMUM_SUPPORTED_SERVER_VERSION = OwnCloudVersion.nextcloud_16;
 
     private static final String TAG = MainApp.class.getSimpleName();

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

@@ -56,7 +56,10 @@ import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.MimeType;
 import com.owncloud.android.utils.MimeTypeUtil;
 
+import org.apache.commons.io.FileUtils;
+
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -71,6 +74,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import kotlin.Pair;
 
 public class FileDataStorageManager {
     private static final String TAG = FileDataStorageManager.class.getSimpleName();
@@ -338,6 +342,36 @@ public class FileDataStorageManager {
         return ocFile;
     }
 
+    public static void clearTempEncryptedFolder(String accountName) {
+        File tempEncryptedFolder =  new File(FileStorageUtils.getTemporalEncryptedFolderPath(accountName));
+
+        if (!tempEncryptedFolder.exists()) {
+            Log_OC.d(TAG,"tempEncryptedFolder not exists");
+            return;
+        }
+
+        try {
+            FileUtils.cleanDirectory(tempEncryptedFolder);
+
+            Log_OC.d(TAG,"tempEncryptedFolder cleared");
+        } catch (IOException exception) {
+            Log_OC.d(TAG,"Error caught at clearTempEncryptedFolder: " + exception);
+        }
+    }
+
+    public static File createTempEncryptedFolder(String accountName) {
+        File tempEncryptedFolder = new File(FileStorageUtils.getTemporalEncryptedFolderPath(accountName));
+
+        if (!tempEncryptedFolder.exists()) {
+            boolean isTempEncryptedFolderCreated = tempEncryptedFolder.mkdirs();
+            Log_OC.d(TAG, "tempEncryptedFolder created" + isTempEncryptedFolderCreated);
+        } else {
+            Log_OC.d(TAG, "tempEncryptedFolder already exists");
+        }
+
+        return tempEncryptedFolder;
+    }
+
     public void saveNewFile(OCFile newFile) {
         String remoteParentPath = new File(newFile.getRemotePath()).getParent();
         remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ?
@@ -1704,6 +1738,7 @@ public class FileDataStorageManager {
         }
     }
 
+    @SuppressFBWarnings("PSC")
     public void saveConflict(OCFile ocFile, String etagInConflict) {
         ContentValues cv = new ContentValues();
         if (!ocFile.isDown()) {
@@ -2297,6 +2332,59 @@ public class FileDataStorageManager {
         }
     }
 
+    public String getFolderName(String path) {
+        return "/" + path.split("/")[1] + "/";
+    }
+
+    public String retrieveRemotePathConsideringEncryption(OCFile file) {
+        if (file == null) {
+            throw new NullPointerException("file cannot be null");
+        }
+
+        String remotePath = file.getRemotePath();
+        if (file.isEncrypted()) {
+            remotePath = getEncryptedRemotePath(file.getRemotePath());
+        }
+
+        return remotePath;
+    }
+
+    public String getEncryptedRemotePath(String decryptedRemotePath) {
+        String folderName = getFolderName(decryptedRemotePath);
+
+        if (folderName == null) {
+            throw new NullPointerException("folderName cannot be null");
+        }
+
+        OCFile folder = getFileByDecryptedRemotePath(folderName);
+        List<OCFile> files = getAllFilesRecursivelyInsideFolder(folder);
+        List<Pair<String, String>> decryptedFileNamesAndEncryptedRemotePaths = getDecryptedFileNamesAndEncryptedRemotePaths(files);
+
+        String decryptedFileName = decryptedRemotePath.substring( decryptedRemotePath.lastIndexOf('/') + 1);
+
+        for (Pair<String, String> item : decryptedFileNamesAndEncryptedRemotePaths) {
+            if (item.getFirst().equals(decryptedFileName)) {
+                return item.getSecond();
+            }
+        }
+
+        return null;
+    }
+
+    @SuppressFBWarnings("OCP")
+    private List<Pair<String, String>> getDecryptedFileNamesAndEncryptedRemotePaths(List<OCFile> fileList) {
+        List<Pair<String, String>> result = new ArrayList<>();
+
+        for (OCFile file : fileList) {
+            if (file.isEncrypted()) {
+                Pair<String, String> fileNameAndEncryptedRemotePath = new Pair<>(file.getDecryptedFileName(), file.getRemotePath());
+                result.add(fileNameAndEncryptedRemotePath);
+            }
+        }
+
+        return result;
+    }
+
     public void removeLocalFiles(User user, FileDataStorageManager storageManager) {
         File tempDir = new File(FileStorageUtils.getTemporalPath(user.getAccountName()));
         File saveDir = new File(FileStorageUtils.getSavePath(user.getAccountName()));

+ 2 - 1
app/src/main/java/com/owncloud/android/datamodel/FilesystemDataProvider.java

@@ -107,6 +107,7 @@ public class FilesystemDataProvider {
 
     public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean isFolder, SyncedFolder syncedFolder) {
 
+        // takes multiple milliseconds to query data from database (around 75% of execution time) (6ms)
         FileSystemDataSet data = getFilesystemDataSet(localPath, syncedFolder);
 
         int isFolderValue = 0;
@@ -145,7 +146,7 @@ public class FilesystemDataProvider {
                 }
             }
 
-
+            // updating data takes multiple milliseconds (around 25% of exec time) (2 ms)
             int result = contentResolver.update(
                 ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
                 cv,

+ 13 - 3
app/src/main/java/com/owncloud/android/datamodel/SyncedFolder.java

@@ -21,6 +21,7 @@ import java.io.Serializable;
 public class SyncedFolder implements Serializable, Cloneable {
     public static final long UNPERSISTED_ID = Long.MIN_VALUE;
     public static final long EMPTY_ENABLED_TIMESTAMP_MS = -1;
+    public static final long NOT_SCANNED_YET = -1;
     private static final long serialVersionUID = -793476118299906429L;
 
 
@@ -41,6 +42,7 @@ public class SyncedFolder implements Serializable, Cloneable {
     private boolean hidden;
     private SubFolderRule subfolderRule;
     private boolean excludeHidden;
+    private long lastScanTimestampMs;
 
     /**
      * constructor for new, to be persisted entity.
@@ -75,7 +77,8 @@ public class SyncedFolder implements Serializable, Cloneable {
                         MediaFolderType type,
                         boolean hidden,
                         SubFolderRule subFolderRule,
-                        boolean excludeHidden) {
+                        boolean excludeHidden,
+                        long lastScanTimestampMs) {
         this(UNPERSISTED_ID,
              localPath,
              remotePath,
@@ -91,7 +94,8 @@ public class SyncedFolder implements Serializable, Cloneable {
              type,
              hidden,
              subFolderRule,
-             excludeHidden);
+             excludeHidden,
+             lastScanTimestampMs);
     }
 
     /**
@@ -114,7 +118,8 @@ public class SyncedFolder implements Serializable, Cloneable {
                            MediaFolderType type,
                            boolean hidden,
                            SubFolderRule subFolderRule,
-                           boolean excludeHidden) {
+                           boolean excludeHidden,
+                           long lastScanTimestampMs) {
         this.id = id;
         this.localPath = localPath;
         this.remotePath = remotePath;
@@ -130,6 +135,7 @@ public class SyncedFolder implements Serializable, Cloneable {
         this.hidden = hidden;
         this.subfolderRule = subFolderRule;
         this.excludeHidden = excludeHidden;
+        this.lastScanTimestampMs = lastScanTimestampMs;
     }
 
     /**
@@ -271,4 +277,8 @@ public class SyncedFolder implements Serializable, Cloneable {
     public boolean containsFile(String filePath){
         return filePath.contains(localPath);
     }
+
+    public long getLastScanTimestampMs() { return lastScanTimestampMs; }
+
+    public void setLastScanTimestampMs(long lastScanTimestampMs) { this.lastScanTimestampMs = lastScanTimestampMs; }
 }

+ 8 - 4
app/src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java

@@ -60,7 +60,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
                                    MediaFolderType type,
                                    boolean hidden,
                                    SubFolderRule subFolderRule,
-                                   boolean excludeHidden) {
+                                   boolean excludeHidden,
+                                   long lastScanTimestampMs) {
         super(id,
               localPath,
               remotePath,
@@ -76,7 +77,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
               type,
               hidden,
               subFolderRule,
-              excludeHidden);
+              excludeHidden,
+              lastScanTimestampMs);
         this.filePaths = filePaths;
         this.folderName = folderName;
         this.numberOfFiles = numberOfFiles;
@@ -98,7 +100,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
                                    MediaFolderType type,
                                    boolean hidden,
                                    SubFolderRule subFolderRule,
-                                   boolean excludeHidden) {
+                                   boolean excludeHidden,
+                                   long lastScanTimestampMs) {
         super(id,
               localPath,
               remotePath,
@@ -114,7 +117,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
               type,
               hidden,
               subFolderRule,
-              excludeHidden);
+              excludeHidden,
+              lastScanTimestampMs);
         this.folderName = folderName;
     }
 

+ 7 - 4
app/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java

@@ -360,7 +360,9 @@ public class SyncedFolderProvider extends Observable {
             SubFolderRule subFolderRule = SubFolderRule.values()[cursor.getInt(
                     cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE))];
             boolean excludeHidden = cursor.getInt(cursor.getColumnIndexOrThrow(
-                ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN)) == 1;
+                ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_EXCLUDE_HIDDEN)) == 1;
+            long lastScanTimestampMs = cursor.getLong(cursor.getColumnIndexOrThrow(
+                ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS));
 
 
             syncedFolder = new SyncedFolder(id,
@@ -378,7 +380,8 @@ public class SyncedFolderProvider extends Observable {
                                             type,
                                             hidden,
                                             subFolderRule,
-                                            excludeHidden);
+                                            excludeHidden,
+                                            lastScanTimestampMs);
         }
         return syncedFolder;
     }
@@ -407,8 +410,8 @@ public class SyncedFolderProvider extends Observable {
         cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_TYPE, syncedFolder.getType().id);
         cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN, syncedFolder.isHidden());
         cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE, syncedFolder.getSubfolderRule().ordinal());
-        cv.put(ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN, syncedFolder.isExcludeHidden());
-
+        cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_EXCLUDE_HIDDEN, syncedFolder.isExcludeHidden());
+        cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS, syncedFolder.getLastScanTimestampMs());
         return cv;
     }
 

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

@@ -25,7 +25,7 @@ import java.util.List;
  */
 public class ProviderMeta {
     public static final String DB_NAME = "filelist";
-    public static final int DB_VERSION = 80;
+    public static final int DB_VERSION = 81;
 
     private ProviderMeta() {
         // No instance
@@ -293,7 +293,8 @@ public class ProviderMeta {
         public static final String SYNCED_FOLDER_NAME_COLLISION_POLICY = "name_collision_policy";
         public static final String SYNCED_FOLDER_HIDDEN = "hidden";
         public static final String SYNCED_FOLDER_SUBFOLDER_RULE = "sub_folder_rule";
-        public static final String SYNCED_EXCLUDE_HIDDEN = "exclude_hidden";
+        public static final String SYNCED_FOLDER_EXCLUDE_HIDDEN = "exclude_hidden";
+        public static final String SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS = "last_scan_timestamp_ms";
 
         // Columns of external links table
         public static final String EXTERNAL_LINKS_ICON_URL = "icon_url";

+ 119 - 96
app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java

@@ -58,15 +58,14 @@ import java.util.Vector;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR;
 
 /**
- *  Remote operation performing the synchronization of the list of files contained in a folder identified with its
- *  remote path.
- *  Fetches the list and properties of the files contained in the given folder, including their properties, and updates
- *  the local database with them.
- *  Does NOT enter in the child folders to synchronize their contents also.
+ * Remote operation performing the synchronization of the list of files contained in a folder identified with its remote
+ * path. Fetches the list and properties of the files contained in the given folder, including their properties, and
+ * updates the local database with them. Does NOT enter in the child folders to synchronize their contents also.
  */
 @SuppressWarnings("PMD.AvoidDuplicateLiterals")
 public class RefreshFolderOperation extends RemoteOperation {
@@ -74,37 +73,53 @@ public class RefreshFolderOperation extends RemoteOperation {
     private static final String TAG = RefreshFolderOperation.class.getSimpleName();
 
     public static final String EVENT_SINGLE_FOLDER_CONTENTS_SYNCED =
-            RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_CONTENTS_SYNCED";
+        RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_CONTENTS_SYNCED";
     public static final String EVENT_SINGLE_FOLDER_SHARES_SYNCED =
-            RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_SHARES_SYNCED";
+        RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_SHARES_SYNCED";
 
-    /** Time stamp for the synchronization process in progress */
+    /**
+     * Time stamp for the synchronization process in progress
+     */
     private long mCurrentSyncTime;
 
-    /** Remote folder to synchronize */
+    /**
+     * Remote folder to synchronize
+     */
     private OCFile mLocalFolder;
 
-    /** Access to the local database */
+    /**
+     * Access to the local database
+     */
     private FileDataStorageManager mStorageManager;
 
-    /** Account where the file to synchronize belongs */
+    /**
+     * Account where the file to synchronize belongs
+     */
     private User user;
 
-    /** Android context; necessary to send requests to the download service */
+    /**
+     * Android context; necessary to send requests to the download service
+     */
     private Context mContext;
 
-    /** Files and folders contained in the synchronized folder after a successful operation */
+    /**
+     * Files and folders contained in the synchronized folder after a successful operation
+     */
     private List<OCFile> mChildren;
 
-    /** Counter of conflicts found between local and remote files */
+    /**
+     * Counter of conflicts found between local and remote files
+     */
     private int mConflictsFound;
 
-    /** Counter of failed operations in synchronization of kept-in-sync files */
+    /**
+     * Counter of failed operations in synchronization of kept-in-sync files
+     */
     private int mFailsInKeptInSyncFound;
 
     /**
-     * Map of remote and local paths to files that where locally stored in a location
-     * out of the ownCloud folder and couldn't be copied automatically into it
+     * Map of remote and local paths to files that where locally stored in a location out of the ownCloud folder and
+     * couldn't be copied automatically into it
      **/
     private Map<String, String> mForgottenLocalFiles;
 
@@ -113,10 +128,14 @@ public class RefreshFolderOperation extends RemoteOperation {
      */
     private boolean mSyncFullAccount;
 
-    /** 'True' means that the remote folder changed and should be fetched */
+    /**
+     * 'True' means that the remote folder changed and should be fetched
+     */
     private boolean mRemoteFolderChanged;
 
-    /** 'True' means that Etag will be ignored */
+    /**
+     * 'True' means that Etag will be ignored
+     */
     private boolean mIgnoreETag;
 
     /**
@@ -131,16 +150,14 @@ public class RefreshFolderOperation extends RemoteOperation {
     /**
      * Creates a new instance of {@link RefreshFolderOperation}.
      *
-     * @param   folder                  Folder to synchronize.
-     * @param   currentSyncTime         Time stamp for the synchronization process in progress.
-     * @param   syncFullAccount         'True' means that this operation is part of a full account
-     *                                  synchronization.
-     * @param   ignoreETag              'True' means that the content of the remote folder should
-     *                                  be fetched and updated even though the 'eTag' did not
-     *                                  change.
-     * @param   dataStorageManager      Interface with the local database.
-     * @param   user                 ownCloud account where the folder is located.
-     * @param   context                 Application context.
+     * @param folder             Folder to synchronize.
+     * @param currentSyncTime    Time stamp for the synchronization process in progress.
+     * @param syncFullAccount    'True' means that this operation is part of a full account synchronization.
+     * @param ignoreETag         'True' means that the content of the remote folder should be fetched and updated even
+     *                           though the 'eTag' did not change.
+     * @param dataStorageManager Interface with the local database.
+     * @param user               ownCloud account where the folder is located.
+     * @param context            Application context.
      */
     public RefreshFolderOperation(OCFile folder,
                                   long currentSyncTime,
@@ -196,8 +213,8 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
     /**
-     * Returns the list of files and folders contained in the synchronized folder,
-     * if called after synchronization is complete.
+     * Returns the list of files and folders contained in the synchronized folder, if called after synchronization is
+     * complete.
      *
      * @return List of files and folders contained in the synchronized folder.
      */
@@ -207,7 +224,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
     /**
      * Performs the synchronization.
-     *
+     * <p>
      * {@inheritDoc}
      */
     @Override
@@ -246,7 +263,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         if (!mSyncFullAccount && mRemoteFolderChanged) {
             sendLocalBroadcast(
                 EVENT_SINGLE_FOLDER_CONTENTS_SYNCED, mLocalFolder.getRemotePath(), result
-            );
+                              );
         }
 
         if (result.isSuccess() && !mSyncFullAccount && !mOnlyFileMetadata) {
@@ -256,7 +273,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         if (!mSyncFullAccount) {
             sendLocalBroadcast(
                 EVENT_SINGLE_FOLDER_SHARES_SYNCED, mLocalFolder.getRemotePath(), result
-            );
+                              );
         }
 
         return result;
@@ -371,7 +388,7 @@ public class RefreshFolderOperation extends RemoteOperation {
             result = new RemoteOperationResult(ResultCode.OK);
 
             Log_OC.i(TAG, "Checked " + user.getAccountName() + remotePath + " : " +
-                    (mRemoteFolderChanged ? "changed" : "not changed"));
+                (mRemoteFolderChanged ? "changed" : "not changed"));
 
         } else {
             // check failed
@@ -380,10 +397,10 @@ public class RefreshFolderOperation extends RemoteOperation {
             }
             if (result.isException()) {
                 Log_OC.e(TAG, "Checked " + user.getAccountName() + remotePath + " : " +
-                        result.getLogMessage(), result.getException());
+                    result.getLogMessage(), result.getException());
             } else {
                 Log_OC.e(TAG, "Checked " + user.getAccountName() + remotePath + " : " +
-                        result.getLogMessage());
+                    result.getLogMessage());
             }
         }
 
@@ -425,9 +442,9 @@ public class RefreshFolderOperation extends RemoteOperation {
 
 
     /**
-     * Synchronizes the data retrieved from the server about the contents of the target folder
-     * with the current data in the local database.
-     *
+     * Synchronizes the data retrieved from the server about the contents of the target folder with the current data in
+     * the local database.
+     * <p>
      * Grants that mChildren is updated with fresh data after execution.
      *
      * @param folderAndFiles Remote folder and children files in Folder
@@ -553,6 +570,7 @@ public class RefreshFolderOperation extends RemoteOperation {
             updatedFiles.add(updatedFile);
         }
 
+
         // save updated contents in local database
         // update file name for encrypted files
         if (e2EVersion == E2EVersion.V1_2) {
@@ -584,6 +602,37 @@ public class RefreshFolderOperation extends RemoteOperation {
         return metadata;
     }
 
+    @SuppressFBWarnings("CE")
+    private static void setMimeTypeAndDecryptedRemotePath(OCFile updatedFile, FileDataStorageManager storageManager, String decryptedFileName, String mimetype) {
+        OCFile parentFile = storageManager.getFileById(updatedFile.getParentId());
+
+        if (parentFile == null) {
+            throw new NullPointerException("parentFile cannot be null");
+        }
+
+        String decryptedRemotePath;
+        if (decryptedFileName != null) {
+            decryptedRemotePath = parentFile.getDecryptedRemotePath() + decryptedFileName;
+        } else {
+            decryptedRemotePath = parentFile.getRemotePath() + updatedFile.getFileName();
+        }
+
+        if (updatedFile.isFolder()) {
+            decryptedRemotePath += "/";
+        }
+        updatedFile.setDecryptedRemotePath(decryptedRemotePath);
+
+        if (mimetype == null || mimetype.isEmpty()) {
+            if (updatedFile.isFolder()) {
+                updatedFile.setMimeType(MimeType.DIRECTORY);
+            } else {
+                updatedFile.setMimeType("application/octet-stream");
+            }
+        } else {
+            updatedFile.setMimeType(mimetype);
+        }
+    }
+
     public static void updateFileNameForEncryptedFileV1(FileDataStorageManager storageManager,
                                                         @NonNull DecryptedFolderMetadataFileV1 metadata,
                                                         OCFile updatedFile) {
@@ -597,28 +646,16 @@ public class RefreshFolderOperation extends RemoteOperation {
             } else {
                 com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFile decryptedFile =
                     metadata.getFiles().get(updatedFile.getFileName());
-                decryptedFileName = decryptedFile.getEncrypted().getFilename();
-                mimetype = decryptedFile.getEncrypted().getMimetype();
-            }
-
 
-            OCFile parentFile = storageManager.getFileById(updatedFile.getParentId());
-            String decryptedRemotePath = parentFile.getDecryptedRemotePath() + decryptedFileName;
+                if (decryptedFile == null) {
+                    throw new NullPointerException("decryptedFile cannot be null");
+                }
 
-            if (updatedFile.isFolder()) {
-                decryptedRemotePath += "/";
+                decryptedFileName = decryptedFile.getEncrypted().getFilename();
+                mimetype = decryptedFile.getEncrypted().getMimetype();
             }
-            updatedFile.setDecryptedRemotePath(decryptedRemotePath);
 
-            if (mimetype == null || mimetype.isEmpty()) {
-                if (updatedFile.isFolder()) {
-                    updatedFile.setMimeType(MimeType.DIRECTORY);
-                } else {
-                    updatedFile.setMimeType("application/octet-stream");
-                }
-            } else {
-                updatedFile.setMimeType(mimetype);
-            }
+            setMimeTypeAndDecryptedRemotePath(updatedFile, storageManager, decryptedFileName, mimetype);
         } catch (NullPointerException e) {
             Log_OC.e(TAG, "DecryptedMetadata for file " + updatedFile.getFileId() + " not found!");
         }
@@ -636,28 +673,16 @@ public class RefreshFolderOperation extends RemoteOperation {
                 mimetype = MimeType.DIRECTORY;
             } else {
                 DecryptedFile decryptedFile = metadata.getMetadata().getFiles().get(updatedFile.getFileName());
-                decryptedFileName = decryptedFile.getFilename();
-                mimetype = decryptedFile.getMimetype();
-            }
-
 
-            OCFile parentFile = storageManager.getFileById(updatedFile.getParentId());
-            String decryptedRemotePath = parentFile.getDecryptedRemotePath() + decryptedFileName;
+                if (decryptedFile == null) {
+                    throw new NullPointerException("decryptedFile cannot be null");
+                }
 
-            if (updatedFile.isFolder()) {
-                decryptedRemotePath += "/";
+                decryptedFileName = decryptedFile.getFilename();
+                mimetype = decryptedFile.getMimetype();
             }
-            updatedFile.setDecryptedRemotePath(decryptedRemotePath);
 
-            if (mimetype == null || mimetype.isEmpty()) {
-                if (updatedFile.isFolder()) {
-                    updatedFile.setMimeType(MimeType.DIRECTORY);
-                } else {
-                    updatedFile.setMimeType("application/octet-stream");
-                }
-            } else {
-                updatedFile.setMimeType(mimetype);
-            }
+            setMimeTypeAndDecryptedRemotePath(updatedFile, storageManager, decryptedFileName, mimetype);
         } catch (NullPointerException e) {
             Log_OC.e(TAG, "DecryptedMetadata for file " + updatedFile.getFileId() + " not found!");
         }
@@ -668,8 +693,8 @@ public class RefreshFolderOperation extends RemoteOperation {
             updatedFile.setFileId(localFile.getFileId());
             updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
             updatedFile.setModificationTimestampAtLastSyncForData(
-                    localFile.getModificationTimestampAtLastSyncForData()
-            );
+                localFile.getModificationTimestampAtLastSyncForData()
+                                                                 );
             if (localFile.isEncrypted()) {
                 if (mLocalFolder.getStoragePath() == null) {
                     updatedFile.setStoragePath(FileStorageUtils.getDefaultSavePathFor(user.getAccountName(), mLocalFolder) +
@@ -685,7 +710,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
             // eTag will not be updated unless file CONTENTS are synchronized
             if (!updatedFile.isFolder() && localFile.isDown() &&
-                    !updatedFile.getEtag().equals(localFile.getEtag())) {
+                !updatedFile.getEtag().equals(localFile.getEtag())) {
                 updatedFile.setEtagInConflict(updatedFile.getEtag());
             }
 
@@ -695,8 +720,8 @@ public class RefreshFolderOperation extends RemoteOperation {
                 updatedFile.setFileLength(remoteFile.getFileLength());
                 updatedFile.setMountType(remoteFile.getMountType());
             } else if (remoteFolderChanged && MimeTypeUtil.isImage(remoteFile) &&
-                    remoteFile.getModificationTimestamp() !=
-                            localFile.getModificationTimestamp()) {
+                remoteFile.getModificationTimestamp() !=
+                    localFile.getModificationTimestamp()) {
                 updatedFile.setUpdateThumbnailNeeded(true);
                 Log_OC.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
             }
@@ -713,6 +738,7 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
     @NonNull
+    @SuppressFBWarnings("OCP")
     public static Map<String, OCFile> prefillLocalFilesMap(Object metadata, List<OCFile> localFiles) {
         Map<String, OCFile> localFilesMap = Maps.newHashMapWithExpectedSize(localFiles.size());
 
@@ -731,13 +757,12 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
     /**
-     * Performs a list of synchronization operations, determining if a download or upload is needed
-     * or if exists conflict due to changes both in local and remote contents of the each file.
-     *
-     * If download or upload is needed, request the operation to the corresponding service and goes
-     * on.
+     * Performs a list of synchronization operations, determining if a download or upload is needed or if exists
+     * conflict due to changes both in local and remote contents of the each file.
+     * <p>
+     * If download or upload is needed, request the operation to the corresponding service and goes on.
      *
-     * @param filesToSyncContents       Synchronization operations to execute.
+     * @param filesToSyncContents Synchronization operations to execute.
      */
     private void startContentSynchronizations(List<SynchronizeFileOperation> filesToSyncContents) {
         RemoteOperationResult contentsResult;
@@ -750,10 +775,10 @@ public class RefreshFolderOperation extends RemoteOperation {
                     mFailsInKeptInSyncFound++;
                     if (contentsResult.getException() != null) {
                         Log_OC.e(TAG, "Error while synchronizing favourites : "
-                                + contentsResult.getLogMessage(), contentsResult.getException());
+                            + contentsResult.getLogMessage(), contentsResult.getException());
                     } else {
                         Log_OC.e(TAG, "Error while synchronizing favourites : "
-                                + contentsResult.getLogMessage());
+                            + contentsResult.getLogMessage());
                     }
                 }
             }   // won't let these fails break the synchronization process
@@ -763,9 +788,9 @@ public class RefreshFolderOperation extends RemoteOperation {
     /**
      * Syncs the Share resources for the files contained in the folder refreshed (children, not deeper descendants).
      *
-     * @param client    Handler of a session with an OC server.
-     * @return The result of the remote operation retrieving the Share resources in the folder refreshed by
-     *                  the operation.
+     * @param client Handler of a session with an OC server.
+     * @return The result of the remote operation retrieving the Share resources in the folder refreshed by the
+     * operation.
      */
     private RemoteOperationResult refreshSharesForFolder(OwnCloudClient client) {
         RemoteOperationResult result;
@@ -793,12 +818,10 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
     /**
-     * Sends a message to any application component interested in the progress
-     * of the synchronization.
+     * Sends a message to any application component interested in the progress of the synchronization.
      *
      * @param event         broadcast event (Intent Action)
-     * @param dirRemotePath Remote path of a folder that was just synchronized
-     *                      (with or without success)
+     * @param dirRemotePath Remote path of a folder that was just synchronized (with or without success)
      * @param result        remote operation result
      */
     private void sendLocalBroadcast(String event, String dirRemotePath, RemoteOperationResult result) {

+ 10 - 6
app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java

@@ -442,6 +442,7 @@ public class UploadFileOperation extends SyncOperation {
         File temporalFile = null;
         File originalFile = new File(mOriginalStoragePath);
         File expectedFile = null;
+        File encryptedTempFile = null;
         FileLock fileLock = null;
         long size;
 
@@ -552,7 +553,7 @@ public class UploadFileOperation extends SyncOperation {
             byte[] iv = EncryptionUtils.randomBytes(EncryptionUtils.ivLength);
             Cipher cipher = EncryptionUtils.getCipher(Cipher.ENCRYPT_MODE, key, iv);
             File file = new File(mFile.getStoragePath());
-            EncryptedFile encryptedFile = EncryptionUtils.encryptFile(file, cipher);
+            EncryptedFile encryptedFile = EncryptionUtils.encryptFile(user.getAccountName(), file, cipher);
 
             // new random file name, check if it exists in metadata
             String encryptedFileName = EncryptionUtils.generateUid();
@@ -567,9 +568,7 @@ public class UploadFileOperation extends SyncOperation {
                 }
             }
 
-            File encryptedTempFile = encryptedFile.getEncryptedFile();
-
-            /***** E2E *****/
+            encryptedTempFile = encryptedFile.getEncryptedFile();
 
             FileChannel channel = null;
             try {
@@ -712,8 +711,6 @@ public class UploadFileOperation extends SyncOperation {
                                                                  user,
                                                                  getStorageManager());
                 }
-
-                encryptedTempFile.delete();
             }
         } catch (FileNotFoundException e) {
             Log_OC.d(TAG, mFile.getStoragePath() + " not exists anymore");
@@ -755,6 +752,13 @@ public class UploadFileOperation extends SyncOperation {
             if (unlockFolderResult != null && !unlockFolderResult.isSuccess()) {
                 result = unlockFolderResult;
             }
+
+            if (encryptedTempFile != null) {
+                boolean isTempEncryptedFileDeleted = encryptedTempFile.delete();
+                Log_OC.e(TAG, "isTempEncryptedFileDeleted: " + isTempEncryptedFileDeleted);
+            } else {
+                Log_OC.e(TAG, "Encrypted temp file cannot be found");
+            }
         }
 
         if (result.isSuccess()) {

+ 12 - 6
app/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.kt

@@ -21,6 +21,7 @@ import com.nextcloud.client.jobs.upload.UploadNotificationManager
 import com.nextcloud.model.HTTPStatusCodes
 import com.nextcloud.utils.extensions.getParcelableArgument
 import com.owncloud.android.R
+import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.datamodel.UploadsStorageManager
 import com.owncloud.android.db.OCUpload
@@ -42,6 +43,10 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
     @Inject
     var uploadsStorageManager: UploadsStorageManager? = null
 
+    @JvmField
+    @Inject
+    var fileStorageManager: FileDataStorageManager? = null
+
     private var conflictUploadId: Long = 0
     private var existingFile: OCFile? = null
     private var newFile: OCFile? = null
@@ -159,8 +164,8 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
             return
         }
         if (existingFile == null) {
-            // fetch info of existing file from server
-            val operation = ReadFileRemoteOperation(newFile!!.remotePath)
+            val remotePath = fileStorageManager?.retrieveRemotePathConsideringEncryption(newFile) ?: return
+            val operation = ReadFileRemoteOperation(remotePath)
 
             @Suppress("TooGenericExceptionCaught")
             Thread {
@@ -169,7 +174,7 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
                     if (result.isSuccess) {
                         existingFile = FileStorageUtils.fillOCFile(result.data[0] as RemoteFile)
                         existingFile?.lastSyncDateForProperties = System.currentTimeMillis()
-                        startDialog()
+                        startDialog(remotePath)
                     } else {
                         Log_OC.e(TAG, "ReadFileRemoteOp returned failure with code: " + result.httpCode)
                         showErrorAndFinish(result.httpCode)
@@ -180,11 +185,12 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
                 }
             }.start()
         } else {
-            startDialog()
+            val remotePath = fileStorageManager?.retrieveRemotePathConsideringEncryption(existingFile) ?: return
+            startDialog(remotePath)
         }
     }
 
-    private fun startDialog() {
+    private fun startDialog(remotePath: String) {
         val userOptional = user
         if (!userOptional.isPresent) {
             Log_OC.e(TAG, "User not present")
@@ -197,7 +203,7 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
         if (prev != null) {
             fragmentTransaction.remove(prev)
         }
-        if (existingFile != null && storageManager.fileExists(newFile?.remotePath)) {
+        if (existingFile != null && storageManager.fileExists(remotePath)) {
             val dialog = ConflictsResolveDialog.newInstance(
                 existingFile,
                 newFile,

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

@@ -286,10 +286,10 @@ public abstract class DrawerActivity extends ToolbarActivity
 
     public void updateHeader() {
         int primaryColor = themeColorUtils.unchangedPrimaryColor(getAccount(), this);
+        boolean isClientBranded = getResources().getBoolean(R.bool.is_branded_client);
 
         if (getAccount() != null &&
-            getCapabilities().getServerBackground() != null &&
-            !getResources().getBoolean(R.bool.is_branded_client)) {
+            getCapabilities().getServerBackground() != null && !isClientBranded) {
 
             OCCapability capability = getCapabilities();
             String logo = capability.getServerLogo();
@@ -339,45 +339,55 @@ public abstract class DrawerActivity extends ToolbarActivity
         }
 
         // hide ecosystem apps according to user preference or in branded client
-        LinearLayout ecosystemApps = mNavigationViewHeader.findViewById(R.id.drawer_ecosystem_apps);
-        if (getResources().getBoolean(R.bool.is_branded_client) || !preferences.isShowEcosystemApps()) {
-            ecosystemApps.setVisibility(View.GONE);
+        LinearLayout banner = mNavigationViewHeader.findViewById(R.id.drawer_ecosystem_apps);
+        boolean shouldHideTopBanner = isClientBranded || !preferences.isShowEcosystemApps();
+
+        if (shouldHideTopBanner) {
+            hideTopBanner(banner);
         } else {
-            LinearLayout notesView = ecosystemApps.findViewById(R.id.drawer_ecosystem_notes);
-            LinearLayout talkView = ecosystemApps.findViewById(R.id.drawer_ecosystem_talk);
-            LinearLayout moreView = ecosystemApps.findViewById(R.id.drawer_ecosystem_more);
-            LinearLayout assistantView = ecosystemApps.findViewById(R.id.drawer_ecosystem_assistant);
-
-            notesView.setOnClickListener(v -> openAppOrStore("it.niedermann.owncloud.notes"));
-            talkView.setOnClickListener(v -> openAppOrStore("com.nextcloud.talk2"));
-            moreView.setOnClickListener(v -> openAppStore("Nextcloud", true));
-            assistantView.setOnClickListener(v -> startComposeActivity(ComposeDestination.AssistantScreen, R.string.assistant_screen_top_bar_title, -1));
-            if (getCapabilities() != null && getCapabilities().getAssistant().isTrue()) {
-                assistantView.setVisibility(View.VISIBLE);
-            } else {
-                assistantView.setVisibility(View.GONE);
-            }
+            showTopBanner(banner, primaryColor);
+        }
+    }
 
-            List<LinearLayout> views = Arrays.asList(notesView, talkView, moreView, assistantView);
+    private void hideTopBanner(LinearLayout banner) {
+        banner.setVisibility(View.GONE);
+    }
 
-            int iconColor;
-            if (Hct.fromInt(primaryColor).getTone() < 80.0) {
-                iconColor = Color.WHITE;
-            } else {
-                iconColor = getColor(R.color.grey_800_transparent);
-            }
+    private void showTopBanner(LinearLayout banner, int primaryColor) {
+        LinearLayout notesView = banner.findViewById(R.id.drawer_ecosystem_notes);
+        LinearLayout talkView = banner.findViewById(R.id.drawer_ecosystem_talk);
+        LinearLayout moreView = banner.findViewById(R.id.drawer_ecosystem_more);
+        LinearLayout assistantView = banner.findViewById(R.id.drawer_ecosystem_assistant);
+
+        notesView.setOnClickListener(v -> openAppOrStore("it.niedermann.owncloud.notes"));
+        talkView.setOnClickListener(v -> openAppOrStore("com.nextcloud.talk2"));
+        moreView.setOnClickListener(v -> openAppStore("Nextcloud", true));
+        assistantView.setOnClickListener(v -> startComposeActivity(ComposeDestination.AssistantScreen, R.string.assistant_screen_top_bar_title, -1));
+        if (getCapabilities() != null && getCapabilities().getAssistant().isTrue()) {
+            assistantView.setVisibility(View.VISIBLE);
+        } else {
+            assistantView.setVisibility(View.GONE);
+        }
 
-            for (LinearLayout view : views) {
-                ImageView imageView = (ImageView) view.getChildAt(0);
-                imageView.setImageTintList(ColorStateList.valueOf(iconColor));
-                GradientDrawable background = (GradientDrawable) imageView.getBackground();
-                background.setStroke(DisplayUtils.convertDpToPixel(1, this), iconColor);
-                TextView textView = (TextView) view.getChildAt(1);
-                textView.setTextColor(iconColor);
-            }
+        List<LinearLayout> views = Arrays.asList(notesView, talkView, moreView, assistantView);
+
+        int iconColor;
+        if (Hct.fromInt(primaryColor).getTone() < 80.0) {
+            iconColor = Color.WHITE;
+        } else {
+            iconColor = getColor(R.color.grey_800_transparent);
+        }
 
-            ecosystemApps.setVisibility(View.VISIBLE);
+        for (LinearLayout view : views) {
+            ImageView imageView = (ImageView) view.getChildAt(0);
+            imageView.setImageTintList(ColorStateList.valueOf(iconColor));
+            GradientDrawable background = (GradientDrawable) imageView.getBackground();
+            background.setStroke(DisplayUtils.convertDpToPixel(1, this), iconColor);
+            TextView textView = (TextView) view.getChildAt(1);
+            textView.setTextColor(iconColor);
         }
+
+        banner.setVisibility(View.VISIBLE);
     }
 
     /**
@@ -463,9 +473,7 @@ public abstract class DrawerActivity extends ToolbarActivity
         DrawerMenuUtil.filterGroupfoldersMenuItem(menu, capability);
         DrawerMenuUtil.filterAssistantMenuItem(menu, capability, getResources());
         DrawerMenuUtil.setupHomeMenuItem(menu, getResources());
-
-        DrawerMenuUtil.removeMenuItem(menu, R.id.nav_community,
-                                      !getResources().getBoolean(R.bool.participate_enabled));
+        DrawerMenuUtil.removeMenuItem(menu, R.id.nav_community, !getResources().getBoolean(R.bool.participate_enabled));
         DrawerMenuUtil.removeMenuItem(menu, R.id.nav_shared, !getResources().getBoolean(R.bool.shared_enabled));
         DrawerMenuUtil.removeMenuItem(menu, R.id.nav_logout, !getResources().getBoolean(R.bool.show_drawer_logout));
     }
@@ -494,10 +502,17 @@ public abstract class DrawerActivity extends ToolbarActivity
                 MainApp.showOnlyPersonalFiles(itemId == R.id.nav_personal_files);
                 Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class);
                 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+                if (this instanceof ComposeActivity) {
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+                }
+
                 intent.setAction(FileDisplayActivity.ALL_FILES);
                 intent.putExtra(FileDisplayActivity.DRAWER_MENU_ID, menuItem.getItemId());
                 startActivity(intent);
             }
+
+            closeDrawer();
         } else if (itemId == R.id.nav_favorites) {
             handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH),
                                menuItem.getItemId());
@@ -520,7 +535,8 @@ public abstract class DrawerActivity extends ToolbarActivity
             startActivity(CommunityActivity.class);
         } else if (itemId == R.id.nav_logout) {
             mCheckedMenuItem = -1;
-            menuItem.setChecked(false);
+            MenuItem isNewMenuItemChecked = menuItem.setChecked(false);
+            Log_OC.d(TAG,"onNavigationItemClicked nav_logout setChecked " + isNewMenuItemChecked);
             final Optional<User> optionalUser = getUser();
             if (optionalUser.isPresent()) {
                 UserInfoActivity.openAccountRemovalDialog(optionalUser.get(), getSupportFragmentManager());
@@ -627,6 +643,11 @@ public abstract class DrawerActivity extends ToolbarActivity
     private void launchActivityForSearch(SearchEvent searchEvent, int menuItemId) {
         Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class);
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+        if (this instanceof ComposeActivity) {
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        }
+
         intent.setAction(Intent.ACTION_SEARCH);
         intent.putExtra(OCFileListFragment.SEARCH_EVENT, searchEvent);
         intent.putExtra(FileDisplayActivity.DRAWER_MENU_ID, menuItemId);
@@ -673,6 +694,14 @@ public abstract class DrawerActivity extends ToolbarActivity
         return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START);
     }
 
+    public void toggleDrawer() {
+        if (isDrawerOpen()) {
+            closeDrawer();
+        } else {
+            openDrawer();
+        }
+    }
+
     /**
      * closes the drawer.
      */
@@ -1115,6 +1144,11 @@ public abstract class DrawerActivity extends ToolbarActivity
         MainApp.showOnlyPersonalFiles(onlyPersonalFiles);
         Intent fileDisplayActivity = new Intent(getApplicationContext(), FileDisplayActivity.class);
         fileDisplayActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+        if (this instanceof ComposeActivity) {
+            fileDisplayActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        }
+
         fileDisplayActivity.setAction(FileDisplayActivity.ALL_FILES);
         startActivity(fileDisplayActivity);
     }
@@ -1122,7 +1156,8 @@ public abstract class DrawerActivity extends ToolbarActivity
     @Override
     public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
         if (callContext instanceof MenuItem menuItem) {
-            menuItem.setIcon(avatarDrawable);
+            MenuItem newIcon = menuItem.setIcon(avatarDrawable);
+            Log_OC.d(TAG,"avatarGenerated new icon: " + newIcon);
         } else if (callContext instanceof ImageView imageView) {
             imageView.setImageDrawable(avatarDrawable);
         } else if (callContext instanceof MaterialButton materialButton) {

+ 12 - 7
app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -54,7 +54,6 @@ import com.nextcloud.client.jobs.download.FileDownloadHelper;
 import com.nextcloud.client.jobs.download.FileDownloadWorker;
 import com.nextcloud.client.jobs.upload.FileUploadHelper;
 import com.nextcloud.client.jobs.upload.FileUploadWorker;
-import com.nextcloud.client.jobs.upload.UploadNotificationManager;
 import com.nextcloud.client.media.PlayerServiceConnection;
 import com.nextcloud.client.network.ClientFactory;
 import com.nextcloud.client.network.ConnectivityService;
@@ -878,18 +877,24 @@ public class FileDisplayActivity extends FileActivity
         requestUploadOfFilesFromFileSystem(basePath, filePaths, resultCode);
     }
 
+    private String[] getRemotePaths(String directory, String[] filePaths, String localBasePath) {
+        String[] remotePaths = new String[filePaths.length];
+        for (int j = 0; j < remotePaths.length; j++) {
+            String relativePath = StringUtils.removePrefix(filePaths[j], localBasePath);
+            remotePaths[j] = directory + relativePath;
+        }
+
+        return remotePaths;
+    }
+
     private void requestUploadOfFilesFromFileSystem(String localBasePath, String[] filePaths, int resultCode) {
         if (localBasePath != null && filePaths != null) {
             if (!localBasePath.endsWith("/")) {
                 localBasePath = localBasePath + "/";
             }
 
-            String[] remotePaths = new String[filePaths.length];
             String remotePathBase = getCurrentDir().getRemotePath();
-            for (int j = 0; j < remotePaths.length; j++) {
-                String relativePath = StringUtils.removePrefix(filePaths[j], localBasePath);
-                remotePaths[j] = remotePathBase + relativePath;
-            }
+            String[] decryptedRemotePaths = getRemotePaths(remotePathBase, filePaths, localBasePath);
 
             int behaviour = switch (resultCode) {
                 case UploadFilesActivity.RESULT_OK_AND_MOVE -> FileUploadWorker.LOCAL_BEHAVIOUR_MOVE;
@@ -899,7 +904,7 @@ public class FileDisplayActivity extends FileActivity
 
             FileUploadHelper.Companion.instance().uploadNewFiles(getUser().orElseThrow(RuntimeException::new),
                                                                  filePaths,
-                                                                 remotePaths,
+                                                                 decryptedRemotePaths,
                                                                  behaviour,
                                                                  true,
                                                                  UploadFileOperation.CREATED_BY_USER,

+ 10 - 5
app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt

@@ -387,7 +387,8 @@ class SyncedFoldersActivity :
             syncedFolder.type,
             syncedFolder.isHidden,
             syncedFolder.subfolderRule,
-            syncedFolder.isExcludeHidden
+            syncedFolder.isExcludeHidden,
+            syncedFolder.lastScanTimestampMs
         )
     }
 
@@ -418,7 +419,8 @@ class SyncedFoldersActivity :
             mediaFolder.type,
             syncedFolder.isHidden,
             syncedFolder.subfolderRule,
-            syncedFolder.isExcludeHidden
+            syncedFolder.isExcludeHidden,
+            syncedFolder.lastScanTimestampMs
         )
     }
 
@@ -448,7 +450,8 @@ class SyncedFoldersActivity :
             mediaFolder.type,
             false,
             SubFolderRule.YEAR_MONTH,
-            false
+            false,
+            SyncedFolder.NOT_SCANNED_YET
         )
     }
 
@@ -541,7 +544,8 @@ class SyncedFoldersActivity :
                         MediaFolderType.CUSTOM,
                         false,
                         SubFolderRule.YEAR_MONTH,
-                        false
+                        false,
+                        SyncedFolder.NOT_SCANNED_YET
                     )
                     onSyncFolderSettingsClick(0, emptyCustomFolder)
                 } else {
@@ -658,7 +662,8 @@ class SyncedFoldersActivity :
                 syncedFolder.type,
                 syncedFolder.isHidden,
                 syncedFolder.subFolderRule,
-                syncedFolder.isExcludeHidden
+                syncedFolder.isExcludeHidden,
+                SyncedFolder.NOT_SCANNED_YET
             )
             saveOrUpdateSyncedFolder(newCustomFolder)
             adapter.addSyncFolderItem(newCustomFolder)

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

@@ -104,6 +104,22 @@ public abstract class ToolbarActivity extends BaseActivity implements Injectable
         viewThemeUtils.material.colorMaterialTextButton(mSwitchAccountButton);
     }
 
+    public void setupToolbarShowOnlyMenuButtonAndTitle(String title, View.OnClickListener toggleDrawer) {
+        setupToolbar(false, false);
+
+        ActionBar actionBar = getSupportActionBar();
+        if (actionBar != null) {
+            actionBar.setDisplayShowTitleEnabled(false);
+        }
+
+        LinearLayout toolbar = findViewById(R.id.toolbar_linear_layout);
+        MaterialButton menuButton = findViewById(R.id.toolbar_menu_button);
+        MaterialTextView titleTextView = findViewById(R.id.toolbar_title);
+        titleTextView.setText(title);
+        toolbar.setVisibility(View.VISIBLE);
+        menuButton.setOnClickListener(toggleDrawer);
+    }
+
     public void setupToolbar() {
         setupToolbar(false, false);
     }
@@ -278,7 +294,7 @@ public abstract class ToolbarActivity extends BaseActivity implements Injectable
 
     public void clearToolbarSubtitle() {
         ActionBar actionBar = getSupportActionBar();
-        if(actionBar != null){
+        if (actionBar != null) {
             actionBar.setSubtitle(null);
         }
     }

+ 12 - 2
app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java

@@ -141,9 +141,11 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
 
             if (itemId == R.id.action_upload_list_failed_clear) {
                 uploadsStorageManager.clearFailedButNotDelayedUploads();
+                clearTempEncryptedFolder();
                 loadUploadItemsFromDb();
-            } else {
+            } else if (itemId == R.id.action_upload_list_failed_retry) {
 
+                // FIXME For e2e resume is not working
                 new Thread(() -> {
                     FileUploadHelper.Companion.instance().retryFailedUploads(
                         uploadsStorageManager,
@@ -152,10 +154,11 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
                         powerManagementService);
                     parentActivity.runOnUiThread(this::loadUploadItemsFromDb);
                 }).start();
-
             }
+
             return true;
         });
+
         failedPopup.show();
     }
 
@@ -169,6 +172,7 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
             if (itemId == R.id.action_upload_list_cancelled_clear) {
                 uploadsStorageManager.clearCancelledUploadsForCurrentAccount();
                 loadUploadItemsFromDb();
+                clearTempEncryptedFolder();
             } else if (itemId == R.id.action_upload_list_cancelled_resume) {
                 retryCancelledUploads();
             }
@@ -179,6 +183,12 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
         popup.show();
     }
 
+    private void clearTempEncryptedFolder() {
+        Optional<User> user = parentActivity.getUser();
+        user.ifPresent(value -> FileDataStorageManager.clearTempEncryptedFolder(value.getAccountName()));
+    }
+
+    // FIXME For e2e resume is not working
     private void retryCancelledUploads() {
         new Thread(() -> {
             boolean showNotExistMessage = FileUploadHelper.Companion.instance().retryCancelledUploads(

+ 11 - 8
app/src/main/java/com/owncloud/android/utils/DrawerMenuUtil.java

@@ -27,7 +27,7 @@ public final class DrawerMenuUtil {
                                              User user,
                                              Resources resources) {
         if (user.isAnonymous()) {
-            filterMenuItems(menu, R.id.nav_gallery, R.id.nav_favorites);
+            removeMenuItem(menu, R.id.nav_gallery, R.id.nav_favorites);
         }
 
         if (!resources.getBoolean(R.bool.recently_modified_enabled)) {
@@ -38,26 +38,29 @@ public final class DrawerMenuUtil {
     public static void filterTrashbinMenuItem(Menu menu, @Nullable OCCapability capability) {
         if (capability != null && capability.getFilesUndelete().isFalse() ||
             capability != null && capability.getFilesUndelete().isUnknown()) {
-            filterMenuItems(menu, R.id.nav_trashbin);
+            removeMenuItem(menu, R.id.nav_trashbin);
         }
     }
 
     public static void filterActivityMenuItem(Menu menu, @Nullable OCCapability capability) {
         if (capability != null && capability.getActivity().isFalse()) {
-            filterMenuItems(menu, R.id.nav_activity);
+            removeMenuItem(menu, R.id.nav_activity);
         }
     }
 
     public static void filterAssistantMenuItem(Menu menu, @Nullable OCCapability capability, Resources resources) {
-        boolean showCondition = capability != null && capability.getAssistant().isTrue() && !resources.getBoolean(R.bool.is_branded_client);
-        if (!showCondition) {
-            filterMenuItems(menu, R.id.nav_assistant);
+        if (resources.getBoolean(R.bool.is_branded_client)) {
+            if (capability != null && capability.getAssistant().isFalse()) {
+                removeMenuItem(menu, R.id.nav_assistant);
+            }
+        } else {
+            removeMenuItem(menu, R.id.nav_assistant);
         }
     }
 
     public static void filterGroupfoldersMenuItem(Menu menu, @Nullable OCCapability capability) {
         if (capability != null && !capability.getGroupfolders().isTrue()) {
-            filterMenuItems(menu, R.id.nav_groupfolders);
+            removeMenuItem(menu, R.id.nav_groupfolders);
         }
     }
 
@@ -74,7 +77,7 @@ public final class DrawerMenuUtil {
         }
     }
 
-    private static void filterMenuItems(Menu menu, int... menuIds) {
+    private static void removeMenuItem(Menu menu, int... menuIds) {
         if (menuIds != null) {
             for (int menuId : menuIds) {
                 menu.removeItem(menuId);

+ 6 - 6
app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java

@@ -547,12 +547,12 @@ public final class EncryptionUtils {
         return Base64.decode(string, Base64.NO_WRAP);
     }
 
-    public static EncryptedFile encryptFile(File file, Cipher cipher) throws InvalidParameterSpecException {
-        // FIXME this won't work on low or write-protected storage
-        File encryptedFile = new File(file.getAbsolutePath() + ".enc.jpg");
-        encryptFileWithGivenCipher(file, encryptedFile, cipher);
+    public static EncryptedFile encryptFile(String accountName, File file, Cipher cipher) throws InvalidParameterSpecException, IOException {
+        File tempEncryptedFolder = FileDataStorageManager.createTempEncryptedFolder(accountName);
+        File tempEncryptedFile = File.createTempFile(file.getName(), null, tempEncryptedFolder);
+        encryptFileWithGivenCipher(file, tempEncryptedFile, cipher);
         String authenticationTagString = getAuthenticationTag(cipher);
-        return new EncryptedFile(encryptedFile, authenticationTagString);
+        return new EncryptedFile(tempEncryptedFile, authenticationTagString);
     }
 
     public static String getAuthenticationTag(Cipher cipher) throws InvalidParameterSpecException {
@@ -569,7 +569,7 @@ public final class EncryptionUtils {
     }
 
     public static void encryptFileWithGivenCipher(File inputFile, File encryptedFile, Cipher cipher) {
-        try( FileInputStream inputStream = new FileInputStream(inputFile);
+        try (FileInputStream inputStream = new FileInputStream(inputFile);
              FileOutputStream fileOutputStream = new FileOutputStream(encryptedFile);
              CipherOutputStream outputStream = new CipherOutputStream(fileOutputStream, cipher)) {
             byte[] buffer = new byte[4096];

+ 11 - 0
app/src/main/java/com/owncloud/android/utils/FileStorageUtils.java

@@ -106,6 +106,17 @@ public final class FileStorageUtils {
         // that can be in the accountName since 0.1.190B
     }
 
+    public static String getTemporalEncryptedFolderPath(String accountName) {
+        return MainApp
+            .getAppContext()
+            .getFilesDir()
+            .getAbsolutePath()
+            + File.separator
+            + accountName
+            + File.separator
+            + "temp_encrypted_folder";
+    }
+
     /**
      * Get absolute path to tmp folder inside app folder for given accountName.
      */

+ 83 - 43
app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java

@@ -20,7 +20,6 @@ import com.nextcloud.client.device.BatteryStatus;
 import com.nextcloud.client.device.PowerManagementService;
 import com.nextcloud.client.jobs.BackgroundJobManager;
 import com.nextcloud.client.jobs.upload.FileUploadHelper;
-import com.nextcloud.client.jobs.upload.FileUploadWorker;
 import com.nextcloud.client.network.ConnectivityService;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.FilesystemDataProvider;
@@ -55,6 +54,59 @@ public final class FilesSyncHelper {
         // utility class -> private constructor
     }
 
+    private static void insertCustomFolderIntoDB(Path path,
+                                                 SyncedFolder syncedFolder,
+                                                 FilesystemDataProvider filesystemDataProvider,
+                                                 long lastCheck,
+                                                 long thisCheck) {
+
+        final long enabledTimestampMs = syncedFolder.getEnabledTimestampMs();
+
+        try {
+            FileUtil.walkFileTree(path, new SimpleFileVisitor<>() {
+                @Override
+                public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
+                    File file = path.toFile();
+                    if (syncedFolder.isExcludeHidden() && file.isHidden()) {
+                        // exclude hidden file or folder
+                        return FileVisitResult.CONTINUE;
+                    }
+
+                    if (attrs.lastModifiedTime().toMillis() < lastCheck) {
+                        // skip files that were already checked
+                        return FileVisitResult.CONTINUE;
+                    }
+
+                    if (syncedFolder.isExisting() || attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) {
+                        // storeOrUpdateFileValue takes a few ms
+                        // -> Rest of this file check takes not even 1 ms.
+                        filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
+                                                                      attrs.lastModifiedTime().toMillis(),
+                                                                      file.isDirectory(), syncedFolder);
+                    }
+
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                    if (syncedFolder.isExcludeHidden() && dir.compareTo(Paths.get(syncedFolder.getLocalPath())) != 0 && dir.toFile().isHidden()) {
+                        return null;
+                    }
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFileFailed(Path file, IOException exc) {
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+            syncedFolder.setLastScanTimestampMs(thisCheck);
+        } catch (IOException e) {
+            Log_OC.e(TAG, "Something went wrong while indexing files for auto upload", e);
+        }
+    }
+
     private static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder) {
         final Context context = MainApp.getAppContext();
         final ContentResolver contentResolver = context.getContentResolver();
@@ -63,55 +115,33 @@ public final class FilesSyncHelper {
 
         if (syncedFolder.isEnabled() && (syncedFolder.isExisting() || enabledTimestampMs >= 0)) {
             MediaFolderType mediaType = syncedFolder.getType();
+            final long lastCheckTimestampMs = syncedFolder.getLastScanTimestampMs();
+            final long thisCheckTimestampMs = System.currentTimeMillis();
+
+            Log_OC.d(TAG,"File-sync start check folder "+syncedFolder.getLocalPath());
+            long startTime = System.nanoTime();
+
             if (mediaType == MediaFolderType.IMAGE) {
-                FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.INTERNAL_CONTENT_URI
-                    , syncedFolder);
+                FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
+                                                    syncedFolder,
+                                                    lastCheckTimestampMs, thisCheckTimestampMs);
                 FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
-                                                    syncedFolder);
+                                                    syncedFolder,
+                                                    lastCheckTimestampMs, thisCheckTimestampMs);
             } else if (mediaType == MediaFolderType.VIDEO) {
                 FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.INTERNAL_CONTENT_URI,
-                                                    syncedFolder);
+                                                    syncedFolder,
+                                                    lastCheckTimestampMs, thisCheckTimestampMs);
                 FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
-                                                    syncedFolder);
+                                                    syncedFolder,
+                                                    lastCheckTimestampMs, thisCheckTimestampMs);
             } else {
-                try {
                     FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
                     Path path = Paths.get(syncedFolder.getLocalPath());
-
-                    FileUtil.walkFileTree(path, new SimpleFileVisitor<Path>() {
-                        @Override
-                        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
-                            File file = path.toFile();
-                            if (syncedFolder.isExcludeHidden() && file.isHidden()) {
-                                // exclude hidden file or folder
-                                return FileVisitResult.CONTINUE;
-                            }
-                            if (syncedFolder.isExisting() || attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) {
-                                filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
-                                                                              attrs.lastModifiedTime().toMillis(),
-                                                                              file.isDirectory(), syncedFolder);
-                            }
-
-                            return FileVisitResult.CONTINUE;
-                        }
-
-                        @Override
-                        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
-                            if (syncedFolder.isExcludeHidden() && dir.compareTo(Paths.get(syncedFolder.getLocalPath())) != 0 && dir.toFile().isHidden()) {
-                                return null;
-                            }
-                            return FileVisitResult.CONTINUE;
-                        }
-
-                        @Override
-                        public FileVisitResult visitFileFailed(Path file, IOException exc) {
-                            return FileVisitResult.CONTINUE;
-                        }
-                    });
-                } catch (IOException e) {
-                    Log_OC.e(TAG, "Something went wrong while indexing files for auto upload", e);
-                }
+                    FilesSyncHelper.insertCustomFolderIntoDB(path, syncedFolder, filesystemDataProvider, lastCheckTimestampMs, thisCheckTimestampMs);
             }
+
+            Log_OC.d(TAG,"File-sync finished full check for custom folder "+syncedFolder.getLocalPath()+" within "+(System.nanoTime() - startTime)+ "ns");
         }
     }
 
@@ -160,7 +190,8 @@ public final class FilesSyncHelper {
         return filePath;
     }
 
-    private static void insertContentIntoDB(Uri uri, SyncedFolder syncedFolder) {
+    private static void insertContentIntoDB(Uri uri, SyncedFolder syncedFolder,
+                                            long lastCheckTimestampMs, long thisCheckTimestampMs) {
         final Context context = MainApp.getAppContext();
         final ContentResolver contentResolver = context.getContentResolver();
 
@@ -192,13 +223,22 @@ public final class FilesSyncHelper {
             while (cursor.moveToNext()) {
                 contentPath = cursor.getString(column_index_data);
                 isFolder = new File(contentPath).isDirectory();
-                if (syncedFolder.isExisting() || cursor.getLong(column_index_date_modified) >= enabledTimestampMs / 1000.0) {
+
+                if (syncedFolder.getLastScanTimestampMs() != SyncedFolder.NOT_SCANNED_YET &&
+                    cursor.getLong(column_index_date_modified) < (lastCheckTimestampMs / 1000)) {
+                    continue;
+                }
+
+                if (syncedFolder.isExisting() || cursor.getLong(column_index_date_modified) >= enabledTimestampMs / 1000) {
+                    // storeOrUpdateFileValue takes a few ms
+                    // -> Rest of this file check takes not even 1 ms.
                     filesystemDataProvider.storeOrUpdateFileValue(contentPath,
                                                                   cursor.getLong(column_index_date_modified), isFolder,
                                                                   syncedFolder);
                 }
             }
             cursor.close();
+            syncedFolder.setLastScanTimestampMs(thisCheckTimestampMs);
         }
     }
 

+ 0 - 15
app/src/main/res/drawable/ic_expand_less.xml

@@ -1,15 +0,0 @@
-<!--
-  ~ Nextcloud - Android Client
-  ~
-  ~ SPDX-FileCopyrightText: 2018-2024 Google LLC
-  ~ SPDX-License-Identifier: Apache-2.0
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="960"
-    android:viewportHeight="960">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="m296,615 l-56,-56 240,-240 240,240 -56,56 -184,-184 -184,184Z" />
-</vector>

+ 36 - 0
app/src/main/res/layout/toolbar_standard.xml

@@ -114,6 +114,42 @@
 
         </RelativeLayout>
 
+        <LinearLayout
+            android:id="@+id/toolbar_linear_layout"
+            android:visibility="gone"
+            tools:visibility="visible"
+            android:orientation="horizontal"
+            android:layout_marginStart="8dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginBottom="4dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/toolbar_menu_button"
+                style="@style/Widget.AppTheme.Button.IconButton"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                app:cornerRadius="@dimen/button_corner_radius"
+                app:icon="@drawable/ic_menu"
+                app:iconTint="@color/black" />
+
+            <com.google.android.material.textview.MaterialTextView
+                android:id="@+id/toolbar_title"
+                android:gravity="center"
+                android:textColor="@color/black"
+                android:lines="1"
+                android:textSize="16sp"
+                android:layout_width="wrap_content"
+                android:layout_height="48dp"/>
+
+        </LinearLayout>
+
+
         <!-- home/search toolbar -->
         <com.google.android.material.card.MaterialCardView
             android:id="@+id/home_toolbar"

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">فشل إنشاء الحساب</string>
     <string name="account_icon">أيقونة الحساب </string>
     <string name="account_not_found">الحساب غير موجود </string>
-    <string name="action_clear_failed_uploads">مسح الملفات التي فشل رفعها</string>
     <string name="action_edit">تعديل</string>
     <string name="action_empty_notifications">إزالة جميع التنبيهات</string>
     <string name="action_empty_trashbin">تفريغ سلة المهملات</string>
@@ -57,6 +56,8 @@
     <string name="assistant_screen_task_types_error_state_message">تعذّر جلب أنواع المهام. قم رجاءً بالتحقُّق من اتصالك بالإنترنت.</string>
     <string name="assistant_screen_top_bar_title">المُساعِد</string>
     <string name="assistant_screen_unknown_task_status_text">غير معروف</string>
+    <string name="assistant_task_detail_screen_input_button_title">مُدخَلات</string>
+    <string name="assistant_task_detail_screen_output_button_title">المُخرَجَات</string>
     <string name="associated_account_not_found">الحساب المرتبط غير موجود!</string>
     <string name="auth_access_failed">فشل الوصول لـ: %1$s</string>
     <string name="auth_account_does_not_exist">هذا الحساب لم تتم إضافته في هذا الجهاز بعد</string>
@@ -171,7 +172,7 @@
     <string name="confirmation_remove_folder_alert">هل توَدُّ حقاً حذف %1$s وما يحتويه؟</string>
     <string name="confirmation_remove_folders_alert">هل توَدُّ حقاً حذف العناصر المختارة وما يحتوّه؟</string>
     <string name="confirmation_remove_local">محلياً فقط</string>
-    <string name="conflict_dialog_error">خطأ في إنشاء حوار التعارض!</string>
+    <string name="conflict_dialog_error">تعذّر إنشاء نافذة حوار لحل التعارضات</string>
     <string name="conflict_file_headline">ملف متضارب %1$s </string>
     <string name="conflict_local_file">ملف محلي</string>
     <string name="conflict_message_description">إذا قمت باختيار كلا الاصدارين, الملف المحلي سيحتوي على رقم ملحق باسم الملف.</string>

+ 4 - 2
app/src/main/res/values-b+en+001/strings.xml

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Account creation failed</string>
     <string name="account_icon">Account icon</string>
     <string name="account_not_found">Account not found!</string>
-    <string name="action_clear_failed_uploads">Clear failed uploads</string>
     <string name="action_edit">Edit</string>
     <string name="action_empty_notifications">Clear all notifications</string>
     <string name="action_empty_trashbin">Empty trash bin</string>
@@ -45,6 +44,7 @@
     <string name="assistant_screen_loading">Task List are loading, please wait</string>
     <string name="assistant_screen_no_task_available_for_all_task_filter_text">No task available. Select a task type to create a new task.</string>
     <string name="assistant_screen_no_task_available_text">No task available for %s task type, you can create a new task from bottom right.</string>
+    <string name="assistant_screen_running_task_text">In Progress</string>
     <string name="assistant_screen_scheduled_task_status_text">Scheduled</string>
     <string name="assistant_screen_successful_task_text">Completed</string>
     <string name="assistant_screen_task_create_fail_message">An error occurred while creating the task</string>
@@ -56,6 +56,8 @@
     <string name="assistant_screen_task_types_error_state_message">Unable to fetch task types, please check your internet connection.</string>
     <string name="assistant_screen_top_bar_title">Assistant</string>
     <string name="assistant_screen_unknown_task_status_text">Unknown</string>
+    <string name="assistant_task_detail_screen_input_button_title">Input</string>
+    <string name="assistant_task_detail_screen_output_button_title">Output</string>
     <string name="associated_account_not_found">Associated account not found!</string>
     <string name="auth_access_failed">Access failed: %1$s</string>
     <string name="auth_account_does_not_exist">The account is not added on this device yet</string>
@@ -170,7 +172,7 @@
     <string name="confirmation_remove_folder_alert">Do you really want to delete %1$s and its content?</string>
     <string name="confirmation_remove_folders_alert">Do you really want to delete the selected items and their contents?</string>
     <string name="confirmation_remove_local">Local only</string>
-    <string name="conflict_dialog_error">Error creating conflict dialogue!</string>
+    <string name="conflict_dialog_error">Conflict resolver dialogue cannot be created</string>
     <string name="conflict_file_headline">Conflicting file %1$s</string>
     <string name="conflict_local_file">Local file</string>
     <string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Създаването на профила се провали</string>
     <string name="account_icon">Профил</string>
     <string name="account_not_found">Няма намерен профил!</string>
-    <string name="action_clear_failed_uploads">Изчисти провалените качвания</string>
     <string name="action_edit">Променяне</string>
     <string name="action_empty_notifications">Премахнете известията</string>
     <string name="action_empty_trashbin">Изпразване на кошчето</string>
@@ -153,7 +152,6 @@
     <string name="confirmation_remove_folder_alert">Наистина ли желаете %1$s и съдържанието ѝ да бъдат изтрито?</string>
     <string name="confirmation_remove_folders_alert">Наистина ли желаете избраните елементи и съдържанието им да бъдат премахнати?</string>
     <string name="confirmation_remove_local">Само локално</string>
-    <string name="conflict_dialog_error">Грешка при създаване на диалог за конфликт!</string>
     <string name="conflict_file_headline">Несъвместим файл %1$s</string>
     <string name="conflict_local_file">Локален файл</string>
     <string name="conflict_message_description">Ако изберете и двете версии, ще бъде добавен номер към името на локалния файл.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">C\'hwitet eo bet ar c\'houiñ eus anr c\'hont</string>
     <string name="account_icon">Ikonenn kont</string>
     <string name="account_not_found">N\'o ket bet kavet ar c\'hont</string>
-    <string name="action_clear_failed_uploads">Lemmel ar pellgasoù chwitet</string>
     <string name="action_edit">Cheñch</string>
     <string name="action_empty_notifications">Lemmel toud ar c\'hemenadennoù</string>
     <string name="action_send_share">Kas/Rannan</string>
@@ -136,7 +135,6 @@
     <string name="confirmation_remove_folder_alert">Sur oc\'h lemel %1$s ha pep tra a zo barzh ?</string>
     <string name="confirmation_remove_folders_alert">Sur oc\'h lemel an traoù choazet ha pep tra a zo barzh ?</string>
     <string name="confirmation_remove_local">E-berzh nemetken</string>
-    <string name="conflict_dialog_error">Ur fazi en deus krouet divizoù diemglev !</string>
     <string name="conflict_message_description">Ma choazit an daou stumm, ar restr diabarzh en do un niver ouzhpennet war e anv.</string>
     <string name="contactlist_item_icon">Skeudenn  implijer evit ar roll darempredoù</string>
     <string name="contactlist_no_permission">Oaetre ebet roet, netra a zo bet emporzhiet.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Ha fallat la creació del compte</string>
     <string name="account_icon">Icona del compte</string>
     <string name="account_not_found">No s\'ha trobat el compte!</string>
-    <string name="action_clear_failed_uploads">Esborra les pujades amb errors</string>
     <string name="action_edit">Edita</string>
     <string name="action_empty_notifications">Neteja totes les notificacions</string>
     <string name="action_empty_trashbin">Buida la paperera</string>
@@ -152,7 +151,6 @@
     <string name="confirmation_remove_folder_alert">Esteu segur que voleu suprimir %1$s i els seus continguts?</string>
     <string name="confirmation_remove_folders_alert">Esteu segur que voleu suprimir els elements seleccionats i el seu contingut?</string>
     <string name="confirmation_remove_local">Només local</string>
-    <string name="conflict_dialog_error">Error creant diàleg de conflicte!</string>
     <string name="conflict_file_headline">Fitxer en conflicte %1$s</string>
     <string name="conflict_local_file">Fitxer local</string>
     <string name="conflict_message_description">Si seleccioneu ambdues versions, s\'afegirà un numero al nom del fitxer local.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Vytvoření účtu se nezdařilo</string>
     <string name="account_icon">Ikona účtu</string>
     <string name="account_not_found">Účet nenalezen!</string>
-    <string name="action_clear_failed_uploads">Vyčistit nezdařená nahrávání</string>
     <string name="action_edit">Upravit</string>
     <string name="action_empty_notifications">Vyčistit všechna upozornění</string>
     <string name="action_empty_trashbin">Vyprázdnit koš</string>
@@ -43,6 +42,7 @@
     <string name="assistant_screen_successful_task_text">Dokončeno</string>
     <string name="assistant_screen_task_delete_success_message">Úloha úspěšně smazána</string>
     <string name="assistant_screen_unknown_task_status_text">Neznámé</string>
+    <string name="assistant_task_detail_screen_output_button_title">Výstup</string>
     <string name="associated_account_not_found">Související účet nenalezen!</string>
     <string name="auth_access_failed">Přístup se nezdařil: %1$s</string>
     <string name="auth_account_does_not_exist">Účet zatím není na tomto zařízení přidán</string>
@@ -157,7 +157,6 @@
     <string name="confirmation_remove_folder_alert">Opravdu chcete %1$s a jeho obsah odstranit?</string>
     <string name="confirmation_remove_folders_alert">Opravdu chcete vybrané položky a jejich obsah odstranit?</string>
     <string name="confirmation_remove_local">Pouze místní</string>
-    <string name="conflict_dialog_error">Chyba při vytváření dialogu ke konfliktu!</string>
     <string name="conflict_file_headline">Kolidující soubor %1$s</string>
     <string name="conflict_local_file">Místní soubor</string>
     <string name="conflict_message_description">Pokud zvolíte obě verze, k názvu místního souboru bude připojeno číslo.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Fejl ved oprettelse af konto</string>
     <string name="account_icon">Kontoikon</string>
     <string name="account_not_found">Konto blev ikke fundet.</string>
-    <string name="action_clear_failed_uploads">Fjern fejlede uploads</string>
     <string name="action_edit">Redigér</string>
     <string name="action_empty_notifications">Ryd alle notifikationer</string>
     <string name="action_empty_trashbin">Tøm papirkurv</string>
@@ -47,6 +46,7 @@
     <string name="assistant_screen_scheduled_task_status_text">Planlagt</string>
     <string name="assistant_screen_successful_task_text">Fuldført</string>
     <string name="assistant_screen_task_create_success_message">Opgaven er oprettet</string>
+    <string name="assistant_screen_task_delete_fail_message">En fejl opstod under sletning af opgaven</string>
     <string name="assistant_screen_task_delete_success_message">Opgaven er slettet</string>
     <string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Slet opgave</string>
     <string name="assistant_screen_top_bar_title">Assistent</string>
@@ -164,7 +164,6 @@
     <string name="confirmation_remove_folder_alert">Er du sikker på at du vil slette %1$s med indhold?</string>
     <string name="confirmation_remove_folders_alert">Er du sikker på at du vil slette de valgte artikler med indhold?</string>
     <string name="confirmation_remove_local">Kun lokal</string>
-    <string name="conflict_dialog_error">Fejl ved skabelse af konfliktdialog</string>
     <string name="conflict_file_headline">Fil i konflikt %1$s</string>
     <string name="conflict_local_file">Lokal fil</string>
     <string name="conflict_message_description">Hvis du vælger begge versioner, vil den lokale fil få tilføjet et nummer til sit navn.</string>
@@ -354,6 +353,7 @@
     <string name="file_list_empty_shared_headline">Intet er delt endnu</string>
     <string name="file_list_empty_unified_search_no_results">Ingen resultater fundet for din forespørgsel</string>
     <string name="file_list_folder">mappe</string>
+    <string name="file_list_live">LIVE</string>
     <string name="file_list_loading">Indlæser...</string>
     <string name="file_list_no_app_for_file_type">Ingen app er sat op til at håndtere denne filtype.</string>
     <string name="file_list_seconds_ago">sekunder siden</string>
@@ -592,6 +592,7 @@
     <string name="prefs_category_dev">Udvikling</string>
     <string name="prefs_category_general">Generel</string>
     <string name="prefs_category_more">Mere</string>
+    <string name="prefs_daily_backup_summary">Daglig backup af din kalender og kontakter</string>
     <string name="prefs_daily_contact_backup_summary">Daglig backup af dine kontakter</string>
     <string name="prefs_davx5_setup_error">Uventet fejl under opsætning af DAVx5 (tidligere kendt som DAVdroid)</string>
     <string name="prefs_e2e_active">End-to-end kryptering er blevet konfigureret!</string>
@@ -665,6 +666,7 @@ Enheds legitimationsoplysninger er sat op
     <string name="rename_local_fail_msg">Lokal kopi kunne ikke omdøbes, prøv et andet navn</string>
     <string name="rename_server_fail_msg">Omdøbning ikke mulig, navnet eksisterer</string>
     <string name="request_account_deletion">Anmodning om sletning af konto</string>
+    <string name="request_account_deletion_button">Anmod om sletning</string>
     <string name="reshare_not_allowed">Gendeling er ikke tilladt</string>
     <string name="resharing_is_not_allowed">Videredeling ikke tilladt</string>
     <string name="resized_image_not_possible_download">Intet skaleret billede tilgængeligt. Hent fuldt billede?</string>
@@ -685,9 +687,11 @@ Enheds legitimationsoplysninger er sat op
     <string name="screenshot_04_accounts_heading">Alle dine konti</string>
     <string name="screenshot_04_accounts_subline">på et sted</string>
     <string name="screenshot_05_autoUpload_heading">Automatisk upload</string>
+    <string name="screenshot_05_autoUpload_subline">for dine billeder og videoer</string>
     <string name="screenshot_06_davdroid_heading">Kalender og kontakter</string>
     <string name="screenshot_06_davdroid_subline">Synkronisér med DAVx5</string>
     <string name="search_error">Fejl ved indhenting af søgeresultater</string>
+    <string name="secure_share_not_set_up">Sikker deling er ikke sat op for denne bruger</string>
     <string name="select_all">Vælg alle</string>
     <string name="select_media_folder">Indstil mediemappe</string>
     <string name="select_one_template">Vælg venligst en skabelon</string>
@@ -800,6 +804,7 @@ Enheds legitimationsoplysninger er sat op
     <string name="subject_shared_with_you">\"%1$s\" er blevet delt med dig</string>
     <string name="subject_user_shared_with_you">%1$s delte \"%2$s\" med dig</string>
     <string name="subtitle_photos_only">Kun billeder</string>
+    <string name="subtitle_photos_videos">Billeder og videoer</string>
     <string name="subtitle_videos_only">Kun videoer</string>
     <string name="suggest">Foreslå</string>
     <string name="sync_conflicts_in_favourites_ticker">Konflikter fundet</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Kontoerstellung fehlgeschlagen</string>
     <string name="account_icon">Konto-Icon</string>
     <string name="account_not_found">Kein Konto gefunden</string>
-    <string name="action_clear_failed_uploads">Fehlgeschlagene Uploads entfernen</string>
     <string name="action_edit">Bearbeiten</string>
     <string name="action_empty_notifications">Alle Benachrichtigungen löschen</string>
     <string name="action_empty_trashbin">Papierkorb leeren</string>
@@ -57,6 +56,8 @@
     <string name="assistant_screen_task_types_error_state_message">Die Aufgabentypen können nicht abgerufen werden. Bitte überprüfen Sie Ihre Internetverbindung.</string>
     <string name="assistant_screen_top_bar_title">Assistent</string>
     <string name="assistant_screen_unknown_task_status_text">Unbekannt</string>
+    <string name="assistant_task_detail_screen_input_button_title">Eingabe</string>
+    <string name="assistant_task_detail_screen_output_button_title">Ausgabe</string>
     <string name="associated_account_not_found">Verknüpftes Konto nicht gefunden!</string>
     <string name="auth_access_failed">Zugriffsfehler: %1$s</string>
     <string name="auth_account_does_not_exist">Das Konto ist bislang auf dem Gerät nicht vorhanden</string>
@@ -171,7 +172,7 @@
     <string name="confirmation_remove_folder_alert">Wollen Sie %1$s und deren Inhalte wirklich löschen?</string>
     <string name="confirmation_remove_folders_alert">Möchten Sie die ausgewählten Elemente und deren inhalt wirklich löschen?</string>
     <string name="confirmation_remove_local">Nur lokal</string>
-    <string name="conflict_dialog_error">Fehler beim Erstellen des Konfliktdialoges</string>
+    <string name="conflict_dialog_error">Konfliktlösungsdialog konnte nicht erstellt werden</string>
     <string name="conflict_file_headline">Konflikt-Datei %1$s</string>
     <string name="conflict_local_file">Lokale Datei</string>
     <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>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Αποτυχία δημιουργίας λογαριασμού</string>
     <string name="account_icon">Εικονίδιο λογαριασμού</string>
     <string name="account_not_found">Δεν βρέθηκε λογαριασμός!</string>
-    <string name="action_clear_failed_uploads">Εκκαθάριση αποτυχημένων μεταφορτώσεων</string>
     <string name="action_edit">Επεξεργασία</string>
     <string name="action_empty_notifications">Εκκαθάριση ειδοποιήσεων</string>
     <string name="action_empty_trashbin">Άδειασμα απορριμάτων</string>
@@ -151,7 +150,6 @@
     <string name="confirmation_remove_folder_alert">Θέλετε σίγουρα να διαγράψετε το %1$s και τα περιεχόμενά του;</string>
     <string name="confirmation_remove_folders_alert">Θέλετε να διαγράψετε τα επιλεγμένα αντικείμενα και τα περιεχόμενά τους;</string>
     <string name="confirmation_remove_local">Μόνο τοπικά</string>
-    <string name="conflict_dialog_error">Σφάλμα δημιουργίας αναφοράς διένεξης!</string>
     <string name="conflict_file_headline">Αρχείο σε αντίφαση %1$s</string>
     <string name="conflict_local_file">Τοπικό αρχείο</string>
     <string name="conflict_message_description">Εάν επιλέξετε και τις δύο εκδόσεις, στο όνομα του τοπικού αρχείου θα προστεθεί ένας αριθμός.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Kreado de konto malsukcesis</string>
     <string name="account_icon">Konta piktogramo</string>
     <string name="account_not_found">Konto ne trovita!</string>
-    <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>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Falló la creación de la carpeta</string>
     <string name="account_icon">Icono de cuenta</string>
     <string name="account_not_found">Cuenta no encontrada!</string>
-    <string name="action_clear_failed_uploads">Borrar subidas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Borrar todas las notificaciones</string>
     <string name="action_empty_trashbin">Vaciar la papelera</string>
@@ -150,7 +149,6 @@
     <string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y su contenido?</string>
     <string name="confirmation_remove_folders_alert">¿Realmente desea eliminar los elementos seleccionados y sus contenidos?</string>
     <string name="confirmation_remove_local">Sólo local</string>
-    <string name="conflict_dialog_error">¡Error al crear el diálogo de conflicto!</string>
     <string name="conflict_file_headline">Archivo en conflicto %1$s</string>
     <string name="conflict_local_file">Archivo local</string>
     <string name="conflict_message_description">Si selecciona ambas versiones, se le agregará un número al nombre del archivo copiado.</string>

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

@@ -5,7 +5,6 @@
     <string name="about_version">versión %1$s</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_send_share">Enviar/Compartir</string>
     <string name="action_switch_grid_view">Vista de cuadrícula</string>

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

@@ -6,7 +6,6 @@
     <string name="account_creation_failed">Fallo en la creación de la cuenta</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Borrar todas las notificaciones</string>
     <string name="action_empty_trashbin">Vacíar la papelera</string>

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

@@ -5,7 +5,6 @@
     <string name="about_version">versión %1$s</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_send_share">Enviar/Compartir</string>
     <string name="action_switch_grid_view">Vista de cuadrícula</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Error al crear la cuenta</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Borrar todas las notificaciones</string>
     <string name="action_send_share">Enviar/Compartir</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Creación de cuenta fallida</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Borrar todas las notificaciones</string>
     <string name="action_empty_trashbin">Eliminar papelera de reciclaje</string>
@@ -153,7 +152,6 @@
     <string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y sus contenidos? </string>
     <string name="confirmation_remove_folders_alert">¿Reamente deseas eliminar los elementos seleccionados y sus contenidos?</string>
     <string name="confirmation_remove_local">Sólo local</string>
-    <string name="conflict_dialog_error">¡Error al crear el diálogo de conflicto!</string>
     <string name="conflict_file_headline">Archivo en conflicto %1$s</string>
     <string name="conflict_local_file">Archivo local</string>
     <string name="conflict_message_description">Si selecciona ambas versiones, el archivo local tendrá un número agregado a su nombre.</string>

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

@@ -5,7 +5,6 @@
     <string name="about_version">versión %1$s</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_send_share">Enviar/Compartir</string>
     <string name="action_switch_grid_view">Vista de cuadrícula</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Falló la creación de la cuenta</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Limpiar todas las notificaciones</string>
     <string name="action_empty_trashbin">Vaciar la papelera de reciclaje</string>
@@ -171,7 +170,6 @@
     <string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y sus contenidos? </string>
     <string name="confirmation_remove_folders_alert">¿Reamente deseas eliminar los elementos seleccionados y sus contenidos?</string>
     <string name="confirmation_remove_local">Sólo local</string>
-    <string name="conflict_dialog_error">¡Se presentó un error al crear el diálogo de conflictos!</string>
     <string name="conflict_file_headline">Archivo conflictivo %1$s</string>
     <string name="conflict_local_file">Archivo local</string>
     <string name="conflict_message_description">Si seleccionas ambas versiones, el archivo local tendrá un número al final del nombre.</string>

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

@@ -5,7 +5,6 @@
     <string name="about_version">versión %1$s</string>
     <string name="account_icon">Ícono de la cuenta</string>
     <string name="account_not_found">¡No se encontró la cuenta!</string>
-    <string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_send_share">Enviar/Compartir</string>
     <string name="action_switch_grid_view">Vista de cuadrícula</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Ha fallado la creación de la cuenta</string>
     <string name="account_icon">Icono de la cuenta</string>
     <string name="account_not_found">¡Cuenta no encontrada!</string>
-    <string name="action_clear_failed_uploads">Borrar subidas fallidas</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Limpiar todas las notificaciones</string>
     <string name="action_empty_trashbin">Vaciar papelera</string>
@@ -47,6 +46,8 @@
     <string name="assistant_screen_task_delete_success_message">¡La tarea fue eliminada exitósamente!</string>
     <string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Eliminar tarea</string>
     <string name="assistant_screen_unknown_task_status_text">Desconocido</string>
+    <string name="assistant_task_detail_screen_input_button_title">Entrada</string>
+    <string name="assistant_task_detail_screen_output_button_title">Salida</string>
     <string name="associated_account_not_found">¡Cuenta asociada no encontrada!</string>
     <string name="auth_access_failed">Acceso fallido: %1$s</string>
     <string name="auth_account_does_not_exist">La cuenta no se ha añadido aún en este dispositivo</string>
@@ -160,7 +161,6 @@
     <string name="confirmation_remove_folder_alert">¿Realmente deseas eliminar %1$s y todo su contenido?</string>
     <string name="confirmation_remove_folders_alert">¿Estás seguro de que quieres eliminar los elementos seleccionados y sus contenidos?</string>
     <string name="confirmation_remove_local">Solo local</string>
-    <string name="conflict_dialog_error">¡Error al crear el diálogo de conflicto!</string>
     <string name="conflict_file_headline">Conflicto en archivo %1$s</string>
     <string name="conflict_local_file">Archivo local</string>
     <string name="conflict_message_description">Si seleccionas ambas versiones, el archivo local tendrá un número añadido a su nombre.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Konto loomine ebaõnnestus</string>
     <string name="account_icon">Konto ikoon</string>
     <string name="account_not_found">Kontot ei leitud!</string>
-    <string name="action_clear_failed_uploads">Puhasta ebaõnnestunud üleslaadimised</string>
     <string name="action_edit">Redigeeri</string>
     <string name="action_empty_notifications">Kustuta kõik teavitused</string>
     <string name="action_empty_trashbin">Tühjenda prügikast</string>
@@ -136,7 +135,6 @@
     <string name="confirmation_remove_folder_alert">Oled sa kindel, et soovid %1$s ja selle sisu kustutada?</string>
     <string name="confirmation_remove_folders_alert">Oled sa kindel, et soovid valitud objektid ja nende sisud kustutada?</string>
     <string name="confirmation_remove_local">Ainult kohalik</string>
-    <string name="conflict_dialog_error">Konfliktidialoogi loomine ebaõnnestus!</string>
     <string name="conflict_local_file">Kohalik fail</string>
     <string name="conflict_message_description">Kui valid mõlemad versioonid, siis lisatakse kohaliku faili nimele number.</string>
     <string name="conflict_server_file">Serveri fail</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Kontuaren sorrerak huts egin du</string>
     <string name="account_icon">Kontuaren ikonoa</string>
     <string name="account_not_found">Ez da kontua aurkitu!</string>
-    <string name="action_clear_failed_uploads">Garbitu huts egin duten igoerak</string>
     <string name="action_edit">Aldatu</string>
     <string name="action_empty_notifications">Garbitu jakinarazpen guztiak</string>
     <string name="action_empty_trashbin">Hustu zakarrontzia</string>
@@ -47,6 +46,8 @@
     <string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Ezabatu zeregina</string>
     <string name="assistant_screen_top_bar_title">Morroia</string>
     <string name="assistant_screen_unknown_task_status_text">Ezezaguna</string>
+    <string name="assistant_task_detail_screen_input_button_title">Sarrera</string>
+    <string name="assistant_task_detail_screen_output_button_title">Irteera</string>
     <string name="associated_account_not_found">Ez da aurkitu lotutako konturik</string>
     <string name="auth_access_failed">Huts egin du atzitzean: %1$s</string>
     <string name="auth_account_does_not_exist">Kontua ez da gailu honetan gehitu oraindik</string>
@@ -161,7 +162,6 @@
     <string name="confirmation_remove_folder_alert">Ziur zaude %1$s eta bere edukia ezabatu nahi duzula?</string>
     <string name="confirmation_remove_folders_alert">Ziur zaude hautatutako elementuak eta beren edukiak ezabatu nahi dituzula?</string>
     <string name="confirmation_remove_local">Lokala bakarrik</string>
-    <string name="conflict_dialog_error">Errorea gatazkaren elkarrizketa-koadroa sortzean!</string>
     <string name="conflict_file_headline">%1$sfitxategi gatazkatsua</string>
     <string name="conflict_local_file">Fitxategi lokala</string>
     <string name="conflict_message_description">Bi bertsioak hautatzen badituzu, fitxategi lokalaren izenari zenbaki bat gehituko zaio.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">ایجاد حساب ناموفق بود</string>
     <string name="account_icon">آیکون حساب</string>
     <string name="account_not_found">حساب پیدا نشد!</string>
-    <string name="action_clear_failed_uploads">پاک کردن آپلودهای ناموفق</string>
     <string name="action_edit">ویرایش</string>
     <string name="action_empty_notifications">پاک کردن تمام اعلانها</string>
     <string name="action_empty_trashbin">خالی کردن سطل زباله</string>
@@ -158,7 +157,6 @@
     <string name="confirmation_remove_folder_alert">آیا واقعا می خواهید %1$s و محتویات آن را حذف کنید؟</string>
     <string name="confirmation_remove_folders_alert">آیا واقعاً می‌خواهید موارد انتخاب شده و محتوای آنها حذف شود؟</string>
     <string name="confirmation_remove_local">فقط محلی</string>
-    <string name="conflict_dialog_error">هنگام ساختن دیالوگ مغایرت‌ها خطایی رخ داده است!</string>
     <string name="conflict_file_headline">فایل متناقض %1$s</string>
     <string name="conflict_local_file">پروندهٔ محلّی</string>
     <string name="conflict_message_description">اگر هردو نسخه را انتخاب کنید، یک شماره به نام فایل محلی اضافه خواهد شد.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Tilin luonti epäonnistui</string>
     <string name="account_icon">Tilikuvake</string>
     <string name="account_not_found">Tiliä ei löydy!</string>
-    <string name="action_clear_failed_uploads">Tyhjennä epäonnistuneet lähetykset</string>
     <string name="action_edit">Muokkaa</string>
     <string name="action_empty_notifications">Hylkää kaikki ilmoitukset</string>
     <string name="action_empty_trashbin">Tyhjennä roskakori</string>
@@ -158,7 +157,6 @@
     <string name="confirmation_remove_folder_alert">Haluatko varmasti poistaa kohteen %1$s ja sen sisällön?</string>
     <string name="confirmation_remove_folders_alert">Haluatko varmasti poistaa valitut kohteet ja niiden sisällön?</string>
     <string name="confirmation_remove_local">Vain paikallisen</string>
-    <string name="conflict_dialog_error">Virhe konfliktitietojen näyttämisessä!</string>
     <string name="conflict_file_headline">Ristiriitainen kohde %1$s</string>
     <string name="conflict_local_file">Paikallinen tiedosto</string>
     <string name="conflict_message_description">Jos valitset molemmat versiot, paikallisen tiedoston nimeen lisätään numero.</string>

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

@@ -7,16 +7,15 @@
     <string name="account_creation_failed">Échec de création du compte</string>
     <string name="account_icon">Icône du compte</string>
     <string name="account_not_found">Compte introuvable !</string>
-    <string name="action_clear_failed_uploads">Effacer les téléversements échoués</string>
     <string name="action_edit">Modifier</string>
     <string name="action_empty_notifications">Effacer toutes les notifications</string>
     <string name="action_empty_trashbin">Vider la corbeille</string>
     <string name="action_send_share">Envoyer / Partager</string>
     <string name="action_switch_grid_view">Affichage mosaïque</string>
     <string name="action_switch_list_view">Affichage liste</string>
-    <string name="actionbar_calendar_contacts_restore">Restore contacts and calendar</string>
+    <string name="actionbar_calendar_contacts_restore">Restaurer les contacts et l’agenda</string>
     <string name="actionbar_mkdir">Nouveau dossier</string>
-    <string name="actionbar_move_or_copy">Move or Copy</string>
+    <string name="actionbar_move_or_copy">Déplacer ou copier</string>
     <string name="actionbar_open_with">Ouvrir avec</string>
     <string name="actionbar_search">Rechercher</string>
     <string name="actionbar_see_details">Propriétés</string>
@@ -37,26 +36,28 @@
     <string name="allow_resharing">Autoriser le repartage</string>
     <string name="app_widget_description">Affiche un widget du tableau de bord</string>
     <string name="appbar_search_in">Recherche dans %s</string>
-    <string name="assistant_screen_all_task_type">All</string>
-    <string name="assistant_screen_create_task_alert_dialog_input_field_placeholder">Type some text</string>
-    <string name="assistant_screen_delete_task_alert_dialog_description">Are you sure you want to delete this task?</string>
-    <string name="assistant_screen_delete_task_alert_dialog_title">Delete Task</string>
+    <string name="assistant_screen_all_task_type">Tout</string>
+    <string name="assistant_screen_create_task_alert_dialog_input_field_placeholder">Tapez du texte</string>
+    <string name="assistant_screen_delete_task_alert_dialog_description">Êtes-vous sûr de vouloir supprimer cette tâche ?</string>
+    <string name="assistant_screen_delete_task_alert_dialog_title">Supprimer la tâche</string>
     <string name="assistant_screen_failed_task_text">Échec</string>
-    <string name="assistant_screen_loading">Task List are loading, please wait</string>
-    <string name="assistant_screen_no_task_available_for_all_task_filter_text">No task available. Select a task type to create a new task.</string>
-    <string name="assistant_screen_no_task_available_text">No task available for %s task type, you can create a new task from bottom right.</string>
+    <string name="assistant_screen_loading">La liste des tâches charge, veuillez patienter</string>
+    <string name="assistant_screen_no_task_available_for_all_task_filter_text">Aucune tâche disponible. Sélectionner un type de tâche pour créer une nouvelle tâche.</string>
+    <string name="assistant_screen_no_task_available_text">Aucune tâche disponible pour le type de tâche %s, vous pouvez créer une nouvelle tâche en bas à droite.</string>
     <string name="assistant_screen_running_task_text">En cours</string>
     <string name="assistant_screen_scheduled_task_status_text">Planifié</string>
     <string name="assistant_screen_successful_task_text">Terminé</string>
-    <string name="assistant_screen_task_create_fail_message">An error occurred while creating the task</string>
-    <string name="assistant_screen_task_create_success_message">Task successfully created</string>
+    <string name="assistant_screen_task_create_fail_message">Une erreur est survenue lors de la création de la tâche</string>
+    <string name="assistant_screen_task_create_success_message">La tâche a bien été créée</string>
     <string name="assistant_screen_task_delete_fail_message">Une erreur est survenue lors de la suppression de la tâche</string>
     <string name="assistant_screen_task_delete_success_message">Tâche supprimée avec succès</string>
     <string name="assistant_screen_task_list_error_state_message">Impossible de récupérer la liste des tâches, veuillez vérifier votre connexion Internet.</string>
-    <string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Delete Task</string>
+    <string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Supprimer la tâche</string>
     <string name="assistant_screen_task_types_error_state_message">Impossible de récupérer les types des tâches, veuillez vérifier votre connexion Internet.</string>
     <string name="assistant_screen_top_bar_title">Assistant</string>
     <string name="assistant_screen_unknown_task_status_text">Inconnu</string>
+    <string name="assistant_task_detail_screen_input_button_title">Entrée</string>
+    <string name="assistant_task_detail_screen_output_button_title">Sortie</string>
     <string name="associated_account_not_found">Compte associé introuvable !</string>
     <string name="auth_access_failed">L\'accès a échoué: %1$s</string>
     <string name="auth_account_does_not_exist">Le compte n\'est pas encore ajouté sur cet appareil</string>
@@ -95,11 +96,11 @@
     <string name="autoupload_custom_folder">Définir un dossier personnalisé</string>
     <string name="autoupload_disable_power_save_check">Désactiver l\'économie de batterie</string>
     <string name="autoupload_hide_folder">Masquer le dossier</string>
-    <string name="autoupload_worker_foreground_info">Preparing auto upload</string>
+    <string name="autoupload_worker_foreground_info">Préparation du téléversement automatique</string>
     <string name="avatar">Avatar</string>
     <string name="away">Absent</string>
     <string name="backup_settings">Paramètres de sauvegarde</string>
-    <string name="backup_title">Contacts and calendar backup</string>
+    <string name="backup_title">Sauvegarder les contacts et l’agenda</string>
     <string name="battery_optimization_close">Fermer</string>
     <string name="battery_optimization_disable">Désactiver</string>
     <string name="battery_optimization_message">L\'optimisation de la batterie est peut-être active sur votre appareil. Le téléversement automatique ne fonctionne correctement que si vous excluez cette application de l\'optimisation.</string>
@@ -171,13 +172,12 @@
     <string name="confirmation_remove_folder_alert">Voulez-vous vraiment supprimer %1$s et ses contenus ?</string>
     <string name="confirmation_remove_folders_alert">Souhaitez-vous vraiment supprimer les éléments sélectionnés ainsi que leurs contenus ?</string>
     <string name="confirmation_remove_local">Local seulement</string>
-    <string name="conflict_dialog_error">Une erreur qui crée un dialogue conflictuel !</string>
     <string name="conflict_file_headline">Fichier %1$s en conflit</string>
     <string name="conflict_local_file">fichier local</string>
     <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">Contact permission is required.</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>
@@ -246,10 +246,10 @@
     <string name="downloader_download_in_progress_ticker">Réception en cours…</string>
     <string name="downloader_download_succeeded_content">%1$s reçu</string>
     <string name="downloader_download_succeeded_ticker">Reçu</string>
-    <string name="downloader_file_download_cancelled">Certain files were canceled during the download by user</string>
-    <string name="downloader_file_download_failed">Error occurred while downloading files</string>
+    <string name="downloader_file_download_cancelled">Certains fichiers ont été annulés pendant le téléchargement par l’utilisateur</string>
+    <string name="downloader_file_download_failed">Une erreur est survenue lors du téléchargement des fichiers</string>
     <string name="downloader_not_downloaded_yet">Pas encore téléchargé</string>
-    <string name="downloader_unexpected_error">Unexpected error occurred while downloading files</string>
+    <string name="downloader_unexpected_error">Erreur inattendue survenue lors du téléchargement des fichiers</string>
     <string name="drawer_close">Fermer le panneau latéral</string>
     <string name="drawer_community">Communauté</string>
     <string name="drawer_header_background">Image d’arrière-plan de l’en-tête du menu-tiroir</string>
@@ -262,7 +262,7 @@
     <string name="drawer_item_home">Accueil</string>
     <string name="drawer_item_notifications">Notifications</string>
     <string name="drawer_item_on_device">Sur l’appareil</string>
-    <string name="drawer_item_personal_files">Personal files</string>
+    <string name="drawer_item_personal_files">Fichiers personnels</string>
     <string name="drawer_item_recently_modified">Modifiés récemment</string>
     <string name="drawer_item_shared">Partagé</string>
     <string name="drawer_item_trashbin">Fichiers supprimés</string>
@@ -281,7 +281,7 @@
     <string name="ecosystem_apps_more">Plus d’applications Nextcloud</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="email_pick_failed">Le choix de l’adresse électronique a échoué.</string>
     <string name="encrypted">Définir comme chiffré</string>
     <string name="end_to_end_encryption_confirm_button">Configurer le chiffrement</string>
     <string name="end_to_end_encryption_decrypting">Décryptage…</string>
@@ -316,8 +316,7 @@
     <string name="error_starting_direct_camera_upload">Erreur au démarrage de l\'appareil photo</string>
     <string name="error_starting_doc_scan">Erreur lors de la numérisation du document</string>
     <string name="etm_accounts">Comptes</string>
-    <string name="etm_background_execution_count">Times run in 48h</string>
-    <string name="etm_background_job_created">Created</string>
+    <string name="etm_background_job_created">Créée</string>
     <string name="etm_background_job_name">Nom de la tâche </string>
     <string name="etm_background_job_progress">Progression</string>
     <string name="etm_background_job_state">État</string>
@@ -367,7 +366,7 @@
     <string name="file_list_empty_shared_headline">Aucun partage</string>
     <string name="file_list_empty_unified_search_no_results">Aucun résultat trouvé pour votre requête</string>
     <string name="file_list_folder">dossier</string>
-    <string name="file_list_live">LIVE</string>
+    <string name="file_list_live">EN DIRECT</string>
     <string name="file_list_loading">Chargement…</string>
     <string name="file_list_no_app_for_file_type">Aucune application trouvée pour ce type de fichier.</string>
     <string name="file_list_seconds_ago">à l’instant</string>
@@ -412,16 +411,16 @@
     <string name="filename_forbidden_charaters_from_server">Le nom du fichier contient au moins un caractère invalide</string>
     <string name="filename_hint">Nom du fichier</string>
     <string name="first_run_1_text">Sécurisez et contrôlez vos données</string>
-    <string name="first_run_2_text">Secure collaboration and file exchange</string>
-    <string name="first_run_3_text">Easy-to-use webmail, calendar and contacts</string>
-    <string name="first_run_4_text">Screensharing, online meetings and web conferences</string>
+    <string name="first_run_2_text">Collaboration et échange de fichiers sécurisés</string>
+    <string name="first_run_3_text">Messagerie web, agenda, contacts faciles à utiliser</string>
+    <string name="first_run_4_text">Partage d’écran, réunions en ligne et conférences en ligne</string>
     <string name="folder_already_exists">Le dossier existe déjà</string>
     <string name="folder_confirm_create">Créer</string>
     <string name="folder_list_empty_headline">Aucun dossier</string>
     <string name="folder_picker_choose_button_text">Choisir</string>
-    <string name="folder_picker_choose_caption_text">Choose target folder</string>
-    <string name="folder_picker_copy_button_text">Copy</string>
-    <string name="folder_picker_move_button_text">Move</string>
+    <string name="folder_picker_choose_caption_text">Sélectionner le dossier cible</string>
+    <string name="folder_picker_copy_button_text">Copier</string>
+    <string name="folder_picker_move_button_text">Déplacer</string>
     <string name="forbidden_permissions">Vous n\'avez pas la permission %s</string>
     <string name="forbidden_permissions_copy">de copier ce fichier</string>
     <string name="forbidden_permissions_create">de créer ce fichier</string>
@@ -436,7 +435,7 @@
     <string name="foreign_files_success">Tous les fichiers ont été déplacés</string>
     <string name="forward">Suivant</string>
     <string name="fourHours">4 heures</string>
-    <string name="grid_file_features_live_photo_content_description">This icon indicates availability of live photo</string>
+    <string name="grid_file_features_live_photo_content_description">Cette icône indique la disponibilité de live photo</string>
     <string name="hidden_file_name_warning">Le nom résultera en un fichier caché</string>
     <string name="hint_name">Nom</string>
     <string name="hint_note">Note</string>
@@ -602,16 +601,16 @@
     <string name="pref_instant_name_collision_policy_entries_rename">Renommer la nouvelle version</string>
     <string name="pref_instant_name_collision_policy_title">Que faire si le fichier existe déjà ?</string>
     <string name="prefs_add_account">Ajouter un compte</string>
-    <string name="prefs_calendar_contacts">Sync calendar and contacts</string>
+    <string name="prefs_calendar_contacts">Synchroniser l’agenda et les contacts</string>
     <string name="prefs_calendar_contacts_no_store_error">Ni Google Play Store ou F-Droid ne sont installés</string>
     <string name="prefs_calendar_contacts_summary">Configurer DAVx5 (autrefois connu comme DAVdroid) (v1.3.0+) pour le compte actuel</string>
-    <string name="prefs_calendar_contacts_sync_setup_successful">Calendar and contacts sync set up</string>
+    <string name="prefs_calendar_contacts_sync_setup_successful">La synchronisation de l\'agenda et des contacts a bien été configurée.</string>
     <string name="prefs_category_about">À propos</string>
     <string name="prefs_category_details">Préférences</string>
     <string name="prefs_category_dev">Dév</string>
     <string name="prefs_category_general">Général</string>
     <string name="prefs_category_more">Plus</string>
-    <string name="prefs_daily_backup_summary">Daily backup of your calendar and contacts</string>
+    <string name="prefs_daily_backup_summary">Sauvegarde quotidienne de votre agenda et des contacts</string>
     <string name="prefs_daily_contact_backup_summary">Sauvegarde quotidienne de vos contacts</string>
     <string name="prefs_davx5_setup_error">Erreur inattendue lors de la configuration de DAVx5 (anciennement connu sous le nom de DAVdroid)</string>
     <string name="prefs_e2e_active">Le chiffrement de bout en bout est configuré !</string>
@@ -624,8 +623,8 @@
     <string name="prefs_imprint">Mentions</string>
     <string name="prefs_instant_behaviour_dialogTitle">Le fichier original sera…</string>
     <string name="prefs_instant_behaviour_title">Le fichier original sera…</string>
-    <string name="prefs_instant_upload_exclude_hidden_summary">Exclude hidden files and folders</string>
-    <string name="prefs_instant_upload_exclude_hidden_title">Exclude hidden</string>
+    <string name="prefs_instant_upload_exclude_hidden_summary">Exclure les fichiers et dossiers cachés</string>
+    <string name="prefs_instant_upload_exclude_hidden_title">Exclure les cachés</string>
     <string name="prefs_instant_upload_path_use_date_subfolders_summary">Stockage dans des sous-dossiers se basant sur la date</string>
     <string name="prefs_instant_upload_path_use_subfolders_title">Utiliser des sous-dossiers</string>
     <string name="prefs_instant_upload_subfolder_rule_title">Options du sous-dossier</string>
@@ -674,17 +673,17 @@
     <string name="remove_e2e">Vous pouvez retirer le chiffrement de bout en bout localement sur ce client</string>
     <string name="remove_e2e_message">Vous pouvez retirer le chiffrement de bout en bout localement sur ce client. Les fichiers chiffrés resteront sur le serveur, mais ne seront plus synchronisés avec cet ordinateur.</string>
     <string name="remove_fail_msg">Échec de la suppression</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="remove_local_account">Supprimer le compte local</string>
+    <string name="remove_local_account_details">Supprimer le compte de l\'appareil et supprimer tous les fichiers locaux</string>
     <string name="remove_notification_failed">Erreur lors de la suppression des notifications.</string>
     <string name="remove_push_notification">Supprimer</string>
     <string name="remove_success_msg">Supprimé</string>
     <string name="rename_dialog_title">Entrez un nouveau nom</string>
     <string name="rename_local_fail_msg">Impossible de renommer la version locale; veuillez réessayer avec un nom différent</string>
     <string name="rename_server_fail_msg">Impossible de renommer, le nom est déjà utilisé</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="request_account_deletion">Demander la suppression du compte</string>
+    <string name="request_account_deletion_button">Demander la suppression</string>
+    <string name="request_account_deletion_details">Demander la suppression permanente du compte par le fournisseur de services</string>
     <string name="reshare_not_allowed">Le repartage n\'est pas autorisé</string>
     <string name="resharing_is_not_allowed">Le repartage est interdit</string>
     <string name="resized_image_not_possible_download">Aucune image réduite disponible. Télécharger l\'image originale ?</string>
@@ -705,12 +704,12 @@
     <string name="screenshot_04_accounts_heading">Tous vos comptes</string>
     <string name="screenshot_04_accounts_subline">en un seul endroit</string>
     <string name="screenshot_05_autoUpload_heading">Téléversement automatique</string>
-    <string name="screenshot_05_autoUpload_subline">for your photos and videos</string>
-    <string name="screenshot_06_davdroid_heading">Calendar and contacts</string>
+    <string name="screenshot_05_autoUpload_subline">pour vos photos et vidéos</string>
+    <string name="screenshot_06_davdroid_heading">Agenda et contacts</string>
     <string name="screenshot_06_davdroid_subline">Synchroniser avec DAVx5</string>
     <string name="search_error">Erreur lors de l\'obtention des résultats de recherche</string>
-    <string name="secure_share_not_set_up">Secure sharing is not set up for this user</string>
-    <string name="secure_share_search">Secure share …</string>
+    <string name="secure_share_not_set_up">Le partage sécurité n’est pas configuré pour cet utilisateur</string>
+    <string name="secure_share_search">Partage sécurisé…</string>
     <string name="select_all">Tout sélectionner</string>
     <string name="select_media_folder">Paramétrer le dossier média</string>
     <string name="select_one_template">Veuillez sélectionner un modèle</string>
@@ -725,7 +724,7 @@
     <string name="set_status_message">Enregistrer le message d\'état</string>
     <string name="setup_e2e">Pendant la configuration du chiffrement de bout en bout, vous recevrez une phrase secrète aléatoire de 12 mots dont vous aurez besoin pour ouvrir vos fichiers sur d\'autres appareils. Cette phrase secrète ne sera stockée que sur cet appareil, et pourra être affichée à nouveau sur cet écran. Veuillez la noter en lieu sûr !</string>
     <string name="share">Partager</string>
-    <string name="share_copy_link">Share and Copy Link</string>
+    <string name="share_copy_link">Partager et copier le lien</string>
     <string name="share_dialog_title">Partage</string>
     <string name="share_expiration_date_format">%1$s</string>
     <string name="share_expiration_date_label">Expire le %1$s</string>
@@ -745,7 +744,7 @@
     <string name="share_link_with_label">Partager le lien (%1$s)</string>
     <string name="share_no_expiration_date_label">Définir une date d\'expiration</string>
     <string name="share_no_password_title">Définir un mot de passe</string>
-    <string name="share_not_allowed_when_file_drop">Resharing is not allowed during secure file drop</string>
+    <string name="share_not_allowed_when_file_drop">Le repartage n’est pas autorisé pendant le dépôt d’un fichier sécurisé</string>
     <string name="share_password_title">Protégé par mot de passe</string>
     <string name="share_permission_can_edit">Peut modifier</string>
     <string name="share_permission_file_drop">Dépôt de fichier</string>
@@ -769,7 +768,6 @@
     <string name="shared_icon_shared_via_link">partagé par lien</string>
     <string name="shared_with_you_by">Partagé avec vous par %1$s</string>
     <string name="sharee_add_failed">L\'ajout du partage a échoué</string>
-    <string name="sharee_already_added_to_file">Adding share failed. This file or folder has already been shared with this person or group.</string>
     <string name="show_images">Afficher les photos</string>
     <string name="show_video">Afficher les vidéos</string>
     <string name="signup_with_provider">Se connecter avec un fournisseur</string>
@@ -812,7 +810,7 @@
     <string name="storage_permission_full_access">Accès complet</string>
     <string name="storage_permission_media_read_only">Média en lecture seule</string>
     <string name="storage_pictures">Images</string>
-    <string name="store_full_desc">The self-hosted productivity platform that keeps you in control.\n\nFeatures:\n* Easy, modern interface, suited to the theme of your server\n* Upload files to your Nextcloud server\n* Share them with others\n* Keep your favorite files and folders synced\n* Search across all folders on your server\n* Auto Upload for photos and videos taken by your device\n* Keep up to date with notifications\n* Multi-account support\n* Secure access to your data with fingerprint or PIN\n* Integration with DAVx5 (formerly known as DAVdroid) for easy setup of calendar and contacts synchronization\n\nPlease report all issues at https://github.com/nextcloud/android/issues and discuss this app at https://help.nextcloud.com/c/clients/android\n\nNew to Nextcloud? Nextcloud is a private file sync and share and communication server. It is libre software, and you can host it yourself or pay a company to do it for you. That way, you are in control of your photos, your calendar and contact data, your documents and everything else.\n\nCheck out Nextcloud at https://nextcloud.com</string>
+    <string name="store_full_desc">La plateforme de productivité auto-hébergée qui vous redonne le contrôle.\n\nFonctionnalités: \n* Intuitif, interface moderne, adaptée au thème de votre serveur.\n* Envoyez des fichiers sur votre serveur Nextcloud\n* Partagez avec d\'autres personnes\n* Gardez vos fichiers et dossiers préférés synchronisés\n* Recherchez dans tous les dossiers de votre serveur\n* Téléversement automatique des photos et vidéos prises par votre appareil\n* Restez à jour avec les notifications\n* Supporte plusieurs comptes simultanément\n* Accès sécurisé avec votre empreinte digitale ou un PIN\n* Intégration avec DAVx5 (ancien nom : DAVdroid) pour configurer facilement l\'agenda&amp;et synchroniser les contacts\n\nMerci de signaler les problèmes sur https://github.com/nextcloud/android/issues et discutez de cette application sur https://help.nextcloud.com/c/clients/android\n\nNew sur Nextcloud ? Nextcloud est un serveur privé de synchronisation de fichiers&amp;de partage et de communications. C\'est un logiciel libre, et vous pouvez l\'héberger vous-même ou payer une entreprise pour le faire à votre place. De cette façon, vous avez le contrôle de vos photos, votre agenda et vos données de contacts, vos documents et tout le reste.\n\nApprenez en plus sur Nextcloud sur https://nextcloud.com</string>
     <string name="store_full_dev_desc">La plateforme de productivité auto-hébergée qui vous permet de garder le contrôle.\nCeci est la version officielle de développement, qui présente chaque jour quelques-unes des fonctionnalités non-testées les plus récentes, causant parfois des instabilités ou des pertes de données. Cette application s\'adresse aux utilisateurs volontaires souhaitant tester et rapporter les problèmes qui peuvent arriver. Ne l\'utilisez jamais pour un environnement de production!\n\nLes versions officielles et en développement sont disponibles sur F-droid, et peuvent être utilisées en même temps.</string>
     <string name="store_short_desc">La plateforme de productivité auto-hébergée qui vous permet de garder le contrôle</string>
     <string name="store_short_dev_desc">La plateforme de productivité auto-hébergée qui vous permet de garder le contrôle (version de développement en démonstration)</string>
@@ -826,7 +824,7 @@
     <string name="subject_shared_with_you">\"%1$s\" a été partagé avec vous</string>
     <string name="subject_user_shared_with_you">%1$s a partagé \"%2$s\" avec vous</string>
     <string name="subtitle_photos_only">Photos uniquement</string>
-    <string name="subtitle_photos_videos">Photos and videos</string>
+    <string name="subtitle_photos_videos">Photos et vidéos</string>
     <string name="subtitle_videos_only">Vidéos uniquement</string>
     <string name="suggest">Suggérer</string>
     <string name="sync_conflicts_in_favourites_ticker">Des conflits ont été trouvés</string>
@@ -868,7 +866,7 @@
     <string name="trashbin_empty_message">Les fichiers supprimés s\'afficheront ici et vous pourrez les restaurer.</string>
     <string name="trashbin_file_not_deleted">Le fichier %1$s n\'a pas pu être supprimé !</string>
     <string name="trashbin_file_not_restored">Le fichier %1$s n\'a pas pu être restauré !</string>
-    <string name="trashbin_file_remove">Delete permanently</string>
+    <string name="trashbin_file_remove">Supprimer définitivement</string>
     <string name="trashbin_loading_failed">Le chargement de la corbeille a échoué !</string>
     <string name="trashbin_not_emptied">Des fichiers n\'ont pas pu être supprimés de manière définitive !</string>
     <string name="unlock_file">Déverrouiller le fichier</string>
@@ -884,13 +882,13 @@
     <string name="update_link_file_no_exist">Impossible de mettre à jour. Vérifiez que le fichier existe </string>
     <string name="update_link_forbidden_permissions">de modifier ce partage</string>
     <string name="updating_share_failed">La mise à jour du partage a échoué</string>
-    <string name="upload_action_cancelled_clear">Clear cancelled uploads</string>
-    <string name="upload_action_cancelled_resume">Resume cancelled uploads</string>
-    <string name="upload_action_failed_clear">Clear failed uploads</string>
-    <string name="upload_action_failed_retry">Retry failed uploads</string>
-    <string name="upload_action_file_not_exist_message">Some files not exists those files cannot be resumed</string>
-    <string name="upload_action_global_upload_pause">Pause all uploads</string>
-    <string name="upload_action_global_upload_resume">Resume all uploads</string>
+    <string name="upload_action_cancelled_clear">Effacer les téléversements annulés</string>
+    <string name="upload_action_cancelled_resume">Poursuivre les téléversements annulés</string>
+    <string name="upload_action_failed_clear">Effacer les téléversements échoués</string>
+    <string name="upload_action_failed_retry">Relancer les envois en erreur</string>
+    <string name="upload_action_file_not_exist_message">Certains fichiers n’existent pas et ne peuvent pas être relancés.</string>
+    <string name="upload_action_global_upload_pause">Suspendre tous les téléversements</string>
+    <string name="upload_action_global_upload_resume">Poursuivre tous les téléversements</string>
     <string name="upload_cannot_create_file">Impossible de créer le fichier local</string>
     <string name="upload_chooser_title">Téléverser depuis…</string>
     <string name="upload_content_from_other_apps">Téléverser du contenu à partir d\'autres applications</string>
@@ -902,7 +900,7 @@
     <string name="upload_file_dialog_filetype_snippet_text">Extrait du fichier texte (.txt)</string>
     <string name="upload_file_dialog_title">Spécifiez le nom et le type du fichier à téléverser</string>
     <string name="upload_files">Téléverser des fichiers</string>
-    <string name="upload_global_pause_title">All uploads are paused</string>
+    <string name="upload_global_pause_title">Tous les téléversements sont suspendus</string>
     <string name="upload_item_action_button">Bouton d\'action d\'upload</string>
     <string name="upload_list_delete">Supprimer</string>
     <string name="upload_list_empty_headline">Aucun téléversement disponible</string>
@@ -911,10 +909,10 @@
     <string name="upload_local_storage_full">Stockage local plein</string>
     <string name="upload_local_storage_not_copied">Le fichier n\'a pas pu être copié sur le stockage local</string>
     <string name="upload_lock_failed">Impossible de verrouiller le dossier</string>
-    <string name="upload_manually_cancelled">Upload was cancelled by user</string>
+    <string name="upload_manually_cancelled">Le téléversement a été annulé par l\'utilisateur</string>
     <string name="upload_old_android">Le chiffrement n\'est disponible que pour les versions d\'Android&gt;= 5.0</string>
     <string name="upload_query_move_foreign_files">Il n\'y a pas assez d\'espace pour copier les fichiers sélectionnés dans le dossier %1$s. Souhaitez-vous plutôt les déplacer ?</string>
-    <string name="upload_quota_exceeded">Storage quota exceeded</string>
+    <string name="upload_quota_exceeded">Quota de stockage dépassé</string>
     <string name="upload_scan_doc_upload">Numériser un document depuis l\'appareil photo</string>
     <string name="upload_sync_conflict">Conflit de synchronisation, veuillez le résoudre manuellement</string>
     <string name="upload_unknown_error">Erreur inconnue </string>
@@ -926,10 +924,10 @@
     <string name="uploader_error_message_source_file_not_found">Le fichier à téléverser n\'a pas été trouvé. Merci de vérifier si ce fichier existe.</string>
     <string name="uploader_error_title_file_cannot_be_uploaded">le fichier ne peut être téléchargé </string>
     <string name="uploader_error_title_no_file_to_upload">Aucun fichier à téléverser</string>
-    <string name="uploader_file_not_found_message">File not found. Are you sure that this file exists or has a previous conflict not been resolved?</string>
-    <string name="uploader_file_not_found_on_server_message">We couldnt locate the file on server. Another user may have deleted the file</string>
+    <string name="uploader_file_not_found_message">Fichier non trouvé. Êtes-vous sûr que ce fichier existe ou qu\'un conflit précédent n\'a pas été résolu ?</string>
+    <string name="uploader_file_not_found_on_server_message">Impossible de retrouver le fichier sur le serveur. Un autre utilisateur l\'a peut-être supprimé</string>
     <string name="uploader_info_dirname">Nom du dossier</string>
-    <string name="uploader_local_files_uploaded">Retry to upload failed local files</string>
+    <string name="uploader_local_files_uploaded">Réessayer de téléverser les fichiers locaux ayant échoués</string>
     <string name="uploader_top_message">Sélectionnez le dossier de téléversement</string>
     <string name="uploader_upload_failed_content_single">Impossible d\'envoyer %1$s</string>
     <string name="uploader_upload_failed_credentials_error">Le téléversement a échoué, reconnectez-vous</string>
@@ -953,7 +951,7 @@
     <string name="uploads_view_group_current_uploads">En cours</string>
     <string name="uploads_view_group_failed_uploads">Échec / En attente de reprise</string>
     <string name="uploads_view_group_finished_uploads">Envoyé</string>
-    <string name="uploads_view_group_manually_cancelled_uploads">Cancelled</string>
+    <string name="uploads_view_group_manually_cancelled_uploads">Annulé</string>
     <string name="uploads_view_later_waiting_to_upload">En attente de téléversement</string>
     <string name="uploads_view_title">Téléversements</string>
     <string name="uploads_view_upload_status_cancelled">Annulé</string>
@@ -968,7 +966,7 @@
     <string name="uploads_view_upload_status_fetching_server_version">Récupération de la version serveur …</string>
     <string name="uploads_view_upload_status_service_interrupted">L\'application s\'est arrêtée</string>
     <string name="uploads_view_upload_status_succeeded">Terminé</string>
-    <string name="uploads_view_upload_status_succeeded_same_file">Same file found on remote, skipping upload</string>
+    <string name="uploads_view_upload_status_succeeded_same_file">Le même fichier a été trouvé sur le serveur distant, le téléversement est ignoré</string>
     <string name="uploads_view_upload_status_unknown_fail">Erreur inconnue </string>
     <string name="uploads_view_upload_status_virus_detected">Un virus a été détecté. Le téléversement ne peut donc pas être réalisé !</string>
     <string name="uploads_view_upload_status_waiting_exit_power_save_mode">En attente de sortie du mode d’économie d’énergie</string>
@@ -989,16 +987,16 @@
     <string name="wait_a_moment">Veuillez patienter…</string>
     <string name="wait_checking_credentials">Vérification des identifiants enregistrés</string>
     <string name="wait_for_tmp_copy_from_private_storage">Copie du fichier depuis le stockage privé</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="webview_version_check_alert_dialog_message">Veuillez mettre à jour l\'application Android System WebView pour vous connecter</string>
+    <string name="webview_version_check_alert_dialog_positive_button_title">Mise à jour</string>
+    <string name="webview_version_check_alert_dialog_title">Mettre à jour Android System WebView</string>
     <string name="what_s_new_image">Image quoi de neuf</string>
     <string name="whats_new_skip">Ignorer</string>
     <string name="whats_new_title">Nouveautés dans %1$s</string>
     <string name="whats_your_status">Quel est votre statut ?</string>
     <string name="widgets_not_available">Les widgets ne sont disponibles que sur %1$s 25 ou plus tard</string>
     <string name="widgets_not_available_title">Non disponible</string>
-    <string name="worker_download">Downloading files…</string>
+    <string name="worker_download">Réception de fichiers…</string>
     <string name="write_email">Envoyer un courriel</string>
     <string name="wrong_storage_path">Le dossier de stockage des données n\'existe pas !</string>
     <string name="wrong_storage_path_desc">Cela peut être dû à une restauration de sauvegarde sur un autre appareil. Retour aux valeurs par défaut. Veuillez vérifier les paramètres pour ajuster le chemin de stockage.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Dh’fhàillig cruthachadh a’ chunntais</string>
     <string name="account_icon">Ìomhaigheag a’ chunntais</string>
     <string name="account_not_found">Cha deach an cunntas a lorg!</string>
-    <string name="action_clear_failed_uploads">Falamhaich na luchdaidhean suas a dh’fhàillig</string>
     <string name="action_edit">Deasaich</string>
     <string name="action_empty_notifications">Falamhaich a h-uile brath</string>
     <string name="action_empty_trashbin">Falamhaich an sgudal</string>
@@ -138,7 +137,6 @@
     <string name="confirmation_remove_folder_alert">A bheil thu cinnteach gu bheil thu airson %1$s ’s a shusbaint a sguabadh às?</string>
     <string name="confirmation_remove_folders_alert">A bheil thu cinnteach gu bheil thu airson na nithean a thagh thu ’s an susbaint a sguabadh às?</string>
     <string name="confirmation_remove_local">Ionadail a-mhàin</string>
-    <string name="conflict_dialog_error">Mearachd le cruthachadh còmhradh na còmhstri!</string>
     <string name="conflict_file_headline">Faidhle %1$s ann an còmhstri</string>
     <string name="conflict_message_description">Ma thaghas tu an dà thionndadh, thèid àireamh a chur ri ainm an fhaidhle ionadail.</string>
     <string name="contactlist_item_icon">Ìomhaigheag a’ chleachdaiche air liosta an luchd-aithne</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Produciuse un fallo ao crear a conta</string>
     <string name="account_icon">Icona da conta</string>
     <string name="account_not_found">Non se atopou a conta!</string>
-    <string name="action_clear_failed_uploads">Limpar os envíos fallados</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Limpar todas as notificacións</string>
     <string name="action_empty_trashbin">Baleirar o lixo</string>
@@ -43,6 +42,7 @@
     <string name="assistant_screen_successful_task_text">Completado</string>
     <string name="assistant_screen_task_delete_success_message">A tarefa foi eliminada satisfactoriamente</string>
     <string name="assistant_screen_unknown_task_status_text">Descoñecido</string>
+    <string name="assistant_task_detail_screen_input_button_title">Entrada</string>
     <string name="associated_account_not_found">Non se atopou unha conta asociada!</string>
     <string name="auth_access_failed">Acceso fallado: %1$s</string>
     <string name="auth_account_does_not_exist">A conta aínda non existe no dispositivo</string>
@@ -155,7 +155,6 @@
     <string name="confirmation_remove_folder_alert">Confirma que quere eliminar %1$s e todo o seu contido?</string>
     <string name="confirmation_remove_folders_alert">Confirma que quere eliminar os elementos seleccionados e o seu contido?</string>
     <string name="confirmation_remove_local">Só local</string>
-    <string name="conflict_dialog_error">Produciuse un erro ao crear o diálogo de conflitos!</string>
     <string name="conflict_file_headline">Ficheiro en conflito %1$s</string>
     <string name="conflict_local_file">Ficheiro local</string>
     <string name="conflict_message_description">Se selecciona ambas versións, o ficheiro local terá un número engadido ao nome.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Kreiranje korisničkog računa neuspjelo</string>
     <string name="account_icon">Ikona korisničkog računa</string>
     <string name="account_not_found">Korisnički račun nije pronađen!</string>
-    <string name="action_clear_failed_uploads">Izbriši neuspješne otpreme</string>
     <string name="action_edit">Uredi</string>
     <string name="action_empty_notifications">Izbriši sve obavijesti</string>
     <string name="action_empty_trashbin">Isprazni kantu za smeće</string>
@@ -145,7 +144,6 @@
     <string name="confirmation_remove_folder_alert">Želite li zaista izbrisati %1$s i pripadajući sadržaj?</string>
     <string name="confirmation_remove_folders_alert">Želite li zaista izbrisati odabrane stavke i pripadajući sadržaj?</string>
     <string name="confirmation_remove_local">Samo lokalno</string>
-    <string name="conflict_dialog_error">Pogreška pri stvaranju dijaloškog okvira o nepodudaranju!</string>
     <string name="conflict_file_headline">Nepodudarna datoteka %1$s</string>
     <string name="conflict_local_file">Lokalna datoteka</string>
     <string name="conflict_message_description">Ako odaberete obje inačice, lokalna će datoteka uz naziv imati i broj.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">A fiók létrehozása sikertelen</string>
     <string name="account_icon">Fiók ikon</string>
     <string name="account_not_found">A fiók nem található!</string>
-    <string name="action_clear_failed_uploads">Sikertelen feltöltések eltávolítása</string>
     <string name="action_edit">Szerkesztés</string>
     <string name="action_empty_notifications">Összes értesítés törlése</string>
     <string name="action_empty_trashbin">Kuka ürítése</string>
@@ -155,7 +154,6 @@
     <string name="confirmation_remove_folder_alert">Biztos, hogy törli ezt: %1$s és a tartalmát?</string>
     <string name="confirmation_remove_folders_alert">Biztos, hogy törli a kiválasztott elemeket és tartalmukat?</string>
     <string name="confirmation_remove_local">Csak a helyi példány</string>
-    <string name="conflict_dialog_error">Hiba az ütközési párbeszédablak létrehozásakor!</string>
     <string name="conflict_file_headline">Ütköző fájl: %1$s</string>
     <string name="conflict_local_file">Helyi fájl</string>
     <string name="conflict_message_description">Amennyiben mindkét verziót kiválasztja, a helyi fájl nevéhez egy szám lesz hozzáfűzve.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Pembuatan akun gagal</string>
     <string name="account_icon">Ikon akun</string>
     <string name="account_not_found">Akun tidak ditemukan!</string>
-    <string name="action_clear_failed_uploads">Bersihkan unggahan gagal.</string>
     <string name="action_edit">Sunting</string>
     <string name="action_empty_notifications">Hapus semua notifikasi</string>
     <string name="action_empty_trashbin">Kosongkan tempat sampah</string>
@@ -147,7 +146,6 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
     <string name="confirmation_remove_folder_alert">Apakah anda yakin ingin menghapus %1$s beserta isinya?</string>
     <string name="confirmation_remove_folders_alert">Apa anda yakin ingin menghapus item yang terpilih beserta isinya?</string>
     <string name="confirmation_remove_local">Lokal saja</string>
-    <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>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Gerð notandaaðgangs mistókst</string>
     <string name="account_icon">Táknmynd fyrir notandaaðgang</string>
     <string name="account_not_found">Notandaaðgangur fannst ekki!</string>
-    <string name="action_clear_failed_uploads">Hreinsa lista yfir innsendingar sem mistókust</string>
     <string name="action_edit">Breyta</string>
     <string name="action_empty_notifications">Hreinsa allar tilkynningar</string>
     <string name="action_empty_trashbin">Tæma ruslið</string>
@@ -150,7 +149,6 @@
     <string name="confirmation_remove_folder_alert">Ertu viss um að þú viljir eyða %1$s og innihaldi þess?</string>
     <string name="confirmation_remove_folders_alert">Ertu viss um að þú viljir eyða völdum atriðum og innihaldi þeirra?</string>
     <string name="confirmation_remove_local">Einungis staðvært</string>
-    <string name="conflict_dialog_error">Villa við að búa til árekstraglugga!</string>
     <string name="conflict_local_file">Skrá á tölvunni</string>
     <string name="conflict_message_description">Ef þú velur báðar útgáfur, þá mun verða bætt tölustaf aftan við heiti afrituðu skrárinnar.</string>
     <string name="conflict_server_file">Skrá á netþjóni</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Creazione dell\'account non riuscita</string>
     <string name="account_icon">Icona dell\'account</string>
     <string name="account_not_found">Account non trovato</string>
-    <string name="action_clear_failed_uploads">Cancella caricamenti non riusciti</string>
     <string name="action_edit">Modifica</string>
     <string name="action_empty_notifications">Cancella tutte le notifiche</string>
     <string name="action_empty_trashbin">Svuota cestino</string>
@@ -153,7 +152,6 @@
     <string name="confirmation_remove_folder_alert">Vuoi davvero rimuovere %1$s e il relativo contenuto?</string>
     <string name="confirmation_remove_folders_alert">Vuoi davvero eliminare gli elementi selezionati e il loro contenuto?</string>
     <string name="confirmation_remove_local">Solo localmente</string>
-    <string name="conflict_dialog_error">Errore di creazione della finestra di conflitto!</string>
     <string name="conflict_file_headline">File %1$s in conflitto</string>
     <string name="conflict_local_file">File locale</string>
     <string name="conflict_message_description">Se selezioni entrambe le versioni, il file locale ha un numero aggiunto al suo nome.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">יצירת החשבון נכשלה</string>
     <string name="account_icon">סמל חשבון</string>
     <string name="account_not_found">החשבון לא נמצא!</string>
-    <string name="action_clear_failed_uploads">פינוי העלאות שנכשלו</string>
     <string name="action_edit">עריכה</string>
     <string name="action_empty_notifications">פינוי כל ההתראות</string>
     <string name="action_empty_trashbin">פינוי סל האשפה</string>
@@ -144,7 +143,6 @@
     <string name="confirmation_remove_folder_alert">למחוק את %1$s על תוכנו?</string>
     <string name="confirmation_remove_folders_alert">למחוק את הפריטים הנבחרים ואת תוכנם?</string>
     <string name="confirmation_remove_local">מקומי בלבד</string>
-    <string name="conflict_dialog_error">שגיאה ביצירת תיבת דו־שיח סתירה!</string>
     <string name="conflict_local_file">קובץ מקומי</string>
     <string name="conflict_message_description">בבחירה של שתי הגרסאות, יתווסף מספר בסוף שמו של הקובץ המקומי.</string>
     <string name="conflict_server_file">קובץ בשרת</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">アカウントの作成に失敗しました</string>
     <string name="account_icon">アカウントアイコン</string>
     <string name="account_not_found">アカウントが見つかりません!</string>
-    <string name="action_clear_failed_uploads">失敗したアップロードのクリア</string>
     <string name="action_edit">編集</string>
     <string name="action_empty_notifications">全ての通知を削除</string>
     <string name="action_empty_trashbin">ゴミ箱を空にする</string>
@@ -155,7 +154,6 @@
     <string name="confirmation_remove_folder_alert">本当に %1$s を中身も一緒に削除しますか?</string>
     <string name="confirmation_remove_folders_alert">本当に選択したアイテムとその内容を削除しますか?</string>
     <string name="confirmation_remove_local">ローカルのみ</string>
-    <string name="conflict_dialog_error">コンフリクトダイアログの作成に失敗しました</string>
     <string name="conflict_file_headline">%1$sはすでに存在します</string>
     <string name="conflict_local_file">ローカルファイル</string>
     <string name="conflict_message_description">両方のバージョンを選択した場合、ローカルファイルはファイル名に数字が追加されます。</string>

+ 0 - 506
app/src/main/res/values-ka-rGE/strings.xml

@@ -1,506 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-  <resources>
-    <string name="about_android">%1$s Android აპლიკაცია</string>
-    <string name="about_title">ჩვენს შესახებ</string>
-    <string name="about_version">ვერსია %1$s</string>
-    <string name="account_icon">ანგარიშის პიქტოგრამა</string>
-    <string name="account_not_found">ანგარიში ვერ იქნა ნაპოვნი!</string>
-    <string name="action_clear_failed_uploads">წარუმატებლად დასრულებული ატვირთების გასუფთავება</string>
-    <string name="action_edit">ცვლილება</string>
-    <string name="action_send_share">გაგზავნა/გაზიარება</string>
-    <string name="action_switch_grid_view">ბადისებური ხედი</string>
-    <string name="action_switch_list_view">ჩამონათვლისებური ხედი</string>
-    <string name="actionbar_mkdir">ახალი დირექტორია</string>
-    <string name="actionbar_open_with">გახსნა</string>
-    <string name="actionbar_search">ძიება</string>
-    <string name="actionbar_see_details">დეტალები</string>
-    <string name="actionbar_send_file">გაგზავნა</string>
-    <string name="actionbar_settings">პარამეტრები</string>
-    <string name="actionbar_sort">განლაგება</string>
-    <string name="active_user">აქტიური მომხმარებელი</string>
-    <string name="activities_no_results_headline">აქტოვობა ჯერ არაა</string>
-    <string name="activity_chooser_send_file_title">გაგზავნა</string>
-    <string name="activity_chooser_title">გააგზავნეთ ბმული…</string>
-    <string name="activity_icon">აქტივობა</string>
-    <string name="allow_resharing">ხელახალი გაზიარების დაშვება</string>
-    <string name="assistant_screen_all_task_type">ყველა</string>
-    <string name="auth_account_does_not_exist">ანგარიში ამ მოწყობილობაზე ჯერ არაა დამატებული</string>
-    <string name="auth_account_not_new">მოწყობილობაზე ანგარიში ამ მომხმარებლით და სერვერით უკვე არსებობს</string>
-    <string name="auth_account_not_the_same">შეყვანილი მომხმარებელი არ ემთხვევა ამ ანგარიშის მომხმარებელს</string>
-    <string name="auth_bad_oc_version_title">სერვერის ამოუცნობი ვერსია</string>
-    <string name="auth_connection_established">კავშირი დამყარდა</string>
-    <string name="auth_host_url">სერვერის მისამართი https://...</string>
-    <string name="auth_incorrect_address_title">სერვერისთვის არასწორი მისამსამართის ფორმატი</string>
-    <string name="auth_incorrect_path_title">სერვერი ვერ მოიძებნა</string>
-    <string name="auth_no_net_conn_title">ქსელთან კავშირი არ არის</string>
-    <string name="auth_nossl_plain_ok_title">დაცული კავშირი არაა ხელმისაწვდომი.</string>
-    <string name="auth_not_configured_title">არასწორი სერვერის კონფიგურაცია</string>
-    <string name="auth_oauth_error">წარუმატებელი ავტორიზაცია</string>
-    <string name="auth_oauth_error_access_denied">წვდომა ავტორიზაციის სერვერის მიერ აიკრძალა</string>
-    <string name="auth_redirect_non_secure_connection_title">დაცული კავშირი გადამისამართდა დაუცველი მარშრუტით.</string>
-    <string name="auth_secure_connection">დაცული კავშირი დამყარდა</string>
-    <string name="auth_ssl_general_error_title">SSL ინიციალიზაცია ვერ მოხერხდა</string>
-    <string name="auth_ssl_unverified_server_title">SSL სერვერის იდენტობა ვერ დამოწმდა</string>
-    <string name="auth_testing_connection">კავშირის შემოწმება</string>
-    <string name="auth_timeout_title">სერვერმა პასუხი დააგვიანია</string>
-    <string name="auth_unauthorized">არასწორი მომხმარებელი ან პაროლი</string>
-    <string name="auth_unknown_error_title">წარმოიშვა უცნობი შეცდომა!</string>
-    <string name="auth_unknown_host_title">ჰოსტი ვერ მოიძებნა</string>
-    <string name="auth_unsupported_multiaccount">%1$s არ უჭერს მხარს მრავალი ანგარიშის არსებობას</string>
-    <string name="auth_wrong_connection_title">კავშირი ვერ დამყარდა</string>
-    <string name="auto_upload_on_wifi">ატვირთვა მხოლოდ შეუზღუდავ Wi-Fi-ზე</string>
-    <string name="auto_upload_path">/ავტომატური_ატვირთვა</string>
-    <string name="autoupload_create_new_custom_folder">შექმენით ახალი სპეციფიური დირექტორია</string>
-    <string name="autoupload_custom_folder">დააყენეთ სპეციფიური დირექტორია</string>
-    <string name="avatar">ავატარი</string>
-    <string name="battery_optimization_close">დახურვა</string>
-    <string name="battery_optimization_disable">გამორთვა</string>
-    <string name="calendar">კალენდარი</string>
-    <string name="certificate_load_problem">სერტიპიკატის ჩატვირთვასთან პრობლემაა.</string>
-    <string name="checkbox">ჩექბოქსი</string>
-    <string name="clipboard_label">ტექსტი %1$s-იდან დაკოპირდა</string>
-    <string name="clipboard_no_text_to_copy">ბუფერში გადასატანად ტექსტი მიღებული არაა</string>
-    <string name="clipboard_unexpected_error">ბუფერში გადატანისას  წარმოშვა მოულოდნელი შეცდომა</string>
-    <string name="common_back">უკან</string>
-    <string name="common_cancel">გაუქმება</string>
-    <string name="common_cancel_sync">სინქრონიზაციის შეჩერება</string>
-    <string name="common_choose_account">აირჩიეთ ანგარიში</string>
-    <string name="common_confirm">დადასტურება</string>
-    <string name="common_copy">კოპირება</string>
-    <string name="common_delete">გაუქმება</string>
-    <string name="common_error">შეცდომა</string>
-    <string name="common_error_out_memory">არასაკმარისი მეხსიერება</string>
-    <string name="common_error_unknown">უცნობი შეცდომა</string>
-    <string name="common_loading">იტვირთება…</string>
-    <string name="common_next">შემდეგი</string>
-    <string name="common_no">არა</string>
-    <string name="common_ok">კარგი</string>
-    <string name="common_pending">მოლოდინშია</string>
-    <string name="common_remove">გაუქმება</string>
-    <string name="common_rename">გადარქმევა</string>
-    <string name="common_save">შენახვა</string>
-    <string name="common_send">გაგზავნა</string>
-    <string name="common_share">გაზიარება</string>
-    <string name="common_skip">გამოტოვება</string>
-    <string name="common_yes">კი</string>
-    <string name="community_beta_headline">დევ. ვერსიის შემოწმება</string>
-    <string name="community_beta_text">იმყოფება სისხლდენის ზღვარზე და მოიცავს ყველა დამდეგ ფუნქციას. შეიძლება გამოჩნდეს შეცდომები, ასეთი შემთხვევისას გთხოვთ გვამცნობოთ რეპორტით.</string>
-    <string name="community_contribute_forum_forum">ფურუმი</string>
-    <string name="community_contribute_forum_text">დაეხმარეთ სხვებს</string>
-    <string name="community_contribute_headline">აქტიურად შეიტანეთ წვლილი</string>
-    <string name="community_contribute_translate_text">აპლიკაცია</string>
-    <string name="community_contribute_translate_translate">გადათარგმნეთ</string>
-    <string name="community_dev_direct_download">დეველოპმენტ რელიზის პირდაპირი ჩამოტვირთვა</string>
-    <string name="community_dev_fdroid">მიიღეთ დეველოპმენტ რელიზი F-Droid აპლიკაციიდან</string>
-    <string name="community_rc_fdroid">მიიღეთ რელიზ კანდიდატი F-Droid აპლიკაციიდან</string>
-    <string name="community_rc_play_store">მიიღეთ რელიზ კანდიდატი Google Play-დან</string>
-    <string name="community_release_candidate_headline">რელიზის კანდიდატი</string>
-    <string name="community_release_candidate_text">ეს რელიზის კანდიდატი (რკ) დამდეგი რელიზის კადრია და მოსალოდნელია მისი სტაბილურობა. ამის დამოწმებაში დაგვეხმარება ინდივიდუალური მოწყობილობის შემოწმება. შემოწმებისთვის დარეგისტრირდით Play-ზე ან გადახედეთ \"ვერსიის\" სექციას F-Droid-ში.</string>
-    <string name="community_testing_bug_text">იპოვეთ შეცდომა? უცნაურობა?</string>
-    <string name="community_testing_headline">დაგვეხმარეთ შემოწმებით</string>
-    <string name="community_testing_report_text">დაამატეთ მოხსენიება GitHub-ზე</string>
-    <string name="confirmation_remove_file_alert">ნამდვილად გსურთ %1$s-ის გაუქმება?</string>
-    <string name="confirmation_remove_files_alert">დარწმუნებული ხართ, რომ გსურთ არჩეული ჩანაწერების გაუქმება?</string>
-    <string name="confirmation_remove_folder_alert">ნამდვილად გსურთ %1$s-ის და შემცველობის გაუქმება?</string>
-    <string name="confirmation_remove_folders_alert">დარწმუნებული ხართ, რომ გსურთ არჩეული ჩანაწერებისა და მათი შემცველობის გაუქმება?</string>
-    <string name="confirmation_remove_local">მხოლოდ ლოკალური</string>
-    <string name="contactlist_item_icon">მომხმარებლის პიქტოგრამა კონტაქტების სიისთვის</string>
-    <string name="contactlist_no_permission">უფლებები არაა მოცემული, არაფერი არ იქნა იმპორტირებული.</string>
-    <string name="contacts">კონტაქტები</string>
-    <string name="contacts_backup_button">ახალი ბექაფი</string>
-    <string name="contacts_preferences_backup_scheduled">ბექაფი დაინიშნა და მალე დაიწყება</string>
-    <string name="contacts_preferences_import_scheduled">იმპორტი დაინიშნა და მალე დაიწყება</string>
-    <string name="contacts_preferences_no_file_found">ფაილი ვერ იქნა ნაპოვნი</string>
-    <string name="contacts_preferences_something_strange_happened">თქვენი ბოლო ბექაფი ვერ იქნა ნაპოვნი!</string>
-    <string name="copied_to_clipboard">კოპირებულია კლიპბორდში</string>
-    <string name="copy_file_error">ამ ფაილისა თუ დირექტორიის კოპირებისას წარმოიშვა შეცდომა</string>
-    <string name="copy_file_invalid_into_descendent">დირექტორიის კოპირება მასში არსებულ დირექტორიაში შეუძლებელია</string>
-    <string name="copy_file_invalid_overwrite">ფაილი დანიშნულ დირექტორიაში უკვე არსებობს</string>
-    <string name="copy_link">ბმულის კოპირება</string>
-    <string name="copy_move_to_encrypted_folder_not_supported">ამჟამად კოპირება/გადატანა დაშიფრულ დირექტორიაში არაა მხარდაჭერილი.</string>
-    <string name="create">შექმნა</string>
-    <string name="create_dir_fail_msg">დირექტორია ვერ შეიქმნა</string>
-    <string name="delete_account">ანგარიშის გაუქმება</string>
-    <string name="deselect_all">ყველას წაშლა</string>
-    <string name="dev_version_new_version_available">ხელმისაწვდომია ახალი ვერსია</string>
-    <string name="dev_version_no_new_version_available">ახალი ვერსია არაა ხელმისაწვდომი.</string>
-    <string name="dialog_close">დახურვა</string>
-    <string name="digest_algorithm_not_available">თქვენს ტელეფონს ამ ალგორითმის დაიჯესტის მხარდაჭერა არ აქვს. </string>
-    <string name="disable_new_media_folder_detection_notifications">გამორთვა</string>
-    <string name="dismiss">დათხოვნა</string>
-    <string name="done">დასრულებულია</string>
-    <string name="downloader_download_failed_content">ვერ ჩამოიტვირთა %1$s</string>
-    <string name="downloader_download_failed_credentials_error">ჩამოტვირთვა ვერ მოხერხდა, ახლიდან გაიარეთ ავტორიზაცია</string>
-    <string name="downloader_download_failed_ticker">ჩამოტვირთვა ვერ განხორციელდა</string>
-    <string name="downloader_download_file_not_found">ფაილი სერვერზე ხელმისაწვდომი აღარაა</string>
-    <string name="downloader_download_in_progress_content">%1$d%% ჩამოტვირთვა %2$s</string>
-    <string name="downloader_download_succeeded_content">%1$s ჩამოტვირთლია</string>
-    <string name="downloader_download_succeeded_ticker">ჩამოტვირთულია</string>
-    <string name="downloader_not_downloaded_yet">ჯერ ვერ ჩამოიტვირთა</string>
-    <string name="drawer_header_background">მხაზველი დასათაურების ფონური სურათი</string>
-    <string name="drawer_item_activities">აქტივობები</string>
-    <string name="drawer_item_all_files">ყველა ფაილი</string>
-    <string name="drawer_item_favorites">რჩეულები</string>
-    <string name="drawer_item_home">სახლი</string>
-    <string name="drawer_item_notifications">შეტყობინებები</string>
-    <string name="drawer_item_on_device">მოწყობილობაზე</string>
-    <string name="drawer_item_recently_modified">ახლად შეცვლილი</string>
-    <string name="drawer_item_shared">გაზიარებული</string>
-    <string name="drawer_item_trashbin">გაუქმებული ფაილები</string>
-    <string name="drawer_item_uploads_list">ატვირთვები</string>
-    <string name="drawer_logout">გასვლა</string>
-    <string name="drawer_quota">გამოყენებულია %1$s სულ %2$s-იდან </string>
-    <string name="drawer_synced_folders">ავტო-ატვირთვა</string>
-    <string name="ecosystem_apps_display_more">უფრო მეტი</string>
-    <string name="ecosystem_apps_display_notes">ჩანაწერები</string>
-    <string name="ecosystem_apps_display_talk">საუბარი</string>
-    <string name="encrypted">დააყენეთ როგორც დაშიფრული</string>
-    <string name="end_to_end_encryption_confirm_button">შიფრაციის დაყენება</string>
-    <string name="end_to_end_encryption_dialog_close">დახურვა</string>
-    <string name="end_to_end_encryption_enter_password">პირადი გასაღების დეშიფრაციისთვის გთხოვთ შეიყვანოთ პაროლი.</string>
-    <string name="end_to_end_encryption_folder_not_empty">ეს დირექტორია არაა ცარიელი</string>
-    <string name="end_to_end_encryption_keywords_description">12 სიტყვა ერთად წარმოქმნის ძალიან ძლიერ პაროლს, იძლევა თქვენი დაშიფრული ფაილების ჩვენებისა და მოხმარების უფლებას. გთხოვთ ჩაიწეროთ და შეინახოთ დაცულ ადგილას.</string>
-    <string name="end_to_end_encryption_passphrase_title">შენიშნეთ თქვენი 12 სიტყვიანი შიფრაციის პაროლი</string>
-    <string name="end_to_end_encryption_storing_keys">გასაღებების შენახვა</string>
-    <string name="end_to_end_encryption_title">შიფრაციის დაყენება</string>
-    <string name="end_to_end_encryption_unsuccessful">გასაღებების შენახვა ვერ მოხერხდა, გთხოვთ სცადოთ ახლიდან.</string>
-    <string name="end_to_end_encryption_wrong_password">შეცდომა დეშიფრაციისას. არასწორი პაროლი?</string>
-    <string name="error__upload__local_file_not_copied">%1$s ვერ კოპირდება %2$s ლოკალურ დირექტორიაში</string>
-    <string name="error_cant_bind_to_operations_service">კრიტიკული შეცდომა: ოპერაციების განხორციელება შეუძლებელია</string>
-    <string name="etm_accounts">ანგარიშები</string>
-    <string name="etm_background_job_created">შექმნილია</string>
-    <string name="etm_background_job_user">მომხმარებელი</string>
-    <string name="etm_background_jobs">ფონური საქმეები</string>
-    <string name="etm_transfer_type_download">ჩამოტვირთვა</string>
-    <string name="etm_transfer_type_upload">ატვირთვა</string>
-    <string name="favorite">რჩეულებში დამატება</string>
-    <string name="favorite_icon">რჩეული</string>
-    <string name="file_delete">წაშლა</string>
-    <string name="file_icon">ფაილი</string>
-    <string name="file_list_empty">ატვირთეთ რამე ან გაუწიეთ თქვნს მოწყობილობას სინქრონიზაცია.</string>
-    <string name="file_list_empty_favorite_headline">რჩეულებში ჯერ არაფერი დამატებულია</string>
-    <string name="file_list_empty_headline">აქ ფაილები არაა</string>
-    <string name="file_list_empty_headline_search">ამ დირექტორიაში შედეგები არაა</string>
-    <string name="file_list_empty_headline_server_search">შედეგები არაა</string>
-    <string name="file_list_empty_moving">აქ არაფერია. შეგიძლიათ დაამატოთ დირექტორია.</string>
-    <string name="file_list_empty_recently_modified">გასული 7 დღის განმავლობაში შეცვლილი ფაილ(ებ)ი ვერ იქნა ნაპოვნი</string>
-    <string name="file_list_empty_search">იქნებ სხვა დირექტორიაშია?</string>
-    <string name="file_list_empty_shared_headline">ჯერ არაფერი გაზიარებულა</string>
-    <string name="file_list_folder">დირექტორია</string>
-    <string name="file_list_loading">იტვირთება…</string>
-    <string name="file_list_no_app_for_file_type">ამ ფაილთან სამუშაოდ არც ერთი აპლიკაცია არაა დაყანებული.</string>
-    <string name="file_list_seconds_ago">წამის წინ</string>
-    <string name="file_migration_directory_already_exists">მონაცემების დირექტორია უკვე არსებობს. აირჩიეთ ერთ-ერთი შემდეგიდან:</string>
-    <string name="file_migration_failed_dir_already_exists">Nextcloud დირექტორია უკვე არსებობს</string>
-    <string name="file_migration_failed_not_enough_space">საჭიროა მეტი სივრცე</string>
-    <string name="file_migration_failed_not_readable">წყარო-ფაილის წაკითხვა ვერ მოხერხდა</string>
-    <string name="file_migration_failed_not_writable">სამიზნე ფაილში ჩაწერა ვერ მოხერხდა</string>
-    <string name="file_migration_failed_while_coping">მიგრაციისას წარმოიქმნა შეცდომა</string>
-    <string name="file_migration_failed_while_updating_index">ინდექსის განახლება ვერ მოხერხდა</string>
-    <string name="file_migration_ok_finished">დასრულებულია</string>
-    <string name="file_migration_override_data_folder">ჩანაცვლება</string>
-    <string name="file_migration_source_not_readable_title">წყარო-დირექტორია ვერ იკითხება!</string>
-    <string name="file_migration_use_data_folder">მოხმარება</string>
-    <string name="file_not_found">ფაილი ვერ იქნა ნაპოვნი</string>
-    <string name="file_not_synced">ფაილის სინქ ვერ მოხერხდა. ნაჩვენებია ბოლო ხელმისაწვდომი ვარიანტი.</string>
-    <string name="file_rename">სახელის შეცვლა</string>
-    <string name="filedetails_details">დეტალები</string>
-    <string name="filedetails_download">ჩამოტვირთვა</string>
-    <string name="filedetails_export">ექსპორტი</string>
-    <string name="filedetails_renamed_in_upload_msg">ატვირთვისას ფაილს სახელი შეეცვალა %1$s-ზე</string>
-    <string name="filedetails_sync_file">სინქ</string>
-    <string name="filedisplay_no_file_selected">ფაილი არაა არჩეული</string>
-    <string name="filename_empty">ფაილის სახელი ვერ იქნება ცარიელი</string>
-    <string name="filename_forbidden_characters">აკრძალული ნიშნები: / \\ &lt; &gt; : \" | ? *</string>
-    <string name="filename_forbidden_charaters_from_server">ფაილის სახელი შეიცავს მინ. 1 არასწორ ნიშანს</string>
-    <string name="filename_hint">ფაილის სახელი</string>
-    <string name="folder_confirm_create">შექმნა</string>
-    <string name="folder_list_empty_headline">აქ დირექტორიები არაა</string>
-    <string name="folder_picker_choose_button_text">აირჩიეთ</string>
-    <string name="folder_picker_move_button_text">გადატანა</string>
-    <string name="forbidden_permissions">თქვენ არ გაქვთ უფლება, %s</string>
-    <string name="forbidden_permissions_copy">რომ დააკოპიროთ ეს ფაილი</string>
-    <string name="forbidden_permissions_create">შექმნათ ეს ფაილი</string>
-    <string name="forbidden_permissions_delete">გააუქმოთ ეს ფაილი</string>
-    <string name="forbidden_permissions_move">რომ გადაიტანოთ ეს ფაილი</string>
-    <string name="forbidden_permissions_rename">შეუცვალოთ ამ ფაილს სახელი</string>
-    <string name="foreground_service_upload">ფაილების ატვირთვა...</string>
-    <string name="foreign_files_fail">გარკვეული ფაილების გადატანა ვერ მოხერხდა</string>
-    <string name="foreign_files_local_text">ლოკალური: %1$s</string>
-    <string name="foreign_files_move">ყველას გადატანა</string>
-    <string name="foreign_files_remote_text">დისტანციური: %1$s</string>
-    <string name="foreign_files_success">ყველა ფაილი გადატანილია</string>
-    <string name="forward">წინ</string>
-    <string name="fourHours">4 საათი</string>
-    <string name="hint_name">სახელი</string>
-    <string name="hint_password">პაროლი</string>
-    <string name="instant_upload_on_charging">ატვირთვა მხოლოდ დატენვისას</string>
-    <string name="instant_upload_path">/მყისიერი_ატვირთვა</string>
-    <string name="invisible">უჩინარი</string>
-    <string name="link">ბმული</string>
-    <string name="link_share_allow_upload_and_editing">ატვირთვისა და ცვლილების უფლებების მინიჭება</string>
-    <string name="link_share_file_drop">ფაილის ჩაგდება (მხოლოდ ატვირთვა)</string>
-    <string name="list_layout">ჩამოწერილი მაკეტი</string>
-    <string name="local_file_list_empty">ამ დირექტორიაში ფაილები არაა.</string>
-    <string name="local_file_not_found_message">ლოკალურ ფაილ-სისტემაში ფაილი ვერ მოიძებნა</string>
-    <string name="local_folder_list_empty">მომდევნო დირექტორიები არაა.</string>
-    <string name="log_send_mail_subject">%1$s Android აპლიკაციის ლოგები.</string>
-    <string name="login">ლოგინი</string>
-    <string name="logs_menu_refresh">განახლება</string>
-    <string name="logs_status_loading">იტვირთება…</string>
-    <string name="logs_title">ლოგები</string>
-    <string name="manage_space_clear_data">მონაცემების გასუფთავება</string>
-    <string name="manage_space_description"> %1$s-ის მონაცემებიდან პარამეტრები, მონაცემთა ბაზა და სერტიფიკატები სამუდამოდ წაიშლება.\n\nგადმოწერილი ფაილები დარჩება ხელუხლებელი.\n\nეს პროცესი გასტანს გარკვეულ დროს.</string>
-    <string name="manage_space_title">მოცულობის მენეჯმენტი</string>
-    <string name="media_err_io">მედია ფაილის წაკითხვა ვერ მოხერხდა</string>
-    <string name="media_err_malformed">მედია ფაილს გააჩნია არასწორი კოდირება</string>
-    <string name="media_err_timeout">ფაილის დაკვრის მცდელობის დრო ამოიწურა</string>
-    <string name="media_err_unknown">ჩაშენებული მედია დამკვრელი ვერ უკრავს მედია ფაილს</string>
-    <string name="media_err_unsupported">მედია კოდეკი მხარდაუჭერელია</string>
-    <string name="media_forward_description">სწრაფი გადახვევის ღილაკი</string>
-    <string name="media_notif_ticker">%1$s მუსიკის დამკვრელი</string>
-    <string name="media_play_pause_description">დაკვრის ან პაუზის ღილაკი</string>
-    <string name="media_rewind_description">გადახვევის ღილაკი</string>
-    <string name="media_state_playing">%1$s (იკვრება)</string>
-    <string name="menu_item_sort_by_date_newest_first">ჯერ ახალი</string>
-    <string name="menu_item_sort_by_date_oldest_first">ჯერ ძველი</string>
-    <string name="menu_item_sort_by_name_a_z">ა - ჰ</string>
-    <string name="menu_item_sort_by_name_z_a">ჰ - ა</string>
-    <string name="menu_item_sort_by_size_biggest_first">ჯერ დიდი</string>
-    <string name="menu_item_sort_by_size_smallest_first">ჯერ პატარა</string>
-    <string name="more">მეტი</string>
-    <string name="move_file_error">ამ ფაილისა თუ დირექტორიის გადატანისას წარმოიშვა შეცდომა</string>
-    <string name="move_file_invalid_into_descendent">დირექტორიის გადატანა მასში არსებულ დირექტორიაში შეუძლებელია</string>
-    <string name="move_file_invalid_overwrite">ფაილი დანიშნულ დირექტორიაში უკვე არსებობს</string>
-    <string name="network_error_socket_exception">სერვერთან დაკავშირებისას წარმოიქმნა შეცდომა</string>
-    <string name="new_media_folder_photos">ფოტო</string>
-    <string name="notification_channel_download_description">აჩვენებს გადმოწერის პროგრესს</string>
-    <string name="notification_channel_download_name_short">ჩამოტვირთვები</string>
-    <string name="notification_channel_file_sync_description">აჩვენებს ფაილების სინქ. პროგრესს და შედეგებს</string>
-    <string name="notification_channel_file_sync_name">ფაილების სინქ.</string>
-    <string name="notification_channel_media_description">მუსიკის დამკვრელის პროგრესი</string>
-    <string name="notification_channel_media_name">მედია დამკვრელი</string>
-    <string name="notification_channel_upload_description">აჩვენებს ატვირთვის პროგრესს</string>
-    <string name="notification_channel_upload_name_short">ატვირთვები</string>
-    <string name="notifications_no_results_headline">შეტყობინებები არაა</string>
-    <string name="notifications_no_results_message">გთხოვთ დაბრუნდეთ მოგვინაებით.</string>
-    <string name="oneHour">1 საათი</string>
-    <string name="pass_code_configure_your_pass_code">შეიყვანეთ თქვენი პასკოდი</string>
-    <string name="pass_code_configure_your_pass_code_explanation">პასკოდი მოთხოვნილ იქნება აპლიკაციის ყოველი გაშვებისას</string>
-    <string name="pass_code_enter_pass_code">გთხოვთ შეიყვანოთ თქვენი პასკოდი</string>
-    <string name="pass_code_mismatch">პასკოდები ერთმანეთს არ ემთხვევა</string>
-    <string name="pass_code_reenter_your_pass_code">გთხოვთ თქვენი პასკოდი შეიყვანოთ ახლიდან</string>
-    <string name="pass_code_remove_your_pass_code">თქვენი პასკოდის გაუქმება</string>
-    <string name="pass_code_removed">პასკოდი გაუქმდა</string>
-    <string name="pass_code_stored">პასკოდი შენახულია</string>
-    <string name="pass_code_wrong">არასწორი პასკოდი</string>
-    <string name="permission_storage_access">ფაილების ატვირთვისა და გადმოწერისათვის საჭიროა დამატებითი უფლებები.</string>
-    <string name="picture_set_as_no_app">სურათის დასაყენებლად ვერც ერთი აპლიკაცია ვერ იქნა ნაპოვნი</string>
-    <string name="placeholder_fileSize">389 კბ</string>
-    <string name="placeholder_filename">ადგილი.txt</string>
-    <string name="placeholder_media_time">12:23:45</string>
-    <string name="placeholder_sentence">ეს არის ადგილი</string>
-    <string name="placeholder_timestamp">18/05/2012 12:23</string>
-    <string name="pref_behaviour_entries_delete_file">გაუქმებულია</string>
-    <string name="pref_behaviour_entries_keep_file">დარჩა ორიგინალ დირექტორიაში</string>
-    <string name="pref_behaviour_entries_move">გადატანილია აპლიკაციის დირექტორიაში</string>
-    <string name="prefs_add_account">ანგარიშის დამატება</string>
-    <string name="prefs_calendar_contacts_no_store_error">არც Google Play-ა დაყენებული, არც F-Droid-ი</string>
-    <string name="prefs_category_about">ჩვენს შესახებ</string>
-    <string name="prefs_category_details">დეტალები</string>
-    <string name="prefs_category_dev">დევ.</string>
-    <string name="prefs_category_general">ზოგადი</string>
-    <string name="prefs_category_more">მეტი</string>
-    <string name="prefs_daily_contact_backup_summary">კონტაქტების ყოველდღიური ბექაფი</string>
-    <string name="prefs_gpl_v2">GNU ზოგადი ღია ლიცენზია, ვერსია 2</string>
-    <string name="prefs_help">დახმარება</string>
-    <string name="prefs_imprint">ბეჭედი</string>
-    <string name="prefs_instant_upload_path_use_subfolders_title">ქვე-დირექტორიების მოხმარება</string>
-    <string name="prefs_license">ლიცენზია</string>
-    <string name="prefs_lock_none">არც ერთი</string>
-    <string name="prefs_manage_accounts">ანგარიშების მართვა</string>
-    <string name="prefs_show_hidden_files">დამალული ფაილების ჩვენება</string>
-    <string name="prefs_sourcecode">მიიღეთ კოდი</string>
-    <string name="prefs_synced_folders_local_path_title">ლოკალური დირექტორია</string>
-    <string name="prefs_synced_folders_remote_path_title">დისტანციური დირექტორია</string>
-    <string name="prefs_theme_title">ვიზუალური თემა</string>
-    <string name="prefs_value_theme_dark">მუქი</string>
-    <string name="prefs_value_theme_light">ღია</string>
-    <string name="preview_image_description">სურათის წინასწარი ჩვენება</string>
-    <string name="preview_image_error_no_local_file">წინასწარი ჩვენებისთვის ლოკალური ფაილი არაა</string>
-    <string name="preview_image_error_unknown_format">სურათის ჩვენება შეუძლებელია</string>
-    <string name="preview_sorry">ბოდიში</string>
-    <string name="privacy">კონფიდენციალურობა</string>
-    <string name="push_notifications_not_implemented">Google Play სერვისების მესაკუთრეობრივი დამოკიდებულებების გამო, ფუშ შეტყობინებები გათიშულია.</string>
-    <string name="push_notifications_old_login">ვადაგასული აუტენტიფიკაციის გამო ფუშ შეტყობინებები არაა. გთხოვთ გაითვალისწინოთ თქვენი ანგარიშის თავიდან დამატება.</string>
-    <string name="push_notifications_temp_error">ფუშ შეტყობინებები ამჟამად ხელმიუწვდომელია.</string>
-    <string name="recommend_subject">სცდეთ %1$s თქვენს მოწყობილობაზე!</string>
-    <string name="recommend_text">გიწვევთ გამოიყენოთ %1$s თქვენს მოწყობილობაზე.\nჩამოტვირთეთ აქედან: %2$s</string>
-    <string name="recommend_urls">%1$s ან %2$s</string>
-    <string name="reload">გადატვირთვა</string>
-    <string name="remove_fail_msg">გაუქმება ვერ მოხერხდა</string>
-    <string name="remove_push_notification">გაუქმება</string>
-    <string name="remove_success_msg">გაუქმდა</string>
-    <string name="rename_dialog_title">შეიყვანეთ ახალი სახელი</string>
-    <string name="rename_local_fail_msg">ლოკალური ასლის სახელის გადარქმევა ვერ მოხერხდა, სცადეთ სხვა სახელი</string>
-    <string name="rename_server_fail_msg">გადარქმევა შეუძლებელია, სახელი უკვე დაკავებულია</string>
-    <string name="reshare_not_allowed">ხელახალი გაზიარება არაა დაშვებული</string>
-    <string name="resharing_is_not_allowed">ხელახალი გაზიარება არაა ნებადართული</string>
-    <string name="resized_image_not_possible_download">ზომა-შეცვლილი სურათი არაა ხელმისაწვდომი. გადმოვწეროთ მთლიანი სურათი?</string>
-    <string name="select_all">ყველას მონიშვნა</string>
-    <string name="send">გაგზავნა</string>
-    <string name="set_as">დააყენეთ როგორც</string>
-    <string name="set_picture_as">გამოიყენეთ სურათი როგორც</string>
-    <string name="share">გაზიარება</string>
-    <string name="share_dialog_title">გაზიარება</string>
-    <string name="share_file">%1$s-ის გაზიარება</string>
-    <string name="share_group_clarification">%1$s (ჯგუფი)</string>
-    <string name="share_link">ბმულის გაზიარება</string>
-    <string name="share_link_empty_password">უნდა შეიყვანოთ პაროლი</string>
-    <string name="share_link_forbidden_permissions">გააზიაროთ ეს ფაილი</string>
-    <string name="share_link_password_title">შეიყვანეთ პაროლი</string>
-    <string name="share_no_expiration_date_label">მიუთითეთ ვადის გასვლის დრო</string>
-    <string name="share_no_password_title">პაროლის დაყენება</string>
-    <string name="share_permission_can_edit">შეუძლია შეცვალოს</string>
-    <string name="share_remote_clarification">%1$s (დისტანციური)</string>
-    <string name="share_settings">პარამეტრები</string>
-    <string name="share_via_link_section_title">ბმულის გაზიარება</string>
-    <string name="shared_icon_shared">გაზიარებული</string>
-    <string name="sort_by">დაასორტირე</string>
-    <string name="ssl_validator_btn_details_hide">დამალვა</string>
-    <string name="ssl_validator_btn_details_see">დეტალები</string>
-    <string name="ssl_validator_header">სერვერის იდენტურობა ვერ დამოწმდა</string>
-    <string name="ssl_validator_label_C">ქვეყანა:</string>
-    <string name="ssl_validator_label_CN">ზოგადი სახელი:</string>
-    <string name="ssl_validator_label_L">ადგილმდებარეობა:</string>
-    <string name="ssl_validator_label_O">ორგანიზაცია:</string>
-    <string name="ssl_validator_label_OU">ორგანიზაციის განყოფილება:</string>
-    <string name="ssl_validator_label_ST">შტატი:</string>
-    <string name="ssl_validator_label_certificate_fingerprint">თითის ანაბეჭდი:</string>
-    <string name="ssl_validator_label_issuer">გაცემულია მიერ:</string>
-    <string name="ssl_validator_label_signature">ხელმოწერა:</string>
-    <string name="ssl_validator_label_signature_algorithm">ალგორითმი:</string>
-    <string name="ssl_validator_label_subject">გაცემულია:</string>
-    <string name="ssl_validator_label_validity">მოქმედების ვადა:</string>
-    <string name="ssl_validator_label_validity_from">ვისგან:</string>
-    <string name="ssl_validator_label_validity_to">ვის:</string>
-    <string name="ssl_validator_no_info_about_error">- ამ შეცდომაზე ინფორმაცია არაა</string>
-    <string name="ssl_validator_not_saved">სერტიფიკატის შენახვა ვერ მოხერხდა</string>
-    <string name="ssl_validator_null_cert">სერტიფიკატის ჩვენება შეუძლებელია.</string>
-    <string name="ssl_validator_question">გსურთ მაინც ენდოთ ამ სერტიფიკატს?</string>
-    <string name="ssl_validator_reason_cert_expired">- სერვერის სერტიფიკატი ვადაგასულია</string>
-    <string name="ssl_validator_reason_cert_not_trusted">- სერვერის სერტიფიკატი არ არის სანდო</string>
-    <string name="ssl_validator_reason_cert_not_yet_valid">- სერვერის სერტიფიკატის თარიღები მომავალშია</string>
-    <string name="ssl_validator_reason_hostname_not_verified">- URL არ ემთხვევა სერტიფიკატში არსებულ ჰოსტნეიმს</string>
-    <string name="storage_description_default">საწყისი</string>
-    <string name="storage_downloads">ჩამოტვირთვები</string>
-    <string name="subject_shared_with_you">გაგიზიარდათ \"%1$s\"</string>
-    <string name="subject_user_shared_with_you">%1$s-სგან გაგიზიარდათ \"%2$s\"</string>
-    <string name="sync_conflicts_in_favourites_ticker">წარმოიშვა კონფლიქტი </string>
-    <string name="sync_current_folder_was_removed">დირექტორია %1$s აღარ არსებობს</string>
-    <string name="sync_fail_content">%1$s სინქ ვერ მოხერხდა</string>
-    <string name="sync_fail_content_unauthorized">%1$s რესურსის არასწორი პაროლი</string>
-    <string name="sync_fail_in_favourites_ticker">Kept-in-sync ფაილების შეცდომა</string>
-    <string name="sync_fail_ticker">სინქრონიზაცია დასრუდლა წარუმატებლად</string>
-    <string name="sync_fail_ticker_unauthorized">სინქ ვერ მოხერხდა, ახლიდან გაიარეთ ავტორიზაცია</string>
-    <string name="sync_file_nothing_to_do_msg">ფაილების შემცველობა სინქრონიზირებულია</string>
-    <string name="sync_foreign_files_forgotten_explanation">როდესაც ერთი ფაილი სინქრონიზირებულია რამოდენიმე ანგარიშთან, 1.3.16 ვერსიაში მონაცემების დაკარგვისგან თავის ასარიდებლად, ამ მოწყობილობით ატვირთული ფაილ(ებ)ი კოპირდება %1$s დირექტორიაში.\n\nამ ცვლილების გამო, აპლიკაციის ძველი ვერსიით ატვირთული ყველა ფაილი დაკოპირდა %2$s დირექტორიაში. თუმცა, შეცდომის გამო სინქრონიზაციისას მოხდა ამ ოპერაციის შეჩერება. შეგიძლიათ ფაილ(ებ)ი დატოვოთ ისე როგორც  არის და წაშალოთ ბმული %3$s-სთან, ან გადაიტანოთ ფაილ(ებ)ი %1$s დირექტორიაში და შეინარჩუნოთ ბმული %4$s-ისთვის.\n\nქვემოთ ჩამოწერილია ლოკალური და %5$s-ში არსებული დისტანციური ფაილ(ებ)ი.</string>
-    <string name="sync_foreign_files_forgotten_ticker">რამოდენიმე ლოკალური ფაილი გამორჩენილია</string>
-    <string name="sync_in_progress">ამოღებულია ფაილის უახლესი ვერსია.</string>
-    <string name="sync_status_button">სინქ. სტატუსის ღილაკი</string>
-    <string name="sync_string_files">ფაილები</string>
-    <string name="synced_folder_settings_button">პარამეტრების ღილაკი</string>
-    <string name="synced_folders_configure_folders">დირექტორიების კონფიგურაცია</string>
-    <string name="synced_folders_new_info">მყისიერი ატვირთვა სრულიად გამოსწორდა. ავტო-ატვირთვას რეკონფიგურაცია გაუწიეთ მთავარი მენიუდან.\n\nისიამოვნეთ ახალი და გაუმჯობესებული ავტო-ატვირთვით.</string>
-    <string name="synced_folders_preferences_folder_path">%1$s-ისთვის</string>
-    <string name="synced_folders_type">სახეობა</string>
-    <string name="tags">ტეგები</string>
-    <string name="test_server_button">სერვერთან კავშირის შემოწმება</string>
-    <string name="thirtyMinutes">30 წუთი</string>
-    <string name="thisWeek">ამ კვირაში</string>
-    <string name="thumbnail">მინიატურა</string>
-    <string name="today">დღეს</string>
-    <string name="trashbin_activity_title">გაუქმებული ფაილები</string>
-    <string name="trashbin_empty_headline">წაშლილი ფაილები ვერ მოიძებნა</string>
-    <string name="trashbin_file_remove">სამუდამოდ წაშლა</string>
-    <string name="unset_encrypted">შიფრაციის გაუქმება</string>
-    <string name="unshare_link_forbidden_permissions">შეწყვიტოთ ამ ფაილის გაზიარება</string>
-    <string name="untrusted_domain">წვდომა არასანდო დომენით. დამატებითი ინფორმაციისთვის გთხოვთ იხილოთ დოკუმენტაცია.</string>
-    <string name="update_link_forbidden_permissions">განაახლოთ ეს გაზიარება</string>
-    <string name="upload_action_failed_clear">წარუმატებლად დასრულებული ატვირთების გასუფთავება</string>
-    <string name="upload_action_failed_retry">წარუმატებლად დასრულებული ატვირთების ხელახლა გაშვება</string>
-    <string name="upload_file_dialog_filename">ფაილის სახელი</string>
-    <string name="upload_file_dialog_filetype">ფაილის სახეობა</string>
-    <string name="upload_file_dialog_filetype_googlemap_shortcut">Google Maps იარლიყის ფაილი(%s)</string>
-    <string name="upload_file_dialog_filetype_internet_shortcut">ინტერნეტ იარლიყის ფაილი(%s)</string>
-    <string name="upload_file_dialog_filetype_snippet_text">ტექსტ ფაილის ჩამონაჭერი(.txt)</string>
-    <string name="upload_file_dialog_title">ატვირთვისთვის შეიყვანეთ ფაილის სახელი და სახეობა</string>
-    <string name="upload_files">ფაილების ატვირთვა</string>
-    <string name="upload_item_action_button">ელემენტის ატვირთვის ქმედების ღილაკი</string>
-    <string name="upload_list_delete">წაშლა</string>
-    <string name="upload_list_empty_headline">არც ერთი ატვირთვა არაა ხელმისაწვდომი.</string>
-    <string name="upload_list_empty_text_auto_upload">ატვირთეთ რაიმე ან გაააქტიურეთ ავტო-ატვირთვა.</string>
-    <string name="upload_query_move_foreign_files">არასაკმარისი ადგილი აფერხებს არჩეული ფაილების კოპირებას %1$s დირექტორიაში. გსურთ სანაცვლოდ მათი გადატანა?</string>
-    <string name="upload_unknown_error">უცნობი შეცდომა</string>
-    <string name="uploader_btn_alternative_text">აირჩიეთ</string>
-    <string name="uploader_btn_upload_text">ატვირთვა</string>
-    <string name="uploader_error_message_no_file_to_upload">მიღებული მონაცემები არ მოიცავდნენ სწორ ფაილს.</string>
-    <string name="uploader_error_message_read_permission_not_granted">%1$s მომხმარებელს არ აქვს უფლება წაიკითხოს ფაილი.</string>
-    <string name="uploader_error_message_source_file_not_copied">ფაილის ასლი დროებით დირექტორიაში ვერ შეიქმნა. სცადეთ მისი ახლიდან გაგზავნა.</string>
-    <string name="uploader_error_message_source_file_not_found">ატვირთვისთვის არჩეული ფაილი ვერ იქნა ნაპოვნი. გთხოვთ დაამოწმოთ ფაილის არსებობა.</string>
-    <string name="uploader_error_title_no_file_to_upload">ფაილი ატვირთვისთვის არაა</string>
-    <string name="uploader_info_dirname">დირექტორიის სახელი</string>
-    <string name="uploader_top_message">აირჩიეთ ატვირთვის დირექტორია</string>
-    <string name="uploader_upload_failed_content_single">%1$s ვერ აიტვირთა</string>
-    <string name="uploader_upload_failed_credentials_error">ატვირთვა ვერ მოხერხდა, ახლიდან გაიარეთ ავტორიზაცია</string>
-    <string name="uploader_upload_failed_ticker">ატვირთვა ვერ განხორციელდა</string>
-    <string name="uploader_upload_files_behaviour">ატვირთვის ოპციონი:</string>
-    <string name="uploader_upload_files_behaviour_only_upload">ფაილის საწყის დირექტორიაში დატოვება</string>
-    <string name="uploader_upload_files_behaviour_upload_and_delete_from_source">ფაილის საწყისი დირექტორიიდან გაუქმება</string>
-    <string name="uploader_upload_forbidden_permissions">ატვირთოთ ამ დირექტორიაში</string>
-    <string name="uploader_upload_in_progress_content">%1$d%% ატვირთვა %2$s</string>
-    <string name="uploader_upload_in_progress_ticker">იტვირთება...</string>
-    <string name="uploader_upload_succeeded_content_single">ატვირთულია %1$s</string>
-    <string name="uploader_wrn_no_account_quit_btn_text">გამოსვლა</string>
-    <string name="uploader_wrn_no_account_setup_btn_text">დაყენება</string>
-    <string name="uploader_wrn_no_account_text">ანგარიშები %1$s თქვენს მოწყობილობაზე არაა. გთხოვთ დააყენოთ ანგარიში.</string>
-    <string name="uploader_wrn_no_account_title">ანგარიში ვერ მოიძებნა</string>
-    <string name="uploads_view_group_current_uploads">მიმდინარე</string>
-    <string name="uploads_view_group_failed_uploads">ვერ მოხერხებული/მიმდინარე რესტარტი</string>
-    <string name="uploads_view_group_finished_uploads">ატვირთულია</string>
-    <string name="uploads_view_group_manually_cancelled_uploads">უარყოფილია</string>
-    <string name="uploads_view_later_waiting_to_upload">ველოდებით ატვირთვას</string>
-    <string name="uploads_view_title">ატვირთვები</string>
-    <string name="uploads_view_upload_status_cancelled">უარყოფილია</string>
-    <string name="uploads_view_upload_status_conflict">კონფლიქტი</string>
-    <string name="uploads_view_upload_status_failed_connection_error">კავშირის პრობლემა</string>
-    <string name="uploads_view_upload_status_failed_credentials_error">შეცდომა უფლებამოსილებებში</string>
-    <string name="uploads_view_upload_status_failed_file_error">ფაილის შეცდომა</string>
-    <string name="uploads_view_upload_status_failed_folder_error">დირექტორიის შეცდომა</string>
-    <string name="uploads_view_upload_status_failed_localfile_error">ლოკალური ფაილი ვერ იქნა ნაპოვნი</string>
-    <string name="uploads_view_upload_status_failed_permission_error">შეცდომა უფლებებში</string>
-    <string name="uploads_view_upload_status_failed_ssl_certificate_not_trusted">სერვერის არასანდო სერტიფიკატი</string>
-    <string name="uploads_view_upload_status_service_interrupted">აპლიკაცია შეჩერდა</string>
-    <string name="uploads_view_upload_status_succeeded">დასრულებულია</string>
-    <string name="uploads_view_upload_status_unknown_fail">უცნობი შეცდომა</string>
-    <string name="uploads_view_upload_status_waiting_exit_power_save_mode">ველოდებით ეკონომიური რეჟიმიდან გამოსვლას</string>
-    <string name="uploads_view_upload_status_waiting_for_charging">გადახდის მოლოდინშია</string>
-    <string name="user_icon">მომხმარებელი</string>
-    <string name="user_info_address">მისამართი</string>
-    <string name="user_info_email">ელ-ფოსტა</string>
-    <string name="user_info_phone">ტელეფონის ნომერი</string>
-    <string name="user_info_twitter">Twitter-ი</string>
-    <string name="user_info_website">ვებ-საიტი</string>
-    <string name="user_information_retrieval_error">მოხმარებლის ინფორმაციის მიღებისას წარმოიშვა შეცდომა</string>
-    <string name="userinfo_no_info_headline">პირადი ინფორმაციის კომპლექტი არაა</string>
-    <string name="userinfo_no_info_text">დაამატეთ სახელი, ფოტო და საკონტაქტო დეტალები თქვენს პროფილის გვერდზე.</string>
-    <string name="username">მომხმარებლის სახელი</string>
-    <string name="version_dev_download">ჩამოტვირთვა</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>
-    <string name="write_email">ელ-წერილის გაგზავნა</string>
-    </resources>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Account creation failed</string>
     <string name="account_icon">Account icon</string>
     <string name="account_not_found">Account not found!</string>
-    <string name="action_clear_failed_uploads">Clear failed uploads</string>
     <string name="action_edit">Edit</string>
     <string name="action_empty_notifications">Clear all notifications</string>
     <string name="action_empty_trashbin">Empty trash bin</string>
@@ -152,7 +151,6 @@
     <string name="confirmation_remove_folder_alert">Do you really want to delete %1$s and the contents thereof?</string>
     <string name="confirmation_remove_folders_alert">Do you really want to delete the selected items and their contents?</string>
     <string name="confirmation_remove_local">Local only</string>
-    <string name="conflict_dialog_error">Error creating conflict dialog!</string>
     <string name="conflict_file_headline">Conflicting file %1$s</string>
     <string name="conflict_local_file">Local file</string>
     <string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">계정 생성에 실패했습니다.</string>
     <string name="account_icon">계정 아이콘</string>
     <string name="account_not_found">계정을 찾을 수 없습니다!</string>
-    <string name="action_clear_failed_uploads">실패한 업로드 삭제</string>
     <string name="action_edit">편집</string>
     <string name="action_empty_notifications">모든 알림 지우기</string>
     <string name="action_empty_trashbin">휴지통 비우기</string>
@@ -154,7 +153,6 @@
     <string name="confirmation_remove_folder_alert">%1$s 및 포함된 모든 내용을 삭제하시겠습니까?</string>
     <string name="confirmation_remove_folders_alert">선택한 항목과 포함된 내용을 삭제하시겠습니까?</string>
     <string name="confirmation_remove_local">로컬만</string>
-    <string name="conflict_dialog_error">다이얼로그의 충돌로 인한 오류</string>
     <string name="conflict_file_headline">충돌하는 파일 %1$s</string>
     <string name="conflict_local_file">로컬 파일</string>
     <string name="conflict_message_description">두 버전을 모두 선택하면 기존 파일 이름에 번호가 추가됩니다.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">ການສ້າງບັນຊີບໍ່ສຳເລັດ</string>
     <string name="account_icon">ໄອຄອນບັນຊີ</string>
     <string name="account_not_found">ບໍ່ພົບບັນຊີ!</string>
-    <string name="action_clear_failed_uploads">ການອັບໂຫຼດບໍ່ສຳເລັດ</string>
     <string name="action_edit">ແກ້ໄຂ</string>
     <string name="action_empty_notifications">ລ້າງການແຈ້ງເຕືອນທັງຫມົດ</string>
     <string name="action_empty_trashbin">ລ້າງຖັງຂີ້ເຫຍື່ອ</string>
@@ -145,7 +144,6 @@
     <string name="confirmation_remove_folder_alert">ທ່ານຕ້ອງການ ລຶບ%1$s ແລະ ເນື້ອຫາບໍ?</string>
     <string name="confirmation_remove_folders_alert">ທ່ານຕ້ອງການລຶບລາຍການທີ່ເລືອກ ແລະ ເນື້ອຫາແທ້ບໍ?</string>
     <string name="confirmation_remove_local">ຊ່ອງເກັບຢ່າງດຽວ</string>
-    <string name="conflict_dialog_error">ຄວາມຜິດພາດໃນການສ້າງການສົນທະນາຜິດພາດ!</string>
     <string name="conflict_file_headline">ຟາຍຜິດພາດ%1$s</string>
     <string name="conflict_message_description">ຖ້າທ່ານເລືອກເອົາທັງສອງເວີຊັ້ນ, ບ່ອນເກັບຟາຍຈະມີຈໍານວນສະສົມ</string>
     <string name="contactlist_item_icon">ລາຍການໄອຄອນຜູ້ຕິດຕໍ່</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Paskyros sukūrimas nepavyko</string>
     <string name="account_icon">Paskyros piktograma</string>
     <string name="account_not_found">Paskyra nerasta!</string>
-    <string name="action_clear_failed_uploads">Išvalyti nepavykusius įkėlimus</string>
     <string name="action_edit">Taisyti</string>
     <string name="action_empty_notifications">Išvalyti visus pranešimus</string>
     <string name="action_empty_trashbin">Išvalyti šiukšlinę</string>
@@ -147,7 +146,6 @@
     <string name="confirmation_remove_folder_alert">Ar tikrai norite ištrinti %1$s ir jo turinį?</string>
     <string name="confirmation_remove_folders_alert">Ar tikrai norite ištrinti pažymėtus elementus ir jų turinį?</string>
     <string name="confirmation_remove_local">Tik vietiniai</string>
-    <string name="conflict_dialog_error">Klaida kuriant konflikto dialogą!</string>
     <string name="conflict_file_headline">Nesuderinamas failas%1$s</string>
     <string name="conflict_local_file">Vietinis failas</string>
     <string name="conflict_message_description">Jei pasirinksite abi versijas, vietinis failas prie pavadinimo turės numerį.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Konta izveidošana neizdevās</string>
     <string name="account_icon">Konta ikona</string>
     <string name="account_not_found">Konts nav atrasts!</string>
-    <string name="action_clear_failed_uploads">Notīrīt neizdevušās augšupielādes</string>
     <string name="action_edit">Rediģēt</string>
     <string name="action_empty_notifications">Notīrīt visus paziņojumus</string>
     <string name="action_empty_trashbin">Izdzēst miskastes saturu</string>
@@ -123,7 +122,6 @@
     <string name="confirmation_remove_folder_alert">Vai tiešām vēlaties izdzēst %1$s un tā saturu?</string>
     <string name="confirmation_remove_folders_alert">Vai tiešām vēlies dzēst izvēlētos objektus un to saturu?</string>
     <string name="confirmation_remove_local">Tikai lokālos</string>
-    <string name="conflict_dialog_error">Kļūda veidojot konfliktu dialogu!</string>
     <string name="contactlist_item_icon">Lietotāja ikona kontaktpersonu sarakstam</string>
     <string name="contactlist_no_permission">Nav dota atļauja, importēšana neizdevās</string>
     <string name="contacts">Kontakti</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Неуспешно креирање на сметка</string>
     <string name="account_icon">Икона за сметката</string>
     <string name="account_not_found">Сметката не е пројандена!</string>
-    <string name="action_clear_failed_uploads">Исчисти ги неуспешните прикачувања</string>
     <string name="action_edit">Уреди</string>
     <string name="action_empty_notifications">Исчисти ги сите известувања</string>
     <string name="action_empty_trashbin">Испразни ја корпата со отпадоци</string>
@@ -144,7 +143,6 @@
     <string name="confirmation_remove_folder_alert">али си сигурен дека сакаш да ја избришеш %1$s и содржината во истата?</string>
     <string name="confirmation_remove_folders_alert">Дали си сигурен дека сакаш да ја избришеш означената ставкаи содржината во неа?</string>
     <string name="confirmation_remove_local">Само локално</string>
-    <string name="conflict_dialog_error">Грешка при креирање конфликтен извештај!</string>
     <string name="conflict_file_headline">Датотеки со конфликт %1$s</string>
     <string name="conflict_local_file">Локална датотека</string>
     <string name="conflict_message_description">Ако ги одберете и двете верзии, локалната датотека ќе има број додаден на нејзиното име.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Oppretting av konto mislyktes</string>
     <string name="account_icon">Kontoikon</string>
     <string name="account_not_found">Konto ble ikke funnet!</string>
-    <string name="action_clear_failed_uploads">Fjern feilede opplastinger</string>
     <string name="action_edit">Rediger</string>
     <string name="action_empty_notifications">Slett alle varsel</string>
     <string name="action_empty_trashbin">Tøm papirkurv</string>
@@ -57,6 +56,8 @@
     <string name="assistant_screen_task_types_error_state_message">Kan ikke hente oppgavetyper, vennligst sjekk internettforbindelsen din.</string>
     <string name="assistant_screen_top_bar_title">Assistent</string>
     <string name="assistant_screen_unknown_task_status_text">Ukjent</string>
+    <string name="assistant_task_detail_screen_input_button_title">Inndata</string>
+    <string name="assistant_task_detail_screen_output_button_title">Utdata</string>
     <string name="associated_account_not_found">Tilknyttet bruker ikke funnet!</string>
     <string name="auth_access_failed">Tilgang mislyktes: %1$s</string>
     <string name="auth_account_does_not_exist">Kontoen er ikke lagt til på denne enheten enda</string>
@@ -171,7 +172,6 @@
     <string name="confirmation_remove_folder_alert">Ønsker du virkelig å slette %1$s og dets innhold?</string>
     <string name="confirmation_remove_folders_alert">Vil du virkelig fjerne de valgte elementene og dets innhold?</string>
     <string name="confirmation_remove_local">Kun lokalt</string>
-    <string name="conflict_dialog_error">Feil ved oppretting av konfliktdialog!</string>
     <string name="conflict_file_headline">Konflikt med%1$s</string>
     <string name="conflict_local_file">Lokal fil</string>
     <string name="conflict_message_description">Hvis du velger begge versjonene vil den lokale filen få et tall lagt til på slutten av navnet.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Account aanmaken mislukt</string>
     <string name="account_icon">Accountpictogram</string>
     <string name="account_not_found">Account niet gevonden!</string>
-    <string name="action_clear_failed_uploads">Wis mislukte uploads</string>
     <string name="action_edit">Bewerken</string>
     <string name="action_empty_notifications">Handel alle meldingen af</string>
     <string name="action_empty_trashbin">Prullenbak legen</string>
@@ -167,7 +166,6 @@
     <string name="confirmation_remove_folder_alert">Wil je %1$s en de inhoud ervan werkelijk verwijderen?</string>
     <string name="confirmation_remove_folders_alert">Wil je de geselecteerde objecten en hun inhoud echt verwijderen?</string>
     <string name="confirmation_remove_local">Alleen lokaal</string>
-    <string name="conflict_dialog_error">Fout bij het maken van conflictdialoog!</string>
     <string name="conflict_file_headline">Conflicterend bestand%1$s</string>
     <string name="conflict_local_file">Lokaal bestand</string>
     <string name="conflict_message_description">Als je beide versies selecteert, zal het lokale bestand een nummer aan de naam toegevoegd krijgen.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Błąd tworzenia konta</string>
     <string name="account_icon">Ikona konta</string>
     <string name="account_not_found">Nie znaleziono konta!</string>
-    <string name="action_clear_failed_uploads">Wyczyść nieudane wysyłanie</string>
     <string name="action_edit">Edytuj</string>
     <string name="action_empty_notifications">Wyczyść wszystkie powiadomienia</string>
     <string name="action_empty_trashbin">Opróżnij kosz</string>
@@ -153,7 +152,6 @@
     <string name="confirmation_remove_folder_alert">Czy na pewno chcesz usunąć %1$s wraz z zawartością?</string>
     <string name="confirmation_remove_folders_alert">Czy na pewno chcesz usunąć wybrane pozycje i ich zawartość?</string>
     <string name="confirmation_remove_local">Tylko lokalnie</string>
-    <string name="conflict_dialog_error">Błąd podczas tworzenia dialogu konfliktu!</string>
     <string name="conflict_file_headline">Plik powodujący konflikt %1$s</string>
     <string name="conflict_local_file">Plik lokalny</string>
     <string name="conflict_message_description">Jeśli wybierzesz obie wersje, to do nazwy pliku lokalnego zostanie dodany numer.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Falha ao criar conta</string>
     <string name="account_icon">Ícone da conta</string>
     <string name="account_not_found">Conta não encontrada!</string>
-    <string name="action_clear_failed_uploads">Apagar envios com falha</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Apagar todas as notificações</string>
     <string name="action_empty_trashbin">Esvaziar lixeira </string>
@@ -57,6 +56,8 @@
     <string name="assistant_screen_task_types_error_state_message">Não foi possível buscar os tipos de tarefas. Verifique sua conexão com a Internet.</string>
     <string name="assistant_screen_top_bar_title">Assistente</string>
     <string name="assistant_screen_unknown_task_status_text">Desconhecido</string>
+    <string name="assistant_task_detail_screen_input_button_title">Entrada</string>
+    <string name="assistant_task_detail_screen_output_button_title">Saída</string>
     <string name="associated_account_not_found">Conta associada não encontrada!</string>
     <string name="auth_access_failed">O acesso falhou: %1$s</string>
     <string name="auth_account_does_not_exist">A conta ainda não está adicionada neste dispositivo</string>
@@ -171,7 +172,6 @@
     <string name="confirmation_remove_folder_alert">Quer realmente excluir %1$s e seu conteúdo?</string>
     <string name="confirmation_remove_folders_alert">Quer realmente excluir os itens selecionados e seus conteúdos?</string>
     <string name="confirmation_remove_local">Somente local</string>
-    <string name="conflict_dialog_error">Erro ao criar diálogo de conflito!</string>
     <string name="conflict_file_headline">Arquivo conflitante %1$s</string>
     <string name="conflict_local_file">Arquivo local</string>
     <string name="conflict_message_description">Se você selecionar as duas versões, o arquivo local terá um número anexado ao seu nome.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Criação de conta falhou</string>
     <string name="account_icon">Ícone de conta</string>
     <string name="account_not_found">Conta não encontrada!</string>
-    <string name="action_clear_failed_uploads">Limpar envios falhados</string>
     <string name="action_edit">Editar</string>
     <string name="action_empty_notifications">Limpar todas as notifcações</string>
     <string name="action_empty_trashbin">Esvaziar a reciclagem</string>
@@ -150,7 +149,6 @@
     <string name="confirmation_remove_folder_alert">Deseja realmente apagar %1$s e o seu conteúdo?</string>
     <string name="confirmation_remove_folders_alert">Quer realmente apagar os itens seleccionados e os seus conteúdos?</string>
     <string name="confirmation_remove_local">Apenas localmente</string>
-    <string name="conflict_dialog_error">Erro ao criar a janela de conflito!</string>
     <string name="conflict_file_headline">Ficheiro em conflito %1$s</string>
     <string name="conflict_local_file">Ficheiro local</string>
     <string name="conflict_message_description">Se selecionou ambas as versões, o ficheiro local terá um número acrescentado ao seu nome.</string>

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

@@ -7,7 +7,6 @@
     <string name="account_creation_failed">Eroare la crearea contului</string>
     <string name="account_icon">Iconița contului</string>
     <string name="account_not_found">Contul nu a fost găsit!</string>
-    <string name="action_clear_failed_uploads">Elimină încărcările eșuate</string>
     <string name="action_edit">Editare</string>
     <string name="action_empty_notifications">Elimină toate notificările</string>
     <string name="action_empty_trashbin">Golește coșul de gunoi</string>
@@ -150,7 +149,6 @@
     <string name="confirmation_remove_folder_alert">Sigur vreți să eliminați %1$s și conținutul său?</string>
     <string name="confirmation_remove_folders_alert">Doriți să ștergeți elementele selectate și conținutul lor?</string>
     <string name="confirmation_remove_local">Doar local</string>
-    <string name="conflict_dialog_error">Eroare la crearea dialogului pentru conflict!</string>
     <string name="conflict_file_headline">Conflict cu fișierul %1$s</string>
     <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>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio