That fuck shit the fascists are using
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}