refactor(clock): use context for centralised time management

This commit is contained in:
alexsparkes
2024-12-15 21:59:33 +00:00
parent 973eecabe9
commit ce9089dcee
6 changed files with 72 additions and 59 deletions

View File

@@ -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 (
<TimeProvider>
<ClockContent />
</TimeProvider>
);
};
export default memo(Clock);

View File

@@ -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 = () => {
<Suspense fallback={<></>}>
<div className={`clockBackground ${enabled('roundClock') ? 'round' : ''}`} ref={elementRef}>
<Clock
value={time}
value={currentDate}
className="analogclock clock-container"
size={1.5 * zoomClock}
renderMinuteMarks={enabled('minuteMarks')}

View File

@@ -1,9 +1,8 @@
import React, { useState, useMemo } from 'react';
import React, { useState, useMemo, useEffect } from 'react';
import { useTimeUpdate } from '../hooks/useTimeUpdate';
import { useClockZoom } from '../hooks/useClockZoom';
import { convertTimezone } from 'utils/date';
import { useTime } from '../context/TimeContext';
// Add memoization of time settings
const getTimeSettings = () => {
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 (
<span className="clock clock-container" ref={elementRef}>

View File

@@ -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 <span className="clock clock-container">{percentage}</span>;
};

View File

@@ -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;

View File

@@ -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 (
<TimeContext.Provider value={{ currentDate, updateTime }}>{children}</TimeContext.Provider>
);
};
export const useTime = () => {
const context = useContext(TimeContext);
if (!context) {
throw new Error('useTime must be used within a TimeProvider');
}
return context;
};