Use dynamic/rule-based size calculations for transfer control view.
This commit is contained in:
parent
e945efac8b
commit
d7c2e6844b
3 changed files with 37 additions and 27 deletions
|
@ -17,6 +17,8 @@ import androidx.core.view.updateLayoutParams
|
|||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.signal.core.util.ByteSize
|
||||
import org.signal.core.util.bytes
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.attachments.Attachment
|
||||
|
@ -529,7 +531,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
val existingEvent = mutableMap[attachment]
|
||||
if (existingEvent == null || updateEvent.completed > existingEvent.completed) {
|
||||
mutableMap[attachment] = updateEvent
|
||||
} else if (updateEvent.completed < 0) {
|
||||
} else if (updateEvent.completed < 0.bytes) {
|
||||
mutableMap.remove(attachment)
|
||||
}
|
||||
verboseLog("onEventAsync compression update")
|
||||
|
@ -540,7 +542,7 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
val existingEvent = mutableMap[attachment]
|
||||
if (existingEvent == null || updateEvent.completed > existingEvent.completed) {
|
||||
mutableMap[attachment] = updateEvent
|
||||
} else if (updateEvent.completed < 0) {
|
||||
} else if (updateEvent.completed < 0.bytes) {
|
||||
mutableMap.remove(attachment)
|
||||
}
|
||||
verboseLog("onEventAsync network update")
|
||||
|
@ -556,14 +558,14 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
val isNewSlideSet = !isUpdateToExistingSet(state, slides)
|
||||
val networkProgress: MutableMap<Attachment, Progress> = if (isNewSlideSet) HashMap() else state.networkProgress.toMutableMap()
|
||||
if (isNewSlideSet) {
|
||||
slides.forEach { networkProgress[it.asAttachment()] = Progress(0L, it.fileSize) }
|
||||
slides.forEach { networkProgress[it.asAttachment()] = Progress(0.bytes, it.fileSize.bytes) }
|
||||
}
|
||||
val compressionProgress: MutableMap<Attachment, Progress> = if (isNewSlideSet) HashMap() else state.compressionProgress.toMutableMap()
|
||||
var allStreamableOrDone = true
|
||||
for (slide in slides) {
|
||||
val attachment = slide.asAttachment()
|
||||
if (attachment.transferState == AttachmentTable.TRANSFER_PROGRESS_DONE) {
|
||||
networkProgress[attachment] = Progress(attachment.size, attachment.size)
|
||||
networkProgress[attachment] = Progress(attachment.size.bytes, attachment.size.bytes)
|
||||
} else if (!MediaUtil.isInstantVideoSupported(slide)) {
|
||||
allStreamableOrDone = false
|
||||
}
|
||||
|
@ -657,12 +659,12 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
|
||||
private fun isCompressing(state: TransferControlViewState): Boolean {
|
||||
val total = state.compressionProgress.sumTotal()
|
||||
return total > 0 && state.compressionProgress.sumCompleted() / total < 0.99f
|
||||
return total > 0.bytes && state.compressionProgress.sumCompleted().percentageOf(total) < 0.99f
|
||||
}
|
||||
|
||||
private fun calculateProgress(state: TransferControlViewState): Float {
|
||||
val totalCompressionProgress: Float = state.compressionProgress.values.map { it.completed.toFloat() / it.total }.sum()
|
||||
val totalDownloadProgress: Float = state.networkProgress.values.map { it.completed.toFloat() / it.total }.sum()
|
||||
val totalCompressionProgress: Float = state.compressionProgress.values.map { it.completed.percentageOf(it.total) }.sum()
|
||||
val totalDownloadProgress: Float = state.networkProgress.values.map { it.completed.percentageOf(it.total) }.sum()
|
||||
val weightedProgress = UPLOAD_TASK_WEIGHT * totalDownloadProgress + COMPRESSION_TASK_WEIGHT * totalCompressionProgress
|
||||
val weightedTotal = (UPLOAD_TASK_WEIGHT * state.networkProgress.size + COMPRESSION_TASK_WEIGHT * state.compressionProgress.size).toFloat()
|
||||
return weightedProgress / weightedTotal
|
||||
|
@ -677,35 +679,35 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
val remainingSlides = currentState.slides.filterNot { it.transferState == AttachmentTable.TRANSFER_PROGRESS_DONE }
|
||||
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)
|
||||
val size = currentState.networkProgress.sumTotal() - currentState.networkProgress.sumCompleted()
|
||||
binding.secondaryDetailsText.text = size.toUnitString()
|
||||
}
|
||||
|
||||
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)
|
||||
val size = currentState.networkProgress.sumTotal() - currentState.networkProgress.sumCompleted()
|
||||
binding.secondaryDetailsText.text = size.toUnitString()
|
||||
}
|
||||
|
||||
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)
|
||||
val size: ByteSize = (currentState.slides.sumOf { it.asAttachment().size }).bytes
|
||||
binding.secondaryDetailsText.text = size.toUnitString()
|
||||
}
|
||||
|
||||
Mode.DOWNLOADING_GALLERY, Mode.DOWNLOADING_SINGLE_ITEM, Mode.DOWNLOADING_VIDEO_PLAYABLE, Mode.UPLOADING_GALLERY, Mode.UPLOADING_SINGLE_ITEM -> {
|
||||
if (currentState.isUpload && (currentState.networkProgress.sumCompleted() == 0L || isCompressing(currentState))) {
|
||||
if (currentState.isUpload && (currentState.networkProgress.sumCompleted() == 0.bytes || 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 progressMiB = currentState.networkProgress.sumCompleted().toUnitString()
|
||||
val totalMiB = currentState.networkProgress.sumTotal().toUnitString()
|
||||
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)
|
||||
|
@ -743,7 +745,6 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
private const val SECONDARY_TEXT_OFFSET_DP = 6
|
||||
private const val RETRY_SECONDARY_TEXT_OFFSET_DP = 6
|
||||
private const val PRIMARY_TEXT_OFFSET_DP = 4
|
||||
private const val MEBIBYTE = 1048576f
|
||||
|
||||
/**
|
||||
* A weighting compared to [UPLOAD_TASK_WEIGHT]
|
||||
|
@ -773,20 +774,20 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
}
|
||||
}
|
||||
|
||||
data class Progress(val completed: Long, val total: Long) {
|
||||
data class Progress(val completed: ByteSize, val total: ByteSize) {
|
||||
companion object {
|
||||
fun fromEvent(event: PartProgressEvent): Progress {
|
||||
return Progress(event.progress, event.total)
|
||||
return Progress(event.progress.bytes, event.total.bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Map<Attachment, Progress>.sumCompleted(): Long {
|
||||
return this.values.sumOf { it.completed }
|
||||
private fun Map<Attachment, Progress>.sumCompleted(): ByteSize {
|
||||
return this.values.sumOf { it.completed.inWholeBytes }.bytes
|
||||
}
|
||||
|
||||
private fun Map<Attachment, Progress>.sumTotal(): Long {
|
||||
return this.values.sumOf { it.total }
|
||||
private fun Map<Attachment, Progress>.sumTotal(): ByteSize {
|
||||
return this.values.sumOf { it.total.inWholeBytes }.bytes
|
||||
}
|
||||
|
||||
enum class Mode {
|
||||
|
|
|
@ -3033,10 +3033,7 @@
|
|||
<!-- Status update label used while the device is transcoding video as a prerequisite to uploading -->
|
||||
<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" -->
|
||||
<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>
|
||||
|
||||
<string name="TransferControlView__download_progress">%1$s/%2$s</string>
|
||||
|
||||
<!-- UnauthorizedReminder -->
|
||||
<!-- Message shown in a reminder banner when the user\'s device is no longer registered -->
|
||||
|
|
|
@ -99,6 +99,18 @@ class ByteSize(val bytes: Long) {
|
|||
return bytes.compareTo(other.bytes)
|
||||
}
|
||||
|
||||
operator fun plus(other: ByteSize): ByteSize {
|
||||
return ByteSize(this.inWholeBytes + other.inWholeBytes)
|
||||
}
|
||||
|
||||
fun percentageOf(other: ByteSize): Float {
|
||||
return this.inWholeBytes.toFloat() / other.inWholeBytes.toFloat()
|
||||
}
|
||||
|
||||
operator fun minus(other: ByteSize): ByteSize {
|
||||
return ByteSize(this.inWholeBytes - other.inWholeBytes)
|
||||
}
|
||||
|
||||
enum class Size(val label: String) {
|
||||
BYTE("B"),
|
||||
KIBIBYTE("KB"),
|
||||
|
|
Loading…
Add table
Reference in a new issue