Compare commits

...

61 Commits

Author SHA1 Message Date
Daniil Bakherov 085cf09dbb Merge pull request 'fix crash on not initialized viewControllerClass field' (#18) from fix_ubrir_crash into ubrir/develop
Reviewed-on: #18
Reviewed-by: Alexey Ganin <alexey.ganin@noreply.localhost>
2024-10-31 13:05:47 +03:00
Daniil Bakherov 809f3aba9f Merge branch 'ubrir/develop' into fix_ubrir_crash 2024-10-25 13:13:16 +03:00
baheroff f4c81cf2a2 fix crash on not initialized viewControllerClass field 2024-10-25 13:11:16 +03:00
Daniil Bakherov 2696cd3af8 Merge pull request 'MB-47298: bump lifecycle version' (#17) from bump_lifycycle_version into ubrir/develop
Reviewed-on: #17
2024-10-23 17:33:24 +03:00
baheroff 57486cab51 MB-47298: bump lifecycle version 2024-10-23 16:19:59 +03:00
Sergey Vlasenko 1259b40d05 Merge pull request 'fix removeUnderline flags in getSpannedTextWithUrls' (#12) from fix_getSpannedTextWithUrls into update_kotlin_ver
Reviewed-on: #12
Reviewed-by: Daniil Bakherov <daniil.bakherov@noreply.localhost>
2024-04-18 17:00:43 +03:00
Sergey Vlasenko fb3365478a fix removeUnderline flags in getSpannedTextWithUrls 2024-04-18 16:51:28 +03:00
Sergey Vlasenko 57e6ca80e3 Merge pull request 'feature MB-43103 add setters in Switcher' (#9) from MB-43103 into update_kotlin_ver
Reviewed-on: #9
Reviewed-by: Daniil Bakherov <daniil.bakherov@noreply.localhost>
2024-03-27 15:23:35 +03:00
Sergey Vlasenko 405ff7459f feature MB-43103 add setters in Switcher 2024-03-27 15:19:27 +03:00
Sergey Vlasenko 87b7863b46 refactor 2023-11-02 16:24:13 +03:00
Sergey Vlasenko 09ce885353 fix when expressions 2023-11-02 10:34:30 +03:00
kostikum e3da08a47b
Merge pull request #283 from TouchInstinct/fix/dependecies
fix unnecessary dependencies in :navigation-view-controller module
2023-02-21 14:34:14 +07:00
Konstantin Kuzhim 7ce02f1c24 fix unnecessary dependencies in :navigation-view-controller module 2023-02-21 02:02:16 +07:00
Baherov Daniil 243fb8a761
Merge pull request #260 from TouchInstinct/MB-14704_fix_huawei_maps
MB-14704: replace null arg with main looper to fix huawei maps on latest versions
2022-08-02 16:26:47 +03:00
Daniil Baherov 3dbe35fedf MB-14704: replace null arg with main looper to fix huawei maps on latest versions 2022-08-02 16:21:06 +03:00
Mikhail Levin bdffe6305d
Merge pull request #258 from TouchInstinct/feature/viewcontroller_viewbinding
MB-13701: ViewBindingDelegate for ViewController
2022-07-22 15:46:48 +03:00
mephistolie 63d932b944 MB-13701: Add ViewBindingDelegate for ViewController 2022-07-20 12:23:18 +03:00
Alemoore 3278562ff4 add TestableLiveDataDispatcher without android classes
(cherry picked from commit 7ed7a25bfe)
2022-03-02 19:25:10 +03:00
Alemoore 5beefaeb31 use interface in RxViewModel
(cherry picked from commit 24b380fff0)
2022-03-02 19:25:02 +03:00
kostikum 8041b66f8d
Merge pull request #234 from TouchInstinct/fix/add_validation_logging_for_null_fields
Fix/add validation logging for null fields
2021-11-09 18:54:14 +07:00
Konstantin Kuzhim d57d8d083e replace multi-log stacktrace printing with one-statement logging 2021-11-08 22:31:45 +07:00
Konstantin Kuzhim 411401a4ec add logging if non-null field is null 2021-11-08 22:30:32 +07:00
Grigorii 41690204fe
Merge pull request #224 from TouchInstinct/fix_merging
fix conflicts after merging ubrir/master <- master
2021-09-15 16:06:15 +03:00
grigorii 09161d3877 fix conflicts after merging ubrir/master <- master 2021-09-15 13:04:35 +03:00
grigorii c9343855f7 Merge branch 'master' of github.com:TouchInstinct/RoboSwag into ubrir/master
 Conflicts:
	views/src/main/java/ru/touchin/roboswag/views/widget/AmountWithDecimalDecorator.kt
2021-09-15 09:35:36 +03:00
Georgy Turev 53adefddbb
Merge pull request #191 from TouchInstinct/ubrir_master/add_recycler_view_submit_with_callback
Add recyclerview submit with callback + up version
2021-04-29 20:13:32 +05:00
Georgy Turev 194f1862c6 Add recyclerview submit with callback + up version 2021-04-29 20:06:15 +05:00
crainzavr 0c8b444f20
Merge pull request #190 from TouchInstinct/ubrir_master/fix_displaying_first_day_of_month_in_calendar
UBRD-6128 Fix displaying first day of month in calendar
2021-04-06 15:49:28 +05:00
crain 4ab4161610 UBRD-6128 Fix displaying first day of month in calendar 2021-04-06 14:55:28 +05:00
crainzavr 47b1c76fdf
Merge pull request #189 from TouchInstinct/ubrir_master/remove_unused_files
Remove unused files after merge master
2020-12-29 17:09:33 +05:00
crain 4bf9d0991b Remove unused files after merge master 2020-12-29 16:50:00 +05:00
crainzavr 58c9f12d3c
Merge pull request #188 from TouchInstinct/ubrir_master/update_roboswag
Ubrir master/update roboswag
2020-12-28 17:47:43 +05:00
crain 6cc66fd242 restore crashlytics initing in main process 2020-12-28 17:32:19 +05:00
crain 501fddd72d fix static analysis issues 2020-12-28 16:56:20 +05:00
crain 3a6afded87 Merge branch 'master' into ubrir_master/update_roboswag
# Conflicts:
#	kotlin-extensions/build.gradle
#	livedata-location/build.gradle
#	navigation-new/build.gradle
#	navigation/build.gradle
#	navigation/src/main/java/ru/touchin/roboswag/components/navigation/TouchinApp.java
#	recyclerview-adapters/build.gradle
#	recyclerview-calendar/build.gradle
#	rx-extensions/build.gradle
2020-12-27 17:30:50 +05:00
crainzavr 9c67b0fa18
Merge pull request #187 from TouchInstinct/ubrir_master/add_open_on_main_process_create_method
Add open onMainProcessCreate method for descendants usage
2020-12-23 11:38:08 +05:00
crain 19044fefa8 Add open onMainProcessCreate method for descendants usage 2020-12-23 10:46:36 +05:00
sysoevi fd51f7f67b
Merge pull request #186 from TouchInstinct/ubrir/crashlytics
Ubrir/crashlytics
2020-12-11 14:00:10 +04:00
Igor Sysoev 89271b79b8 code cleanup 2020-12-10 19:53:48 +04:00
Igor Sysoev e65752731f main app refactoring, removed fabric, added firebase crashlytics, added checking main process function 2020-12-10 19:52:18 +04:00
Kirill Nayduik 949b53f79d
Merge pull request #185 from TouchInstinct/ubrir_master/remove_callback
Revert "Add submit with callback into DelegationListAdapter"
2020-12-07 14:52:48 +03:00
NoDopezzz 231356bb82 Revert "Add submit with callback into DelegationListAdapter"
This reverts commit 2ddc08c22b.
2020-12-07 14:22:46 +03:00
Kirill Nayduik 14d099806f
Merge pull request #184 from TouchInstinct/ubrir/nullable_state
Nullable state
2020-12-07 13:06:49 +03:00
NoDopezzz 39289f61f4 Make state nullable after migrating to compileSdk=29 2020-12-07 13:03:13 +03:00
crainzavr a616a39f27
Merge pull request #183 from TouchInstinct/add_recycler_view_submit_with_callback
Add submit with callback into DelegationListAdapter
2020-11-25 16:05:44 +05:00
crain 2ddc08c22b Add submit with callback into DelegationListAdapter 2020-11-25 15:53:00 +05:00
sysoevi adc53e6a7b
Merge pull request #182 from TouchInstinct/ubrir/remove_unused_func
Ubrir/removed unused method
2020-11-10 18:02:54 +04:00
Igor Sysoev 2bc496562e removed submitList with callback 2020-11-10 17:18:40 +04:00
Kirill Nayduik 79c9336c33
Merge pull request #179 from TouchInstinct/ubrir_mastur/huawei_location_live_data
Add HuaweiLocationLiveData
2020-10-27 11:27:58 +03:00
NoDopezzz 527df2be1c Add HuaweiLocationLiveData 2020-10-27 10:27:38 +03:00
Daniil Borisovskii b54daede13
Merge pull request #176 from TouchInstinct/ubrir_master/rx-extensions
Cherrypick added in PR #126 and #127 functionallity from "master" into "ubrir/master"
2020-10-08 18:23:28 +03:00
Даниил Борисовский 0889ed2e9b Merge pull request #127 from TouchInstinct/feature/rx-extensions
Rename 'Constants' to 'StringConstants'
2020-10-08 18:14:48 +03:00
Даниил Борисовский a615d54f3e Merge pull request #126 from TouchInstinct/feature/rx-extensions
Added extension 'unwrapOrError' to main RX classes typed with Optional
2020-10-08 18:14:36 +03:00
crainzavr 060aa5bb6a
Merge pull request #175 from TouchInstinct/add_content_event_transform
Add transform method into ContentEvent
2020-10-07 17:12:20 +05:00
crain 8b0d17d5cc Add transform method into ContentEvent 2020-10-07 15:37:09 +05:00
crainzavr 8d4c5244a4
Merge pull request #171 from TouchInstinct/fix_payment_search_scroll_position
UBRD-4736 Add new submit list functionality in DelegationListAdapter
2020-09-28 15:45:05 +05:00
crain f5f8183924 UBRD-4736 Add new submit list functionality in DelegationListAdapter 2020-09-28 10:49:18 +05:00
Daniil Borisovskii a710d30b67
Merge pull request #170 from TouchInstinct/ubrir_master/crashlytics
Add "noinspection" to suppress crashlytics outdate warning in order to proceed static analysis
2020-09-25 13:43:48 +03:00
Daniil Borisovskii c7e24038dd Add "noinspection" to suppress crashlytics outdate warning in order to proceed static analysis 2020-09-25 13:38:06 +03:00
crainzavr 184140b967
Merge pull request #168 from TouchInstinct/increase_target_sdk_version_to_30
Fix due to increase target sdk version to 30
2020-09-15 14:19:20 +05:00
crain 5edc752686 Fix due to increase target sdk version to 30 2020-09-14 18:07:59 +05:00
23 changed files with 250 additions and 61 deletions

View File

@ -1,10 +1,10 @@
apply plugin: 'kotlin-android'
rootProject.ext {
compileSdk = 30
compileSdk = 29
minSdk = 21
targetSdk = 30
targetSdk = 29
}
android {

View File

@ -22,6 +22,7 @@ package ru.touchin.templates.logansquare;
import androidx.annotation.Nullable;
import ru.touchin.roboswag.core.log.Lc;
import ru.touchin.roboswag.core.log.LcGroup;
import ru.touchin.templates.ApiModel;
/**
@ -38,7 +39,9 @@ public abstract class LoganSquareJsonModel extends ApiModel {
*/
protected static void validateNotNull(@Nullable final Object object) throws ValidationException {
if (object == null) {
throw new ValidationException("Not nullable object is null or missed at " + Lc.getCodePoint(null, 1));
ValidationException exception = new ValidationException("Not nullable object is null or missed at " + Lc.getCodePoint(null, 1));
LcGroup.API_VALIDATION.e(exception, "Invalid item");
throw exception;
}
}

View File

@ -1,19 +1,13 @@
package ru.touchin.extensions
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import ru.touchin.roboswag.core.log.Lc
import android.provider.Browser
fun Context.safeStartActivity(intent: Intent, options: Bundle? = null) =
try {
startActivity(intent, options)
} catch (e: ActivityNotFoundException) {
Lc.e(e, "Couldn't find activity with this parameters")
}
fun Context.safeStartActivity(intent: Intent, options: Bundle? = null, resolveFlags: Int = 0): Boolean =
packageManager.resolveActivity(intent, resolveFlags)?.let { startActivity(intent, options) } != null
fun Context.openBrowser(url: String) = Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(url))
@ -34,3 +28,4 @@ fun Context.openBrowserWithHeaders(url: String, headersMap: Map<String, String>)
fun Context.callToPhoneNumber(phoneNumber: String) = Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("tel:$phoneNumber"))
.let { intent -> safeStartActivity(intent) }

View File

@ -8,7 +8,7 @@ import androidx.annotation.CallSuper
*/
open class RxViewModel(
private val destroyable: BaseDestroyable = BaseDestroyable(),
private val liveDataDispatcher: BaseLiveDataDispatcher = BaseLiveDataDispatcher(destroyable)
private val liveDataDispatcher: LiveDataDispatcher = BaseLiveDataDispatcher(destroyable)
) : ViewModel(), Destroyable by destroyable, LiveDataDispatcher by liveDataDispatcher {
@CallSuper

View File

@ -0,0 +1,49 @@
package ru.touchin.lifecycle.viewmodel
import androidx.lifecycle.MutableLiveData
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.disposables.Disposable
import ru.touchin.lifecycle.event.ContentEvent
import ru.touchin.lifecycle.event.Event
class TestableLiveDataDispatcher(
private val destroyable: BaseDestroyable = BaseDestroyable()
) : LiveDataDispatcher, Destroyable by destroyable {
override fun <T> Flowable<out T>.dispatchTo(liveData: MutableLiveData<ContentEvent<T>>): Disposable {
return untilDestroy(
{ data -> liveData.value = ContentEvent.Success(data) },
{ throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) },
{ liveData.value = ContentEvent.Complete(liveData.value?.data) })
}
override fun <T> Observable<out T>.dispatchTo(liveData: MutableLiveData<ContentEvent<T>>): Disposable {
return untilDestroy(
{ data -> liveData.value = ContentEvent.Success(data) },
{ throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) },
{ liveData.value = ContentEvent.Complete(liveData.value?.data) })
}
override fun <T> Single<out T>.dispatchTo(liveData: MutableLiveData<ContentEvent<T>>): Disposable {
return untilDestroy(
{ data -> liveData.value = ContentEvent.Success(data) },
{ throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) })
}
override fun <T> Maybe<out T>.dispatchTo(liveData: MutableLiveData<ContentEvent<T>>): Disposable {
return untilDestroy(
{ data -> liveData.value = ContentEvent.Success(data) },
{ throwable -> liveData.value = ContentEvent.Error(throwable, liveData.value?.data) },
{ liveData.value = ContentEvent.Complete(liveData.value?.data) })
}
override fun Completable.dispatchTo(liveData: MutableLiveData<Event>): Disposable {
return untilDestroy(
{ liveData.value = Event.Complete },
{ throwable -> liveData.value = Event.Error(throwable) })
}
}

View File

@ -10,4 +10,13 @@ sealed class ContentEvent<out T>(open val data: T?) {
data class Complete<out T>(override val data: T? = null) : ContentEvent<T>(data)
fun <P> transform(transformation: (T?) -> P): ContentEvent<P> {
return when(this) {
is Loading -> Loading(transformation(data))
is Success -> Success(transformation(data))
is Complete -> Complete(transformation(data))
is Error -> Error(throwable, transformation(data))
}
}
}

View File

@ -5,6 +5,8 @@ dependencies {
implementation "com.google.android.gms:play-services-location"
implementation "com.huawei.hms:location:$versions.hmsLocation"
constraints {
implementation("com.google.android.gms:play-services-location") {
version {

View File

@ -0,0 +1,62 @@
package ru.touchin.livedata.location
import android.Manifest.permission.ACCESS_COARSE_LOCATION
import android.Manifest.permission.ACCESS_FINE_LOCATION
import android.content.Context
import android.location.Location
import android.os.Looper
import androidx.annotation.RequiresPermission
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import com.huawei.hms.location.FusedLocationProviderClient
import com.huawei.hms.location.LocationAvailability
import com.huawei.hms.location.LocationCallback
import com.huawei.hms.location.LocationRequest
import com.huawei.hms.location.LocationResult
import com.huawei.hms.location.LocationServices
class HuaweiLocationLiveData(
context: Context,
private val request: LocationRequest
) : LiveData<Location>() {
private val fusedLocationClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult) {
postValue(result.lastLocation)
}
override fun onLocationAvailability(availability: LocationAvailability) {
if (!availability.isLocationAvailable) postValue(null)
}
}
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
override fun observe(owner: LifecycleOwner, observer: Observer<in Location>) {
super.observe(owner, observer)
}
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
override fun onActive() {
startListening()
}
override fun onInactive() {
stopListening()
}
private fun stopListening() {
fusedLocationClient.removeLocationUpdates(locationCallback)
}
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
private fun startListening() {
fusedLocationClient.requestLocationUpdates(
request,
locationCallback,
Looper.getMainLooper()
)
}
}

View File

@ -29,8 +29,6 @@ import android.util.Log;
*/
public class ConsoleLogProcessor extends LogProcessor {
private static final int MAX_LOG_LENGTH = 4000;
public ConsoleLogProcessor(@NonNull final LcLevel lclevel) {
super(lclevel);
}
@ -46,18 +44,8 @@ public class ConsoleLogProcessor extends LogProcessor {
public void processLogMessage(@NonNull final LcGroup group, @NonNull final LcLevel level,
@NonNull final String tag, @NonNull final String message, @Nullable final Throwable throwable) {
final String messageToLog = normalize(message + (throwable != null ? '\n' + Log.getStackTraceString(throwable) : ""));
final int length = messageToLog.length();
for (int i = 0; i < length; i++) {
int newline = messageToLog.indexOf('\n', i);
newline = newline != -1 ? newline : length;
do {
final int end = Math.min(newline, i + MAX_LOG_LENGTH);
Log.println(level.getPriority(), tag, messageToLog.substring(i, end));
i = end;
}
while (i < newline);
}
Log.println(level.getPriority(), tag, messageToLog);
}
}

View File

@ -64,7 +64,7 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-common-java8") {
version {
require '2.2.0'
require '2.6.2'
}
}

View File

@ -26,6 +26,7 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics;
import net.danlew.android.joda.JodaTimeAndroid;
import ru.touchin.hardware.ProcessKt;
import ru.touchin.roboswag.core.log.ConsoleLogProcessor;
import ru.touchin.roboswag.core.log.Lc;
import ru.touchin.roboswag.core.log.LcGroup;
@ -46,7 +47,7 @@ public abstract class TouchinApp extends Application {
enableStrictMode();
Lc.initialize(new ConsoleLogProcessor(LcLevel.VERBOSE), true);
LcGroup.UI_LIFECYCLE.disable();
} else {
} else if (ProcessKt.isOnMainProcess(this)) {
try {
final FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
crashlytics.setCrashlyticsCollectionEnabled(true);

View File

@ -7,36 +7,19 @@ dependencies {
implementation project(":logging")
implementation project(":navigation-base")
implementation 'androidx.multidex:multidex'
implementation 'net.danlew:android.joda'
implementation "androidx.appcompat:appcompat"
implementation("com.crashlytics.sdk.android:crashlytics")
implementation "androidx.lifecycle:lifecycle-common-java8"
constraints {
implementation("androidx.multidex:multidex") {
version {
require '2.0.1'
}
}
implementation("net.danlew:android.joda") {
version {
require '2.10.2'
}
}
implementation("androidx.appcompat:appcompat") {
version {
require '1.0.2'
}
}
implementation("com.crashlytics.sdk.android:crashlytics") {
implementation("androidx.lifecycle:lifecycle-common-java8") {
version {
require '2.10.0'
require '2.6.2'
}
}
}

View File

@ -80,7 +80,8 @@ open class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcela
lateinit var state: TState private set
lateinit var viewControllerClass: Class<ViewController<TActivity, TState>> private set
var viewControllerClass: Class<ViewController<TActivity, TState>>? = null
private set
private var viewController: ViewController<out TActivity, out TState>? = null
@ -241,14 +242,14 @@ open class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcela
creationContext: ViewController.CreationContext,
savedInstanceState: Bundle?
): ViewController<out TActivity, out TState> {
if (viewControllerClass.constructors.size != 1) {
if (viewControllerClass?.constructors?.size != 1) {
throw IllegalStateException("There should be single constructor for $viewControllerClass")
}
val constructor = viewControllerClass.constructors[0]
return when (constructor.parameterTypes.size) {
val constructor = viewControllerClass?.constructors?.get(0)
return when (constructor?.parameterTypes?.size) {
1 -> constructor.newInstance(creationContext)
2 -> constructor.newInstance(creationContext, savedInstanceState)
else -> throw IllegalArgumentException("Wrong constructor parameters count: ${constructor.parameterTypes.size}")
else -> throw IllegalArgumentException("Wrong constructor parameters count: ${constructor?.parameterTypes?.size}")
} as ViewController<out TActivity, out TState>
}

View File

@ -73,7 +73,8 @@ open class ViewController<TActivity : FragmentActivity, TState : Parcelable>(
lifecycle.addObserver(LifecycleLoggingObserver(this))
}
override fun getLifecycle(): Lifecycle = fragment.viewLifecycleOwner.lifecycle
override val lifecycle: Lifecycle
get() = fragment.viewLifecycleOwner.lifecycle
/**
* Look for a child view with the given id. If this view has the given id, return this view.

View File

@ -120,7 +120,7 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
*/
fun <TState : Parcelable> setViewControllerAsTop(
viewControllerClass: Class<out ViewController<out TActivity, TState>>,
state: TState,
state: TState?,
addToStack: Boolean = true,
tag: String? = null,
transactionSetup: ((FragmentTransaction) -> Unit)? = null
@ -149,7 +149,7 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
*/
fun <TState : Parcelable> setInitialViewController(
viewControllerClass: Class<out ViewController<out TActivity, TState>>,
state: TState,
state: TState?,
tag: String? = null,
transactionSetup: ((FragmentTransaction) -> Unit)? = null
) {

View File

@ -0,0 +1,44 @@
package ru.touchin.roboswag.navigation_viewcontroller.viewcontrollers
import android.os.Parcelable
import android.view.View
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.viewbinding.ViewBinding
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class ViewControllerViewBindingDelegate<T : ViewBinding, TActivity : FragmentActivity, TState : Parcelable>(
val viewController: ViewController<TActivity, TState>,
val viewBindingFactory: (View) -> T
) : ReadOnlyProperty<ViewController<TActivity, TState>, T> {
private var binding: T? = null
init {
viewController.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
viewController.fragment.viewLifecycleOwnerLiveData.observe(viewController) { viewLifecycleOwner ->
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
binding = null
}
})
}
}
})
}
override fun getValue(thisRef: ViewController<TActivity, TState>, property: KProperty<*>): T {
val binding = binding
if (binding != null) {
return binding
}
return viewBindingFactory(viewController.view).also { this.binding = it }
}
}
fun <T : ViewBinding, TActivity : FragmentActivity, TState : Parcelable>
ViewController<TActivity, TState>.viewBinding(viewBindingFactory: (View) -> T) =
ViewControllerViewBindingDelegate(this, viewBindingFactory)

View File

@ -10,7 +10,7 @@ dependencies {
constraints {
implementation("androidx.recyclerview:recyclerview") {
version {
require '1.0.0'
require '1.1.0'
}
}
implementation("androidx.core:core-ktx") {

View File

@ -69,7 +69,28 @@ open class DelegationListAdapter<TItem>(config: AsyncDifferConfig<TItem>) : Recy
*
* @param list The new list to be displayed.
*/
fun submitList(list: List<TItem>) = differ.submitList(list)
fun submitList(list: List<TItem>?) = differ.submitList(list)
/**
* Submits a new list to be diffed, and displayed.
*
* The commit callback can be used to know when the List is committed, but note that it
* may not be executed. If List B is submitted immediately after List A, and is
* committed directly, the callback associated with List A will not be run.
*
* @param newList The new List.
* @param commitCallback Optional runnable that is executed when the List is committed, if
* it is committed.
*/
fun submitList(list: List<TItem>?, commitCallback: (() -> Unit)?) = differ.submitList(list, commitCallback)
/**
* Same as [submitList] with fast simple remove all items of a previous list
*/
fun replaceList(list: List<TItem>) {
submitList(null)
submitList(list)
}
/**
* Get the current List - any diffing to present this list has already been computed and

View File

@ -276,7 +276,7 @@ public final class CalendarUtils {
final int firstDayInNextMonth = nextMonthFirstDay.getDayOfWeek() - 1;
if (daysLeftInWeek != 0) {
calendarItems.add(new CalendarEmptyItem(shift, shift + daysLeftInWeek));
calendarItems.add(new CalendarEmptyItem(shift, shift + daysLeftInWeek - 1));
shift += daysLeftInWeek;
}
calendarItems.add(new CalendarHeaderItem(nextMonthFirstDay.getYear(), nextMonthFirstDay.getMonthOfYear() - 1, shift, shift));

View File

@ -0,0 +1,21 @@
package ru.touchin.hardware
import android.app.ActivityManager
import android.content.Context
import android.os.Process
fun Context.isOnMainProcess(): Boolean {
val applicationContext = this.applicationContext
val runningAppProcesses = (applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
.runningAppProcesses
if (runningAppProcesses != null && runningAppProcesses.size != 0) {
for (runningProcessInfo in runningAppProcesses) {
val isCurrentProcess = runningProcessInfo.pid == Process.myPid()
val isMainProcessName = this.packageName == runningProcessInfo.processName
if (isCurrentProcess && isMainProcessName) {
return true
}
}
}
return false
}

View File

@ -16,11 +16,11 @@ import ru.touchin.extensions.indexesOf
*/
fun String.getSpannedTextWithUrls(
removeUnderline: Boolean = true,
flags: Int = HtmlCompat.FROM_HTML_MODE_COMPACT
htmlFormatFlags: Int = HtmlCompat.FROM_HTML_MODE_COMPACT
): Spanned {
// HtmlCompat.fromHtml doesn't respect line breaks
val text = this.replace(lineBreakRegex, "<br/>")
val spannableText = SpannableString(HtmlCompat.fromHtml(text, flags))
val spannableText = SpannableString(HtmlCompat.fromHtml(text, htmlFormatFlags))
// Linkify removes all previous URLSpan's, we need to save all created spans for reapply after Linkify
val spans = spannableText.getUrlSpans()
@ -29,7 +29,7 @@ fun String.getSpannedTextWithUrls(
spannableText.setSpan(it.span, it.start, it.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
if (!removeUnderline) {
if (removeUnderline) {
spannableText.getUrlSpans()
.forEach { urlSpan ->
spannableText.removeSpan(urlSpan.span)

View File

@ -55,6 +55,7 @@ class LoadingContentView @JvmOverloads constructor(
showChild(R.id.error_with_repeat)
}
}
else -> Unit
}
}
}

View File

@ -28,6 +28,14 @@ public class Switcher extends FrameLayout {
@Nullable
private Animation outAnimation;
public void setOutAnimation(@Nullable Animation outAnimation) {
this.outAnimation = outAnimation;
}
public void setInAnimation(@Nullable Animation inAnimation) {
this.inAnimation = inAnimation;
}
public Switcher(@NonNull final Context context) {
this(context, null);
}