diff --git a/CHANGELOG.md b/CHANGELOG.md index c6bbc8f..90f71fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ ## Change Log +### Kotlin AndroidX Account 1.1.3 *(2020-02-07)* + + * Migrate schema to support deferred streams. + +### Kotlin AndroidX Account 1.1.2 *(2019-12-04)* + + * Fix single account scheme to remove only authenticator accounts. + +### Kotlin AndroidX Account 1.1.1 *(2019-11-12)* + + * Make `removeAccount()` method dependant on scheme mode. + +### Kotlin AndroidX Account 1.1.0 *(2019-11-12)* + + * Add `mode` property to `AccountScheme`. + +### Kotlin AndroidX Account 1.0.1 *(2019-11-12)* + + * Correct constant package names in scheme; + * Refactor schema code to remove duplications. + ### Kotlin AndroidX Account 1.0.0 *(2019-11-12)* * Stable library release. diff --git a/README.md b/README.md index 0efd3d8..eb48e84 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ Add dependencies to the *Kotlin-based* project: ```groovy dependencies { - implementation "co.windly:ktx-account:1.0.0" - kapt "co.windly:ktx-account-compiler:1.0.0" + implementation "co.windly:ktx-account:1.1.3" + kapt "co.windly:ktx-account-compiler:1.1.3" } ``` diff --git a/gradle.properties b/gradle.properties index 74394b7..d74941d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ #region Maven Central -VERSION_NAME=1.0.1-SNAPSHOT +VERSION_NAME=1.1.4-SNAPSHOT GROUP=co.windly POM_DESCRIPTION=Maintenance POM_URL=https://github.com/tommus/ktx-account diff --git a/ktx-account-compiler/src/main/resources/co/windly/ktxaccount/compiler/scheme.ftl b/ktx-account-compiler/src/main/resources/co/windly/ktxaccount/compiler/scheme.ftl index 9f1e17e..4ace846 100644 --- a/ktx-account-compiler/src/main/resources/co/windly/ktxaccount/compiler/scheme.ftl +++ b/ktx-account-compiler/src/main/resources/co/windly/ktxaccount/compiler/scheme.ftl @@ -44,9 +44,11 @@ abstract class ${schemeClassName}(context: Context) : <#if classEnableReactive> open fun clearRx(<#if schemaMode == "multiple">name: String): Completable = - Completable - .fromAction { clear(<#if schemaMode == "multiple">name) } - .subscribeOn(Schedulers.io()) + Completable.defer { + Completable + .fromAction { clear(<#if schemaMode == "multiple">name) } + } + .subscribeOn(Schedulers.io()) //endregion @@ -78,22 +80,24 @@ abstract class ${schemeClassName}(context: Context) : } - override fun removeAccount(name: String): Completable = + override fun removeAccount(<#if schemaMode == "multiple">name: String): Completable = super - .removeAccount(name) + .removeAccount(<#if schemaMode == "multiple">name) .andThen(clearSubjects()) private fun clearSubjects(): Completable = - Completable - .fromAction { - <#list descriptorList as descriptor> - - // Tear down "${descriptor.propertyName}" property subject. - if (${descriptor.fieldName}Subject != null) { - ${descriptor.fieldName}Subject = null + Completable.defer { + Completable + .fromAction { + <#list descriptorList as descriptor> + + // Tear down "${descriptor.propertyName}" property subject. + if (${descriptor.fieldName}Subject != null) { + ${descriptor.fieldName}Subject = null + } + } - - } + } //endregion <#list descriptorList as descriptor> @@ -189,9 +193,11 @@ abstract class ${schemeClassName}(context: Context) : */ <#t> open fun saveRx${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name: String, ${descriptor.fieldName}: ${descriptor.type.simpleName}): Completable = - Completable - .fromAction { save${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name, ${descriptor.fieldName}) } - .subscribeOn(Schedulers.io()) + Completable.defer { + Completable + .fromAction { save${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name, ${descriptor.fieldName}) } + } + .subscribeOn(Schedulers.io()) <#if descriptor.enableReactive> @@ -201,32 +207,34 @@ abstract class ${schemeClassName}(context: Context) : */ <#t> open fun getRx${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name: String): Single<${descriptor.type.simpleName}> = - Single - .fromPublisher<${descriptor.type.simpleName}> { - - // Retrieve account. - val account = retrieveNullableAccount(<#if schemaMode == "multiple">name) - - // Emit an error for non-existent account. - if (account == null) { - it.onError(NoSuchElementException("Account does not exist.")) - it.onComplete() - return@fromPublisher - } - - // Retrieve property. - val property = manager.getUserData(account, KEY_${descriptor.fieldNameUpperCase}) - - // Complete with default value if property does not exist. - if (property.isNullOrBlank()) { - it.onNext(DEFAULT_${descriptor.fieldNameUpperCase}) + Single.defer<${descriptor.type.simpleName}> { + Single + .fromPublisher<${descriptor.type.simpleName}> { + + // Retrieve account. + val account = retrieveNullableAccount(<#if schemaMode == "multiple">name) + + // Emit an error for non-existent account. + if (account == null) { + it.onError(NoSuchElementException("Account does not exist.")) + it.onComplete() + return@fromPublisher + } + + // Retrieve property. + val property = manager.getUserData(account, KEY_${descriptor.fieldNameUpperCase}) + + // Complete with default value if property does not exist. + if (property.isNullOrBlank()) { + it.onNext(DEFAULT_${descriptor.fieldNameUpperCase}) + it.onComplete() + return@fromPublisher + } + + // Emit property. + it.onNext(property.to${descriptor.type.simpleName}()) it.onComplete() - return@fromPublisher } - - // Emit property. - it.onNext(property.to${descriptor.type.simpleName}()) - it.onComplete() } .subscribeOn(Schedulers.io()) @@ -238,8 +246,11 @@ abstract class ${schemeClassName}(context: Context) : */ <#t> open fun removeRx${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name: String): Completable = - Completable - .fromAction { remove${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name) } + Completable.defer { + Completable + .fromAction { remove${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name) } + } + .subscribeOn(Schedulers.io()) <#if descriptor.enableReactive> @@ -249,11 +260,14 @@ abstract class ${schemeClassName}(context: Context) : */ <#t> open fun observeRx${descriptor.fieldName?cap_first}(<#if schemaMode == "multiple">name: String): Flowable<${descriptor.type.simpleName}> = + Flowable.defer<${descriptor.type.simpleName}> { retrieve${descriptor.fieldName?cap_first}Subject(<#if schemaMode == "multiple">name) .toFlowable(LATEST) <#if descriptor.distinctUntilChanged> .distinctUntilChanged() + } + .subscribeOn(Schedulers.io()) //endregion diff --git a/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/BaseAccountScheme.kt b/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/BaseAccountScheme.kt index 5d37098..31dafc0 100644 --- a/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/BaseAccountScheme.kt +++ b/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/BaseAccountScheme.kt @@ -55,22 +55,4 @@ abstract class BaseAccountScheme(private val context: Context) { manager.addAccountExplicitly(account, password, null) } .subscribeOn(Schedulers.io()) - - /** - * Removes account associated with given email. - */ - open fun removeAccount(name: String): Completable = - Completable - .fromAction { - - // Retrieve account. - val account = manager - .getAccountsByType(provideAuthenticator()) - .first { it.name == name } - - // Remove account. - @Suppress("DEPRECATION") - manager.removeAccount(account, null, null) - } - .subscribeOn(Schedulers.io()) } diff --git a/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/MultipleAccountScheme.kt b/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/MultipleAccountScheme.kt index 9889ea8..e93b1d0 100644 --- a/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/MultipleAccountScheme.kt +++ b/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/MultipleAccountScheme.kt @@ -2,6 +2,8 @@ package co.windly.ktxaccount.runtime.scheme import android.accounts.Account import android.content.Context +import io.reactivex.Completable +import io.reactivex.schedulers.Schedulers /** * This scheme assumes MULTIPLE accounts for given authenticator can exist. @@ -41,5 +43,23 @@ abstract class MultipleAccountScheme(context: Context) : BaseAccountScheme(conte .firstOrNull { it.name == name } } + /** + * Removes account associated with given email. + */ + open fun removeAccount(name: String): Completable = + Completable + .fromAction { + + // Retrieve account. + val account = manager + .getAccountsByType(provideAuthenticator()) + .first { it.name == name } + + // Remove account. + @Suppress("DEPRECATION") + manager.removeAccount(account, null, null) + } + .subscribeOn(Schedulers.io()) + //endregion } diff --git a/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/SingleAccountScheme.kt b/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/SingleAccountScheme.kt index d556668..6819770 100644 --- a/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/SingleAccountScheme.kt +++ b/ktx-account-runtime/src/main/java/co/windly/ktxaccount/runtime/scheme/SingleAccountScheme.kt @@ -3,6 +3,7 @@ package co.windly.ktxaccount.runtime.scheme import android.accounts.Account import android.content.Context import io.reactivex.Completable +import io.reactivex.schedulers.Schedulers /** * This scheme assumes ONE and ONLY account for given authenticator will ever exist. @@ -28,6 +29,12 @@ abstract class SingleAccountScheme(context: Context) : BaseAccountScheme(context clearExistingAccounts() .andThen(super.saveAccount(name, password)) + /** + * Removes account associated with given email. + */ + open fun removeAccount(): Completable = + clearExistingAccounts() + /** * Retrieves an account associated with provided authenticator and identified by * given name. @@ -65,12 +72,15 @@ abstract class SingleAccountScheme(context: Context) : BaseAccountScheme(context .fromAction { // Clears all accounts associated with this authenticator. - manager.accounts.forEach { + manager + .getAccountsByType(provideAuthenticator()) + .forEach { @Suppress("DEPRECATION") manager.removeAccount(it, null, null) } } + .subscribeOn(Schedulers.io()) //endregion } diff --git a/samples/kotlin-dagger/src/main/java/co/windly/ktxaccount/sample/kotlindagger/presentation/main/MainActivity.kt b/samples/kotlin-dagger/src/main/java/co/windly/ktxaccount/sample/kotlindagger/presentation/main/MainActivity.kt index 23d5596..6fa8b27 100644 --- a/samples/kotlin-dagger/src/main/java/co/windly/ktxaccount/sample/kotlindagger/presentation/main/MainActivity.kt +++ b/samples/kotlin-dagger/src/main/java/co/windly/ktxaccount/sample/kotlindagger/presentation/main/MainActivity.kt @@ -153,7 +153,7 @@ class MainActivity : Activity() { // Remove account. manager - .removeAccount(name) + .removeAccount() .subscribe( ::handleRemoveAccountSuccess, ::handleRemoveAccountError