This file contains 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> { | |
this@plus.onActivityResult(it) | |
another.onActivityResult(it) | |
} |
This file contains 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 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 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 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 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 { | |
"" | |
} | |
} |
This file contains 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 <T> lazyLiveData(function: suspend LiveDataScope<T>.() -> Unit) = object : kotlin.Lazy<LiveData<T>> { | |
lateinit var liveDataCached: LiveData<T> | |
override val value: LiveData<T> | |
get() { | |
if (!isInitialized()) { | |
liveDataCached = liveData { function() } | |
} | |
return liveDataCached | |
} |
This file contains 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
import androidx.appcompat.app.AppCompatActivity | |
import androidx.fragment.app.Fragment | |
import androidx.lifecycle.ViewModel | |
import androidx.lifecycle.ViewModelProvider | |
import kotlin.properties.ReadOnlyProperty | |
import kotlin.reflect.KProperty | |
import kotlin.reflect.jvm.javaType | |
class FragmentViewModelProperty<VM : ViewModel>(private val viewModelFactoryProvider: () -> ViewModelProvider.Factory? = { null }, |
This file contains 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
public fun <T> Flow<T>.last(): Flow<T> = flow { | |
try { | |
var last : Any? = null | |
collect { value -> | |
last = value | |
} | |
emit(last as T) | |
} catch (e: Throwable) { | |
// Nothing, bail out | |
} |