spacedrive/interface/hooks/useCounter.ts
Brendan Allan c65d92ee4c
[ENG-380] Interface code structure improvement (#581)
* beginnings of app directory

* settings mostly good

* colocate way more components

* flatten components folder

* reexport QueryClientProvider from client

* move CodeBlock back to interface

* colocate Explorer, KeyManager + more

* goddamn captialisation

* get toasts out of components

* please eslint

* no more src directory

* $ instead of :

* added back RowHeader component

* fix settings modal padding

* more spacing, less margin

* fix sidebar locations button

* fix tags sidebar link

* clean up back button

* added margin to explorer context menu to prevent contact with edge of viewport

* don't export QueryClientProvider from @sd/client

* basic guidelines

* import interface correctly

* remove old demo data

* fix onboarding layout

* fix onboarding navigation

* fix key manager settings button

---------

Co-authored-by: Jamie Pine <ijamespine@me.com>
2023-02-27 21:29:48 -08:00

65 lines
1.4 KiB
TypeScript

import { useEffect } from 'react';
import { useCountUp } from 'use-count-up';
import { proxy, useSnapshot } from 'valtio';
const counterStore = proxy({
counterLastValue: new Map<string, number>(),
setCounterLastValue: (name: string, lastValue: number) =>
counterStore.counterLastValue.set(name, lastValue)
});
const useCounterState = (key: string) => {
const { counterLastValue, setCounterLastValue } = useSnapshot(counterStore);
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'
});
useEffect(() => {
if (saveState && value == end) {
setLastValue(name, end);
}
}, [end, name, saveState, setLastValue, value]);
if (start === end) return end;
if (saveState && lastValue && lastValue === end) return end;
return value;
};
export default useCounter;