From 7190f38653a469912d73beb659c20ec706a15840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adriel=20Caf=C3=A9?= Date: Sun, 3 Nov 2019 17:30:44 -0300 Subject: [PATCH] refactor: simplify di, normalize strings when filtering (#41) --- .../com/jcaique/dialetus/data/di/injection.kt | 5 ++- .../dialetus/data/mappers/RegionsMapper.kt | 1 + .../dialetus/presentation/di/injection.kt | 31 +++----------- .../dialects/DialectsViewModel.kt | 16 ++++--- .../utils/extensions/dependency_injection.kt | 42 ------------------- .../dialetus/utils/extensions/di_ktx.kt | 42 +++++++++++++++++++ .../dialetus/utils/extensions/strings_ktx.kt | 10 ++++- 7 files changed, 72 insertions(+), 75 deletions(-) delete mode 100644 utils/src/main/java/com/jcaique/dialetus/utils/extensions/dependency_injection.kt create mode 100644 utils/src/main/java/com/jcaique/dialetus/utils/extensions/di_ktx.kt diff --git a/data/src/main/java/com/jcaique/dialetus/data/di/injection.kt b/data/src/main/java/com/jcaique/dialetus/data/di/injection.kt index 099955d..f4a6450 100644 --- a/data/src/main/java/com/jcaique/dialetus/data/di/injection.kt +++ b/data/src/main/java/com/jcaique/dialetus/data/di/injection.kt @@ -14,8 +14,9 @@ import org.kodein.di.generic.bind import org.kodein.di.generic.instance import org.kodein.di.generic.singleton -private val interceptors = - listOf(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }) +private val interceptors = listOf( + HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } +) val dataModule = Kodein.Module(name = "network") { diff --git a/data/src/main/java/com/jcaique/dialetus/data/mappers/RegionsMapper.kt b/data/src/main/java/com/jcaique/dialetus/data/mappers/RegionsMapper.kt index 0388e13..81e163d 100644 --- a/data/src/main/java/com/jcaique/dialetus/data/mappers/RegionsMapper.kt +++ b/data/src/main/java/com/jcaique/dialetus/data/mappers/RegionsMapper.kt @@ -4,6 +4,7 @@ import com.jcaique.dialetus.data.responses.RegionResponse import com.jcaique.dialetus.domain.models.Region internal object RegionsMapper { + fun toDomain(response: RegionResponse): Region = Region(response.name, response.total) } diff --git a/presentation/src/main/java/com/jcaique/dialetus/presentation/di/injection.kt b/presentation/src/main/java/com/jcaique/dialetus/presentation/di/injection.kt index 904a3fb..bab9cc1 100644 --- a/presentation/src/main/java/com/jcaique/dialetus/presentation/di/injection.kt +++ b/presentation/src/main/java/com/jcaique/dialetus/presentation/di/injection.kt @@ -5,9 +5,8 @@ import com.jcaique.dialetus.presentation.dialects.DialectsViewModel import com.jcaique.dialetus.presentation.regions.RegionsPresentation import com.jcaique.dialetus.presentation.regions.RegionsViewModel import com.jcaique.dialetus.utils.KodeinTags -import com.jcaique.dialetus.utils.dataflow.ConfigChangesAwareStateContainer -import com.jcaique.dialetus.utils.dataflow.StateMachine -import com.jcaique.dialetus.utils.dataflow.TaskExecutor +import com.jcaique.dialetus.utils.extensions.newStateContainer +import com.jcaique.dialetus.utils.extensions.newStateMachine import org.kodein.di.Kodein import org.kodein.di.generic.bind import org.kodein.di.generic.instance @@ -16,17 +15,8 @@ import org.kodein.di.generic.provider val presentationModule = Kodein.Module(name = "presentation") { bind() from provider { - val stateContainer = - ConfigChangesAwareStateContainer( - host = instance(KodeinTags.hostActivity) - ) - val stateMachine = StateMachine( - container = stateContainer, - executor = TaskExecutor.Concurrent( - scope = stateContainer.emissionScope, - dispatcher = instance() - ) - ) + val stateContainer = newStateContainer(KodeinTags.hostActivity) + val stateMachine = newStateMachine(stateContainer) RegionsViewModel( service = instance(), @@ -35,17 +25,8 @@ val presentationModule = Kodein.Module(name = "presentation") { } bind() from provider { - val stateContainer = - ConfigChangesAwareStateContainer( - host = instance(KodeinTags.hostActivity) - ) - val stateMachine = StateMachine( - container = stateContainer, - executor = TaskExecutor.Concurrent( - scope = stateContainer.emissionScope, - dispatcher = instance() - ) - ) + val stateContainer = newStateContainer(KodeinTags.hostActivity) + val stateMachine = newStateMachine(stateContainer) DialectsViewModel( machine = stateMachine, diff --git a/presentation/src/main/java/com/jcaique/dialetus/presentation/dialects/DialectsViewModel.kt b/presentation/src/main/java/com/jcaique/dialetus/presentation/dialects/DialectsViewModel.kt index a2368d6..6b9a0c6 100644 --- a/presentation/src/main/java/com/jcaique/dialetus/presentation/dialects/DialectsViewModel.kt +++ b/presentation/src/main/java/com/jcaique/dialetus/presentation/dialects/DialectsViewModel.kt @@ -6,6 +6,7 @@ import com.jcaique.dialetus.utils.dataflow.StateMachine import com.jcaique.dialetus.utils.dataflow.StateTransition import com.jcaique.dialetus.utils.dataflow.UnsupportedUserInteraction import com.jcaique.dialetus.utils.dataflow.UserInteraction +import com.jcaique.dialetus.utils.extensions.normalize import kotlinx.coroutines.coroutineScope internal class DialectsViewModel( @@ -35,15 +36,13 @@ internal class DialectsViewModel( else -> throw UnsupportedUserInteraction } - // TODO get dialects from service private suspend fun showDialects( parameters: StateTransition.Parameters ): DialectsPresentation = coroutineScope { val interaction = parameters as ShowDialects - dialects = service.getDialectsBy(interaction.region.name.toLowerCase()) - - dialects + service + .getDialectsBy(interaction.region.name.toLowerCase()) .let(::DialectsPresentation) } @@ -53,7 +52,14 @@ internal class DialectsViewModel( val interaction = parameters as FilterDialects dialects - .filter { it.dialect.contains(interaction.query, ignoreCase = true) } + .filter { + it.dialect + .normalize() + .contains( + other = interaction.query.normalize(), + ignoreCase = true + ) + } .let(::DialectsPresentation) } } diff --git a/utils/src/main/java/com/jcaique/dialetus/utils/extensions/dependency_injection.kt b/utils/src/main/java/com/jcaique/dialetus/utils/extensions/dependency_injection.kt deleted file mode 100644 index 2999c3c..0000000 --- a/utils/src/main/java/com/jcaique/dialetus/utils/extensions/dependency_injection.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.jcaique.dialetus.utils.extensions - -import androidx.appcompat.app.AppCompatActivity -import androidx.fragment.app.FragmentActivity -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelProviders -import com.jcaique.dialetus.utils.KodeinTags.hostActivity -import org.kodein.di.Kodein -import org.kodein.di.KodeinAware -import org.kodein.di.direct -import org.kodein.di.generic.bind -import org.kodein.di.generic.instance -import org.kodein.di.generic.instanceOrNull -import org.kodein.di.generic.provider - -@Suppress("UNCHECKED_CAST") -inline fun KodeinAware.viewModel() = lazy { - - val factory = object : ViewModelProvider.Factory { - override fun create(klass: Class) = - direct.instance() as Model - } - - val host = direct.instanceOrNull() - ?: throw IllegalStateException("Host Activity not attached on this graph") - - ViewModelProviders.of(host, factory).get(VM::class.java) -} - -fun AppCompatActivity.selfInject(bindings: Kodein.MainBuilder.() -> Unit = {}) = Kodein.lazy { - - val parentKodein = (applicationContext as KodeinAware).kodein - - extend(parentKodein) - - bind(tag = hostActivity) with provider { - this@selfInject - } - - bindings.invoke(this) -} diff --git a/utils/src/main/java/com/jcaique/dialetus/utils/extensions/di_ktx.kt b/utils/src/main/java/com/jcaique/dialetus/utils/extensions/di_ktx.kt new file mode 100644 index 0000000..c558d82 --- /dev/null +++ b/utils/src/main/java/com/jcaique/dialetus/utils/extensions/di_ktx.kt @@ -0,0 +1,42 @@ +package com.jcaique.dialetus.utils.extensions + +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.FragmentActivity +import com.jcaique.dialetus.utils.KodeinTags.hostActivity +import com.jcaique.dialetus.utils.dataflow.ConfigChangesAwareStateContainer +import com.jcaique.dialetus.utils.dataflow.StateContainer +import com.jcaique.dialetus.utils.dataflow.StateMachine +import com.jcaique.dialetus.utils.dataflow.TaskExecutor +import org.kodein.di.Kodein +import org.kodein.di.KodeinAware +import org.kodein.di.bindings.NoArgBindingKodein +import org.kodein.di.generic.bind +import org.kodein.di.generic.instance +import org.kodein.di.generic.provider + +fun AppCompatActivity.selfInject(bindings: Kodein.MainBuilder.() -> Unit = {}) = Kodein.lazy { + + val parentKodein = (applicationContext as KodeinAware).kodein + + extend(parentKodein) + + bind(tag = hostActivity) with provider { + this@selfInject + } + + bindings.invoke(this) +} + +fun NoArgBindingKodein<*>.newStateContainer(tag: String) = + ConfigChangesAwareStateContainer( + host = instance(tag) + ) + +fun NoArgBindingKodein<*>.newStateMachine(stateContainer: StateContainer) = + StateMachine( + container = stateContainer, + executor = TaskExecutor.Concurrent( + scope = stateContainer.emissionScope, + dispatcher = instance() + ) + ) diff --git a/utils/src/main/java/com/jcaique/dialetus/utils/extensions/strings_ktx.kt b/utils/src/main/java/com/jcaique/dialetus/utils/extensions/strings_ktx.kt index 99611c8..7cb0265 100644 --- a/utils/src/main/java/com/jcaique/dialetus/utils/extensions/strings_ktx.kt +++ b/utils/src/main/java/com/jcaique/dialetus/utils/extensions/strings_ktx.kt @@ -3,10 +3,18 @@ package com.jcaique.dialetus.utils.extensions import android.app.Activity import android.content.ClipDescription import androidx.core.app.ShareCompat +import java.text.Normalizer -fun String.share(activity: Activity) = +private val REGEX_NORMALIZE = "\\p{InCombiningDiacriticalMarks}+".toRegex() + +fun CharSequence.share(activity: Activity) = ShareCompat.IntentBuilder .from(activity) .setText(this) .setType(ClipDescription.MIMETYPE_TEXT_PLAIN) .startChooser() + +fun CharSequence.normalize(): String { + val temp = Normalizer.normalize(this, Normalizer.Form.NFD) + return REGEX_NORMALIZE.replace(temp, "") +}