Skip to content

Commit

Permalink
Human readable relative time (#6613)
Browse files Browse the repository at this point in the history
* human readable date time

* lint

* feedback

* lint
  • Loading branch information
lovincyrus authored Feb 10, 2025
1 parent 6cfd7b2 commit dcd553f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 22 deletions.
29 changes: 22 additions & 7 deletions web-admin/src/features/dashboards/listing/utils.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import { DateTime, Duration } from "luxon";

function formatUnit(value: number, unit: string): string {
return `${value} ${value === 1 ? unit : unit + "s"} ago`;
}

export function timeAgo(date: Date): string {
const now = DateTime.now();
const then = DateTime.fromJSDate(date);
const diff = Duration.fromMillis(now.diff(then).milliseconds);

if (diff.as("minutes") < 1) return "just now";
if (diff.as("hours") < 1) return `${Math.floor(diff.as("minutes"))}m ago`;
if (diff.as("days") < 1) return `${Math.floor(diff.as("hours"))}h ago`;
if (diff.as("weeks") < 1) return `${Math.floor(diff.as("days"))}d ago`;
if (diff.as("months") < 1) return `${Math.floor(diff.as("weeks"))}w ago`;
if (diff.as("years") < 1) return `${Math.floor(diff.as("months"))}M ago`;
if (diff.as("minutes") < 1) return "Just now";

const minutes = Math.round(diff.as("minutes"));
if (diff.as("hours") < 1) return formatUnit(minutes, "minute");

const hours = Math.round(diff.as("hours"));
if (diff.as("days") < 1) return formatUnit(hours, "hour");

const days = Math.round(diff.as("days"));
if (diff.as("weeks") < 1) return formatUnit(days, "day");

const weeks = Math.round(diff.as("weeks"));
if (diff.as("months") < 1) return formatUnit(weeks, "week");

const months = Math.round(diff.as("months"));
if (diff.as("years") < 1) return formatUnit(months, "month");

return `${Math.floor(diff.as("years"))}y ago`;
const years = Math.round(diff.as("years"));
return formatUnit(years, "year");
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
<script lang="ts">
import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
import { timeAgo } from "../../dashboards/listing/utils";
import { DateTime } from "luxon";
import TimeAgo from "./TimeAgo.svelte";
export let updatedOn: string;
function formatText() {
const updatedDate = new Date(updatedOn);
// FIXME: `updateProjectVariables` does not update the `updatedOn` timestamp correctly
// if (createdDate.getTime() === updatedDate.getTime()) {
// return `Added ${timeAgo(createdDate)}`;
// }
return `${timeAgo(updatedDate)}`;
}
$: formattedText = formatText();
$: fullDate = DateTime.fromISO(updatedOn).toLocaleString(
DateTime.DATETIME_FULL,
);
</script>

<div class="flex justify-start items-center">
<Tooltip distance={8} location="top">
<div
class="flex flex-row gap-x-1 text-gray-500 cursor-pointer w-fit truncate line-clamp-1"
>
{formattedText}
<TimeAgo datetime={updatedOn} />
</div>
<TooltipContent slot="tooltip-content">
<span class="text-xs text-gray-50 font-medium">
{new Date(updatedOn).toLocaleString()}
{fullDate}
</span>
</TooltipContent>
</Tooltip>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script lang="ts">
import { onDestroy } from "svelte";
import { timeAgo } from "../../dashboards/listing/utils";
import { Duration } from "luxon";
export let datetime: Date | string;
let formattedTime: string;
let interval: ReturnType<typeof setInterval> | null = null;
let lastInterval: number | null = null;
const INTERVALS = {
SECOND: Duration.fromObject({ seconds: 1 }).toMillis(),
MINUTE: Duration.fromObject({ minutes: 1 }).toMillis(),
FIVE_MINUTES: Duration.fromObject({ minutes: 5 }).toMillis(),
HOUR: Duration.fromObject({ hours: 1 }).toMillis(),
};
function getInterval(date: Date): number {
const diff = Duration.fromMillis(Date.now() - date.getTime());
if (diff.as("minutes") < 1) return INTERVALS.SECOND;
if (diff.as("hours") < 1) return INTERVALS.MINUTE;
if (diff.as("days") < 1) return INTERVALS.FIVE_MINUTES;
return INTERVALS.HOUR;
}
function updateTimeAgo(date: Date) {
formattedTime = timeAgo(date);
const newInterval = getInterval(date);
if (newInterval !== lastInterval) {
lastInterval = newInterval;
resetInterval(newInterval);
}
}
function resetInterval(newInterval: number) {
if (interval) clearInterval(interval);
interval = setInterval(
() => updateTimeAgo(new Date(datetime)),
newInterval,
);
}
$: {
const date = new Date(datetime);
updateTimeAgo(date);
}
onDestroy(() => {
if (interval) clearInterval(interval);
});
</script>

<time datetime={datetime.toString()}>{formattedTime}</time>

1 comment on commit dcd553f

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.