mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Uploads: rework: provide information about the sender
This commit is contained in:
parent
907a786b1a
commit
f3a5fb7fe3
12 changed files with 170 additions and 82 deletions
|
@ -228,12 +228,3 @@ fun Event.isVideoMessage(): Boolean {
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Event.isPreviewableMessage(): Boolean {
|
|
||||||
return getClearType() == EventType.MESSAGE
|
|
||||||
&& when (getClearContent()?.toModel<MessageContent>()?.msgType) {
|
|
||||||
MessageType.MSGTYPE_IMAGE,
|
|
||||||
MessageType.MSGTYPE_VIDEO -> true
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,13 +16,12 @@
|
||||||
|
|
||||||
package im.vector.matrix.android.api.session.room.uploads
|
package im.vector.matrix.android.api.session.room.uploads
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
|
||||||
|
|
||||||
data class GetUploadsResult(
|
data class GetUploadsResult(
|
||||||
// List of fetched Events, most recent first
|
// List of fetched Events, most recent first
|
||||||
val events: List<Event>,
|
val events: List<UploadEvent>,
|
||||||
// token to get more events
|
// token to get more events
|
||||||
val nextToken: String,
|
val nextToken: String,
|
||||||
// True if there are more event to load
|
// True if there are more event to load
|
||||||
val hasMore: Boolean
|
val hasMore: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.room.uploads
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around on Event.
|
||||||
|
* Similar to [im.vector.matrix.android.api.session.room.timeline.TimelineEvent], contains an Event with extra useful data
|
||||||
|
*/
|
||||||
|
data class UploadEvent(
|
||||||
|
val root: Event,
|
||||||
|
val eventId: String,
|
||||||
|
val contentWithAttachmentContent: MessageWithAttachmentContent,
|
||||||
|
val uploadSenderInfo: UploadSenderInfo
|
||||||
|
)
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.room.uploads
|
||||||
|
|
||||||
|
// TODO Maybe use this model for TimelineEvent as well
|
||||||
|
data class UploadSenderInfo(
|
||||||
|
val senderId: String,
|
||||||
|
val senderName: String?,
|
||||||
|
val isUniqueDisplayName: Boolean,
|
||||||
|
val senderAvatar: String?
|
||||||
|
) {
|
||||||
|
fun getDisambiguatedDisplayName(): String {
|
||||||
|
return when {
|
||||||
|
senderName.isNullOrBlank() -> senderId
|
||||||
|
isUniqueDisplayName -> senderName
|
||||||
|
else -> "$senderName (${senderId})"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -126,6 +126,7 @@ internal class RoomDisplayNameResolver @Inject constructor(private val context:
|
||||||
return name ?: roomId
|
return name ?: roomId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** See [im.vector.matrix.android.api.session.room.timeline.TimelineEvent.getDisambiguatedDisplayName] */
|
||||||
private fun resolveRoomMemberName(roomMemberSummary: RoomMemberSummaryEntity?,
|
private fun resolveRoomMemberName(roomMemberSummary: RoomMemberSummaryEntity?,
|
||||||
roomMemberHelper: RoomMemberHelper): String? {
|
roomMemberHelper: RoomMemberHelper): String? {
|
||||||
if (roomMemberSummary == null) return null
|
if (roomMemberSummary == null) return null
|
||||||
|
|
|
@ -16,10 +16,17 @@
|
||||||
|
|
||||||
package im.vector.matrix.android.internal.session.room.uploads
|
package im.vector.matrix.android.internal.session.room.uploads
|
||||||
|
|
||||||
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
|
||||||
import im.vector.matrix.android.api.session.room.uploads.GetUploadsResult
|
import im.vector.matrix.android.api.session.room.uploads.GetUploadsResult
|
||||||
|
import im.vector.matrix.android.api.session.room.uploads.UploadEvent
|
||||||
|
import im.vector.matrix.android.api.session.room.uploads.UploadSenderInfo
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.session.filter.FilterFactory
|
import im.vector.matrix.android.internal.session.filter.FilterFactory
|
||||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||||
|
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
|
||||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection
|
import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection
|
||||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationResponse
|
import im.vector.matrix.android.internal.session.room.timeline.PaginationResponse
|
||||||
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
|
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
|
||||||
|
@ -39,6 +46,7 @@ internal interface GetUploadsTask : Task<GetUploadsTask.Params, GetUploadsResult
|
||||||
internal class DefaultGetUploadsTask @Inject constructor(
|
internal class DefaultGetUploadsTask @Inject constructor(
|
||||||
private val roomAPI: RoomAPI,
|
private val roomAPI: RoomAPI,
|
||||||
private val tokenStore: SyncTokenStore,
|
private val tokenStore: SyncTokenStore,
|
||||||
|
private val monarchy: Monarchy,
|
||||||
private val eventBus: EventBus)
|
private val eventBus: EventBus)
|
||||||
: GetUploadsTask {
|
: GetUploadsTask {
|
||||||
|
|
||||||
|
@ -50,8 +58,42 @@ internal class DefaultGetUploadsTask @Inject constructor(
|
||||||
apiCall = roomAPI.getRoomMessagesFrom(params.roomId, since, PaginationDirection.BACKWARDS.value, params.numberOfEvents, filter)
|
apiCall = roomAPI.getRoomMessagesFrom(params.roomId, since, PaginationDirection.BACKWARDS.value, params.numberOfEvents, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var uploadEvents = listOf<UploadEvent>()
|
||||||
|
|
||||||
|
val cacheOfSenderInfos = mutableMapOf<String, UploadSenderInfo>()
|
||||||
|
|
||||||
|
// Get a snapshot of all room members
|
||||||
|
monarchy.doWithRealm { realm ->
|
||||||
|
val roomMemberHelper = RoomMemberHelper(realm, params.roomId)
|
||||||
|
|
||||||
|
uploadEvents = chunk.events.mapNotNull { event ->
|
||||||
|
val eventId = event.eventId ?: return@mapNotNull null
|
||||||
|
val messageContent = event.getClearContent()?.toModel<MessageContent>() ?: return@mapNotNull null
|
||||||
|
val messageWithAttachmentContent = (messageContent as? MessageWithAttachmentContent) ?: return@mapNotNull null
|
||||||
|
val senderId = event.senderId ?: return@mapNotNull null
|
||||||
|
|
||||||
|
val senderInfo = cacheOfSenderInfos.getOrPut(senderId) {
|
||||||
|
val roomMemberSummaryEntity = roomMemberHelper.getLastRoomMember(senderId)
|
||||||
|
UploadSenderInfo(
|
||||||
|
senderId = senderId,
|
||||||
|
senderName = roomMemberSummaryEntity?.displayName,
|
||||||
|
isUniqueDisplayName = roomMemberHelper.isUniqueDisplayName(roomMemberSummaryEntity?.displayName),
|
||||||
|
senderAvatar = roomMemberSummaryEntity?.avatarUrl
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadEvent(
|
||||||
|
root = event,
|
||||||
|
eventId = eventId,
|
||||||
|
contentWithAttachmentContent = messageWithAttachmentContent,
|
||||||
|
uploadSenderInfo = senderInfo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return GetUploadsResult(
|
return GetUploadsResult(
|
||||||
events = chunk.events,
|
events = uploadEvents,
|
||||||
nextToken = chunk.end ?: "",
|
nextToken = chunk.end ?: "",
|
||||||
hasMore = chunk.hasMore()
|
hasMore = chunk.hasMore()
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,13 +16,12 @@
|
||||||
|
|
||||||
package im.vector.riotx.features.roomprofile.uploads
|
package im.vector.riotx.features.roomprofile.uploads
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.room.uploads.UploadEvent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
|
|
||||||
import im.vector.riotx.core.platform.VectorViewModelAction
|
import im.vector.riotx.core.platform.VectorViewModelAction
|
||||||
|
|
||||||
sealed class RoomUploadsAction : VectorViewModelAction {
|
sealed class RoomUploadsAction : VectorViewModelAction {
|
||||||
data class Download(val event: Event, val messageContent: MessageWithAttachmentContent) : RoomUploadsAction()
|
data class Download(val uploadEvent: UploadEvent) : RoomUploadsAction()
|
||||||
data class Share(val event: Event, val messageContent: MessageWithAttachmentContent) : RoomUploadsAction()
|
data class Share(val uploadEvent: UploadEvent) : RoomUploadsAction()
|
||||||
|
|
||||||
object Retry : RoomUploadsAction()
|
object Retry : RoomUploadsAction()
|
||||||
object LoadMore : RoomUploadsAction()
|
object LoadMore : RoomUploadsAction()
|
||||||
|
|
|
@ -27,11 +27,8 @@ import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
|
||||||
import im.vector.matrix.android.api.session.events.model.isPreviewableMessage
|
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.file.FileService
|
import im.vector.matrix.android.api.session.file.FileService
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||||
import im.vector.matrix.android.api.session.room.model.message.getFileUrl
|
import im.vector.matrix.android.api.session.room.model.message.getFileUrl
|
||||||
import im.vector.matrix.android.api.session.room.uploads.GetUploadsResult
|
import im.vector.matrix.android.api.session.room.uploads.GetUploadsResult
|
||||||
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
||||||
|
@ -100,8 +97,10 @@ class RoomUploadsViewModel @AssistedInject constructor(
|
||||||
token = result.nextToken
|
token = result.nextToken
|
||||||
|
|
||||||
val groupedEvents = result.events
|
val groupedEvents = result.events
|
||||||
.filter { it.getClearType() == EventType.MESSAGE && it.getClearContent()?.toModel<MessageContent>() != null }
|
.groupBy {
|
||||||
.groupBy { it.isPreviewableMessage() }
|
it.contentWithAttachmentContent.msgType == MessageType.MSGTYPE_IMAGE
|
||||||
|
|| it.contentWithAttachmentContent.msgType == MessageType.MSGTYPE_VIDEO
|
||||||
|
}
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
|
@ -139,10 +138,10 @@ class RoomUploadsViewModel @AssistedInject constructor(
|
||||||
val file = awaitCallback<File> {
|
val file = awaitCallback<File> {
|
||||||
session.downloadFile(
|
session.downloadFile(
|
||||||
FileService.DownloadMode.FOR_EXTERNAL_SHARE,
|
FileService.DownloadMode.FOR_EXTERNAL_SHARE,
|
||||||
action.event.eventId ?: "",
|
action.uploadEvent.eventId,
|
||||||
action.messageContent.body,
|
action.uploadEvent.contentWithAttachmentContent.body,
|
||||||
action.messageContent.getFileUrl(),
|
action.uploadEvent.contentWithAttachmentContent.getFileUrl(),
|
||||||
action.messageContent.encryptedFileInfo?.toElementToDecrypt(),
|
action.uploadEvent.contentWithAttachmentContent.encryptedFileInfo?.toElementToDecrypt(),
|
||||||
it
|
it
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -159,14 +158,14 @@ class RoomUploadsViewModel @AssistedInject constructor(
|
||||||
val file = awaitCallback<File> {
|
val file = awaitCallback<File> {
|
||||||
session.downloadFile(
|
session.downloadFile(
|
||||||
FileService.DownloadMode.FOR_EXTERNAL_SHARE,
|
FileService.DownloadMode.FOR_EXTERNAL_SHARE,
|
||||||
action.event.eventId ?: "",
|
action.uploadEvent.eventId,
|
||||||
action.messageContent.body,
|
action.uploadEvent.contentWithAttachmentContent.body,
|
||||||
action.messageContent.getFileUrl(),
|
action.uploadEvent.contentWithAttachmentContent.getFileUrl(),
|
||||||
action.messageContent.encryptedFileInfo?.toElementToDecrypt(),
|
action.uploadEvent.contentWithAttachmentContent.encryptedFileInfo?.toElementToDecrypt(),
|
||||||
it)
|
it)
|
||||||
|
|
||||||
}
|
}
|
||||||
_viewEvents.post(RoomUploadsViewEvents.FileReadyForSaving(file, action.messageContent.body))
|
_viewEvents.post(RoomUploadsViewEvents.FileReadyForSaving(file, action.uploadEvent.contentWithAttachmentContent.body))
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomUploadsViewEvents.Failure(failure))
|
_viewEvents.post(RoomUploadsViewEvents.Failure(failure))
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,16 +19,16 @@ package im.vector.riotx.features.roomprofile.uploads
|
||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.Uninitialized
|
import com.airbnb.mvrx.Uninitialized
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import im.vector.matrix.android.api.session.room.uploads.UploadEvent
|
||||||
import im.vector.riotx.features.roomprofile.RoomProfileArgs
|
import im.vector.riotx.features.roomprofile.RoomProfileArgs
|
||||||
|
|
||||||
data class RoomUploadsViewState(
|
data class RoomUploadsViewState(
|
||||||
val roomId: String = "",
|
val roomId: String = "",
|
||||||
val roomSummary: Async<RoomSummary> = Uninitialized,
|
val roomSummary: Async<RoomSummary> = Uninitialized,
|
||||||
// Store cumul of pagination result, grouped by type
|
// Store cumul of pagination result, grouped by type
|
||||||
val mediaEvents: List<Event> = emptyList(),
|
val mediaEvents: List<UploadEvent> = emptyList(),
|
||||||
val fileEvents: List<Event> = emptyList(),
|
val fileEvents: List<UploadEvent> = emptyList(),
|
||||||
// Current pagination request
|
// Current pagination request
|
||||||
val asyncEventsRequest: Async<Unit> = Uninitialized,
|
val asyncEventsRequest: Async<Unit> = Uninitialized,
|
||||||
// True if more result are available server side
|
// True if more result are available server side
|
||||||
|
|
|
@ -20,8 +20,7 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.airbnb.mvrx.parentFragmentViewModel
|
import com.airbnb.mvrx.parentFragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.room.uploads.UploadEvent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
|
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.extensions.cleanup
|
import im.vector.riotx.core.extensions.cleanup
|
||||||
import im.vector.riotx.core.extensions.configureWith
|
import im.vector.riotx.core.extensions.configureWith
|
||||||
|
@ -54,8 +53,9 @@ class RoomUploadsFilesFragment @Inject constructor(
|
||||||
controller.listener = null
|
controller.listener = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOpenClicked(event: Event) {
|
override fun onOpenClicked(uploadEvent: UploadEvent) {
|
||||||
TODO()
|
// Same action than Share
|
||||||
|
uploadsViewModel.handle(RoomUploadsAction.Share(uploadEvent))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRetry() {
|
override fun onRetry() {
|
||||||
|
@ -66,12 +66,12 @@ class RoomUploadsFilesFragment @Inject constructor(
|
||||||
uploadsViewModel.handle(RoomUploadsAction.LoadMore)
|
uploadsViewModel.handle(RoomUploadsAction.LoadMore)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDownloadClicked(event: Event, messageWithAttachmentContent: MessageWithAttachmentContent) {
|
override fun onDownloadClicked(uploadEvent: UploadEvent) {
|
||||||
uploadsViewModel.handle(RoomUploadsAction.Download(event, messageWithAttachmentContent))
|
uploadsViewModel.handle(RoomUploadsAction.Download(uploadEvent))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onShareClicked(event: Event, messageWithAttachmentContent: MessageWithAttachmentContent) {
|
override fun onShareClicked(uploadEvent: UploadEvent) {
|
||||||
uploadsViewModel.handle(RoomUploadsAction.Share(event, messageWithAttachmentContent))
|
uploadsViewModel.handle(RoomUploadsAction.Share(uploadEvent))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidate() = withState(uploadsViewModel) { state ->
|
override fun invalidate() = withState(uploadsViewModel) { state ->
|
||||||
|
|
|
@ -21,10 +21,7 @@ import com.airbnb.epoxy.VisibilityState
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.room.uploads.UploadEvent
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
|
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.date.VectorDateFormatter
|
import im.vector.riotx.core.date.VectorDateFormatter
|
||||||
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
||||||
|
@ -44,9 +41,9 @@ class UploadsFileController @Inject constructor(
|
||||||
interface Listener {
|
interface Listener {
|
||||||
fun onRetry()
|
fun onRetry()
|
||||||
fun loadMore()
|
fun loadMore()
|
||||||
fun onOpenClicked(event: Event)
|
fun onOpenClicked(uploadEvent: UploadEvent)
|
||||||
fun onDownloadClicked(event: Event, messageWithAttachmentContent: MessageWithAttachmentContent)
|
fun onDownloadClicked(uploadEvent: UploadEvent)
|
||||||
fun onShareClicked(event: Event, messageWithAttachmentContent: MessageWithAttachmentContent)
|
fun onShareClicked(uploadEvent: UploadEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
var listener: Listener? = null
|
var listener: Listener? = null
|
||||||
|
@ -106,27 +103,25 @@ class UploadsFileController @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildFileItems(fileEvents: List<Event>) {
|
private fun buildFileItems(fileEvents: List<UploadEvent>) {
|
||||||
fileEvents.forEach {
|
fileEvents.forEach { uploadEvent ->
|
||||||
val messageContent = it.getClearContent()?.toModel<MessageContent>() ?: return@forEach
|
|
||||||
val messageWithAttachmentContent = (messageContent as? MessageWithAttachmentContent) ?: return@forEach
|
|
||||||
|
|
||||||
uploadsFileItem {
|
uploadsFileItem {
|
||||||
id(it.eventId ?: "")
|
id(uploadEvent.eventId)
|
||||||
title(messageWithAttachmentContent.body)
|
title(uploadEvent.contentWithAttachmentContent.body)
|
||||||
// TODO Resolve user displayName
|
subtitle(stringProvider.getString(R.string.uploads_files_subtitle,
|
||||||
subtitle(stringProvider.getString(R.string.uploads_files_subtitle, it.senderId, dateFormatter.formatRelativeDateTime(it.originServerTs)))
|
uploadEvent.uploadSenderInfo.getDisambiguatedDisplayName(),
|
||||||
|
dateFormatter.formatRelativeDateTime(uploadEvent.root.originServerTs)))
|
||||||
listener(object : UploadsFileItem.Listener {
|
listener(object : UploadsFileItem.Listener {
|
||||||
override fun onItemClicked() {
|
override fun onItemClicked() {
|
||||||
listener?.onOpenClicked(it)
|
listener?.onOpenClicked(uploadEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDownloadClicked() {
|
override fun onDownloadClicked() {
|
||||||
listener?.onDownloadClicked(it, messageWithAttachmentContent)
|
listener?.onDownloadClicked(uploadEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onShareClicked() {
|
override fun onShareClicked() {
|
||||||
listener?.onShareClicked(it, messageWithAttachmentContent)
|
listener?.onShareClicked(uploadEvent)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,11 @@ import com.airbnb.epoxy.VisibilityState
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
|
||||||
import im.vector.matrix.android.api.session.events.model.isImageMessage
|
|
||||||
import im.vector.matrix.android.api.session.events.model.isVideoMessage
|
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.getFileUrl
|
import im.vector.matrix.android.api.session.room.model.message.getFileUrl
|
||||||
|
import im.vector.matrix.android.api.session.room.uploads.UploadEvent
|
||||||
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
||||||
|
@ -115,13 +113,13 @@ class UploadsMediaController @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildMediaItems(mediaEvents: List<Event>) {
|
private fun buildMediaItems(mediaEvents: List<UploadEvent>) {
|
||||||
mediaEvents.forEach { event ->
|
mediaEvents.forEach { uploadEvent ->
|
||||||
when {
|
when (uploadEvent.contentWithAttachmentContent.msgType) {
|
||||||
event.isImageMessage() -> {
|
MessageType.MSGTYPE_IMAGE -> {
|
||||||
val data = event.toImageContentRendererData() ?: return@forEach
|
val data = uploadEvent.toImageContentRendererData() ?: return@forEach
|
||||||
uploadsImageItem {
|
uploadsImageItem {
|
||||||
id(event.eventId ?: "")
|
id(uploadEvent.eventId)
|
||||||
imageContentRenderer(imageContentRenderer)
|
imageContentRenderer(imageContentRenderer)
|
||||||
data(data)
|
data(data)
|
||||||
listener(object : UploadsImageItem.Listener {
|
listener(object : UploadsImageItem.Listener {
|
||||||
|
@ -131,10 +129,10 @@ class UploadsMediaController @Inject constructor(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.isVideoMessage() -> {
|
MessageType.MSGTYPE_VIDEO -> {
|
||||||
val data = event.toVideoContentRendererData() ?: return@forEach
|
val data = uploadEvent.toVideoContentRendererData() ?: return@forEach
|
||||||
uploadsVideoItem {
|
uploadsVideoItem {
|
||||||
id(event.eventId ?: "")
|
id(uploadEvent.eventId)
|
||||||
imageContentRenderer(imageContentRenderer)
|
imageContentRenderer(imageContentRenderer)
|
||||||
data(data)
|
data(data)
|
||||||
listener(object : UploadsVideoItem.Listener {
|
listener(object : UploadsVideoItem.Listener {
|
||||||
|
@ -148,11 +146,11 @@ class UploadsMediaController @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Event.toImageContentRendererData(): ImageContentRenderer.Data? {
|
private fun UploadEvent.toImageContentRendererData(): ImageContentRenderer.Data? {
|
||||||
val messageContent = getClearContent()?.toModel<MessageImageContent>() ?: return null
|
val messageContent = (contentWithAttachmentContent as? MessageImageContent) ?: return null
|
||||||
|
|
||||||
return ImageContentRenderer.Data(
|
return ImageContentRenderer.Data(
|
||||||
eventId = eventId ?: "",
|
eventId = eventId,
|
||||||
filename = messageContent.body,
|
filename = messageContent.body,
|
||||||
url = messageContent.getFileUrl(),
|
url = messageContent.getFileUrl(),
|
||||||
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt(),
|
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt(),
|
||||||
|
@ -163,11 +161,11 @@ class UploadsMediaController @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Event.toVideoContentRendererData(): VideoContentRenderer.Data? {
|
private fun UploadEvent.toVideoContentRendererData(): VideoContentRenderer.Data? {
|
||||||
val messageContent = getClearContent()?.toModel<MessageVideoContent>() ?: return null
|
val messageContent = (contentWithAttachmentContent as? MessageVideoContent) ?: return null
|
||||||
|
|
||||||
val thumbnailData = ImageContentRenderer.Data(
|
val thumbnailData = ImageContentRenderer.Data(
|
||||||
eventId = eventId ?: "",
|
eventId = eventId,
|
||||||
filename = messageContent.body,
|
filename = messageContent.body,
|
||||||
url = messageContent.videoInfo?.thumbnailFile?.url ?: messageContent.videoInfo?.thumbnailUrl,
|
url = messageContent.videoInfo?.thumbnailFile?.url ?: messageContent.videoInfo?.thumbnailUrl,
|
||||||
elementToDecrypt = messageContent.videoInfo?.thumbnailFile?.toElementToDecrypt(),
|
elementToDecrypt = messageContent.videoInfo?.thumbnailFile?.toElementToDecrypt(),
|
||||||
|
@ -178,7 +176,7 @@ class UploadsMediaController @Inject constructor(
|
||||||
)
|
)
|
||||||
|
|
||||||
return VideoContentRenderer.Data(
|
return VideoContentRenderer.Data(
|
||||||
eventId = eventId ?: "",
|
eventId = eventId,
|
||||||
filename = messageContent.body,
|
filename = messageContent.body,
|
||||||
url = messageContent.getFileUrl(),
|
url = messageContent.getFileUrl(),
|
||||||
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt(),
|
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt(),
|
||||||
|
|
Loading…
Reference in a new issue