NoteTime memo

This commit is contained in:
Martti Malmi
2024-01-04 19:37:56 +02:00
parent 3963db1a0a
commit c8215b1408

View File

@ -1,5 +1,5 @@
import { useEffect, useMemo, useState } from "react"; import React, {useEffect, useState, useCallback, useMemo, ReactNode} from 'react';
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from 'react-intl';
export interface NoteTimeProps { export interface NoteTimeProps {
from: number; from: number;
@ -10,25 +10,10 @@ const secondsInAMinute = 60;
const secondsInAnHour = secondsInAMinute * 60; const secondsInAnHour = secondsInAMinute * 60;
const secondsInADay = secondsInAnHour * 24; const secondsInADay = secondsInAnHour * 24;
export default function NoteTime(props: NoteTimeProps) { const NoteTime: React.FC<NoteTimeProps> = ({ from, fallback }) => {
const { from, fallback } = props; const calcTime = useCallback((fromTime: number) => {
const [time, setTime] = useState<string | JSX.Element>(calcTime());
const absoluteTime = useMemo(
() =>
new Intl.DateTimeFormat(undefined, {
dateStyle: "medium",
timeStyle: "long",
}).format(from),
[from],
);
const isoDate = new Date(from).toISOString();
function calcTime() {
const fromDate = new Date(from);
const currentTime = new Date(); const currentTime = new Date();
const timeDifference = Math.floor((currentTime.getTime() - fromDate.getTime()) / 1000); const timeDifference = Math.floor((currentTime.getTime() - fromTime) / 1000);
if (timeDifference < secondsInAMinute) { if (timeDifference < secondsInAMinute) {
return <FormattedMessage defaultMessage="now" id="kaaf1E" />; return <FormattedMessage defaultMessage="now" id="kaaf1E" />;
@ -37,34 +22,42 @@ export default function NoteTime(props: NoteTimeProps) {
} else if (timeDifference < secondsInADay) { } else if (timeDifference < secondsInADay) {
return `${Math.floor(timeDifference / secondsInAnHour)}h`; return `${Math.floor(timeDifference / secondsInAnHour)}h`;
} else { } else {
const fromDate = new Date(fromTime);
if (fromDate.getFullYear() === currentTime.getFullYear()) { if (fromDate.getFullYear() === currentTime.getFullYear()) {
return fromDate.toLocaleDateString(undefined, { return fromDate.toLocaleDateString(undefined, {
month: "short", month: 'short',
day: "numeric", day: 'numeric',
}); });
} else { } else {
return fromDate.toLocaleDateString(undefined, { return fromDate.toLocaleDateString(undefined, {
year: "numeric", year: 'numeric',
month: "short", month: 'short',
day: "numeric", day: 'numeric',
}); });
} }
} }
} }, []);
const [time, setTime] = useState<string | ReactNode>(calcTime(from));
const absoluteTime = useMemo(
() => new Intl.DateTimeFormat(undefined, {
dateStyle: 'medium',
timeStyle: 'long',
}).format(from),
[from]
);
const isoDate = useMemo(() => new Date(from).toISOString(), [from]);
useEffect(() => { useEffect(() => {
setTime(calcTime());
const t = setInterval(() => { const t = setInterval(() => {
setTime(s => { const newTime = calcTime(from);
const newTime = calcTime(); setTime(s => s !== newTime ? newTime : s);
if (newTime !== s) {
return newTime;
}
return s;
});
}, 60_000); // update every minute }, 60_000); // update every minute
return () => clearInterval(t); return () => clearInterval(t);
}, [from]); }, [calcTime, from]);
return ( return (
<time dateTime={isoDate} title={absoluteTime}> <time dateTime={isoDate} title={absoluteTime}>
@ -72,3 +65,5 @@ export default function NoteTime(props: NoteTimeProps) {
</time> </time>
); );
} }
export default NoteTime;