diff --git a/build.gradle b/build.gradle index 0d5c1266..cb38ba75 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ allprojects { ext { androidApplicationId = 'org.cryptomator' androidVersionCode = getVersionCode() - androidVersionName = '1.6.7' + androidVersionName = '1.6.8' } repositories { mavenCentral() diff --git a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.kt b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.kt index 6458d4da..f0bc0b0c 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.kt @@ -56,5 +56,9 @@ class DropboxClientFactory { return HttpLoggingInterceptor(logger, context) } + fun logout() { + instance = null + } + } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudContentRepository.kt b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudContentRepository.kt index 1d9f39d1..101330e5 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudContentRepository.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudContentRepository.kt @@ -203,7 +203,7 @@ internal class DropboxCloudContentRepository(private val cloud: DropboxCloud, co @Throws(BackendException::class) override fun logout(cloud: DropboxCloud) { - // empty + this.cloud.logout() } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.kt b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.kt index bb6b6d5b..05555f46 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.kt @@ -372,6 +372,10 @@ internal class DropboxImpl(cloud: DropboxCloud, context: Context) { return currentAccount.name.displayName } + fun logout() { + DropboxClientFactory.logout() + } + companion object { private const val CHUNKED_UPLOAD_CHUNK_SIZE = 8L shl 20 diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.kt b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.kt index 684571c9..272071b5 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.kt @@ -59,5 +59,10 @@ class OnedriveClientFactory private constructor() { return HttpLoggingInterceptor(logger, context) } + + @Synchronized + fun logout() { + instance = null + } } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.kt b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.kt index 692a260a..2e3343ed 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.kt @@ -481,6 +481,8 @@ internal class OnedriveImpl(cloud: OnedriveCloud, context: Context, nodeInfoCach } catch (e: ExecutionException) { throw FatalBackendException(e) } + + OnedriveClientFactory.logout() } companion object { diff --git a/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudClientFactory.kt b/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudClientFactory.kt index c69d2f3b..29cc8d71 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudClientFactory.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudClientFactory.kt @@ -53,5 +53,10 @@ class PCloudClientFactory { return HttpLoggingInterceptor(logger, context) } + + @Synchronized + fun logout() { + instance = null + } } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudContentRepository.kt b/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudContentRepository.kt index 4b23cf25..39404bb8 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudContentRepository.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudContentRepository.kt @@ -171,7 +171,7 @@ internal class PCloudContentRepository(private val cloud: PCloud, context: Conte @Throws(BackendException::class) override fun logout(cloud: PCloud) { - // empty + this.cloud.logout() } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudImpl.kt b/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudImpl.kt index 637a3714..351f174f 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudImpl.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/pcloud/PCloudImpl.kt @@ -359,6 +359,10 @@ internal class PCloudImpl(context: Context, cloud: PCloud) { } } + fun logout() { + PCloudClientFactory.logout() + } + init { if (cloud.accessToken() == null) { throw NoAuthenticationProvidedException(cloud) diff --git a/data/src/main/java/org/cryptomator/data/cloud/s3/S3ClientFactory.kt b/data/src/main/java/org/cryptomator/data/cloud/s3/S3ClientFactory.kt index 501fc6ea..ca0e188a 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/s3/S3ClientFactory.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/s3/S3ClientFactory.kt @@ -85,5 +85,10 @@ class S3ClientFactory private constructor() { val activeNetworkInfo = connectivityManager.activeNetworkInfo return activeNetworkInfo != null && activeNetworkInfo.isConnected } + + @Synchronized + fun logout() { + instance = null + } } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/s3/S3CloudContentRepository.kt b/data/src/main/java/org/cryptomator/data/cloud/s3/S3CloudContentRepository.kt index ce9e038f..071ca589 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/s3/S3CloudContentRepository.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/s3/S3CloudContentRepository.kt @@ -169,7 +169,7 @@ internal class S3CloudContentRepository(private val cloud: S3Cloud, context: Con @Throws(BackendException::class) override fun logout(cloud: S3Cloud) { - // empty + this.cloud.logout() } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt b/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt index f8d4429f..e281f02b 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt @@ -366,6 +366,10 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { } } + fun logout() { + S3ClientFactory.logout() + } + companion object { private const val DELIMITER = "/" diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt index 22d912c2..7ffc8fe4 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt @@ -110,12 +110,11 @@ internal class WebDavCompatibleHttpClient(cloud: WebDavCloud, context: Context) val credentials = Credentials(webDavCloud.username(), decryptPassword(context, webDavCloud.password())) val basicAuthenticator = BasicAuthenticator(credentials, StandardCharsets.UTF_8) val digestAuthenticator = DigestAuthenticator(credentials) - var result: Authenticator = DispatchingAuthenticator.Builder() // + val authenticator = DispatchingAuthenticator.Builder() // .with("digest", digestAuthenticator) // .with("basic", basicAuthenticator) // .build() - result = CachingAuthenticatorDecorator(result, authCache) - return result + return CachingAuthenticatorDecorator(authenticator, authCache) } @Throws(UnableToDecryptWebdavPasswordException::class) diff --git a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt index 66b5a2dc..acc5e6d5 100644 --- a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt +++ b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt @@ -61,5 +61,9 @@ class GoogleDriveClientFactory internal constructor() { } .build() } + + fun invalidateClient() { + instance = null + } } } diff --git a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveCloudContentRepository.kt b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveCloudContentRepository.kt index 85f160d7..e20369f9 100644 --- a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveCloudContentRepository.kt +++ b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveCloudContentRepository.kt @@ -188,7 +188,7 @@ internal class GoogleDriveCloudContentRepository(context: Context, private val c @Throws(BackendException::class) override fun logout(cloud: GoogleDriveCloud) { - // empty + impl.logout() } } diff --git a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.kt b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.kt index 4365e810..fe021368 100644 --- a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.kt +++ b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.kt @@ -382,6 +382,10 @@ internal class GoogleDriveImpl(context: Context, googleDriveCloud: GoogleDriveCl return about.user.displayName } + fun logout() { + GoogleDriveClientFactory.invalidateClient() + } + companion object { private const val STATUS_REQUEST_RANGE_NOT_SATISFIABLE = 416 diff --git a/fastlane/metadata/android/de-DE/changelogs/default.txt b/fastlane/metadata/android/de-DE/changelogs/default.txt index 413692c6..65c19714 100644 --- a/fastlane/metadata/android/de-DE/changelogs/default.txt +++ b/fastlane/metadata/android/de-DE/changelogs/default.txt @@ -1 +1,2 @@ -- Automatischer Upload bei Geräten mit Android Version 10 behoben \ No newline at end of file +- Zeige Dialog und Benachrichtigung an, wenn die Berechtigung "Dateien" widerrufen wird, erforderlich für den automatischen Upload +- Das Abmelden von einer Cloud löscht nun auch die Anmeldeinformationen einer aktiven Verbindung zu ihr \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/default.txt b/fastlane/metadata/android/en-US/changelogs/default.txt index ccbf9fab..553889a4 100644 --- a/fastlane/metadata/android/en-US/changelogs/default.txt +++ b/fastlane/metadata/android/en-US/changelogs/default.txt @@ -1 +1,2 @@ -- Fixed auto upload via devices running Android version 10 \ No newline at end of file +- Show information when "Storage" permission revoked, required for auto upload +- Logging out of a cloud now also clears the credentials of an active connection to it \ No newline at end of file diff --git a/fastlane/release-notes.html b/fastlane/release-notes.html index d18e9f07..f9ebcce6 100644 --- a/fastlane/release-notes.html +++ b/fastlane/release-notes.html @@ -1,3 +1,4 @@ \ No newline at end of file diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt index edea86e7..c0844d1c 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt @@ -112,6 +112,7 @@ class UnlockVaultPresenter @Inject constructor( view?.closeDialog() val error = result.getSingleResult(Throwable::class.java) error?.let { showError(it) } + finishWithResult(null) } } @@ -219,6 +220,7 @@ class UnlockVaultPresenter @Inject constructor( view?.closeDialog() val error = result.getSingleResult(Throwable::class.java) error?.let { showError(it) } + finishWithResult(null) } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt index 101e826b..4b19ef9d 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt @@ -1,5 +1,6 @@ package org.cryptomator.presentation.presenter +import android.Manifest import android.app.KeyguardManager import android.app.admin.DevicePolicyManager import android.content.ActivityNotFoundException @@ -56,6 +57,7 @@ import org.cryptomator.presentation.workflow.ActivityResult import org.cryptomator.presentation.workflow.AddExistingVaultWorkflow import org.cryptomator.presentation.workflow.AuthenticationExceptionHandler import org.cryptomator.presentation.workflow.CreateNewVaultWorkflow +import org.cryptomator.presentation.workflow.PermissionsResult import org.cryptomator.presentation.workflow.Workflow import org.cryptomator.util.SharedPreferencesHandler import javax.inject.Inject @@ -112,6 +114,10 @@ class VaultListPresenter @Inject constructor( // } checkLicense() + + if(sharedPreferencesHandler.usePhotoUpload()) { + checkLocalStoragePermissionRegardingAutoUpload() + } } private fun checkLicense() { @@ -185,6 +191,27 @@ class VaultListPresenter @Inject constructor( // } } + private fun checkLocalStoragePermissionRegardingAutoUpload() { + requestPermissions( + PermissionsResultCallbacks.onLocalStoragePermissionGrantedForAutoUpload(), // + R.string.permission_snackbar_auth_auto_upload, // + Manifest.permission.READ_EXTERNAL_STORAGE + ) + } + + @Callback + fun onLocalStoragePermissionGrantedForAutoUpload(result: PermissionsResult) { + if (!result.granted()) { + Timber.tag("VaultListPresenter").e("Local storage permission not granted, auto upload will not work") + } + } + + fun loadVaultList() { + view?.hideVaultCreationHint() + vaultList + assertUnlockingVaultIsLocked() + } + private fun assertUnlockingVaultIsLocked() { if (view?.isShowingDialog(EnterPasswordDialog::class) == true) { if (view?.currentDialog() != null) { @@ -196,12 +223,6 @@ class VaultListPresenter @Inject constructor( // } } - fun loadVaultList() { - view?.hideVaultCreationHint() - vaultList - assertUnlockingVaultIsLocked() - } - fun deleteVault(vaultModel: VaultModel) { deleteVaultUseCase // .withVault(vaultModel.toVault()) // diff --git a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt index 232db6e1..d2f38f46 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt @@ -47,18 +47,15 @@ class AutoUploadNotification(private val context: Context, private val amountOfP } private fun cancelNowAction(): NotificationCompat.Action { + val intentAction = cancelAutoUploadIntent(context) + val cancelIntent = PendingIntent.getService(context, 0, intentAction, FLAG_CANCEL_CURRENT) return NotificationCompat.Action.Builder( // R.drawable.ic_lock, // getString(R.string.notification_cancel_auto_upload), // - cancelNowIntent() // + cancelIntent // ).build() } - private fun cancelNowIntent(): PendingIntent { - val intentAction = cancelAutoUploadIntent(context) - return PendingIntent.getService(context, 0, intentAction, FLAG_CANCEL_CURRENT) - } - private fun startTheActivity(): PendingIntent { val startTheActivity = Intent(context, VaultListActivity::class.java) startTheActivity.action = ACTION_MAIN @@ -67,8 +64,8 @@ class AutoUploadNotification(private val context: Context, private val amountOfP } fun update(progress: Int) { - builder.setContentIntent(startTheActivity()) builder // + .setContentIntent(startTheActivity()) .setContentText( // String.format( context.getString(R.string.notification_auto_upload_message), // @@ -105,27 +102,32 @@ class AutoUploadNotification(private val context: Context, private val amountOfP showErrorWithMessage(context.getString(R.string.notification_auto_upload_failed_due_to_vault_not_found)) } + fun showPermissionNotGrantedNotification() { + Timber.tag("AutoUploadNotification").i("Show storage permission required notification") + showErrorWithMessage(context.getString(R.string.notification_auto_upload_permission_not_granted)) + } + private fun showErrorWithMessage(message: String) { - builder.setContentIntent(startTheActivity()) - builder // + builder + .setContentIntent(startTheActivity()) .setContentTitle(context.getString(R.string.notification_auto_upload_failed_title)) .setContentText(message) // .setProgress(0, 0, false) .setAutoCancel(true) .setOngoing(false) - .mActions.clear() + .clearActions() show() } fun showUploadFinished(size: Int) { - builder.setContentIntent(startTheActivity()) - builder // + builder + .setContentIntent(startTheActivity()) .setContentTitle(context.getString(R.string.notification_auto_upload_finished_title)) - .setContentText(format(context.getString(R.string.notification_auto_upload_finished_message), size)) // + .setContentText(format(context.getString(R.string.notification_auto_upload_finished_message), size)) .setProgress(0, 0, false) .setAutoCancel(true) .setOngoing(false) - .mActions.clear() + .clearActions() show() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java index b4a56aec..b760436d 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java +++ b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java @@ -10,6 +10,8 @@ import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Looper; +import android.system.ErrnoException; +import android.system.OsConstants; import androidx.annotation.Nullable; @@ -37,6 +39,7 @@ import org.cryptomator.presentation.util.FileUtil; import org.cryptomator.util.SharedPreferencesHandler; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Date; @@ -111,6 +114,8 @@ public class AutoUploadService extends Service { notification.showVaultLockedDuringUpload(); } else if (e instanceof CancellationException) { Timber.tag("AutoUploadService").i("Upload canceled by user"); + } else if (wrappedStoragePermissionException(e)) { + notification.showPermissionNotGrantedNotification(); } else { notification.showGeneralErrorDuringUpload(); } @@ -122,6 +127,14 @@ public class AutoUploadService extends Service { worker.start(); } + private boolean wrappedStoragePermissionException(Exception e) { + return e.getCause() != null // + && e.getCause() instanceof FileNotFoundException // + && e.getCause().getCause() != null // + && e.getCause().getCause() instanceof ErrnoException // + && ((ErrnoException) e.getCause().getCause()).errno == OsConstants.EACCES; + } + private void updateNotification(int asPercentage) { if (elapsedTimeAutoUploadNotificationDelay > 200 && !cancelled) { new Handler(Looper.getMainLooper()).post(() -> { @@ -170,8 +183,7 @@ public class AutoUploadService extends Service { } catch (FileRemovedDuringUploadException e) { Timber.tag("AutoUploadService").i("Not uploading file because it was removed during upload"); Timber.tag("AutoUploadService").v(format("Not uploading file because it was removed during upload %s", file.getFileName())); - } - catch (Exception e) { + } catch (Exception e) { cancelled = true; fileUtil.removeImagesFromAutoUploads(uploadedCloudFileNames); throw e; @@ -200,7 +212,7 @@ public class AutoUploadService extends Service { private CloudFile writeCloudFile(String fileName, CancelAwareDataSource dataSource, boolean replacing, ProgressAware progressAware) throws BackendException { Long size = dataSource.size(context); - if(size == null) { + if (size == null) { throw new FileRemovedDuringUploadException(); } CloudFile source = cloudContentRepository.file(parent, fileName, size); diff --git a/presentation/src/main/res/values-fr-rFR/strings.xml b/presentation/src/main/res/values-fr-rFR/strings.xml index b93d9509..4f5663ab 100644 --- a/presentation/src/main/res/values-fr-rFR/strings.xml +++ b/presentation/src/main/res/values-fr-rFR/strings.xml @@ -13,10 +13,10 @@ Le coffre-fort existe déjà. Le fichier n\'existe pas. Le coffre-fort a été verrouillé. - Cloud existant. + Compte Cloud déjà existant. Veuillez télécharger une application qui peut ouvrir ce fichier. Serveur introuvable. - Veuillez ouvrir les paramètres de votre appareil et régler le verrouillage de l\'écran à la main + Veuillez ouvrir les paramètres de votre appareil et activer le verrouillage manuel de l\'écran L\'exportation a échoué. Essayez de supprimer les caractères spéciaux des noms de fichiers et d\'exporter à nouveau. Ne peut pas contenir de caractères spéciaux. Les noms de fichiers ne peuvent pas contenir de caractères spéciaux. @@ -24,24 +24,24 @@ La vérification de la mise à jour a échoué. Une erreur générale s\'est produite. La vérification de la mise à jour a échoué. Le hachage calculé ne correspond pas au fichier téléchargé La vérification de la mise à jour a échoué. Pas de connexion Internet. - Echec lors du déchiffrement du mot de passe WebDAV, veuillez l\'ajouter une nouvelle fois dans les paramètres + Échec lors du déchiffrement du mot de passe WebDAV, veuillez l\'ajouter une nouvelle fois dans les paramètres Les services Google Play ne sont pas installés Authentification biométrique avortée La version spécifiée dans %1$s est différente de %2$s %1$s ne correspond pas à ce %2$s Erreur générale lors du chargement de la configuration du coffre - Le fichier local n\'est plus présent après le retour à Cryptomator. Les éventuels modifications ne peuvent être propagées au nuage. - Aucun compartiment de ce type - Localisation personnalisée de Masterkey pas encore prise en charge + Le fichier local n\'est plus présent après le retour à Cryptomator. Les éventuelles modifications ne peuvent être propagées dans le cloud. + Aucun bucket correspondant + Localisation personnalisée de la Masterkey n\'est pas encore prise en charge Stockage local Cryptomator a besoin de l\'accès au stockage pour exporter des fichiers - Cryptomateur a besoin de l\'accès au stockage pour téléverser des fichiers + Cryptomator a besoin de l\'accès au stockage pour envoyer des fichiers Cryptomator a besoin de l\'accès au stockage pour partager des fichiers - Cryptomator n\'a plus accès à cet emplacement. Merci de resélectionner ce répertoire pour restaurer les droits d\'accès. + Cryptomator n\'a plus accès à cet emplacement. Merci de re-sélectionner ce répertoire pour restaurer les droits d\'accès. Paramètres Rechercher Précédent @@ -50,7 +50,7 @@ A - Z Z - A Récent d\'abord - Plus ancien + Ancien d\'abord Taille décroissante Taille croissante diff --git a/presentation/src/main/res/values-it-rIT/strings.xml b/presentation/src/main/res/values-it-rIT/strings.xml index b6e53a95..635eedcb 100644 --- a/presentation/src/main/res/values-it-rIT/strings.xml +++ b/presentation/src/main/res/values-it-rIT/strings.xml @@ -368,6 +368,7 @@ Errore generale durante il caricamento. La cartella selezionata per il caricamento non è più disponibile. Vai alle impostazioni e sceglierne una nuova Cassaforte bloccata durante il caricamento, riapri la cassaforte per continuare + La cassaforte specificata per il caricamento automatico non esiste più. Apri file scrivibile La cassaforte rimane sbloccata fino alla modifica completata Ultima versione installata diff --git a/presentation/src/main/res/values-nb-rNO/strings.xml b/presentation/src/main/res/values-nb-rNO/strings.xml index e1f4a372..d1342c6f 100644 --- a/presentation/src/main/res/values-nb-rNO/strings.xml +++ b/presentation/src/main/res/values-nb-rNO/strings.xml @@ -9,10 +9,19 @@ Ingen nettverkstilkobling Feil passord En fil eller mappe finnes allerede. + Hvelvet støttes ikke. Dette hvelvet er laget med en annen versjon av Cryptomator. Hvelvet finnes allerede. Filen finnes ikke. Hvelvet har blitt låst. Skylagringen finnes allerede. + Vennligst last ned en app som kan åpne denne filen. + Serveren ble ikke funnet. + Vennligst åpne enhetsinnstillingene og angi skjermlås manuelt + Eksporteringen mislyktes. Prøv å fjerne spesialtegn fra filnavnet og eksporter på nytt. + Kan ikke inneholde spesialtegn. + Filnavn kan ikke inneholde spesialtegn. + Navn på hvelvet kan ikke inneholde spesialtegn. + Oppdateringskontrollen mislyktes. Det oppstod en generell feil. Lokal lagring diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 8ed8a1de..243af0ee 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -538,6 +538,7 @@ Selected folder for upload isn\'t available anymore. Go to settings and choose a new one Vault locked during upload, please reopen vault to continue Vault specified for auto upload doesn\'t exist anymore. + @string/permission_snackbar_auth_auto_upload @string/dialog_button_cancel Open writable file