1
1
package com.shifthackz.aisdv1.presentation.widget.connectivity
2
2
3
3
import androidx.compose.animation.AnimatedVisibility
4
- import androidx.compose.foundation.background
4
+ import androidx.compose.animation.core.LinearEasing
5
+ import androidx.compose.animation.core.RepeatMode
6
+ import androidx.compose.animation.core.animateFloat
7
+ import androidx.compose.animation.core.infiniteRepeatable
8
+ import androidx.compose.animation.core.rememberInfiniteTransition
9
+ import androidx.compose.animation.core.tween
5
10
import androidx.compose.foundation.layout.Column
6
11
import androidx.compose.foundation.layout.fillMaxWidth
7
12
import androidx.compose.foundation.layout.padding
8
- import androidx.compose.foundation.shape.RoundedCornerShape
9
13
import androidx.compose.material3.Text
10
14
import androidx.compose.runtime.Composable
15
+ import androidx.compose.runtime.getValue
11
16
import androidx.compose.ui.Alignment
12
17
import androidx.compose.ui.Modifier
18
+ import androidx.compose.ui.draw.drawWithCache
19
+ import androidx.compose.ui.geometry.CornerRadius
20
+ import androidx.compose.ui.geometry.Offset
21
+ import androidx.compose.ui.graphics.Brush
22
+ import androidx.compose.ui.graphics.Color
23
+ import androidx.compose.ui.graphics.TileMode
24
+ import androidx.compose.ui.platform.LocalDensity
13
25
import androidx.compose.ui.res.stringResource
14
26
import androidx.compose.ui.tooling.preview.Preview
15
27
import androidx.compose.ui.unit.dp
16
- import com.shifthackz.android .core.mvi.MviComponent
28
+ import com.shifthackz.aisdv1 .core.extensions.measureTextWidth
17
29
import com.shifthackz.aisdv1.presentation.theme.colors
30
+ import com.shifthackz.android.core.mvi.MviComponent
18
31
import com.shifthackz.catppuccin.palette.Catppuccin
19
32
import org.koin.androidx.compose.koinViewModel
20
33
import com.shifthackz.aisdv1.core.localization.R as LocalizationR
@@ -35,27 +48,80 @@ private fun ConnectivityWidgetState(
35
48
modifier : Modifier = Modifier ,
36
49
state : ConnectivityState ,
37
50
) {
51
+ val text = stringResource(
52
+ id = when (state) {
53
+ is ConnectivityState .Connected -> LocalizationR .string.status_connected
54
+ is ConnectivityState .Disconnected -> LocalizationR .string.status_disconnected
55
+ is ConnectivityState .Uninitialized -> LocalizationR .string.status_communicating
56
+ }
57
+ )
58
+ val infiniteTransition = rememberInfiniteTransition(label = " background" )
59
+ val targetOffset = with (LocalDensity .current) {
60
+ measureTextWidth(text = text).toPx()
61
+ }
62
+
63
+ val offset by infiniteTransition.animateFloat(
64
+ initialValue = 0f ,
65
+ targetValue = targetOffset,
66
+ animationSpec = infiniteRepeatable(
67
+ animation = tween(durationMillis = 1500 , easing = LinearEasing ),
68
+ repeatMode = RepeatMode .Reverse
69
+ ),
70
+ label = " offset" ,
71
+ )
38
72
AnimatedVisibility (visible = state.enabled) {
39
73
val uiColor = when (state) {
40
- is ConnectivityState .Connected -> colors(light = Catppuccin .Latte .Green , dark = Catppuccin .Frappe .Green )
41
- is ConnectivityState .Disconnected -> colors(light = Catppuccin .Latte .Red , dark = Catppuccin .Frappe .Red )
42
- is ConnectivityState .Uninitialized -> colors(light = Catppuccin .Latte .Lavender , dark = Catppuccin .Frappe .Lavender )
74
+ is ConnectivityState .Connected -> colors(
75
+ light = Catppuccin .Latte .Green ,
76
+ dark = Catppuccin .Frappe .Green
77
+ )
78
+
79
+ is ConnectivityState .Disconnected -> colors(
80
+ light = Catppuccin .Latte .Red ,
81
+ dark = Catppuccin .Frappe .Red
82
+ )
83
+
84
+ is ConnectivityState .Uninitialized -> colors(
85
+ light = Catppuccin .Latte .Lavender ,
86
+ dark = Catppuccin .Frappe .Lavender
87
+ )
43
88
}
44
89
Column (
45
- modifier = modifier.padding(top = 4 .dp),
90
+ modifier = modifier
91
+ .padding(top = 4 .dp),
46
92
horizontalAlignment = Alignment .CenterHorizontally ,
47
93
) {
48
94
Text (
49
95
modifier = Modifier
50
- .background(uiColor, shape = RoundedCornerShape (8 .dp))
51
- .padding(vertical = 4 .dp, horizontal = 16 .dp),
52
- text = stringResource(
53
- id = when (state) {
54
- is ConnectivityState .Connected -> LocalizationR .string.status_connected
55
- is ConnectivityState .Disconnected -> LocalizationR .string.status_disconnected
56
- is ConnectivityState .Uninitialized -> LocalizationR .string.status_communicating
96
+ .drawWithCache {
97
+ val brushSize = 40f
98
+ val brushDefault = Brush .linearGradient(
99
+ colors = listOf (uiColor, uiColor)
100
+ )
101
+ val brushAnimated = Brush .linearGradient(
102
+ colors = listOf (
103
+ Color .Transparent ,
104
+ Color .White .copy(alpha = 0.5f ),
105
+ Color .Transparent ,
106
+ ),
107
+ start = Offset (offset, offset),
108
+ end = Offset (offset + brushSize, offset + brushSize),
109
+ tileMode = TileMode .Clamp ,
110
+ )
111
+ onDrawBehind {
112
+ drawRoundRect(
113
+ cornerRadius = CornerRadius (8 .dp.toPx()),
114
+ brush = brushDefault,
115
+ )
116
+ if (state !is ConnectivityState .Uninitialized ) return @onDrawBehind
117
+ drawRoundRect(
118
+ cornerRadius = CornerRadius (8 .dp.toPx()),
119
+ brush = brushAnimated,
120
+ )
121
+ }
57
122
}
58
- ),
123
+ .padding(vertical = 4 .dp, horizontal = 16 .dp),
124
+ text = text,
59
125
color = colors(light = Catppuccin .Latte .Base , dark = Catppuccin .Frappe .Base )
60
126
)
61
127
}
0 commit comments