Threads - first iteration (#5165)
* Initial threads support: parse `ThreadSummary`. Replace several `isThreaded` values with `EventThreadInfo`, which contains the info about the event either being the root of a thread or part of it. * Add `Threaded` timeline mode * Add a `liveTimeline` parameter to `TimelineController`'s constructor. This way we can customise which timeline will be used as the 'live' one. Also add `@LiveTimeline` DI qualifier for the actual live timeline of the room. * Create `ThreadedMessagesNode`. Allow opening a thread in a separate screen. * Add the callbacks for the list menu actions - even if they're the wrong ones and will send the data to the room instead * Send attachments and location in threads * Fix polls in threads, add support for sending voice messages in threads * Display thread summaries only when the feature flag is enabled * Use 'Reply' instead of 'Reply in thread' when in threaded timeline mode * Remove incorrect usage of `Timeline` in `MessageComposerPresenter`. This led to replies to threaded events not appearing as actual replies. --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
parent
cc10ba41fd
commit
35928e3630
119 changed files with 1520 additions and 339 deletions
|
|
@ -97,9 +97,9 @@ class MediaGalleryRootNode @AssistedInject constructor(
|
|||
val mode = when (item) {
|
||||
is MediaItem.Audio,
|
||||
is MediaItem.Voice,
|
||||
is MediaItem.File -> MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(Timeline.Mode.MEDIA)
|
||||
is MediaItem.File -> MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(Timeline.Mode.Media)
|
||||
is MediaItem.Image,
|
||||
is MediaItem.Video -> MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(Timeline.Mode.MEDIA)
|
||||
is MediaItem.Video -> MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(Timeline.Mode.Media)
|
||||
}
|
||||
overlay.show(
|
||||
NavTarget.MediaViewer(
|
||||
|
|
|
|||
|
|
@ -82,8 +82,9 @@ class MediaViewerNode @AssistedInject constructor(
|
|||
}
|
||||
when (timelineMode) {
|
||||
null -> timelineMediaGalleryDataSource
|
||||
Timeline.Mode.LIVE,
|
||||
Timeline.Mode.FOCUSED_ON_EVENT -> {
|
||||
Timeline.Mode.Live,
|
||||
is Timeline.Mode.FocusedOnEvent,
|
||||
is Timeline.Mode.Thread -> {
|
||||
// Does timelineMediaGalleryDataSource knows the eventId?
|
||||
val lastData = timelineMediaGalleryDataSource.getLastData().dataOrNull()
|
||||
val isEventKnown = lastData?.hasEvent(eventId) == true
|
||||
|
|
@ -97,14 +98,14 @@ class MediaViewerNode @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
Timeline.Mode.PINNED_EVENTS -> {
|
||||
Timeline.Mode.PinnedEvents -> {
|
||||
focusedTimelineMediaGalleryDataSourceFactory.createFor(
|
||||
eventId = eventId,
|
||||
mediaItem = inputs.toMediaItem(),
|
||||
onlyPinnedEvents = true,
|
||||
)
|
||||
}
|
||||
Timeline.Mode.MEDIA -> timelineMediaGalleryDataSource
|
||||
Timeline.Mode.Media -> timelineMediaGalleryDataSource
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ class MediaViewerDataSourceTest {
|
|||
fun `test dataFlow with data galleryMode image`() = runTest {
|
||||
val galleryDataSource = FakeMediaGalleryDataSource()
|
||||
val sut = createMediaViewerDataSource(
|
||||
mode = MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.MEDIA),
|
||||
mode = MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.Media),
|
||||
galleryDataSource = galleryDataSource,
|
||||
)
|
||||
sut.dataFlow().test {
|
||||
|
|
@ -159,7 +159,7 @@ class MediaViewerDataSourceTest {
|
|||
fun `test dataFlow with data galleryMode files`() = runTest {
|
||||
val galleryDataSource = FakeMediaGalleryDataSource()
|
||||
val sut = createMediaViewerDataSource(
|
||||
mode = MediaViewerMode.TimelineFilesAndAudios(timelineMode = Timeline.Mode.MEDIA),
|
||||
mode = MediaViewerMode.TimelineFilesAndAudios(timelineMode = Timeline.Mode.Media),
|
||||
galleryDataSource = galleryDataSource,
|
||||
)
|
||||
sut.dataFlow().test {
|
||||
|
|
@ -265,7 +265,7 @@ class MediaViewerDataSourceTest {
|
|||
}
|
||||
|
||||
private fun TestScope.createMediaViewerDataSource(
|
||||
mode: MediaViewerMode = MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.MEDIA),
|
||||
mode: MediaViewerMode = MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.Media),
|
||||
galleryDataSource: MediaGalleryDataSource = FakeMediaGalleryDataSource(),
|
||||
mediaLoader: MatrixMediaLoader = FakeMatrixMediaLoader(),
|
||||
localMediaFactory: LocalMediaFactory = FakeLocalMediaFactory(mockMediaUrl),
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ class MediaViewerPresenterTest {
|
|||
@Test
|
||||
fun `present - snackbar displayed when there is no more items forward images and videos`() {
|
||||
`present - snackbar displayed when there is no more items forward`(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.MEDIA),
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.Media),
|
||||
expectedSnackbarResId = R.string.screen_media_details_no_more_media_to_show,
|
||||
)
|
||||
}
|
||||
|
|
@ -536,7 +536,7 @@ class MediaViewerPresenterTest {
|
|||
@Test
|
||||
fun `present - snackbar displayed when there is no more items forward files and audio`() {
|
||||
`present - snackbar displayed when there is no more items forward`(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(timelineMode = Timeline.Mode.MEDIA),
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(timelineMode = Timeline.Mode.Media),
|
||||
expectedSnackbarResId = R.string.screen_media_details_no_more_files_to_show,
|
||||
)
|
||||
}
|
||||
|
|
@ -599,7 +599,7 @@ class MediaViewerPresenterTest {
|
|||
@Test
|
||||
fun `present - snackbar displayed when there is no more items backward images and videos`() {
|
||||
`present - snackbar displayed when there is no more items backward`(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.MEDIA),
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode = Timeline.Mode.Media),
|
||||
expectedSnackbarResId = R.string.screen_media_details_no_more_media_to_show,
|
||||
)
|
||||
}
|
||||
|
|
@ -607,7 +607,7 @@ class MediaViewerPresenterTest {
|
|||
@Test
|
||||
fun `present - snackbar displayed when there is no more items backward files and audio`() {
|
||||
`present - snackbar displayed when there is no more items backward`(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(timelineMode = Timeline.Mode.MEDIA),
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(timelineMode = Timeline.Mode.Media),
|
||||
expectedSnackbarResId = R.string.screen_media_details_no_more_files_to_show,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue