Skip to content

Commit fd1820c

Browse files
committed
fix: app llaunching
1 parent 0d50ed5 commit fd1820c

27 files changed

Lines changed: 1331 additions & 612 deletions

app/src/main/java/com/smthbig/shadow/delay/DelayOverlayActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void handleOnBackPressed() { }
8585

8686
viewModel.initialize(pkg, delay, additionalExtension);
8787

88-
binding.title.setText("Shadow Friction");
88+
binding.title.setText("Flux Friction");
8989
binding.subtitle.setText(viewModel.getQuote().getValue());
9090
binding.btnCancel.setOnClickListener(v -> finish());
9191

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.smthbig.shadow.launcher.home;
2+
3+
import android.animation.ValueAnimator;
4+
import android.content.Context;
5+
import android.graphics.Canvas;
6+
import android.graphics.Color;
7+
import android.graphics.Paint;
8+
import android.graphics.RadialGradient;
9+
import android.graphics.Shader;
10+
import android.util.AttributeSet;
11+
import android.view.View;
12+
import android.view.animation.AccelerateDecelerateInterpolator;
13+
14+
import androidx.annotation.Nullable;
15+
16+
import com.smthbig.shadow.R;
17+
18+
public class AuraGradientView extends View {
19+
20+
private final Paint glowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
21+
private ValueAnimator animator;
22+
private float phase = 0f;
23+
private int primaryColor = 0x1A58A6FF;
24+
private int secondaryColor = 0x0A3FB950;
25+
26+
public AuraGradientView(Context context, @Nullable AttributeSet attrs) {
27+
super(context, attrs);
28+
setLayerType(LAYER_TYPE_SOFTWARE, null);
29+
resolveColors();
30+
startAnimation();
31+
}
32+
33+
private void resolveColors() {
34+
android.util.TypedValue tv = new android.util.TypedValue();
35+
if (getContext().getTheme().resolveAttribute(R.attr.fluxAuraPrimary, tv, true))
36+
primaryColor = tv.data;
37+
if (getContext().getTheme().resolveAttribute(R.attr.fluxAuraSecondary, tv, true))
38+
secondaryColor = tv.data;
39+
}
40+
41+
private void startAnimation() {
42+
animator = ValueAnimator.ofFloat(0f, 1f);
43+
animator.setDuration(6000);
44+
animator.setRepeatCount(ValueAnimator.INFINITE);
45+
animator.setRepeatMode(ValueAnimator.RESTART);
46+
animator.setInterpolator(new AccelerateDecelerateInterpolator());
47+
animator.addUpdateListener(a -> {
48+
phase = (float) a.getAnimatedValue();
49+
invalidate();
50+
});
51+
animator.start();
52+
}
53+
54+
@Override
55+
protected void onDraw(Canvas canvas) {
56+
super.onDraw(canvas);
57+
if (getWidth() <= 0 || getHeight() <= 0) return;
58+
59+
float cx = getWidth() * (0.3f + 0.4f * (float) Math.sin(phase * 2 * Math.PI));
60+
float cy = getHeight() * (0.2f + 0.3f * (float) Math.cos(phase * 1.3f * Math.PI));
61+
float radius = Math.max(getWidth(), getHeight()) * 0.9f;
62+
63+
RadialGradient gradient = new RadialGradient(
64+
cx, cy, radius,
65+
new int[]{primaryColor, secondaryColor, Color.TRANSPARENT},
66+
new float[]{0f, 0.4f, 1f},
67+
Shader.TileMode.CLAMP
68+
);
69+
glowPaint.setShader(gradient);
70+
canvas.drawRect(0, 0, getWidth(), getHeight(), glowPaint);
71+
}
72+
73+
@Override
74+
protected void onDetachedFromWindow() {
75+
super.onDetachedFromWindow();
76+
if (animator != null) {
77+
animator.cancel();
78+
animator = null;
79+
}
80+
}
81+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package com.smthbig.shadow.launcher.home;
2+
3+
import android.animation.ValueAnimator;
4+
import android.content.Context;
5+
import android.graphics.Canvas;
6+
import android.graphics.Color;
7+
import android.graphics.Paint;
8+
import android.graphics.RectF;
9+
import android.util.AttributeSet;
10+
import android.view.View;
11+
import android.view.animation.DecelerateInterpolator;
12+
13+
import androidx.annotation.Nullable;
14+
15+
public class CircularProgressRingView extends View {
16+
17+
private final Paint trackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
18+
private final Paint progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
19+
private final Paint valuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
20+
private final Paint labelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
21+
private final RectF arcRect = new RectF();
22+
23+
private float progress = 0f;
24+
private float animatedProgress = 0f;
25+
private int ringColor = 0xFF58A6FF;
26+
private int trackColor = 0xFF21262D;
27+
private int textColor = 0xFFF0F6FC;
28+
private int mutedColor = 0xFF8B949E;
29+
private String valueText = "0";
30+
private String labelText = "";
31+
private float strokeWidth;
32+
private ValueAnimator animator;
33+
34+
public CircularProgressRingView(Context context, @Nullable AttributeSet attrs) {
35+
super(context, attrs);
36+
float density = getResources().getDisplayMetrics().density;
37+
strokeWidth = density * 4;
38+
39+
trackPaint.setStyle(Paint.Style.STROKE);
40+
trackPaint.setStrokeWidth(strokeWidth);
41+
trackPaint.setStrokeCap(Paint.Cap.ROUND);
42+
trackPaint.setColor(trackColor);
43+
44+
progressPaint.setStyle(Paint.Style.STROKE);
45+
progressPaint.setStrokeWidth(strokeWidth);
46+
progressPaint.setStrokeCap(Paint.Cap.ROUND);
47+
progressPaint.setColor(ringColor);
48+
49+
valuePaint.setAntiAlias(true);
50+
valuePaint.setColor(textColor);
51+
valuePaint.setTextAlign(Paint.Align.CENTER);
52+
valuePaint.setFakeBoldText(true);
53+
54+
labelPaint.setAntiAlias(true);
55+
labelPaint.setColor(mutedColor);
56+
labelPaint.setTextAlign(Paint.Align.CENTER);
57+
}
58+
59+
public void setProgress(float p) {
60+
progress = Math.max(0f, Math.min(1f, p));
61+
animateToProgress(progress);
62+
}
63+
64+
public void setRingColor(int color) {
65+
ringColor = color;
66+
progressPaint.setColor(color);
67+
invalidate();
68+
}
69+
70+
public void setTrackColor(int color) {
71+
trackColor = color;
72+
trackPaint.setColor(color);
73+
invalidate();
74+
}
75+
76+
public void setValueText(String text) {
77+
valueText = text;
78+
invalidate();
79+
}
80+
81+
public void setLabelText(String text) {
82+
labelText = text;
83+
invalidate();
84+
}
85+
86+
public void setTextColor(int color) {
87+
textColor = color;
88+
valuePaint.setColor(color);
89+
invalidate();
90+
}
91+
92+
public void setMutedColor(int color) {
93+
mutedColor = color;
94+
labelPaint.setColor(color);
95+
invalidate();
96+
}
97+
98+
private void animateToProgress(float target) {
99+
if (animator != null) animator.cancel();
100+
float start = animatedProgress;
101+
animator = ValueAnimator.ofFloat(start, target);
102+
animator.setDuration(800);
103+
animator.setInterpolator(new DecelerateInterpolator());
104+
animator.addUpdateListener(a -> {
105+
animatedProgress = (float) a.getAnimatedValue();
106+
invalidate();
107+
});
108+
animator.start();
109+
}
110+
111+
public void setValues(String value, String label, float progress, int color) {
112+
valueText = value;
113+
labelText = label;
114+
ringColor = color;
115+
progressPaint.setColor(color);
116+
this.progress = Math.max(0f, Math.min(1f, progress));
117+
animateToProgress(this.progress);
118+
}
119+
120+
@Override
121+
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
122+
int size = Math.min(
123+
MeasureSpec.getSize(widthMeasureSpec),
124+
MeasureSpec.getSize(heightMeasureSpec));
125+
setMeasuredDimension(size, size);
126+
}
127+
128+
@Override
129+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
130+
super.onSizeChanged(w, h, oldw, oldh);
131+
float padding = strokeWidth / 2f + getResources().getDisplayMetrics().density * 4;
132+
arcRect.set(padding, padding, w - padding, h - padding);
133+
}
134+
135+
@Override
136+
protected void onDraw(Canvas canvas) {
137+
super.onDraw(canvas);
138+
float cx = getWidth() / 2f;
139+
float cy = getHeight() / 2f;
140+
141+
canvas.drawArc(arcRect, -90f, 360f, false, trackPaint);
142+
if (animatedProgress > 0) {
143+
canvas.drawArc(arcRect, -90f, 360f * animatedProgress, false, progressPaint);
144+
}
145+
146+
float density = getResources().getDisplayMetrics().density;
147+
valuePaint.setTextSize(density * 18);
148+
labelPaint.setTextSize(density * 8);
149+
150+
float baseline = cy - (valuePaint.descent() + valuePaint.ascent()) / 2f;
151+
canvas.drawText(valueText, cx, baseline, valuePaint);
152+
153+
float labelBaseline = cy + density * 10;
154+
canvas.drawText(labelText, cx, labelBaseline, labelPaint);
155+
}
156+
}

app/src/main/java/com/smthbig/shadow/launcher/home/ContributionView.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class ContributionView extends View {
2828
private final Paint cellPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
2929
private final Paint labelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
3030
private final Paint todayRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
31+
private final Paint todayFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
3132
private final RectF cellRect = new RectF();
3233

3334
private FocusStore focusStore;
@@ -41,7 +42,9 @@ public class ContributionView extends View {
4142

4243
private int todayIndex = -1;
4344
private float ringProgress = 0f;
45+
private float ringScale = 1f;
4446
private ValueAnimator pulseAnimator;
47+
private ValueAnimator breatheAnimator;
4548
private long lastRenderTime = 0;
4649

4750
private final String[] dayLabels = {"", "Mon", "", "Wed", "", "Fri", ""};
@@ -68,10 +71,27 @@ private void init(Context context) {
6871
todayRingPaint.setStrokeWidth(dpToPx(2));
6972
todayRingPaint.setAntiAlias(true);
7073

74+
todayFillPaint.setStyle(Paint.Style.FILL);
75+
todayFillPaint.setAntiAlias(true);
76+
7177
startPulseAnimation();
78+
startBreatheAnimation();
7279
updateData();
7380
}
7481

82+
private void startBreatheAnimation() {
83+
breatheAnimator = ValueAnimator.ofFloat(1f, 1.12f);
84+
breatheAnimator.setDuration(2000);
85+
breatheAnimator.setRepeatCount(ValueAnimator.INFINITE);
86+
breatheAnimator.setRepeatMode(ValueAnimator.REVERSE);
87+
breatheAnimator.setInterpolator(new DecelerateInterpolator());
88+
breatheAnimator.addUpdateListener(a -> {
89+
ringScale = (float) a.getAnimatedValue();
90+
invalidate();
91+
});
92+
breatheAnimator.start();
93+
}
94+
7595
private int getThemeAttrColor(int attr) {
7696
TypedValue tv = new TypedValue();
7797
if (getContext().getTheme().resolveAttribute(attr, tv, true)) {
@@ -212,13 +232,19 @@ private void drawTodayHighlight(Canvas canvas, float startX, float startY) {
212232

213233
float cx = startX + col * (cellSize + cellGap) + cellSize / 2;
214234
float cy = startY + row * (cellSize + cellGap) + cellSize / 2;
235+
float r = cellSize / 2;
236+
float scaledR = r * ringScale;
215237

216-
todayRingPaint.setColor(getThemeAttrColor(R.attr.fluxToday));
238+
int todayColor = getThemeAttrColor(R.attr.fluxToday);
239+
todayFillPaint.setColor(todayColor);
240+
todayFillPaint.setAlpha(15);
241+
canvas.drawCircle(cx, cy, scaledR + dpToPx(4), todayFillPaint);
217242

218-
float radius = cellSize / 2 + dpToPx(2) + ringProgress * dpToPx(3);
219-
int alpha = (int) (100 + (1 - ringProgress) * 155);
243+
todayRingPaint.setColor(todayColor);
244+
float ringR = r + dpToPx(2) + ringProgress * dpToPx(3);
245+
int alpha = (int) (80 + (1 - ringProgress) * 175);
220246
todayRingPaint.setAlpha(alpha);
221-
canvas.drawCircle(cx, cy, radius, todayRingPaint);
247+
canvas.drawCircle(cx, cy, ringR, todayRingPaint);
222248
}
223249

224250
private int dpToPx(int dp) {
@@ -232,5 +258,9 @@ protected void onDetachedFromWindow() {
232258
pulseAnimator.cancel();
233259
pulseAnimator = null;
234260
}
261+
if (breatheAnimator != null) {
262+
breatheAnimator.cancel();
263+
breatheAnimator = null;
264+
}
235265
}
236266
}

0 commit comments

Comments
 (0)