mirror of
https://github.com/remvze/moodist.git
synced 2025-12-18 01:14:17 +00:00
chore: add animation to countdown timer
This commit is contained in:
parent
cfd2744e92
commit
73a5c21be9
2 changed files with 33 additions and 7 deletions
|
|
@ -5,6 +5,7 @@ import {
|
|||
IoRefresh,
|
||||
IoTrashOutline,
|
||||
} from 'react-icons/io5/index';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
import { ReverseTimer } from './reverse-timer';
|
||||
|
||||
|
|
@ -29,13 +30,20 @@ export function Timer({ id }: TimerProps) {
|
|||
|
||||
const { name, spent, total } = useCountdownTimers(state =>
|
||||
state.getTimer(id),
|
||||
);
|
||||
) || { name: '', spent: 0, total: 0 };
|
||||
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [snapshot, setSnapshot] = useState({ spent: 0, total: 0 });
|
||||
|
||||
const tick = useCountdownTimers(state => state.tick);
|
||||
const rename = useCountdownTimers(state => state.rename);
|
||||
const reset = useCountdownTimers(state => state.reset);
|
||||
const deleteTimer = useCountdownTimers(state => state.delete);
|
||||
|
||||
const left = useMemo(() => total - spent, [total, spent]);
|
||||
const left = useMemo(
|
||||
() => (isDeleting ? snapshot.total - snapshot.spent : total - spent),
|
||||
[total, spent, isDeleting, snapshot],
|
||||
);
|
||||
|
||||
const hours = useMemo(() => Math.floor(left / 3600), [left]);
|
||||
const minutes = useMemo(() => Math.floor((left % 3600) / 60), [left]);
|
||||
|
|
@ -68,6 +76,9 @@ export function Timer({ id }: TimerProps) {
|
|||
const handleDelete = () => {
|
||||
if (isRunning) return showSnackbar('Please first stop the timer.');
|
||||
|
||||
setIsDeleting(true);
|
||||
setSnapshot({ spent, total });
|
||||
|
||||
deleteTimer(id);
|
||||
};
|
||||
|
||||
|
|
@ -128,8 +139,20 @@ export function Timer({ id }: TimerProps) {
|
|||
};
|
||||
}, [isRunning, tick, id, spent, total, left]);
|
||||
|
||||
const variants = {
|
||||
enter: { opacity: 1 },
|
||||
exit: { opacity: 0 },
|
||||
initial: { opacity: 0 },
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.timer}>
|
||||
<motion.div
|
||||
animate="enter"
|
||||
className={styles.timer}
|
||||
exit="exit"
|
||||
initial="initial"
|
||||
variants={variants}
|
||||
>
|
||||
<header className={styles.header}>
|
||||
<div className={styles.bar}>
|
||||
<div
|
||||
|
|
@ -188,6 +211,6 @@ export function Timer({ id }: TimerProps) {
|
|||
<IoTrashOutline />
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useMemo } from 'react';
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
|
||||
import { Timer } from './timer';
|
||||
import { Notice } from './notice';
|
||||
|
|
@ -30,9 +31,11 @@ export function Timers() {
|
|||
)}
|
||||
</header>
|
||||
|
||||
{timers.map(timer => (
|
||||
<Timer id={timer.id} key={timer.id} />
|
||||
))}
|
||||
<AnimatePresence>
|
||||
{timers.map(timer => (
|
||||
<Timer id={timer.id} key={timer.id} />
|
||||
))}
|
||||
</AnimatePresence>
|
||||
|
||||
<Notice />
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue