Reformat code using new Kotlin formatting rule

This commit is contained in:
Julian Raufelder 2021-05-17 18:26:07 +02:00
parent bb07076ba8
commit 5c024dbda9
No known key found for this signature in database
GPG Key ID: 17EE71F6634E381D
122 changed files with 2235 additions and 2008 deletions

View File

@ -88,7 +88,8 @@ public class CryptoCloudFactory {
case MASTERKEY_SCHEME: { case MASTERKEY_SCHEME: {
return new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom); return new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom);
} }
default: throw new IllegalStateException(String.format("Provider with scheme %s not supported", unverifiedVaultConfigOptional.get().getKeyId().getScheme())); default:
throw new IllegalStateException(String.format("Provider with scheme %s not supported", unverifiedVaultConfigOptional.get().getKeyId().getScheme()));
} }
} else { } else {
return new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom); return new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom);

View File

@ -162,7 +162,7 @@ public class MasterkeyCryptoCloudProvider implements CryptoCloudProvider {
private CloudFile masterkeyFile(CloudFolder vaultLocation, UnverifiedVaultConfig unverifiedVaultConfig) throws BackendException { private CloudFile masterkeyFile(CloudFolder vaultLocation, UnverifiedVaultConfig unverifiedVaultConfig) throws BackendException {
String path = unverifiedVaultConfig.getKeyId().getSchemeSpecificPart(); String path = unverifiedVaultConfig.getKeyId().getSchemeSpecificPart();
if(!path.equals(MASTERKEY_FILE_NAME)) { if (!path.equals(MASTERKEY_FILE_NAME)) {
throw new UnsupportedMasterkeyLocationException(unverifiedVaultConfig); throw new UnsupportedMasterkeyLocationException(unverifiedVaultConfig);
} }
return cloudContentRepository.file(vaultLocation, path); return cloudContentRepository.file(vaultLocation, path);

View File

@ -28,13 +28,13 @@ class VaultConfig private constructor(builder: VaultConfigBuilder) {
fun toToken(rawKey: ByteArray): String { fun toToken(rawKey: ByteArray): String {
return Jwts.builder() return Jwts.builder()
.setHeaderParam(JSON_KEY_ID, keyId.toASCIIString()) // .setHeaderParam(JSON_KEY_ID, keyId.toASCIIString()) //
.setId(id) // .setId(id) //
.claim(JSON_KEY_VAULTFORMAT, vaultFormat) // .claim(JSON_KEY_VAULTFORMAT, vaultFormat) //
.claim(JSON_KEY_CIPHERCONFIG, cipherCombo.name) // .claim(JSON_KEY_CIPHERCONFIG, cipherCombo.name) //
.claim(JSON_KEY_SHORTENING_THRESHOLD, shorteningThreshold) // .claim(JSON_KEY_SHORTENING_THRESHOLD, shorteningThreshold) //
.signWith(Keys.hmacShaKeyFor(rawKey)) // .signWith(Keys.hmacShaKeyFor(rawKey)) //
.compact() .compact()
} }
class VaultConfigBuilder { class VaultConfigBuilder {
@ -101,18 +101,18 @@ class VaultConfig private constructor(builder: VaultConfigBuilder) {
fun verify(rawKey: ByteArray, unverifiedVaultConfig: UnverifiedVaultConfig): VaultConfig { fun verify(rawKey: ByteArray, unverifiedVaultConfig: UnverifiedVaultConfig): VaultConfig {
return try { return try {
val parser = Jwts // val parser = Jwts //
.parserBuilder() // .parserBuilder() //
.setSigningKey(rawKey) // .setSigningKey(rawKey) //
.require(JSON_KEY_VAULTFORMAT, unverifiedVaultConfig.vaultFormat) // .require(JSON_KEY_VAULTFORMAT, unverifiedVaultConfig.vaultFormat) //
.build() // .build() //
.parseClaimsJws(unverifiedVaultConfig.jwt) .parseClaimsJws(unverifiedVaultConfig.jwt)
val vaultConfigBuilder = createVaultConfig() // val vaultConfigBuilder = createVaultConfig() //
.keyId(unverifiedVaultConfig.keyId) .keyId(unverifiedVaultConfig.keyId)
.id(parser.header[JSON_KEY_ID] as String) // .id(parser.header[JSON_KEY_ID] as String) //
.cipherCombo(VaultCipherCombo.valueOf(parser.body.get(JSON_KEY_CIPHERCONFIG, String::class.java))) // .cipherCombo(VaultCipherCombo.valueOf(parser.body.get(JSON_KEY_CIPHERCONFIG, String::class.java))) //
.vaultFormat(unverifiedVaultConfig.vaultFormat) // .vaultFormat(unverifiedVaultConfig.vaultFormat) //
.shorteningThreshold(parser.body[JSON_KEY_SHORTENING_THRESHOLD] as Int) .shorteningThreshold(parser.body[JSON_KEY_SHORTENING_THRESHOLD] as Int)
VaultConfig(vaultConfigBuilder) VaultConfig(vaultConfigBuilder)
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -33,6 +33,30 @@ class S3ClientFactory {
return new HttpLoggingInterceptor(message -> Timber.tag("OkHttp").d(message), context); return new HttpLoggingInterceptor(message -> Timber.tag("OkHttp").d(message), context);
} }
private static Interceptor provideOfflineCacheInterceptor(final Context context) {
return chain -> {
Request request = chain.request();
if (isNetworkAvailable(context)) {
final CacheControl cacheControl = new CacheControl.Builder() //
.maxAge(0, TimeUnit.DAYS) //
.build();
request = request.newBuilder() //
.cacheControl(cacheControl) //
.build();
}
return chain.proceed(request);
};
}
private static boolean isNetworkAvailable(final Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
public MinioClient getClient(S3Cloud cloud, Context context) { public MinioClient getClient(S3Cloud cloud, Context context) {
if (apiClient == null) { if (apiClient == null) {
apiClient = createApiClient(cloud, context); apiClient = createApiClient(cloud, context);
@ -66,30 +90,6 @@ class S3ClientFactory {
.build(); .build();
} }
private static Interceptor provideOfflineCacheInterceptor(final Context context) {
return chain -> {
Request request = chain.request();
if (isNetworkAvailable(context)) {
final CacheControl cacheControl = new CacheControl.Builder() //
.maxAge(0, TimeUnit.DAYS) //
.build();
request = request.newBuilder() //
.cacheControl(cacheControl) //
.build();
}
return chain.proceed(request);
};
}
private static boolean isNetworkAvailable(final Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private String decrypt(String password, Context context) { private String decrypt(String password, Context context) {
return CredentialCryptor // return CredentialCryptor //
.getInstance(context) // .getInstance(context) //

View File

@ -1,14 +1,7 @@
package org.cryptomator.data.cloud.s3; package org.cryptomator.data.cloud.s3;
public enum S3CloudApiErrorCodes { public enum S3CloudApiErrorCodes {
ACCESS_DENIED("AccessDenied"), ACCESS_DENIED("AccessDenied"), ACCOUNT_PROBLEM("AccountProblem"), INTERNAL_ERROR("InternalError"), INVALID_ACCESS_KEY_ID("InvalidAccessKeyId"), INVALID_BUCKET_NAME("InvalidBucketName"), INVALID_OBJECT_STATE("InvalidObjectState"), NO_SUCH_BUCKET("NoSuchBucket"), NO_SUCH_KEY("NoSuchKey");
ACCOUNT_PROBLEM("AccountProblem"),
INTERNAL_ERROR("InternalError"),
INVALID_ACCESS_KEY_ID("InvalidAccessKeyId"),
INVALID_BUCKET_NAME("InvalidBucketName"),
INVALID_OBJECT_STATE("InvalidObjectState"),
NO_SUCH_BUCKET("NoSuchBucket"),
NO_SUCH_KEY("NoSuchKey");
private final String value; private final String value;

View File

@ -3,9 +3,7 @@ package org.cryptomator.data.cloud.s3;
public class S3CloudApiExceptions { public class S3CloudApiExceptions {
public static boolean isAccessProblem(String errorCode) { public static boolean isAccessProblem(String errorCode) {
return errorCode.equals(S3CloudApiErrorCodes.ACCESS_DENIED.getValue()) return errorCode.equals(S3CloudApiErrorCodes.ACCESS_DENIED.getValue()) || errorCode.equals(S3CloudApiErrorCodes.ACCOUNT_PROBLEM.getValue()) || errorCode.equals(S3CloudApiErrorCodes.INVALID_ACCESS_KEY_ID.getValue());
|| errorCode.equals(S3CloudApiErrorCodes.ACCOUNT_PROBLEM.getValue())
|| errorCode.equals(S3CloudApiErrorCodes.INVALID_ACCESS_KEY_ID.getValue());
} }
public static boolean isNoSuchBucketException(String errorCode) { public static boolean isNoSuchBucketException(String errorCode) {

View File

@ -63,7 +63,7 @@ class S3CloudContentRepository extends InterceptingCloudContentRepository<S3Clou
if (S3CloudApiExceptions.isAccessProblem(errorCode)) { if (S3CloudApiExceptions.isAccessProblem(errorCode)) {
throw new WrongCredentialsException(cloud); throw new WrongCredentialsException(cloud);
} }
} else if(e instanceof ForbiddenException) { } else if (e instanceof ForbiddenException) {
throw new WrongCredentialsException(cloud); throw new WrongCredentialsException(cloud);
} }
} }

View File

@ -107,7 +107,7 @@ class S3Impl {
public boolean exists(S3Node node) throws BackendException { public boolean exists(S3Node node) throws BackendException {
String key = node.getKey(); String key = node.getKey();
try { try {
if(!(node instanceof RootS3Folder)) { if (!(node instanceof RootS3Folder)) {
client().statObject(StatObjectArgs.builder().bucket(cloud.s3Bucket()).object(key).build()); client().statObject(StatObjectArgs.builder().bucket(cloud.s3Bucket()).object(key).build());
return true; return true;
} else { } else {
@ -256,7 +256,7 @@ class S3Impl {
Date lastModified = objectWriteResponse.headers().getDate("Last-Modified"); Date lastModified = objectWriteResponse.headers().getDate("Last-Modified");
if(lastModified == null) { if (lastModified == null) {
StatObjectResponse statObjectResponse = client().statObject(StatObjectArgs // StatObjectResponse statObjectResponse = client().statObject(StatObjectArgs //
.builder() // .builder() //
.bucket(cloud.s3Bucket()) // .bucket(cloud.s3Bucket()) //

View File

@ -14,19 +14,19 @@ internal class Upgrade2To3 @Inject constructor(private val context: Context) : D
db.beginTransaction() db.beginTransaction()
try { try {
Sql.query("CLOUD_ENTITY") Sql.query("CLOUD_ENTITY")
.columns(listOf("ACCESS_TOKEN")) .columns(listOf("ACCESS_TOKEN"))
.where("TYPE", Sql.eq("DROPBOX")) .where("TYPE", Sql.eq("DROPBOX"))
.executeOn(db).use { .executeOn(db).use {
if (it.moveToFirst()) { if (it.moveToFirst()) {
Sql.update("CLOUD_ENTITY") Sql.update("CLOUD_ENTITY")
.set("ACCESS_TOKEN", Sql.toString(encrypt(it.getString(it.getColumnIndex("ACCESS_TOKEN"))))) .set("ACCESS_TOKEN", Sql.toString(encrypt(it.getString(it.getColumnIndex("ACCESS_TOKEN")))))
.where("TYPE", Sql.eq("DROPBOX")); .where("TYPE", Sql.eq("DROPBOX"));
}
} }
}
Sql.update("CLOUD_ENTITY") Sql.update("CLOUD_ENTITY")
.set("ACCESS_TOKEN", Sql.toString(encrypt(onedriveToken()))) .set("ACCESS_TOKEN", Sql.toString(encrypt(onedriveToken())))
.where("TYPE", Sql.eq("ONEDRIVE")); .where("TYPE", Sql.eq("ONEDRIVE"));
db.setTransactionSuccessful() db.setTransactionSuccessful()
} finally { } finally {
@ -36,8 +36,8 @@ internal class Upgrade2To3 @Inject constructor(private val context: Context) : D
private fun encrypt(token: String?): String? { private fun encrypt(token: String?): String? {
return if (token == null) null else CredentialCryptor // return if (token == null) null else CredentialCryptor //
.getInstance(context) // .getInstance(context) //
.encrypt(token) .encrypt(token)
} }
private fun onedriveToken(): String? { private fun onedriveToken(): String? {

View File

@ -25,42 +25,42 @@ internal class Upgrade3To4 @Inject constructor() : DatabaseUpgrade(3, 4) {
private fun addPositionToVaultSchema(db: Database) { private fun addPositionToVaultSchema(db: Database) {
Sql.alterTable("VAULT_ENTITY").renameTo("VAULT_ENTITY_OLD").executeOn(db) Sql.alterTable("VAULT_ENTITY").renameTo("VAULT_ENTITY_OLD").executeOn(db)
Sql.createTable("VAULT_ENTITY") // Sql.createTable("VAULT_ENTITY") //
.id() // .id() //
.optionalInt("FOLDER_CLOUD_ID") // .optionalInt("FOLDER_CLOUD_ID") //
.optionalText("FOLDER_PATH") // .optionalText("FOLDER_PATH") //
.optionalText("FOLDER_NAME") // .optionalText("FOLDER_NAME") //
.requiredText("CLOUD_TYPE") // .requiredText("CLOUD_TYPE") //
.optionalText("PASSWORD") // .optionalText("PASSWORD") //
.optionalInt("POSITION") // .optionalInt("POSITION") //
.foreignKey("FOLDER_CLOUD_ID", "CLOUD_ENTITY", ForeignKeyBehaviour.ON_DELETE_SET_NULL) // .foreignKey("FOLDER_CLOUD_ID", "CLOUD_ENTITY", ForeignKeyBehaviour.ON_DELETE_SET_NULL) //
.executeOn(db) .executeOn(db)
Sql.insertInto("VAULT_ENTITY") // Sql.insertInto("VAULT_ENTITY") //
.select("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "CLOUD_ENTITY.TYPE") // .select("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "CLOUD_ENTITY.TYPE") //
.columns("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "CLOUD_TYPE") // .columns("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "CLOUD_TYPE") //
.from("VAULT_ENTITY_OLD") // .from("VAULT_ENTITY_OLD") //
.join("CLOUD_ENTITY", "VAULT_ENTITY_OLD.FOLDER_CLOUD_ID") // .join("CLOUD_ENTITY", "VAULT_ENTITY_OLD.FOLDER_CLOUD_ID") //
.executeOn(db) .executeOn(db)
Sql.dropIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID").executeOn(db) Sql.dropIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID").executeOn(db)
Sql.createUniqueIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID") // Sql.createUniqueIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID") //
.on("VAULT_ENTITY") // .on("VAULT_ENTITY") //
.asc("FOLDER_PATH") // .asc("FOLDER_PATH") //
.asc("FOLDER_CLOUD_ID") // .asc("FOLDER_CLOUD_ID") //
.executeOn(db) .executeOn(db)
Sql.dropTable("VAULT_ENTITY_OLD").executeOn(db) Sql.dropTable("VAULT_ENTITY_OLD").executeOn(db)
} }
private fun initVaultPositionUsingCurrentSortOrder(db: Database) { private fun initVaultPositionUsingCurrentSortOrder(db: Database) {
CloudEntityDao(DaoConfig(db, VaultEntityDao::class.java)) // CloudEntityDao(DaoConfig(db, VaultEntityDao::class.java)) //
.loadAll() // .loadAll() //
.map { .map {
Sql.update("VAULT_ENTITY") // Sql.update("VAULT_ENTITY") //
.where("_id", Sql.eq(it.id)) // .where("_id", Sql.eq(it.id)) //
.set("POSITION", Sql.toInteger(it.id - 1)) // .set("POSITION", Sql.toInteger(it.id - 1)) //
.executeOn(db) .executeOn(db)
} }
} }
} }

View File

@ -21,19 +21,19 @@ internal class Upgrade4To5 @Inject constructor() : DatabaseUpgrade(4, 5) {
Sql.alterTable("CLOUD_ENTITY").renameTo("CLOUD_ENTITY_OLD").executeOn(db) Sql.alterTable("CLOUD_ENTITY").renameTo("CLOUD_ENTITY_OLD").executeOn(db)
Sql.createTable("CLOUD_ENTITY") // Sql.createTable("CLOUD_ENTITY") //
.id() // .id() //
.requiredText("TYPE") // .requiredText("TYPE") //
.optionalText("ACCESS_TOKEN") // .optionalText("ACCESS_TOKEN") //
.optionalText("URL") // .optionalText("URL") //
.optionalText("USERNAME") // .optionalText("USERNAME") //
.optionalText("WEBDAV_CERTIFICATE") // .optionalText("WEBDAV_CERTIFICATE") //
.executeOn(db); .executeOn(db);
Sql.insertInto("CLOUD_ENTITY") // Sql.insertInto("CLOUD_ENTITY") //
.select("_id", "TYPE", "ACCESS_TOKEN", "WEBDAV_URL", "USERNAME", "WEBDAV_CERTIFICATE") // .select("_id", "TYPE", "ACCESS_TOKEN", "WEBDAV_URL", "USERNAME", "WEBDAV_CERTIFICATE") //
.columns("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") // .columns("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") //
.from("CLOUD_ENTITY_OLD") // .from("CLOUD_ENTITY_OLD") //
.executeOn(db) .executeOn(db)
recreateVaultEntity(db) recreateVaultEntity(db)
@ -43,30 +43,30 @@ internal class Upgrade4To5 @Inject constructor() : DatabaseUpgrade(4, 5) {
private fun recreateVaultEntity(db: Database) { private fun recreateVaultEntity(db: Database) {
Sql.alterTable("VAULT_ENTITY").renameTo("VAULT_ENTITY_OLD").executeOn(db) Sql.alterTable("VAULT_ENTITY").renameTo("VAULT_ENTITY_OLD").executeOn(db)
Sql.createTable("VAULT_ENTITY") // Sql.createTable("VAULT_ENTITY") //
.id() // .id() //
.optionalInt("FOLDER_CLOUD_ID") // .optionalInt("FOLDER_CLOUD_ID") //
.optionalText("FOLDER_PATH") // .optionalText("FOLDER_PATH") //
.optionalText("FOLDER_NAME") // .optionalText("FOLDER_NAME") //
.requiredText("CLOUD_TYPE") // .requiredText("CLOUD_TYPE") //
.optionalText("PASSWORD") // .optionalText("PASSWORD") //
.optionalInt("POSITION") // .optionalInt("POSITION") //
.foreignKey("FOLDER_CLOUD_ID", "CLOUD_ENTITY", Sql.SqlCreateTableBuilder.ForeignKeyBehaviour.ON_DELETE_SET_NULL) // .foreignKey("FOLDER_CLOUD_ID", "CLOUD_ENTITY", Sql.SqlCreateTableBuilder.ForeignKeyBehaviour.ON_DELETE_SET_NULL) //
.executeOn(db) .executeOn(db)
Sql.insertInto("VAULT_ENTITY") // Sql.insertInto("VAULT_ENTITY") //
.select("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_ENTITY.TYPE") // .select("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_ENTITY.TYPE") //
.columns("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_TYPE") // .columns("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_TYPE") //
.from("VAULT_ENTITY_OLD") // .from("VAULT_ENTITY_OLD") //
.join("CLOUD_ENTITY", "VAULT_ENTITY_OLD.FOLDER_CLOUD_ID") // .join("CLOUD_ENTITY", "VAULT_ENTITY_OLD.FOLDER_CLOUD_ID") //
.executeOn(db) .executeOn(db)
Sql.dropIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID").executeOn(db) Sql.dropIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID").executeOn(db)
Sql.createUniqueIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID") // Sql.createUniqueIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID") //
.on("VAULT_ENTITY") // .on("VAULT_ENTITY") //
.asc("FOLDER_PATH") // .asc("FOLDER_PATH") //
.asc("FOLDER_CLOUD_ID") // .asc("FOLDER_CLOUD_ID") //
.executeOn(db) .executeOn(db)
Sql.dropTable("VAULT_ENTITY_OLD").executeOn(db) Sql.dropTable("VAULT_ENTITY_OLD").executeOn(db)
} }

View File

@ -21,22 +21,22 @@ internal class Upgrade5To6 @Inject constructor() : DatabaseUpgrade(5, 6) {
Sql.alterTable("CLOUD_ENTITY").renameTo("CLOUD_ENTITY_OLD").executeOn(db) Sql.alterTable("CLOUD_ENTITY").renameTo("CLOUD_ENTITY_OLD").executeOn(db)
Sql.createTable("CLOUD_ENTITY") // Sql.createTable("CLOUD_ENTITY") //
.id() // .id() //
.requiredText("TYPE") // .requiredText("TYPE") //
.optionalText("ACCESS_TOKEN") // .optionalText("ACCESS_TOKEN") //
.optionalText("URL") // .optionalText("URL") //
.optionalText("USERNAME") // .optionalText("USERNAME") //
.optionalText("WEBDAV_CERTIFICATE") // .optionalText("WEBDAV_CERTIFICATE") //
.optionalText("S3_BUCKET") // .optionalText("S3_BUCKET") //
.optionalText("S3_REGION") // .optionalText("S3_REGION") //
.optionalText("S3_SECRET_KEY") // .optionalText("S3_SECRET_KEY") //
.executeOn(db); .executeOn(db);
Sql.insertInto("CLOUD_ENTITY") // Sql.insertInto("CLOUD_ENTITY") //
.select("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") // .select("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") //
.columns("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") // .columns("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") //
.from("CLOUD_ENTITY_OLD") // .from("CLOUD_ENTITY_OLD") //
.executeOn(db) .executeOn(db)
recreateVaultEntity(db) recreateVaultEntity(db)
@ -46,30 +46,30 @@ internal class Upgrade5To6 @Inject constructor() : DatabaseUpgrade(5, 6) {
private fun recreateVaultEntity(db: Database) { private fun recreateVaultEntity(db: Database) {
Sql.alterTable("VAULT_ENTITY").renameTo("VAULT_ENTITY_OLD").executeOn(db) Sql.alterTable("VAULT_ENTITY").renameTo("VAULT_ENTITY_OLD").executeOn(db)
Sql.createTable("VAULT_ENTITY") // Sql.createTable("VAULT_ENTITY") //
.id() // .id() //
.optionalInt("FOLDER_CLOUD_ID") // .optionalInt("FOLDER_CLOUD_ID") //
.optionalText("FOLDER_PATH") // .optionalText("FOLDER_PATH") //
.optionalText("FOLDER_NAME") // .optionalText("FOLDER_NAME") //
.requiredText("CLOUD_TYPE") // .requiredText("CLOUD_TYPE") //
.optionalText("PASSWORD") // .optionalText("PASSWORD") //
.optionalInt("POSITION") // .optionalInt("POSITION") //
.foreignKey("FOLDER_CLOUD_ID", "CLOUD_ENTITY", Sql.SqlCreateTableBuilder.ForeignKeyBehaviour.ON_DELETE_SET_NULL) // .foreignKey("FOLDER_CLOUD_ID", "CLOUD_ENTITY", Sql.SqlCreateTableBuilder.ForeignKeyBehaviour.ON_DELETE_SET_NULL) //
.executeOn(db) .executeOn(db)
Sql.insertInto("VAULT_ENTITY") // Sql.insertInto("VAULT_ENTITY") //
.select("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_ENTITY.TYPE") // .select("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_ENTITY.TYPE") //
.columns("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_TYPE") // .columns("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_TYPE") //
.from("VAULT_ENTITY_OLD") // .from("VAULT_ENTITY_OLD") //
.join("CLOUD_ENTITY", "VAULT_ENTITY_OLD.FOLDER_CLOUD_ID") // .join("CLOUD_ENTITY", "VAULT_ENTITY_OLD.FOLDER_CLOUD_ID") //
.executeOn(db) .executeOn(db)
Sql.dropIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID").executeOn(db) Sql.dropIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID").executeOn(db)
Sql.createUniqueIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID") // Sql.createUniqueIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID") //
.on("VAULT_ENTITY") // .on("VAULT_ENTITY") //
.asc("FOLDER_PATH") // .asc("FOLDER_PATH") //
.asc("FOLDER_CLOUD_ID") // .asc("FOLDER_CLOUD_ID") //
.executeOn(db) .executeOn(db)
Sql.dropTable("VAULT_ENTITY_OLD").executeOn(db) Sql.dropTable("VAULT_ENTITY_OLD").executeOn(db)
} }

View File

@ -21,20 +21,20 @@ internal class Upgrade6To7 @Inject constructor() : DatabaseUpgrade(6, 7) {
Sql.alterTable("UPDATE_CHECK_ENTITY").renameTo("UPDATE_CHECK_ENTITY_OLD").executeOn(db) Sql.alterTable("UPDATE_CHECK_ENTITY").renameTo("UPDATE_CHECK_ENTITY_OLD").executeOn(db)
Sql.createTable("UPDATE_CHECK_ENTITY") // Sql.createTable("UPDATE_CHECK_ENTITY") //
.id() // .id() //
.optionalText("LICENSE_TOKEN") // .optionalText("LICENSE_TOKEN") //
.optionalText("RELEASE_NOTE") // .optionalText("RELEASE_NOTE") //
.optionalText("VERSION") // .optionalText("VERSION") //
.optionalText("URL_TO_APK") // .optionalText("URL_TO_APK") //
.optionalText("APK_SHA256") // .optionalText("APK_SHA256") //
.optionalText("URL_TO_RELEASE_NOTE") // .optionalText("URL_TO_RELEASE_NOTE") //
.executeOn(db) .executeOn(db)
Sql.insertInto("UPDATE_CHECK_ENTITY") // Sql.insertInto("UPDATE_CHECK_ENTITY") //
.select("_id", "LICENSE_TOKEN", "RELEASE_NOTE", "VERSION", "URL_TO_APK", "URL_TO_RELEASE_NOTE") // .select("_id", "LICENSE_TOKEN", "RELEASE_NOTE", "VERSION", "URL_TO_APK", "URL_TO_RELEASE_NOTE") //
.columns("_id", "LICENSE_TOKEN", "RELEASE_NOTE", "VERSION", "URL_TO_APK", "URL_TO_RELEASE_NOTE") // .columns("_id", "LICENSE_TOKEN", "RELEASE_NOTE", "VERSION", "URL_TO_APK", "URL_TO_RELEASE_NOTE") //
.from("UPDATE_CHECK_ENTITY_OLD") // .from("UPDATE_CHECK_ENTITY_OLD") //
.executeOn(db) .executeOn(db)
Sql.dropTable("UPDATE_CHECK_ENTITY_OLD").executeOn(db) Sql.dropTable("UPDATE_CHECK_ENTITY_OLD").executeOn(db)
} }

View File

@ -26,8 +26,7 @@ public class UpdateCheckEntity extends DatabaseEntity {
} }
@Generated(hash = 67239496) @Generated(hash = 67239496)
public UpdateCheckEntity(Long id, String licenseToken, String releaseNote, String version, String urlToApk, String apkSha256, public UpdateCheckEntity(Long id, String licenseToken, String releaseNote, String version, String urlToApk, String apkSha256, String urlToReleaseNote) {
String urlToReleaseNote) {
this.id = id; this.id = id;
this.licenseToken = licenseToken; this.licenseToken = licenseToken;
this.releaseNote = releaseNote; this.releaseNote = releaseNote;

View File

@ -182,7 +182,9 @@ public class VaultEntity extends DatabaseEntity {
this.position = position; this.position = position;
} }
/** called by internal mechanisms, do not call yourself. */ /**
* called by internal mechanisms, do not call yourself.
*/
@Generated(hash = 674742652) @Generated(hash = 674742652)
public void __setDaoSession(DaoSession daoSession) { public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession; this.daoSession = daoSession;

View File

@ -120,7 +120,7 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository {
String apkSha256 = calculateSha256(file); String apkSha256 = calculateSha256(file);
if(!apkSha256.equals(entity.getApkSha256())) { if (!apkSha256.equals(entity.getApkSha256())) {
file.delete(); file.delete();
throw new HashMismatchUpdateCheckException(String.format( // throw new HashMismatchUpdateCheckException(String.format( //
"Sha of calculated hash (%s) doesn't match the specified one (%s)", // "Sha of calculated hash (%s) doesn't match the specified one (%s)", //
@ -138,9 +138,9 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository {
private String calculateSha256(File file) throws GeneralUpdateErrorException { private String calculateSha256(File file) throws GeneralUpdateErrorException {
try { try {
MessageDigest digest = MessageDigest.getInstance("SHA-256"); MessageDigest digest = MessageDigest.getInstance("SHA-256");
try(DigestInputStream digestInputStream = new DigestInputStream(context.getContentResolver().openInputStream(Uri.fromFile(file)), digest)) { try (DigestInputStream digestInputStream = new DigestInputStream(context.getContentResolver().openInputStream(Uri.fromFile(file)), digest)) {
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
while(digestInputStream.read(buffer) > -1) { while (digestInputStream.read(buffer) > -1) {
} }
} }
return new String(Hex.encodeHex(digest.digest())); return new String(Hex.encodeHex(digest.digest()));

View File

@ -3,4 +3,5 @@ package org.cryptomator.domain.exception.vaultconfig;
import org.cryptomator.domain.exception.BackendException; import org.cryptomator.domain.exception.BackendException;
public class VaultKeyInvalidException extends BackendException { public class VaultKeyInvalidException extends BackendException {
} }

View File

@ -20,7 +20,8 @@ class ChangePassword {
private final Vault vault; private final Vault vault;
private final Optional<UnverifiedVaultConfig> unverifiedVaultConfig; private final Optional<UnverifiedVaultConfig> unverifiedVaultConfig;
private final String oldPassword; private final String oldPassword;
private final String newPassword;; private final String newPassword;
;
public ChangePassword(CloudRepository cloudRepository, // public ChangePassword(CloudRepository cloudRepository, //
@Parameter Vault vault, // @Parameter Vault vault, //

View File

@ -14,9 +14,8 @@ class UnlockVaultUsingMasterkey {
private final CloudRepository cloudRepository; private final CloudRepository cloudRepository;
private final VaultOrUnlockToken vaultOrUnlockToken; private final VaultOrUnlockToken vaultOrUnlockToken;
private Optional<UnverifiedVaultConfig> unverifiedVaultConfig;
private final String password; private final String password;
private Optional<UnverifiedVaultConfig> unverifiedVaultConfig;
private volatile boolean cancelled; private volatile boolean cancelled;
private final Flag cancelledFlag = new Flag() { private final Flag cancelledFlag = new Flag() {
@Override @Override

View File

@ -61,21 +61,22 @@ import timber.log.Timber
@PerView @PerView
class AuthenticateCloudPresenter @Inject constructor( // class AuthenticateCloudPresenter @Inject constructor( //
exceptionHandlers: ExceptionHandlers, // exceptionHandlers: ExceptionHandlers, //
private val cloudModelMapper: CloudModelMapper, // private val cloudModelMapper: CloudModelMapper, //
private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, // private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, //
private val getCloudsUseCase: GetCloudsUseCase, // private val getCloudsUseCase: GetCloudsUseCase, //
private val getUsernameUseCase: GetUsernameUseCase, // private val getUsernameUseCase: GetUsernameUseCase, //
private val addExistingVaultWorkflow: AddExistingVaultWorkflow, // private val addExistingVaultWorkflow: AddExistingVaultWorkflow, //
private val createNewVaultWorkflow: CreateNewVaultWorkflow) : Presenter<AuthenticateCloudView>(exceptionHandlers) { private val createNewVaultWorkflow: CreateNewVaultWorkflow
) : Presenter<AuthenticateCloudView>(exceptionHandlers) {
private val strategies = arrayOf( // private val strategies = arrayOf( //
DropboxAuthStrategy(), // DropboxAuthStrategy(), //
OnedriveAuthStrategy(), // OnedriveAuthStrategy(), //
PCloudAuthStrategy(), // PCloudAuthStrategy(), //
WebDAVAuthStrategy(), // WebDAVAuthStrategy(), //
S3AuthStrategy(), // S3AuthStrategy(), //
LocalStorageAuthStrategy() // LocalStorageAuthStrategy() //
) )
override fun workflows(): Iterable<Workflow<*>> { override fun workflows(): Iterable<Workflow<*>> {
@ -128,17 +129,17 @@ class AuthenticateCloudPresenter @Inject constructor( //
private fun succeedAuthenticationWith(cloud: Cloud) { private fun succeedAuthenticationWith(cloud: Cloud) {
addOrChangeCloudConnectionUseCase // addOrChangeCloudConnectionUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<Void?>() { .run(object : DefaultResultHandler<Void?>() {
override fun onSuccess(void: Void?) { override fun onSuccess(void: Void?) {
finishWithResult(cloudModelMapper.toModel(cloud)) finishWithResult(cloudModelMapper.toModel(cloud))
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
super.onError(e) super.onError(e)
finish() finish()
} }
}) })
} }
private fun failAuthentication(cloudName: Int) { private fun failAuthentication(cloudName: Int) {
@ -180,9 +181,10 @@ class AuthenticateCloudPresenter @Inject constructor( //
failAuthentication(cloudModel.name()) failAuthentication(cloudModel.name())
} else { } else {
getUsernameAndSuceedAuthentication( // getUsernameAndSuceedAuthentication( //
DropboxCloud.aCopyOf(cloudModel.toCloud() as DropboxCloud) // DropboxCloud.aCopyOf(cloudModel.toCloud() as DropboxCloud) //
.withAccessToken(encrypt(authToken)) // .withAccessToken(encrypt(authToken)) //
.build()) .build()
)
} }
} }
} }
@ -200,10 +202,12 @@ class AuthenticateCloudPresenter @Inject constructor( //
fun onGoogleDriveAuthenticated(result: ActivityResult, cloud: CloudModel) { fun onGoogleDriveAuthenticated(result: ActivityResult, cloud: CloudModel) {
if (result.isResultOk) { if (result.isResultOk) {
val accountName = result.intent()?.extras?.getString(AccountManager.KEY_ACCOUNT_NAME) val accountName = result.intent()?.extras?.getString(AccountManager.KEY_ACCOUNT_NAME)
succeedAuthenticationWith(GoogleDriveCloud.aCopyOf(cloud.toCloud() as GoogleDriveCloud) // succeedAuthenticationWith(
GoogleDriveCloud.aCopyOf(cloud.toCloud() as GoogleDriveCloud) //
.withUsername(accountName) // .withUsername(accountName) //
.withAccessToken(accountName) // .withAccessToken(accountName) //
.build()) .build()
)
} else { } else {
failAuthentication(cloud.name()) failAuthentication(cloud.name())
} }
@ -245,9 +249,10 @@ class AuthenticateCloudPresenter @Inject constructor( //
private fun handleAuthenticationResult(cloud: CloudModel, accessToken: String) { private fun handleAuthenticationResult(cloud: CloudModel, accessToken: String) {
getUsernameAndSuceedAuthentication( // getUsernameAndSuceedAuthentication( //
OnedriveCloud.aCopyOf(cloud.toCloud() as OnedriveCloud) // OnedriveCloud.aCopyOf(cloud.toCloud() as OnedriveCloud) //
.withAccessToken(accessToken) // .withAccessToken(accessToken) //
.build()) .build()
)
} }
} }
@ -265,9 +270,10 @@ class AuthenticateCloudPresenter @Inject constructor( //
if (!authenticationStarted) { if (!authenticationStarted) {
startAuthentication() startAuthentication()
Toast.makeText( Toast.makeText(
context(), context(),
String.format(getString(R.string.error_authentication_failed_re_authenticate), intent.cloud().username()), String.format(getString(R.string.error_authentication_failed_re_authenticate), intent.cloud().username()),
Toast.LENGTH_LONG).show() Toast.LENGTH_LONG
).show()
} }
} }
else -> { else -> {
@ -280,15 +286,18 @@ class AuthenticateCloudPresenter @Inject constructor( //
private fun startAuthentication() { private fun startAuthentication() {
authenticationStarted = true authenticationStarted = true
val authIntent: Intent = AuthorizationActivity.createIntent( val authIntent: Intent = AuthorizationActivity.createIntent(
context(), context(),
AuthorizationRequest.create() AuthorizationRequest.create()
.setType(AuthorizationRequest.Type.TOKEN) .setType(AuthorizationRequest.Type.TOKEN)
.setClientId(BuildConfig.PCLOUD_CLIENT_ID) .setClientId(BuildConfig.PCLOUD_CLIENT_ID)
.setForceAccessApproval(true) .setForceAccessApproval(true)
.addPermission("manageshares") .addPermission("manageshares")
.build()) .build()
requestActivityResult(ActivityResultCallbacks.pCloudReAuthenticationFinished(), // )
authIntent) requestActivityResult(
ActivityResultCallbacks.pCloudReAuthenticationFinished(), //
authIntent
)
} }
} }
@ -300,19 +309,19 @@ class AuthenticateCloudPresenter @Inject constructor( //
when (result) { when (result) {
AuthorizationResult.ACCESS_GRANTED -> { AuthorizationResult.ACCESS_GRANTED -> {
val accessToken: String = CredentialCryptor // val accessToken: String = CredentialCryptor //
.getInstance(context()) // .getInstance(context()) //
.encrypt(authData.token) .encrypt(authData.token)
val pCloudSkeleton: PCloud = PCloud.aPCloud() // val pCloudSkeleton: PCloud = PCloud.aPCloud() //
.withAccessToken(accessToken) .withAccessToken(accessToken)
.withUrl(authData.apiHost) .withUrl(authData.apiHost)
.build(); .build();
getUsernameUseCase // getUsernameUseCase //
.withCloud(pCloudSkeleton) // .withCloud(pCloudSkeleton) //
.run(object : DefaultResultHandler<String>() { .run(object : DefaultResultHandler<String>() {
override fun onSuccess(username: String?) { override fun onSuccess(username: String?) {
prepareForSavingPCloud(PCloud.aCopyOf(pCloudSkeleton).withUsername(username).build()) prepareForSavingPCloud(PCloud.aCopyOf(pCloudSkeleton).withUsername(username).build())
} }
}) })
} }
AuthorizationResult.ACCESS_DENIED -> { AuthorizationResult.ACCESS_DENIED -> {
Timber.tag("CloudConnListPresenter").e("Account access denied") Timber.tag("CloudConnListPresenter").e("Account access denied")
@ -331,20 +340,22 @@ class AuthenticateCloudPresenter @Inject constructor( //
fun prepareForSavingPCloud(cloud: PCloud) { fun prepareForSavingPCloud(cloud: PCloud) {
getCloudsUseCase // getCloudsUseCase //
.withCloudType(cloud.type()) // .withCloudType(cloud.type()) //
.run(object : DefaultResultHandler<List<Cloud>>() { .run(object : DefaultResultHandler<List<Cloud>>() {
override fun onSuccess(clouds: List<Cloud>) { override fun onSuccess(clouds: List<Cloud>) {
clouds.firstOrNull { clouds.firstOrNull {
(it as PCloud).username() == cloud.username() (it as PCloud).username() == cloud.username()
}?.let { }?.let {
it as PCloud it as PCloud
succeedAuthenticationWith(PCloud.aCopyOf(it) // succeedAuthenticationWith(
.withUrl(cloud.url()) PCloud.aCopyOf(it) //
.withAccessToken(cloud.accessToken()) .withUrl(cloud.url())
.build()) .withAccessToken(cloud.accessToken())
} ?: succeedAuthenticationWith(cloud) .build()
} )
}) } ?: succeedAuthenticationWith(cloud)
}
})
} }
private inner class WebDAVAuthStrategy : AuthStrategy { private inner class WebDAVAuthStrategy : AuthStrategy {
@ -392,11 +403,13 @@ class AuthenticateCloudPresenter @Inject constructor( //
fun onAcceptWebDavCertificateClicked(cloud: WebDavCloud?, certificate: X509Certificate?) { fun onAcceptWebDavCertificateClicked(cloud: WebDavCloud?, certificate: X509Certificate?) {
try { try {
val webDavCloudWithAcceptedCert = WebDavCloud.aCopyOf(cloud) // val webDavCloudWithAcceptedCert = WebDavCloud.aCopyOf(cloud) //
.withCertificate(X509CertificateHelper.convertToPem(certificate)) // .withCertificate(X509CertificateHelper.convertToPem(certificate)) //
.build() .build()
finishWithResultAndExtra(cloudModelMapper.toModel(webDavCloudWithAcceptedCert), // finishWithResultAndExtra(
WEBDAV_ACCEPTED_UNTRUSTED_CERTIFICATE, // cloudModelMapper.toModel(webDavCloudWithAcceptedCert), //
true) WEBDAV_ACCEPTED_UNTRUSTED_CERTIFICATE, //
true
)
} catch (e: CertificateEncodingException) { } catch (e: CertificateEncodingException) {
Timber.tag("AuthicateCloudPrester").e(e) Timber.tag("AuthicateCloudPrester").e(e)
throw FatalBackendException(e) throw FatalBackendException(e)
@ -421,9 +434,10 @@ class AuthenticateCloudPresenter @Inject constructor( //
if (!authenticationStarted) { if (!authenticationStarted) {
startAuthentication(intent.cloud()) startAuthentication(intent.cloud())
Toast.makeText( Toast.makeText(
context(), context(),
String.format(getString(R.string.error_authentication_failed), intent.cloud().username()), String.format(getString(R.string.error_authentication_failed), intent.cloud().username()),
Toast.LENGTH_LONG).show() Toast.LENGTH_LONG
).show()
} }
} }
else -> { else -> {
@ -454,10 +468,12 @@ class AuthenticateCloudPresenter @Inject constructor( //
private fun startAuthentication(cloud: CloudModel) { private fun startAuthentication(cloud: CloudModel) {
authenticationStarted = true authenticationStarted = true
requestPermissions(PermissionsResultCallbacks.onLocalStorageAuthenticated(cloud), // requestPermissions(
R.string.permission_snackbar_auth_local_vault, // PermissionsResultCallbacks.onLocalStorageAuthenticated(cloud), //
Manifest.permission.READ_EXTERNAL_STORAGE, // R.string.permission_snackbar_auth_local_vault, //
Manifest.permission.WRITE_EXTERNAL_STORAGE) Manifest.permission.READ_EXTERNAL_STORAGE, //
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
} }
} }
@ -472,8 +488,8 @@ class AuthenticateCloudPresenter @Inject constructor( //
private fun encrypt(password: String): String { private fun encrypt(password: String): String {
return CredentialCryptor // return CredentialCryptor //
.getInstance(context()) // .getInstance(context()) //
.encrypt(password) .encrypt(password)
} }
private inner class FailingAuthStrategy : AuthStrategy { private inner class FailingAuthStrategy : AuthStrategy {

View File

@ -97,9 +97,10 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".ui.activity.UnlockVaultActivity" <activity
android:theme="@style/TransparentAlertDialogCustom" android:name=".ui.activity.UnlockVaultActivity"
android:label=""/> android:label=""
android:theme="@style/TransparentAlertDialogCustom" />
<activity android:name=".ui.activity.EmptyDirIdFileInfoActivity" /> <activity android:name=".ui.activity.EmptyDirIdFileInfoActivity" />
<!-- Settings --> <!-- Settings -->

View File

@ -51,10 +51,12 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
} }
else -> "Google Play Edition" else -> "Google Play Edition"
} }
Timber.tag("App").i("Cryptomator v%s (%d) \"%s\" started on android %s / API%d using a %s", // Timber.tag("App").i(
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, flavor, // "Cryptomator v%s (%d) \"%s\" started on android %s / API%d using a %s", //
Build.VERSION.RELEASE, Build.VERSION.SDK_INT, // BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, flavor, //
Build.MODEL) Build.VERSION.RELEASE, Build.VERSION.SDK_INT, //
Build.MODEL
)
Timber.tag("App").d("appId %s", BuildConfig.APPLICATION_ID) Timber.tag("App").d("appId %s", BuildConfig.APPLICATION_ID)
launchServices() launchServices()
@ -105,10 +107,11 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
Timber.tag("App").i("Auto upload service connected") Timber.tag("App").i("Auto upload service connected")
autoUploadServiceBinder = service as AutoUploadService.Binder autoUploadServiceBinder = service as AutoUploadService.Binder
autoUploadServiceBinder.init( // autoUploadServiceBinder.init( //
applicationComponent.cloudContentRepository(), // applicationComponent.cloudContentRepository(), //
applicationComponent.fileUtil(), // applicationComponent.fileUtil(), //
applicationComponent.contentResolverUtil(), // applicationComponent.contentResolverUtil(), //
Companion.applicationContext) Companion.applicationContext
)
} }
override fun onServiceDisconnected(name: ComponentName) { override fun onServiceDisconnected(name: ComponentName) {
@ -124,11 +127,11 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
private fun initializeInjector() { private fun initializeInjector() {
applicationComponent = DaggerApplicationComponent.builder() // applicationComponent = DaggerApplicationComponent.builder() //
.applicationModule(ApplicationModule(this)) // .applicationModule(ApplicationModule(this)) //
.threadModule(ThreadModule()) // .threadModule(ThreadModule()) //
.repositoryModule(RepositoryModule()) // .repositoryModule(RepositoryModule()) //
.cryptorsModule(CryptorsModule(appCryptors)) // .cryptorsModule(CryptorsModule(appCryptors)) //
.build() .build()
} }
private fun cleanupCache() { private fun cleanupCache() {

View File

@ -15,7 +15,7 @@ class MissingCryptorExceptionHandler : ExceptionHandler() {
public override fun doHandle(view: View, e: Throwable) { public override fun doHandle(view: View, e: Throwable) {
view.showMessage(R.string.error_vault_has_been_locked) view.showMessage(R.string.error_vault_has_been_locked)
Intents.vaultListIntent() // Intents.vaultListIntent() //
.preventGoingBackInHistory() // .preventGoingBackInHistory() //
.startActivity(view) .startActivity(view)
} }
} }

View File

@ -12,10 +12,7 @@ public interface UnlockVaultIntent {
VaultAction vaultAction(); VaultAction vaultAction();
enum VaultAction { enum VaultAction {
UNLOCK, UNLOCK, UNLOCK_FOR_BIOMETRIC_AUTH, ENCRYPT_PASSWORD, CHANGE_PASSWORD
UNLOCK_FOR_BIOMETRIC_AUTH,
ENCRYPT_PASSWORD,
CHANGE_PASSWORD
} }
} }

View File

@ -12,7 +12,7 @@ object Logfiles {
* Maximum size of all logfiles * Maximum size of all logfiles
*/ */
private const val MAX_LOGS_SIZE = (1 shl 20 // 1 MiB private const val MAX_LOGS_SIZE = (1 shl 20 // 1 MiB
.toLong().toInt()).toLong() .toLong().toInt()).toLong()
/** /**
* When this size is reached a logfile is rotated * When this size is reached a logfile is rotated

View File

@ -8,14 +8,14 @@ import timber.log.Timber
class ReleaseLogger(context: Context) : Timber.Tree() { class ReleaseLogger(context: Context) : Timber.Tree() {
private val priorityNames = charArrayOf( // private val priorityNames = charArrayOf( //
'?', // '?', //
'?', // '?', //
'V', // 'V', //
'D', // 'D', //
'I', // 'I', //
'W', // 'W', //
'E', // 'E', //
'A' // 'A' //
) )
private val log: LogRotator private val log: LogRotator
@ -26,10 +26,10 @@ class ReleaseLogger(context: Context) : Timber.Tree() {
override fun log(priority: Int, tag: String?, message: String, throwable: Throwable?) { override fun log(priority: Int, tag: String?, message: String, throwable: Throwable?) {
val line = StringBuilder() val line = StringBuilder()
line // line //
.append(priorityNames[validPriority(priority)]).append('\t') // .append(priorityNames[validPriority(priority)]).append('\t') //
.append(FormattedTime.now()).append('\t') // .append(FormattedTime.now()).append('\t') //
.append(tag ?: "App").append('\t') // .append(tag ?: "App").append('\t') //
.append(message) .append(message)
if (throwable != null) { if (throwable != null) {
line.append("\nErrorCode: ").append(GeneratedErrorCode.of(throwable)) line.append("\nErrorCode: ").append(GeneratedErrorCode.of(throwable))
} }

View File

@ -3,7 +3,7 @@ package org.cryptomator.presentation.model
import java.io.Serializable import java.io.Serializable
data class AutoUploadFilesStore( data class AutoUploadFilesStore(
val uris: Set<String> val uris: Set<String>
) : Serializable { ) : Serializable {
companion object { companion object {

View File

@ -6,38 +6,52 @@ import org.cryptomator.presentation.R
enum class CloudTypeModel(builder: Builder) { enum class CloudTypeModel(builder: Builder) {
CRYPTO(Builder("CRYPTO", R.string.cloud_names_crypto)), // CRYPTO(Builder("CRYPTO", R.string.cloud_names_crypto)), //
DROPBOX(Builder("DROPBOX", R.string.cloud_names_dropbox) // DROPBOX(
Builder("DROPBOX", R.string.cloud_names_dropbox) //
.withCloudImageResource(R.drawable.dropbox) // .withCloudImageResource(R.drawable.dropbox) //
.withVaultImageResource(R.drawable.dropbox_vault) // .withVaultImageResource(R.drawable.dropbox_vault) //
.withVaultSelectedImageResource(R.drawable.dropbox_vault_selected)), // .withVaultSelectedImageResource(R.drawable.dropbox_vault_selected)
GOOGLE_DRIVE(Builder("GOOGLE_DRIVE", R.string.cloud_names_google_drive) // ), //
GOOGLE_DRIVE(
Builder("GOOGLE_DRIVE", R.string.cloud_names_google_drive) //
.withCloudImageResource(R.drawable.google_drive) // .withCloudImageResource(R.drawable.google_drive) //
.withVaultImageResource(R.drawable.google_drive_vault) // .withVaultImageResource(R.drawable.google_drive_vault) //
.withVaultSelectedImageResource(R.drawable.google_drive_vault_selected)), // .withVaultSelectedImageResource(R.drawable.google_drive_vault_selected)
ONEDRIVE(Builder("ONEDRIVE", R.string.cloud_names_onedrive) // ), //
ONEDRIVE(
Builder("ONEDRIVE", R.string.cloud_names_onedrive) //
.withCloudImageResource(R.drawable.onedrive) // .withCloudImageResource(R.drawable.onedrive) //
.withVaultImageResource(R.drawable.onedrive_vault) // .withVaultImageResource(R.drawable.onedrive_vault) //
.withVaultSelectedImageResource(R.drawable.onedrive_vault_selected)), // .withVaultSelectedImageResource(R.drawable.onedrive_vault_selected)
PCLOUD(Builder("PCLOUD", R.string.cloud_names_pcloud) // ), //
PCLOUD(
Builder("PCLOUD", R.string.cloud_names_pcloud) //
.withCloudImageResource(R.drawable.pcloud) // .withCloudImageResource(R.drawable.pcloud) //
.withVaultImageResource(R.drawable.pcloud_vault) // .withVaultImageResource(R.drawable.pcloud_vault) //
.withVaultSelectedImageResource(R.drawable.pcloud_vault_selected) // .withVaultSelectedImageResource(R.drawable.pcloud_vault_selected) //
.withMultiInstances()), // .withMultiInstances()
WEBDAV(Builder("WEBDAV", R.string.cloud_names_webdav) // ), //
WEBDAV(
Builder("WEBDAV", R.string.cloud_names_webdav) //
.withCloudImageResource(R.drawable.webdav) // .withCloudImageResource(R.drawable.webdav) //
.withVaultImageResource(R.drawable.webdav_vault) // .withVaultImageResource(R.drawable.webdav_vault) //
.withVaultSelectedImageResource(R.drawable.webdav_vault_selected) // .withVaultSelectedImageResource(R.drawable.webdav_vault_selected) //
.withMultiInstances()), // .withMultiInstances()
S3(Builder("S3", R.string.cloud_names_s3) // ), //
S3(
Builder("S3", R.string.cloud_names_s3) //
.withCloudImageResource(R.drawable.s3) // .withCloudImageResource(R.drawable.s3) //
.withVaultImageResource(R.drawable.s3_vault) // .withVaultImageResource(R.drawable.s3_vault) //
.withVaultSelectedImageResource(R.drawable.s3_vault_selected) // .withVaultSelectedImageResource(R.drawable.s3_vault_selected) //
.withMultiInstances()), // .withMultiInstances()
LOCAL(Builder("LOCAL", R.string.cloud_names_local_storage) // ), //
LOCAL(
Builder("LOCAL", R.string.cloud_names_local_storage) //
.withCloudImageResource(R.drawable.local_fs) // .withCloudImageResource(R.drawable.local_fs) //
.withVaultImageResource(R.drawable.local_fs_vault) // .withVaultImageResource(R.drawable.local_fs_vault) //
.withVaultSelectedImageResource(R.drawable.local_fs_vault_selected) // .withVaultSelectedImageResource(R.drawable.local_fs_vault_selected) //
.withMultiInstances()); .withMultiInstances()
);
val cloudName: String = builder.cloudName val cloudName: String = builder.cloudName
val displayNameResource: Int = builder.displayNameResource val displayNameResource: Int = builder.displayNameResource

View File

@ -8,6 +8,6 @@ import kotlinx.android.parcel.Parcelize
@Parcelize @Parcelize
@SuppressLint("ParcelCreator") @SuppressLint("ParcelCreator")
data class ImagePreviewFile( data class ImagePreviewFile(
val cloudFileModel: CloudFileModel, val cloudFileModel: CloudFileModel,
var uri: Uri? var uri: Uri?
) : Parcelable ) : Parcelable

View File

@ -3,6 +3,6 @@ package org.cryptomator.presentation.model
import java.io.Serializable import java.io.Serializable
data class ImagePreviewFilesStore( data class ImagePreviewFilesStore(
val cloudFileModels: ArrayList<CloudFileModel>, val cloudFileModels: ArrayList<CloudFileModel>,
var index: Int var index: Int
) : Serializable ) : Serializable

View File

@ -31,21 +31,29 @@ class ProgressStateModelMapper @Inject internal constructor(private val fileUtil
fun toModel(state: UploadState): ProgressStateModel { fun toModel(state: UploadState): ProgressStateModel {
return if (state.isUpload) { return if (state.isUpload) {
FileProgressStateModel(state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.UPLOAD, ProgressStateModel.image(R.drawable.ic_file_upload), FileProgressStateModel(
ProgressStateModel.text(R.string.dialog_progress_upload_file)) state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.UPLOAD, ProgressStateModel.image(R.drawable.ic_file_upload),
ProgressStateModel.text(R.string.dialog_progress_upload_file)
)
} else { } else {
FileProgressStateModel(state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.ENCRYPTION, ProgressStateModel.image(R.drawable.ic_lock_closed), FileProgressStateModel(
ProgressStateModel.text(R.string.dialog_progress_encryption)) state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.ENCRYPTION, ProgressStateModel.image(R.drawable.ic_lock_closed),
ProgressStateModel.text(R.string.dialog_progress_encryption)
)
} }
} }
fun toModel(state: DownloadState): ProgressStateModel { fun toModel(state: DownloadState): ProgressStateModel {
return if (state.isDownload) { return if (state.isDownload) {
FileProgressStateModel(state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.DOWNLOAD, ProgressStateModel.image(R.drawable.ic_file_download), FileProgressStateModel(
ProgressStateModel.text(R.string.dialog_progress_download_file)) state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.DOWNLOAD, ProgressStateModel.image(R.drawable.ic_file_download),
ProgressStateModel.text(R.string.dialog_progress_download_file)
)
} else { } else {
FileProgressStateModel(state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.DECRYPTION, ProgressStateModel.image(R.drawable.ic_lock_open), FileProgressStateModel(
ProgressStateModel.text(R.string.dialog_progress_decryption)) state.file(), FileIcon.fileIconFor(state.file().name, fileUtil), FileProgressStateModel.DECRYPTION, ProgressStateModel.image(R.drawable.ic_lock_open),
ProgressStateModel.text(R.string.dialog_progress_decryption)
)
} }
} }
} }

View File

@ -26,13 +26,14 @@ import javax.inject.Inject
@PerView @PerView
class AutoUploadChooseVaultPresenter @Inject constructor( // class AutoUploadChooseVaultPresenter @Inject constructor( //
private val getVaultListUseCase: GetVaultListUseCase, // private val getVaultListUseCase: GetVaultListUseCase, //
private val getRootFolderUseCase: GetRootFolderUseCase, // private val getRootFolderUseCase: GetRootFolderUseCase, //
private val getDecryptedCloudForVaultUseCase: GetDecryptedCloudForVaultUseCase, // private val getDecryptedCloudForVaultUseCase: GetDecryptedCloudForVaultUseCase, //
private val cloudFolderModelMapper: CloudFolderModelMapper, // private val cloudFolderModelMapper: CloudFolderModelMapper, //
private val sharedPreferencesHandler: SharedPreferencesHandler, // private val sharedPreferencesHandler: SharedPreferencesHandler, //
private val authenticationExceptionHandler: AuthenticationExceptionHandler, // private val authenticationExceptionHandler: AuthenticationExceptionHandler, //
exceptionMappings: ExceptionHandlers) : Presenter<AutoUploadChooseVaultView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<AutoUploadChooseVaultView>(exceptionMappings) {
private var selectedVault: VaultModel? = null private var selectedVault: VaultModel? = null
private var location: CloudFolderModel? = null private var location: CloudFolderModel? = null
@ -79,8 +80,9 @@ class AutoUploadChooseVaultPresenter @Inject constructor( //
} else { } else {
if (!isPaused) { if (!isPaused) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.vaultUnlockedAutoUpload(), // ActivityResultCallbacks.vaultUnlockedAutoUpload(), //
Intents.unlockVaultIntent().withVaultModel(VaultModel(authenticatedVault)).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK)) Intents.unlockVaultIntent().withVaultModel(VaultModel(authenticatedVault)).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK)
)
} }
} }
} }
@ -95,24 +97,25 @@ class AutoUploadChooseVaultPresenter @Inject constructor( //
} }
private fun decryptedCloudFor(vault: Vault) { private fun decryptedCloudFor(vault: Vault) {
getDecryptedCloudForVaultUseCase // getDecryptedCloudForVaultUseCase //
.withVault(vault) // .withVault(vault) //
.run(object : DefaultResultHandler<Cloud>() { .run(object : DefaultResultHandler<Cloud>() {
override fun onSuccess(cloud: Cloud) { override fun onSuccess(cloud: Cloud) {
rootFolderFor(cloud) rootFolderFor(cloud)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (!authenticationExceptionHandler.handleAuthenticationException( // if (!authenticationExceptionHandler.handleAuthenticationException( //
this@AutoUploadChooseVaultPresenter, // this@AutoUploadChooseVaultPresenter, //
e, // e, //
ActivityResultCallbacks.decryptedCloudForAfterAuthInAutoPhotoUpload(vault))) { ActivityResultCallbacks.decryptedCloudForAfterAuthInAutoPhotoUpload(vault)
super.onError(e) )
} ) {
super.onError(e)
} }
}) }
})
} }
@Callback @Callback
@ -123,33 +126,35 @@ class AutoUploadChooseVaultPresenter @Inject constructor( //
private fun rootFolderFor(cloud: Cloud) { private fun rootFolderFor(cloud: Cloud) {
getRootFolderUseCase // getRootFolderUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<CloudFolder>() { .run(object : DefaultResultHandler<CloudFolder>() {
override fun onSuccess(folder: CloudFolder) { override fun onSuccess(folder: CloudFolder) {
when (authenticationState) { when (authenticationState) {
AuthenticationState.CHOOSE_LOCATION -> { AuthenticationState.CHOOSE_LOCATION -> {
location = cloudFolderModelMapper.toModel(folder) location = cloudFolderModelMapper.toModel(folder)
selectedVault?.let { navigateToVaultContent(it, location) } selectedVault?.let { navigateToVaultContent(it, location) }
}
AuthenticationState.INIT_ROOT -> location = cloudFolderModelMapper.toModel(folder)
} }
AuthenticationState.INIT_ROOT -> location = cloudFolderModelMapper.toModel(folder)
} }
}) }
})
} }
private fun navigateToVaultContent(vaultModel: VaultModel, decryptedRoot: CloudFolderModel?) { private fun navigateToVaultContent(vaultModel: VaultModel, decryptedRoot: CloudFolderModel?) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.onAutoUploadChooseLocation(vaultModel), // ActivityResultCallbacks.onAutoUploadChooseLocation(vaultModel), //
Intents.browseFilesIntent() // Intents.browseFilesIntent() //
.withFolder(decryptedRoot) // .withFolder(decryptedRoot) //
.withTitle(vaultModel.name) // .withTitle(vaultModel.name) //
.withChooseCloudNodeSettings( // .withChooseCloudNodeSettings( //
ChooseCloudNodeSettings.chooseCloudNodeSettings() // ChooseCloudNodeSettings.chooseCloudNodeSettings() //
.withExtraTitle(context().getString(R.string.screen_file_browser_share_destination_title)) // .withExtraTitle(context().getString(R.string.screen_file_browser_share_destination_title)) //
.withExtraToolbarIcon(R.drawable.ic_clear) // .withExtraToolbarIcon(R.drawable.ic_clear) //
.withButtonText(context().getString(R.string.screen_file_browser_share_button_text)) // .withButtonText(context().getString(R.string.screen_file_browser_share_button_text)) //
.selectingFolders() // .selectingFolders() //
.build())) .build()
)
)
} }
@Callback @Callback

View File

@ -22,11 +22,12 @@ import timber.log.Timber
@PerView @PerView
class BiometricAuthSettingsPresenter @Inject constructor( // class BiometricAuthSettingsPresenter @Inject constructor( //
private val getVaultListUseCase: GetVaultListUseCase, // private val getVaultListUseCase: GetVaultListUseCase, //
private val saveVaultUseCase: SaveVaultUseCase, // private val saveVaultUseCase: SaveVaultUseCase, //
private val lockVaultUseCase: LockVaultUseCase, // private val lockVaultUseCase: LockVaultUseCase, //
exceptionMappings: ExceptionHandlers, // exceptionMappings: ExceptionHandlers, //
private val sharedPreferencesHandler: SharedPreferencesHandler) : Presenter<BiometricAuthSettingsView>(exceptionMappings) { private val sharedPreferencesHandler: SharedPreferencesHandler
) : Presenter<BiometricAuthSettingsView>(exceptionMappings) {
fun loadVaultList() { fun loadVaultList() {
updateVaultListView() updateVaultListView()
@ -55,19 +56,21 @@ class BiometricAuthSettingsPresenter @Inject constructor( //
Timber.tag("BiomtricAuthSettngsPres").i("Checking entered vault password") Timber.tag("BiomtricAuthSettngsPres").i("Checking entered vault password")
if (vaultModel.isLocked) { if (vaultModel.isLocked) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.vaultUnlockedBiometricAuthPres(vaultModel), // ActivityResultCallbacks.vaultUnlockedBiometricAuthPres(vaultModel), //
Intents.unlockVaultIntent().withVaultModel(vaultModel).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH)) Intents.unlockVaultIntent().withVaultModel(vaultModel).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH)
)
} else { } else {
lockVaultUseCase lockVaultUseCase
.withVault(vaultModel.toVault()) .withVault(vaultModel.toVault())
.run(object : DefaultResultHandler<Vault>() { .run(object : DefaultResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
super.onSuccess(vault) super.onSuccess(vault)
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.vaultUnlockedBiometricAuthPres(vaultModel), // ActivityResultCallbacks.vaultUnlockedBiometricAuthPres(vaultModel), //
Intents.unlockVaultIntent().withVaultModel(vaultModel).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH)) Intents.unlockVaultIntent().withVaultModel(vaultModel).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH)
} )
}) }
})
} }
} }
@ -78,8 +81,9 @@ class BiometricAuthSettingsPresenter @Inject constructor( //
val vault = Vault.aCopyOf(vaultModel.toVault()).withCloud(cloud).withSavedPassword(password).build() val vault = Vault.aCopyOf(vaultModel.toVault()).withCloud(cloud).withSavedPassword(password).build()
when { when {
result.isResultOk -> requestActivityResult( // result.isResultOk -> requestActivityResult( //
ActivityResultCallbacks.encryptVaultPassword(vaultModel), // ActivityResultCallbacks.encryptVaultPassword(vaultModel), //
Intents.unlockVaultIntent().withVaultModel(VaultModel(vault)).withVaultAction(UnlockVaultIntent.VaultAction.ENCRYPT_PASSWORD)) Intents.unlockVaultIntent().withVaultModel(VaultModel(vault)).withVaultAction(UnlockVaultIntent.VaultAction.ENCRYPT_PASSWORD)
)
else -> TODO("Not yet implemented") else -> TODO("Not yet implemented")
} }
} }
@ -96,12 +100,12 @@ class BiometricAuthSettingsPresenter @Inject constructor( //
private fun saveVault(vault: Vault?) { private fun saveVault(vault: Vault?) {
saveVaultUseCase // saveVaultUseCase //
.withVault(vault) // .withVault(vault) //
.run(object : ProgressCompletingResultHandler<Vault>() { .run(object : ProgressCompletingResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
Timber.tag("BiomtricAuthSettngsPres").i("Saved updated vault successfully") Timber.tag("BiomtricAuthSettngsPres").i("Saved updated vault successfully")
} }
}) })
} }
fun switchedGeneralBiometricAuthSettings(isChecked: Boolean) { fun switchedGeneralBiometricAuthSettings(isChecked: Boolean) {
@ -124,9 +128,9 @@ class BiometricAuthSettingsPresenter @Inject constructor( //
private fun removePasswordAndSave(vault: Vault) { private fun removePasswordAndSave(vault: Vault) {
val vaultWithRemovedPassword = Vault // val vaultWithRemovedPassword = Vault //
.aCopyOf(vault) // .aCopyOf(vault) //
.withSavedPassword(null) // .withSavedPassword(null) //
.build() .build()
saveVault(vaultWithRemovedPassword) saveVault(vaultWithRemovedPassword)
} }

View File

@ -20,11 +20,12 @@ import javax.inject.Inject
@PerView @PerView
class ChooseCloudServicePresenter @Inject constructor( // class ChooseCloudServicePresenter @Inject constructor( //
private val getCloudsUseCase: GetCloudsUseCase, // private val getCloudsUseCase: GetCloudsUseCase, //
private val cloudModelMapper: CloudModelMapper, // private val cloudModelMapper: CloudModelMapper, //
private val addExistingVaultWorkflow: AddExistingVaultWorkflow, // private val addExistingVaultWorkflow: AddExistingVaultWorkflow, //
private val createNewVaultWorkflow: CreateNewVaultWorkflow, // private val createNewVaultWorkflow: CreateNewVaultWorkflow, //
exceptionMappings: ExceptionHandlers) : Presenter<ChooseCloudServiceView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<ChooseCloudServiceView>(exceptionMappings) {
override fun workflows(): Iterable<Workflow<*>> { override fun workflows(): Iterable<Workflow<*>> {
return listOf(addExistingVaultWorkflow, createNewVaultWorkflow) return listOf(addExistingVaultWorkflow, createNewVaultWorkflow)
@ -55,11 +56,12 @@ class ChooseCloudServicePresenter @Inject constructor( //
private fun startCloudConnectionListActivity(cloudTypeModel: CloudTypeModel) { private fun startCloudConnectionListActivity(cloudTypeModel: CloudTypeModel) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.cloudConnectionListFinished(), // ActivityResultCallbacks.cloudConnectionListFinished(), //
Intents.cloudConnectionListIntent() // Intents.cloudConnectionListIntent() //
.withCloudType(cloudTypeModel) // .withCloudType(cloudTypeModel) //
.withDialogTitle(context().getString(R.string.screen_cloud_connections_title)) // .withDialogTitle(context().getString(R.string.screen_cloud_connections_title)) //
.withFinishOnCloudItemClick(true)) .withFinishOnCloudItemClick(true)
)
} }
@Callback @Callback
@ -70,15 +72,15 @@ class ChooseCloudServicePresenter @Inject constructor( //
private fun handleSingleInstanceClouds(cloudTypeModel: CloudTypeModel) { private fun handleSingleInstanceClouds(cloudTypeModel: CloudTypeModel) {
getCloudsUseCase // getCloudsUseCase //
.withCloudType(CloudTypeModel.valueOf(cloudTypeModel)) // .withCloudType(CloudTypeModel.valueOf(cloudTypeModel)) //
.run(object : DefaultResultHandler<List<Cloud>>() { .run(object : DefaultResultHandler<List<Cloud>>() {
override fun onSuccess(clouds: List<Cloud>) { override fun onSuccess(clouds: List<Cloud>) {
if (clouds.size > 1) { if (clouds.size > 1) {
throw FatalBackendException("More then one cloud") throw FatalBackendException("More then one cloud")
}
onCloudSelected(clouds[0])
} }
}) onCloudSelected(clouds[0])
}
})
} }
private fun onCloudSelected(cloud: Cloud) { private fun onCloudSelected(cloud: Cloud) {

View File

@ -42,14 +42,15 @@ import timber.log.Timber
@PerView @PerView
class CloudConnectionListPresenter @Inject constructor( // class CloudConnectionListPresenter @Inject constructor( //
private val getCloudsUseCase: GetCloudsUseCase, // private val getCloudsUseCase: GetCloudsUseCase, //
private val getUsernameUseCase: GetUsernameUseCase, // private val getUsernameUseCase: GetUsernameUseCase, //
private val removeCloudUseCase: RemoveCloudUseCase, // private val removeCloudUseCase: RemoveCloudUseCase, //
private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, // private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, //
private val getVaultListUseCase: GetVaultListUseCase, // private val getVaultListUseCase: GetVaultListUseCase, //
private val deleteVaultUseCase: DeleteVaultUseCase, // private val deleteVaultUseCase: DeleteVaultUseCase, //
private val cloudModelMapper: CloudModelMapper, // private val cloudModelMapper: CloudModelMapper, //
exceptionMappings: ExceptionHandlers) : Presenter<CloudConnectionListView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<CloudConnectionListView>(exceptionMappings) {
private val selectedCloudType = AtomicReference<CloudTypeModel>() private val selectedCloudType = AtomicReference<CloudTypeModel>()
private var defaultLocalStorageCloud: LocalStorageCloud? = null private var defaultLocalStorageCloud: LocalStorageCloud? = null
@ -59,22 +60,22 @@ class CloudConnectionListPresenter @Inject constructor( //
fun loadCloudList() { fun loadCloudList() {
getCloudsUseCase // getCloudsUseCase //
.withCloudType(CloudTypeModel.valueOf(selectedCloudType.get())) // .withCloudType(CloudTypeModel.valueOf(selectedCloudType.get())) //
.run(object : DefaultResultHandler<List<Cloud>>() { .run(object : DefaultResultHandler<List<Cloud>>() {
override fun onSuccess(clouds: List<Cloud>) { override fun onSuccess(clouds: List<Cloud>) {
val cloudModels: MutableList<CloudModel> = ArrayList() val cloudModels: MutableList<CloudModel> = ArrayList()
clouds.forEach { cloud -> clouds.forEach { cloud ->
if (CloudTypeModel.LOCAL == selectedCloudType.get()) { if (CloudTypeModel.LOCAL == selectedCloudType.get()) {
if ((cloud as LocalStorageCloud).rootUri() == null) { if ((cloud as LocalStorageCloud).rootUri() == null) {
defaultLocalStorageCloud = cloud defaultLocalStorageCloud = cloud
return@forEach return@forEach
}
} }
cloudModels.add(cloudModelMapper.toModel(cloud))
} }
view?.showCloudModels(cloudModels) cloudModels.add(cloudModelMapper.toModel(cloud))
} }
}) view?.showCloudModels(cloudModels)
}
})
} }
fun onDeleteCloudClicked(cloudModel: CloudModel) { fun onDeleteCloudClicked(cloudModel: CloudModel) {
@ -120,32 +121,39 @@ class CloudConnectionListPresenter @Inject constructor( //
private fun deleteCloud(cloud: Cloud) { private fun deleteCloud(cloud: Cloud) {
removeCloudUseCase // removeCloudUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<Void?>() { .run(object : DefaultResultHandler<Void?>() {
override fun onSuccess(ignore: Void?) { override fun onSuccess(ignore: Void?) {
loadCloudList() loadCloudList()
} }
}) })
} }
fun onAddConnectionClicked() { fun onAddConnectionClicked() {
when (selectedCloudType.get()) { when (selectedCloudType.get()) {
CloudTypeModel.WEBDAV -> requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), // CloudTypeModel.WEBDAV -> requestActivityResult(
Intents.webDavAddOrChangeIntent()) ActivityResultCallbacks.addChangeMultiCloud(), //
Intents.webDavAddOrChangeIntent()
)
CloudTypeModel.PCLOUD -> { CloudTypeModel.PCLOUD -> {
val authIntent: Intent = AuthorizationActivity.createIntent( val authIntent: Intent = AuthorizationActivity.createIntent(
this.context(), this.context(),
AuthorizationRequest.create() AuthorizationRequest.create()
.setType(AuthorizationRequest.Type.TOKEN) .setType(AuthorizationRequest.Type.TOKEN)
.setClientId(BuildConfig.PCLOUD_CLIENT_ID) .setClientId(BuildConfig.PCLOUD_CLIENT_ID)
.setForceAccessApproval(true) .setForceAccessApproval(true)
.addPermission("manageshares") .addPermission("manageshares")
.build()) .build()
requestActivityResult(ActivityResultCallbacks.pCloudAuthenticationFinished(), // )
authIntent) requestActivityResult(
ActivityResultCallbacks.pCloudAuthenticationFinished(), //
authIntent
)
} }
CloudTypeModel.S3 -> requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), // CloudTypeModel.S3 -> requestActivityResult(
Intents.s3AddOrChangeIntent()) ActivityResultCallbacks.addChangeMultiCloud(), //
Intents.s3AddOrChangeIntent()
)
CloudTypeModel.LOCAL -> openDocumentTree() CloudTypeModel.LOCAL -> openDocumentTree()
} }
} }
@ -154,15 +162,17 @@ class CloudConnectionListPresenter @Inject constructor( //
private fun openDocumentTree() { private fun openDocumentTree() {
try { try {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.pickedLocalStorageLocation(), // ActivityResultCallbacks.pickedLocalStorageLocation(), //
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)) Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
)
} catch (exception: ActivityNotFoundException) { } catch (exception: ActivityNotFoundException) {
Toast // Toast //
.makeText( // .makeText( //
activity().applicationContext, // activity().applicationContext, //
context().getText(R.string.screen_cloud_local_error_no_content_provider), // context().getText(R.string.screen_cloud_local_error_no_content_provider), //
Toast.LENGTH_SHORT) // Toast.LENGTH_SHORT
.show() ) //
.show()
Timber.tag("CloudConnListPresenter").e(exception, "No ContentProvider on system") Timber.tag("CloudConnListPresenter").e(exception, "No ContentProvider on system")
} }
} }
@ -170,14 +180,18 @@ class CloudConnectionListPresenter @Inject constructor( //
fun onChangeCloudClicked(cloudModel: CloudModel) { fun onChangeCloudClicked(cloudModel: CloudModel) {
when { when {
cloudModel.cloudType() == CloudTypeModel.WEBDAV -> { cloudModel.cloudType() == CloudTypeModel.WEBDAV -> {
requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), // requestActivityResult(
Intents.webDavAddOrChangeIntent() // ActivityResultCallbacks.addChangeMultiCloud(), //
.withWebDavCloud(cloudModel as WebDavCloudModel)) Intents.webDavAddOrChangeIntent() //
.withWebDavCloud(cloudModel as WebDavCloudModel)
)
} }
cloudModel.cloudType() == CloudTypeModel.S3 -> { cloudModel.cloudType() == CloudTypeModel.S3 -> {
requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), // requestActivityResult(
Intents.s3AddOrChangeIntent() // ActivityResultCallbacks.addChangeMultiCloud(), //
.withS3Cloud(cloudModel as S3CloudModel)) Intents.s3AddOrChangeIntent() //
.withS3Cloud(cloudModel as S3CloudModel)
)
} }
else -> { else -> {
throw IllegalStateException("Change cloud with type " + cloudModel.cloudType() + " is not supported") throw IllegalStateException("Change cloud with type " + cloudModel.cloudType() + " is not supported")
@ -202,19 +216,19 @@ class CloudConnectionListPresenter @Inject constructor( //
when (result) { when (result) {
AuthorizationResult.ACCESS_GRANTED -> { AuthorizationResult.ACCESS_GRANTED -> {
val accessToken: String = CredentialCryptor // val accessToken: String = CredentialCryptor //
.getInstance(this.context()) // .getInstance(this.context()) //
.encrypt(authData.token) .encrypt(authData.token)
val pCloudSkeleton: PCloud = PCloud.aPCloud() // val pCloudSkeleton: PCloud = PCloud.aPCloud() //
.withAccessToken(accessToken) .withAccessToken(accessToken)
.withUrl(authData.apiHost) .withUrl(authData.apiHost)
.build(); .build();
getUsernameUseCase // getUsernameUseCase //
.withCloud(pCloudSkeleton) // .withCloud(pCloudSkeleton) //
.run(object : DefaultResultHandler<String>() { .run(object : DefaultResultHandler<String>() {
override fun onSuccess(username: String?) { override fun onSuccess(username: String?) {
prepareForSavingPCloud(PCloud.aCopyOf(pCloudSkeleton).withUsername(username).build()) prepareForSavingPCloud(PCloud.aCopyOf(pCloudSkeleton).withUsername(username).build())
} }
}) })
} }
AuthorizationResult.ACCESS_DENIED -> { AuthorizationResult.ACCESS_DENIED -> {
Timber.tag("CloudConnListPresenter").e("Account access denied") Timber.tag("CloudConnListPresenter").e("Account access denied")
@ -233,30 +247,32 @@ class CloudConnectionListPresenter @Inject constructor( //
fun prepareForSavingPCloud(cloud: PCloud) { fun prepareForSavingPCloud(cloud: PCloud) {
getCloudsUseCase // getCloudsUseCase //
.withCloudType(CloudTypeModel.valueOf(selectedCloudType.get())) // .withCloudType(CloudTypeModel.valueOf(selectedCloudType.get())) //
.run(object : DefaultResultHandler<List<Cloud>>() { .run(object : DefaultResultHandler<List<Cloud>>() {
override fun onSuccess(clouds: List<Cloud>) { override fun onSuccess(clouds: List<Cloud>) {
clouds.firstOrNull { clouds.firstOrNull {
(it as PCloud).username() == cloud.username() (it as PCloud).username() == cloud.username()
}?.let { }?.let {
it as PCloud it as PCloud
saveCloud(PCloud.aCopyOf(it) // saveCloud(
.withUrl(cloud.url()) PCloud.aCopyOf(it) //
.withAccessToken(cloud.accessToken()) .withUrl(cloud.url())
.build()) .withAccessToken(cloud.accessToken())
} ?: saveCloud(cloud) .build()
} )
}) } ?: saveCloud(cloud)
}
})
} }
fun saveCloud(cloud: PCloud) { fun saveCloud(cloud: PCloud) {
addOrChangeCloudConnectionUseCase // addOrChangeCloudConnectionUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<Void?>() { .run(object : DefaultResultHandler<Void?>() {
override fun onSuccess(void: Void?) { override fun onSuccess(void: Void?) {
loadCloudList() loadCloudList()
} }
}) })
} }
@Callback @Callback
@ -264,34 +280,38 @@ class CloudConnectionListPresenter @Inject constructor( //
fun pickedLocalStorageLocation(result: ActivityResult) { fun pickedLocalStorageLocation(result: ActivityResult) {
val rootTreeUriOfLocalStorage = result.intent().data val rootTreeUriOfLocalStorage = result.intent().data
persistUriPermission(rootTreeUriOfLocalStorage) persistUriPermission(rootTreeUriOfLocalStorage)
addOrChangeCloudConnectionUseCase.withCloud(LocalStorageCloud.aLocalStorage() // addOrChangeCloudConnectionUseCase.withCloud(
LocalStorageCloud.aLocalStorage() //
.withRootUri(rootTreeUriOfLocalStorage.toString()) // .withRootUri(rootTreeUriOfLocalStorage.toString()) //
.build()) // .build()
.run(object : DefaultResultHandler<Void?>() { ) //
override fun onSuccess(void: Void?) { .run(object : DefaultResultHandler<Void?>() {
loadCloudList() override fun onSuccess(void: Void?) {
} loadCloudList()
}) }
})
} }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @RequiresApi(api = Build.VERSION_CODES.KITKAT)
private fun persistUriPermission(rootTreeUriOfLocalStorage: Uri?) { private fun persistUriPermission(rootTreeUriOfLocalStorage: Uri?) {
rootTreeUriOfLocalStorage?.let { rootTreeUriOfLocalStorage?.let {
context() // context() //
.contentResolver // .contentResolver //
.takePersistableUriPermission( // .takePersistableUriPermission( //
it, // it, //
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
} }
} }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @RequiresApi(api = Build.VERSION_CODES.KITKAT)
private fun releaseUriPermission(uri: String) { private fun releaseUriPermission(uri: String) {
context() // context() //
.contentResolver // .contentResolver //
.releasePersistableUriPermission( // .releasePersistableUriPermission( //
Uri.parse(uri), // Uri.parse(uri), //
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
} }
fun onCloudConnectionClicked(cloudModel: CloudModel) { fun onCloudConnectionClicked(cloudModel: CloudModel) {

View File

@ -29,18 +29,20 @@ import javax.inject.Inject
@PerView @PerView
class CloudSettingsPresenter @Inject constructor( // class CloudSettingsPresenter @Inject constructor( //
private val getAllCloudsUseCase: GetAllCloudsUseCase, // private val getAllCloudsUseCase: GetAllCloudsUseCase, //
private val getCloudsUseCase: GetCloudsUseCase, // private val getCloudsUseCase: GetCloudsUseCase, //
private val logoutCloudUsecase: LogoutCloudUseCase, // private val logoutCloudUsecase: LogoutCloudUseCase, //
private val cloudModelMapper: CloudModelMapper, // private val cloudModelMapper: CloudModelMapper, //
exceptionMappings: ExceptionHandlers) : Presenter<CloudSettingsView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<CloudSettingsView>(exceptionMappings) {
private val nonSingleLoginClouds: Set<CloudTypeModel> = EnumSet.of( // private val nonSingleLoginClouds: Set<CloudTypeModel> = EnumSet.of( //
CloudTypeModel.CRYPTO, // CloudTypeModel.CRYPTO, //
CloudTypeModel.LOCAL, // CloudTypeModel.LOCAL, //
CloudTypeModel.PCLOUD, // CloudTypeModel.PCLOUD, //
CloudTypeModel.S3, // CloudTypeModel.S3, //
CloudTypeModel.WEBDAV) CloudTypeModel.WEBDAV
)
fun loadClouds() { fun loadClouds() {
getAllCloudsUseCase.run(CloudsSubscriber()) getAllCloudsUseCase.run(CloudsSubscriber())
@ -52,12 +54,12 @@ class CloudSettingsPresenter @Inject constructor( //
} else { } else {
if (isLoggedIn(cloudModel)) { if (isLoggedIn(cloudModel)) {
logoutCloudUsecase // logoutCloudUsecase //
.withCloud(cloudModel.toCloud()) // .withCloud(cloudModel.toCloud()) //
.run(object : DefaultResultHandler<Cloud>() { .run(object : DefaultResultHandler<Cloud>() {
override fun onSuccess(cloud: Cloud) { override fun onSuccess(cloud: Cloud) {
loadClouds() loadClouds()
} }
}) })
} else { } else {
loginCloud(cloudModel) loginCloud(cloudModel)
} }
@ -66,15 +68,15 @@ class CloudSettingsPresenter @Inject constructor( //
private fun loginCloud(cloudModel: CloudModel) { private fun loginCloud(cloudModel: CloudModel) {
getCloudsUseCase // getCloudsUseCase //
.withCloudType(CloudTypeModel.valueOf(cloudModel.cloudType())) // .withCloudType(CloudTypeModel.valueOf(cloudModel.cloudType())) //
.run(object : DefaultResultHandler<List<Cloud>>() { .run(object : DefaultResultHandler<List<Cloud>>() {
override fun onSuccess(clouds: List<Cloud>) { override fun onSuccess(clouds: List<Cloud>) {
if (clouds.size > 1) { if (clouds.size > 1) {
throw FatalBackendException("More then one cloud") throw FatalBackendException("More then one cloud")
}
startAuthentication(clouds[0])
} }
}) startAuthentication(clouds[0])
}
})
} }
private fun isLoggedIn(cloudModel: CloudModel): Boolean { private fun isLoggedIn(cloudModel: CloudModel): Boolean {
@ -83,11 +85,12 @@ class CloudSettingsPresenter @Inject constructor( //
private fun startConnectionListActivity(cloudTypeModel: CloudTypeModel) { private fun startConnectionListActivity(cloudTypeModel: CloudTypeModel) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.webDavConnectionListFinisheds(), // ActivityResultCallbacks.webDavConnectionListFinisheds(), //
Intents.cloudConnectionListIntent() // Intents.cloudConnectionListIntent() //
.withCloudType(cloudTypeModel) // .withCloudType(cloudTypeModel) //
.withDialogTitle(effectiveTitle(cloudTypeModel)) // .withDialogTitle(effectiveTitle(cloudTypeModel)) //
.withFinishOnCloudItemClick(false)) .withFinishOnCloudItemClick(false)
)
} }
private fun effectiveTitle(cloudTypeModel: CloudTypeModel): String { private fun effectiveTitle(cloudTypeModel: CloudTypeModel): String {
@ -108,9 +111,10 @@ class CloudSettingsPresenter @Inject constructor( //
private fun startAuthentication(cloud: Cloud) { private fun startAuthentication(cloud: Cloud) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.onCloudAuthenticated(), // ActivityResultCallbacks.onCloudAuthenticated(), //
Intents.authenticateCloudIntent() // Intents.authenticateCloudIntent() //
.withCloud(cloudModelMapper.toModel(cloud))) .withCloud(cloudModelMapper.toModel(cloud))
)
} }
@Callback @Callback
@ -122,15 +126,15 @@ class CloudSettingsPresenter @Inject constructor( //
override fun onSuccess(clouds: List<Cloud>) { override fun onSuccess(clouds: List<Cloud>) {
val cloudModel = cloudModelMapper.toModels(clouds) // val cloudModel = cloudModelMapper.toModels(clouds) //
.filter { isSingleLoginCloud(it) } // .filter { isSingleLoginCloud(it) } //
.filter { cloud -> !(BuildConfig.FLAVOR == "fdroid" && cloud.cloudType() == CloudTypeModel.GOOGLE_DRIVE) } // .filter { cloud -> !(BuildConfig.FLAVOR == "fdroid" && cloud.cloudType() == CloudTypeModel.GOOGLE_DRIVE) } //
.toMutableList() // .toMutableList() //
.also { .also {
it.add(aPCloud()) it.add(aPCloud())
it.add(aWebdavCloud()) it.add(aWebdavCloud())
it.add(aS3Cloud()) it.add(aS3Cloud())
it.add(aLocalCloud()) it.add(aLocalCloud())
} }
view?.render(cloudModel) view?.render(cloudModel)
} }

View File

@ -11,8 +11,9 @@ import javax.inject.Inject
@PerView @PerView
class CreateVaultPresenter @Inject constructor( // class CreateVaultPresenter @Inject constructor( //
private val createNewVaultWorkflow: CreateNewVaultWorkflow, // private val createNewVaultWorkflow: CreateNewVaultWorkflow, //
exceptionMappings: ExceptionHandlers) : Presenter<CreateVaultView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<CreateVaultView>(exceptionMappings) {
override fun workflows(): Iterable<Workflow<*>> { override fun workflows(): Iterable<Workflow<*>> {
return setOf(createNewVaultWorkflow) return setOf(createNewVaultWorkflow)

View File

@ -42,15 +42,16 @@ import timber.log.Timber
@PerView @PerView
class ImagePreviewPresenter @Inject constructor( // class ImagePreviewPresenter @Inject constructor( //
exceptionMappings: ExceptionHandlers, // exceptionMappings: ExceptionHandlers, //
private val shareFileHelper: ShareFileHelper, // private val shareFileHelper: ShareFileHelper, //
private val contentResolverUtil: ContentResolverUtil, // private val contentResolverUtil: ContentResolverUtil, //
private val copyDataUseCase: CopyDataUseCase, // private val copyDataUseCase: CopyDataUseCase, //
private val downloadFilesUseCase: DownloadFilesUseCase, // private val downloadFilesUseCase: DownloadFilesUseCase, //
private val deleteNodesUseCase: DeleteNodesUseCase, // private val deleteNodesUseCase: DeleteNodesUseCase, //
private val downloadFileUtil: DownloadFileUtil, // private val downloadFileUtil: DownloadFileUtil, //
private val fileUtil: FileUtil, // private val fileUtil: FileUtil, //
private val cloudFileModelMapper: CloudFileModelMapper) : Presenter<ImagePreviewView>(exceptionMappings) { private val cloudFileModelMapper: CloudFileModelMapper
) : Presenter<ImagePreviewView>(exceptionMappings) {
private var isSystemUiVisible = true private var isSystemUiVisible = true
@ -66,8 +67,10 @@ class ImagePreviewPresenter @Inject constructor( //
} }
private fun copyFileToDownloadDirectory(uri: Uri) { private fun copyFileToDownloadDirectory(uri: Uri) {
requestPermissions(PermissionsResultCallbacks.copyFileToDownloadDirectory(uri.toString()), // requestPermissions(
R.string.permission_message_export_file, Manifest.permission.WRITE_EXTERNAL_STORAGE) PermissionsResultCallbacks.copyFileToDownloadDirectory(uri.toString()), //
R.string.permission_message_export_file, Manifest.permission.WRITE_EXTERNAL_STORAGE
)
} }
@Callback @Callback
@ -95,13 +98,13 @@ class ImagePreviewPresenter @Inject constructor( //
throw FatalBackendException("Input- or OutputStream is null") throw FatalBackendException("Input- or OutputStream is null")
} }
copyDataUseCase // copyDataUseCase //
.withSource(source) // .withSource(source) //
.andTarget(target) // .andTarget(target) //
.run(object : DefaultResultHandler<Void?>() { .run(object : DefaultResultHandler<Void?>() {
override fun onFinished() { override fun onFinished() {
view?.showMessage(R.string.screen_file_browser_msg_file_exported) view?.showMessage(R.string.screen_file_browser_msg_file_exported)
} }
}) })
} }
private fun copyFileToUserSelectedLocation(uri: Uri) { private fun copyFileToUserSelectedLocation(uri: Uri) {
@ -114,17 +117,21 @@ class ImagePreviewPresenter @Inject constructor( //
@Callback @Callback
fun copyFileToUserSelectedLocation(result: ActivityResult, sourceUri: String?) { fun copyFileToUserSelectedLocation(result: ActivityResult, sourceUri: String?) {
requestPermissions(PermissionsResultCallbacks.copyFileToUserSelectedLocation(result.intent()?.dataString, sourceUri), // requestPermissions(
R.string.permission_message_export_file, // PermissionsResultCallbacks.copyFileToUserSelectedLocation(result.intent()?.dataString, sourceUri), //
Manifest.permission.READ_EXTERNAL_STORAGE) R.string.permission_message_export_file, //
Manifest.permission.READ_EXTERNAL_STORAGE
)
} }
@Callback @Callback
fun copyFileToUserSelectedLocation(result: PermissionsResult, targetUri: String?, sourceUri: String?) { fun copyFileToUserSelectedLocation(result: PermissionsResult, targetUri: String?, sourceUri: String?) {
if (result.granted()) { if (result.granted()) {
try { try {
copyFile(contentResolverUtil.openInputStream(Uri.parse(sourceUri)), // copyFile(
contentResolverUtil.openOutputStream(Uri.parse(targetUri))) contentResolverUtil.openInputStream(Uri.parse(sourceUri)), //
contentResolverUtil.openOutputStream(Uri.parse(targetUri))
)
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
showError(e) showError(e)
} }
@ -142,18 +149,18 @@ class ImagePreviewPresenter @Inject constructor( //
fun onDeleteImageConfirmed(imagePreviewFile: ImagePreviewFile, index: Int) { fun onDeleteImageConfirmed(imagePreviewFile: ImagePreviewFile, index: Int) {
view?.showProgress(ProgressModel.GENERIC) view?.showProgress(ProgressModel.GENERIC)
deleteNodesUseCase deleteNodesUseCase
.withCloudNodes(listOf(imagePreviewFile.cloudFileModel.toCloudNode())) .withCloudNodes(listOf(imagePreviewFile.cloudFileModel.toCloudNode()))
.run(object : ProgressCompletingResultHandler<List<CloudNode?>?>() { .run(object : ProgressCompletingResultHandler<List<CloudNode?>?>() {
override fun onFinished() { override fun onFinished() {
view?.showProgress(ProgressModel.COMPLETED) view?.showProgress(ProgressModel.COMPLETED)
view?.onImageDeleted(index) view?.onImageDeleted(index)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
Timber.tag("ImagePreviewPresenter").e(e, "Failed to delete preview image") Timber.tag("ImagePreviewPresenter").e(e, "Failed to delete preview image")
view?.showProgress(ProgressModel.COMPLETED) view?.showProgress(ProgressModel.COMPLETED)
} }
}) })
} }
fun onImagePreviewClicked() { fun onImagePreviewClicked() {
@ -167,24 +174,24 @@ class ImagePreviewPresenter @Inject constructor( //
fun onMissingImagePreviewFile(imagePreviewFile: ImagePreviewFile) { fun onMissingImagePreviewFile(imagePreviewFile: ImagePreviewFile) {
downloadFilesUseCase // downloadFilesUseCase //
.withDownloadFiles(downloadFileUtil.createDownloadFilesFor(this, listOf(imagePreviewFile.cloudFileModel))) // .withDownloadFiles(downloadFileUtil.createDownloadFilesFor(this, listOf(imagePreviewFile.cloudFileModel))) //
.run(object : DefaultProgressAwareResultHandler<List<CloudFile>, DownloadState>() { .run(object : DefaultProgressAwareResultHandler<List<CloudFile>, DownloadState>() {
override fun onSuccess(result: List<CloudFile>) { override fun onSuccess(result: List<CloudFile>) {
cloudFileModelMapper.toModel(result[0]) cloudFileModelMapper.toModel(result[0])
imagePreviewFile.uri = fileUtil.contentUriFor(cloudFileModelMapper.toModel(result[0])) imagePreviewFile.uri = fileUtil.contentUriFor(cloudFileModelMapper.toModel(result[0]))
view?.showImagePreview(imagePreviewFile) view?.showImagePreview(imagePreviewFile)
view?.hideProgressBar(imagePreviewFile) view?.hideProgressBar(imagePreviewFile)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (ExceptionUtil.contains(e, IOException::class.java, ExceptionUtil.thatContainsMessage("Stream Closed"))) { if (ExceptionUtil.contains(e, IOException::class.java, ExceptionUtil.thatContainsMessage("Stream Closed"))) {
// ignore error // ignore error
Timber.tag("ImagePreviewPresenter").d("User swiped to quickly and close the stream before finishing the download.") Timber.tag("ImagePreviewPresenter").d("User swiped to quickly and close the stream before finishing the download.")
} else { } else {
super.onError(e) super.onError(e)
}
} }
}) }
})
} }
fun getImagePreviewFileStore(path: String): ImagePreviewFilesStore { fun getImagePreviewFileStore(path: String): ImagePreviewFilesStore {

View File

@ -11,24 +11,25 @@ import javax.inject.Inject
import timber.log.Timber import timber.log.Timber
class LicenseCheckPresenter @Inject internal constructor( class LicenseCheckPresenter @Inject internal constructor(
exceptionHandlers: ExceptionHandlers, // exceptionHandlers: ExceptionHandlers, //
private val doLicenseCheckUsecase: DoLicenseCheckUseCase, // private val doLicenseCheckUsecase: DoLicenseCheckUseCase, //
private val sharedPreferencesHandler: SharedPreferencesHandler) : Presenter<UpdateLicenseView>(exceptionHandlers) { private val sharedPreferencesHandler: SharedPreferencesHandler
) : Presenter<UpdateLicenseView>(exceptionHandlers) {
fun validate(data: Uri?) { fun validate(data: Uri?) {
data?.let { data?.let {
val license = it.fragment ?: it.lastPathSegment ?: "" val license = it.fragment ?: it.lastPathSegment ?: ""
view?.showOrUpdateLicenseDialog(license) view?.showOrUpdateLicenseDialog(license)
doLicenseCheckUsecase doLicenseCheckUsecase
.withLicense(license) .withLicense(license)
.run(CheckLicenseStatusSubscriber()) .run(CheckLicenseStatusSubscriber())
} }
} }
fun validateDialogAware(license: String?) { fun validateDialogAware(license: String?) {
doLicenseCheckUsecase doLicenseCheckUsecase
.withLicense(license) .withLicense(license)
.run(CheckLicenseStatusSubscriber()) .run(CheckLicenseStatusSubscriber())
} }
private inner class CheckLicenseStatusSubscriber : NoOpResultHandler<LicenseCheck>() { private inner class CheckLicenseStatusSubscriber : NoOpResultHandler<LicenseCheck>() {

View File

@ -76,23 +76,23 @@ abstract class Presenter<V : View> protected constructor(private val exceptionMa
fun finishWithResult(resultName: String, result: Serializable?) { fun finishWithResult(resultName: String, result: Serializable?) {
activeWorkflow()?.dispatch(result) activeWorkflow()?.dispatch(result)
?: run { ?: run {
val data = Intent() val data = Intent()
when (result) { when (result) {
null -> { null -> {
activity().setResult(Activity.RESULT_CANCELED) activity().setResult(Activity.RESULT_CANCELED)
} }
is Throwable -> { is Throwable -> {
data.putExtra(resultName, result) data.putExtra(resultName, result)
activity().setResult(Activity.RESULT_CANCELED, data) activity().setResult(Activity.RESULT_CANCELED, data)
} }
else -> { else -> {
data.putExtra(resultName, result) data.putExtra(resultName, result)
activity().setResult(Activity.RESULT_OK, data) activity().setResult(Activity.RESULT_OK, data)
}
} }
finish()
} }
finish()
}
} }
private fun activeWorkflow(): Workflow<*>? { private fun activeWorkflow(): Workflow<*>? {

View File

@ -16,9 +16,10 @@ import javax.inject.Inject
@PerView @PerView
class S3AddOrChangePresenter @Inject internal constructor( // class S3AddOrChangePresenter @Inject internal constructor( //
private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, // private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, //
private val connectToS3UseCase: ConnectToS3UseCase, // private val connectToS3UseCase: ConnectToS3UseCase, //
exceptionMappings: ExceptionHandlers) : Presenter<S3AddOrChangeView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<S3AddOrChangeView>(exceptionMappings) {
fun checkUserInput(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?, displayName: String) { fun checkUserInput(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?, displayName: String) {
var statusMessage: String? = null var statusMessage: String? = null
@ -48,19 +49,19 @@ class S3AddOrChangePresenter @Inject internal constructor( //
private fun encrypt(text: String): String { private fun encrypt(text: String): String {
return CredentialCryptor // return CredentialCryptor //
.getInstance(context()) // .getInstance(context()) //
.encrypt(text) .encrypt(text)
} }
private fun mapToCloud(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?, displayName: String): S3Cloud { private fun mapToCloud(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?, displayName: String): S3Cloud {
var builder = S3Cloud // var builder = S3Cloud //
.aS3Cloud() // .aS3Cloud() //
.withAccessKey(accessKey) // .withAccessKey(accessKey) //
.withSecretKey(secretKey) // .withSecretKey(secretKey) //
.withS3Bucket(bucket) // .withS3Bucket(bucket) //
.withS3Endpoint(endpoint) // .withS3Endpoint(endpoint) //
.withS3Region(region) // .withS3Region(region) //
.withDisplayName(displayName) .withDisplayName(displayName)
cloudId?.let { builder = builder.withId(cloudId) } cloudId?.let { builder = builder.withId(cloudId) }
@ -74,17 +75,17 @@ class S3AddOrChangePresenter @Inject internal constructor( //
private fun authenticate(cloud: S3Cloud) { private fun authenticate(cloud: S3Cloud) {
view?.showProgress(ProgressModel(ProgressStateModel.AUTHENTICATION)) view?.showProgress(ProgressModel(ProgressStateModel.AUTHENTICATION))
connectToS3UseCase // connectToS3UseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<Void?>() { .run(object : DefaultResultHandler<Void?>() {
override fun onSuccess(void: Void?) { override fun onSuccess(void: Void?) {
onCloudAuthenticated(cloud) onCloudAuthenticated(cloud)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
view?.showProgress(ProgressModel.COMPLETED) view?.showProgress(ProgressModel.COMPLETED)
super.onError(e) super.onError(e)
} }
}) })
} }
private fun onCloudAuthenticated(cloud: Cloud) { private fun onCloudAuthenticated(cloud: Cloud) {
@ -94,8 +95,8 @@ class S3AddOrChangePresenter @Inject internal constructor( //
private fun save(cloud: Cloud) { private fun save(cloud: Cloud) {
addOrChangeCloudConnectionUseCase // addOrChangeCloudConnectionUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(DefaultResultHandler()) .run(DefaultResultHandler())
} }
init { init {

View File

@ -10,8 +10,9 @@ import javax.inject.Inject
@PerView @PerView
class SetPasswordPresenter @Inject constructor( // class SetPasswordPresenter @Inject constructor( //
private val createNewVaultWorkflow: CreateNewVaultWorkflow, // private val createNewVaultWorkflow: CreateNewVaultWorkflow, //
exceptionMappings: ExceptionHandlers) : Presenter<SetPasswordView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<SetPasswordView>(exceptionMappings) {
override fun workflows(): Iterable<Workflow<*>> { override fun workflows(): Iterable<Workflow<*>> {
return setOf(createNewVaultWorkflow) return setOf(createNewVaultWorkflow)

View File

@ -39,12 +39,13 @@ import timber.log.Timber
@PerView @PerView
class SettingsPresenter @Inject internal constructor( class SettingsPresenter @Inject internal constructor(
private val updateCheckUseCase: DoUpdateCheckUseCase, // private val updateCheckUseCase: DoUpdateCheckUseCase, //
private val updateUseCase: DoUpdateUseCase, // private val updateUseCase: DoUpdateUseCase, //
private val networkConnectionCheck: NetworkConnectionCheck, // private val networkConnectionCheck: NetworkConnectionCheck, //
exceptionMappings: ExceptionHandlers, // exceptionMappings: ExceptionHandlers, //
private val fileUtil: FileUtil, // private val fileUtil: FileUtil, //
private val sharedPreferencesHandler: SharedPreferencesHandler) : Presenter<SettingsView>(exceptionMappings) { private val sharedPreferencesHandler: SharedPreferencesHandler
) : Presenter<SettingsView>(exceptionMappings) {
fun onSendErrorReportClicked() { fun onSendErrorReportClicked() {
view?.showProgress(ProgressModel.GENERIC) view?.showProgress(ProgressModel.GENERIC)
@ -58,11 +59,11 @@ class SettingsPresenter @Inject internal constructor(
private fun sendErrorReport(attachment: File) { private fun sendErrorReport(attachment: File) {
EmailBuilder.anEmail() // EmailBuilder.anEmail() //
.to("support@cryptomator.org") // .to("support@cryptomator.org") //
.withSubject(context().getString(R.string.error_report_subject)) // .withSubject(context().getString(R.string.error_report_subject)) //
.withBody(errorReportEmailBody()) // .withBody(errorReportEmailBody()) //
.attach(attachment) // .attach(attachment) //
.send(activity()) .send(activity())
} }
private fun errorReportEmailBody(): String { private fun errorReportEmailBody(): String {
@ -76,20 +77,22 @@ class SettingsPresenter @Inject internal constructor(
else -> "Google Play" else -> "Google Play"
} }
return StringBuilder().append("## ").append(context().getString(R.string.error_report_subject)).append("\n\n") // return StringBuilder().append("## ").append(context().getString(R.string.error_report_subject)).append("\n\n") //
.append("### ").append(context().getString(R.string.error_report_section_summary)).append('\n') // .append("### ").append(context().getString(R.string.error_report_section_summary)).append('\n') //
.append(context().getString(R.string.error_report_summary_description)).append("\n\n") // .append(context().getString(R.string.error_report_summary_description)).append("\n\n") //
.append("### ").append(context().getString(R.string.error_report_section_device)).append("\n") // .append("### ").append(context().getString(R.string.error_report_section_device)).append("\n") //
.append("Cryptomator v").append(BuildConfig.VERSION_NAME).append(" (").append(BuildConfig.VERSION_CODE).append(") ").append(variant).append("\n") // .append("Cryptomator v").append(BuildConfig.VERSION_NAME).append(" (").append(BuildConfig.VERSION_CODE).append(") ").append(variant).append("\n") //
.append("Android ").append(Build.VERSION.RELEASE).append(" / API").append(Build.VERSION.SDK_INT).append("\n") // .append("Android ").append(Build.VERSION.RELEASE).append(" / API").append(Build.VERSION.SDK_INT).append("\n") //
.append("Device ").append(Build.MODEL) // .append("Device ").append(Build.MODEL) //
.toString() .toString()
} }
fun grantLocalStoragePermissionForAutoUpload() { fun grantLocalStoragePermissionForAutoUpload() {
requestPermissions(PermissionsResultCallbacks.onLocalStoragePermissionGranted(), // requestPermissions(
R.string.permission_snackbar_auth_auto_upload, // PermissionsResultCallbacks.onLocalStoragePermissionGranted(), //
Manifest.permission.READ_EXTERNAL_STORAGE, // R.string.permission_snackbar_auth_auto_upload, //
Manifest.permission.WRITE_EXTERNAL_STORAGE) Manifest.permission.READ_EXTERNAL_STORAGE, //
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
} }
@Callback @Callback
@ -106,23 +109,23 @@ class SettingsPresenter @Inject internal constructor(
fun onCheckUpdateClicked() { fun onCheckUpdateClicked() {
if (networkConnectionCheck.isPresent) { if (networkConnectionCheck.isPresent) {
updateCheckUseCase // updateCheckUseCase //
.withVersion(BuildConfig.VERSION_NAME) .withVersion(BuildConfig.VERSION_NAME)
.run(object : NoOpResultHandler<Optional<UpdateCheck?>?>() { .run(object : NoOpResultHandler<Optional<UpdateCheck?>?>() {
override fun onSuccess(result: Optional<UpdateCheck?>?) { override fun onSuccess(result: Optional<UpdateCheck?>?) {
if (result?.isPresent == true) { if (result?.isPresent == true) {
result.get()?.let { updateStatusRetrieved(it, context()) } result.get()?.let { updateStatusRetrieved(it, context()) }
} else { } else {
Timber.tag("SettingsPresenter").i("UpdateCheck finished, latest version") Timber.tag("SettingsPresenter").i("UpdateCheck finished, latest version")
Toast.makeText(context(), getString(R.string.notification_update_check_finished_latest), Toast.LENGTH_SHORT).show() Toast.makeText(context(), getString(R.string.notification_update_check_finished_latest), Toast.LENGTH_SHORT).show()
}
sharedPreferencesHandler.updateExecuted()
view?.refreshUpdateTimeView()
} }
sharedPreferencesHandler.updateExecuted()
view?.refreshUpdateTimeView()
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
showError(e) showError(e)
} }
}) })
} else { } else {
Toast.makeText(context(), R.string.error_update_no_internet, Toast.LENGTH_SHORT).show() Toast.makeText(context(), R.string.error_update_no_internet, Toast.LENGTH_SHORT).show()
} }
@ -145,21 +148,21 @@ class SettingsPresenter @Inject internal constructor(
val uri = fileUtil.contentUriForNewTempFile("cryptomator.apk") val uri = fileUtil.contentUriForNewTempFile("cryptomator.apk")
val file = fileUtil.tempFile("cryptomator.apk") val file = fileUtil.tempFile("cryptomator.apk")
updateUseCase // updateUseCase //
.withFile(file) // .withFile(file) //
.run(object : NoOpResultHandler<Void?>() { .run(object : NoOpResultHandler<Void?>() {
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
showError(e) showError(e)
} }
override fun onSuccess(result: Void?) { override fun onSuccess(result: Void?) {
super.onSuccess(result) super.onSuccess(result)
val intent = Intent(Intent.ACTION_VIEW) val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(uri, "application/vnd.android.package-archive") intent.setDataAndType(uri, "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context().startActivity(intent) context().startActivity(intent)
} }
}) })
} }
private inner class CreateErrorReportArchiveTask : AsyncTask<Void?, IOException?, File?>() { private inner class CreateErrorReportArchiveTask : AsyncTask<Void?, IOException?, File?>() {

View File

@ -32,17 +32,18 @@ import timber.log.Timber
@PerView @PerView
class SharedFilesPresenter @Inject constructor( // class SharedFilesPresenter @Inject constructor( //
private val getVaultListUseCase: GetVaultListUseCase, // private val getVaultListUseCase: GetVaultListUseCase, //
private val getRootFolderUseCase: GetRootFolderUseCase, // private val getRootFolderUseCase: GetRootFolderUseCase, //
private val getDecryptedCloudForVaultUseCase: GetDecryptedCloudForVaultUseCase, // private val getDecryptedCloudForVaultUseCase: GetDecryptedCloudForVaultUseCase, //
private val uploadFilesUseCase: UploadFilesUseCase, // private val uploadFilesUseCase: UploadFilesUseCase, //
private val getCloudListUseCase: GetCloudListUseCase, // private val getCloudListUseCase: GetCloudListUseCase, //
private val contentResolverUtil: ContentResolverUtil, // private val contentResolverUtil: ContentResolverUtil, //
private val fileCacheUtils: FileCacheUtils, // private val fileCacheUtils: FileCacheUtils, //
private val authenticationExceptionHandler: AuthenticationExceptionHandler, // private val authenticationExceptionHandler: AuthenticationExceptionHandler, //
private val cloudFolderModelMapper: CloudFolderModelMapper, // private val cloudFolderModelMapper: CloudFolderModelMapper, //
private val progressModelMapper: ProgressModelMapper, // private val progressModelMapper: ProgressModelMapper, //
exceptionMappings: ExceptionHandlers) : Presenter<SharedFilesView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<SharedFilesView>(exceptionMappings) {
private val filesForUpload: MutableSet<UploadFile> = HashSet() private val filesForUpload: MutableSet<UploadFile> = HashSet()
private val existingFilesForUpload: MutableSet<UploadFile> = HashSet() private val existingFilesForUpload: MutableSet<UploadFile> = HashSet()
@ -65,8 +66,8 @@ class SharedFilesPresenter @Inject constructor( //
} else { } else {
Timber.tag("SharedFile").i("Received 1 file") Timber.tag("SharedFile").i("Received 1 file")
contentResolverUtil.fileName(uri) contentResolverUtil.fileName(uri)
?.let { filesForUpload.add(createUploadFile(it, uri)) } ?.let { filesForUpload.add(createUploadFile(it, uri)) }
?: Timber.tag("SharedFile").i("The file doesn't have a path in the URI") ?: Timber.tag("SharedFile").i("The file doesn't have a path in the URI")
} }
} }
@ -74,8 +75,8 @@ class SharedFilesPresenter @Inject constructor( //
Timber.tag("SharedFile").i("Received %d files", uris.size) Timber.tag("SharedFile").i("Received %d files", uris.size)
uris.forEach { uri -> uris.forEach { uri ->
contentResolverUtil.fileName(uri) contentResolverUtil.fileName(uri)
?.let { filesForUpload.add(createUploadFile(it, uri)) } ?.let { filesForUpload.add(createUploadFile(it, uri)) }
?: Timber.tag("SharedFile").i("The file doesn't have a path in the URI") ?: Timber.tag("SharedFile").i("The file doesn't have a path in the URI")
} }
} }
@ -128,8 +129,9 @@ class SharedFilesPresenter @Inject constructor( //
} else { } else {
if (!isPaused) { if (!isPaused) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.vaultUnlockedSharedFiles(), // ActivityResultCallbacks.vaultUnlockedSharedFiles(), //
Intents.unlockVaultIntent().withVaultModel(VaultModel(authenticatedVault)).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK)) Intents.unlockVaultIntent().withVaultModel(VaultModel(authenticatedVault)).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK)
)
} }
} }
} }
@ -146,18 +148,18 @@ class SharedFilesPresenter @Inject constructor( //
private fun decryptedCloudFor(vault: Vault) { private fun decryptedCloudFor(vault: Vault) {
getDecryptedCloudForVaultUseCase // getDecryptedCloudForVaultUseCase //
.withVault(vault) // .withVault(vault) //
.run(object : DefaultResultHandler<Cloud>() { .run(object : DefaultResultHandler<Cloud>() {
override fun onSuccess(cloud: Cloud) { override fun onSuccess(cloud: Cloud) {
rootFolderFor(cloud) rootFolderFor(cloud)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (!authenticationExceptionHandler.handleAuthenticationException(this@SharedFilesPresenter, e, ActivityResultCallbacks.decryptedCloudForAfterAuth(vault))) { if (!authenticationExceptionHandler.handleAuthenticationException(this@SharedFilesPresenter, e, ActivityResultCallbacks.decryptedCloudForAfterAuth(vault))) {
super.onError(e) super.onError(e)
}
} }
}) }
})
} }
@Callback @Callback
@ -168,18 +170,18 @@ class SharedFilesPresenter @Inject constructor( //
private fun rootFolderFor(cloud: Cloud) { private fun rootFolderFor(cloud: Cloud) {
getRootFolderUseCase // getRootFolderUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<CloudFolder>() { .run(object : DefaultResultHandler<CloudFolder>() {
override fun onSuccess(folder: CloudFolder) { override fun onSuccess(folder: CloudFolder) {
when (authenticationState) { when (authenticationState) {
AuthenticationState.CHOOSE_LOCATION -> navigateToVaultContent((folder.cloud as CryptoCloud).vault, folder) AuthenticationState.CHOOSE_LOCATION -> navigateToVaultContent((folder.cloud as CryptoCloud).vault, folder)
AuthenticationState.INIT_ROOT -> { AuthenticationState.INIT_ROOT -> {
location = cloudFolderModelMapper.toModel(folder) location = cloudFolderModelMapper.toModel(folder)
checkForUsedFileNames(folder) checkForUsedFileNames(folder)
}
} }
} }
}) }
})
} }
private fun navigateToVaultContent(vault: Vault, folder: CloudFolder) { private fun navigateToVaultContent(vault: Vault, folder: CloudFolder) {
@ -192,9 +194,11 @@ class SharedFilesPresenter @Inject constructor( //
this.location = location this.location = location
} }
private fun uploadFiles(nonReplacing: Set<UploadFile>, // private fun uploadFiles(
replacing: Set<UploadFile>, // nonReplacing: Set<UploadFile>, //
folder: CloudFolder) { replacing: Set<UploadFile>, //
folder: CloudFolder
) {
if (nonReplacing.size + replacing.size == 0) { if (nonReplacing.size + replacing.size == 0) {
view?.finish() view?.finish()
} }
@ -207,17 +211,17 @@ class SharedFilesPresenter @Inject constructor( //
private fun uploadFiles(folder: CloudFolder, files: List<UploadFile>) { private fun uploadFiles(folder: CloudFolder, files: List<UploadFile>) {
uploadFilesUseCase // uploadFilesUseCase //
.withParent(folder) // .withParent(folder) //
.andFiles(files) // .andFiles(files) //
.run(object : DefaultProgressAwareResultHandler<List<CloudFile>, UploadState>() { .run(object : DefaultProgressAwareResultHandler<List<CloudFile>, UploadState>() {
override fun onProgress(progress: Progress<UploadState>) { override fun onProgress(progress: Progress<UploadState>) {
view?.showProgress(progressModelMapper.toModel(progress)) view?.showProgress(progressModelMapper.toModel(progress))
} }
override fun onFinished() { override fun onFinished() {
onFileUploadCompleted() onFileUploadCompleted()
} }
}) })
} }
private fun onFileUploadCompleted() { private fun onFileUploadCompleted() {
@ -248,12 +252,12 @@ class SharedFilesPresenter @Inject constructor( //
private fun checkForUsedFileNames(folder: CloudFolder) { private fun checkForUsedFileNames(folder: CloudFolder) {
view?.showProgress(ProgressModel.GENERIC) view?.showProgress(ProgressModel.GENERIC)
getCloudListUseCase // getCloudListUseCase //
.withFolder(folder) // .withFolder(folder) //
.run(object : DefaultResultHandler<List<CloudNode>>() { .run(object : DefaultResultHandler<List<CloudNode>>() {
override fun onSuccess(currentCloudNodes: List<CloudNode>) { override fun onSuccess(currentCloudNodes: List<CloudNode>) {
checkForExistingFilesOrUploadFiles(folder, currentCloudNodes) checkForExistingFilesOrUploadFiles(folder, currentCloudNodes)
} }
}) })
} }
private fun hasUsedFileNamesAtLocation(currentCloudNodes: List<CloudNode>): Boolean { private fun hasUsedFileNamesAtLocation(currentCloudNodes: List<CloudNode>): Boolean {
@ -264,9 +268,10 @@ class SharedFilesPresenter @Inject constructor( //
if (cloudNode is CloudFile) { if (cloudNode is CloudFile) {
filesForUpload.remove(uploadFileWithName.get()) filesForUpload.remove(uploadFileWithName.get())
existingFilesForUpload.add( // existingFilesForUpload.add( //
UploadFile.aCopyOf(uploadFileWithName.get()) // UploadFile.aCopyOf(uploadFileWithName.get()) //
.thatIsReplacing(true) // .thatIsReplacing(true) //
.build()) .build()
)
} else { } else {
// remove file when name is used by a folder // remove file when name is used by a folder
filesForUpload.remove(uploadFileWithName.get()) filesForUpload.remove(uploadFileWithName.get())
@ -278,9 +283,9 @@ class SharedFilesPresenter @Inject constructor( //
private fun fileForUploadWithName(name: String): Optional<UploadFile> { private fun fileForUploadWithName(name: String): Optional<UploadFile> {
return filesForUpload return filesForUpload
.firstOrNull { it.fileName == name } .firstOrNull { it.fileName == name }
?.let { Optional.of(it) } ?.let { Optional.of(it) }
?: Optional.empty() ?: Optional.empty()
} }
private fun checkForExistingFilesOrUploadFiles(folder: CloudFolder, currentCloudNodes: List<CloudNode>) { private fun checkForExistingFilesOrUploadFiles(folder: CloudFolder, currentCloudNodes: List<CloudNode>) {
@ -297,7 +302,7 @@ class SharedFilesPresenter @Inject constructor( //
private fun prepareSavingFiles() { private fun prepareSavingFiles() {
location?.let { checkForUsedFileNames(it.toCloudNode()) } location?.let { checkForUsedFileNames(it.toCloudNode()) }
?: authenticate(selectedVault, AuthenticationState.INIT_ROOT) ?: authenticate(selectedVault, AuthenticationState.INIT_ROOT)
} }
fun onSaveButtonPressed(filesForUpload: List<SharedFileModel>) { fun onSaveButtonPressed(filesForUpload: List<SharedFileModel>) {
@ -310,9 +315,11 @@ class SharedFilesPresenter @Inject constructor( //
view?.showMessage(R.string.error_names_contains_invalid_characters) view?.showMessage(R.string.error_names_contains_invalid_characters)
} }
else -> { else -> {
requestPermissions(PermissionsResultCallbacks.saveFilesPermissionCallback(), // requestPermissions(
R.string.permission_message_share_file, // PermissionsResultCallbacks.saveFilesPermissionCallback(), //
Manifest.permission.READ_EXTERNAL_STORAGE) R.string.permission_message_share_file, //
Manifest.permission.READ_EXTERNAL_STORAGE
)
} }
} }
} }
@ -335,17 +342,19 @@ class SharedFilesPresenter @Inject constructor( //
private fun navigateToVaultContent(vaultModel: VaultModel, decryptedRoot: CloudFolderModel) { private fun navigateToVaultContent(vaultModel: VaultModel, decryptedRoot: CloudFolderModel) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.onChooseLocation(vaultModel), // ActivityResultCallbacks.onChooseLocation(vaultModel), //
Intents.browseFilesIntent() // Intents.browseFilesIntent() //
.withFolder(decryptedRoot) // .withFolder(decryptedRoot) //
.withTitle(vaultModel.name) // .withTitle(vaultModel.name) //
.withChooseCloudNodeSettings( // .withChooseCloudNodeSettings( //
ChooseCloudNodeSettings.chooseCloudNodeSettings() // ChooseCloudNodeSettings.chooseCloudNodeSettings() //
.withExtraTitle(context().getString(R.string.screen_file_browser_share_destination_title)) // .withExtraTitle(context().getString(R.string.screen_file_browser_share_destination_title)) //
.withExtraToolbarIcon(R.drawable.ic_clear) // .withExtraToolbarIcon(R.drawable.ic_clear) //
.withButtonText(context().getString(R.string.screen_file_browser_share_button_text)) // .withButtonText(context().getString(R.string.screen_file_browser_share_button_text)) //
.selectingFolders() // .selectingFolders() //
.build())) .build()
)
)
} }
@Callback @Callback
@ -396,18 +405,19 @@ class SharedFilesPresenter @Inject constructor( //
private fun createUploadFile(fileName: String, uri: Uri): UploadFile { private fun createUploadFile(fileName: String, uri: Uri): UploadFile {
return UploadFile.anUploadFile() // return UploadFile.anUploadFile() //
.withFileName(fileName) // .withFileName(fileName) //
.withDataSource(UriBasedDataSource.from(uri)) // .withDataSource(UriBasedDataSource.from(uri)) //
.thatIsReplacing(false) // .thatIsReplacing(false) //
.build() .build()
} }
init { init {
unsubscribeOnDestroy( // unsubscribeOnDestroy( //
getRootFolderUseCase, // getRootFolderUseCase, //
getVaultListUseCase, // getVaultListUseCase, //
getDecryptedCloudForVaultUseCase, // getDecryptedCloudForVaultUseCase, //
uploadFilesUseCase, // uploadFilesUseCase, //
getCloudListUseCase) getCloudListUseCase
)
} }
} }

View File

@ -21,11 +21,12 @@ import javax.inject.Inject
@PerView @PerView
class TextEditorPresenter @Inject constructor( // class TextEditorPresenter @Inject constructor( //
private val fileCacheUtils: FileCacheUtils, // private val fileCacheUtils: FileCacheUtils, //
private val fileUtil: FileUtil, // private val fileUtil: FileUtil, //
private val contentResolverUtil: ContentResolverUtil, // private val contentResolverUtil: ContentResolverUtil, //
private val uploadFilesUseCase: UploadFilesUseCase, // private val uploadFilesUseCase: UploadFilesUseCase, //
exceptionMappings: ExceptionHandlers) : Presenter<TextEditorView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<TextEditorView>(exceptionMappings) {
private val textFile = AtomicReference<CloudFileModel>() private val textFile = AtomicReference<CloudFileModel>()
@ -64,34 +65,36 @@ class TextEditorPresenter @Inject constructor( //
view?.let { view?.let {
it.showProgress(ProgressModel.GENERIC) it.showProgress(ProgressModel.GENERIC)
val uri = fileCacheUtils.tmpFile() // val uri = fileCacheUtils.tmpFile() //
.withContent(it.textFileContent) // .withContent(it.textFileContent) //
.create() .create()
uploadFile(textFile.get().name, UriBasedDataSource.from(uri)) uploadFile(textFile.get().name, UriBasedDataSource.from(uri))
} }
} }
private fun uploadFile(fileName: String, dataSource: DataSource) { private fun uploadFile(fileName: String, dataSource: DataSource) {
uploadFilesUseCase // uploadFilesUseCase //
.withParent(textFile.get().parent.toCloudNode()) // .withParent(textFile.get().parent.toCloudNode()) //
.andFiles(listOf( // .andFiles(
UploadFile.anUploadFile() // listOf( //
.withFileName(fileName) // UploadFile.anUploadFile() //
.withDataSource(dataSource) // .withFileName(fileName) //
.thatIsReplacing(true) // .withDataSource(dataSource) //
.build() // .thatIsReplacing(true) //
)) // .build() //
.run(object : DefaultProgressAwareResultHandler<List<CloudFile?>, UploadState>() { )
override fun onFinished() { ) //
view?.showProgress(ProgressModel.COMPLETED) .run(object : DefaultProgressAwareResultHandler<List<CloudFile?>, UploadState>() {
view?.finish() override fun onFinished() {
view?.showMessage(R.string.screen_text_editor_save_success) view?.showProgress(ProgressModel.COMPLETED)
} view?.finish()
view?.showMessage(R.string.screen_text_editor_save_success)
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
view?.showProgress(ProgressModel.COMPLETED) view?.showProgress(ProgressModel.COMPLETED)
showError(e) showError(e)
} }
}) })
} }
fun loadFileContent() { fun loadFileContent() {

View File

@ -40,17 +40,18 @@ import timber.log.Timber
@PerView @PerView
class UnlockVaultPresenter @Inject constructor( class UnlockVaultPresenter @Inject constructor(
private val changePasswordUseCase: ChangePasswordUseCase, private val changePasswordUseCase: ChangePasswordUseCase,
private val deleteVaultUseCase: DeleteVaultUseCase, private val deleteVaultUseCase: DeleteVaultUseCase,
private val getUnverifiedVaultConfigUseCase: GetUnverifiedVaultConfigUseCase, private val getUnverifiedVaultConfigUseCase: GetUnverifiedVaultConfigUseCase,
private val lockVaultUseCase: LockVaultUseCase, private val lockVaultUseCase: LockVaultUseCase,
private val unlockVaultUsingMasterkeyUseCase: UnlockVaultUsingMasterkeyUseCase, private val unlockVaultUsingMasterkeyUseCase: UnlockVaultUsingMasterkeyUseCase,
private val prepareUnlockUseCase: PrepareUnlockUseCase, private val prepareUnlockUseCase: PrepareUnlockUseCase,
private val removeStoredVaultPasswordsUseCase: RemoveStoredVaultPasswordsUseCase, private val removeStoredVaultPasswordsUseCase: RemoveStoredVaultPasswordsUseCase,
private val saveVaultUseCase: SaveVaultUseCase, private val saveVaultUseCase: SaveVaultUseCase,
private val authenticationExceptionHandler: AuthenticationExceptionHandler, private val authenticationExceptionHandler: AuthenticationExceptionHandler,
private val sharedPreferencesHandler: SharedPreferencesHandler, private val sharedPreferencesHandler: SharedPreferencesHandler,
exceptionMappings: ExceptionHandlers) : Presenter<UnlockVaultView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<UnlockVaultView>(exceptionMappings) {
private var startedUsingPrepareUnlock = false private var startedUsingPrepareUnlock = false
private var retryUnlockHandler: Handler? = null private var retryUnlockHandler: Handler? = null
@ -77,27 +78,27 @@ class UnlockVaultPresenter @Inject constructor(
} }
getUnverifiedVaultConfigUseCase getUnverifiedVaultConfigUseCase
.withVault(intent.vaultModel().toVault()) .withVault(intent.vaultModel().toVault())
.run(object : DefaultResultHandler<Optional<UnverifiedVaultConfig>>() { .run(object : DefaultResultHandler<Optional<UnverifiedVaultConfig>>() {
override fun onSuccess(unverifiedVaultConfig: Optional<UnverifiedVaultConfig>) { override fun onSuccess(unverifiedVaultConfig: Optional<UnverifiedVaultConfig>) {
if (unverifiedVaultConfig.isAbsent || unverifiedVaultConfig.get().keyId.scheme == CryptoConstants.MASTERKEY_SCHEME) { if (unverifiedVaultConfig.isAbsent || unverifiedVaultConfig.get().keyId.scheme == CryptoConstants.MASTERKEY_SCHEME) {
when (intent.vaultAction()) { when (intent.vaultAction()) {
UnlockVaultIntent.VaultAction.UNLOCK, UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH -> { UnlockVaultIntent.VaultAction.UNLOCK, UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH -> {
startedUsingPrepareUnlock = sharedPreferencesHandler.backgroundUnlockPreparation() startedUsingPrepareUnlock = sharedPreferencesHandler.backgroundUnlockPreparation()
pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig = unverifiedVaultConfig.orElse(null) pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig = unverifiedVaultConfig.orElse(null)
unlockVault(intent.vaultModel()) unlockVault(intent.vaultModel())
}
UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> view?.showChangePasswordDialog(intent.vaultModel(), unverifiedVaultConfig.orElse(null))
else -> TODO("Not yet implemented")
} }
UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> view?.showChangePasswordDialog(intent.vaultModel(), unverifiedVaultConfig.orElse(null))
else -> TODO("Not yet implemented")
} }
} }
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
super.onError(e) super.onError(e)
finishWithResult(null) finishWithResult(null)
} }
}) })
} }
private fun unlockVault(vaultModel: VaultModel) { private fun unlockVault(vaultModel: VaultModel) {
@ -134,8 +135,8 @@ class UnlockVaultPresenter @Inject constructor(
private fun canUseBiometricOn(vault: VaultModel): Boolean { private fun canUseBiometricOn(vault: VaultModel): Boolean {
return vault.password != null && BiometricManager // return vault.password != null && BiometricManager //
.from(context()) // .from(context()) //
.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS
} }
fun onUnlockCanceled() { fun onUnlockCanceled() {
@ -146,31 +147,31 @@ class UnlockVaultPresenter @Inject constructor(
fun startPrepareUnlockUseCase(vault: Vault) { fun startPrepareUnlockUseCase(vault: Vault) {
prepareUnlockUseCase // prepareUnlockUseCase //
.withVault(vault) // .withVault(vault) //
.andUnverifiedVaultConfig(Optional.ofNullable(pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig)) .andUnverifiedVaultConfig(Optional.ofNullable(pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig))
.run(object : DefaultResultHandler<UnlockToken>() { .run(object : DefaultResultHandler<UnlockToken>() {
override fun onSuccess(unlockToken: UnlockToken) { override fun onSuccess(unlockToken: UnlockToken) {
if (!startedUsingPrepareUnlock && vault.password != null) { if (!startedUsingPrepareUnlock && vault.password != null) {
doUnlock(unlockToken, vault.password, pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig) doUnlock(unlockToken, vault.password, pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig)
} else { } else {
unlockTokenObtained(unlockToken) unlockTokenObtained(unlockToken)
}
} }
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (e is AuthenticationException) { if (e is AuthenticationException) {
view?.cancelBasicAuthIfRunning() view?.cancelBasicAuthIfRunning()
} }
if (!authenticationExceptionHandler.handleAuthenticationException(this@UnlockVaultPresenter, e, ActivityResultCallbacks.authenticatedAfterUnlock(vault))) { if (!authenticationExceptionHandler.handleAuthenticationException(this@UnlockVaultPresenter, e, ActivityResultCallbacks.authenticatedAfterUnlock(vault))) {
super.onError(e) super.onError(e)
if (e is NetworkConnectionException) { if (e is NetworkConnectionException) {
running = true running = true
retryUnlockHandler = Handler() retryUnlockHandler = Handler()
restartUnlockUseCase(vault) restartUnlockUseCase(vault)
}
} }
} }
}) }
})
} }
@Callback(dispatchResultOkOnly = false) @Callback(dispatchResultOkOnly = false)
@ -197,22 +198,22 @@ class UnlockVaultPresenter @Inject constructor(
retryUnlockHandler?.postDelayed({ retryUnlockHandler?.postDelayed({
if (running) { if (running) {
prepareUnlockUseCase // prepareUnlockUseCase //
.withVault(vault) // .withVault(vault) //
.run(object : DefaultResultHandler<UnlockToken>() { .run(object : DefaultResultHandler<UnlockToken>() {
override fun onSuccess(unlockToken: UnlockToken) { override fun onSuccess(unlockToken: UnlockToken) {
if (!startedUsingPrepareUnlock && vault.password != null) { if (!startedUsingPrepareUnlock && vault.password != null) {
doUnlock(unlockToken, vault.password, pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig) doUnlock(unlockToken, vault.password, pendingUnlockFor(intent.vaultModel().toVault())?.unverifiedVaultConfig)
} else { } else {
unlockTokenObtained(unlockToken) unlockTokenObtained(unlockToken)
}
} }
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (e is NetworkConnectionException) { if (e is NetworkConnectionException) {
restartUnlockUseCase(vault) restartUnlockUseCase(vault)
}
} }
}) }
})
} }
}, 1000) }, 1000)
} }
@ -228,28 +229,28 @@ class UnlockVaultPresenter @Inject constructor(
private fun doUnlock(token: UnlockToken, password: String, unverifiedVaultConfig: UnverifiedVaultConfig?) { private fun doUnlock(token: UnlockToken, password: String, unverifiedVaultConfig: UnverifiedVaultConfig?) {
unlockVaultUsingMasterkeyUseCase // unlockVaultUsingMasterkeyUseCase //
.withVaultOrUnlockToken(VaultOrUnlockToken.from(token)) // .withVaultOrUnlockToken(VaultOrUnlockToken.from(token)) //
.andUnverifiedVaultConfig(Optional.ofNullable(unverifiedVaultConfig)) // .andUnverifiedVaultConfig(Optional.ofNullable(unverifiedVaultConfig)) //
.andPassword(password) // .andPassword(password) //
.run(object : DefaultResultHandler<Cloud>() { .run(object : DefaultResultHandler<Cloud>() {
override fun onSuccess(cloud: Cloud) { override fun onSuccess(cloud: Cloud) {
when (intent.vaultAction()) { when (intent.vaultAction()) {
UnlockVaultIntent.VaultAction.ENCRYPT_PASSWORD, UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH -> { UnlockVaultIntent.VaultAction.ENCRYPT_PASSWORD, UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH -> {
handleUnlockVaultSuccess(token.vault, cloud, password) handleUnlockVaultSuccess(token.vault, cloud, password)
}
UnlockVaultIntent.VaultAction.UNLOCK -> finishWithResult(cloud)
else -> TODO("Not yet implemented")
} }
UnlockVaultIntent.VaultAction.UNLOCK -> finishWithResult(cloud)
else -> TODO("Not yet implemented")
} }
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
super.onError(e) super.onError(e)
// finish in case of biometric auth, otherwise show error in dialog // finish in case of biometric auth, otherwise show error in dialog
if(view?.isShowingDialog(EnterPasswordDialog::class) == false) { if (view?.isShowingDialog(EnterPasswordDialog::class) == false) {
finishWithResult(null) finishWithResult(null)
}
} }
}) }
})
} }
private fun handleUnlockVaultSuccess(vault: Vault, cloud: Cloud, password: String) { private fun handleUnlockVaultSuccess(vault: Vault, cloud: Cloud, password: String) {
@ -295,12 +296,12 @@ class UnlockVaultPresenter @Inject constructor(
} }
UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> { UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> {
saveVaultUseCase // saveVaultUseCase //
.withVault(vaultModel.toVault()) // .withVault(vaultModel.toVault()) //
.run(object : DefaultResultHandler<Vault>() { .run(object : DefaultResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
finishWithResult(vaultModel) finishWithResult(vaultModel)
} }
}) })
} }
else -> TODO("Not yet implemented") else -> TODO("Not yet implemented")
} }
@ -309,31 +310,36 @@ class UnlockVaultPresenter @Inject constructor(
fun onChangePasswordClick(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedVaultConfig?, oldPassword: String, newPassword: String) { fun onChangePasswordClick(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedVaultConfig?, oldPassword: String, newPassword: String) {
view?.showProgress(ProgressModel(ProgressStateModel.CHANGING_PASSWORD)) view?.showProgress(ProgressModel(ProgressStateModel.CHANGING_PASSWORD))
changePasswordUseCase.withVault(vaultModel.toVault()) // changePasswordUseCase.withVault(vaultModel.toVault()) //
.andUnverifiedVaultConfig(Optional.ofNullable(unverifiedVaultConfig)) // .andUnverifiedVaultConfig(Optional.ofNullable(unverifiedVaultConfig)) //
.andOldPassword(oldPassword) // .andOldPassword(oldPassword) //
.andNewPassword(newPassword) // .andNewPassword(newPassword) //
.run(object : DefaultResultHandler<Void?>() { .run(object : DefaultResultHandler<Void?>() {
override fun onSuccess(void: Void?) { override fun onSuccess(void: Void?) {
view?.showProgress(ProgressModel.COMPLETED) view?.showProgress(ProgressModel.COMPLETED)
view?.showMessage(R.string.screen_vault_list_change_password_successful) view?.showMessage(R.string.screen_vault_list_change_password_successful)
if (canUseBiometricOn(vaultModel)) { if (canUseBiometricOn(vaultModel)) {
view?.getEncryptedPasswordWithBiometricAuthentication(VaultModel( // view?.getEncryptedPasswordWithBiometricAuthentication(
Vault.aCopyOf(vaultModel.toVault()) // VaultModel( //
.withSavedPassword(newPassword) // Vault.aCopyOf(vaultModel.toVault()) //
.build())) .withSavedPassword(newPassword) //
} else { .build()
finishWithResult(vaultModel) )
} )
} else {
finishWithResult(vaultModel)
} }
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (!authenticationExceptionHandler.handleAuthenticationException( // if (!authenticationExceptionHandler.handleAuthenticationException( //
this@UnlockVaultPresenter, e, // this@UnlockVaultPresenter, e, //
ActivityResultCallbacks.changePasswordAfterAuthentication(vaultModel.toVault(), unverifiedVaultConfig, oldPassword, newPassword))) { ActivityResultCallbacks.changePasswordAfterAuthentication(vaultModel.toVault(), unverifiedVaultConfig, oldPassword, newPassword)
showError(e) )
} ) {
showError(e)
} }
}) }
})
} }
@Callback @Callback
@ -346,22 +352,22 @@ class UnlockVaultPresenter @Inject constructor(
fun saveVaultAfterChangePasswordButFailedBiometricAuth(vault: Vault) { fun saveVaultAfterChangePasswordButFailedBiometricAuth(vault: Vault) {
Timber.tag("UnlockVaultPresenter").e("Save vault without password because biometric auth failed after changing vault password") Timber.tag("UnlockVaultPresenter").e("Save vault without password because biometric auth failed after changing vault password")
saveVaultUseCase // saveVaultUseCase //
.withVault(vault) // .withVault(vault) //
.run(object : DefaultResultHandler<Vault>() { .run(object : DefaultResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
finishWithResult(vault) finishWithResult(vault)
} }
}) })
} }
fun onDeleteMissingVaultClicked(vault: Vault) { fun onDeleteMissingVaultClicked(vault: Vault) {
deleteVaultUseCase // deleteVaultUseCase //
.withVault(vault) // .withVault(vault) //
.run(object : DefaultResultHandler<Long>() { .run(object : DefaultResultHandler<Long>() {
override fun onSuccess(vaultId: Long) { override fun onSuccess(vaultId: Long) {
finishWithResult(null) finishWithResult(null)
} }
}) })
} }
fun onCancelMissingVaultClicked(vault: Vault) { fun onCancelMissingVaultClicked(vault: Vault) {
@ -410,14 +416,15 @@ class UnlockVaultPresenter @Inject constructor(
init { init {
unsubscribeOnDestroy( // unsubscribeOnDestroy( //
changePasswordUseCase, // changePasswordUseCase, //
deleteVaultUseCase, // deleteVaultUseCase, //
getUnverifiedVaultConfigUseCase, // getUnverifiedVaultConfigUseCase, //
lockVaultUseCase, // lockVaultUseCase, //
unlockVaultUsingMasterkeyUseCase, // unlockVaultUsingMasterkeyUseCase, //
prepareUnlockUseCase, // prepareUnlockUseCase, //
removeStoredVaultPasswordsUseCase, // removeStoredVaultPasswordsUseCase, //
saveVaultUseCase) saveVaultUseCase
)
} }
} }

View File

@ -61,25 +61,26 @@ import timber.log.Timber
@PerView @PerView
class VaultListPresenter @Inject constructor( // class VaultListPresenter @Inject constructor( //
private val getVaultListUseCase: GetVaultListUseCase, // private val getVaultListUseCase: GetVaultListUseCase, //
private val deleteVaultUseCase: DeleteVaultUseCase, // private val deleteVaultUseCase: DeleteVaultUseCase, //
private val renameVaultUseCase: RenameVaultUseCase, // private val renameVaultUseCase: RenameVaultUseCase, //
private val lockVaultUseCase: LockVaultUseCase, // private val lockVaultUseCase: LockVaultUseCase, //
private val getDecryptedCloudForVaultUseCase: GetDecryptedCloudForVaultUseCase, // private val getDecryptedCloudForVaultUseCase: GetDecryptedCloudForVaultUseCase, //
private val getRootFolderUseCase: GetRootFolderUseCase, // private val getRootFolderUseCase: GetRootFolderUseCase, //
private val addExistingVaultWorkflow: AddExistingVaultWorkflow, // private val addExistingVaultWorkflow: AddExistingVaultWorkflow, //
private val createNewVaultWorkflow: CreateNewVaultWorkflow, // private val createNewVaultWorkflow: CreateNewVaultWorkflow, //
private val saveVaultUseCase: SaveVaultUseCase, // private val saveVaultUseCase: SaveVaultUseCase, //
private val moveVaultPositionUseCase: MoveVaultPositionUseCase, // private val moveVaultPositionUseCase: MoveVaultPositionUseCase, //
private val licenseCheckUseCase: DoLicenseCheckUseCase, // private val licenseCheckUseCase: DoLicenseCheckUseCase, //
private val updateCheckUseCase: DoUpdateCheckUseCase, // private val updateCheckUseCase: DoUpdateCheckUseCase, //
private val updateUseCase: DoUpdateUseCase, // private val updateUseCase: DoUpdateUseCase, //
private val networkConnectionCheck: NetworkConnectionCheck, // private val networkConnectionCheck: NetworkConnectionCheck, //
private val fileUtil: FileUtil, // private val fileUtil: FileUtil, //
private val authenticationExceptionHandler: AuthenticationExceptionHandler, // private val authenticationExceptionHandler: AuthenticationExceptionHandler, //
private val cloudFolderModelMapper: CloudFolderModelMapper, // private val cloudFolderModelMapper: CloudFolderModelMapper, //
private val sharedPreferencesHandler: SharedPreferencesHandler, // private val sharedPreferencesHandler: SharedPreferencesHandler, //
exceptionMappings: ExceptionHandlers) : Presenter<VaultListView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<VaultListView>(exceptionMappings) {
private var vaultAction: VaultAction? = null private var vaultAction: VaultAction? = null
@ -107,56 +108,56 @@ class VaultListPresenter @Inject constructor( //
private fun checkLicense() { private fun checkLicense() {
if (BuildConfig.FLAVOR == "apkstore" || BuildConfig.FLAVOR == "fdroid") { if (BuildConfig.FLAVOR == "apkstore" || BuildConfig.FLAVOR == "fdroid") {
licenseCheckUseCase // licenseCheckUseCase //
.withLicense("") // .withLicense("") //
.run(object : NoOpResultHandler<LicenseCheck>() { .run(object : NoOpResultHandler<LicenseCheck>() {
override fun onSuccess(licenseCheck: LicenseCheck) { override fun onSuccess(licenseCheck: LicenseCheck) {
if (BuildConfig.FLAVOR == "apkstore" && sharedPreferencesHandler.doUpdate()) { if (BuildConfig.FLAVOR == "apkstore" && sharedPreferencesHandler.doUpdate()) {
checkForAppUpdates() checkForAppUpdates()
}
} }
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
var license: String? = "" var license: String? = ""
if (e is LicenseNotValidException) { if (e is LicenseNotValidException) {
license = e.license license = e.license
}
val intent = Intent(context(), LicenseCheckActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intent.data = Uri.parse(String.format("app://cryptomator/%s", license))
try {
context().startActivity(intent)
} catch (e: ActivityNotFoundException) {
Toast.makeText(context(), "Please contact the support.", Toast.LENGTH_LONG).show()
finish()
}
} }
}) val intent = Intent(context(), LicenseCheckActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intent.data = Uri.parse(String.format("app://cryptomator/%s", license))
try {
context().startActivity(intent)
} catch (e: ActivityNotFoundException) {
Toast.makeText(context(), "Please contact the support.", Toast.LENGTH_LONG).show()
finish()
}
}
})
} }
} }
private fun checkForAppUpdates() { private fun checkForAppUpdates() {
if (networkConnectionCheck.isPresent) { if (networkConnectionCheck.isPresent) {
updateCheckUseCase // updateCheckUseCase //
.withVersion(BuildConfig.VERSION_NAME) // .withVersion(BuildConfig.VERSION_NAME) //
.run(object : NoOpResultHandler<Optional<UpdateCheck>>() { .run(object : NoOpResultHandler<Optional<UpdateCheck>>() {
override fun onSuccess(updateCheck: Optional<UpdateCheck>) { override fun onSuccess(updateCheck: Optional<UpdateCheck>) {
if (updateCheck.isPresent) { if (updateCheck.isPresent) {
updateStatusRetrieved(updateCheck.get(), context()) updateStatusRetrieved(updateCheck.get(), context())
} else { } else {
Timber.tag("VaultListPresenter").i("UpdateCheck finished, latest version") Timber.tag("VaultListPresenter").i("UpdateCheck finished, latest version")
}
sharedPreferencesHandler.updateExecuted()
} }
sharedPreferencesHandler.updateExecuted()
}
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (e is SSLHandshakePreAndroid5UpdateCheckException) { if (e is SSLHandshakePreAndroid5UpdateCheckException) {
Timber.tag("SettingsPresenter").e(e, "Update check failed due to Android pre 5 and SSL Handshake not accepted") Timber.tag("SettingsPresenter").e(e, "Update check failed due to Android pre 5 and SSL Handshake not accepted")
} else { } else {
showError(e) showError(e)
}
} }
}) }
})
} else { } else {
Timber.tag("VaultListPresenter").i("Update check not started due to no internal connection") Timber.tag("VaultListPresenter").i("Update check not started due to no internal connection")
} }
@ -193,32 +194,34 @@ class VaultListPresenter @Inject constructor( //
fun deleteVault(vaultModel: VaultModel) { fun deleteVault(vaultModel: VaultModel) {
deleteVaultUseCase // deleteVaultUseCase //
.withVault(vaultModel.toVault()) // .withVault(vaultModel.toVault()) //
.run(object : DefaultResultHandler<Long>() { .run(object : DefaultResultHandler<Long>() {
override fun onSuccess(vaultId: Long) { override fun onSuccess(vaultId: Long) {
view?.deleteVaultFromAdapter(vaultId) view?.deleteVaultFromAdapter(vaultId)
} }
}) })
} }
fun renameVault(vaultModel: VaultModel, newVaultName: String?) { fun renameVault(vaultModel: VaultModel, newVaultName: String?) {
renameVaultUseCase // renameVaultUseCase //
.withVault(vaultModel.toVault()) // .withVault(vaultModel.toVault()) //
.andNewVaultName(newVaultName) // .andNewVaultName(newVaultName) //
.run(object : DefaultResultHandler<Vault>() { .run(object : DefaultResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
view?.renameVault(VaultModel(vault)) view?.renameVault(VaultModel(vault))
view?.closeDialog() view?.closeDialog()
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (!authenticationExceptionHandler.handleAuthenticationException( // if (!authenticationExceptionHandler.handleAuthenticationException( //
this@VaultListPresenter, e, // this@VaultListPresenter, e, //
ActivityResultCallbacks.renameVaultAfterAuthentication(vaultModel.toVault(), newVaultName))) { ActivityResultCallbacks.renameVaultAfterAuthentication(vaultModel.toVault(), newVaultName)
showError(e) )
} ) {
showError(e)
} }
}) }
})
} }
@Callback @Callback
@ -230,32 +233,32 @@ class VaultListPresenter @Inject constructor( //
private fun browseFilesOf(vault: VaultModel) { private fun browseFilesOf(vault: VaultModel) {
getDecryptedCloudForVaultUseCase // getDecryptedCloudForVaultUseCase //
.withVault(vault.toVault()) // .withVault(vault.toVault()) //
.run(object : DefaultResultHandler<Cloud>() { .run(object : DefaultResultHandler<Cloud>() {
override fun onSuccess(cloud: Cloud) { override fun onSuccess(cloud: Cloud) {
getRootFolderAndNavigateInto(cloud) getRootFolderAndNavigateInto(cloud)
} }
}) })
} }
private fun getRootFolderAndNavigateInto(cloud: Cloud) { private fun getRootFolderAndNavigateInto(cloud: Cloud) {
getRootFolderUseCase // getRootFolderUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<CloudFolder>() { .run(object : DefaultResultHandler<CloudFolder>() {
override fun onSuccess(folder: CloudFolder) { override fun onSuccess(folder: CloudFolder) {
navigateToVaultContent((folder.cloud as CryptoCloud).vault, folder) navigateToVaultContent((folder.cloud as CryptoCloud).vault, folder)
} }
}) })
} }
private fun lockVault(vaultModel: VaultModel) { private fun lockVault(vaultModel: VaultModel) {
lockVaultUseCase // lockVaultUseCase //
.withVault(vaultModel.toVault()) // .withVault(vaultModel.toVault()) //
.run(object : DefaultResultHandler<Vault>() { .run(object : DefaultResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
view?.addOrUpdateVault(VaultModel(vault)) view?.addOrUpdateVault(VaultModel(vault))
} }
}) })
} }
private val vaultList: Unit private val vaultList: Unit
@ -297,12 +300,12 @@ class VaultListPresenter @Inject constructor( //
onVaultWithoutCloudClickedAndLocked(vault) onVaultWithoutCloudClickedAndLocked(vault)
} else { } else {
lockVaultUseCase // lockVaultUseCase //
.withVault(vault.toVault()) // .withVault(vault.toVault()) //
.run(object : DefaultResultHandler<Vault>() { .run(object : DefaultResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
onVaultWithoutCloudClickedAndLocked(VaultModel(vault)) onVaultWithoutCloudClickedAndLocked(VaultModel(vault))
} }
}) })
} }
} }
} }
@ -310,11 +313,12 @@ class VaultListPresenter @Inject constructor( //
private fun onVaultWithoutCloudClickedAndLocked(vault: VaultModel) { private fun onVaultWithoutCloudClickedAndLocked(vault: VaultModel) {
if (isWebdavOrLocal(vault.cloudType)) { if (isWebdavOrLocal(vault.cloudType)) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.cloudConnectionForVaultSelected(vault), // ActivityResultCallbacks.cloudConnectionForVaultSelected(vault), //
Intents.cloudConnectionListIntent() // Intents.cloudConnectionListIntent() //
.withCloudType(vault.cloudType) // .withCloudType(vault.cloudType) //
.withDialogTitle(context().getString(R.string.screen_cloud_connections_title)) // .withDialogTitle(context().getString(R.string.screen_cloud_connections_title)) //
.withFinishOnCloudItemClick(true)) .withFinishOnCloudItemClick(true)
)
} }
} }
@ -326,16 +330,16 @@ class VaultListPresenter @Inject constructor( //
fun cloudConnectionForVaultSelected(result: ActivityResult, vaultModel: VaultModel) { fun cloudConnectionForVaultSelected(result: ActivityResult, vaultModel: VaultModel) {
val cloud = result.intent().getSerializableExtra(CloudConnectionListPresenter.SELECTED_CLOUD) as Cloud val cloud = result.intent().getSerializableExtra(CloudConnectionListPresenter.SELECTED_CLOUD) as Cloud
val vault = Vault.aCopyOf(vaultModel.toVault()) // val vault = Vault.aCopyOf(vaultModel.toVault()) //
.withCloud(cloud) // .withCloud(cloud) //
.build() .build()
saveVaultUseCase // saveVaultUseCase //
.withVault(vault) // .withVault(vault) //
.run(object : DefaultResultHandler<Vault>() { .run(object : DefaultResultHandler<Vault>() {
override fun onSuccess(vault: Vault) { override fun onSuccess(vault: Vault) {
view?.addOrUpdateVault(VaultModel(vault)) view?.addOrUpdateVault(VaultModel(vault))
onCloudOfVaultAuthenticated(vault) onCloudOfVaultAuthenticated(vault)
} }
}) })
} }
private fun onCloudOfVaultAuthenticated(authenticatedVault: Vault) { private fun onCloudOfVaultAuthenticated(authenticatedVault: Vault) {
@ -352,8 +356,9 @@ class VaultListPresenter @Inject constructor( //
if (authenticatedVault.isLocked) { if (authenticatedVault.isLocked) {
if (!isPaused) { if (!isPaused) {
requestActivityResult( // requestActivityResult( //
ActivityResultCallbacks.vaultUnlockedVaultList(), // ActivityResultCallbacks.vaultUnlockedVaultList(), //
Intents.unlockVaultIntent().withVaultModel(authenticatedVault).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK)) Intents.unlockVaultIntent().withVaultModel(authenticatedVault).withVaultAction(UnlockVaultIntent.VaultAction.UNLOCK)
)
} }
} else { } else {
browseFilesOf(authenticatedVault) browseFilesOf(authenticatedVault)
@ -371,18 +376,18 @@ class VaultListPresenter @Inject constructor( //
private fun navigateToVaultContent(cloud: Cloud) { private fun navigateToVaultContent(cloud: Cloud) {
getRootFolderUseCase // getRootFolderUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<CloudFolder>() { .run(object : DefaultResultHandler<CloudFolder>() {
override fun onSuccess(folder: CloudFolder) { override fun onSuccess(folder: CloudFolder) {
val vault = (folder.cloud as CryptoCloud).vault val vault = (folder.cloud as CryptoCloud).vault
view?.addOrUpdateVault(VaultModel(vault)) view?.addOrUpdateVault(VaultModel(vault))
navigateToVaultContent(vault, folder) navigateToVaultContent(vault, folder)
view?.showProgress(ProgressModel.COMPLETED) view?.showProgress(ProgressModel.COMPLETED)
if (checkToStartAutoImageUpload(vault)) { if (checkToStartAutoImageUpload(vault)) {
context().startService(AutoUploadService.startAutoUploadIntent(context(), folder.cloud)) context().startService(AutoUploadService.startAutoUploadIntent(context(), folder.cloud))
}
} }
}) }
})
} }
private fun checkToStartAutoImageUpload(vault: Vault): Boolean { private fun checkToStartAutoImageUpload(vault: Vault): Boolean {
@ -407,10 +412,10 @@ class VaultListPresenter @Inject constructor( //
fun onChangePasswordClicked(vaultModel: VaultModel) { fun onChangePasswordClicked(vaultModel: VaultModel) {
Intents Intents
.unlockVaultIntent() .unlockVaultIntent()
.withVaultModel(vaultModel) .withVaultModel(vaultModel)
.withVaultAction(UnlockVaultIntent.VaultAction.CHANGE_PASSWORD) .withVaultAction(UnlockVaultIntent.VaultAction.CHANGE_PASSWORD)
.startActivity(this) .startActivity(this)
} }
fun onVaultSettingsClicked(vaultModel: VaultModel) { fun onVaultSettingsClicked(vaultModel: VaultModel) {
@ -446,17 +451,17 @@ class VaultListPresenter @Inject constructor( //
fun onVaultMoved(fromPosition: Int, toPosition: Int) { fun onVaultMoved(fromPosition: Int, toPosition: Int) {
moveVaultPositionUseCase moveVaultPositionUseCase
.withFromPosition(fromPosition) // .withFromPosition(fromPosition) //
.andToPosition(toPosition) // .andToPosition(toPosition) //
.run(object : DefaultResultHandler<List<Vault>>() { .run(object : DefaultResultHandler<List<Vault>>() {
override fun onSuccess(vaults: List<Vault>) { override fun onSuccess(vaults: List<Vault>) {
view?.vaultMoved(vaults.mapTo(ArrayList()) { VaultModel(it) }) view?.vaultMoved(vaults.mapTo(ArrayList()) { VaultModel(it) })
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
Timber.tag("VaultListPresenter").e(e, "Failed to execute MoveVaultUseCase") Timber.tag("VaultListPresenter").e(e, "Failed to execute MoveVaultUseCase")
} }
}) })
} }
private enum class VaultAction { private enum class VaultAction {
@ -468,33 +473,34 @@ class VaultListPresenter @Inject constructor( //
val uri = fileUtil.contentUriForNewTempFile("cryptomator.apk") val uri = fileUtil.contentUriForNewTempFile("cryptomator.apk")
val file = fileUtil.tempFile("cryptomator.apk") val file = fileUtil.tempFile("cryptomator.apk")
updateUseCase // updateUseCase //
.withFile(file) // .withFile(file) //
.run(object : NoOpResultHandler<Void?>() { .run(object : NoOpResultHandler<Void?>() {
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
showError(e) showError(e)
} }
override fun onSuccess(aVoid: Void?) { override fun onSuccess(aVoid: Void?) {
super.onSuccess(aVoid) super.onSuccess(aVoid)
val intent = Intent(Intent.ACTION_VIEW) val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(uri, "application/vnd.android.package-archive") intent.setDataAndType(uri, "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context().startActivity(intent) context().startActivity(intent)
} }
}) })
} }
init { init {
unsubscribeOnDestroy( // unsubscribeOnDestroy( //
deleteVaultUseCase, // deleteVaultUseCase, //
renameVaultUseCase, // renameVaultUseCase, //
lockVaultUseCase, // lockVaultUseCase, //
getVaultListUseCase, // getVaultListUseCase, //
saveVaultUseCase, // saveVaultUseCase, //
moveVaultPositionUseCase, // moveVaultPositionUseCase, //
licenseCheckUseCase, // licenseCheckUseCase, //
updateCheckUseCase, // updateCheckUseCase, //
updateUseCase) updateUseCase
)
} }
} }

View File

@ -21,10 +21,11 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
@PerView @PerView
class WebDavAddOrChangePresenter @Inject internal constructor( // class WebDavAddOrChangePresenter @Inject internal constructor( //
private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, // private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, //
private val connectToWebDavUseCase: ConnectToWebDavUseCase, // private val connectToWebDavUseCase: ConnectToWebDavUseCase, //
private val authenticationExceptionHandler: AuthenticationExceptionHandler, // private val authenticationExceptionHandler: AuthenticationExceptionHandler, //
exceptionMappings: ExceptionHandlers) : Presenter<WebDavAddOrChangeView>(exceptionMappings) { exceptionMappings: ExceptionHandlers
) : Presenter<WebDavAddOrChangeView>(exceptionMappings) {
fun checkUserInput(urlPort: String, username: String, password: String, cloudId: Long?, certificate: String?) { fun checkUserInput(urlPort: String, username: String, password: String, cloudId: Long?, certificate: String?) {
var statusMessage: String? = null var statusMessage: String? = null
@ -55,8 +56,8 @@ class WebDavAddOrChangePresenter @Inject internal constructor( //
private fun encryptPassword(password: String): String { private fun encryptPassword(password: String): String {
return CredentialCryptor // return CredentialCryptor //
.getInstance(context()) // .getInstance(context()) //
.encrypt(password) .encrypt(password)
} }
private fun isValid(urlPort: String): Boolean { private fun isValid(urlPort: String): Boolean {
@ -65,10 +66,10 @@ class WebDavAddOrChangePresenter @Inject internal constructor( //
private fun mapToCloud(username: String, password: String, hostPort: String, id: Long?, certificate: String?): WebDavCloud { private fun mapToCloud(username: String, password: String, hostPort: String, id: Long?, certificate: String?): WebDavCloud {
var builder = WebDavCloud // var builder = WebDavCloud //
.aWebDavCloudCloud() // .aWebDavCloudCloud() //
.withUrl(hostPort) // .withUrl(hostPort) //
.withUsername(username) // .withUsername(username) //
.withPassword(password) .withPassword(password)
if (id != null) { if (id != null) {
builder = builder.withId(id) builder = builder.withId(id)
@ -88,19 +89,19 @@ class WebDavAddOrChangePresenter @Inject internal constructor( //
private fun authenticate(cloud: WebDavCloud) { private fun authenticate(cloud: WebDavCloud) {
view?.showProgress(ProgressModel(ProgressStateModel.AUTHENTICATION)) view?.showProgress(ProgressModel(ProgressStateModel.AUTHENTICATION))
connectToWebDavUseCase // connectToWebDavUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(object : DefaultResultHandler<Void?>() { .run(object : DefaultResultHandler<Void?>() {
override fun onSuccess(void: Void?) { override fun onSuccess(void: Void?) {
onCloudAuthenticated(cloud) onCloudAuthenticated(cloud)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
view?.showProgress(ProgressModel.COMPLETED) view?.showProgress(ProgressModel.COMPLETED)
if (!authenticationExceptionHandler.handleAuthenticationException(this@WebDavAddOrChangePresenter, e, ActivityResultCallbacks.handledAuthenticationWebDavCloud())) { if (!authenticationExceptionHandler.handleAuthenticationException(this@WebDavAddOrChangePresenter, e, ActivityResultCallbacks.handledAuthenticationWebDavCloud())) {
super.onError(e) super.onError(e)
}
} }
}) }
})
} }
@Callback @Callback
@ -117,8 +118,8 @@ class WebDavAddOrChangePresenter @Inject internal constructor( //
private fun save(cloud: Cloud) { private fun save(cloud: Cloud) {
addOrChangeCloudConnectionUseCase // addOrChangeCloudConnectionUseCase //
.withCloud(cloud) // .withCloud(cloud) //
.run(DefaultResultHandler()) .run(DefaultResultHandler())
} }
init { init {

View File

@ -29,26 +29,27 @@ class AutoUploadNotification(private val context: Context, private val amountOfP
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel( // val notificationChannel = NotificationChannel( //
NOTIFICATION_CHANNEL_ID, // NOTIFICATION_CHANNEL_ID, //
NOTIFICATION_CHANNEL_NAME, // NOTIFICATION_CHANNEL_NAME, //
IMPORTANCE_LOW) IMPORTANCE_LOW
)
notificationManager?.createNotificationChannel(notificationChannel) notificationManager?.createNotificationChannel(notificationChannel)
} }
this.builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) // this.builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) //
.setContentTitle(context.getString(R.string.notification_auto_upload_title)) // .setContentTitle(context.getString(R.string.notification_auto_upload_title)) //
.setSmallIcon(R.drawable.background_splash_cryptomator) // .setSmallIcon(R.drawable.background_splash_cryptomator) //
.setColor(getColor(R.color.colorPrimary)) // .setColor(getColor(R.color.colorPrimary)) //
.addAction(cancelNowAction()) .addAction(cancelNowAction())
.setGroup(NOTIFICATION_GROUP_KEY) .setGroup(NOTIFICATION_GROUP_KEY)
.setOngoing(true) .setOngoing(true)
} }
private fun cancelNowAction(): NotificationCompat.Action { private fun cancelNowAction(): NotificationCompat.Action {
return NotificationCompat.Action.Builder( // return NotificationCompat.Action.Builder( //
R.drawable.ic_lock, // R.drawable.ic_lock, //
getString(R.string.notification_cancel_auto_upload), // getString(R.string.notification_cancel_auto_upload), //
cancelNowIntent() // cancelNowIntent() //
).build() ).build()
} }
@ -67,11 +68,14 @@ class AutoUploadNotification(private val context: Context, private val amountOfP
fun update(progress: Int) { fun update(progress: Int) {
builder.setContentIntent(startTheActivity()) builder.setContentIntent(startTheActivity())
builder // builder //
.setContentText( // .setContentText( //
String.format(context.getString(R.string.notification_auto_upload_message), // String.format(
alreadyUploadedPictures + 1, // context.getString(R.string.notification_auto_upload_message), //
amountOfPictures)) // alreadyUploadedPictures + 1, //
.setProgress(100, progress, false) amountOfPictures
)
) //
.setProgress(100, progress, false)
show() show()
} }
@ -95,24 +99,24 @@ class AutoUploadNotification(private val context: Context, private val amountOfP
private fun showErrorWithMessage(message: String) { private fun showErrorWithMessage(message: String) {
builder.setContentIntent(startTheActivity()) builder.setContentIntent(startTheActivity())
builder // builder //
.setContentTitle(context.getString(R.string.notification_auto_upload_failed_title)) .setContentTitle(context.getString(R.string.notification_auto_upload_failed_title))
.setContentText(message) // .setContentText(message) //
.setProgress(0, 0, false) .setProgress(0, 0, false)
.setAutoCancel(true) .setAutoCancel(true)
.setOngoing(false) .setOngoing(false)
.mActions.clear() .mActions.clear()
show() show()
} }
fun showUploadFinished(size: Int) { fun showUploadFinished(size: Int) {
builder.setContentIntent(startTheActivity()) builder.setContentIntent(startTheActivity())
builder // builder //
.setContentTitle(context.getString(R.string.notification_auto_upload_finished_title)) .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) .setProgress(0, 0, false)
.setAutoCancel(true) .setAutoCancel(true)
.setOngoing(false) .setOngoing(false)
.mActions.clear() .mActions.clear()
show() show()
} }

View File

@ -26,27 +26,28 @@ class OpenWritableFileNotification(private val context: Context, private val uri
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel( // val notificationChannel = NotificationChannel( //
NOTIFICATION_CHANNEL_ID, // NOTIFICATION_CHANNEL_ID, //
NOTIFICATION_CHANNEL_NAME, // NOTIFICATION_CHANNEL_NAME, //
IMPORTANCE_LOW) IMPORTANCE_LOW
)
notificationManager?.createNotificationChannel(notificationChannel) notificationManager?.createNotificationChannel(notificationChannel)
} }
this.builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) // this.builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) //
.setContentTitle(context.getString(R.string.notification_open_writable_file_title)) // .setContentTitle(context.getString(R.string.notification_open_writable_file_title)) //
.setContentText(context.getString(R.string.notification_open_writable_file_message)) // .setContentText(context.getString(R.string.notification_open_writable_file_message)) //
.setSmallIcon(R.drawable.background_splash_cryptomator) // .setSmallIcon(R.drawable.background_splash_cryptomator) //
.setColor(getColor(R.color.colorPrimary)) // .setColor(getColor(R.color.colorPrimary)) //
.setGroup(NOTIFICATION_GROUP_KEY) .setGroup(NOTIFICATION_GROUP_KEY)
.setOngoing(true) .setOngoing(true)
.addAction(cancelNowAction()) .addAction(cancelNowAction())
} }
private fun cancelNowAction(): NotificationCompat.Action { private fun cancelNowAction(): NotificationCompat.Action {
return NotificationCompat.Action.Builder( // return NotificationCompat.Action.Builder( //
R.drawable.ic_lock, // R.drawable.ic_lock, //
ResourceHelper.getString(R.string.notification_cancel_open_writable_file), // ResourceHelper.getString(R.string.notification_cancel_open_writable_file), //
cancelNowIntent() // cancelNowIntent() //
).build() ).build()
} }

View File

@ -75,12 +75,16 @@ class PhotoContentJob : JobService() {
private fun getContentResolvers(ids: Set<String>): Array<Cursor?> { private fun getContentResolvers(ids: Set<String>): Array<Cursor?> {
val selection = buildSelection(ids) val selection = buildSelection(ids)
var resolvers = arrayOf(contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION_IMAGES, selection, null, null), var resolvers = arrayOf(
contentResolver.query(MediaStore.Images.Media.INTERNAL_CONTENT_URI, PROJECTION_IMAGES, selection, null, null)) contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION_IMAGES, selection, null, null),
contentResolver.query(MediaStore.Images.Media.INTERNAL_CONTENT_URI, PROJECTION_IMAGES, selection, null, null)
)
if (SharedPreferencesHandler(applicationContext).autoPhotoUploadIncludingVideos()) { if (SharedPreferencesHandler(applicationContext).autoPhotoUploadIncludingVideos()) {
resolvers += arrayOf(contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, PROJECTION_VIDEOS, selection, null, null), resolvers += arrayOf(
contentResolver.query(MediaStore.Video.Media.INTERNAL_CONTENT_URI, PROJECTION_VIDEOS, selection, null, null)) contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, PROJECTION_VIDEOS, selection, null, null),
contentResolver.query(MediaStore.Video.Media.INTERNAL_CONTENT_URI, PROJECTION_VIDEOS, selection, null, null)
)
} }
return resolvers return resolvers
@ -88,14 +92,14 @@ class PhotoContentJob : JobService() {
private fun getIds(params: JobParameters): Set<String>? { private fun getIds(params: JobParameters): Set<String>? {
return params.triggeredContentUris return params.triggeredContentUris
?.map { it.pathSegments } ?.map { it.pathSegments }
?.filter { ?.filter {
it != null && (it.size == MediaStore.Images.Media.EXTERNAL_CONTENT_URI.pathSegments.size + 1 it != null && (it.size == MediaStore.Images.Media.EXTERNAL_CONTENT_URI.pathSegments.size + 1
|| it.size == MediaStore.Video.Media.EXTERNAL_CONTENT_URI.pathSegments.size + 1 || it.size == MediaStore.Video.Media.EXTERNAL_CONTENT_URI.pathSegments.size + 1
|| it.size == MediaStore.Images.Media.INTERNAL_CONTENT_URI.pathSegments.size + 1 || it.size == MediaStore.Images.Media.INTERNAL_CONTENT_URI.pathSegments.size + 1
|| it.size == MediaStore.Video.Media.INTERNAL_CONTENT_URI.pathSegments.size + 1) || it.size == MediaStore.Video.Media.INTERNAL_CONTENT_URI.pathSegments.size + 1)
} }
?.mapTo(HashSet()) { it[it.size - 1] } ?.mapTo(HashSet()) { it[it.size - 1] }
} }
private fun buildSelection(ids: Set<String>): String { private fun buildSelection(ids: Set<String>): String {

View File

@ -15,8 +15,8 @@ import javax.inject.Inject
@Activity(layout = R.layout.activity_empty) @Activity(layout = R.layout.activity_empty)
class AuthenticateCloudActivity : BaseActivity(), class AuthenticateCloudActivity : BaseActivity(),
AuthenticateCloudView, AuthenticateCloudView,
AssignSslCertificateDialog.Callback { AssignSslCertificateDialog.Callback {
@Inject @Inject
lateinit var presenter: AuthenticateCloudPresenter lateinit var presenter: AuthenticateCloudPresenter

View File

@ -14,8 +14,8 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity @Activity
class AutoUploadChooseVaultActivity : BaseActivity(), // class AutoUploadChooseVaultActivity : BaseActivity(), //
AutoUploadChooseVaultView, // AutoUploadChooseVaultView, //
NotEnoughVaultsDialog.Callback { NotEnoughVaultsDialog.Callback {
@Inject @Inject
lateinit var presenter: AutoUploadChooseVaultPresenter lateinit var presenter: AutoUploadChooseVaultPresenter
@ -42,9 +42,9 @@ class AutoUploadChooseVaultActivity : BaseActivity(), //
override fun displayDialogUnableToUploadFiles() { override fun displayDialogUnableToUploadFiles() {
NotEnoughVaultsDialog // NotEnoughVaultsDialog //
.withContext(this) // .withContext(this) //
.andTitle(getString(R.string.dialog_unable_to_auto_upload_files_title)) // .andTitle(getString(R.string.dialog_unable_to_auto_upload_files_title)) //
.show() .show()
} }
override fun onNotEnoughVaultsOkClicked() { override fun onNotEnoughVaultsOkClicked() {

View File

@ -162,9 +162,9 @@ abstract class BaseActivity : AppCompatActivity(), View, ActivityCompat.OnReques
private fun initializeDagger(): ActivityComponent { private fun initializeDagger(): ActivityComponent {
val activityComponent = DaggerActivityComponent.builder() val activityComponent = DaggerActivityComponent.builder()
.applicationComponent(applicationComponent) .applicationComponent(applicationComponent)
.activityModule(ActivityModule(this)) .activityModule(ActivityModule(this))
.build() .build()
Activities.inject(activityComponent, this) Activities.inject(activityComponent, this)
return activityComponent return activityComponent
} }
@ -316,7 +316,7 @@ abstract class BaseActivity : AppCompatActivity(), View, ActivityCompat.OnReques
internal open fun snackbarView(): android.view.View { internal open fun snackbarView(): android.view.View {
return activity().findViewById(R.id.locationsRecyclerView) as android.view.View? return activity().findViewById(R.id.locationsRecyclerView) as android.view.View?
?: return activity().findViewById(R.id.coordinatorLayout) ?: return activity().findViewById(R.id.coordinatorLayout)
} }
internal fun getCurrentFragment(fragmentContainer: Int): Fragment? = supportFragmentManager.findFragmentById(fragmentContainer) internal fun getCurrentFragment(fragmentContainer: Int): Fragment? = supportFragmentManager.findFragmentById(fragmentContainer)
@ -374,10 +374,11 @@ abstract class BaseActivity : AppCompatActivity(), View, ActivityCompat.OnReques
} }
internal enum class FragmentAnimation constructor( internal enum class FragmentAnimation constructor(
val enter: Int, val enter: Int,
val exit: Int, val exit: Int,
val popEnter: Int, val popEnter: Int,
val popExit: Int) { val popExit: Int
) {
NAVIGATE_IN_TO_FOLDER(R.animator.enter_from_right, R.animator.exit_to_left, R.animator.enter_from_left, R.animator.exit_to_right), // NAVIGATE_IN_TO_FOLDER(R.animator.enter_from_right, R.animator.exit_to_left, R.animator.enter_from_left, R.animator.exit_to_right), //
NAVIGATE_OUT_OF_FOLDER(R.animator.enter_from_left, R.animator.exit_to_right, R.animator.enter_from_right, R.animator.exit_to_left) NAVIGATE_OUT_OF_FOLDER(R.animator.enter_from_left, R.animator.exit_to_right, R.animator.enter_from_right, R.animator.exit_to_left)

View File

@ -14,8 +14,8 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity @Activity
class BiometricAuthSettingsActivity : BaseActivity(), // class BiometricAuthSettingsActivity : BaseActivity(), //
BiometricAuthSettingsView, // BiometricAuthSettingsView, //
EnrollSystemBiometricDialog.Callback { EnrollSystemBiometricDialog.Callback {
@Inject @Inject
lateinit var presenter: BiometricAuthSettingsPresenter lateinit var presenter: BiometricAuthSettingsPresenter
@ -29,8 +29,8 @@ class BiometricAuthSettingsActivity : BaseActivity(), //
override fun showSetupBiometricAuthDialog() { override fun showSetupBiometricAuthDialog() {
val biometricAuthenticationAvailable = BiometricManager // val biometricAuthenticationAvailable = BiometricManager //
.from(context()) // .from(context()) //
.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)
if (biometricAuthenticationAvailable == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) { if (biometricAuthenticationAvailable == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
showDialog(EnrollSystemBiometricDialog.newInstance()) showDialog(EnrollSystemBiometricDialog.newInstance())
} }

View File

@ -51,17 +51,17 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity @Activity
class BrowseFilesActivity : BaseActivity(), // class BrowseFilesActivity : BaseActivity(), //
BrowseFilesView, // BrowseFilesView, //
BrowseFilesCallback, // BrowseFilesCallback, //
ReplaceDialog.Callback, // ReplaceDialog.Callback, //
FileNameDialog.Callback, // FileNameDialog.Callback, //
ConfirmDeleteCloudNodeDialog.Callback, // ConfirmDeleteCloudNodeDialog.Callback, //
UploadCloudFileDialog.Callback, UploadCloudFileDialog.Callback,
ExportCloudFilesDialog.Callback, ExportCloudFilesDialog.Callback,
SymLinkDialog.CallBack, SymLinkDialog.CallBack,
NoDirFileDialog.CallBack, NoDirFileDialog.CallBack,
SearchView.OnQueryTextListener, SearchView.OnQueryTextListener,
SearchView.OnCloseListener { SearchView.OnCloseListener {
@Inject @Inject
lateinit var browseFilesPresenter: BrowseFilesPresenter lateinit var browseFilesPresenter: BrowseFilesPresenter
@ -97,8 +97,10 @@ class BrowseFilesActivity : BaseActivity(), //
get() = browseFilesFragment().folder get() = browseFilesFragment().folder
override fun createFragment(): Fragment = override fun createFragment(): Fragment =
BrowseFilesFragment.newInstance(browseFilesIntent.folder(), BrowseFilesFragment.newInstance(
browseFilesIntent.chooseCloudNodeSettings()) browseFilesIntent.folder(),
browseFilesIntent.chooseCloudNodeSettings()
)
override fun onBackPressed() { override fun onBackPressed() {
browseFilesPresenter.onBackPressed() browseFilesPresenter.onBackPressed()
@ -121,7 +123,7 @@ class BrowseFilesActivity : BaseActivity(), //
private fun isNavigationMode(navigationMode: ChooseCloudNodeSettings.NavigationMode): Boolean = this.navigationMode == navigationMode private fun isNavigationMode(navigationMode: ChooseCloudNodeSettings.NavigationMode): Boolean = this.navigationMode == navigationMode
private fun hasCloudNodeSettings(): Boolean = private fun hasCloudNodeSettings(): Boolean =
browseFilesIntent.chooseCloudNodeSettings() != null browseFilesIntent.chooseCloudNodeSettings() != null
override fun getCustomMenuResource(): Int { override fun getCustomMenuResource(): Int {
return when { return when {
@ -160,14 +162,17 @@ class BrowseFilesActivity : BaseActivity(), //
true true
} }
R.id.action_move_items -> { R.id.action_move_items -> {
browseFilesPresenter.onMoveNodesClicked(folder, // browseFilesPresenter.onMoveNodesClicked(
browseFilesFragment().selectedCloudNodes as ArrayList<CloudNodeModel<*>>) folder, //
browseFilesFragment().selectedCloudNodes as ArrayList<CloudNodeModel<*>>
)
true true
} }
R.id.action_export_items -> { R.id.action_export_items -> {
browseFilesPresenter.onExportNodesClicked( // browseFilesPresenter.onExportNodesClicked( //
browseFilesFragment().selectedCloudNodes as ArrayList<CloudNodeModel<*>>, // browseFilesFragment().selectedCloudNodes as ArrayList<CloudNodeModel<*>>, //
BrowseFilesPresenter.EXPORT_TRIGGERED_BY_USER) BrowseFilesPresenter.EXPORT_TRIGGERED_BY_USER
)
true true
} }
R.id.action_share_items -> { R.id.action_share_items -> {
@ -398,14 +403,18 @@ class BrowseFilesActivity : BaseActivity(), //
} }
override fun navigateTo(folder: CloudFolderModel) { override fun navigateTo(folder: CloudFolderModel) {
replaceFragment(BrowseFilesFragment.newInstance(folder, replaceFragment(
browseFilesIntent.chooseCloudNodeSettings()), BrowseFilesFragment.newInstance(
FragmentAnimation.NAVIGATE_IN_TO_FOLDER) folder,
browseFilesIntent.chooseCloudNodeSettings()
),
FragmentAnimation.NAVIGATE_IN_TO_FOLDER
)
} }
override fun showAddContentDialog() { override fun showAddContentDialog() {
VaultContentActionBottomSheet.newInstance(browseFilesFragment().folder) VaultContentActionBottomSheet.newInstance(browseFilesFragment().folder)
.show(supportFragmentManager, "AddContentDialog") .show(supportFragmentManager, "AddContentDialog")
} }
override fun updateTitle(folder: CloudFolderModel) { override fun updateTitle(folder: CloudFolderModel) {
@ -484,10 +493,14 @@ class BrowseFilesActivity : BaseActivity(), //
} }
private fun createBackStackFor(sourceParent: CloudFolderModel) { private fun createBackStackFor(sourceParent: CloudFolderModel) {
replaceFragment(BrowseFilesFragment.newInstance(sourceParent, replaceFragment(
browseFilesIntent.chooseCloudNodeSettings()), BrowseFilesFragment.newInstance(
FragmentAnimation.NAVIGATE_OUT_OF_FOLDER, sourceParent,
false) browseFilesIntent.chooseCloudNodeSettings()
),
FragmentAnimation.NAVIGATE_OUT_OF_FOLDER,
false
)
} }
override fun onRenameCloudNodeClicked(cloudNodeModel: CloudNodeModel<*>, newCloudNodeName: String) { override fun onRenameCloudNodeClicked(cloudNodeModel: CloudNodeModel<*>, newCloudNodeName: String) {

View File

@ -18,9 +18,9 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity @Activity
class CloudConnectionListActivity : BaseActivity(), class CloudConnectionListActivity : BaseActivity(),
CloudConnectionListView, CloudConnectionListView,
CloudConnectionSettingsBottomSheet.Callback, CloudConnectionSettingsBottomSheet.Callback,
DeleteCloudConnectionWithVaultsDialog.Callback { DeleteCloudConnectionWithVaultsDialog.Callback {
@Inject @Inject
lateinit var presenter: CloudConnectionListPresenter lateinit var presenter: CloudConnectionListPresenter
@ -55,7 +55,7 @@ class CloudConnectionListActivity : BaseActivity(),
override fun showNodeSettings(cloudModel: CloudModel) { override fun showNodeSettings(cloudModel: CloudModel) {
val cloudNodeSettingDialog = // val cloudNodeSettingDialog = //
CloudConnectionSettingsBottomSheet.newInstance(cloudModel) CloudConnectionSettingsBottomSheet.newInstance(cloudModel)
cloudNodeSettingDialog.show(supportFragmentManager, "CloudNodeSettings") cloudNodeSettingDialog.show(supportFragmentManager, "CloudNodeSettings")
} }

View File

@ -24,14 +24,16 @@ class EmptyDirIdFileInfoActivity : BaseActivity(), EmptyDirFileView {
} }
private fun setupToolbar() { private fun setupToolbar() {
toolbar.title = getString(R.string.screen_empty_dir_file_info_title, toolbar.title = getString(
emptyDirIdFileInfoIntent.dirName()) R.string.screen_empty_dir_file_info_title,
emptyDirIdFileInfoIntent.dirName()
)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
(supportFragmentManager.findFragmentByTag("EmptyDirIdFileInfoFragment") as EmptyDirIdFileInfoFragment) (supportFragmentManager.findFragmentByTag("EmptyDirIdFileInfoFragment") as EmptyDirIdFileInfoFragment)
.setDirFilePath(emptyDirIdFileInfoIntent.dirFilePath()) .setDirFilePath(emptyDirIdFileInfoIntent.dirFilePath())
} }
} }

View File

@ -180,10 +180,10 @@ class ImagePreviewActivity : BaseActivity(), ImagePreviewView, ConfirmDeleteClou
private fun fragmentFor(imagePreviewFile: ImagePreviewFile): Optional<ImagePreviewFragment> { private fun fragmentFor(imagePreviewFile: ImagePreviewFile): Optional<ImagePreviewFragment> {
return supportFragmentManager.fragments return supportFragmentManager.fragments
.map { it as ImagePreviewFragment } .map { it as ImagePreviewFragment }
.firstOrNull { it.imagePreviewFile() == imagePreviewFile } .firstOrNull { it.imagePreviewFile() == imagePreviewFile }
?.let { Optional.of(it) } ?.let { Optional.of(it) }
?: Optional.empty() ?: Optional.empty()
} }
override fun hideProgressBar(imagePreviewFile: ImagePreviewFile) { override fun hideProgressBar(imagePreviewFile: ImagePreviewFile) {

View File

@ -63,7 +63,7 @@ class LicenseCheckActivity : BaseActivity(), UpdateLicenseDialog.Callback, Licen
override fun licenseConfirmationClicked() { override fun licenseConfirmationClicked() {
vaultListIntent() // vaultListIntent() //
.preventGoingBackInHistory() // .preventGoingBackInHistory() //
.startActivity(this) // .startActivity(this) //
} }
} }

View File

@ -19,12 +19,12 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity(layout = R.layout.activity_settings) @Activity(layout = R.layout.activity_settings)
class SettingsActivity : BaseActivity(), class SettingsActivity : BaseActivity(),
SettingsView, SettingsView,
DebugModeDisclaimerDialog.Callback, DebugModeDisclaimerDialog.Callback,
DisableAppWhenObscuredDisclaimerDialog.Callback, DisableAppWhenObscuredDisclaimerDialog.Callback,
DisableSecureScreenDisclaimerDialog.Callback, DisableSecureScreenDisclaimerDialog.Callback,
UpdateAppAvailableDialog.Callback, // UpdateAppAvailableDialog.Callback, //
UpdateAppDialog.Callback { UpdateAppDialog.Callback {
@Inject @Inject
lateinit var presenter: SettingsPresenter lateinit var presenter: SettingsPresenter

View File

@ -26,10 +26,10 @@ import timber.log.Timber
@Activity @Activity
class SharedFilesActivity : BaseActivity(), // class SharedFilesActivity : BaseActivity(), //
SharedFilesView, // SharedFilesView, //
ReplaceDialog.Callback, // ReplaceDialog.Callback, //
NotEnoughVaultsDialog.Callback, // NotEnoughVaultsDialog.Callback, //
UploadCloudFileDialog.Callback { UploadCloudFileDialog.Callback {
@Inject @Inject
lateinit var presenter: SharedFilesPresenter lateinit var presenter: SharedFilesPresenter
@ -92,8 +92,8 @@ class SharedFilesActivity : BaseActivity(), //
val uriList = ArrayList<Uri>(clipData.itemCount) val uriList = ArrayList<Uri>(clipData.itemCount)
(0 until clipData.itemCount).forEach { i -> (0 until clipData.itemCount).forEach { i ->
clipData.getItemAt(i).uri clipData.getItemAt(i).uri
?.let { uriList.add(it) } ?.let { uriList.add(it) }
?: Timber.tag("Sharing").i("Item %d without uri", i) ?: Timber.tag("Sharing").i("Item %d without uri", i)
} }
return uriList return uriList
} }
@ -173,10 +173,10 @@ class SharedFilesActivity : BaseActivity(), //
override fun onNotEnoughVaultsCreateVaultClicked() { override fun onNotEnoughVaultsCreateVaultClicked() {
packageManager.getLaunchIntentForPackage(packageName) packageManager.getLaunchIntentForPackage(packageName)
?.let { ?.let {
it.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) it.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(it) startActivity(it)
} }
finish() finish()
} }

View File

@ -17,9 +17,9 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity @Activity
class TextEditorActivity : BaseActivity(), class TextEditorActivity : BaseActivity(),
TextEditorView, TextEditorView,
UnsavedChangesDialog.Callback, UnsavedChangesDialog.Callback,
SearchView.OnQueryTextListener { SearchView.OnQueryTextListener {
@Inject @Inject
lateinit var textEditorPresenter: TextEditorPresenter lateinit var textEditorPresenter: TextEditorPresenter
@ -45,18 +45,18 @@ class TextEditorActivity : BaseActivity(),
super.onCreateOptionsMenu(menu) super.onCreateOptionsMenu(menu)
menu.findItem(R.id.action_search) menu.findItem(R.id.action_search)
.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { .setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem?): Boolean { override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
menu.findItem(R.id.action_search_previous).isVisible = true menu.findItem(R.id.action_search_previous).isVisible = true
menu.findItem(R.id.action_search_next).isVisible = true menu.findItem(R.id.action_search_next).isVisible = true
return true return true
} }
override fun onMenuItemActionCollapse(item: MenuItem?): Boolean { override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
invalidateOptionsMenu() invalidateOptionsMenu()
return true return true
} }
}) })
return true return true
} }

View File

@ -21,10 +21,10 @@ import javax.inject.Inject
@Activity(layout = R.layout.activity_unlock_vault) @Activity(layout = R.layout.activity_unlock_vault)
class UnlockVaultActivity : BaseActivity(), // class UnlockVaultActivity : BaseActivity(), //
UnlockVaultView, // UnlockVaultView, //
BiometricAuthentication.Callback, BiometricAuthentication.Callback,
ChangePasswordDialog.Callback, ChangePasswordDialog.Callback,
VaultNotFoundDialog.Callback { VaultNotFoundDialog.Callback {
@Inject @Inject
lateinit var presenter: UnlockVaultPresenter lateinit var presenter: UnlockVaultPresenter
@ -84,7 +84,7 @@ class UnlockVaultActivity : BaseActivity(), //
override fun onBiometricAuthenticationFailed(vault: VaultModel) { override fun onBiometricAuthenticationFailed(vault: VaultModel) {
val vaultWithoutPassword = Vault.aCopyOf(vault.toVault()).withSavedPassword(null).build() val vaultWithoutPassword = Vault.aCopyOf(vault.toVault()).withSavedPassword(null).build()
when(unlockVaultIntent.vaultAction()) { when (unlockVaultIntent.vaultAction()) {
UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> presenter.saveVaultAfterChangePasswordButFailedBiometricAuth(vaultWithoutPassword) UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> presenter.saveVaultAfterChangePasswordButFailedBiometricAuth(vaultWithoutPassword)
else -> { else -> {
if (!presenter.startedUsingPrepareUnlock()) { if (!presenter.startedUsingPrepareUnlock()) {
@ -100,7 +100,7 @@ class UnlockVaultActivity : BaseActivity(), //
} }
private fun unlockVaultFragment(): UnlockVaultFragment = // private fun unlockVaultFragment(): UnlockVaultFragment = //
getCurrentFragment(R.id.fragmentContainer) as UnlockVaultFragment getCurrentFragment(R.id.fragmentContainer) as UnlockVaultFragment
override fun showChangePasswordDialog(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedVaultConfig?) { override fun showChangePasswordDialog(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedVaultConfig?) {
showDialog(ChangePasswordDialog.newInstance(vaultModel, unverifiedVaultConfig)) showDialog(ChangePasswordDialog.newInstance(vaultModel, unverifiedVaultConfig))

View File

@ -35,12 +35,12 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity(layout = R.layout.activity_layout_obscure_aware) @Activity(layout = R.layout.activity_layout_obscure_aware)
class VaultListActivity : BaseActivity(), // class VaultListActivity : BaseActivity(), //
VaultListView, // VaultListView, //
VaultListCallback, // VaultListCallback, //
AskForLockScreenDialog.Callback, // AskForLockScreenDialog.Callback, //
UpdateAppAvailableDialog.Callback, // UpdateAppAvailableDialog.Callback, //
UpdateAppDialog.Callback, // UpdateAppDialog.Callback, //
BetaConfirmationDialog.Callback { BetaConfirmationDialog.Callback {
@Inject @Inject
lateinit var vaultListPresenter: VaultListPresenter lateinit var vaultListPresenter: VaultListPresenter
@ -122,7 +122,7 @@ class VaultListActivity : BaseActivity(), //
override fun showVaultSettingsDialog(vaultModel: VaultModel) { override fun showVaultSettingsDialog(vaultModel: VaultModel) {
val vaultSettingDialog = // val vaultSettingDialog = //
SettingsVaultBottomSheet.newInstance(vaultModel) SettingsVaultBottomSheet.newInstance(vaultModel)
vaultSettingDialog.show(supportFragmentManager, "VaultSettings") vaultSettingDialog.show(supportFragmentManager, "VaultSettings")
} }
@ -164,7 +164,7 @@ class VaultListActivity : BaseActivity(), //
override fun onDeleteVaultClick(vaultModel: VaultModel) { override fun onDeleteVaultClick(vaultModel: VaultModel) {
VaultDeleteConfirmationDialog.newInstance(vaultModel) // VaultDeleteConfirmationDialog.newInstance(vaultModel) //
.show(supportFragmentManager, "VaultDeleteConfirmationDialog") .show(supportFragmentManager, "VaultDeleteConfirmationDialog")
} }
override fun onRenameVaultClick(vaultModel: VaultModel) { override fun onRenameVaultClick(vaultModel: VaultModel) {
@ -192,7 +192,7 @@ class VaultListActivity : BaseActivity(), //
} }
private fun vaultListFragment(): VaultListFragment = // private fun vaultListFragment(): VaultListFragment = //
getCurrentFragment(R.id.fragmentContainer) as VaultListFragment getCurrentFragment(R.id.fragmentContainer) as VaultListFragment
override fun onUpdateAppDialogLoaded() { override fun onUpdateAppDialogLoaded() {
showProgress(ProgressModel.GENERIC) showProgress(ProgressModel.GENERIC)

View File

@ -17,8 +17,8 @@ import kotlinx.android.synthetic.main.toolbar_layout.toolbar
@Activity @Activity
class WebDavAddOrChangeActivity : BaseActivity(), class WebDavAddOrChangeActivity : BaseActivity(),
WebDavAddOrChangeView, WebDavAddOrChangeView,
WebDavAskForHttpDialog.Callback { WebDavAskForHttpDialog.Callback {
@Inject @Inject
lateinit var webDavAddOrChangePresenter: WebDavAddOrChangePresenter lateinit var webDavAddOrChangePresenter: WebDavAddOrChangePresenter

View File

@ -45,10 +45,12 @@ import kotlinx.android.synthetic.main.view_cloud_folder_content.view.cloudFolder
import kotlinx.android.synthetic.main.view_cloud_folder_content.view.cloudFolderText import kotlinx.android.synthetic.main.view_cloud_folder_content.view.cloudFolderText
class BrowseFilesAdapter @Inject class BrowseFilesAdapter @Inject
constructor(private val dateHelper: DateHelper, // constructor(
private val fileSizeHelper: FileSizeHelper, // private val dateHelper: DateHelper, //
private val fileUtil: FileUtil, // private val fileSizeHelper: FileSizeHelper, //
private val sharedPreferencesHandler: SharedPreferencesHandler) : RecyclerViewBaseAdapter<CloudNodeModel<*>, BrowseFilesAdapter.ItemClickListener, VaultContentViewHolder>(CloudNodeModelNameAZComparator()), FastScrollRecyclerView.SectionedAdapter { private val fileUtil: FileUtil, //
private val sharedPreferencesHandler: SharedPreferencesHandler
) : RecyclerViewBaseAdapter<CloudNodeModel<*>, BrowseFilesAdapter.ItemClickListener, VaultContentViewHolder>(CloudNodeModelNameAZComparator()), FastScrollRecyclerView.SectionedAdapter {
private var chooseCloudNodeSettings: ChooseCloudNodeSettings? = null private var chooseCloudNodeSettings: ChooseCloudNodeSettings? = null
private var navigationMode: ChooseCloudNodeSettings.NavigationMode? = null private var navigationMode: ChooseCloudNodeSettings.NavigationMode? = null

View File

@ -7,4 +7,5 @@ import org.cryptomator.presentation.ui.dialog.CloudNodeRenameDialog
import org.cryptomator.presentation.ui.dialog.CreateFolderDialog import org.cryptomator.presentation.ui.dialog.CreateFolderDialog
import org.cryptomator.presentation.ui.dialog.FileTypeNotSupportedDialog import org.cryptomator.presentation.ui.dialog.FileTypeNotSupportedDialog
interface BrowseFilesCallback : CreateFolderDialog.Callback, VaultContentActionBottomSheet.Callback, FileSettingsBottomSheet.Callback, FolderSettingsBottomSheet.Callback, CloudNodeRenameDialog.Callback, FileTypeNotSupportedDialog.Callback interface BrowseFilesCallback : CreateFolderDialog.Callback, VaultContentActionBottomSheet.Callback, FileSettingsBottomSheet.Callback, FolderSettingsBottomSheet.Callback, CloudNodeRenameDialog.Callback,
FileTypeNotSupportedDialog.Callback

View File

@ -7,6 +7,6 @@ import org.cryptomator.presentation.ui.dialog.VaultRenameDialog
// FIXME delete this file and add this interfaces to VaultListView.kt // FIXME delete this file and add this interfaces to VaultListView.kt
interface VaultListCallback : AddVaultBottomSheet.Callback, // interface VaultListCallback : AddVaultBottomSheet.Callback, //
SettingsVaultBottomSheet.Callback, // SettingsVaultBottomSheet.Callback, //
VaultDeleteConfirmationDialog.Callback, // VaultDeleteConfirmationDialog.Callback, //
VaultRenameDialog.Callback VaultRenameDialog.Callback

View File

@ -14,8 +14,8 @@ class AppIsObscuredInfoDialog : BaseDialog<Activity>() {
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_app_is_obscured_info_title) // .setTitle(R.string.dialog_app_is_obscured_info_title) //
.setNeutralButton(R.string.dialog_app_is_obscured_info_neutral_button) { dialog: DialogInterface, _: Int -> dialog.dismiss() } .setNeutralButton(R.string.dialog_app_is_obscured_info_neutral_button) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
return builder.create() return builder.create()
} }

View File

@ -17,8 +17,8 @@ class AskForLockScreenDialog : BaseDialog<AskForLockScreenDialog.Callback>() {
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_no_screen_lock_title) // .setTitle(R.string.dialog_no_screen_lock_title) //
.setNeutralButton(getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int -> callback?.onAskForLockScreenFinished(cb_select_screen_lock.isChecked) } .setNeutralButton(getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int -> callback?.onAskForLockScreenFinished(cb_select_screen_lock.isChecked) }
return builder.create() return builder.create()
} }

View File

@ -29,14 +29,14 @@ class AssignSslCertificateDialog : BaseDialog<AssignSslCertificateDialog.Callbac
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(requireContext().getString(R.string.dialog_accept_ssl_certificate_title)) .setTitle(requireContext().getString(R.string.dialog_accept_ssl_certificate_title))
.setPositiveButton(requireActivity().getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int -> .setPositiveButton(requireActivity().getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int ->
val cloud = requireArguments().getSerializable(WEBDAV_CLOUD) as WebDavCloud val cloud = requireArguments().getSerializable(WEBDAV_CLOUD) as WebDavCloud
callback?.onAcceptCertificateClicked(cloud, certificate) callback?.onAcceptCertificateClicked(cloud, certificate)
} // } //
.setNegativeButton(requireContext().getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> .setNegativeButton(requireContext().getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int ->
callback?.onAcceptCertificateDenied() callback?.onAcceptCertificateDenied()
} }
return builder.create() return builder.create()
} }

View File

@ -16,8 +16,8 @@ class BetaConfirmationDialog : BaseDialog<BetaConfirmationDialog.Callback>() {
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_beta_confirmation_title) // .setTitle(R.string.dialog_beta_confirmation_title) //
.setNeutralButton(getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int -> callback?.onAskForBetaConfirmationFinished() } .setNeutralButton(getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int -> callback?.onAskForBetaConfirmationFinished() }
return builder.create() return builder.create()
} }

View File

@ -10,8 +10,8 @@ class BiometricAuthKeyInvalidatedDialog : BaseDialog<BiometricAuthKeyInvalidated
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_biometric_auth_key_invalidated_title) // .setTitle(R.string.dialog_biometric_auth_key_invalidated_title) //
.setNegativeButton(getString(R.string.dialog_biometric_auth_key_invalidated_neutral_button)) { _: DialogInterface, _: Int -> } .setNegativeButton(getString(R.string.dialog_biometric_auth_key_invalidated_neutral_button)) { _: DialogInterface, _: Int -> }
return builder.create() return builder.create()
} }

View File

@ -35,13 +35,18 @@ class ChangePasswordDialog : BaseProgressErrorDialog<ChangePasswordDialog.Callba
changePasswordButton?.setOnClickListener { changePasswordButton?.setOnClickListener {
val vaultModel = requireArguments().getSerializable(VAULT_ARG) as VaultModel val vaultModel = requireArguments().getSerializable(VAULT_ARG) as VaultModel
val unverifiedVaultConfig = requireArguments().getSerializable(VAULT_CONFIG_ARG) as UnverifiedVaultConfig? val unverifiedVaultConfig = requireArguments().getSerializable(VAULT_CONFIG_ARG) as UnverifiedVaultConfig?
if (valid(et_old_password.text.toString(), // if (valid(
et_new_password.text.toString(), // et_old_password.text.toString(), //
et_new_retype_password.text.toString())) { et_new_password.text.toString(), //
callback?.onChangePasswordClick(vaultModel, // et_new_retype_password.text.toString()
unverifiedVaultConfig, // )
et_old_password.text.toString(), // ) {
et_new_password.text.toString()) callback?.onChangePasswordClick(
vaultModel, //
unverifiedVaultConfig, //
et_old_password.text.toString(), //
et_new_password.text.toString()
)
onWaitForResponse(et_old_password) onWaitForResponse(et_old_password)
} else { } else {
hideKeyboard(et_old_password) hideKeyboard(et_old_password)
@ -58,10 +63,12 @@ class ChangePasswordDialog : BaseProgressErrorDialog<ChangePasswordDialog.Callba
registerOnEditorDoneActionAndPerformButtonClick(et_new_retype_password) { changePasswordButton } registerOnEditorDoneActionAndPerformButtonClick(et_new_retype_password) { changePasswordButton }
PasswordStrengthUtil() // PasswordStrengthUtil() //
.startUpdatingPasswordStrengthMeter(et_new_password, // .startUpdatingPasswordStrengthMeter(
progressBarPwStrengthIndicator, // et_new_password, //
textViewPwStrengthIndicator, // progressBarPwStrengthIndicator, //
changePasswordButton) textViewPwStrengthIndicator, //
changePasswordButton
)
} }
} }
@ -86,10 +93,10 @@ class ChangePasswordDialog : BaseProgressErrorDialog<ChangePasswordDialog.Callba
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
val vaultModel = requireArguments().getSerializable(VAULT_ARG) as VaultModel val vaultModel = requireArguments().getSerializable(VAULT_ARG) as VaultModel
return builder // return builder //
.setTitle(vaultModel.name) // .setTitle(vaultModel.name) //
.setPositiveButton(getString(R.string.dialog_change_password)) { _: DialogInterface, _: Int -> } // .setPositiveButton(getString(R.string.dialog_change_password)) { _: DialogInterface, _: Int -> } //
.setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface?, _: Int -> } // .setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface?, _: Int -> } //
.create() .create()
} }
override fun setupView() { override fun setupView() {

View File

@ -50,10 +50,10 @@ class CloudNodeRenameDialog : BaseProgressErrorDialog<CloudNodeRenameDialog.Call
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
val cloudNodeModel = requireArguments().getSerializable(CLOUD_NODE_ARG) as CloudNodeModel<*> val cloudNodeModel = requireArguments().getSerializable(CLOUD_NODE_ARG) as CloudNodeModel<*>
return builder return builder
.setTitle(getTitle(cloudNodeModel)) .setTitle(getTitle(cloudNodeModel))
.setPositiveButton(requireActivity().getString(R.string.dialog_rename_node_positive_button)) { _: DialogInterface, _: Int -> } .setPositiveButton(requireActivity().getString(R.string.dialog_rename_node_positive_button)) { _: DialogInterface, _: Int -> }
.setNegativeButton(requireActivity().getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> } .setNegativeButton(requireActivity().getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> }
.create() .create()
} }
private fun getTitle(cloudNodeModel: CloudNodeModel<*>): String { private fun getTitle(cloudNodeModel: CloudNodeModel<*>): String {

View File

@ -27,10 +27,10 @@ class ConfirmDeleteCloudNodeDialog : BaseDialog<ConfirmDeleteCloudNodeDialog.Cal
title = nodes[0].name title = nodes[0].name
} }
return builder // return builder //
.setTitle(title) // .setTitle(title) //
.setPositiveButton(getString(R.string.dialog_confirm_delete_positive_button)) { _: DialogInterface, _: Int -> callback?.onDeleteCloudNodeConfirmed(nodes) } // .setPositiveButton(getString(R.string.dialog_confirm_delete_positive_button)) { _: DialogInterface, _: Int -> callback?.onDeleteCloudNodeConfirmed(nodes) } //
.setNegativeButton(getString(R.string.dialog_confirm_delete_negative_button)) { _: DialogInterface, _: Int -> } // .setNegativeButton(getString(R.string.dialog_confirm_delete_negative_button)) { _: DialogInterface, _: Int -> } //
.create() .create()
} }
private fun getMessage(cloudNodeModel: CloudNodeModel<*>): String { private fun getMessage(cloudNodeModel: CloudNodeModel<*>): String {

View File

@ -44,9 +44,9 @@ class CreateFolderDialog : BaseProgressErrorDialog<CreateFolderDialog.Callback>(
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder.setTitle(requireContext().getString(R.string.dialog_create_folder_title)) return builder.setTitle(requireContext().getString(R.string.dialog_create_folder_title))
.setPositiveButton(requireContext().getString(R.string.dialog_create_folder_positive_button)) { _: DialogInterface, _: Int -> } .setPositiveButton(requireContext().getString(R.string.dialog_create_folder_positive_button)) { _: DialogInterface, _: Int -> }
.setNegativeButton(requireContext().getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> } .setNegativeButton(requireContext().getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> }
.create() .create()
} }
override fun setupView() { override fun setupView() {

View File

@ -17,9 +17,9 @@ class DebugModeDisclaimerDialog : BaseDialog<DebugModeDisclaimerDialog.Callback>
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_debug_mode_disclaimer_title) // .setTitle(R.string.dialog_debug_mode_disclaimer_title) //
.setPositiveButton(getString(R.string.dialog_debug_mode_positive_button)) { _: DialogInterface, _: Int -> callback?.onDisclaimerAccepted() } // .setPositiveButton(getString(R.string.dialog_debug_mode_positive_button)) { _: DialogInterface, _: Int -> callback?.onDisclaimerAccepted() } //
.setNegativeButton(getString(R.string.dialog_debug_mode_negative_button)) { _: DialogInterface, _: Int -> callback?.onDisclaimerRejected() } .setNegativeButton(getString(R.string.dialog_debug_mode_negative_button)) { _: DialogInterface, _: Int -> callback?.onDisclaimerRejected() }
return builder.create() return builder.create()
} }

View File

@ -20,11 +20,11 @@ class DeleteCloudConnectionWithVaultsDialog : BaseDialog<DeleteCloudConnectionWi
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
val cloudModel = requireArguments().getSerializable(ARG_CLOUD) as CloudModel val cloudModel = requireArguments().getSerializable(ARG_CLOUD) as CloudModel
builder.setTitle(cloudModel.name()) // builder.setTitle(cloudModel.name()) //
.setPositiveButton(getString(R.string.dialog_delete_cloud_connection_with_vaults_positive_button)) { _: DialogInterface, _: Int -> .setPositiveButton(getString(R.string.dialog_delete_cloud_connection_with_vaults_positive_button)) { _: DialogInterface, _: Int ->
val vaultsOfCloud = requireArguments().getSerializable(ARG_VAULTS) as ArrayList<Vault> val vaultsOfCloud = requireArguments().getSerializable(ARG_VAULTS) as ArrayList<Vault>
callback?.onDeleteCloudConnectionAndVaults(cloudModel, vaultsOfCloud) callback?.onDeleteCloudConnectionAndVaults(cloudModel, vaultsOfCloud)
dismiss() dismiss()
}.setNegativeButton(getString(R.string.dialog_delete_cloud_connection_with_vaults_negative_button)) { _: DialogInterface, _: Int -> } }.setNegativeButton(getString(R.string.dialog_delete_cloud_connection_with_vaults_negative_button)) { _: DialogInterface, _: Int -> }
return builder.create() return builder.create()
} }

View File

@ -19,9 +19,9 @@ class DisableAppWhenObscuredDisclaimerDialog : BaseDialog<DisableAppWhenObscured
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_disable_app_obscured_disclaimer_title) // .setTitle(R.string.dialog_disable_app_obscured_disclaimer_title) //
.setPositiveButton(getString(R.string.dialog_disable_app_obscured_positive_button)) { _: DialogInterface, _: Int -> callback?.onDisableAppObscuredDisclaimerAccepted() } // .setPositiveButton(getString(R.string.dialog_disable_app_obscured_positive_button)) { _: DialogInterface, _: Int -> callback?.onDisableAppObscuredDisclaimerAccepted() } //
.setNegativeButton(getString(R.string.dialog_disable_app_obscured_negative_button)) { _: DialogInterface, _: Int -> callback?.onDisableAppObscuredDisclaimerRejected() } .setNegativeButton(getString(R.string.dialog_disable_app_obscured_negative_button)) { _: DialogInterface, _: Int -> callback?.onDisableAppObscuredDisclaimerRejected() }
return builder.create() return builder.create()
} }

View File

@ -19,9 +19,9 @@ class DisableSecureScreenDisclaimerDialog : BaseDialog<DisableSecureScreenDiscla
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_disable_app_obscured_disclaimer_title) // .setTitle(R.string.dialog_disable_app_obscured_disclaimer_title) //
.setPositiveButton(getString(R.string.dialog_disable_app_obscured_positive_button)) { _: DialogInterface, _: Int -> callback?.onDisableSecureScreenDisclaimerAccepted() } // .setPositiveButton(getString(R.string.dialog_disable_app_obscured_positive_button)) { _: DialogInterface, _: Int -> callback?.onDisableSecureScreenDisclaimerAccepted() } //
.setNegativeButton(getString(R.string.dialog_disable_app_obscured_negative_button)) { _: DialogInterface, _: Int -> callback?.onDisableSecureScreenDisclaimerRejected() } .setNegativeButton(getString(R.string.dialog_disable_app_obscured_negative_button)) { _: DialogInterface, _: Int -> callback?.onDisableSecureScreenDisclaimerRejected() }
return builder.create() return builder.create()
} }

View File

@ -21,11 +21,13 @@ class EnrollSystemBiometricDialog : BaseDialog<EnrollSystemBiometricDialog.Callb
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(getString(R.string.dialog_no_biometric_auth_set_up_title)) // .setTitle(getString(R.string.dialog_no_biometric_auth_set_up_title)) //
.setPositiveButton(getString(R.string.dialog_unable_to_share_positive_button) // .setPositiveButton(
) { _: DialogInterface, _: Int -> callback?.onSetupBiometricAuthInSystemClicked() } getString(R.string.dialog_unable_to_share_positive_button) //
.setNegativeButton(getString(R.string.dialog_button_cancel) // ) { _: DialogInterface, _: Int -> callback?.onSetupBiometricAuthInSystemClicked() }
) { _: DialogInterface?, _: Int -> callback?.onCancelSetupBiometricAuthInSystemClicked() } .setNegativeButton(
getString(R.string.dialog_button_cancel) //
) { _: DialogInterface?, _: Int -> callback?.onCancelSetupBiometricAuthInSystemClicked() }
return builder.create() return builder.create()
} }

View File

@ -51,12 +51,12 @@ class EnterPasswordDialog : BaseProgressErrorDialog<EnterPasswordDialog.Callback
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder // return builder //
.setTitle(vaultModel().name) // .setTitle(vaultModel().name) //
.setPositiveButton(getString(R.string.dialog_enter_password_positive_button)) { _: DialogInterface, _: Int -> } .setPositiveButton(getString(R.string.dialog_enter_password_positive_button)) { _: DialogInterface, _: Int -> }
.setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> .setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int ->
callback?.onUnlockCanceled() callback?.onUnlockCanceled()
callback?.closeDialog() callback?.closeDialog()
}.create() }.create()
} }
fun vaultModel(): VaultModel { fun vaultModel(): VaultModel {

View File

@ -19,8 +19,8 @@ class ExistingFileDialog : BaseDialog<ExistingFileDialog.Callback>() {
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
val fileUri = requireArguments().getParcelable<Uri>(FILE_URI_ARG) val fileUri = requireArguments().getParcelable<Uri>(FILE_URI_ARG)
builder.setTitle(getString(R.string.dialog_existing_file_title)) // builder.setTitle(getString(R.string.dialog_existing_file_title)) //
.setPositiveButton(getString(R.string.dialog_existing_file_positive_button)) { _: DialogInterface?, _: Int -> fileUri?.let { callback?.onReplaceClick(it) } } // .setPositiveButton(getString(R.string.dialog_existing_file_positive_button)) { _: DialogInterface?, _: Int -> fileUri?.let { callback?.onReplaceClick(it) } } //
.setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface?, _: Int -> } .setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface?, _: Int -> }
return builder.create() return builder.create()
} }

View File

@ -32,15 +32,17 @@ class ExportCloudFilesDialog : BaseProgressErrorDialog<ExportCloudFilesDialog.Ca
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder // return builder //
.setTitle(effectiveTitle(1)) // .setTitle(effectiveTitle(1)) //
.setNeutralButton(getString(R.string.dialog_export_file_cancel_button)) { _: DialogInterface, _: Int -> callback?.onExportCancelled() } // .setNeutralButton(getString(R.string.dialog_export_file_cancel_button)) { _: DialogInterface, _: Int -> callback?.onExportCancelled() } //
.create() .create()
} }
private fun effectiveTitle(seenFiles: Int): String { private fun effectiveTitle(seenFiles: Int): String {
return String.format(getString(R.string.dialog_export_file_title), // return String.format(
seenFiles, // getString(R.string.dialog_export_file_title), //
requireArguments().getInt(ARG_NUMBER_OF_FILES)) seenFiles, //
requireArguments().getInt(ARG_NUMBER_OF_FILES)
)
} }
override fun setupView() {} override fun setupView() {}

View File

@ -46,9 +46,9 @@ class FileNameDialog : BaseProgressErrorDialog<FileNameDialog.Callback>() {
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder.setTitle(R.string.dialog_file_name_title) // return builder.setTitle(R.string.dialog_file_name_title) //
.setPositiveButton(R.string.dialog_file_name_create) { _: DialogInterface, _: Int -> } // .setPositiveButton(R.string.dialog_file_name_create) { _: DialogInterface, _: Int -> } //
.setNegativeButton(R.string.dialog_file_name_cancel) { _: DialogInterface, _: Int -> } // .setNegativeButton(R.string.dialog_file_name_cancel) { _: DialogInterface, _: Int -> } //
.create() .create()
} }
private fun effectiveNewFileName(newFileName: String): String { private fun effectiveNewFileName(newFileName: String): String {

View File

@ -18,8 +18,8 @@ class FileTypeNotSupportedDialog : BaseDialog<FileTypeNotSupportedDialog.Callbac
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
val cloudFileModel = requireArguments().getSerializable(CLOUD_FILE_ARG) as CloudFileModel val cloudFileModel = requireArguments().getSerializable(CLOUD_FILE_ARG) as CloudFileModel
builder.setTitle(String.format(getString(R.string.dialog_filetype_not_supported_title), cloudFileModel.name)) builder.setTitle(String.format(getString(R.string.dialog_filetype_not_supported_title), cloudFileModel.name))
.setPositiveButton(getString(R.string.dialog_filetype_not_supported_positive_button)) { _: DialogInterface, _: Int -> callback?.onExportFileAfterAppChooserClicked(cloudFileModel) } // .setPositiveButton(getString(R.string.dialog_filetype_not_supported_positive_button)) { _: DialogInterface, _: Int -> callback?.onExportFileAfterAppChooserClicked(cloudFileModel) } //
.setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> } .setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> }
return builder.create() return builder.create()
} }

View File

@ -17,8 +17,8 @@ class LicenseConfirmationDialog : BaseDialog<LicenseConfirmationDialog.Callback>
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(getString(R.string.dialog_license_confirmation_title)) // .setTitle(getString(R.string.dialog_license_confirmation_title)) //
.setNeutralButton(getText(R.string.dialog_license_confirmation_ok_btn)) { _: DialogInterface, _: Int -> callback?.licenseConfirmationClicked() } .setNeutralButton(getText(R.string.dialog_license_confirmation_ok_btn)) { _: DialogInterface, _: Int -> callback?.licenseConfirmationClicked() }
return builder.create() return builder.create()
} }

View File

@ -18,11 +18,11 @@ class NoDirFileDialog : BaseDialog<NoDirFileDialog.CallBack>() {
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_no_dir_file_title) // .setTitle(R.string.dialog_no_dir_file_title) //
.setNeutralButton(R.string.dialog_no_dir_file_back_button) { dialog: DialogInterface, _: Int -> .setNeutralButton(R.string.dialog_no_dir_file_back_button) { dialog: DialogInterface, _: Int ->
callback?.navigateFolderBackBecauseNoDirFile() callback?.navigateFolderBackBecauseNoDirFile()
dialog.dismiss() dialog.dismiss()
} }
return builder.create() return builder.create()
} }

View File

@ -24,13 +24,13 @@ class NotEnoughVaultsDialog private constructor(private val context: Context) {
fun show() { fun show() {
AlertDialog.Builder(context) // AlertDialog.Builder(context) //
.setCancelable(false) // .setCancelable(false) //
.setTitle(title) // .setTitle(title) //
.setMessage(ResourceHelper.getString(R.string.dialog_unable_to_share_message)) // .setMessage(ResourceHelper.getString(R.string.dialog_unable_to_share_message)) //
.setPositiveButton(ResourceHelper.getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int -> callback.onNotEnoughVaultsOkClicked() } // .setPositiveButton(ResourceHelper.getString(R.string.dialog_unable_to_share_positive_button)) { _: DialogInterface, _: Int -> callback.onNotEnoughVaultsOkClicked() } //
.setNegativeButton(ResourceHelper.getString(R.string.dialog_unable_to_share_negative_button)) { _: DialogInterface, _: Int -> callback.onNotEnoughVaultsCreateVaultClicked() } // .setNegativeButton(ResourceHelper.getString(R.string.dialog_unable_to_share_negative_button)) { _: DialogInterface, _: Int -> callback.onNotEnoughVaultsCreateVaultClicked() } //
.create() // .create() //
.show() .show()
} }
companion object { companion object {

View File

@ -20,11 +20,11 @@ class ReplaceDialog private constructor(private val context: Context) {
fun show(existingFiles: List<String>, uploadingFilesCount: Int) { fun show(existingFiles: List<String>, uploadingFilesCount: Int) {
val existingFilesCount = existingFiles.size val existingFilesCount = existingFiles.size
val alertDialogBuilder = AlertDialog.Builder(context) // val alertDialogBuilder = AlertDialog.Builder(context) //
.setTitle(effectiveReplaceDialogTitle(existingFilesCount)) // .setTitle(effectiveReplaceDialogTitle(existingFilesCount)) //
.setMessage(effectiveReplaceDialogMessage(existingFiles, uploadingFilesCount)) .setMessage(effectiveReplaceDialogMessage(existingFiles, uploadingFilesCount))
.setPositiveButton(effectiveReplaceDialogPositiveButton(existingFilesCount, uploadingFilesCount)) { _: DialogInterface, _: Int -> callback.onReplacePositiveClicked() } // .setPositiveButton(effectiveReplaceDialogPositiveButton(existingFilesCount, uploadingFilesCount)) { _: DialogInterface, _: Int -> callback.onReplacePositiveClicked() } //
.setNeutralButton(effectiveReplaceDialogNeutralButton()) { _: DialogInterface, _: Int -> callback.onReplaceCanceled() } // .setNeutralButton(effectiveReplaceDialogNeutralButton()) { _: DialogInterface, _: Int -> callback.onReplaceCanceled() } //
.setOnCancelListener { callback.onReplaceCanceled() } .setOnCancelListener { callback.onReplaceCanceled() }
if (uploadingFilesCount > 1 && existingFilesCount != uploadingFilesCount) { if (uploadingFilesCount > 1 && existingFilesCount != uploadingFilesCount) {
alertDialogBuilder.setNegativeButton(effectiveReplaceDialogNegativeButton()) { _: DialogInterface, _: Int -> callback.onReplaceNegativeClicked() } alertDialogBuilder.setNegativeButton(effectiveReplaceDialogNegativeButton()) { _: DialogInterface, _: Int -> callback.onReplaceNegativeClicked() }
} }

View File

@ -18,11 +18,11 @@ class SymLinkDialog : BaseDialog<SymLinkDialog.CallBack?>() {
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
builder // builder //
.setTitle(R.string.dialog_sym_link_title) // .setTitle(R.string.dialog_sym_link_title) //
.setNeutralButton(R.string.dialog_sym_link_back_button) { dialog: DialogInterface, _: Int -> .setNeutralButton(R.string.dialog_sym_link_back_button) { dialog: DialogInterface, _: Int ->
callback?.navigateFolderBackBecauseSymlink() callback?.navigateFolderBackBecauseSymlink()
dialog.dismiss() dialog.dismiss()
} }
return builder.create() return builder.create()
} }

View File

@ -17,12 +17,12 @@ class UnsavedChangesDialog private constructor(private val context: Context) {
fun show() { fun show() {
AlertDialog.Builder(context) // AlertDialog.Builder(context) //
.setCancelable(false) // .setCancelable(false) //
.setTitle(R.string.dialog_unsaved_changes_title) // .setTitle(R.string.dialog_unsaved_changes_title) //
.setMessage(R.string.dialog_unsaved_changes_message) // .setMessage(R.string.dialog_unsaved_changes_message) //
.setPositiveButton(R.string.dialog_unsaved_changes_save) { _: DialogInterface?, _: Int -> callback.onSaveChangesClicked() } // .setPositiveButton(R.string.dialog_unsaved_changes_save) { _: DialogInterface?, _: Int -> callback.onSaveChangesClicked() } //
.setNegativeButton(R.string.dialog_unsaved_changes_discard) { _: DialogInterface?, _: Int -> callback.onDiscardChangesClicked() } // .setNegativeButton(R.string.dialog_unsaved_changes_discard) { _: DialogInterface?, _: Int -> callback.onDiscardChangesClicked() } //
.create().show() .create().show()
} }
companion object { companion object {

View File

@ -22,12 +22,12 @@ class UpdateAppAvailableDialog : BaseProgressErrorDialog<UpdateAppAvailableDialo
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder // return builder //
.setTitle(getString(R.string.dialog_update_available_title)) // .setTitle(getString(R.string.dialog_update_available_title)) //
.setPositiveButton(getString(R.string.dialog_update_available_update)) { _: DialogInterface, _: Int -> callback?.installUpdate() } // .setPositiveButton(getString(R.string.dialog_update_available_update)) { _: DialogInterface, _: Int -> callback?.installUpdate() } //
.setNeutralButton(getString(R.string.dialog_update_available_download_site)) { _: DialogInterface, _: Int -> callback?.showUpdateWebsite() } .setNeutralButton(getString(R.string.dialog_update_available_download_site)) { _: DialogInterface, _: Int -> callback?.showUpdateWebsite() }
.setNegativeButton(getText(R.string.dialog_update_available_cancel)) { _: DialogInterface, _: Int -> callback?.cancelUpdateClicked() } // .setNegativeButton(getText(R.string.dialog_update_available_cancel)) { _: DialogInterface, _: Int -> callback?.cancelUpdateClicked() } //
.setCancelable(false) // .setCancelable(false) //
.create() .create()
} }
public override fun setupView() { public override fun setupView() {

View File

@ -21,9 +21,9 @@ class UpdateAppDialog : BaseProgressErrorDialog<UpdateAppDialog.Callback>() {
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder // return builder //
.setTitle(getString(R.string.dialog_download_update_title)) // .setTitle(getString(R.string.dialog_download_update_title)) //
.setCancelable(false) // .setCancelable(false) //
.create() .create()
} }
public override fun setupView() { public override fun setupView() {

View File

@ -39,10 +39,10 @@ class UpdateLicenseDialog : BaseProgressErrorDialog<UpdateLicenseDialog.Callback
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder // return builder //
.setTitle(getString(R.string.dialog_enter_license_title)) // .setTitle(getString(R.string.dialog_enter_license_title)) //
.setPositiveButton(getText(R.string.dialog_enter_license_ok_button)) { _: DialogInterface, _: Int -> } // .setPositiveButton(getText(R.string.dialog_enter_license_ok_button)) { _: DialogInterface, _: Int -> } //
.setNegativeButton(getText(R.string.dialog_enter_license_decline_button)) { _: DialogInterface, _: Int -> callback?.onCheckLicenseCanceled() } // .setNegativeButton(getText(R.string.dialog_enter_license_decline_button)) { _: DialogInterface, _: Int -> callback?.onCheckLicenseCanceled() } //
.create() .create()
} }
public override fun setupView() { public override fun setupView() {

View File

@ -41,9 +41,9 @@ class UploadCloudFileDialog : BaseProgressErrorDialog<UploadCloudFileDialog.Call
override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
return builder // return builder //
.setTitle(effectiveTitle()) // .setTitle(effectiveTitle()) //
.setNeutralButton(getString(R.string.dialog_upload_file_cancel_button)) { _: DialogInterface?, _: Int -> } // .setNeutralButton(getString(R.string.dialog_upload_file_cancel_button)) { _: DialogInterface?, _: Int -> } //
.create() .create()
} }
private fun effectiveTitle(): String { private fun effectiveTitle(): String {

View File

@ -19,8 +19,8 @@ class VaultDeleteConfirmationDialog : BaseDialog<VaultDeleteConfirmationDialog.C
public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog {
val vaultModel = requireArguments().getSerializable(VAULT_ARG) as VaultModel val vaultModel = requireArguments().getSerializable(VAULT_ARG) as VaultModel
builder.setTitle(vaultModel.name) // builder.setTitle(vaultModel.name) //
.setPositiveButton(getString(R.string.dialog_delete_vault_positive_button_text)) { _: DialogInterface, _: Int -> callback?.onDeleteConfirmedClick(vaultModel) } // .setPositiveButton(getString(R.string.dialog_delete_vault_positive_button_text)) { _: DialogInterface, _: Int -> callback?.onDeleteConfirmedClick(vaultModel) } //
.setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> } .setNegativeButton(getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> }
return builder.create() return builder.create()
} }

Some files were not shown because too many files have changed in this diff Show More