@wandelbots/wandelbots-js-react-components 2.37.0-pr.feature-states-for-cycle-timer.379.4ca80c1 → 2.37.0-pr.feature-states-for-cycle-timer.379.6ceb08e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/CycleTimer/DefaultVariant.d.ts.map +1 -1
- package/dist/components/CycleTimer/SmallVariant.d.ts.map +1 -1
- package/dist/components/CycleTimer/index.d.ts.map +1 -1
- package/dist/components/CycleTimer/types.d.ts +2 -0
- package/dist/components/CycleTimer/types.d.ts.map +1 -1
- package/dist/components/CycleTimer/useAnimations.d.ts +2 -0
- package/dist/components/CycleTimer/useAnimations.d.ts.map +1 -1
- package/dist/components/CycleTimer/useTimerLogic.d.ts.map +1 -1
- package/dist/components/jogging/PoseCartesianValues.d.ts.map +1 -1
- package/dist/components/jogging/PoseJointValues.d.ts.map +1 -1
- package/dist/index.cjs +23 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1463 -1324
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/CycleTimer/DefaultVariant.tsx +96 -41
- package/src/components/CycleTimer/SmallVariant.tsx +79 -39
- package/src/components/CycleTimer/index.tsx +14 -0
- package/src/components/CycleTimer/types.ts +2 -0
- package/src/components/CycleTimer/useAnimations.ts +66 -18
- package/src/components/CycleTimer/useTimerLogic.ts +24 -15
- package/src/components/jogging/PoseCartesianValues.tsx +27 -9
- package/src/components/jogging/PoseJointValues.tsx +27 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wandelbots/wandelbots-js-react-components",
|
|
3
|
-
"version": "2.37.0-pr.feature-states-for-cycle-timer.379.
|
|
3
|
+
"version": "2.37.0-pr.feature-states-for-cycle-timer.379.6ceb08e",
|
|
4
4
|
"description": "React UI toolkit for building applications on top of the Wandelbots platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -27,6 +27,8 @@ export const DefaultVariant = ({
|
|
|
27
27
|
pulsatingFinished,
|
|
28
28
|
showLabels,
|
|
29
29
|
showMainText,
|
|
30
|
+
showIdlePulsating,
|
|
31
|
+
idleDotsCount,
|
|
30
32
|
} = animationState
|
|
31
33
|
|
|
32
34
|
return (
|
|
@@ -47,8 +49,9 @@ export const DefaultVariant = ({
|
|
|
47
49
|
value={currentState === "idle" ? 0 : currentProgress}
|
|
48
50
|
valueMin={0}
|
|
49
51
|
valueMax={100}
|
|
50
|
-
innerRadius=
|
|
51
|
-
outerRadius="
|
|
52
|
+
innerRadius="85%"
|
|
53
|
+
outerRadius="100%"
|
|
54
|
+
margin={0}
|
|
52
55
|
skipAnimation={true}
|
|
53
56
|
text={() => ""}
|
|
54
57
|
sx={{
|
|
@@ -61,9 +64,9 @@ export const DefaultVariant = ({
|
|
|
61
64
|
transition: "fill 0.5s ease-out",
|
|
62
65
|
},
|
|
63
66
|
[`& .MuiGauge-referenceArc`]: {
|
|
64
|
-
fill: currentState === "idle" ? "#
|
|
65
|
-
stroke:
|
|
66
|
-
strokeWidth:
|
|
67
|
+
fill: currentState === "idle" ? "#171927" : "#171927",
|
|
68
|
+
stroke: "transparent",
|
|
69
|
+
strokeWidth: 0,
|
|
67
70
|
transition:
|
|
68
71
|
"fill 0.5s ease-out, stroke 0.5s ease-out, stroke-width 0.5s ease-out",
|
|
69
72
|
},
|
|
@@ -83,8 +86,6 @@ export const DefaultVariant = ({
|
|
|
83
86
|
top: "50%",
|
|
84
87
|
left: "50%",
|
|
85
88
|
transform: "translate(-50%, -50%)",
|
|
86
|
-
width: 200,
|
|
87
|
-
height: 200,
|
|
88
89
|
borderRadius: "50%",
|
|
89
90
|
display: "flex",
|
|
90
91
|
flexDirection: "column",
|
|
@@ -102,7 +103,7 @@ export const DefaultVariant = ({
|
|
|
102
103
|
display: "flex",
|
|
103
104
|
alignItems: "center",
|
|
104
105
|
justifyContent: "center",
|
|
105
|
-
marginBottom:
|
|
106
|
+
marginBottom: 1,
|
|
106
107
|
}}
|
|
107
108
|
>
|
|
108
109
|
<Fade
|
|
@@ -121,22 +122,32 @@ export const DefaultVariant = ({
|
|
|
121
122
|
fontSize: "12px",
|
|
122
123
|
color:
|
|
123
124
|
currentState === "measured"
|
|
124
|
-
? pulsatingFinished
|
|
125
|
-
? theme.palette.
|
|
126
|
-
:
|
|
127
|
-
? theme.palette.success.main
|
|
128
|
-
: theme.palette.text.secondary
|
|
125
|
+
? showPulsatingText || pulsatingFinished
|
|
126
|
+
? theme.palette.success.main
|
|
127
|
+
: theme.palette.text.secondary
|
|
129
128
|
: theme.palette.text.secondary,
|
|
130
129
|
transition: "color 0.8s ease-in-out",
|
|
131
130
|
}}
|
|
132
131
|
>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
<span
|
|
133
|
+
style={{
|
|
134
|
+
opacity:
|
|
135
|
+
currentState === "measured" && pulsatingFinished
|
|
136
|
+
? showPulsatingText
|
|
137
|
+
? 1
|
|
138
|
+
: 0.6
|
|
139
|
+
: 1,
|
|
140
|
+
transition: "opacity 2s ease-in-out",
|
|
141
|
+
}}
|
|
142
|
+
>
|
|
143
|
+
{currentState === "measuring"
|
|
136
144
|
? t("CycleTimer.CycleTime.lb", "Cycle Time")
|
|
137
|
-
: currentState === "
|
|
138
|
-
? t("CycleTimer.
|
|
139
|
-
: ""
|
|
145
|
+
: currentState === "measured"
|
|
146
|
+
? t("CycleTimer.CycleTime.lb", "Cycle Time")
|
|
147
|
+
: currentState === "countdown"
|
|
148
|
+
? t("CycleTimer.RemainingTime.lb", "Remaining Time")
|
|
149
|
+
: ""}
|
|
150
|
+
</span>
|
|
140
151
|
</Typography>
|
|
141
152
|
</Fade>
|
|
142
153
|
</Box>
|
|
@@ -167,11 +178,35 @@ export const DefaultVariant = ({
|
|
|
167
178
|
lineHeight: "166%",
|
|
168
179
|
letterSpacing: "0.17px",
|
|
169
180
|
textAlign: "center",
|
|
170
|
-
width: "
|
|
181
|
+
width: "200px",
|
|
171
182
|
height: "20px",
|
|
183
|
+
display: "flex",
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
justifyContent: "center",
|
|
172
186
|
}}
|
|
173
187
|
>
|
|
174
|
-
|
|
188
|
+
<span
|
|
189
|
+
style={{
|
|
190
|
+
opacity: showIdlePulsating ? 1 : 0.6,
|
|
191
|
+
transition: "opacity 2s ease-in-out",
|
|
192
|
+
}}
|
|
193
|
+
>
|
|
194
|
+
{t(
|
|
195
|
+
"CycleTimer.WaitingForCycle.lb",
|
|
196
|
+
"Waiting for program cycle",
|
|
197
|
+
)}
|
|
198
|
+
</span>
|
|
199
|
+
<span
|
|
200
|
+
style={{
|
|
201
|
+
display: "inline-block",
|
|
202
|
+
width: "18px",
|
|
203
|
+
textAlign: "left",
|
|
204
|
+
opacity: showIdlePulsating ? 1 : 0.6,
|
|
205
|
+
transition: "opacity 2s ease-in-out",
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
{".".repeat(idleDotsCount)}
|
|
209
|
+
</span>
|
|
175
210
|
</Typography>
|
|
176
211
|
</Fade>
|
|
177
212
|
|
|
@@ -207,15 +242,24 @@ export const DefaultVariant = ({
|
|
|
207
242
|
position: "absolute",
|
|
208
243
|
fontSize: "48px",
|
|
209
244
|
fontWeight: 500,
|
|
210
|
-
color:
|
|
211
|
-
currentState === "measured"
|
|
212
|
-
? theme.palette.text.primary
|
|
213
|
-
: theme.palette.text.primary,
|
|
245
|
+
color: theme.palette.text.primary,
|
|
214
246
|
lineHeight: 1,
|
|
215
|
-
transition: "color 0.
|
|
247
|
+
transition: "color 0.8s ease-in-out",
|
|
216
248
|
}}
|
|
217
249
|
>
|
|
218
|
-
|
|
250
|
+
<span
|
|
251
|
+
style={{
|
|
252
|
+
opacity:
|
|
253
|
+
currentState === "measured" && pulsatingFinished
|
|
254
|
+
? showPulsatingText
|
|
255
|
+
? 1
|
|
256
|
+
: 0.6
|
|
257
|
+
: 1,
|
|
258
|
+
transition: "opacity 2s ease-in-out",
|
|
259
|
+
}}
|
|
260
|
+
>
|
|
261
|
+
{formatTime(remainingTime)}
|
|
262
|
+
</span>
|
|
219
263
|
</Typography>
|
|
220
264
|
</Fade>
|
|
221
265
|
</Box>
|
|
@@ -225,6 +269,7 @@ export const DefaultVariant = ({
|
|
|
225
269
|
sx={{
|
|
226
270
|
height: "16px",
|
|
227
271
|
display: "flex",
|
|
272
|
+
marginTop: 0.5,
|
|
228
273
|
alignItems: "center",
|
|
229
274
|
justifyContent: "center",
|
|
230
275
|
}}
|
|
@@ -245,24 +290,34 @@ export const DefaultVariant = ({
|
|
|
245
290
|
fontSize: "12px",
|
|
246
291
|
color:
|
|
247
292
|
currentState === "measured"
|
|
248
|
-
? pulsatingFinished
|
|
249
|
-
? theme.palette.
|
|
250
|
-
:
|
|
251
|
-
? theme.palette.success.main
|
|
252
|
-
: theme.palette.text.secondary
|
|
293
|
+
? showPulsatingText || pulsatingFinished
|
|
294
|
+
? theme.palette.success.main
|
|
295
|
+
: theme.palette.text.secondary
|
|
253
296
|
: theme.palette.text.secondary,
|
|
254
297
|
transition: "color 0.8s ease-in-out",
|
|
255
298
|
}}
|
|
256
299
|
>
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
300
|
+
<span
|
|
301
|
+
style={{
|
|
302
|
+
opacity:
|
|
303
|
+
currentState === "measured" && pulsatingFinished
|
|
304
|
+
? showPulsatingText
|
|
305
|
+
? 1
|
|
306
|
+
: 0.6
|
|
307
|
+
: 1,
|
|
308
|
+
transition: "opacity 2s ease-in-out",
|
|
309
|
+
}}
|
|
310
|
+
>
|
|
311
|
+
{currentState === "measuring"
|
|
312
|
+
? t("CycleTimer.Measuring.lb", "measuring...")
|
|
313
|
+
: currentState === "measured"
|
|
314
|
+
? t("CycleTimer.Determined.lb", "determined")
|
|
315
|
+
: currentState === "countdown" && maxTime !== null
|
|
316
|
+
? t("CycleTimer.OfTime.lb", {
|
|
317
|
+
time: formatTime(maxTime),
|
|
318
|
+
})
|
|
319
|
+
: ""}
|
|
320
|
+
</span>
|
|
266
321
|
</Typography>
|
|
267
322
|
</Fade>
|
|
268
323
|
</Box>
|
|
@@ -26,6 +26,8 @@ export const SmallVariant = ({
|
|
|
26
26
|
showPauseAnimation,
|
|
27
27
|
showPulsatingText,
|
|
28
28
|
pulsatingFinished,
|
|
29
|
+
showIdlePulsating,
|
|
30
|
+
idleDotsCount,
|
|
29
31
|
} = animationState
|
|
30
32
|
|
|
31
33
|
// Simple text-only mode for compact variant in certain states
|
|
@@ -103,17 +105,21 @@ export const SmallVariant = ({
|
|
|
103
105
|
hasError
|
|
104
106
|
? theme.palette.error.light
|
|
105
107
|
: currentState === "measured"
|
|
106
|
-
? pulsatingFinished
|
|
107
|
-
? theme.palette.
|
|
108
|
-
:
|
|
109
|
-
? theme.palette.success.main
|
|
110
|
-
: theme.palette.text.secondary
|
|
108
|
+
? showPulsatingText || pulsatingFinished
|
|
109
|
+
? theme.palette.success.main
|
|
110
|
+
: theme.palette.text.secondary
|
|
111
111
|
: theme.palette.success.main
|
|
112
112
|
}
|
|
113
113
|
strokeWidth="2"
|
|
114
|
-
opacity={
|
|
114
|
+
opacity={
|
|
115
|
+
currentState === "measured" && pulsatingFinished
|
|
116
|
+
? showPulsatingText
|
|
117
|
+
? 1
|
|
118
|
+
: 0.6
|
|
119
|
+
: 0.3
|
|
120
|
+
}
|
|
115
121
|
style={{
|
|
116
|
-
transition: "stroke 0.8s ease-in-out",
|
|
122
|
+
transition: "stroke 0.8s ease-in-out, opacity 2s ease-in-out",
|
|
117
123
|
}}
|
|
118
124
|
/>
|
|
119
125
|
{/* Progress ring */}
|
|
@@ -126,11 +132,9 @@ export const SmallVariant = ({
|
|
|
126
132
|
hasError
|
|
127
133
|
? theme.palette.error.light
|
|
128
134
|
: currentState === "measured"
|
|
129
|
-
? pulsatingFinished
|
|
130
|
-
? theme.palette.
|
|
131
|
-
:
|
|
132
|
-
? theme.palette.success.main
|
|
133
|
-
: theme.palette.text.secondary
|
|
135
|
+
? showPulsatingText || pulsatingFinished
|
|
136
|
+
? theme.palette.success.main
|
|
137
|
+
: theme.palette.text.secondary
|
|
134
138
|
: theme.palette.success.main
|
|
135
139
|
}
|
|
136
140
|
strokeWidth="2"
|
|
@@ -138,8 +142,14 @@ export const SmallVariant = ({
|
|
|
138
142
|
strokeDasharray={`${2 * Math.PI * 8}`}
|
|
139
143
|
strokeDashoffset={`${2 * Math.PI * 8 * (1 - (currentState === "idle" ? 0 : timerState.currentProgress) / 100)}`}
|
|
140
144
|
style={{
|
|
145
|
+
opacity:
|
|
146
|
+
currentState === "measured" && pulsatingFinished
|
|
147
|
+
? showPulsatingText
|
|
148
|
+
? 1
|
|
149
|
+
: 0.6
|
|
150
|
+
: 1,
|
|
141
151
|
transition:
|
|
142
|
-
"stroke-dashoffset 0.1s ease-out, stroke 0.8s ease-in-out",
|
|
152
|
+
"stroke-dashoffset 0.1s ease-out, stroke 0.8s ease-in-out, opacity 2s ease-in-out",
|
|
143
153
|
}}
|
|
144
154
|
/>
|
|
145
155
|
</svg>
|
|
@@ -155,35 +165,65 @@ export const SmallVariant = ({
|
|
|
155
165
|
: currentState === "idle"
|
|
156
166
|
? "rgba(255, 255, 255, 0.7)"
|
|
157
167
|
: currentState === "measured"
|
|
158
|
-
? pulsatingFinished
|
|
159
|
-
? theme.palette.
|
|
160
|
-
:
|
|
161
|
-
? theme.palette.success.main
|
|
162
|
-
: theme.palette.text.secondary
|
|
168
|
+
? showPulsatingText || pulsatingFinished
|
|
169
|
+
? theme.palette.success.main
|
|
170
|
+
: theme.palette.text.secondary
|
|
163
171
|
: theme.palette.text.primary,
|
|
164
|
-
fontSize:
|
|
165
|
-
lineHeight:
|
|
166
|
-
letterSpacing:
|
|
167
|
-
|
|
172
|
+
fontSize: "14px",
|
|
173
|
+
lineHeight: "normal",
|
|
174
|
+
letterSpacing: "normal",
|
|
175
|
+
opacity:
|
|
176
|
+
currentState === "idle"
|
|
177
|
+
? showIdlePulsating
|
|
178
|
+
? 1
|
|
179
|
+
: 0.6
|
|
180
|
+
: currentState === "measured" && pulsatingFinished
|
|
181
|
+
? showPulsatingText
|
|
182
|
+
? 1
|
|
183
|
+
: 0.6
|
|
184
|
+
: 1,
|
|
185
|
+
transition:
|
|
186
|
+
"color 0.8s ease-in-out, font-size 0.3s ease-out, opacity 2s ease-in-out",
|
|
168
187
|
}}
|
|
169
188
|
>
|
|
170
|
-
{hasError
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
{hasError ? (
|
|
190
|
+
t("CycleTimer.Error.lb", "Error")
|
|
191
|
+
) : currentState === "idle" ? (
|
|
192
|
+
<>
|
|
193
|
+
<span>
|
|
194
|
+
{t("CycleTimer.WaitingForCycle.lb", "Waiting for program cycle")}
|
|
195
|
+
</span>
|
|
196
|
+
<span
|
|
197
|
+
style={{
|
|
198
|
+
display: "inline-block",
|
|
199
|
+
width: "18px",
|
|
200
|
+
textAlign: "left",
|
|
201
|
+
}}
|
|
202
|
+
>
|
|
203
|
+
{".".repeat(idleDotsCount)}
|
|
204
|
+
</span>
|
|
205
|
+
</>
|
|
206
|
+
) : currentState === "measuring" ? (
|
|
207
|
+
compact ? (
|
|
208
|
+
`${formatTime(remainingTime)} ${t("CycleTimer.Time.lb", { time: "" }).replace(/\s*$/, "")}`
|
|
209
|
+
) : (
|
|
210
|
+
`${formatTime(remainingTime)} / ${t("CycleTimer.Measuring.lb", "measuring...")}`
|
|
211
|
+
)
|
|
212
|
+
) : currentState === "measured" ? (
|
|
213
|
+
compact ? (
|
|
214
|
+
`${formatTime(remainingTime)} ${t("CycleTimer.Time.lb", { time: "" }).replace(/\s*$/, "")}`
|
|
215
|
+
) : (
|
|
216
|
+
`${formatTime(remainingTime)} / ${t("CycleTimer.Determined.lb", "determined")}`
|
|
217
|
+
)
|
|
218
|
+
) : currentState === "countdown" && maxTime !== null ? (
|
|
219
|
+
compact ? (
|
|
220
|
+
`${formatTime(remainingTime)} ${t("CycleTimer.Time.lb", { time: "" }).replace(/\s*$/, "")}`
|
|
221
|
+
) : (
|
|
222
|
+
`${formatTime(remainingTime)} / ${t("CycleTimer.Time.lb", { time: formatTime(maxTime) })}`
|
|
223
|
+
)
|
|
224
|
+
) : (
|
|
225
|
+
formatTime(remainingTime)
|
|
226
|
+
)}
|
|
187
227
|
</Typography>
|
|
188
228
|
</Box>
|
|
189
229
|
)
|
|
@@ -52,6 +52,8 @@ export const CycleTimer = externalizeComponent(
|
|
|
52
52
|
clearErrorAnimation,
|
|
53
53
|
startPulsatingAnimation,
|
|
54
54
|
stopPulsatingAnimation,
|
|
55
|
+
startIdleAnimations,
|
|
56
|
+
stopIdleAnimations,
|
|
55
57
|
triggerFadeTransition,
|
|
56
58
|
setInitialAnimationState,
|
|
57
59
|
cleanup,
|
|
@@ -82,6 +84,11 @@ export const CycleTimer = externalizeComponent(
|
|
|
82
84
|
stopPulsatingAnimation()
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
// Stop idle animations if leaving idle state
|
|
88
|
+
if (prevState === "idle") {
|
|
89
|
+
stopIdleAnimations()
|
|
90
|
+
}
|
|
91
|
+
|
|
85
92
|
// Trigger fade transition
|
|
86
93
|
triggerFadeTransition()
|
|
87
94
|
} else {
|
|
@@ -89,10 +96,17 @@ export const CycleTimer = externalizeComponent(
|
|
|
89
96
|
setInitialAnimationState()
|
|
90
97
|
}
|
|
91
98
|
|
|
99
|
+
// Start idle animations if entering idle state
|
|
100
|
+
if (timerState.currentState === "idle") {
|
|
101
|
+
startIdleAnimations()
|
|
102
|
+
}
|
|
103
|
+
|
|
92
104
|
prevStateRef.current = timerState.currentState
|
|
93
105
|
}, [
|
|
94
106
|
timerState.currentState,
|
|
95
107
|
stopPulsatingAnimation,
|
|
108
|
+
stopIdleAnimations,
|
|
109
|
+
startIdleAnimations,
|
|
96
110
|
triggerFadeTransition,
|
|
97
111
|
setInitialAnimationState,
|
|
98
112
|
])
|
|
@@ -9,6 +9,8 @@ export const useAnimations = () => {
|
|
|
9
9
|
pulsatingFinished: false,
|
|
10
10
|
showLabels: true,
|
|
11
11
|
showMainText: true,
|
|
12
|
+
showIdlePulsating: false,
|
|
13
|
+
idleDotsCount: 0,
|
|
12
14
|
})
|
|
13
15
|
|
|
14
16
|
// Refs for managing timeouts and intervals
|
|
@@ -17,6 +19,8 @@ export const useAnimations = () => {
|
|
|
17
19
|
const pulsatingIntervalRef = useRef<NodeJS.Timeout | null>(null)
|
|
18
20
|
const fadeTimeoutRef = useRef<NodeJS.Timeout | null>(null)
|
|
19
21
|
const pulseCountRef = useRef<number>(0)
|
|
22
|
+
const idlePulsatingIntervalRef = useRef<NodeJS.Timeout | null>(null)
|
|
23
|
+
const idleDotsIntervalRef = useRef<NodeJS.Timeout | null>(null)
|
|
20
24
|
|
|
21
25
|
const triggerPauseAnimation = useCallback(() => {
|
|
22
26
|
setAnimationState((prev) => ({ ...prev, showPauseAnimation: true }))
|
|
@@ -51,36 +55,32 @@ export const useAnimations = () => {
|
|
|
51
55
|
|
|
52
56
|
const startPulsatingAnimation = useCallback((onComplete?: () => void) => {
|
|
53
57
|
pulseCountRef.current = 0
|
|
58
|
+
// Start with fade to success color
|
|
54
59
|
setAnimationState((prev) => ({
|
|
55
60
|
...prev,
|
|
56
61
|
showPulsatingText: true,
|
|
57
62
|
pulsatingFinished: false,
|
|
58
63
|
}))
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
// After initial success color fade, start slow pulsating like idle
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
setAnimationState((prev) => ({
|
|
68
|
+
...prev,
|
|
69
|
+
pulsatingFinished: true, // This will keep the success color and start slow pulsating
|
|
70
|
+
}))
|
|
62
71
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (pulsatingIntervalRef.current) {
|
|
66
|
-
clearInterval(pulsatingIntervalRef.current)
|
|
67
|
-
pulsatingIntervalRef.current = null
|
|
68
|
-
}
|
|
69
|
-
setAnimationState((prev) => ({
|
|
70
|
-
...prev,
|
|
71
|
-
showPulsatingText: false,
|
|
72
|
-
pulsatingFinished: true,
|
|
73
|
-
}))
|
|
74
|
-
if (onComplete) {
|
|
75
|
-
onComplete()
|
|
76
|
-
}
|
|
77
|
-
} else {
|
|
72
|
+
// Start slow pulsating animation similar to idle
|
|
73
|
+
pulsatingIntervalRef.current = setInterval(() => {
|
|
78
74
|
setAnimationState((prev) => ({
|
|
79
75
|
...prev,
|
|
80
76
|
showPulsatingText: !prev.showPulsatingText,
|
|
81
77
|
}))
|
|
78
|
+
}, 2000) // Same slow timing as idle pulsating
|
|
79
|
+
|
|
80
|
+
if (onComplete) {
|
|
81
|
+
onComplete()
|
|
82
82
|
}
|
|
83
|
-
}, 800)
|
|
83
|
+
}, 800) // Initial success color display duration
|
|
84
84
|
}, [])
|
|
85
85
|
|
|
86
86
|
const stopPulsatingAnimation = useCallback(() => {
|
|
@@ -88,6 +88,7 @@ export const useAnimations = () => {
|
|
|
88
88
|
clearInterval(pulsatingIntervalRef.current)
|
|
89
89
|
pulsatingIntervalRef.current = null
|
|
90
90
|
}
|
|
91
|
+
// Reset all pulsating states to ensure colors are reset
|
|
91
92
|
setAnimationState((prev) => ({
|
|
92
93
|
...prev,
|
|
93
94
|
showPulsatingText: false,
|
|
@@ -96,6 +97,45 @@ export const useAnimations = () => {
|
|
|
96
97
|
pulseCountRef.current = 0
|
|
97
98
|
}, [])
|
|
98
99
|
|
|
100
|
+
const startIdleAnimations = useCallback(() => {
|
|
101
|
+
// Start pulsating animation for the text
|
|
102
|
+
setAnimationState((prev) => ({
|
|
103
|
+
...prev,
|
|
104
|
+
showIdlePulsating: true,
|
|
105
|
+
}))
|
|
106
|
+
|
|
107
|
+
idlePulsatingIntervalRef.current = setInterval(() => {
|
|
108
|
+
setAnimationState((prev) => ({
|
|
109
|
+
...prev,
|
|
110
|
+
showIdlePulsating: !prev.showIdlePulsating,
|
|
111
|
+
}))
|
|
112
|
+
}, 2000) // Slower pulsate every 2 seconds
|
|
113
|
+
|
|
114
|
+
// Start animated dots
|
|
115
|
+
idleDotsIntervalRef.current = setInterval(() => {
|
|
116
|
+
setAnimationState((prev) => ({
|
|
117
|
+
...prev,
|
|
118
|
+
idleDotsCount: (prev.idleDotsCount + 1) % 4, // Cycle through 0, 1, 2, 3
|
|
119
|
+
}))
|
|
120
|
+
}, 800) // Change dots every 800ms
|
|
121
|
+
}, [])
|
|
122
|
+
|
|
123
|
+
const stopIdleAnimations = useCallback(() => {
|
|
124
|
+
if (idlePulsatingIntervalRef.current) {
|
|
125
|
+
clearInterval(idlePulsatingIntervalRef.current)
|
|
126
|
+
idlePulsatingIntervalRef.current = null
|
|
127
|
+
}
|
|
128
|
+
if (idleDotsIntervalRef.current) {
|
|
129
|
+
clearInterval(idleDotsIntervalRef.current)
|
|
130
|
+
idleDotsIntervalRef.current = null
|
|
131
|
+
}
|
|
132
|
+
setAnimationState((prev) => ({
|
|
133
|
+
...prev,
|
|
134
|
+
showIdlePulsating: false,
|
|
135
|
+
idleDotsCount: 0,
|
|
136
|
+
}))
|
|
137
|
+
}, [])
|
|
138
|
+
|
|
99
139
|
const triggerFadeTransition = useCallback(() => {
|
|
100
140
|
setAnimationState((prev) => ({
|
|
101
141
|
...prev,
|
|
@@ -138,6 +178,12 @@ export const useAnimations = () => {
|
|
|
138
178
|
if (pulsatingIntervalRef.current) {
|
|
139
179
|
clearInterval(pulsatingIntervalRef.current)
|
|
140
180
|
}
|
|
181
|
+
if (idlePulsatingIntervalRef.current) {
|
|
182
|
+
clearInterval(idlePulsatingIntervalRef.current)
|
|
183
|
+
}
|
|
184
|
+
if (idleDotsIntervalRef.current) {
|
|
185
|
+
clearInterval(idleDotsIntervalRef.current)
|
|
186
|
+
}
|
|
141
187
|
}, [])
|
|
142
188
|
|
|
143
189
|
return {
|
|
@@ -147,6 +193,8 @@ export const useAnimations = () => {
|
|
|
147
193
|
clearErrorAnimation,
|
|
148
194
|
startPulsatingAnimation,
|
|
149
195
|
stopPulsatingAnimation,
|
|
196
|
+
startIdleAnimations,
|
|
197
|
+
stopIdleAnimations,
|
|
150
198
|
triggerFadeTransition,
|
|
151
199
|
setInitialAnimationState,
|
|
152
200
|
cleanup,
|