Converted TransferControlView into Kotlin and updated Phrase usage

This commit is contained in:
alansley 2024-08-29 09:03:55 +10:00
parent a35a7a6a96
commit 34b15d7865
2 changed files with 182 additions and 225 deletions

View File

@ -1,225 +0,0 @@
package org.thoughtcrime.securesms.components;
import static org.session.libsession.utilities.StringSubstitutionConstants.COUNT_KEY;
import android.animation.LayoutTransition;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.annimon.stream.Stream;
import com.pnikosis.materialishprogress.ProgressWheel;
import com.squareup.phrase.Phrase;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import network.loki.messenger.R;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress;
import org.session.libsession.utilities.ViewUtil;
import org.thoughtcrime.securesms.events.PartProgressEvent;
import org.thoughtcrime.securesms.mms.Slide;
public class TransferControlView extends FrameLayout {
@Nullable private List<Slide> slides;
@Nullable private View current;
private final ProgressWheel progressWheel;
private final View downloadDetails;
private final TextView downloadDetailsText;
private final Map<Attachment, Float> downloadProgress;
public TransferControlView(Context context) {
this(context, null);
}
public TransferControlView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TransferControlView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context, R.layout.transfer_controls_view, this);
setLongClickable(false);
ViewUtil.setBackground(this, ContextCompat.getDrawable(context, R.drawable.transfer_controls_background));
setVisibility(GONE);
setLayoutTransition(new LayoutTransition());
this.downloadProgress = new HashMap<>();
this.progressWheel = ViewUtil.findById(this, R.id.progress_wheel);
this.downloadDetails = ViewUtil.findById(this, R.id.download_details);
this.downloadDetailsText = ViewUtil.findById(this, R.id.download_details_text);
}
@Override
public void setFocusable(boolean focusable) {
super.setFocusable(focusable);
downloadDetails.setFocusable(focusable);
}
@Override
public void setClickable(boolean clickable) {
super.setClickable(clickable);
downloadDetails.setClickable(clickable);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().register(this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
EventBus.getDefault().unregister(this);
}
public void setSlide(final @NonNull Slide slides) {
setSlides(Collections.singletonList(slides));
}
public void setSlides(final @NonNull List<Slide> slides) {
if (slides.isEmpty()) {
throw new IllegalArgumentException("Must provide at least one slide.");
}
this.slides = slides;
if (!isUpdateToExistingSet(slides)) {
downloadProgress.clear();
Stream.of(slides).forEach(s -> downloadProgress.put(s.asAttachment(), 0f));
}
for (Slide slide : slides) {
if (slide.asAttachment().getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) {
downloadProgress.put(slide.asAttachment(), 1f);
}
}
switch (getTransferState(slides)) {
case AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED:
showProgressSpinner(calculateProgress(downloadProgress));
break;
case AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING:
case AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED:
downloadDetailsText.setText(getDownloadText(this.slides));
display(downloadDetails);
break;
default:
display(null);
break;
}
}
public void showProgressSpinner() {
showProgressSpinner(calculateProgress(downloadProgress));
}
public void showProgressSpinner(float progress) {
if (progress == 0) {
progressWheel.spin();
} else {
progressWheel.setInstantProgress(progress);
}
display(progressWheel);
}
public void setDownloadClickListener(final @Nullable OnClickListener listener) {
downloadDetails.setOnClickListener(listener);
}
public void clear() {
clearAnimation();
setVisibility(GONE);
if (current != null) {
current.clearAnimation();
current.setVisibility(GONE);
}
current = null;
slides = null;
}
public void setShowDownloadText(boolean showDownloadText) {
downloadDetailsText.setVisibility(showDownloadText ? VISIBLE : GONE);
forceLayout();
}
private boolean isUpdateToExistingSet(@NonNull List<Slide> slides) {
if (slides.size() != downloadProgress.size()) {
return false;
}
for (Slide slide : slides) {
if (!downloadProgress.containsKey(slide.asAttachment())) {
return false;
}
}
return true;
}
private int getTransferState(@NonNull List<Slide> slides) {
int transferState = AttachmentTransferProgress.TRANSFER_PROGRESS_DONE;
for (Slide slide : slides) {
if (slide.getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING && transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) {
transferState = slide.getTransferState();
} else {
transferState = Math.max(transferState, slide.getTransferState());
}
}
return transferState;
}
private String getDownloadText(@NonNull List<Slide> slides) {
if (slides.size() == 1) {
return slides.get(0).getContentDescription();
} else {
int downloadCount = Stream.of(slides).reduce(0, (count, slide) -> slide.getTransferState() != AttachmentTransferProgress.TRANSFER_PROGRESS_DONE ? count + 1 : count);
return Phrase.from(getContext(), R.string.andMore).put(COUNT_KEY, downloadCount).format().toString();
}
}
private void display(@Nullable final View view) {
if (current != null) {
current.setVisibility(GONE);
}
if (view != null) {
view.setVisibility(VISIBLE);
} else {
setVisibility(GONE);
}
current = view;
}
private float calculateProgress(@NonNull Map<Attachment, Float> downloadProgress) {
float totalProgress = 0;
for (float progress : downloadProgress.values()) {
totalProgress += progress / downloadProgress.size();
}
return totalProgress;
}
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEventAsync(final PartProgressEvent event) {
if (downloadProgress.containsKey(event.attachment)) {
downloadProgress.put(event.attachment, ((float) event.progress) / event.total);
progressWheel.setInstantProgress(calculateProgress(downloadProgress));
}
}
}

View File

@ -0,0 +1,182 @@
package org.thoughtcrime.securesms.components
import android.animation.LayoutTransition
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.annimon.stream.Stream
import com.pnikosis.materialishprogress.ProgressWheel
import kotlin.math.max
import network.loki.messenger.R
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress
import org.session.libsession.utilities.StringSubstitutionConstants.COUNT_KEY
import org.session.libsession.utilities.ViewUtil
import org.thoughtcrime.securesms.events.PartProgressEvent
import org.thoughtcrime.securesms.mms.Slide
import org.thoughtcrime.securesms.ui.getSubbedString
class TransferControlView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : FrameLayout(context!!, attrs, defStyleAttr) {
private var slides: List<Slide>? = null
private var current: View? = null
private val progressWheel: ProgressWheel
private val downloadDetails: View
private val downloadDetailsText: TextView
private val downloadProgress: MutableMap<Attachment, Float>
init {
inflate(context, R.layout.transfer_controls_view, this)
isLongClickable = false
ViewUtil.setBackground(this, ContextCompat.getDrawable(context!!, R.drawable.transfer_controls_background))
visibility = GONE
layoutTransition = LayoutTransition()
this.downloadProgress = HashMap()
this.progressWheel = ViewUtil.findById(this, R.id.progress_wheel)
this.downloadDetails = ViewUtil.findById(this, R.id.download_details)
this.downloadDetailsText = ViewUtil.findById(this, R.id.download_details_text)
}
override fun setFocusable(focusable: Boolean) {
super.setFocusable(focusable)
downloadDetails.isFocusable = focusable
}
override fun setClickable(clickable: Boolean) {
super.setClickable(clickable)
downloadDetails.isClickable = clickable
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().register(this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
EventBus.getDefault().unregister(this)
}
private fun setSlides(slides: List<Slide>) {
require(slides.isNotEmpty()) { "Must provide at least one slide." }
this.slides = slides
if (!isUpdateToExistingSet(slides)) {
downloadProgress.clear()
Stream.of(slides).forEach { s: Slide -> downloadProgress[s.asAttachment()] = 0f }
}
for (slide in slides) {
if (slide.asAttachment().transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) {
downloadProgress[slide.asAttachment()] = 1f
}
}
when (getTransferState(slides)) {
AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED -> showProgressSpinner(calculateProgress(downloadProgress))
AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING, AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED -> {
downloadDetailsText.text = getDownloadText(this.slides!!)
display(downloadDetails)
}
else -> display(null)
}
}
@JvmOverloads
fun showProgressSpinner(progress: Float = calculateProgress(downloadProgress)) {
if (progress == 0f) {
progressWheel.spin()
} else {
progressWheel.setInstantProgress(progress)
}
display(progressWheel)
}
fun clear() {
clearAnimation()
visibility = GONE
if (current != null) {
current!!.clearAnimation()
current!!.visibility = GONE
}
current = null
slides = null
}
private fun isUpdateToExistingSet(slides: List<Slide>): Boolean {
if (slides.size != downloadProgress.size) {
return false
}
for (slide in slides) {
if (!downloadProgress.containsKey(slide.asAttachment())) {
return false
}
}
return true
}
private fun getTransferState(slides: List<Slide>): Int {
var transferState = AttachmentTransferProgress.TRANSFER_PROGRESS_DONE
for (slide in slides) {
transferState = if (slide.transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING && transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) {
slide.transferState
} else {
max(transferState.toDouble(), slide.transferState.toDouble()).toInt()
}
}
return transferState
}
private fun getDownloadText(slides: List<Slide>): String {
if (slides.size == 1) {
return slides[0].contentDescription
} else {
val downloadCount = Stream.of(slides).reduce(0) { count: Int, slide: Slide ->
if (slide.transferState != AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) count + 1 else count
}
return context.getSubbedString(R.string.andMore, COUNT_KEY to downloadCount.toString())
}
}
private fun display(view: View?) {
if (current != null) {
current!!.visibility = GONE
}
if (view != null) {
view.visibility = VISIBLE
} else {
visibility = GONE
}
current = view
}
private fun calculateProgress(downloadProgress: Map<Attachment, Float>): Float {
var totalProgress = 0f
for (progress in downloadProgress.values) {
totalProgress += progress / downloadProgress.size
}
return totalProgress
}
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
fun onEventAsync(event: PartProgressEvent) {
if (downloadProgress.containsKey(event.attachment)) {
downloadProgress[event.attachment] = event.progress.toFloat() / event.total
progressWheel.setInstantProgress(calculateProgress(downloadProgress))
}
}
}