Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Media gallery UI #4010

Merged
merged 31 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3e1b1c2
Media Gallery
bmarty Dec 9, 2024
653c1e8
Sync strings.
bmarty Dec 9, 2024
d818597
Fix preview.
bmarty Dec 9, 2024
68dd3a0
Update screenshots
ElementBot Dec 9, 2024
73143d8
Fix preview
bmarty Dec 9, 2024
c2ad4a9
Update screenshots
ElementBot Dec 9, 2024
ae0593d
Rename preview.
bmarty Dec 10, 2024
2207040
remove blank line.
bmarty Dec 10, 2024
197fda5
Rename onDone to onBackClick.
bmarty Dec 10, 2024
323ae0a
Rename imageItems to imageAndVideoItems.
bmarty Dec 10, 2024
e55e977
Remove TimelineMediaItemsCacheInvalidator, it is not needed.
bmarty Dec 10, 2024
a40aff6
Change scope to RoomScope
bmarty Dec 10, 2024
a89a9c3
Remove not needed MediaGalleryTimelineProvider
bmarty Dec 10, 2024
6386645
Remove extra space.
bmarty Dec 10, 2024
cce1c99
Format file.
bmarty Dec 10, 2024
b78039a
Add test.
bmarty Dec 10, 2024
6dbfa94
Fix test.
bmarty Dec 10, 2024
ff86d06
Fix test.
bmarty Dec 10, 2024
0f43e7c
More formatting
bmarty Dec 10, 2024
893c152
Add missing previews
bmarty Dec 10, 2024
6fbd343
Introduce GroupedMediaItems for code clarity
bmarty Dec 10, 2024
f314c25
Iterate on Error rendering.
bmarty Dec 10, 2024
db0bca9
Improve preview.
bmarty Dec 10, 2024
36eceb7
Move bottom state to the View state
bmarty Dec 10, 2024
e5b3421
Media timeline: improve pagination logic.
bmarty Dec 10, 2024
1b7d3a3
Add test on DefaultEventItemFactory
bmarty Dec 10, 2024
bb06b68
Let the Presenter use real classes.
bmarty Dec 10, 2024
ec821bb
Order imports.
bmarty Dec 10, 2024
1c691d2
Add unit test on MediaItemsPostProcessor
bmarty Dec 10, 2024
fc35e8e
Update screenshots
ElementBot Dec 10, 2024
0113a52
Fix test.
bmarty Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,13 @@
<string name="screen_knock_requests_list_empty_state_description">"Když někdo požádá o vstup do místnosti, uvidíte jeho žádost zde."</string>
<string name="screen_knock_requests_list_empty_state_title">"Žádná čekající žádost o vstup"</string>
<string name="screen_knock_requests_list_title">"Žádosti o vstup"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s +%2$d další chce vstoupit do této místnosti"</item>
<item quantity="few">"%1$s +%2$d další chtějí vstoupit do této místnosti"</item>
<item quantity="other">"%1$s +%2$d dalších chce vstoupit do této místnosti"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Zobrazit vše"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Přijmout"</string>
<string name="screen_room_single_knock_request_title">"%1$s chce vstoupit do této místnosti"</string>
<string name="screen_room_single_knock_request_view_button_title">"Zobrazit"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@
<string name="screen_knock_requests_list_empty_state_description">"Falls jemand um Aufnahme in den Raum bittet, können Sie dessen Anfrage hier sehen."</string>
<string name="screen_knock_requests_list_empty_state_title">"Keine ausstehende Beitrittsanfrage"</string>
<string name="screen_knock_requests_list_title">"Beitrittsanfragen"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s+ %2$d andere wollen diesem Chatroom beitreten"</item>
<item quantity="other">"%1$s+ %2$d andere wollen diesem Chatroom beitreten"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Alles ansehen"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Akzeptieren"</string>
<string name="screen_room_single_knock_request_title">"%1$s möchte diesem Chatroom beitreten"</string>
<string name="screen_room_single_knock_request_view_button_title">"Ansicht"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@
<string name="screen_knock_requests_list_empty_state_description">"Όταν κάποιος θα ζητήσει να συμμετάσχει στο δωμάτιο, θα μπορείς να δεις το αίτημά του εδώ."</string>
<string name="screen_knock_requests_list_empty_state_title">"Δεν υπάρχει εκκρεμές αίτημα συμμετοχής"</string>
<string name="screen_knock_requests_list_title">"Αιτήματα συμμετοχής"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"Οι χρήστες %1$s +%2$d ακόμη θέλουν να συμμετάσχουν σε αυτό το δωμάτιο"</item>
<item quantity="other">"Οι χρήστες %1$s +%2$d ακόμη θέλουν να συμμετάσχουν σε αυτό το δωμάτιο"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Προβολή όλων"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Αποδοχή"</string>
<string name="screen_room_single_knock_request_title">"Ο χρήστης %1$s θέλει να μπει σε αυτό το δωμάτιο"</string>
<string name="screen_room_single_knock_request_view_button_title">"Προβολή"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@
<string name="screen_knock_requests_list_empty_state_description">"Kui keegi soovib jututoaga liituda, siis need päringud on kuvatud siin."</string>
<string name="screen_knock_requests_list_empty_state_title">"Pole ühtegi liitumispalvet"</string>
<string name="screen_knock_requests_list_title">"Liitumispalved"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s + veel %2$d kasutaja soovivad selle jututoaga liituda"</item>
<item quantity="other">"%1$s + veel %2$d kasutajat soovivad selle jututoaga liituda"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Vaata kõiki"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Nõustu"</string>
<string name="screen_room_single_knock_request_title">"%1$s soovib selle jututoaga liituda"</string>
<string name="screen_room_single_knock_request_view_button_title">"Vaata"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@
<string name="screen_knock_requests_list_empty_state_description">"Lorsque quelqu’un demandera à rejoindre le salon, vous pourrez voir sa demande ici."</string>
<string name="screen_knock_requests_list_empty_state_title">"Personne ne demande à rejoindre le salon"</string>
<string name="screen_knock_requests_list_title">"Demandes en attente"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s et %2$d autre personne souhaitent rejoindre ce salon"</item>
<item quantity="other">"%1$s et %2$d autres personnes souhaitent rejoindre ce salon"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Tout afficher"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Accepter"</string>
<string name="screen_room_single_knock_request_title">"%1$s souhaite rejoindre ce salon"</string>
<string name="screen_room_single_knock_request_view_button_title">"Voir"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@
<string name="screen_knock_requests_list_empty_state_description">"Ha valaki csatlakozni kíván a szobához, itt láthatja a kérését."</string>
<string name="screen_knock_requests_list_empty_state_title">"Nincs függőben lévő csatlakozási kérelem"</string>
<string name="screen_knock_requests_list_title">"Csatlakozási kérelmek"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s és még %2$d felhasználó szeretne csatlakozni ehhez a szobához"</item>
<item quantity="other">"%1$s és még %2$d felhasználó szeretne csatlakozni ehhez a szobához"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Összes megtekintése"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Elfogadás"</string>
<string name="screen_room_single_knock_request_title">"%1$s szeretne csatlakozni ehhez a szobához"</string>
<string name="screen_room_single_knock_request_view_button_title">"Megtekintés"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@
<string name="screen_knock_requests_list_empty_state_description">"Quando qualcuno ti chiederà di entrare nella stanza, potrai vedere la sua richiesta qui."</string>
<string name="screen_knock_requests_list_empty_state_title">"Nessuna richiesta di accesso in sospeso"</string>
<string name="screen_knock_requests_list_title">"Richieste di accesso"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s +%2$d vogliono entrare in questa stanza"</item>
<item quantity="other">"%1$s +%2$d vogliono entrare in questa stanza"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Visualizza tutte"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Accetta"</string>
<string name="screen_room_single_knock_request_title">"%1$s vuole entrare in questa stanza"</string>
<string name="screen_room_single_knock_request_view_button_title">"Visualizza"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,13 @@
<string name="screen_knock_requests_list_empty_state_description">"Вы сможете увидеть запрос, когда кто-то попросит присоединиться к комнате."</string>
<string name="screen_knock_requests_list_empty_state_title">"Нет ожидающих запросов на присоединение"</string>
<string name="screen_knock_requests_list_title">"Запросы на присоединение"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s +%2$d хочет присоединиться к этой комнате"</item>
<item quantity="few">"%1$s +%2$d хотят присоединиться к этой комнате"</item>
<item quantity="many">"%1$s +%2$d хотят присоединиться к этой комнате"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Показать все"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Принять"</string>
<string name="screen_room_single_knock_request_title">"%1$s хочет присоединиться к этой комнате"</string>
<string name="screen_room_single_knock_request_view_button_title">"Просмотр"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,13 @@
<string name="screen_knock_requests_list_empty_state_description">"Keď niekto požiada, aby sa pripojil k miestnosti, jeho žiadosť si môžete pozrieť tu."</string>
<string name="screen_knock_requests_list_empty_state_title">"Žiadna čakajúca žiadosť o pripojenie"</string>
<string name="screen_knock_requests_list_title">"Žiadosti o pripojenie"</string>
<plurals name="screen_room_multiple_knock_requests_title">
<item quantity="one">"%1$s +%2$d ďalší chcú vstúpiť do tejto miestnosti"</item>
<item quantity="few">"%1$s +%2$d ďalší chcú vstúpiť do tejto miestnosti"</item>
<item quantity="other">"%1$s +%2$d ďalších chce vstúpiť do tejto miestnosti"</item>
</plurals>
<string name="screen_room_multiple_knock_requests_view_all_button_title">"Zobraziť všetko"</string>
<string name="screen_room_single_knock_request_accept_button_title">"Prijať"</string>
<string name="screen_room_single_knock_request_title">"%1$s chce vstúpiť do tejto miestnosti"</string>
<string name="screen_room_single_knock_request_view_button_title">"Zobraziť"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class MessagesFlowNode @AssistedInject constructor(

@Parcelize
data class MediaViewer(
val eventId: EventId?,
val mediaInfo: MediaInfo,
val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
Expand Down Expand Up @@ -241,16 +242,22 @@ class MessagesFlowNode @AssistedInject constructor(
}
is NavTarget.MediaViewer -> {
val params = MediaViewerEntryPoint.Params(
eventId = navTarget.eventId,
mediaInfo = navTarget.mediaInfo,
mediaSource = navTarget.mediaSource,
thumbnailSource = navTarget.thumbnailSource,
canShowInfo = true,
canDownload = true,
canShare = true,
)
val callback = object : MediaViewerEntryPoint.Callback {
override fun onDone() {
overlay.hide()
}

override fun onViewInTimeline(eventId: EventId) {
viewInTimeline(eventId)
}
}
mediaViewerEntryPoint.nodeBuilder(this, buildContext)
.params(params)
Expand Down Expand Up @@ -311,11 +318,7 @@ class MessagesFlowNode @AssistedInject constructor(
}

override fun onViewInTimelineClick(eventId: EventId) {
val permalinkData = PermalinkData.RoomLink(
roomIdOrAlias = room.roomId.toRoomIdOrAlias(),
eventId = eventId,
)
callbacks.forEach { it.onPermalinkClick(permalinkData, pushToBackstack = false) }
viewInTimeline(eventId)
}

override fun onRoomPermalinkClick(data: PermalinkData.RoomLink) {
Expand All @@ -341,6 +344,14 @@ class MessagesFlowNode @AssistedInject constructor(
}
}

private fun viewInTimeline(eventId: EventId) {
val permalinkData = PermalinkData.RoomLink(
roomIdOrAlias = room.roomId.toRoomIdOrAlias(),
eventId = eventId,
)
callbacks.forEach { it.onPermalinkClick(permalinkData, pushToBackstack = false) }
}

private fun processEventClick(event: TimelineItem.Event): Boolean {
val navTarget = when (event.content) {
is TimelineItemImageContent -> {
Expand Down Expand Up @@ -415,13 +426,16 @@ class MessagesFlowNode @AssistedInject constructor(
thumbnailSource: MediaSource?,
): NavTarget {
return NavTarget.MediaViewer(
eventId = event.eventId,
mediaInfo = MediaInfo(
filename = content.filename,
caption = content.caption,
mimeType = content.mimeType,
formattedFileSize = content.formattedFileSize,
fileExtension = content.fileExtension,
senderId = event.senderId,
senderName = event.safeSenderName,
senderAvatar = event.senderAvatar.url,
dateSent = event.sentTime,
),
mediaSource = mediaSource,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
Expand All @@ -39,10 +40,13 @@ import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.overlay.operation.hide
import io.element.android.libraries.architecture.overlay.operation.show
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analyticsproviders.api.trackers.captureInteraction
Expand All @@ -59,6 +63,7 @@ class RoomDetailsFlowNode @AssistedInject constructor(
private val messagesEntryPoint: MessagesEntryPoint,
private val knockRequestsListEntryPoint: KnockRequestsListEntryPoint,
private val mediaViewerEntryPoint: MediaViewerEntryPoint,
private val mediaGalleryEntryPoint: MediaGalleryEntryPoint,
) : BaseFlowNode<RoomDetailsFlowNode.NavTarget>(
backstack = BackStack(
initialElement = plugins.filterIsInstance<RoomDetailsEntryPoint.Params>().first().initialElement.toNavTarget(),
Expand Down Expand Up @@ -98,6 +103,9 @@ class RoomDetailsFlowNode @AssistedInject constructor(
@Parcelize
data object PollHistory : NavTarget

@Parcelize
data object MediaGallery : NavTarget

@Parcelize
data object AdminSettings : NavTarget

Expand Down Expand Up @@ -136,6 +144,10 @@ class RoomDetailsFlowNode @AssistedInject constructor(
backstack.push(NavTarget.PollHistory)
}

override fun openMediaGallery() {
backstack.push(NavTarget.MediaGallery)
}

override fun openAdminSettings() {
backstack.push(NavTarget.AdminSettings)
}
Expand Down Expand Up @@ -213,6 +225,10 @@ class RoomDetailsFlowNode @AssistedInject constructor(
override fun onDone() {
overlay.hide()
}

override fun onViewInTimeline(eventId: EventId) {
// Cannot happen
}
}
mediaViewerEntryPoint.nodeBuilder(this, buildContext)
.avatar(
Expand All @@ -222,10 +238,29 @@ class RoomDetailsFlowNode @AssistedInject constructor(
.callback(callback)
.build()
}

is NavTarget.PollHistory -> {
pollHistoryEntryPoint.createNode(this, buildContext)
}
is NavTarget.MediaGallery -> {
val callback = object : MediaGalleryEntryPoint.Callback {
override fun onDone() {
backstack.pop()
}

override fun onViewInTimeline(eventId: EventId) {
val permalinkData = PermalinkData.RoomLink(
roomIdOrAlias = room.roomId.toRoomIdOrAlias(),
eventId = eventId,
)
plugins<RoomDetailsEntryPoint.Callback>().forEach {
it.onPermalinkClick(permalinkData, pushToBackstack = false)
}
}
}
mediaGalleryEntryPoint.nodeBuilder(this, buildContext)
.callback(callback)
.build()
}

is NavTarget.AdminSettings -> {
createNode<RolesAndPermissionsFlowNode>(buildContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class RoomDetailsNode @AssistedInject constructor(
fun openRoomNotificationSettings()
fun openAvatarPreview(name: String, url: String)
fun openPollHistory()
fun openMediaGallery()
fun openAdminSettings()
fun openPinnedMessagesList()
fun openKnockRequestsList()
Expand Down Expand Up @@ -77,6 +78,10 @@ class RoomDetailsNode @AssistedInject constructor(
callbacks.forEach { it.openPollHistory() }
}

private fun openMediaGallery() {
callbacks.forEach { it.openMediaGallery() }
}

private fun onJoinCall() {
callbacks.forEach { it.onJoinCall() }
}
Expand Down Expand Up @@ -143,6 +148,7 @@ class RoomDetailsNode @AssistedInject constructor(
invitePeople = ::invitePeople,
openAvatarPreview = ::openAvatarPreview,
openPollHistory = ::openPollHistory,
openMediaGallery = ::openMediaGallery,
openAdminSettings = this::openAdminSettings,
onJoinCallClick = ::onJoinCall,
onPinnedMessagesClick = ::openPinnedMessages,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import im.vector.app.features.analytics.plan.Interaction
import io.element.android.features.leaveroom.api.LeaveRoomEvent
import io.element.android.features.leaveroom.api.LeaveRoomState
Expand Down Expand Up @@ -79,6 +80,10 @@ class RoomDetailsPresenter @Inject constructor(
val isPublic by remember { derivedStateOf { roomInfo?.isPublic.orFalse() } }

val canShowPinnedMessages = isPinnedMessagesFeatureEnabled()
var canShowMediaGallery by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
canShowMediaGallery = featureFlagService.isFeatureEnabled(FeatureFlags.MediaGallery)
}
val pinnedMessagesCount by remember { derivedStateOf { roomInfo?.pinnedEventIds?.size } }

LaunchedEffect(Unit) {
Expand Down Expand Up @@ -162,6 +167,7 @@ class RoomDetailsPresenter @Inject constructor(
isPublic = isPublic,
heroes = roomInfo?.heroes.orEmpty().toPersistentList(),
canShowPinnedMessages = canShowPinnedMessages,
canShowMediaGallery = canShowMediaGallery,
pinnedMessagesCount = pinnedMessagesCount,
canShowKnockRequests = canShowKnockRequests,
knockRequestsCount = knockRequestsCount,
Expand Down
Loading
Loading