Skip to content

Commit 8b37257

Browse files
committed
Glimpse: MediaRepository: Introduce medias(List<Uri>)
And use instead of the hacky toFlowOfRequestStatusList() Change-Id: Ibf4d4641c430c1b5bc1ca3b89e9b3e04218b7474
1 parent 7e7ea6d commit 8b37257

File tree

4 files changed

+36
-34
lines changed

4 files changed

+36
-34
lines changed

app/src/main/java/org/lineageos/glimpse/datasources/LocalDataSource.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.lineageos.glimpse.models.Thumbnail
2424
import org.lineageos.glimpse.query.Query
2525
import org.lineageos.glimpse.query.and
2626
import org.lineageos.glimpse.query.eq
27+
import org.lineageos.glimpse.query.`in`
2728
import org.lineageos.glimpse.query.or
2829
import org.lineageos.glimpse.query.query
2930
import org.lineageos.glimpse.utils.MimeUtils
@@ -265,6 +266,26 @@ class LocalDataSource(
265266
} ?: RequestStatus.Error(MediaError.NOT_FOUND)
266267
}
267268

269+
override fun medias(mediaUris: List<Uri>) = contentResolver.queryFlow(
270+
filesUri,
271+
mediaProjection,
272+
bundleOf(
273+
ContentResolver.QUERY_ARG_SQL_SELECTION to query {
274+
(MediaStore.Files.FileColumns._ID `in` List(mediaUris.size) {
275+
Query.ARG
276+
}) and isImageOrVideo
277+
},
278+
ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS to mediaUris.map {
279+
it.lastPathSegment!!
280+
}.toTypedArray(),
281+
ContentResolver.QUERY_ARG_SORT_COLUMNS to arrayOf(
282+
"${MediaStore.Files.FileColumns.DATE_MODIFIED} DESC",
283+
),
284+
),
285+
).mapEachRow(mapMedia).mapLatest {
286+
RequestStatus.Success<_, MediaError>(it)
287+
}
288+
268289
companion object {
269290
private const val ALBUMS_PATH = "albums"
270291

app/src/main/java/org/lineageos/glimpse/datasources/MediaDataSource.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 The LineageOS Project
2+
* SPDX-FileCopyrightText: 2024-2025 The LineageOS Project
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -75,4 +75,9 @@ interface MediaDataSource {
7575
* Get the media information of the given media.
7676
*/
7777
fun media(mediaUri: Uri): Flow<MediaRequestStatus<Media>>
78+
79+
/**
80+
* Get the media information of the given medias.
81+
*/
82+
fun medias(mediaUris: List<Uri>): Flow<MediaRequestStatus<List<Media>>>
7883
}

app/src/main/java/org/lineageos/glimpse/repository/MediaRepository.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
2+
* SPDX-FileCopyrightText: 2023-2025 The LineageOS Project
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -79,4 +79,9 @@ class MediaRepository(
7979
* @see MediaDataSource.media
8080
*/
8181
fun media(mediaUri: Uri) = localDataSource.media(mediaUri)
82+
83+
/**
84+
* @see MediaDataSource.medias
85+
*/
86+
fun medias(mediaUris: List<Uri>) = localDataSource.medias(mediaUris)
8287
}

app/src/main/java/org/lineageos/glimpse/viewmodels/LocalPlayerViewModel.kt

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import androidx.media3.common.MediaItem
1515
import androidx.media3.exoplayer.ExoPlayer
1616
import kotlinx.coroutines.Dispatchers
1717
import kotlinx.coroutines.ExperimentalCoroutinesApi
18-
import kotlinx.coroutines.flow.Flow
1918
import kotlinx.coroutines.flow.MutableStateFlow
2019
import kotlinx.coroutines.flow.SharingStarted
2120
import kotlinx.coroutines.flow.asStateFlow
@@ -114,46 +113,18 @@ class LocalPlayerViewModel(
114113
initialValue = RequestStatus.Loading(),
115114
)
116115

117-
private fun <T, E> List<Flow<RequestStatus<T, E>>>.toFlowOfRequestStatusList() = flow {
118-
if (isEmpty()) {
119-
emit(RequestStatus.Success(emptyList()))
120-
return@flow
121-
}
122-
123-
emit(RequestStatus.Loading())
124-
125-
combine(this@toFlowOfRequestStatusList) { statusArray ->
126-
// Check if any item is still loading
127-
if (statusArray.any { it is RequestStatus.Loading }) {
128-
return@combine RequestStatus.Loading<List<T>, E>()
129-
}
130-
131-
// Collect all successful data, ignoring errors
132-
statusArray
133-
.filterIsInstance<RequestStatus.Success<T, E>>()
134-
.map { it.data }
135-
.let {
136-
RequestStatus.Success(it)
137-
}
138-
}.collect { combinedStatus ->
139-
emit(combinedStatus)
140-
}
141-
}
142-
143116
/**
144117
* Collect secure media via Uri to update its list after deletion/restore.
145118
* Needed because we can't use the album to observe for changes.
146-
*
147-
* NOTE: This _will_ be slow for large amounts of media.
148119
*/
149120
@OptIn(ExperimentalCoroutinesApi::class)
150121
val secureMedias = parsedIntent
151122
.flatMapLatest {
152123
when (it) {
153124
is IntentsViewModel.ParsedIntent.SecureReviewIntent -> {
154-
it.medias.map { media ->
155-
mediaRepository.media(media.uri)
156-
}.toFlowOfRequestStatusList()
125+
mediaRepository.medias(it.medias.map { media ->
126+
media.uri
127+
})
157128
}
158129

159130
else -> flowOf(RequestStatus.Loading())

0 commit comments

Comments
 (0)