🐛 Refactor DateTile component to use API timezone (#1563)
and remove unused hook
This commit is contained in:
@@ -6,12 +6,12 @@ import advancedFormat from 'dayjs/plugin/advancedFormat';
|
|||||||
import timezones from 'dayjs/plugin/timezone';
|
import timezones from 'dayjs/plugin/timezone';
|
||||||
import utc from 'dayjs/plugin/utc';
|
import utc from 'dayjs/plugin/utc';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useSetSafeInterval } from '~/hooks/useSetSafeInterval';
|
|
||||||
import { getLanguageByCode } from '~/tools/language';
|
import { getLanguageByCode } from '~/tools/language';
|
||||||
import { api } from '~/utils/api';
|
import { api } from '~/utils/api';
|
||||||
|
|
||||||
import { defineWidget } from '../helper';
|
import { defineWidget } from '../helper';
|
||||||
|
import { WidgetLoading } from '../loading';
|
||||||
import { IWidget } from '../widgets';
|
import { IWidget } from '../widgets';
|
||||||
|
|
||||||
dayjs.extend(advancedFormat);
|
dayjs.extend(advancedFormat);
|
||||||
@@ -76,12 +76,31 @@ interface DateTileProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function DateTile({ widget }: 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 formatString = widget.properties.display24HourFormat ? 'HH:mm' : 'h:mm A';
|
||||||
const { ref, width } = useElementSize();
|
const { ref, width } = useElementSize();
|
||||||
const { cx, classes } = useStyles();
|
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 <WidgetLoading />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack ref={ref} className={cx(classes.wrapper, 'dashboard-tile-clock-wrapper')}>
|
<Stack ref={ref} className={cx(classes.wrapper, 'dashboard-tile-clock-wrapper')}>
|
||||||
@@ -90,12 +109,13 @@ function DateTile({ widget }: DateTileProps) {
|
|||||||
size={width < 150 ? 'sm' : 'lg'}
|
size={width < 150 ? 'sm' : 'lg'}
|
||||||
className={cx(classes.extras, 'dashboard-tile-clock-city')}
|
className={cx(classes.extras, 'dashboard-tile-clock-city')}
|
||||||
>
|
>
|
||||||
|
{isFetching}
|
||||||
{widget.properties.timezoneLocation.name}
|
{widget.properties.timezoneLocation.name}
|
||||||
{widget.properties.titleState === 'both' && dayjs(date).format(' (z)')}
|
{widget.properties.titleState === 'both' && dayjs(now).tz(data).format(' (z)')}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
<Text className={cx(classes.clock, 'dashboard-tile-clock-hour')}>
|
<Text className={cx(classes.clock, 'dashboard-tile-clock-hour')}>
|
||||||
{dayjs(date).format(formatString)}
|
{dayjs(now).tz(data).format(formatString)}
|
||||||
</Text>
|
</Text>
|
||||||
{!widget.properties.dateFormat.includes('hide') && (
|
{!widget.properties.dateFormat.includes('hide') && (
|
||||||
<Text
|
<Text
|
||||||
@@ -103,7 +123,7 @@ function DateTile({ widget }: DateTileProps) {
|
|||||||
pt="0.2rem"
|
pt="0.2rem"
|
||||||
className={cx(classes.extras, 'dashboard-tile-clock-date')}
|
className={cx(classes.extras, 'dashboard-tile-clock-date')}
|
||||||
>
|
>
|
||||||
{dayjs(date).format(widget.properties.dateFormat)}
|
{dayjs(now).tz(data).format(widget.properties.dateFormat)}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -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<NodeJS.Timeout>(); // 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;
|
export default definition;
|
||||||
|
|||||||
Reference in New Issue
Block a user