2022-08-01 13:58:34 +00:00
|
|
|
import { useEffect } from 'react';
|
2022-07-30 10:05:08 +00:00
|
|
|
import { useCountUp } from 'use-count-up';
|
2022-10-18 13:52:00 +00:00
|
|
|
import { proxy, useSnapshot } from 'valtio';
|
2022-07-30 10:05:08 +00:00
|
|
|
|
2022-10-18 13:52:00 +00:00
|
|
|
const counterStore = proxy({
|
2022-07-30 10:05:08 +00:00
|
|
|
counterLastValue: new Map<string, number>(),
|
2022-10-18 13:52:00 +00:00
|
|
|
setCounterLastValue: (name: string, lastValue: number) =>
|
|
|
|
counterStore.counterLastValue.set(name, lastValue)
|
|
|
|
});
|
2022-07-30 10:05:08 +00:00
|
|
|
|
|
|
|
const useCounterState = (key: string) => {
|
2022-10-18 13:52:00 +00:00
|
|
|
const { counterLastValue, setCounterLastValue } = useSnapshot(counterStore);
|
2022-07-30 10:05:08 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
lastValue: counterLastValue.get(key),
|
|
|
|
setLastValue: setCounterLastValue
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
type UseCounterProps = {
|
|
|
|
name: string;
|
|
|
|
start?: number;
|
|
|
|
end: number;
|
|
|
|
/**
|
|
|
|
* Duration of the counter animation in seconds
|
|
|
|
* default: `2s`
|
|
|
|
*/
|
|
|
|
duration?: number;
|
|
|
|
/**
|
|
|
|
* If `true`, counter will only count up/down once per app session.
|
|
|
|
* default: `true`
|
|
|
|
*/
|
|
|
|
saveState?: boolean;
|
|
|
|
};
|
|
|
|
|
|
|
|
const useCounter = ({ name, start = 0, end, duration = 2, saveState = true }: UseCounterProps) => {
|
|
|
|
const { lastValue, setLastValue } = useCounterState(name);
|
|
|
|
|
|
|
|
if (saveState && lastValue) {
|
|
|
|
start = lastValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const { value } = useCountUp({
|
|
|
|
isCounting: !(start === end),
|
|
|
|
start,
|
|
|
|
end,
|
|
|
|
duration,
|
|
|
|
easing: 'easeOutCubic'
|
|
|
|
});
|
2022-10-04 16:16:49 +00:00
|
|
|
|
2022-08-01 13:43:01 +00:00
|
|
|
useEffect(() => {
|
|
|
|
if (saveState && value == end) {
|
|
|
|
setLastValue(name, end);
|
|
|
|
}
|
2022-10-04 16:16:49 +00:00
|
|
|
}, [end, name, saveState, setLastValue, value]);
|
2022-07-30 10:05:08 +00:00
|
|
|
|
|
|
|
if (start === end) return end;
|
|
|
|
|
|
|
|
if (saveState && lastValue && lastValue === end) return end;
|
|
|
|
|
|
|
|
return value;
|
|
|
|
};
|
|
|
|
|
|
|
|
export default useCounter;
|