1 /*
<lambda>null2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.settingslib.spa.framework.util
18
19 import androidx.lifecycle.Lifecycle
20 import androidx.lifecycle.LifecycleOwner
21 import androidx.lifecycle.lifecycleScope
22 import androidx.lifecycle.repeatOnLifecycle
23 import kotlinx.coroutines.Job
24 import kotlinx.coroutines.flow.Flow
25 import kotlinx.coroutines.flow.collectLatest
26 import kotlinx.coroutines.flow.combine
27 import kotlinx.coroutines.flow.map
28 import kotlinx.coroutines.flow.take
29 import kotlinx.coroutines.launch
30
31 /**
32 * Returns a [Flow] whose values are a list which containing the results of applying the given
33 * [transform] function to each element in the original flow's list.
34 */
35 inline fun <T, R> Flow<List<T>>.mapItem(crossinline transform: (T) -> R): Flow<List<R>> =
36 map { list -> list.map(transform) }
37
38 /**
39 * Returns a [Flow] whose values are a list which containing the results of asynchronously applying
40 * the given [transform] function to each element in the original flow's list.
41 */
asyncMapItemnull42 inline fun <T, R> Flow<List<T>>.asyncMapItem(crossinline transform: (T) -> R): Flow<List<R>> =
43 map { list -> list.asyncMap(transform) }
44
45 /**
46 * Returns a [Flow] whose values are a list containing only elements matching the given [predicate].
47 */
filterItemnull48 inline fun <T> Flow<List<T>>.filterItem(crossinline predicate: (T) -> Boolean): Flow<List<T>> =
49 map { list -> list.filter(predicate) }
50
51 /**
52 * Delays the flow a little bit, wait the other flow's first value.
53 */
waitFirstnull54 fun <T1, T2> Flow<T1>.waitFirst(otherFlow: Flow<T2>): Flow<T1> =
55 combine(otherFlow.take(1)) { value, _ -> value }
56
57
58 /**
59 * Collects the latest value of given flow with a provided action with [LifecycleOwner].
60 */
collectLatestWithLifecyclenull61 fun <T> Flow<T>.collectLatestWithLifecycle(
62 lifecycleOwner: LifecycleOwner,
63 minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
64 action: suspend (value: T) -> Unit,
65 ): Job = lifecycleOwner.lifecycleScope.launch {
66 lifecycleOwner.repeatOnLifecycle(minActiveState) {
67 collectLatest(action)
68 }
69 }
70