From 545749a057e52b47c9646226a7b7ebcaedd3ae26 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Thu, 9 Nov 2023 20:25:32 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Refactor=20DateTile=20component?= =?UTF-8?q?=20to=20use=20API=20timezone=20(#1563)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and remove unused hook --- src/widgets/date/DateTile.tsx | 82 ++++++++++++----------------------- 1 file changed, 28 insertions(+), 54 deletions(-) diff --git a/src/widgets/date/DateTile.tsx b/src/widgets/date/DateTile.tsx index 91df9bcb3..32204b760 100644 --- a/src/widgets/date/DateTile.tsx +++ b/src/widgets/date/DateTile.tsx @@ -6,12 +6,12 @@ import advancedFormat from 'dayjs/plugin/advancedFormat'; import timezones from 'dayjs/plugin/timezone'; import utc from 'dayjs/plugin/utc'; import { useSession } from 'next-auth/react'; -import { useEffect, useRef, useState } from 'react'; -import { useSetSafeInterval } from '~/hooks/useSetSafeInterval'; +import { useEffect, useState } from 'react'; import { getLanguageByCode } from '~/tools/language'; import { api } from '~/utils/api'; import { defineWidget } from '../helper'; +import { WidgetLoading } from '../loading'; import { IWidget } from '../widgets'; dayjs.extend(advancedFormat); @@ -76,12 +76,31 @@ interface DateTileProps { } function DateTile({ widget }: DateTileProps) { - const date = useDateState( - widget.properties.enableTimezone ? widget.properties.timezoneLocation : undefined - ); const formatString = widget.properties.display24HourFormat ? 'HH:mm' : 'h:mm A'; const { ref, width } = useElementSize(); const { cx, classes } = useStyles(); + const { data: sessionData } = useSession(); + const [now, setDate] = useState(new Date()); + const { data, isFetching } = api.timezone.at.useQuery( + { + latitude: widget.properties.timezoneLocation.latitude, + longitude: widget.properties.timezoneLocation.longitude, + }, + { + enabled: location !== undefined && widget.properties.enableTimezone, + retry: false, + } + ); + useEffect(() => { + // Refresh the time every second + const interval = setInterval(() => setDate(new Date()), 1000); + return () => clearInterval(interval); + }, []); + + const language = getLanguageByCode(sessionData?.user.language ?? 'en'); + dayjs.locale(language.locale); + + if (isFetching) return ; return ( @@ -90,12 +109,13 @@ function DateTile({ widget }: DateTileProps) { size={width < 150 ? 'sm' : 'lg'} className={cx(classes.extras, 'dashboard-tile-clock-city')} > + {isFetching} {widget.properties.timezoneLocation.name} - {widget.properties.titleState === 'both' && dayjs(date).format(' (z)')} + {widget.properties.titleState === 'both' && dayjs(now).tz(data).format(' (z)')} )} - {dayjs(date).format(formatString)} + {dayjs(now).tz(data).format(formatString)} {!widget.properties.dateFormat.includes('hide') && ( - {dayjs(date).format(widget.properties.dateFormat)} + {dayjs(now).tz(data).format(widget.properties.dateFormat)} )} @@ -131,50 +151,4 @@ const useStyles = createStyles(() => ({ }, })); -/** - * State which updates when the minute is changing - * @returns current date updated every new minute - */ -const useDateState = (location?: { latitude: number; longitude: number }) => { - //Gets a timezone from user input location. If location is undefined, then it means it's a local timezone so keep undefined - const { data: timezone } = api.timezone.at.useQuery(location!, { - enabled: location !== undefined, - }); - const { data: sessionData } = useSession(); - const { data: userWithSettings } = api.user.withSettings.useQuery(undefined, { - enabled: !!sessionData?.user, - }); - const userLanguage = userWithSettings?.settings.language; - const [date, setDate] = useState(getNewDate(timezone)); - const setSafeInterval = useSetSafeInterval(); - const timeoutRef = useRef(); // reference for initial timeout until first minute change - useEffect(() => { - const language = getLanguageByCode(userLanguage ?? 'en'); - dayjs.locale(language.locale); - setDate(getNewDate(timezone)); - timeoutRef.current = setTimeout( - () => { - setDate(getNewDate(timezone)); - // Starts interval which update the date every minute - setSafeInterval(() => { - setDate(getNewDate(timezone)); - }, 1000 * 60); - //1 minute - current seconds and milliseconds count - }, - 1000 * 60 - (1000 * dayjs().second() + dayjs().millisecond()) - ); - return () => timeoutRef.current && clearTimeout(timeoutRef.current); - }, [timezone, userLanguage]); - - return date; -}; - -//Returns a local date if no inputs or returns date from input zone -const getNewDate = (timezone?: string) => { - if (timezone) { - return dayjs().tz(timezone); - } - return dayjs(); -}; - export default definition;