diff --git a/web/src/components/TimeAgo.jsx b/web/src/components/TimeAgo.jsx new file mode 100644 index 000000000..eafce61db --- /dev/null +++ b/web/src/components/TimeAgo.jsx @@ -0,0 +1,61 @@ +import { h } from 'preact'; + +const timeAgo = ({ time, dense = false }) => { + if (!time) return 'Invalid Time'; + try { + const currentTime = new Date(); + const pastTime = new Date(time); + const elapsedTime = currentTime - pastTime; + if (elapsedTime < 0) return 'Invalid Time'; + + const timeUnits = [ + { unit: 'ye', full: 'year', value: 31536000 }, + { unit: 'mo', full: 'month', value: 0 }, + { unit: 'day', full: 'day', value: 86400 }, + { unit: 'h', full: 'hour', value: 3600 }, + { unit: 'm', full: 'minute', value: 60 }, + { unit: 's', full: 'second', value: 1 }, + ]; + + let elapsed = elapsedTime / 1000; + if (elapsed < 60) { + return 'just now'; + } + + for (let i = 0; i < timeUnits.length; i++) { + // if months + if (i === 1) { + // Get the month and year for the time provided + const pastMonth = pastTime.getUTCMonth(); + const pastYear = pastTime.getUTCFullYear(); + + // get current month and year + const currentMonth = currentTime.getUTCMonth(); + const currentYear = currentTime.getUTCFullYear(); + + let monthDiff = (currentYear - pastYear) * 12 + (currentMonth - pastMonth); + + // check if the time provided is the previous month but not exceeded 1 month ago. + if (currentTime.getUTCDate() < pastTime.getUTCDate()) { + monthDiff--; + } + + if (monthDiff > 0) { + const unitAmount = monthDiff; + return `${unitAmount}${dense ? timeUnits[i].unit[0] : ` ${timeUnits[i].full}`}${dense ? '' : 's'} ago`; + } + } else if (elapsed >= timeUnits[i].value) { + const unitAmount = Math.floor(elapsed / timeUnits[i].value); + return `${unitAmount}${dense ? timeUnits[i].unit[0] : ` ${timeUnits[i].full}`}${dense ? '' : 's'} ago`; + } + } + } catch { + return 'Invalid Time'; + } +}; + +const TimeAgo = (props) => { + return {timeAgo({ ...props })}; +}; + +export default TimeAgo; diff --git a/web/src/icons/Clock.jsx b/web/src/icons/Clock.jsx new file mode 100644 index 000000000..e813e006d --- /dev/null +++ b/web/src/icons/Clock.jsx @@ -0,0 +1,24 @@ +import { h } from 'preact'; +import { memo } from 'preact/compat'; + +export function Clock({ className = 'h-6 w-6', stroke = 'currentColor', fill = 'none', onClick = () => {} }) { + return ( + + ); +} + +export default memo(Clock); diff --git a/web/src/routes/Events.jsx b/web/src/routes/Events.jsx index 2b79efe90..87ae63ec8 100644 --- a/web/src/routes/Events.jsx +++ b/web/src/routes/Events.jsx @@ -15,6 +15,7 @@ import { UploadPlus } from '../icons/UploadPlus'; import { Clip } from '../icons/Clip'; import { Zone } from '../icons/Zone'; import { Camera } from '../icons/Camera'; +import { Clock } from '../icons/Clock'; import { Delete } from '../icons/Delete'; import { Download } from '../icons/Download'; import Menu, { MenuItem } from '../components/Menu'; @@ -22,8 +23,9 @@ import CalendarIcon from '../icons/Calendar'; import Calendar from '../components/Calendar'; import Button from '../components/Button'; import Dialog from '../components/Dialog'; -import { fromUnixTime, intervalToDuration, formatDuration } from 'date-fns'; import MultiSelect from '../components/MultiSelect'; +import { formatUnixTimestampToDateTime, getDurationFromTimestamps } from '../utils/dateUtil'; +import TimeAgo from '../components/TimeAgo'; const API_LIMIT = 25; @@ -39,16 +41,6 @@ const monthsAgo = (num) => { return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() / 1000; }; -const clipDuration = (start_time, end_time) => { - const start = fromUnixTime(start_time); - const end = fromUnixTime(end_time); - let duration = 'In Progress'; - if (end_time) { - duration = formatDuration(intervalToDuration({ start, end })); - } - return duration; -}; - export default function Events({ path, ...props }) { const apiHost = useApiHost(); const [searchParams, setSearchParams] = useState({ @@ -511,13 +503,19 @@ export default function Events({ path, ...props }) {