diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 00000000..0dd4b354
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460d..00000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a8ca5d97..0f367f9a 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -52,7 +52,7 @@ dependencies {
implementation(featureMain)
implementation(featureAdd)
- implementation(deps.jetbrains.coroutinesAndroid)
+ implementation(deps.coroutines.android)
implementation(deps.koin.android)
testImplementation(deps.test.junit)
diff --git a/build.gradle.kts b/build.gradle.kts
index f05f118e..1b48d85e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,17 +1,17 @@
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- val kotlinVersion by extra("1.4.0-rc")
repositories {
google()
- jcenter()
- maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
+ mavenCentral()
gradlePluginPortal()
}
dependencies {
- classpath("com.android.tools.build:gradle:4.0.1")
+ classpath("com.android.tools.build:gradle:4.0.2")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
- classpath("com.diffplug.spotless:spotless-plugin-gradle:5.3.0")
+ classpath("com.diffplug.spotless:spotless-plugin-gradle:5.10.0")
}
}
@@ -61,19 +61,20 @@ subprojects {
}
allprojects {
- tasks.withType {
+ tasks.withType {
kotlinOptions {
- jvmTarget = JavaVersion.VERSION_1_8.toString()
- sourceCompatibility = JavaVersion.VERSION_1_8.toString()
- targetCompatibility = JavaVersion.VERSION_1_8.toString()
+ useIR = true
+
+ val version = JavaVersion.VERSION_1_8.toString()
+ jvmTarget = version
+ sourceCompatibility = version
+ targetCompatibility = version
}
}
repositories {
google()
- jcenter()
mavenCentral()
- maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
}
}
diff --git a/buildSrc/src/main/kotlin/deps.kt b/buildSrc/src/main/kotlin/deps.kt
index f41e1dc6..7c9f9804 100644
--- a/buildSrc/src/main/kotlin/deps.kt
+++ b/buildSrc/src/main/kotlin/deps.kt
@@ -5,8 +5,8 @@ import org.gradle.kotlin.dsl.project
import org.gradle.plugin.use.PluginDependenciesSpec
import org.gradle.plugin.use.PluginDependencySpec
-const val ktlintVersion = "0.38.1"
-const val kotlinVersion = "1.4.10"
+const val ktlintVersion = "0.41.0"
+const val kotlinVersion = "1.5.0-M1"
object appConfig {
const val applicationId = "com.hoc.flowmvi"
@@ -22,16 +22,16 @@ object appConfig {
object deps {
object androidx {
- const val appCompat = "androidx.appcompat:appcompat:1.3.0-alpha02"
- const val coreKtx = "androidx.core:core-ktx:1.5.0-alpha02"
- const val constraintLayout = "androidx.constraintlayout:constraintlayout:2.0.1"
- const val recyclerView = "androidx.recyclerview:recyclerview:1.2.0-alpha05"
+ const val appCompat = "androidx.appcompat:appcompat:1.3.0-rc01"
+ const val coreKtx = "androidx.core:core-ktx:1.6.0-alpha01"
+ const val constraintLayout = "androidx.constraintlayout:constraintlayout:2.1.0-beta01"
+ const val recyclerView = "androidx.recyclerview:recyclerview:1.2.0-rc01"
const val swipeRefreshLayout = "androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01"
- const val material = "com.google.android.material:material:1.3.0-alpha02"
+ const val material = "com.google.android.material:material:1.4.0-alpha01"
}
object lifecycle {
- private const val version = "2.3.0-beta01"
+ private const val version = "2.4.0-alpha01"
const val viewModelKtx = "androidx.lifecycle:lifecycle-viewmodel-ktx:$version" // viewModelScope
const val runtimeKtx = "androidx.lifecycle:lifecycle-runtime-ktx:$version" // lifecycleScope
@@ -41,26 +41,25 @@ object deps {
object squareup {
const val retrofit = "com.squareup.retrofit2:retrofit:2.9.0"
const val converterMoshi = "com.squareup.retrofit2:converter-moshi:2.9.0"
- const val loggingInterceptor = "com.squareup.okhttp3:logging-interceptor:4.8.1"
- const val moshiKotlin = "com.squareup.moshi:moshi-kotlin:1.10.0"
+ const val loggingInterceptor = "com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2"
+ const val moshiKotlin = "com.squareup.moshi:moshi-kotlin:1.11.0"
}
- object jetbrains {
- private const val version = "1.4.0"
+ object coroutines {
+ private const val version = "1.4.3"
- const val coroutinesCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version"
- const val coroutinesAndroid = "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version"
+ const val core = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version"
+ const val android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version"
}
object koin {
- private const val version = "2.2.2"
+ private const val version = "3.0.1-beta-2"
- const val androidXViewModel = "org.koin:koin-androidx-viewmodel:$version"
- const val core = "org.koin:koin-core:$version"
- const val android = "org.koin:koin-android:$version"
+ const val core = "io.insert-koin:koin-core:$version"
+ const val android = "io.insert-koin:koin-android:$version"
}
- const val coil = "io.coil-kt:coil:1.0.0"
+ const val coil = "io.coil-kt:coil:1.1.1"
object test {
const val junit = "junit:junit:4.13"
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
index 31353c20..0770677d 100644
--- a/core/build.gradle.kts
+++ b/core/build.gradle.kts
@@ -34,8 +34,8 @@ android {
}
dependencies {
- implementation(deps.jetbrains.coroutinesCore)
- implementation(deps.jetbrains.coroutinesAndroid)
+ implementation(deps.coroutines.core)
+ implementation(deps.coroutines.android)
implementation(deps.androidx.coreKtx)
implementation(deps.androidx.swipeRefreshLayout)
diff --git a/core/src/main/java/com/hoc/flowmvi/core/Flow+LaunchIn.kt b/core/src/main/java/com/hoc/flowmvi/core/Flow+LaunchIn.kt
deleted file mode 100644
index 69d305d7..00000000
--- a/core/src/main/java/com/hoc/flowmvi/core/Flow+LaunchIn.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.hoc.flowmvi.core
-
-import androidx.lifecycle.DefaultLifecycleObserver
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.lifecycleScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.launchIn
-
-fun Flow.launchWhenStartedUntilStopped(owner: LifecycleOwner) {
- if (owner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
- // ignore
- return
- }
- owner.lifecycle.addObserver(LifecycleBoundObserver(this))
-}
-
-private class LifecycleBoundObserver(private val flow: Flow<*>) : DefaultLifecycleObserver {
- private var job: Job? = null
-
- override fun onStart(owner: LifecycleOwner) {
- job = flow.launchIn(owner.lifecycleScope)
- }
-
- override fun onStop(owner: LifecycleOwner) {
- cancelJob()
- }
-
- override fun onDestroy(owner: LifecycleOwner) {
- super.onDestroy(owner)
- owner.lifecycle.removeObserver(this)
- cancelJob()
- }
-
- @Suppress("NOTHING_TO_INLINE")
- private inline fun cancelJob() {
- job?.cancel()
- job = null
- }
-}
diff --git a/data/build.gradle.kts b/data/build.gradle.kts
index d32375fe..58f18ee4 100644
--- a/data/build.gradle.kts
+++ b/data/build.gradle.kts
@@ -37,7 +37,7 @@ dependencies {
implementation(core)
implementation(domain)
- implementation(deps.jetbrains.coroutinesCore)
+ implementation(deps.coroutines.core)
implementation(deps.squareup.retrofit)
implementation(deps.squareup.moshiKotlin)
diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts
index 6cc7bff5..45c82b6d 100644
--- a/domain/build.gradle.kts
+++ b/domain/build.gradle.kts
@@ -3,6 +3,6 @@ plugins {
}
dependencies {
- implementation(deps.jetbrains.coroutinesCore)
+ implementation(deps.coroutines.core)
implementation(deps.koin.core)
}
diff --git a/feature-add/build.gradle.kts b/feature-add/build.gradle.kts
index 0d7f4a7f..f4ca0597 100644
--- a/feature-add/build.gradle.kts
+++ b/feature-add/build.gradle.kts
@@ -48,6 +48,6 @@ dependencies {
implementation(deps.androidx.constraintLayout)
implementation(deps.androidx.material)
- implementation(deps.jetbrains.coroutinesCore)
- implementation(deps.koin.androidXViewModel)
+ implementation(deps.coroutines.core)
+ implementation(deps.koin.android)
}
diff --git a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt
index 9c1decce..89f89272 100644
--- a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt
+++ b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt
@@ -7,12 +7,13 @@ import android.util.Log
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isInvisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import com.hoc.flowmvi.core.clicks
import com.hoc.flowmvi.core.firstChange
-import com.hoc.flowmvi.core.launchWhenStartedUntilStopped
import com.hoc.flowmvi.core.navigator.IntentProviders
import com.hoc.flowmvi.core.textChanges
import com.hoc.flowmvi.core.toast
@@ -24,14 +25,13 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
-import org.koin.androidx.viewmodel.ext.android.viewModel
-import org.koin.androidx.viewmodel.scope.emptyState
+import org.koin.androidx.viewmodel.ext.android.stateViewModel
import kotlin.LazyThreadSafetyMode.NONE
@FlowPreview
@ExperimentalCoroutinesApi
class AddActivity : AppCompatActivity() {
- private val addVM by viewModel(state = emptyState())
+ private val addVM by stateViewModel()
private val addBinding by lazy(NONE) { ActivityAddBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
@@ -54,12 +54,14 @@ class AddActivity : AppCompatActivity() {
// observe view model
addVM.viewState
.onEach { render(it) }
- .launchWhenStartedUntilStopped(this)
+ .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
+ .launchIn(lifecycleScope)
// observe single event
addVM.singleEvent
.onEach { handleSingleEvent(it) }
- .launchWhenStartedUntilStopped(this)
+ .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
+ .launchIn(lifecycleScope)
// pass view intent to view model
intents()
diff --git a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt
index 0c1c33da..5fb56d91 100644
--- a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt
+++ b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt
@@ -9,10 +9,10 @@ import org.koin.dsl.module
@ExperimentalCoroutinesApi
@FlowPreview
val addModule = module {
- viewModel {
+ viewModel { params ->
AddVM(
addUser = get(),
- savedStateHandle = it.get(),
+ savedStateHandle = params.get(),
)
}
diff --git a/feature-main/build.gradle.kts b/feature-main/build.gradle.kts
index 6ec302c8..1505c100 100644
--- a/feature-main/build.gradle.kts
+++ b/feature-main/build.gradle.kts
@@ -50,7 +50,7 @@ dependencies {
implementation(deps.androidx.swipeRefreshLayout)
implementation(deps.androidx.material)
- implementation(deps.jetbrains.coroutinesCore)
- implementation(deps.koin.androidXViewModel)
+ implementation(deps.coroutines.core)
+ implementation(deps.koin.android)
implementation(deps.coil)
}
diff --git a/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt b/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt
index 917445db..f2bef2ac 100644
--- a/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt
+++ b/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt
@@ -6,6 +6,8 @@ import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.ItemTouchHelper
@@ -13,7 +15,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.hoc.flowmvi.core.SwipeLeftToDeleteCallback
import com.hoc.flowmvi.core.clicks
-import com.hoc.flowmvi.core.launchWhenStartedUntilStopped
import com.hoc.flowmvi.core.navigator.Navigator
import com.hoc.flowmvi.core.refreshes
import com.hoc.flowmvi.core.safeOffer
@@ -86,12 +87,14 @@ class MainActivity : AppCompatActivity() {
// observe view model
mainVM.viewState
.onEach { render(it) }
- .launchWhenStartedUntilStopped(this)
+ .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
+ .launchIn(lifecycleScope)
// observe single event
mainVM.singleEvent
.onEach { handleSingleEvent(it) }
- .launchWhenStartedUntilStopped(this)
+ .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
+ .launchIn(lifecycleScope)
// pass view intent to view model
intents()