media viewer : use collectAsState in the DataSource

This commit is contained in:
ganfra 2025-01-21 09:57:22 +01:00 committed by Benoit Marty
parent bad45663d1
commit 3248041d90
2 changed files with 38 additions and 31 deletions

View file

@ -7,10 +7,13 @@
package io.element.android.libraries.mediaviewer.impl.viewer
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import io.element.android.libraries.matrix.api.media.MediaFile
import io.element.android.libraries.matrix.api.timeline.Timeline
@ -56,33 +59,27 @@ class MediaViewerDataSource(
localMediaStates.clear()
}
fun initialPageIndex(eventId: EventId?): Int {
if (eventId == null) {
return 0
}
val mediaItems =
galleryDataSource.getLastData().dataOrNull()?.getItems(galleryMode).orEmpty()
val pageList = buildMediaViewerPageList(mediaItems)
return pageList.indexOfFirst { data ->
when (data) {
is MediaViewerPageData.MediaViewerData -> data.eventId == eventId
else -> false
}
}
.takeIf { it != -1 }
?: 0
@Composable
fun collectAsState(): State<PersistentList<MediaViewerPageData>> {
return remember { dataFlow() }.collectAsState(initialData())
}
fun dataFlow(): Flow<PersistentList<MediaViewerPageData>> {
private fun dataFlow(): Flow<PersistentList<MediaViewerPageData>> {
return galleryDataSource.groupedMediaItemsFlow()
.map {
val groupedItems = it.dataOrNull()?.getItems(galleryMode).orEmpty()
.map { groupedItems ->
val mediaItems = groupedItems.dataOrNull()?.getItems(galleryMode).orEmpty()
withContext(dispatcher) {
buildMediaViewerPageList(groupedItems)
buildMediaViewerPageList(mediaItems)
}
}
}
private fun initialData(): PersistentList<MediaViewerPageData> {
val initialMediaItems =
galleryDataSource.getLastData().dataOrNull()?.getItems(galleryMode).orEmpty()
return buildMediaViewerPageList(initialMediaItems)
}
private fun buildMediaViewerPageList(groupedItems: List<MediaItem>) = buildList {
groupedItems.forEach { mediaItem ->
when (mediaItem) {
@ -112,6 +109,14 @@ class MediaViewerDataSource(
}
}.toPersistentList()
fun clearLoadingError(data: MediaViewerPageData.MediaViewerData) {
localMediaStates[data.mediaSource.url]?.value = AsyncData.Uninitialized
}
suspend fun loadMore(direction: Timeline.PaginationDirection) {
galleryDataSource.loadMore(direction)
}
suspend fun loadMedia(data: MediaViewerPageData.MediaViewerData) {
Timber.d("loadMedia for ${data.eventId}")
val localMediaState = localMediaStates.getOrPut(data.mediaSource.url) {
@ -141,11 +146,5 @@ class MediaViewerDataSource(
}
}
fun clearLoadingError(data: MediaViewerPageData.MediaViewerData) {
localMediaStates[data.mediaSource.url]?.value = AsyncData.Uninitialized
}
suspend fun loadMore(direction: Timeline.PaginationDirection) {
galleryDataSource.loadMore(direction)
}
}

View file

@ -10,7 +10,6 @@ package io.element.android.libraries.mediaviewer.impl.viewer
import android.content.ActivityNotFoundException
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
@ -35,8 +34,6 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMedia
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import io.element.android.libraries.androidutils.R as UtilsR
@ -61,8 +58,8 @@ class MediaViewerPresenter @AssistedInject constructor(
@Composable
override fun present(): MediaViewerState {
val coroutineScope = rememberCoroutineScope()
val data: ImmutableList<MediaViewerPageData> by dataSource.dataFlow().collectAsState(persistentListOf())
var currentIndex by remember { mutableIntStateOf(dataSource.initialPageIndex(inputs.eventId)) }
val data by dataSource.collectAsState()
var currentIndex by remember { mutableIntStateOf(searchIndex(data, inputs.eventId)) }
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
var mediaBottomSheetState by remember { mutableStateOf<MediaBottomSheetState>(MediaBottomSheetState.Hidden) }
@ -202,4 +199,15 @@ class MediaViewerPresenter @AssistedInject constructor(
CommonStrings.error_unknown
}
}
private fun searchIndex(data: List<MediaViewerPageData>, eventId: EventId?): Int {
if (eventId == null) {
return 0
}
return data.indexOfFirst {
(it as? MediaViewerPageData.MediaViewerData)?.eventId == eventId
}
.takeIf { it != -1 }
?: 0
}
}