Add timestamp to trigger back pagination.
This commit is contained in:
parent
5e506be062
commit
40a44cae75
7 changed files with 48 additions and 12 deletions
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue