From ea1804cc6b2f603a22017a93e4e56c9c784d7467 Mon Sep 17 00:00:00 2001 From: Aksenov Vladimir Date: Wed, 5 Feb 2020 15:21:55 +0300 Subject: [PATCH 01/12] Migrate FB crashlytics --- build.gradle | 2 +- navigation/build.gradle | 6 ++-- .../components/navigation/TouchinApp.java | 28 +++++++++---------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/build.gradle b/build.gradle index 65450e5..eb10492 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ ext { retrofit : '2.4.0', rxJava : '2.2.2', rxAndroid : '2.1.0', - crashlytics : '2.9.5', + crashlytics : '17.0.0-beta01', location : '16.0.0', coreKtx : '1.0.1', yandex_mapkit: '3.4.0', diff --git a/navigation/build.gradle b/navigation/build.gradle index c4fa596..bb97748 100644 --- a/navigation/build.gradle +++ b/navigation/build.gradle @@ -27,8 +27,6 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "androidx.appcompat:appcompat:$versions.appcompat" - - implementation("com.crashlytics.sdk.android:crashlytics:$versions.crashlytics@aar") { - transitive = true - } + + implementation "com.google.firebase:firebase-crashlytics:$versions.crashlytics" } diff --git a/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java index 49f4047..b95c2e0 100644 --- a/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java +++ b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java @@ -24,7 +24,7 @@ import android.content.Context; import android.os.StrictMode; import android.util.Log; -import com.crashlytics.android.Crashlytics; +import com.google.firebase.crashlytics.FirebaseCrashlytics; import net.danlew.android.joda.JodaTimeAndroid; @@ -34,7 +34,6 @@ import java.util.List; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.multidex.MultiDex; -import io.fabric.sdk.android.Fabric; import ru.touchin.roboswag.core.log.ConsoleLogProcessor; import ru.touchin.roboswag.core.log.Lc; import ru.touchin.roboswag.core.log.LcGroup; @@ -65,16 +64,13 @@ public abstract class TouchinApp extends Application { LcGroup.UI_LIFECYCLE.disable(); } else { try { - final Crashlytics crashlytics = new Crashlytics(); - Fabric.with(this, crashlytics); - Fabric.getLogger().setLogLevel(Log.ERROR); + final FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); + crashlytics.setCrashlyticsCollectionEnabled(true); Lc.initialize(new CrashlyticsLogProcessor(crashlytics), false); } catch (final NoClassDefFoundError error) { Lc.initialize(new ConsoleLogProcessor(LcLevel.INFO), false); Lc.e("Crashlytics initialization error! Did you forget to add\n" - + "compile('com.crashlytics.sdk.android:crashlytics:+@aar') {\n" - + " transitive = true;\n" - + "}\n" + + "com.google.firebase:firebase-crashlytics\n" + "to your build.gradle?", error); } } @@ -96,13 +92,17 @@ public abstract class TouchinApp extends Application { private static class CrashlyticsLogProcessor extends LogProcessor { @NonNull - private final Crashlytics crashlytics; + private final FirebaseCrashlytics crashlytics; - public CrashlyticsLogProcessor(@NonNull final Crashlytics crashlytics) { + public CrashlyticsLogProcessor(@NonNull final FirebaseCrashlytics crashlytics) { super(LcLevel.INFO); this.crashlytics = crashlytics; } + private String getLogMessage(final int priorityLevel, final String tag, final String message) { + return "Priority:" + priorityLevel + ' ' + tag + ':' + message; + } + @Override public void processLogMessage(@NonNull final LcGroup group, @NonNull final LcLevel level, @@ -110,17 +110,17 @@ public abstract class TouchinApp extends Application { @NonNull final String message, @Nullable final Throwable throwable) { if (group == LcGroup.UI_LIFECYCLE) { - crashlytics.core.log(level.getPriority(), tag, message); + crashlytics.log(getLogMessage(level.getPriority(), tag, message)); } else if (!level.lessThan(LcLevel.ASSERT) || (group == ApiModel.API_VALIDATION_LC_GROUP && level == LcLevel.ERROR)) { Log.e(tag, message); if (throwable != null) { - crashlytics.core.log(level.getPriority(), tag, message); - crashlytics.core.logException(throwable); + crashlytics.log(getLogMessage(level.getPriority(), tag, message)); + crashlytics.recordException(throwable); } else { final ShouldNotHappenException exceptionToLog = new ShouldNotHappenException(tag + ':' + message); reduceStackTrace(exceptionToLog); - crashlytics.core.logException(exceptionToLog); + crashlytics.recordException(exceptionToLog); } } } From e9bf8e29d0a5a4ded4d2f13efdb4148135cc3857 Mon Sep 17 00:00:00 2001 From: Aksenov Vladimir Date: Wed, 5 Feb 2020 19:23:13 +0300 Subject: [PATCH 02/12] Upd naming --- build.gradle | 1 - navigation/build.gradle | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index eb10492..3ae8bcf 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,6 @@ ext { retrofit : '2.4.0', rxJava : '2.2.2', rxAndroid : '2.1.0', - crashlytics : '17.0.0-beta01', location : '16.0.0', coreKtx : '1.0.1', yandex_mapkit: '3.4.0', diff --git a/navigation/build.gradle b/navigation/build.gradle index bb97748..284cb76 100644 --- a/navigation/build.gradle +++ b/navigation/build.gradle @@ -28,5 +28,5 @@ dependencies { implementation "androidx.appcompat:appcompat:$versions.appcompat" - implementation "com.google.firebase:firebase-crashlytics:$versions.crashlytics" + implementation "com.google.firebase:firebase-crashlytics:$versions.crashlyticsFirebase" } From 0ee9f72e266c4d49b329959fac3c094cd3c090fa Mon Sep 17 00:00:00 2001 From: Aksenov Vladimir Date: Thu, 6 Feb 2020 13:08:01 +0300 Subject: [PATCH 03/12] Removed useless deps. --- build.gradle | 21 +-------------------- navigation/build.gradle | 2 +- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index 3ae8bcf..235e5bf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,4 @@ buildscript { - ext.kotlin_version = '1.3.50' repositories { google() jcenter() @@ -23,22 +22,4 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir -} - -ext { - versions = [ - compileSdk : 29, - appcompat : '1.0.2', - androidx : '1.0.0', - material : '1.0.0', - lifecycle : '2.0.0', - dagger : '2.17', - retrofit : '2.4.0', - rxJava : '2.2.2', - rxAndroid : '2.1.0', - location : '16.0.0', - coreKtx : '1.0.1', - yandex_mapkit: '3.4.0', - google_maps : '16.1.0' - ] -} +} \ No newline at end of file diff --git a/navigation/build.gradle b/navigation/build.gradle index 284cb76..20cec33 100644 --- a/navigation/build.gradle +++ b/navigation/build.gradle @@ -28,5 +28,5 @@ dependencies { implementation "androidx.appcompat:appcompat:$versions.appcompat" - implementation "com.google.firebase:firebase-crashlytics:$versions.crashlyticsFirebase" + implementation "com.google.firebase:firebase-crashlytics:$versions.firebaseCrashlytics" } From 2302fbc16d4e6250136ab17da65b554217ef0a4f Mon Sep 17 00:00:00 2001 From: Aksenov Vladimir Date: Thu, 6 Feb 2020 13:09:17 +0300 Subject: [PATCH 04/12] Added new line --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 235e5bf..41d4c15 100644 --- a/build.gradle +++ b/build.gradle @@ -22,4 +22,4 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir -} \ No newline at end of file +} From 6c795a6f4a01df0003e9f59bfb3c1249cb406799 Mon Sep 17 00:00:00 2001 From: Stanislav Date: Wed, 12 Feb 2020 19:49:43 +0300 Subject: [PATCH 05/12] fixed inner navigation with navigation_new & tabbarnavigation_new fixed inner navigation with navigation_new & tabbarnavigation_new --- .../tabbarnavigation_new/BottomNavigationController.kt | 2 +- .../tabbarnavigation_new/NavigationContainerFragment.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/BottomNavigationController.kt b/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/BottomNavigationController.kt index 67c0f95..f14504b 100644 --- a/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/BottomNavigationController.kt +++ b/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/BottomNavigationController.kt @@ -84,7 +84,7 @@ class BottomNavigationController( fragment = if (wrapWithNavigationContainer) { Fragment.instantiate( context, - fragmentClass.name, + NavigationContainerFragment::class.java.name, NavigationContainerFragment.args(fragmentClass, fragmentState, contentContainerViewId, contentContainerLayoutId) ) } else { diff --git a/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/NavigationContainerFragment.kt b/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/NavigationContainerFragment.kt index 160f883..3d9e5a9 100644 --- a/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/NavigationContainerFragment.kt +++ b/tabbar-navigation-new/src/main/java/ru/touchin/roboswag/components/tabbarnavigation_new/NavigationContainerFragment.kt @@ -67,7 +67,7 @@ class NavigationContainerFragment : Fragment() { containerLayoutId = getInt(CONTAINER_LAYOUT_ID_ARG) transition = getInt(TRANSITION_ARG) } - navigation.setInitial(getFragmentClass(), args.getParcelable(FRAGMENT_STATE_ARG)) + navigation.setInitial(getFragmentClass().kotlin, args.getParcelable(FRAGMENT_STATE_ARG)) } } From 69f269528e5ba0ad5234190a56dc1a625c348e02 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Thu, 13 Feb 2020 12:57:51 +0300 Subject: [PATCH 06/12] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 53640c2..3413e51 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ Roboswag - библиотека решений, ускоряющих разра * Andoroid Api: 19 * Kotlin: 1.3.11 * Gradle: 3.2.1 -* Gradle CPD Plugin: 1.1 -* Detekt Plugin: 1.0.0-RC12 ## Основная архитектура За основу архитектуры взят подход от Google - MVVM на основе [Android Architecture Components](https://developer.android.com/jetpack/docs/guide). Данный подход популярен в сообществе Android разработки, позволяет разбивать код на мелкие и независимые части, что ускоряет разработку и последующую поддержку приложения. @@ -22,10 +20,6 @@ Roboswag позволяет сочетать эти три решения в о ## Основные инструменты библиотеки ### Работа с RecyclerView RecyclerView - один из самых часто используемых инструментов Android разработчика. Модуль [recyclerview-adapters](/recyclerview-adapters) позволяет сделать работу с RecyclerView более гибкой и делает работу самого элемента быстрее. -### BuildScripts -[BuildScrpts](https://github.com/TouchInstinct/BuildScripts) - набор скриптов, автоматизирующих разработку. Один из главных скриптов - staticAnalysis - инструмент для автоматической проверки кода на соответствие правилам компании. -### Api Generator -Внутренний инструмент компании Touch Instinct для генерации общего кода на разные платформы - Android, iOS и Server. Описанные в одном месте общие классы и Http методы используются на разных платформах. Данный инструмент позволяет сократить время разработки в два раза. ### Работа с SharedPreferences Чтобы сохранять простые данные в память смартфона, используются SharedPreferences. Модуль [storable](/storable) разработан для облегчения работы с SharedPreferences. ### Утилиты и extension функции From 672936b8c1e1c931b7cf43a20bde1754306aaf55 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Thu, 13 Feb 2020 13:46:05 +0300 Subject: [PATCH 07/12] add java version to kotlin compile --- lifecycle/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lifecycle/build.gradle b/lifecycle/build.gradle index 41a0ebb..f67ddbe 100644 --- a/lifecycle/build.gradle +++ b/lifecycle/build.gradle @@ -12,6 +12,10 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } } dependencies { From 833215eb6d2602b6cbcc2f3a5fc4dac999c3a139 Mon Sep 17 00:00:00 2001 From: Stanisalv Date: Tue, 10 Mar 2020 15:56:15 +0300 Subject: [PATCH 08/12] fix outOfBoundsException in delegationListAdapter --- .../main/java/ru/touchin/adapters/DelegationListAdapter.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recyclerview-adapters/src/main/java/ru/touchin/adapters/DelegationListAdapter.kt b/recyclerview-adapters/src/main/java/ru/touchin/adapters/DelegationListAdapter.kt index 8328211..a47fbe6 100644 --- a/recyclerview-adapters/src/main/java/ru/touchin/adapters/DelegationListAdapter.kt +++ b/recyclerview-adapters/src/main/java/ru/touchin/adapters/DelegationListAdapter.kt @@ -1,10 +1,10 @@ package ru.touchin.adapters +import android.view.ViewGroup import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import android.view.ViewGroup import ru.touchin.extensions.setOnRippleClickListener /** @@ -36,7 +36,7 @@ open class DelegationListAdapter(config: AsyncDifferConfig) : Recy if (collectionPosition in 0 until getList().size) { if (itemClickListener != null) { holder.itemView.setOnRippleClickListener { - itemClickListener?.invoke(getList()[getCollectionPosition(holder.adapterPosition)], holder) + getList().getOrNull(getCollectionPosition(holder.adapterPosition))?.let { item -> itemClickListener?.invoke(item, holder) } } } else { holder.itemView.setOnClickListener(null) From a9ba1c79719fdf16b0a0edb40938cd9c731420e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=91=D0=B0=D1=87?= =?UTF-8?q?=D0=B8=D0=BD=D1=81=D0=BA=D0=B8=D0=B8=CC=86?= Date: Thu, 19 Mar 2020 21:19:30 +0300 Subject: [PATCH 09/12] Revert "Migrate FB crashlytics" This reverts commit ea1804cc --- navigation/build.gradle | 4 ++- .../components/navigation/TouchinApp.java | 28 +++++++++---------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/navigation/build.gradle b/navigation/build.gradle index 20cec33..e70ea8f 100644 --- a/navigation/build.gradle +++ b/navigation/build.gradle @@ -28,5 +28,7 @@ dependencies { implementation "androidx.appcompat:appcompat:$versions.appcompat" - implementation "com.google.firebase:firebase-crashlytics:$versions.firebaseCrashlytics" + implementation("com.crashlytics.sdk.android:crashlytics:$versions.crashlytics@aar") { + transitive = true + } } diff --git a/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java index b95c2e0..49f4047 100644 --- a/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java +++ b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java @@ -24,7 +24,7 @@ import android.content.Context; import android.os.StrictMode; import android.util.Log; -import com.google.firebase.crashlytics.FirebaseCrashlytics; +import com.crashlytics.android.Crashlytics; import net.danlew.android.joda.JodaTimeAndroid; @@ -34,6 +34,7 @@ import java.util.List; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.multidex.MultiDex; +import io.fabric.sdk.android.Fabric; import ru.touchin.roboswag.core.log.ConsoleLogProcessor; import ru.touchin.roboswag.core.log.Lc; import ru.touchin.roboswag.core.log.LcGroup; @@ -64,13 +65,16 @@ public abstract class TouchinApp extends Application { LcGroup.UI_LIFECYCLE.disable(); } else { try { - final FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); - crashlytics.setCrashlyticsCollectionEnabled(true); + final Crashlytics crashlytics = new Crashlytics(); + Fabric.with(this, crashlytics); + Fabric.getLogger().setLogLevel(Log.ERROR); Lc.initialize(new CrashlyticsLogProcessor(crashlytics), false); } catch (final NoClassDefFoundError error) { Lc.initialize(new ConsoleLogProcessor(LcLevel.INFO), false); Lc.e("Crashlytics initialization error! Did you forget to add\n" - + "com.google.firebase:firebase-crashlytics\n" + + "compile('com.crashlytics.sdk.android:crashlytics:+@aar') {\n" + + " transitive = true;\n" + + "}\n" + "to your build.gradle?", error); } } @@ -92,17 +96,13 @@ public abstract class TouchinApp extends Application { private static class CrashlyticsLogProcessor extends LogProcessor { @NonNull - private final FirebaseCrashlytics crashlytics; + private final Crashlytics crashlytics; - public CrashlyticsLogProcessor(@NonNull final FirebaseCrashlytics crashlytics) { + public CrashlyticsLogProcessor(@NonNull final Crashlytics crashlytics) { super(LcLevel.INFO); this.crashlytics = crashlytics; } - private String getLogMessage(final int priorityLevel, final String tag, final String message) { - return "Priority:" + priorityLevel + ' ' + tag + ':' + message; - } - @Override public void processLogMessage(@NonNull final LcGroup group, @NonNull final LcLevel level, @@ -110,17 +110,17 @@ public abstract class TouchinApp extends Application { @NonNull final String message, @Nullable final Throwable throwable) { if (group == LcGroup.UI_LIFECYCLE) { - crashlytics.log(getLogMessage(level.getPriority(), tag, message)); + crashlytics.core.log(level.getPriority(), tag, message); } else if (!level.lessThan(LcLevel.ASSERT) || (group == ApiModel.API_VALIDATION_LC_GROUP && level == LcLevel.ERROR)) { Log.e(tag, message); if (throwable != null) { - crashlytics.log(getLogMessage(level.getPriority(), tag, message)); - crashlytics.recordException(throwable); + crashlytics.core.log(level.getPriority(), tag, message); + crashlytics.core.logException(throwable); } else { final ShouldNotHappenException exceptionToLog = new ShouldNotHappenException(tag + ':' + message); reduceStackTrace(exceptionToLog); - crashlytics.recordException(exceptionToLog); + crashlytics.core.logException(exceptionToLog); } } } From 1976c3095b845d0f6d8237956023edd5a3d20c07 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 27 Mar 2020 11:49:52 +0300 Subject: [PATCH 10/12] "fix" static --- .../components/tabbarnavigation/BottomNavigationController.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/tabbar-navigation/src/main/java/ru/touchin/roboswag/components/tabbarnavigation/BottomNavigationController.kt b/tabbar-navigation/src/main/java/ru/touchin/roboswag/components/tabbarnavigation/BottomNavigationController.kt index b8a1bc6..8e21e3c 100644 --- a/tabbar-navigation/src/main/java/ru/touchin/roboswag/components/tabbarnavigation/BottomNavigationController.kt +++ b/tabbar-navigation/src/main/java/ru/touchin/roboswag/components/tabbarnavigation/BottomNavigationController.kt @@ -61,6 +61,7 @@ class BottomNavigationController( fun detach() = callback?.let(fragmentManager::unregisterFragmentLifecycleCallbacks) + @Suppress("detekt.ComplexMethod") fun navigateTo(@IdRes itemId: Int, state: Parcelable? = null) { // Find view controller class that needs to open val (viewControllerClass, defaultViewControllerState, saveStateOnSwitching) = viewControllers[itemId] ?: return From 96fb2bf13dd760d89fa34109e5869a42f5f782fb Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 30 Mar 2020 13:41:05 +0300 Subject: [PATCH 11/12] fix IllegalStateException when try to call MutableLiveData.setValue() outside main thread --- .../viewmodel/BaseLiveDataDispatcher.kt | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/lifecycle-rx/src/main/java/ru/touchin/lifecycle/viewmodel/BaseLiveDataDispatcher.kt b/lifecycle-rx/src/main/java/ru/touchin/lifecycle/viewmodel/BaseLiveDataDispatcher.kt index ec18dbd..0bab96d 100644 --- a/lifecycle-rx/src/main/java/ru/touchin/lifecycle/viewmodel/BaseLiveDataDispatcher.kt +++ b/lifecycle-rx/src/main/java/ru/touchin/lifecycle/viewmodel/BaseLiveDataDispatcher.kt @@ -1,5 +1,6 @@ package ru.touchin.lifecycle.viewmodel +import android.os.Looper import androidx.lifecycle.MutableLiveData import io.reactivex.Completable import io.reactivex.Flowable @@ -13,7 +14,7 @@ import ru.touchin.lifecycle.event.Event class BaseLiveDataDispatcher(private val destroyable: BaseDestroyable = BaseDestroyable()) : LiveDataDispatcher, Destroyable by destroyable { override fun Flowable.dispatchTo(liveData: MutableLiveData>): Disposable { - liveData.value = ContentEvent.Loading(liveData.value?.data) + liveData.setLoadingEvent() return untilDestroy( { data -> liveData.value = ContentEvent.Success(data) }, { throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) }, @@ -21,7 +22,7 @@ class BaseLiveDataDispatcher(private val destroyable: BaseDestroyable = BaseDest } override fun Observable.dispatchTo(liveData: MutableLiveData>): Disposable { - liveData.value = ContentEvent.Loading(liveData.value?.data) + liveData.setLoadingEvent() return untilDestroy( { data -> liveData.value = ContentEvent.Success(data) }, { throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) }, @@ -29,14 +30,14 @@ class BaseLiveDataDispatcher(private val destroyable: BaseDestroyable = BaseDest } override fun Single.dispatchTo(liveData: MutableLiveData>): Disposable { - liveData.value = ContentEvent.Loading(liveData.value?.data) + liveData.setLoadingEvent() return untilDestroy( { data -> liveData.value = ContentEvent.Success(data) }, { throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) }) } override fun Maybe.dispatchTo(liveData: MutableLiveData>): Disposable { - liveData.value = ContentEvent.Loading(liveData.value?.data) + liveData.setLoadingEvent() return untilDestroy( { data -> liveData.value = ContentEvent.Success(data) }, { throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) }, @@ -44,10 +45,29 @@ class BaseLiveDataDispatcher(private val destroyable: BaseDestroyable = BaseDest } override fun Completable.dispatchTo(liveData: MutableLiveData): Disposable { - liveData.value = Event.Loading + liveData.setLoadingEvent() return untilDestroy( { liveData.value = Event.Complete }, { throwable -> liveData.value = Event.Error(throwable) }) } + private fun MutableLiveData>.setLoadingEvent() { + val loadingContent = ContentEvent.Loading(this.value?.data) + if (Looper.getMainLooper().thread == Thread.currentThread()) { + this.value = loadingContent + } else { + this.postValue(loadingContent) + } + } + + @JvmName("setCompletableLoadingEvent") + private fun MutableLiveData.setLoadingEvent() { + val loadingContent = Event.Loading + if (Looper.getMainLooper().thread == Thread.currentThread()) { + this.value = loadingContent + } else { + this.postValue(loadingContent) + } + } + } From 43fd0f6f40cee9b9e890e4fafc53e7d62a878861 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 3 Apr 2020 13:04:31 +0300 Subject: [PATCH 12/12] fix line breaks abscence in spanned text --- .../touchin/roboswag/components/utils/spans/SpanUtils.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt b/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt index 5ad792f..25b6fec 100644 --- a/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt +++ b/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt @@ -13,8 +13,9 @@ fun String.getSpannedTextWithUrls( removeUnderline: Boolean = true, flags: Int = HtmlCompat.FROM_HTML_MODE_COMPACT ): Spanned { - - val spannableText = SpannableString(HtmlCompat.fromHtml(this, flags)) + // HtmlCompat.fromHtml doesn't respect line breaks + val text = this.replace(lineBreakRegex, "
") + val spannableText = SpannableString(HtmlCompat.fromHtml(text, flags)) // Linkify removes all previous URLSpan's, we need to save all created spans for reapply after Linkify val spans = spannableText.getUrlSpans() @@ -38,6 +39,10 @@ fun String.getSpannedTextWithUrls( return spannableText } +private val lineBreakRegex by lazy(LazyThreadSafetyMode.NONE) { + "\r?\n".toRegex() +} + private fun SpannableString.getUrlSpans() = getSpans(0, length, URLSpan::class.java) .map { UrlSpanWithBorders(it, this.getSpanStart(it), this.getSpanEnd(it)) }