From 1ab04cf951cc772183e9f4eaa23f29c663ceab60 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 18 Apr 2026 14:46:56 +0300 Subject: [PATCH] feat(revisions): improve grouping with smart auto-titles --- apps/client/src/widgets/dialogs/revisions.css | 8 ++++ apps/client/src/widgets/dialogs/revisions.tsx | 47 ++++++++++++++----- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/apps/client/src/widgets/dialogs/revisions.css b/apps/client/src/widgets/dialogs/revisions.css index 189858ccfb..609973cb86 100644 --- a/apps/client/src/widgets/dialogs/revisions.css +++ b/apps/client/src/widgets/dialogs/revisions.css @@ -119,6 +119,14 @@ body.mobile .revisions-dialog { .dropdown-item + .dropdown-item { border-top: 1px solid var(--main-border-color) !important; } + + .dropdown-item { + min-height: 2.5em; + + >div { + padding-left: 0.25em; + } + } } .revision-item-description { diff --git a/apps/client/src/widgets/dialogs/revisions.tsx b/apps/client/src/widgets/dialogs/revisions.tsx index 8438d37a07..f23fcbc5c4 100644 --- a/apps/client/src/widgets/dialogs/revisions.tsx +++ b/apps/client/src/widgets/dialogs/revisions.tsx @@ -208,39 +208,64 @@ function getRevisionSourceTitle(source?: string): string { return t(`revisions.source_description_${source ?? "unknown"}`); } -function getRelativeDateGroup(dateStr: string): string { +type DateGroup = "today" | "yesterday" | "this_week" | "this_month" | "older"; + +function getDateGroup(dateStr: string): DateGroup { const date = dayjs(dateStr); const now = dayjs(); - if (date.isSame(now, "day")) return t("revisions.date_today"); - if (date.isSame(now.subtract(1, "day"), "day")) return t("revisions.date_yesterday"); - if (date.isSame(now, "week")) return t("revisions.date_this_week"); - if (date.isSame(now, "month")) return t("revisions.date_this_month"); - return date.format("MMMM YYYY"); + if (date.isSame(now, "day")) return "today"; + if (date.isSame(now.subtract(1, "day"), "day")) return "yesterday"; + if (date.isSame(now, "week")) return "this_week"; + if (date.isSame(now, "month")) return "this_month"; + return "older"; +} + +function getDateGroupLabel(group: DateGroup, dateStr: string): string { + if (group === "older") return dayjs(dateStr).format("MMMM YYYY"); + return t(`revisions.date_${group}`); +} + +function formatRevisionDate(dateStr: string, group: DateGroup): string { + const date = dayjs(dateStr); + switch (group) { + case "today": + case "yesterday": + return date.format("HH:mm"); + case "this_week": + return date.format("dddd · HH:mm"); + default: + return date.isSame(dayjs(), "year") + ? date.format("MMM D · HH:mm") + : date.format("MMM D, YYYY · HH:mm"); + } } function buildRevisionTooltip(item: RevisionItem): string { + const dateLine = item.dateCreated + ? `${dayjs(item.dateCreated).format("YYYY-MM-DD HH:mm")} (${dayjs(item.dateCreated).fromNow()})` + : ""; return [ getRevisionSourceTitle(item.source), - item.dateCreated && dayjs(item.dateCreated).fromNow(), + dateLine, item.contentLength && utils.formatSize(item.contentLength) ].filter(Boolean).join("\n"); } function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: RevisionItem[], onSelect: (val: string) => void, currentRevision?: RevisionItem }) { - let lastGroup = ""; + let lastGroup: DateGroup | "" = ""; return ( {revisions.map((item) => { - const group = item.dateCreated ? getRelativeDateGroup(item.dateCreated) : ""; + const group = item.dateCreated ? getDateGroup(item.dateCreated) : "" as DateGroup; const showHeader = group !== lastGroup; lastGroup = group; return ( {showHeader && ( -
{group}
+
{item.dateCreated ? getDateGroupLabel(group, item.dateCreated) : ""}
)}
- {item.dateCreated && dayjs(item.dateCreated).format("MMM D · HH:mm")} + {item.dateCreated && formatRevisionDate(item.dateCreated, group)}
{item.description && (