Skip to content

Commit

Permalink
feat: getSnapshot method
Browse files Browse the repository at this point in the history
  • Loading branch information
rgommezz committed Jan 12, 2023
1 parent 2de97bc commit c485138
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 22 deletions.
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ function play() {
}

function pause() {
stopwatchRef.current?.pause();
const elapsedTimeInMs = stopwatchRef.current?.pause();
// Do something with the elapsed time
console.log(elapsedTimeInMs);
}

function reset() {
Expand All @@ -54,31 +56,39 @@ return <AnimatedStopwatch ref={stopwatchRef} />;

## Methods

#### `start()`
#### `play: () => void`

Starts the stopwatch or resumes it if paused. It has no effect if the stopwatch is already running.

```js
stopwatchRef.current?.play();
```
#### `pause()`
#### `pause: () => number`
Pauses the stopwatch. It has no effect if the stopwatch is either paused or reset. You can use the `onPaused` prop to get a snapshot of the time elapsed when the stopwatch pauses
Pauses the stopwatch. It has no effect if the stopwatch is either paused or reset. The method returns a snapshot of the time elapsed in ms.
```js
stopwatchRef.current?.pause();
```
#### `reset()`
#### `reset: () => void`
Resets the stopwatch to 0.
```js
stopwatchRef.current?.reset();
```
`stopwatchRef` refers to the [`ref`](https://reactjs.org/docs/react-api.html#reactcreateref) passed to the `AnimatedStopwatch` component.
#### `getSnapshot: () => number`
Returns the current time elapsed in ms.
```js
stopwatchRef.current?.getSnapshot();
```
`stopwatchRef` refers to the [`ref`](https://reactjs.org/docs/hooks-reference.html#useref) passed to the `AnimatedStopwatch` component.
## Contributing
Expand Down
1 change: 0 additions & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default function App() {
containerStyle={styles.stopWatchContainer}
textStyle={styles.stopWatch}
trailingZeros={2}
onPaused={(elapsedInMs) => console.log('onPaused', elapsedInMs)}
/>
<View style={styles.buttonsContainer}>
{/** @ts-ignore */}
Expand Down
26 changes: 17 additions & 9 deletions src/AnimatedStopwatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ export interface StopwatchProps {
* Whether the new digit should enter from the top or the bottom.
*/
enterAnimationType?: 'slide-in-up' | 'slide-in-down';
/**
* A snapshot of the stopwatch digits and the current ms Elapsed
*/
onPaused?: (elapsedInMs: number) => void;
/**
* The style of the stopwatch Text.
*/
Expand All @@ -66,13 +62,17 @@ export interface StopWatchMethods {
*/
play: () => void;
/**
* Pauses the stopwatch.
* Pauses the stopwatch and returns the current elapsed time in milliseconds.
*/
pause: () => void;
pause: () => number;
/**
* Resets the stopwatch.
*/
reset: () => void;
/**
* Returns the current elapsed time in milliseconds.
*/
getSnapshot: () => number;
}

function Stopwatch(
Expand All @@ -83,19 +83,27 @@ function Stopwatch(
containerStyle,
enterAnimationType = 'slide-in-up',
leadingZeros = 1,
onPaused,
textStyle,
trailingZeros = 1,
}: StopwatchProps,
ref: ForwardedRef<StopWatchMethods>
) {
const { tensOfMs, lastDigit, tens, minutes, play, reset, pause } =
useStopwatch(onPaused);
const {
tensOfMs,
lastDigit,
tens,
minutes,
play,
reset,
pause,
getSnapshot,
} = useStopwatch();

useImperativeHandle(ref, () => ({
play,
pause,
reset,
getSnapshot,
}));

const oldLastDigit = useSharedValue<number>(-1);
Expand Down
15 changes: 9 additions & 6 deletions src/useStopwatch.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { useRef, useState } from 'react';
import type { StopwatchProps } from './AnimatedStopwatch';

/**
* A custom hooks that handles the state for the stopwatch
*/
const useStopwatch = (onPaused: StopwatchProps['onPaused']) => {
const useStopwatch = () => {
const [elapsedInMs, setElapsedInMs] = useState(0);
const startTime = useRef<number | null>(null);
const pausedTime = useRef<number | null>(null);
const intervalId = useRef<NodeJS.Timer | null>(null);

const countInSeconds = Math.floor(elapsedInMs / 1000);

function getSnapshot() {
return elapsedInMs;
}

function play() {
if (intervalId.current) {
return;
Expand Down Expand Up @@ -45,11 +48,10 @@ const useStopwatch = (onPaused: StopwatchProps['onPaused']) => {

function pause() {
removeInterval();
if (pausedTime.current || elapsedInMs === 0) {
return;
if (!pausedTime.current && elapsedInMs > 0) {
pausedTime.current = Date.now();
}
onPaused?.(elapsedInMs);
pausedTime.current = Date.now();
return getSnapshot();
}

function reset() {
Expand All @@ -65,6 +67,7 @@ const useStopwatch = (onPaused: StopwatchProps['onPaused']) => {
play,
pause,
reset,
getSnapshot,
};
};

Expand Down

0 comments on commit c485138

Please sign in to comment.