From 3248041d90a6f35faed316d3a2711e35a7a9bf41 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 21 Jan 2025 09:57:22 +0100 Subject: [PATCH] media viewer : use collectAsState in the DataSource --- .../impl/viewer/MediaViewerDataSource.kt | 51 +++++++++---------- .../impl/viewer/MediaViewerPresenter.kt | 18 +++++-- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerDataSource.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerDataSource.kt index 2b86ee841b..592a84c1cb 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerDataSource.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerDataSource.kt @@ -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> { + return remember { dataFlow() }.collectAsState(initialData()) } - fun dataFlow(): Flow> { + private fun dataFlow(): Flow> { 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 { + val initialMediaItems = + galleryDataSource.getLastData().dataOrNull()?.getItems(galleryMode).orEmpty() + return buildMediaViewerPageList(initialMediaItems) + } + private fun buildMediaViewerPageList(groupedItems: List) = 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) - } } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt index 176288b537..a8a22b21d8 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt @@ -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 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.Hidden) } @@ -202,4 +199,15 @@ class MediaViewerPresenter @AssistedInject constructor( CommonStrings.error_unknown } } + + private fun searchIndex(data: List, eventId: EventId?): Int { + if (eventId == null) { + return 0 + } + return data.indexOfFirst { + (it as? MediaViewerPageData.MediaViewerData)?.eventId == eventId + } + .takeIf { it != -1 } + ?: 0 + } }