mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 21:48:50 +03:00
Display progress in the timeline when uploading file
This commit is contained in:
parent
f077cc8467
commit
17cba1a432
7 changed files with 37 additions and 12 deletions
|
@ -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
|
||||
* ========================================================================================== */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue