diff --git a/kotlin-extensions/src/main/java/ru/touchin/extensions/View.kt b/kotlin-extensions/src/main/java/ru/touchin/extensions/View.kt index d6e2920..5602cef 100644 --- a/kotlin-extensions/src/main/java/ru/touchin/extensions/View.kt +++ b/kotlin-extensions/src/main/java/ru/touchin/extensions/View.kt @@ -2,8 +2,9 @@ package ru.touchin.extensions import android.os.Build import android.view.View +import ru.touchin.utils.ActionThrottler -private const val RIPPLE_EFFECT_DELAY = 150L +const val RIPPLE_EFFECT_DELAY_MS = 150L /** * Sets click listener to view. On click it will call something after delay. @@ -12,7 +13,11 @@ private const val RIPPLE_EFFECT_DELAY = 150L */ fun View.setOnRippleClickListener(listener: () -> Unit) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - setOnClickListener { postDelayed({ if (hasWindowFocus()) listener() }, RIPPLE_EFFECT_DELAY) } + setOnClickListener { + ActionThrottler.throttleAction { + postDelayed({ if (hasWindowFocus()) listener() }, RIPPLE_EFFECT_DELAY_MS) + } + } } else { setOnClickListener { listener() } } diff --git a/kotlin-extensions/src/main/java/ru/touchin/utils/ActionThrottler.kt b/kotlin-extensions/src/main/java/ru/touchin/utils/ActionThrottler.kt new file mode 100644 index 0000000..8721e60 --- /dev/null +++ b/kotlin-extensions/src/main/java/ru/touchin/utils/ActionThrottler.kt @@ -0,0 +1,27 @@ +package ru.touchin.utils + +import android.os.SystemClock +import ru.touchin.extensions.RIPPLE_EFFECT_DELAY_MS + +object ActionThrottler { + + // It is necessary because in interval after ripple effect finish and before + // action invoking start user may be in time to click and launch action again + private const val PREVENTION_OF_CLICK_AGAIN_COEFFICIENT = 2 + private const val DELAY_MS = PREVENTION_OF_CLICK_AGAIN_COEFFICIENT * RIPPLE_EFFECT_DELAY_MS + private var lastActionTime = 0L + + fun throttleAction(action: () -> Unit): Boolean { + val currentTime = SystemClock.elapsedRealtime() + val diff = currentTime - lastActionTime + + return if (diff >= DELAY_MS) { + lastActionTime = currentTime + action.invoke() + true + } else { + false + } + } + +} diff --git a/lifecycle/src/main/java/ru/touchin/lifecycle/extensions/ImmutableExt.kt b/lifecycle/src/main/java/ru/touchin/lifecycle/extensions/ImmutableExt.kt new file mode 100644 index 0000000..a4c1873 --- /dev/null +++ b/lifecycle/src/main/java/ru/touchin/lifecycle/extensions/ImmutableExt.kt @@ -0,0 +1,6 @@ +package ru.touchin.lifecycle.extensions + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData + +fun MutableLiveData.toImmutable() = this as LiveData diff --git a/navigation-base/build.gradle b/navigation-base/build.gradle index 8d3b8e9..5aa8b2b 100644 --- a/navigation-base/build.gradle +++ b/navigation-base/build.gradle @@ -31,9 +31,6 @@ dependencies { implementation "androidx.fragment:fragment:$versions.fragment" implementation "androidx.fragment:fragment-ktx:$versions.fragment" - implementation "com.jakewharton:butterknife:$versions.butterknife" - kapt "com.jakewharton:butterknife-compiler:$versions.butterknife" - implementation("com.crashlytics.sdk.android:crashlytics:$versions.crashlytics@aar") { transitive = true } diff --git a/navigation-base/src/main/java/ru/touchin/roboswag/components/navigation_base/fragments/BaseFragment.kt b/navigation-base/src/main/java/ru/touchin/roboswag/components/navigation_base/fragments/BaseFragment.kt index e99477a..07c653e 100644 --- a/navigation-base/src/main/java/ru/touchin/roboswag/components/navigation_base/fragments/BaseFragment.kt +++ b/navigation-base/src/main/java/ru/touchin/roboswag/components/navigation_base/fragments/BaseFragment.kt @@ -15,9 +15,8 @@ import androidx.annotation.LayoutRes import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity -import butterknife.ButterKnife -import butterknife.Unbinder import ru.touchin.roboswag.components.navigation_base.BuildConfig +import ru.touchin.roboswag.components.navigation_base.LifecycleLoggingObserver open class BaseFragment(@LayoutRes layoutRes: Int) : Fragment(layoutRes) { @@ -54,8 +53,6 @@ open class BaseFragment(@Layo protected lateinit var state: TState private set - private lateinit var butterKnifeUnbinder: Unbinder - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -74,12 +71,6 @@ open class BaseFragment(@Layo super.onViewCreated(view, savedInstanceState) lifecycle.addObserver(LifecycleLoggingObserver(this)) - butterKnifeUnbinder = ButterKnife.bind(this, view) - } - - override fun onDestroyView() { - butterKnifeUnbinder.unbind() - super.onDestroyView() } override fun onSaveInstanceState(outState: Bundle) { diff --git a/rx-extensions/.gitignore b/rx-extensions/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/rx-extensions/.gitignore @@ -0,0 +1 @@ +/build diff --git a/rx-extensions/build.gradle b/rx-extensions/build.gradle new file mode 100644 index 0000000..3b49d3c --- /dev/null +++ b/rx-extensions/build.gradle @@ -0,0 +1,6 @@ +apply plugin: 'kotlin' + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "io.reactivex.rxjava2:rxjava:$versions.rxJava" +} diff --git a/rx-extensions/src/main/AndroidManifest.xml b/rx-extensions/src/main/AndroidManifest.xml new file mode 100644 index 0000000..afb773f --- /dev/null +++ b/rx-extensions/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/rx-extensions/src/main/java/ru/touchin/extensions/rx/Flowable.kt b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Flowable.kt new file mode 100644 index 0000000..043cf09 --- /dev/null +++ b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Flowable.kt @@ -0,0 +1,8 @@ +package ru.touchin.extensions.rx + +import io.reactivex.Completable +import io.reactivex.Flowable + +fun Flowable.emitAfter(other: Completable): Flowable = this.flatMap { value -> + other.andThen(Flowable.just(value)) +} diff --git a/rx-extensions/src/main/java/ru/touchin/extensions/rx/Maybe.kt b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Maybe.kt new file mode 100644 index 0000000..5f5fe6c --- /dev/null +++ b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Maybe.kt @@ -0,0 +1,8 @@ +package ru.touchin.extensions.rx + +import io.reactivex.Completable +import io.reactivex.Maybe + +fun Maybe.emitAfter(other: Completable): Maybe = this.flatMap { value -> + other.andThen(Maybe.just(value)) +} diff --git a/rx-extensions/src/main/java/ru/touchin/extensions/rx/Observable.kt b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Observable.kt new file mode 100644 index 0000000..0c5a8c5 --- /dev/null +++ b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Observable.kt @@ -0,0 +1,8 @@ +package ru.touchin.extensions.rx + +import io.reactivex.Completable +import io.reactivex.Observable + +fun Observable.emitAfter(other: Completable): Observable = this.flatMap { value -> + other.andThen(Observable.just(value)) +} diff --git a/rx-extensions/src/main/java/ru/touchin/extensions/rx/Single.kt b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Single.kt new file mode 100644 index 0000000..9c3b6c7 --- /dev/null +++ b/rx-extensions/src/main/java/ru/touchin/extensions/rx/Single.kt @@ -0,0 +1,8 @@ +package ru.touchin.extensions.rx + +import io.reactivex.Completable +import io.reactivex.Single + +fun Single.emitAfter(other: Completable): Single = this.flatMap { value -> + other.andThen(Single.just(value)) +}