This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2020 Nikola Despotoski | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend fun <T, R : Iterable<T>> Flow<Iterable<T>>.filterIterable(predicate: suspend (T) -> Boolean): Flow<R> = | |
transform { | |
flow { | |
val emitted = arrayListOf<T>() | |
for (item in it) { | |
if (predicate(item)) { | |
emitted.add(item) | |
} | |
} | |
emit(emitted) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend fun <TResult> Task<TResult>.awaitTask() = | |
suspendCancellableCoroutine<Task<TResult>> { continuation -> | |
addOnCompleteListener { | |
continuation.resume(it) | |
} | |
} | |
suspend fun <TResult> Task<TResult>.awaitTaskResult() = | |
suspendCancellableCoroutine<TResult> { continuation -> | |
addOnCanceledListener { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data class AnimationListenerChain(val animation: Animation, val listener: Animation.AnimationListener = object : Animation.AnimationListener() { | |
override fun onAnimationStart(animation: Animation?) {} | |
override fun onAnimationEnd(animation: Animation?) {} | |
override fun onAnimationRepeat(animation: Animation?) {} | |
}) | |
inline fun Animation.doOnStart(crossinline onStart: () -> Unit): AnimationListenerChain { | |
val chain = AnimationListenerChain(this) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
operator fun <O> ActivityResultCallback<O>.plus(another: ActivityResultCallback<O>) = ActivityResultCallback<O> { | |
[email protected](it) | |
another.onActivityResult(it) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend fun <F : Fragment> FragmentManager.awaitFragmentById(idRes: Int) = | |
suspendCancellableCoroutine<F> { | |
val backStackListener = object : FragmentManager.OnBackStackChangedListener { | |
override fun onBackStackChanged() { | |
val f = findFragmentById(idRes) as F? | |
if (f != null) { | |
removeOnBackStackChangedListener(this) | |
it.resume(f) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object SuspendingBleScanner { | |
suspend fun BluetoothLeScanner.startScan(timeout: Long, scanFilters: List<ScanFilter>? = null, settings: ScanSettings? = null): List<ScanResult> { | |
check(timeout <= 0L) { "BLE scan timeout must be > 0" } | |
var scanCallback: ScanCallback? = null | |
val accumulator = mutableListOf<ScanResult>() | |
return try { | |
withTimeout(timeout) { | |
suspendCancellableCoroutine<List<ScanResult>> { continuation -> | |
scanCallback = object : ScanCallback() { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun <I, O> prepareCall(activityResultContractor: ActivityResultContractor<I, O>,activityResultCallback: ActivityResultCallback<O>) | |
: ActivityResultLauncher<I> = prepareCall(object : ActivityResultContract<I, O>() { | |
override fun createIntent(input: I): Intent = activityResultContractor.createIntent(input) | |
override fun parseResult(resultCode: Int, intent: Intent?): O = activityResultContractor.parseResult(resultCode, intent) | |
}, activityResultCallback) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ProductsViewModel @Inject constructor( | |
private val activityResultContractor: ActivityResultContractor<Nothing, String>, | |
private val coroutineProvider: CoroutineProvider, | |
private val productInteractor: ProductInteractor | |
) : ViewModel(), ActivityResultCallback<String>, | |
ActivityResultContractor<Unit, String> by activityResultContractor{ | |
override fun onActivityResult(result: String?) { | |
// do something with the result | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@FragmentScope | |
class ChooseFilterContractor @Inject constructor(private val context: Context) : ActivityResultContractor<Unit, String> { | |
override fun createIntent(input: Unit): Intent = Intent(context, ChooseFilterActivity::class.java) | |
override fun parseResult(resultCode: Int, intent: Intent?): String = if (resultCode == Activity.RESULT_OK) { | |
intent?.getStringExtra(KEY_FILTER)?: error("Dispatched RESULT_OK, but no payload) | |
} else { | |
"" | |
} | |
} |