From 792c350a1bf9cf46bb054f6e7b9417d2e11681c8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 27 Jan 2025 15:07:17 +0100 Subject: [PATCH] Extract snackbar displayer to its own methods. --- .../impl/viewer/MediaViewerPresenter.kt | 89 +++++++++++-------- 1 file changed, 54 insertions(+), 35 deletions(-) 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 9ad458efe6..b926291461 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,9 @@ 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.IntState import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf @@ -38,6 +40,7 @@ import io.element.android.libraries.mediaviewer.impl.R 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.PersistentList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter @@ -68,40 +71,12 @@ class MediaViewerPresenter @AssistedInject constructor( @Composable override fun present(): MediaViewerState { val coroutineScope = rememberCoroutineScope() - val data by dataSource.collectAsState() - var currentIndex by remember { mutableIntStateOf(searchIndex(data, inputs.eventId)) } + val data = dataSource.collectAsState() + val currentIndex = remember { mutableIntStateOf(searchIndex(data.value, inputs.eventId)) } val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState() - val isRenderingLoadingBackward by remember { - derivedStateOf { - currentIndex == data.lastIndex && data.lastOrNull() is MediaViewerPageData.Loading - } - } - if (isRenderingLoadingBackward) { - LaunchedEffect(Unit) { - // Observe the loading data vanishing - snapshotFlow { data.lastOrNull() is MediaViewerPageData.Loading } - .distinctUntilChanged() - .filter { !it } - .onEach { showNoMoreItemsSnackbar() } - .launchIn(this) - } - } - val isRenderingLoadingForward by remember { - derivedStateOf { - currentIndex == 0 && data.firstOrNull() is MediaViewerPageData.Loading - } - } - if (isRenderingLoadingForward) { - LaunchedEffect(Unit) { - // Observe the loading data vanishing - snapshotFlow { data.firstOrNull() is MediaViewerPageData.Loading } - .distinctUntilChanged() - .filter { !it } - .onEach { showNoMoreItemsSnackbar() } - .launchIn(this) - } - } + NoMoreItemsBackwardSnackBarDisplayer(currentIndex, data) + NoMoreItemsForwardSnackBarDisplayer(currentIndex, data) var mediaBottomSheetState by remember { mutableStateOf(MediaBottomSheetState.Hidden) } @@ -164,7 +139,7 @@ class MediaViewerPresenter @AssistedInject constructor( mediaBottomSheetState = MediaBottomSheetState.Hidden } is MediaViewerEvents.OnNavigateTo -> { - currentIndex = event.index + currentIndex.intValue = event.index } is MediaViewerEvents.LoadMore -> coroutineScope.launch { dataSource.loadMore(event.direction) @@ -173,8 +148,8 @@ class MediaViewerPresenter @AssistedInject constructor( } return MediaViewerState( - listData = data, - currentIndex = currentIndex, + listData = data.value, + currentIndex = currentIndex.intValue, snackbarMessage = snackbarMessage, canShowInfo = inputs.canShowInfo, mediaBottomSheetState = mediaBottomSheetState, @@ -182,6 +157,50 @@ class MediaViewerPresenter @AssistedInject constructor( ) } + @Composable + private fun NoMoreItemsBackwardSnackBarDisplayer( + currentIndex: IntState, + data: State>, + ) { + val isRenderingLoadingBackward by remember { + derivedStateOf { + currentIndex.intValue == data.value.lastIndex && data.value.lastOrNull() is MediaViewerPageData.Loading + } + } + if (isRenderingLoadingBackward) { + LaunchedEffect(Unit) { + // Observe the loading data vanishing + snapshotFlow { data.value.lastOrNull() is MediaViewerPageData.Loading } + .distinctUntilChanged() + .filter { !it } + .onEach { showNoMoreItemsSnackbar() } + .launchIn(this) + } + } + } + + @Composable + private fun NoMoreItemsForwardSnackBarDisplayer( + currentIndex: IntState, + data: State>, + ) { + val isRenderingLoadingForward by remember { + derivedStateOf { + currentIndex.intValue == 0 && data.value.firstOrNull() is MediaViewerPageData.Loading + } + } + if (isRenderingLoadingForward) { + LaunchedEffect(Unit) { + // Observe the loading data vanishing + snapshotFlow { data.value.firstOrNull() is MediaViewerPageData.Loading } + .distinctUntilChanged() + .filter { !it } + .onEach { showNoMoreItemsSnackbar() } + .launchIn(this) + } + } + } + private fun showNoMoreItemsSnackbar() { val messageResId = when (inputs.mode) { MediaViewerEntryPoint.MediaViewerMode.SingleMedia,