Display progress in the timeline when uploading file

This commit is contained in:
Benoit Marty 2019-09-25 14:39:33 +02:00
parent f077cc8467
commit 17cba1a432
7 changed files with 37 additions and 12 deletions

View file

@ -24,6 +24,8 @@ import java.io.File
// Implementation should return true in case of success
typealias ActionOnFile = (file: File) -> Boolean
internal fun String?.isLocalFile() = this != null && File(this).exists()
/* ==========================================================================================
* Delete
* ========================================================================================== */

View file

@ -42,6 +42,7 @@ import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.core.utils.containsOnlyEmojis
import im.vector.riotx.core.utils.isLocalFile
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
@ -117,6 +118,8 @@ class MessageItemFactory @Inject constructor(
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.izLocalFile(messageContent.getFileUrl().isLocalFile())
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -147,6 +150,8 @@ class MessageItemFactory @Inject constructor(
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.dimensionConverter(dimensionConverter)
.izLocalFile(messageContent.getFileUrl().isLocalFile())
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)

View file

@ -27,7 +27,6 @@ import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.features.media.ImageContentRenderer
import im.vector.riotx.features.ui.getMessageTextColor
import javax.inject.Inject
@ -37,12 +36,12 @@ class ContentUploadStateTrackerBinder @Inject constructor(private val activeSess
private val updateListeners = mutableMapOf<String, ContentUploadStateTracker.UpdateListener>()
fun bind(eventId: String,
mediaData: ImageContentRenderer.Data,
isLocalFile: Boolean,
progressLayout: ViewGroup) {
activeSessionHolder.getActiveSession().also { session ->
val uploadStateTracker = session.contentUploadProgressTracker()
val updateListener = ContentMediaProgressUpdater(progressLayout, mediaData, colorProvider)
val updateListener = ContentMediaProgressUpdater(progressLayout, isLocalFile, colorProvider)
updateListeners[eventId] = updateListener
uploadStateTracker.track(eventId, updateListener)
}
@ -60,7 +59,7 @@ class ContentUploadStateTrackerBinder @Inject constructor(private val activeSess
}
private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
private val mediaData: ImageContentRenderer.Data,
private val isLocalFile: Boolean,
private val colorProvider: ColorProvider) : ContentUploadStateTracker.UpdateListener {
override fun onUpdate(state: ContentUploadStateTracker.State) {
@ -76,7 +75,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
}
private fun handleIdle(state: ContentUploadStateTracker.State.Idle) {
if (mediaData.isLocalFile()) {
if (isLocalFile) {
progressLayout.isVisible = true
val progressBar = progressLayout.findViewById<ProgressBar>(R.id.mediaProgressBar)
val progressTextView = progressLayout.findViewById<TextView>(R.id.mediaProgressTextView)

View file

@ -22,9 +22,11 @@ import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
import im.vector.riotx.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
@ -36,19 +38,35 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
var iconRes: Int = 0
@EpoxyAttribute
var clickListener: View.OnClickListener? = null
@EpoxyAttribute
var izLocalFile = false
@EpoxyAttribute
lateinit var contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder
override fun bind(holder: Holder) {
super.bind(holder)
renderSendState(holder.fileLayout, holder.filenameView)
if (!informationData.sendState.hasFailed()) {
contentUploadStateTrackerBinder.bind(informationData.eventId, izLocalFile, holder.progressLayout)
} else {
holder.progressLayout.isVisible = false
}
holder.filenameView.text = filename
holder.fileImageView.setImageResource(iconRes)
holder.filenameView.setOnClickListener(clickListener)
holder.filenameView.paintFlags = (holder.filenameView.paintFlags or Paint.UNDERLINE_TEXT_FLAG)
}
override fun unbind(holder: Holder) {
super.unbind(holder)
contentUploadStateTrackerBinder.unbind(informationData.eventId)
}
override fun getViewType() = STUB_ID
class Holder : AbsMessageItem.Holder(STUB_ID) {
val progressLayout by bind<ViewGroup>(R.id.messageFileUploadProgressLayout)
val fileLayout by bind<ViewGroup>(R.id.messageFileLayout)
val fileImageView by bind<ImageView>(R.id.messageFileImageView)
val filenameView by bind<TextView>(R.id.messageFilenameView)

View file

@ -20,6 +20,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
@ -44,11 +45,13 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
super.bind(holder)
imageContentRenderer.render(mediaData, ImageContentRenderer.Mode.THUMBNAIL, holder.imageView)
if (!informationData.sendState.hasFailed()) {
contentUploadStateTrackerBinder.bind(informationData.eventId, mediaData, holder.progressLayout)
contentUploadStateTrackerBinder.bind(informationData.eventId, mediaData.isLocalFile(), holder.progressLayout)
} else {
holder.progressLayout.isVisible = false
}
holder.imageView.setOnClickListener(clickListener)
holder.imageView.setOnLongClickListener(longClickListener)
ViewCompat.setTransitionName(holder.imageView,"imagePreview_${id()}")
ViewCompat.setTransitionName(holder.imageView, "imagePreview_${id()}")
holder.mediaContentView.setOnClickListener(cellClickListener)
holder.mediaContentView.setOnLongClickListener(longClickListener)
// The sending state color will be apply to the progress text

View file

@ -33,9 +33,9 @@ import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.glide.GlideApp
import im.vector.riotx.core.glide.GlideRequest
import im.vector.riotx.core.utils.DimensionConverter
import im.vector.riotx.core.utils.isLocalFile
import kotlinx.android.parcel.Parcelize
import timber.log.Timber
import java.io.File
import javax.inject.Inject
class ImageContentRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
@ -54,9 +54,7 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
val rotation: Int? = null
) : Parcelable {
fun isLocalFile(): Boolean {
return url != null && File(url).exists()
}
fun isLocalFile() = url.isLocalFile()
}
enum class Mode {

View file

@ -51,7 +51,7 @@
</LinearLayout>
<include
android:id="@+id/messageMediaUploadProgressLayout"
android:id="@+id/messageFileUploadProgressLayout"
layout="@layout/media_upload_download_progress_layout"
android:layout_width="0dp"
android:layout_height="46dp"