Fix width of attachment download status text.

This commit is contained in:
Nicholas Tinsley 2024-01-08 13:58:28 -05:00 committed by Alex Hart
parent 1bb0c55d88
commit 7aab86643a
3 changed files with 79 additions and 31 deletions

View file

@ -4,15 +4,16 @@
*/ */
package org.thoughtcrime.securesms.components.transfercontrols package org.thoughtcrime.securesms.components.transfercontrols
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.text.format.Formatter import android.text.StaticLayout
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children import androidx.core.view.children
import androidx.core.view.updateLayoutParams
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
@ -29,6 +30,8 @@ import org.thoughtcrime.securesms.util.ThrottledDebouncer
import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.visible import org.thoughtcrime.securesms.util.visible
import java.util.UUID import java.util.UUID
import kotlin.math.ceil
import kotlin.math.roundToInt
class TransferControlView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout(context, attrs, defStyleAttr) { class TransferControlView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout(context, attrs, defStyleAttr) {
private val uuid = UUID.randomUUID().toString() private val uuid = UUID.randomUUID().toString()
@ -236,11 +239,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
} else { } else {
ViewUtil.dpToPx(PRIMARY_TEXT_OFFSET_DP).toFloat() ViewUtil.dpToPx(PRIMARY_TEXT_OFFSET_DP).toFloat()
} }
val remainingSlides = currentState.slides.filterNot { it.transferState == AttachmentTable.TRANSFER_PROGRESS_DONE } setSecondaryDetailsText(currentState)
val downloadCount = remainingSlides.size
binding.primaryDetailsText.text = context.resources.getQuantityString(R.plurals.TransferControlView_n_items, downloadCount, downloadCount)
val byteCount = currentState.networkProgress.sumTotal() - currentState.networkProgress.sumCompleted()
binding.secondaryDetailsText.text = Formatter.formatShortFileSize(context, byteCount)
} }
private fun displayPendingGalleryWithPlayable(currentState: TransferControlViewState) { private fun displayPendingGalleryWithPlayable(currentState: TransferControlViewState) {
@ -259,13 +258,12 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
) )
binding.secondaryProgressView.setStopped(false) binding.secondaryProgressView.setStopped(false)
setSecondaryDetailsText(currentState)
binding.secondaryDetailsText.translationX = if (ViewUtil.isLtr(this)) { binding.secondaryDetailsText.translationX = if (ViewUtil.isLtr(this)) {
ViewUtil.dpToPx(-SECONDARY_TEXT_OFFSET_DP).toFloat() ViewUtil.dpToPx(-SECONDARY_TEXT_OFFSET_DP).toFloat()
} else { } else {
ViewUtil.dpToPx(SECONDARY_TEXT_OFFSET_DP).toFloat() ViewUtil.dpToPx(SECONDARY_TEXT_OFFSET_DP).toFloat()
} }
val byteCount = currentState.networkProgress.sumTotal() - currentState.networkProgress.sumCompleted()
binding.secondaryDetailsText.text = Formatter.formatShortFileSize(context, byteCount)
} }
private fun displayPendingSingleItem(currentState: TransferControlViewState) { private fun displayPendingSingleItem(currentState: TransferControlViewState) {
@ -278,9 +276,8 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
secondaryProgressView = false, secondaryProgressView = false,
secondaryDetailsText = currentState.showSecondaryText secondaryDetailsText = currentState.showSecondaryText
) )
val byteCount = currentState.slides.sumOf { it.asAttachment().size }
binding.secondaryDetailsText.translationX = 0f binding.secondaryDetailsText.translationX = 0f
binding.secondaryDetailsText.text = Formatter.formatShortFileSize(context, byteCount) setSecondaryDetailsText(currentState)
} }
private fun displayPendingPlayableVideo(currentState: TransferControlViewState) { private fun displayPendingPlayableVideo(currentState: TransferControlViewState) {
@ -300,13 +297,12 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
secondaryDetailsText = currentState.showSecondaryText, secondaryDetailsText = currentState.showSecondaryText,
secondaryProgressView = currentState.showSecondaryText secondaryProgressView = currentState.showSecondaryText
) )
setSecondaryDetailsText(currentState)
binding.secondaryDetailsText.translationX = if (ViewUtil.isLtr(this)) { binding.secondaryDetailsText.translationX = if (ViewUtil.isLtr(this)) {
ViewUtil.dpToPx(-SECONDARY_TEXT_OFFSET_DP).toFloat() ViewUtil.dpToPx(-SECONDARY_TEXT_OFFSET_DP).toFloat()
} else { } else {
ViewUtil.dpToPx(SECONDARY_TEXT_OFFSET_DP).toFloat() ViewUtil.dpToPx(SECONDARY_TEXT_OFFSET_DP).toFloat()
} }
val byteCount = currentState.slides.sumOf { it.asAttachment().size }
binding.secondaryDetailsText.text = Formatter.formatShortFileSize(context, byteCount)
} }
private fun displayDownloadingGallery(currentState: TransferControlViewState) { private fun displayDownloadingGallery(currentState: TransferControlViewState) {
@ -326,7 +322,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
binding.secondaryProgressView.setProgress(progress) binding.secondaryProgressView.setProgress(progress)
} }
binding.secondaryDetailsText.translationX = 0f binding.secondaryDetailsText.translationX = 0f
binding.secondaryDetailsText.text = deriveSecondaryDetailsText(currentState) setSecondaryDetailsText(currentState)
} }
private fun displayDownloadingSingleItem(currentState: TransferControlViewState) { private fun displayDownloadingSingleItem(currentState: TransferControlViewState) {
@ -346,7 +342,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
binding.primaryProgressView.setProgress(progress) binding.primaryProgressView.setProgress(progress)
} }
binding.secondaryDetailsText.translationX = 0f binding.secondaryDetailsText.translationX = 0f
binding.secondaryDetailsText.text = deriveSecondaryDetailsText(currentState) setSecondaryDetailsText(currentState)
} }
private fun displayDownloadingPlayableVideo(currentState: TransferControlViewState) { private fun displayDownloadingPlayableVideo(currentState: TransferControlViewState) {
@ -367,7 +363,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
binding.secondaryProgressView.setProgress(progress) binding.secondaryProgressView.setProgress(progress)
} }
binding.secondaryDetailsText.translationX = 0f binding.secondaryDetailsText.translationX = 0f
binding.secondaryDetailsText.text = deriveSecondaryDetailsText(currentState) setSecondaryDetailsText(currentState)
} }
private fun displayUploadingSingleItem(currentState: TransferControlViewState) { private fun displayUploadingSingleItem(currentState: TransferControlViewState) {
@ -384,7 +380,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
binding.secondaryProgressView.setProgress(progress) binding.secondaryProgressView.setProgress(progress)
binding.secondaryDetailsText.translationX = 0f binding.secondaryDetailsText.translationX = 0f
binding.secondaryDetailsText.text = deriveSecondaryDetailsText(currentState) setSecondaryDetailsText(currentState)
} }
private fun displayUploadingGallery(currentState: TransferControlViewState) { private fun displayUploadingGallery(currentState: TransferControlViewState) {
@ -400,7 +396,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
binding.secondaryProgressView.setProgress(progress) binding.secondaryProgressView.setProgress(progress)
binding.secondaryDetailsText.translationX = 0f binding.secondaryDetailsText.translationX = 0f
binding.secondaryDetailsText.text = deriveSecondaryDetailsText(currentState) setSecondaryDetailsText(currentState)
} }
private fun displayRetry(currentState: TransferControlViewState, isUploading: Boolean) { private fun displayRetry(currentState: TransferControlViewState, isUploading: Boolean) {
@ -420,15 +416,15 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
primaryDetailsText = false, primaryDetailsText = false,
secondaryDetailsText = currentState.showSecondaryText secondaryDetailsText = currentState.showSecondaryText
) )
binding.secondaryBackground.setOnClickListener(currentState.startTransferClickListener)
binding.secondaryDetailsText.setOnClickListener(currentState.startTransferClickListener)
binding.secondaryProgressView.setStopped(isUploading)
setSecondaryDetailsText(currentState)
binding.secondaryDetailsText.translationX = if (ViewUtil.isLtr(this)) { binding.secondaryDetailsText.translationX = if (ViewUtil.isLtr(this)) {
ViewUtil.dpToPx(-RETRY_SECONDARY_TEXT_OFFSET_DP).toFloat() ViewUtil.dpToPx(-RETRY_SECONDARY_TEXT_OFFSET_DP).toFloat()
} else { } else {
ViewUtil.dpToPx(RETRY_SECONDARY_TEXT_OFFSET_DP).toFloat() ViewUtil.dpToPx(RETRY_SECONDARY_TEXT_OFFSET_DP).toFloat()
} }
binding.secondaryBackground.setOnClickListener(currentState.startTransferClickListener)
binding.secondaryDetailsText.setOnClickListener(currentState.startTransferClickListener)
binding.secondaryProgressView.setStopped(isUploading)
binding.secondaryDetailsText.text = resources.getString(R.string.NetworkFailure__retry)
} }
private fun displayChildrenAsGone() { private fun displayChildrenAsGone() {
@ -654,14 +650,62 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
return weightedProgress / weightedTotal return weightedProgress / weightedTotal
} }
@SuppressLint("SetTextI18n") private fun setSecondaryDetailsText(currentState: TransferControlViewState) {
private fun deriveSecondaryDetailsText(currentState: TransferControlViewState): String { when (deriveMode(currentState)) {
return if (currentState.networkProgress.sumCompleted() == 0L || isCompressing(currentState)) { Mode.PENDING_GALLERY -> {
return context.getString(R.string.TransferControlView__processing) binding.secondaryDetailsText.updateLayoutParams {
} else { width = ViewGroup.LayoutParams.WRAP_CONTENT
val progressMiB = currentState.networkProgress.sumCompleted() / MEBIBYTE }
val totalMiB = currentState.networkProgress.sumTotal() / MEBIBYTE val remainingSlides = currentState.slides.filterNot { it.transferState == AttachmentTable.TRANSFER_PROGRESS_DONE }
context.resources.getString(R.string.TransferControlView__download_progress, progressMiB, totalMiB) val downloadCount = remainingSlides.size
binding.primaryDetailsText.text = context.resources.getQuantityString(R.plurals.TransferControlView_n_items, downloadCount, downloadCount)
val mebibyteCount = (currentState.networkProgress.sumTotal() - currentState.networkProgress.sumCompleted()) / MEBIBYTE
binding.secondaryDetailsText.text = context.getString(R.string.TransferControlView__filesize, mebibyteCount)
}
Mode.PENDING_GALLERY_CONTAINS_PLAYABLE -> {
binding.secondaryDetailsText.updateLayoutParams {
width = ViewGroup.LayoutParams.WRAP_CONTENT
}
val mebibyteCount = (currentState.networkProgress.sumTotal() - currentState.networkProgress.sumCompleted()) / MEBIBYTE
binding.secondaryDetailsText.text = context.getString(R.string.TransferControlView__filesize, mebibyteCount)
}
Mode.PENDING_SINGLE_ITEM, Mode.PENDING_VIDEO_PLAYABLE -> {
binding.secondaryDetailsText.updateLayoutParams {
width = ViewGroup.LayoutParams.WRAP_CONTENT
}
val mebibyteCount = (currentState.slides.sumOf { it.asAttachment().size }) / MEBIBYTE
binding.secondaryDetailsText.text = context.getString(R.string.TransferControlView__filesize, mebibyteCount)
}
Mode.DOWNLOADING_GALLERY, Mode.DOWNLOADING_SINGLE_ITEM, Mode.DOWNLOADING_VIDEO_PLAYABLE, Mode.UPLOADING_GALLERY, Mode.UPLOADING_SINGLE_ITEM -> {
if (currentState.networkProgress.sumCompleted() == 0L || isCompressing(currentState)) {
binding.secondaryDetailsText.updateLayoutParams {
width = ViewGroup.LayoutParams.WRAP_CONTENT
}
binding.secondaryDetailsText.text = context.getString(R.string.TransferControlView__processing)
} else {
val progressMiB = currentState.networkProgress.sumCompleted() / MEBIBYTE
val totalMiB = currentState.networkProgress.sumTotal() / MEBIBYTE
val completedLabel = context.resources.getString(R.string.TransferControlView__download_progress, totalMiB, totalMiB)
val desiredWidth = StaticLayout.getDesiredWidth(completedLabel, binding.secondaryDetailsText.paint)
binding.secondaryDetailsText.text = context.resources.getString(R.string.TransferControlView__download_progress, progressMiB, totalMiB)
val roundedWidth = ceil(desiredWidth.toDouble()).roundToInt() + binding.secondaryDetailsText.compoundPaddingLeft + binding.secondaryDetailsText.compoundPaddingRight
binding.secondaryDetailsText.updateLayoutParams {
width = roundedWidth
}
}
}
Mode.RETRY_DOWNLOADING, Mode.RETRY_UPLOADING -> {
binding.secondaryDetailsText.text = resources.getString(R.string.NetworkFailure__retry)
binding.secondaryDetailsText.updateLayoutParams {
width = ViewGroup.LayoutParams.WRAP_CONTENT
}
}
Mode.GONE -> Unit
} }
} }

View file

@ -57,13 +57,15 @@
android:layout_marginStart="@dimen/transfer_control_view_progressbar_to_textview_margin" android:layout_marginStart="@dimen/transfer_control_view_progressbar_to_textview_margin"
android:layout_marginEnd="4dp" android:layout_marginEnd="4dp"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:gravity="center" android:gravity="center_vertical|end"
android:includeFontPadding="false" android:includeFontPadding="false"
android:longClickable="false" android:longClickable="false"
android:maxLines="1"
android:paddingStart="4dp" android:paddingStart="4dp"
android:paddingTop="2dp" android:paddingTop="2dp"
android:paddingEnd="9dp" android:paddingEnd="9dp"
android:paddingBottom="2dp" android:paddingBottom="2dp"
android:textAlignment="viewEnd"
android:textColor="@color/signal_colorOnCustom" android:textColor="@color/signal_colorOnCustom"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="@+id/secondary_progress_view" app:layout_constraintStart_toEndOf="@+id/secondary_progress_view"

View file

@ -2423,6 +2423,8 @@
<string name="TransferControlView__processing">Processing…</string> <string name="TransferControlView__processing">Processing…</string>
<!-- Status update label used while the device is transmitting data over the network. Will take the form of "1.0 MB/2.0 MB" --> <!-- Status update label used while the device is transmitting data over the network. Will take the form of "1.0 MB/2.0 MB" -->
<string name="TransferControlView__download_progress">%1.1f MB/%2.1f MB</string> <string name="TransferControlView__download_progress">%1.1f MB/%2.1f MB</string>
<!-- Attachment file size label for not-yet-downloaded images and video. Will take the form of "1.0 MB" -->
<string name="TransferControlView__filesize">%1.1f MB</string>
<!-- UnauthorizedReminder --> <!-- UnauthorizedReminder -->