That fuck shit the fascists are using
at master 123 lines 4.0 kB view raw
1package org.tm.archive.components; 2 3import android.content.Context; 4import android.util.AttributeSet; 5 6import androidx.annotation.NonNull; 7import androidx.annotation.Nullable; 8 9import org.signal.core.util.ThreadUtil; 10import org.tm.archive.R; 11 12import java.lang.ref.WeakReference; 13import java.util.concurrent.TimeUnit; 14 15public class ExpirationTimerView extends androidx.appcompat.widget.AppCompatImageView { 16 17 private long startedAt; 18 private long expiresIn; 19 20 private boolean visible = false; 21 private boolean stopped = true; 22 23 private final int[] frames = new int[]{ R.drawable.ic_timer_00_12, 24 R.drawable.ic_timer_05_12, 25 R.drawable.ic_timer_10_12, 26 R.drawable.ic_timer_15_12, 27 R.drawable.ic_timer_20_12, 28 R.drawable.ic_timer_25_12, 29 R.drawable.ic_timer_30_12, 30 R.drawable.ic_timer_35_12, 31 R.drawable.ic_timer_40_12, 32 R.drawable.ic_timer_45_12, 33 R.drawable.ic_timer_50_12, 34 R.drawable.ic_timer_55_12, 35 R.drawable.ic_timer_60_12 }; 36 37 public ExpirationTimerView(Context context) { 38 super(context); 39 } 40 41 public ExpirationTimerView(Context context, @Nullable AttributeSet attrs) { 42 super(context, attrs); 43 } 44 45 public ExpirationTimerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 46 super(context, attrs, defStyleAttr); 47 } 48 49 public void setExpirationTime(long startedAt, long expiresIn) { 50 this.startedAt = startedAt; 51 this.expiresIn = expiresIn; 52 setPercentComplete(calculateProgress(this.startedAt, this.expiresIn)); 53 } 54 55 public void setPercentComplete(float percentage) { 56 float percentFull = 1 - percentage; 57 int frame = (int) Math.ceil(percentFull * (frames.length - 1)); 58 59 frame = Math.max(0, Math.min(frame, frames.length - 1)); 60 setImageResource(frames[frame]); 61 } 62 63 public void startAnimation() { 64 synchronized (this) { 65 visible = true; 66 if (!stopped) return; 67 else stopped = false; 68 } 69 70 ThreadUtil.runOnMainDelayed(new AnimationUpdateRunnable(this), calculateAnimationDelay(this.startedAt, this.expiresIn)); 71 } 72 73 public void stopAnimation() { 74 synchronized (this) { 75 visible = false; 76 } 77 } 78 79 private float calculateProgress(long startedAt, long expiresIn) { 80 long progressed = System.currentTimeMillis() - startedAt; 81 float percentComplete = (float)progressed / (float)expiresIn; 82 83 return Math.max(0, Math.min(percentComplete, 1)); 84 } 85 86 private long calculateAnimationDelay(long startedAt, long expiresIn) { 87 long progressed = System.currentTimeMillis() - startedAt; 88 long remaining = expiresIn - progressed; 89 90 if (remaining < TimeUnit.SECONDS.toMillis(30)) { 91 return 50; 92 } else { 93 return 1000; 94 } 95 } 96 97 private static class AnimationUpdateRunnable implements Runnable { 98 99 private final WeakReference<ExpirationTimerView> expirationTimerViewReference; 100 101 private AnimationUpdateRunnable(@NonNull ExpirationTimerView expirationTimerView) { 102 this.expirationTimerViewReference = new WeakReference<>(expirationTimerView); 103 } 104 105 @Override 106 public void run() { 107 ExpirationTimerView timerView = expirationTimerViewReference.get(); 108 if (timerView == null) return; 109 110 timerView.setExpirationTime(timerView.startedAt, timerView.expiresIn); 111 112 synchronized (timerView) { 113 if (!timerView.visible) { 114 timerView.stopped = true; 115 return; 116 } 117 } 118 119 ThreadUtil.runOnMainDelayed(this, timerView.calculateAnimationDelay(timerView.startedAt, timerView.expiresIn)); 120 } 121 } 122 123}