diff --git a/src/features/time/Clock.jsx b/src/features/time/Clock.jsx index acf27dae..0e9b96e0 100644 --- a/src/features/time/Clock.jsx +++ b/src/features/time/Clock.jsx @@ -6,11 +6,12 @@ import { PercentageClock } from './components/PercentageClock'; import EventBus from 'utils/eventbus'; import defaults from './options/default'; import ErrorBoundary from '../../ErrorBoundary'; +import { TimeProvider } from './context/TimeContext'; import 'react-clock/dist/Clock.css'; import './clock.scss'; -const Clock = () => { +const ClockContent = () => { const [timeType, setTimeType] = useState(localStorage.getItem('timeType') || defaults.timeType); useEffect(() => { @@ -57,4 +58,12 @@ const Clock = () => { ); }; +const Clock = () => { + return ( + + + + ); +}; + export default memo(Clock); diff --git a/src/features/time/components/AnalogClock.jsx b/src/features/time/components/AnalogClock.jsx index f8042483..7fd24b54 100644 --- a/src/features/time/components/AnalogClock.jsx +++ b/src/features/time/components/AnalogClock.jsx @@ -3,22 +3,13 @@ import { useTimeUpdate } from '../hooks/useTimeUpdate'; import { useClockZoom } from '../hooks/useClockZoom'; import { convertTimezone } from 'utils/date'; import defaults from '../options/default'; +import { useTime } from '../context/TimeContext'; const Clock = lazy(() => import('react-clock')); export const AnalogClock = () => { - const [time, setTime] = useState(new Date()); - const { elementRef, updateZoom } = useClockZoom(); - - const updateTime = () => { - let now = new Date(); - const timezone = localStorage.getItem('timezone'); - - if (timezone && timezone !== 'auto') { - now = convertTimezone(now, timezone); - } - setTime(now); - }; + const { currentDate, updateTime } = useTime(); + const { elementRef } = useClockZoom(); useTimeUpdate(updateTime); @@ -29,7 +20,7 @@ export const AnalogClock = () => { }>
{ const settings = { timeformat: localStorage.getItem('timeformat'), @@ -18,21 +17,18 @@ export const DigitalClock = React.memo(() => { const [time, setTime] = useState(''); const [ampm, setAmpm] = useState(''); const { elementRef } = useClockZoom(); + const { currentDate, updateTime } = useTime(); const timeSettings = useMemo(getTimeSettings, []); - const updateTime = () => { - let now = new Date(); - const { timezone, zero, showSeconds, timeformat } = timeSettings; + useTimeUpdate(updateTime); - if (timezone && timezone !== 'auto') { - now = convertTimezone(now, timezone); - } + useEffect(() => { + const { zero, showSeconds, timeformat } = timeSettings; + let hours = currentDate.getHours(); + const minutes = ('00' + currentDate.getMinutes()).slice(-2); + const seconds = showSeconds ? `:${('00' + currentDate.getSeconds()).slice(-2)}` : ''; let timeStr = ''; - let hours = now.getHours(); - const minutes = ('00' + now.getMinutes()).slice(-2); - const seconds = showSeconds ? `:${('00' + now.getSeconds()).slice(-2)}` : ''; - if (timeformat === 'twentyfourhour') { timeStr = zero === 'false' @@ -49,12 +45,10 @@ export const DigitalClock = React.memo(() => { zero === 'false' ? `${hours}:${minutes}${seconds}` : `${('00' + hours).slice(-2)}:${minutes}${seconds}`; - setAmpm(now.getHours() > 11 ? 'PM' : 'AM'); + setAmpm(currentDate.getHours() > 11 ? 'PM' : 'AM'); } setTime(timeStr); - }; - - useTimeUpdate(updateTime); + }, [currentDate, timeSettings]); return ( diff --git a/src/features/time/components/PercentageClock.jsx b/src/features/time/components/PercentageClock.jsx index 45c87e67..9cd8338f 100644 --- a/src/features/time/components/PercentageClock.jsx +++ b/src/features/time/components/PercentageClock.jsx @@ -1,22 +1,16 @@ import { useState, useEffect } from 'react'; import { useTimeUpdate } from '../hooks/useTimeUpdate'; -import { convertTimezone } from 'utils/date'; +import { useTime } from '../context/TimeContext'; export const PercentageClock = () => { const [percentage, setPercentage] = useState(''); - - const updateTime = () => { - let now = new Date(); - const timezone = localStorage.getItem('timezone'); - - if (timezone && timezone !== 'auto') { - now = convertTimezone(now, timezone); - } - - setPercentage((now.getHours() / 24).toFixed(2).replace('0.', '') + '%'); - }; + const { currentDate, updateTime } = useTime(); useTimeUpdate(updateTime); + useEffect(() => { + setPercentage((currentDate.getHours() / 24).toFixed(2).replace('0.', '') + '%'); + }, [currentDate]); + return {percentage}; }; diff --git a/src/features/time/components/VerticalClock.jsx b/src/features/time/components/VerticalClock.jsx index e1c68c5c..af773752 100644 --- a/src/features/time/components/VerticalClock.jsx +++ b/src/features/time/components/VerticalClock.jsx @@ -1,27 +1,24 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useTimeUpdate } from '../hooks/useTimeUpdate'; import { useClockZoom } from '../hooks/useClockZoom'; -import { convertTimezone } from 'utils/date'; +import { useTime } from '../context/TimeContext'; import defaults from '../options/default'; export const VerticalClock = () => { const [hour, setHour] = useState(''); const [minute, setMinute] = useState(''); const [seconds, setSeconds] = useState(''); - const { elementRef, updateZoom } = useClockZoom(); + const { elementRef } = useClockZoom(); + const { currentDate, updateTime } = useTime(); - const updateTime = () => { - let now = new Date(); - const timezone = localStorage.getItem('timezone'); + useTimeUpdate(updateTime); + + useEffect(() => { const zero = localStorage.getItem('zero'); const showSeconds = localStorage.getItem('seconds') === 'true'; - if (timezone && timezone !== 'auto') { - now = convertTimezone(now, timezone); - } - - let hours = now.getHours(); - const minutes = ('00' + now.getMinutes()).slice(-2); + let hours = currentDate.getHours(); + const minutes = ('00' + currentDate.getMinutes()).slice(-2); if (localStorage.getItem('timeformat') !== 'twentyfourhour') { if (hours > 12) { @@ -34,11 +31,9 @@ export const VerticalClock = () => { setHour(zero === 'false' ? `${hours}` : ('00' + hours).slice(-2)); setMinute(minutes); if (showSeconds) { - setSeconds(('00' + now.getSeconds()).slice(-2)); + setSeconds(('00' + currentDate.getSeconds()).slice(-2)); } - }; - - useTimeUpdate(updateTime); + }, [currentDate]); const hourColour = localStorage.getItem('hourColour') || defaults.hourColour; const minuteColour = localStorage.getItem('minuteColour') || defaults.minuteColour; diff --git a/src/features/time/context/TimeContext.jsx b/src/features/time/context/TimeContext.jsx new file mode 100644 index 00000000..bef04136 --- /dev/null +++ b/src/features/time/context/TimeContext.jsx @@ -0,0 +1,30 @@ +import { createContext, useContext, useState } from 'react'; +import { convertTimezone } from 'utils/date'; + +const TimeContext = createContext(); + +export const TimeProvider = ({ children }) => { + const [currentDate, setCurrentDate] = useState(new Date()); + + const updateTime = () => { + let now = new Date(); + const timezone = localStorage.getItem('timezone'); + + if (timezone && timezone !== 'auto') { + now = convertTimezone(now, timezone); + } + setCurrentDate(now); + }; + + return ( + {children} + ); +}; + +export const useTime = () => { + const context = useContext(TimeContext); + if (!context) { + throw new Error('useTime must be used within a TimeProvider'); + } + return context; +};