mirror of
https://github.com/remvze/moodist.git
synced 2025-12-17 08:54:13 +00:00
feat: replace reverse timer
This commit is contained in:
parent
3e11fb6123
commit
a6c7ac41ad
6 changed files with 35 additions and 58 deletions
|
|
@ -41,6 +41,7 @@
|
||||||
"sort-destructure-keys/sort-destructure-keys": "warn",
|
"sort-destructure-keys/sort-destructure-keys": "warn",
|
||||||
"jsx-a11y/no-static-element-interactions": "off",
|
"jsx-a11y/no-static-element-interactions": "off",
|
||||||
"jsx-a11y/media-has-caption": "off",
|
"jsx-a11y/media-has-caption": "off",
|
||||||
|
"jsx-a11y/no-noninteractive-tabindex": "off",
|
||||||
"react/jsx-sort-props": [
|
"react/jsx-sort-props": [
|
||||||
"warn",
|
"warn",
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export { ReverseTimer } from './reverse-timer';
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
.reverseTimer {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
left: 50%;
|
|
||||||
font-size: var(--font-xsm);
|
|
||||||
color: var(--color-foreground-subtle);
|
|
||||||
letter-spacing: 1px;
|
|
||||||
transform: translate(-50%);
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { useMemo } from 'react';
|
|
||||||
|
|
||||||
import { padNumber } from '@/helpers/number';
|
|
||||||
|
|
||||||
import styles from './reverse-timer.module.css';
|
|
||||||
|
|
||||||
interface ReverseTimerProps {
|
|
||||||
spent: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ReverseTimer({ spent }: ReverseTimerProps) {
|
|
||||||
const hours = useMemo(() => Math.floor(spent / 3600), [spent]);
|
|
||||||
const minutes = useMemo(() => Math.floor((spent % 3600) / 60), [spent]);
|
|
||||||
const seconds = useMemo(() => spent % 60, [spent]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.reverseTimer}>
|
|
||||||
-{padNumber(hours)}:{padNumber(minutes)}:{padNumber(seconds)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -118,6 +118,7 @@
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: var(--font-2xlg);
|
font-size: var(--font-2xlg);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
& span {
|
& span {
|
||||||
color: var(--color-foreground-subtle);
|
color: var(--color-foreground-subtle);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
import { useRef, useMemo, useState, useEffect } from 'react';
|
import { useRef, useMemo, useState, useEffect } from 'react';
|
||||||
import {
|
import { IoPlay, IoPause, IoRefresh, IoTrashOutline } from 'react-icons/io5';
|
||||||
IoPlay,
|
|
||||||
IoPause,
|
|
||||||
IoRefresh,
|
|
||||||
IoTrashOutline,
|
|
||||||
} from 'react-icons/io5/index';
|
|
||||||
|
|
||||||
import { ReverseTimer } from './reverse-timer';
|
|
||||||
import { Toolbar } from './toolbar';
|
import { Toolbar } from './toolbar';
|
||||||
|
|
||||||
import { useCountdownTimers } from '@/stores/countdown-timers';
|
import { useCountdownTimers } from '@/stores/countdown-timers';
|
||||||
|
|
@ -31,25 +25,24 @@ export function Timer({ enableAnimations, id }: TimerProps) {
|
||||||
|
|
||||||
const { first, last, name, spent, total } = useCountdownTimers(state =>
|
const { first, last, name, spent, total } = useCountdownTimers(state =>
|
||||||
state.getTimer(id),
|
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 tick = useCountdownTimers(state => state.tick);
|
||||||
const rename = useCountdownTimers(state => state.rename);
|
const rename = useCountdownTimers(state => state.rename);
|
||||||
const reset = useCountdownTimers(state => state.reset);
|
const reset = useCountdownTimers(state => state.reset);
|
||||||
const deleteTimer = useCountdownTimers(state => state.delete);
|
const deleteTimer = useCountdownTimers(state => state.delete);
|
||||||
|
|
||||||
const left = useMemo(
|
const left = useMemo(() => total - spent, [total, spent]);
|
||||||
() => (isDeleting ? snapshot.total - snapshot.spent : total - spent),
|
|
||||||
[total, spent, isDeleting, snapshot],
|
|
||||||
);
|
|
||||||
|
|
||||||
const hours = useMemo(() => Math.floor(left / 3600), [left]);
|
const hours = useMemo(() => Math.floor(left / 3600), [left]);
|
||||||
const minutes = useMemo(() => Math.floor((left % 3600) / 60), [left]);
|
const minutes = useMemo(() => Math.floor((left % 3600) / 60), [left]);
|
||||||
const seconds = useMemo(() => left % 60, [left]);
|
const seconds = useMemo(() => left % 60, [left]);
|
||||||
|
|
||||||
|
const [isReversed, setIsReversed] = useState(false);
|
||||||
|
|
||||||
|
const spentHours = useMemo(() => Math.floor(spent / 3600), [spent]);
|
||||||
|
const spentMinutes = useMemo(() => Math.floor((spent % 3600) / 60), [spent]);
|
||||||
|
const spentSeconds = useMemo(() => spent % 60, [spent]);
|
||||||
|
|
||||||
const playAlarm = useAlarm();
|
const playAlarm = useAlarm();
|
||||||
|
|
||||||
const showSnackbar = useSnackbar();
|
const showSnackbar = useSnackbar();
|
||||||
|
|
@ -79,9 +72,6 @@ export function Timer({ enableAnimations, id }: TimerProps) {
|
||||||
|
|
||||||
enableAnimations(false);
|
enableAnimations(false);
|
||||||
|
|
||||||
setIsDeleting(true);
|
|
||||||
setSnapshot({ spent, total });
|
|
||||||
|
|
||||||
deleteTimer(id);
|
deleteTimer(id);
|
||||||
|
|
||||||
setTimeout(() => enableAnimations(true), 100);
|
setTimeout(() => enableAnimations(true), 100);
|
||||||
|
|
@ -157,14 +147,30 @@ export function Timer({ enableAnimations, id }: TimerProps) {
|
||||||
|
|
||||||
<Toolbar first={first} id={id} last={last} />
|
<Toolbar first={first} id={id} last={last} />
|
||||||
|
|
||||||
<ReverseTimer spent={spent} />
|
<div
|
||||||
|
className={styles.left}
|
||||||
<div className={styles.left}>
|
tabIndex={0}
|
||||||
|
onClick={() => setIsReversed(prev => !prev)}
|
||||||
|
onKeyDown={() => setIsReversed(prev => !prev)}
|
||||||
|
>
|
||||||
|
{!isReversed ? (
|
||||||
|
<>
|
||||||
{padNumber(hours)}
|
{padNumber(hours)}
|
||||||
<span>:</span>
|
<span>:</span>
|
||||||
{padNumber(minutes)}
|
{padNumber(minutes)}
|
||||||
<span>:</span>
|
<span>:</span>
|
||||||
{padNumber(seconds)}
|
{padNumber(seconds)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span>-</span>
|
||||||
|
{padNumber(spentHours)}
|
||||||
|
<span>:</span>
|
||||||
|
{padNumber(spentMinutes)}
|
||||||
|
<span>:</span>
|
||||||
|
{padNumber(spentSeconds)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer className={styles.footer}>
|
<footer className={styles.footer}>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue