mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 21:32:34 +00:00
Add timestamp to trigger back pagination.
This commit is contained in:
committed by
Benoit Marty
parent
dfda13ac20
commit
bac69c4a35
+12
-2
@@ -27,6 +27,7 @@ import io.element.android.libraries.mediaviewer.impl.gallery.eventId
|
|||||||
import io.element.android.libraries.mediaviewer.impl.gallery.mediaInfo
|
import io.element.android.libraries.mediaviewer.impl.gallery.mediaInfo
|
||||||
import io.element.android.libraries.mediaviewer.impl.gallery.mediaSource
|
import io.element.android.libraries.mediaviewer.impl.gallery.mediaSource
|
||||||
import io.element.android.libraries.mediaviewer.impl.gallery.thumbnailSource
|
import io.element.android.libraries.mediaviewer.impl.gallery.thumbnailSource
|
||||||
|
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||||
import kotlinx.collections.immutable.PersistentList
|
import kotlinx.collections.immutable.PersistentList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
@@ -42,6 +43,7 @@ class MediaViewerDataSource(
|
|||||||
private val galleryDataSource: MediaGalleryDataSource,
|
private val galleryDataSource: MediaGalleryDataSource,
|
||||||
private val mediaLoader: MatrixMediaLoader,
|
private val mediaLoader: MatrixMediaLoader,
|
||||||
private val localMediaFactory: LocalMediaFactory,
|
private val localMediaFactory: LocalMediaFactory,
|
||||||
|
private val systemClock: SystemClock,
|
||||||
) {
|
) {
|
||||||
// List of media files that are currently being loaded
|
// List of media files that are currently being loaded
|
||||||
private val mediaFiles: MutableList<MediaFile> = mutableListOf()
|
private val mediaFiles: MutableList<MediaFile> = mutableListOf()
|
||||||
@@ -108,12 +110,20 @@ class MediaViewerDataSource(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is MediaItem.LoadingIndicator -> add(
|
is MediaItem.LoadingIndicator -> add(
|
||||||
MediaViewerPageData.Loading(mediaItem.direction)
|
MediaViewerPageData.Loading(
|
||||||
|
direction = mediaItem.direction,
|
||||||
|
timestamp = systemClock.epochMillis(),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
add(MediaViewerPageData.Loading(Timeline.PaginationDirection.BACKWARDS))
|
add(
|
||||||
|
MediaViewerPageData.Loading(
|
||||||
|
direction = Timeline.PaginationDirection.BACKWARDS,
|
||||||
|
timestamp = systemClock.epochMillis(),
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.toPersistentList()
|
}.toPersistentList()
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -27,6 +27,7 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory
|
|||||||
import io.element.android.libraries.mediaviewer.impl.gallery.MediaGalleryMode
|
import io.element.android.libraries.mediaviewer.impl.gallery.MediaGalleryMode
|
||||||
import io.element.android.libraries.mediaviewer.impl.gallery.SingleMediaGalleryDataSource
|
import io.element.android.libraries.mediaviewer.impl.gallery.SingleMediaGalleryDataSource
|
||||||
import io.element.android.libraries.mediaviewer.impl.gallery.TimelineMediaGalleryDataSource
|
import io.element.android.libraries.mediaviewer.impl.gallery.TimelineMediaGalleryDataSource
|
||||||
|
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||||
|
|
||||||
@ContributesNode(RoomScope::class)
|
@ContributesNode(RoomScope::class)
|
||||||
class MediaViewerNode @AssistedInject constructor(
|
class MediaViewerNode @AssistedInject constructor(
|
||||||
@@ -37,6 +38,7 @@ class MediaViewerNode @AssistedInject constructor(
|
|||||||
mediaLoader: MatrixMediaLoader,
|
mediaLoader: MatrixMediaLoader,
|
||||||
localMediaFactory: LocalMediaFactory,
|
localMediaFactory: LocalMediaFactory,
|
||||||
coroutineDispatchers: CoroutineDispatchers,
|
coroutineDispatchers: CoroutineDispatchers,
|
||||||
|
systemClock: SystemClock,
|
||||||
) : Node(buildContext, plugins = plugins),
|
) : Node(buildContext, plugins = plugins),
|
||||||
MediaViewerNavigator {
|
MediaViewerNavigator {
|
||||||
private val inputs = inputs<MediaViewerEntryPoint.Params>()
|
private val inputs = inputs<MediaViewerEntryPoint.Params>()
|
||||||
@@ -77,7 +79,8 @@ class MediaViewerNode @AssistedInject constructor(
|
|||||||
galleryMode = galleryMode,
|
galleryMode = galleryMode,
|
||||||
galleryDataSource = mediaGallerySource,
|
galleryDataSource = mediaGallerySource,
|
||||||
mediaLoader = mediaLoader,
|
mediaLoader = mediaLoader,
|
||||||
localMediaFactory = localMediaFactory
|
localMediaFactory = localMediaFactory,
|
||||||
|
systemClock = systemClock,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+1
@@ -34,6 +34,7 @@ sealed interface MediaViewerPageData {
|
|||||||
|
|
||||||
data class Loading(
|
data class Loading(
|
||||||
val direction: Timeline.PaginationDirection,
|
val direction: Timeline.PaginationDirection,
|
||||||
|
val timestamp: Long,
|
||||||
) : MediaViewerPageData
|
) : MediaViewerPageData
|
||||||
|
|
||||||
data class MediaViewerData(
|
data class MediaViewerData(
|
||||||
|
|||||||
+11
-1
@@ -151,7 +151,7 @@ open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState>
|
|||||||
},
|
},
|
||||||
aMediaViewerState(
|
aMediaViewerState(
|
||||||
listOf(
|
listOf(
|
||||||
MediaViewerPageData.Loading(Timeline.PaginationDirection.BACKWARDS)
|
aMediaViewerPageDataLoading()
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
aMediaViewerState(
|
aMediaViewerState(
|
||||||
@@ -162,6 +162,16 @@ open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState>
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun aMediaViewerPageDataLoading(
|
||||||
|
direction: Timeline.PaginationDirection = Timeline.PaginationDirection.BACKWARDS,
|
||||||
|
timestamp: Long = 0L,
|
||||||
|
): MediaViewerPageData {
|
||||||
|
return MediaViewerPageData.Loading(
|
||||||
|
direction = direction,
|
||||||
|
timestamp = timestamp,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun aMediaViewerPageData(
|
fun aMediaViewerPageData(
|
||||||
downloadedMedia: AsyncData<LocalMedia> = AsyncData.Uninitialized,
|
downloadedMedia: AsyncData<LocalMedia> = AsyncData.Uninitialized,
|
||||||
mediaInfo: MediaInfo = anImageMediaInfo(),
|
mediaInfo: MediaInfo = anImageMediaInfo(),
|
||||||
|
|||||||
+1
-1
@@ -128,7 +128,7 @@ fun MediaViewerView(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is MediaViewerPageData.Loading -> {
|
is MediaViewerPageData.Loading -> {
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(dataForPage.timestamp) {
|
||||||
state.eventSink(MediaViewerEvents.LoadMore(dataForPage.direction))
|
state.eventSink(MediaViewerEvents.LoadMore(dataForPage.direction))
|
||||||
}
|
}
|
||||||
MediaViewerLoadingPage(
|
MediaViewerLoadingPage(
|
||||||
|
|||||||
+17
-7
@@ -27,6 +27,8 @@ import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemFile
|
|||||||
import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemImage
|
import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemImage
|
||||||
import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemLoadingIndicator
|
import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemLoadingIndicator
|
||||||
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaFactory
|
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaFactory
|
||||||
|
import io.element.android.services.toolbox.test.systemclock.A_FAKE_TIMESTAMP
|
||||||
|
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import io.element.android.tests.testutils.lambda.value
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
@@ -90,7 +92,12 @@ class MediaViewerDataSourceTest {
|
|||||||
)
|
)
|
||||||
val result = awaitItem()
|
val result = awaitItem()
|
||||||
assertThat(result).hasSize(1)
|
assertThat(result).hasSize(1)
|
||||||
assertThat(result.first()).isEqualTo(MediaViewerPageData.Loading(Timeline.PaginationDirection.BACKWARDS))
|
assertThat(result.first()).isEqualTo(
|
||||||
|
MediaViewerPageData.Loading(
|
||||||
|
direction = Timeline.PaginationDirection.BACKWARDS,
|
||||||
|
timestamp = A_FAKE_TIMESTAMP,
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,8 +125,14 @@ class MediaViewerDataSourceTest {
|
|||||||
)
|
)
|
||||||
val result = awaitItem()
|
val result = awaitItem()
|
||||||
assertThat(result).containsExactly(
|
assertThat(result).containsExactly(
|
||||||
MediaViewerPageData.Loading(Timeline.PaginationDirection.BACKWARDS),
|
MediaViewerPageData.Loading(
|
||||||
MediaViewerPageData.Loading(Timeline.PaginationDirection.FORWARDS),
|
direction = Timeline.PaginationDirection.BACKWARDS,
|
||||||
|
timestamp = A_FAKE_TIMESTAMP,
|
||||||
|
),
|
||||||
|
MediaViewerPageData.Loading(
|
||||||
|
direction = Timeline.PaginationDirection.FORWARDS,
|
||||||
|
timestamp = A_FAKE_TIMESTAMP,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,10 +268,6 @@ class MediaViewerDataSourceTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun clearLoadingError() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TestScope.createMediaViewerDataSource(
|
private fun TestScope.createMediaViewerDataSource(
|
||||||
galleryMode: MediaGalleryMode = MediaGalleryMode.Images,
|
galleryMode: MediaGalleryMode = MediaGalleryMode.Images,
|
||||||
galleryDataSource: MediaGalleryDataSource = FakeMediaGalleryDataSource(),
|
galleryDataSource: MediaGalleryDataSource = FakeMediaGalleryDataSource(),
|
||||||
@@ -270,5 +279,6 @@ class MediaViewerDataSourceTest {
|
|||||||
galleryDataSource = galleryDataSource,
|
galleryDataSource = galleryDataSource,
|
||||||
mediaLoader = mediaLoader,
|
mediaLoader = mediaLoader,
|
||||||
localMediaFactory = localMediaFactory,
|
localMediaFactory = localMediaFactory,
|
||||||
|
systemClock = FakeSystemClock(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -37,6 +37,7 @@ import io.element.android.libraries.mediaviewer.impl.gallery.MediaGalleryMode
|
|||||||
import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemImage
|
import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemImage
|
||||||
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaActions
|
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaActions
|
||||||
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaFactory
|
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaFactory
|
||||||
|
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import io.element.android.tests.testutils.lambda.value
|
import io.element.android.tests.testutils.lambda.value
|
||||||
@@ -593,6 +594,7 @@ class MediaViewerPresenterTest {
|
|||||||
galleryDataSource = mediaGalleryDataSource,
|
galleryDataSource = mediaGalleryDataSource,
|
||||||
mediaLoader = matrixMediaLoader,
|
mediaLoader = matrixMediaLoader,
|
||||||
localMediaFactory = localMediaFactory,
|
localMediaFactory = localMediaFactory,
|
||||||
|
systemClock = FakeSystemClock(),
|
||||||
),
|
),
|
||||||
room = room,
|
room = room,
|
||||||
localMediaActions = localMediaActions,
|
localMediaActions = localMediaActions,
|
||||||
|
|||||||
Reference in New Issue
Block a user