2016-08-15 20:23:56 -07:00
|
|
|
package org.thoughtcrime.securesms.components;
|
|
|
|
|
|
|
|
import android.content.Context;
|
2017-09-09 23:46:48 -07:00
|
|
|
import android.support.annotation.NonNull;
|
2016-08-15 20:23:56 -07:00
|
|
|
import android.support.annotation.Nullable;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
|
2019-07-24 12:30:23 +10:00
|
|
|
import network.loki.messenger.R;
|
2017-09-09 23:46:48 -07:00
|
|
|
import org.thoughtcrime.securesms.util.Util;
|
|
|
|
|
|
|
|
import java.lang.ref.WeakReference;
|
2016-08-15 20:23:56 -07:00
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
2018-06-26 10:27:44 -07:00
|
|
|
public class ExpirationTimerView extends android.support.v7.widget.AppCompatImageView {
|
2016-08-15 20:23:56 -07:00
|
|
|
|
|
|
|
private long startedAt;
|
|
|
|
private long expiresIn;
|
|
|
|
|
|
|
|
private boolean visible = false;
|
|
|
|
private boolean stopped = true;
|
|
|
|
|
2018-06-26 10:27:44 -07:00
|
|
|
private final int[] frames = new int[]{ R.drawable.timer00,
|
|
|
|
R.drawable.timer05,
|
|
|
|
R.drawable.timer10,
|
|
|
|
R.drawable.timer15,
|
|
|
|
R.drawable.timer20,
|
|
|
|
R.drawable.timer25,
|
|
|
|
R.drawable.timer30,
|
|
|
|
R.drawable.timer35,
|
|
|
|
R.drawable.timer40,
|
|
|
|
R.drawable.timer45,
|
|
|
|
R.drawable.timer50,
|
|
|
|
R.drawable.timer55,
|
|
|
|
R.drawable.timer60 };
|
|
|
|
|
2016-08-15 20:23:56 -07:00
|
|
|
public ExpirationTimerView(Context context) {
|
|
|
|
super(context);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ExpirationTimerView(Context context, @Nullable AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ExpirationTimerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
|
|
super(context, attrs, defStyleAttr);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setExpirationTime(long startedAt, long expiresIn) {
|
|
|
|
this.startedAt = startedAt;
|
|
|
|
this.expiresIn = expiresIn;
|
2018-06-26 10:27:44 -07:00
|
|
|
setPercentComplete(calculateProgress(this.startedAt, this.expiresIn));
|
|
|
|
}
|
2016-08-15 20:23:56 -07:00
|
|
|
|
2018-06-26 10:27:44 -07:00
|
|
|
public void setPercentComplete(float percentage) {
|
|
|
|
float percentFull = 1 - percentage;
|
|
|
|
int frame = (int) Math.ceil(percentFull * (frames.length - 1));
|
2018-07-20 14:08:58 -07:00
|
|
|
|
|
|
|
frame = Math.max(0, Math.min(frame, frames.length - 1));
|
2018-06-26 10:27:44 -07:00
|
|
|
setImageResource(frames[frame]);
|
2016-08-15 20:23:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public void startAnimation() {
|
|
|
|
synchronized (this) {
|
|
|
|
visible = true;
|
2017-09-09 23:46:48 -07:00
|
|
|
if (!stopped) return;
|
|
|
|
else stopped = false;
|
2016-08-15 20:23:56 -07:00
|
|
|
}
|
|
|
|
|
2017-09-09 23:46:48 -07:00
|
|
|
Util.runOnMainDelayed(new AnimationUpdateRunnable(this), calculateAnimationDelay(this.startedAt, this.expiresIn));
|
2016-08-15 20:23:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public void stopAnimation() {
|
|
|
|
synchronized (this) {
|
|
|
|
visible = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private float calculateProgress(long startedAt, long expiresIn) {
|
|
|
|
long progressed = System.currentTimeMillis() - startedAt;
|
|
|
|
float percentComplete = (float)progressed / (float)expiresIn;
|
|
|
|
|
2018-07-20 14:08:58 -07:00
|
|
|
return Math.max(0, Math.min(percentComplete, 1));
|
2016-08-15 20:23:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
private long calculateAnimationDelay(long startedAt, long expiresIn) {
|
|
|
|
long progressed = System.currentTimeMillis() - startedAt;
|
|
|
|
long remaining = expiresIn - progressed;
|
|
|
|
|
|
|
|
if (remaining < TimeUnit.SECONDS.toMillis(30)) {
|
|
|
|
return 50;
|
|
|
|
} else {
|
|
|
|
return 1000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-09 23:46:48 -07:00
|
|
|
private static class AnimationUpdateRunnable implements Runnable {
|
|
|
|
|
|
|
|
private final WeakReference<ExpirationTimerView> expirationTimerViewReference;
|
|
|
|
|
|
|
|
private AnimationUpdateRunnable(@NonNull ExpirationTimerView expirationTimerView) {
|
|
|
|
this.expirationTimerViewReference = new WeakReference<>(expirationTimerView);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
ExpirationTimerView timerView = expirationTimerViewReference.get();
|
|
|
|
if (timerView == null) return;
|
|
|
|
|
|
|
|
timerView.setExpirationTime(timerView.startedAt, timerView.expiresIn);
|
|
|
|
|
|
|
|
synchronized (timerView) {
|
|
|
|
if (!timerView.visible) {
|
|
|
|
timerView.stopped = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Util.runOnMainDelayed(this, timerView.calculateAnimationDelay(timerView.startedAt, timerView.expiresIn));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-15 20:23:56 -07:00
|
|
|
}
|