@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.
@@ -56,25 +56,27 @@ export const useTimerLogic = ({
56
56
  remainingTime: 0,
57
57
  isRunning: false,
58
58
  isPausedState: false,
59
+ currentProgress: 0, // Immediately reset progress to 0
59
60
  }))
60
61
  pausedTimeRef.current = 0
61
62
  startTimeRef.current = null
62
- progressInterpolator.setTarget([0])
63
+ progressInterpolator.setImmediate([0]) // Use setImmediate for instant reset
63
64
  }, [progressInterpolator])
64
65
 
65
66
  const startMeasuring = useCallback(
66
67
  (elapsedSeconds: number = 0) => {
68
+ const initialProgress = ((elapsedSeconds / 60) % 1) * 100
67
69
  setTimerState((prev) => ({
68
70
  ...prev,
69
71
  currentState: "measuring",
70
72
  maxTime: null,
71
73
  remainingTime: elapsedSeconds,
72
74
  isPausedState: false,
75
+ currentProgress: initialProgress, // Immediately set progress
73
76
  }))
74
77
  pausedTimeRef.current = 0
75
78
 
76
- const initialProgress = ((elapsedSeconds / 60) % 1) * 100
77
- progressInterpolator.setTarget([initialProgress])
79
+ progressInterpolator.setImmediate([initialProgress]) // Use setImmediate for instant reset
78
80
 
79
81
  if (autoStart) {
80
82
  startTimeRef.current = Date.now() - elapsedSeconds * 1000
@@ -88,17 +90,18 @@ export const useTimerLogic = ({
88
90
 
89
91
  const startCountUp = useCallback(
90
92
  (elapsedSeconds: number = 0) => {
93
+ const initialProgress = ((elapsedSeconds / 60) % 1) * 100
91
94
  setTimerState((prev) => ({
92
95
  ...prev,
93
96
  currentState: "countup",
94
97
  maxTime: null,
95
98
  remainingTime: elapsedSeconds,
96
99
  isPausedState: false,
100
+ currentProgress: initialProgress, // Immediately set progress
97
101
  }))
98
102
  pausedTimeRef.current = 0
99
103
 
100
- const initialProgress = ((elapsedSeconds / 60) % 1) * 100
101
- progressInterpolator.setTarget([initialProgress])
104
+ progressInterpolator.setImmediate([initialProgress]) // Use setImmediate for instant reset
102
105
 
103
106
  if (autoStart) {
104
107
  startTimeRef.current = Date.now() - elapsedSeconds * 1000
@@ -128,19 +131,22 @@ export const useTimerLogic = ({
128
131
  if (maxTimeSeconds !== undefined) {
129
132
  // Count-down mode
130
133
  const remainingSeconds = Math.max(0, maxTimeSeconds - elapsedSeconds)
131
- setTimerState((prev) => ({ ...prev, remainingTime: remainingSeconds }))
132
-
133
134
  const initialProgress =
134
135
  elapsedSeconds > 0 ? (elapsedSeconds / maxTimeSeconds) * 100 : 0
135
136
 
136
- progressInterpolator.setTarget([initialProgress])
137
- progressInterpolator.update(1)
137
+ setTimerState((prev) => ({
138
+ ...prev,
139
+ remainingTime: remainingSeconds,
140
+ currentProgress: initialProgress, // Immediately set progress
141
+ }))
142
+
143
+ progressInterpolator.setImmediate([initialProgress]) // Use setImmediate for instant reset
138
144
 
139
145
  if (remainingSeconds === 0) {
140
146
  setTimerState((prev) => ({ ...prev, isRunning: false }))
141
147
  startTimeRef.current = null
142
148
  if (onCycleEnd) {
143
- setTimeout(() => onCycleEnd(), 0)
149
+ queueMicrotask(() => onCycleEnd())
144
150
  }
145
151
  } else if (autoStart) {
146
152
  setTimeout(() => {
@@ -152,11 +158,14 @@ export const useTimerLogic = ({
152
158
  }
153
159
  } else {
154
160
  // Count-up mode
155
- setTimerState((prev) => ({ ...prev, remainingTime: elapsedSeconds }))
156
-
157
161
  const initialProgress = ((elapsedSeconds / 60) % 1) * 100
158
- progressInterpolator.setTarget([initialProgress])
159
- progressInterpolator.update(1)
162
+ setTimerState((prev) => ({
163
+ ...prev,
164
+ remainingTime: elapsedSeconds,
165
+ currentProgress: initialProgress, // Immediately set progress
166
+ }))
167
+
168
+ progressInterpolator.setImmediate([initialProgress]) // Use setImmediate for instant reset
160
169
 
161
170
  if (autoStart) {
162
171
  setTimeout(() => {
@@ -296,7 +305,7 @@ export const useTimerLogic = ({
296
305
  startTimeRef.current = null
297
306
  progressInterpolator.setTarget([100])
298
307
  if (onCycleEnd) {
299
- setTimeout(() => onCycleEnd(), 0)
308
+ queueMicrotask(() => onCycleEnd())
300
309
  }
301
310
  return
302
311
  }
@@ -2,6 +2,7 @@ import { Button, Stack, Typography } from "@mui/material"
2
2
  import { poseToWandelscriptString } from "@wandelbots/nova-js"
3
3
  import type {
4
4
  ConnectedMotionGroup,
5
+ MotionGroupStateResponse,
5
6
  MotionStreamConnection,
6
7
  } from "@wandelbots/nova-js/v1"
7
8
  import { observer } from "mobx-react-lite"
@@ -9,6 +10,28 @@ import { useRef, useState } from "react"
9
10
  import { CopyableText } from "../CopyableText"
10
11
  import { useAnimationFrame } from "../utils/hooks"
11
12
 
13
+ /** Minimal interface for what PoseCartesianValues needs from motion stream */
14
+ type MotionStateProvider = {
15
+ rapidlyChangingMotionState: MotionGroupStateResponse
16
+ }
17
+
18
+ /** Creates a motion state provider from either a MotionStreamConnection or ConnectedMotionGroup */
19
+ function createMotionStateProvider(
20
+ motionStream?: MotionStreamConnection,
21
+ connectedMotionGroup?: ConnectedMotionGroup,
22
+ ): MotionStateProvider | undefined {
23
+ if (motionStream) {
24
+ return motionStream
25
+ }
26
+ if (connectedMotionGroup) {
27
+ return {
28
+ rapidlyChangingMotionState:
29
+ connectedMotionGroup.rapidlyChangingMotionState,
30
+ }
31
+ }
32
+ return undefined
33
+ }
34
+
12
35
  export type PoseCartesianValuesProps = {
13
36
  /** Either a MotionStreamConnection or ConnectedMotionGroup */
14
37
  motionStream?: MotionStreamConnection
@@ -25,15 +48,10 @@ export const PoseCartesianValues = observer(
25
48
  const poseHolderRef = useRef<HTMLDivElement>(null)
26
49
  const [copyMessage, setCopyMessage] = useState("")
27
50
 
28
- // Use the provided motionStream or create a mock-like object from connectedMotionGroup
29
- const activeMotionStream =
30
- motionStream ||
31
- (connectedMotionGroup
32
- ? ({
33
- rapidlyChangingMotionState:
34
- connectedMotionGroup.rapidlyChangingMotionState,
35
- } as MotionStreamConnection)
36
- : undefined)
51
+ const activeMotionStream = createMotionStateProvider(
52
+ motionStream,
53
+ connectedMotionGroup,
54
+ )
37
55
 
38
56
  if (!activeMotionStream) {
39
57
  throw new Error(
@@ -1,6 +1,7 @@
1
1
  import { Button, Stack, Typography } from "@mui/material"
2
2
  import type {
3
3
  ConnectedMotionGroup,
4
+ MotionGroupStateResponse,
4
5
  MotionStreamConnection,
5
6
  } from "@wandelbots/nova-js/v1"
6
7
  import { observer } from "mobx-react-lite"
@@ -8,6 +9,28 @@ import { useRef, useState } from "react"
8
9
  import { CopyableText } from "../CopyableText"
9
10
  import { useAnimationFrame } from "../utils/hooks"
10
11
 
12
+ /** Minimal interface for what PoseJointValues needs from motion stream */
13
+ type MotionStateProvider = {
14
+ rapidlyChangingMotionState: MotionGroupStateResponse
15
+ }
16
+
17
+ /** Creates a motion state provider from either a MotionStreamConnection or ConnectedMotionGroup */
18
+ function createMotionStateProvider(
19
+ motionStream?: MotionStreamConnection,
20
+ connectedMotionGroup?: ConnectedMotionGroup,
21
+ ): MotionStateProvider | undefined {
22
+ if (motionStream) {
23
+ return motionStream
24
+ }
25
+ if (connectedMotionGroup) {
26
+ return {
27
+ rapidlyChangingMotionState:
28
+ connectedMotionGroup.rapidlyChangingMotionState,
29
+ }
30
+ }
31
+ return undefined
32
+ }
33
+
11
34
  export type PoseJointValuesProps = {
12
35
  /** Either a MotionStreamConnection or ConnectedMotionGroup */
13
36
  motionStream?: MotionStreamConnection
@@ -24,15 +47,10 @@ export const PoseJointValues = observer(
24
47
  const poseHolderRef = useRef<HTMLDivElement>(null)
25
48
  const [copyMessage, setCopyMessage] = useState("")
26
49
 
27
- // Use the provided motionStream or create a mock-like object from connectedMotionGroup
28
- const activeMotionStream =
29
- motionStream ||
30
- (connectedMotionGroup
31
- ? ({
32
- rapidlyChangingMotionState:
33
- connectedMotionGroup.rapidlyChangingMotionState,
34
- } as MotionStreamConnection)
35
- : undefined)
50
+ const activeMotionStream = createMotionStateProvider(
51
+ motionStream,
52
+ connectedMotionGroup,
53
+ )
36
54
 
37
55
  if (!activeMotionStream) {
38
56
  throw new Error(