diff --git a/apps/code/package.json b/apps/code/package.json index ef6fc96e9..a2b014c83 100644 --- a/apps/code/package.json +++ b/apps/code/package.json @@ -130,8 +130,8 @@ "@posthog/electron-trpc": "workspace:*", "@posthog/git": "workspace:*", "@posthog/hedgehog-mode": "^0.0.48", - "@posthog/quill": "0.1.0-alpha.7", "@posthog/platform": "workspace:*", + "@posthog/quill": "0.1.0-alpha.7", "@posthog/shared": "workspace:*", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-icons": "^1.3.2", diff --git a/apps/code/src/renderer/features/sidebar/components/TaskListView.tsx b/apps/code/src/renderer/features/sidebar/components/TaskListView.tsx index 820fe3be6..93425cd93 100644 --- a/apps/code/src/renderer/features/sidebar/components/TaskListView.tsx +++ b/apps/code/src/renderer/features/sidebar/components/TaskListView.tsx @@ -20,7 +20,8 @@ import { Flex, Text } from "@radix-ui/themes"; import { useWorkspace } from "@renderer/features/workspace/hooks/useWorkspace"; import { normalizeRepoKey } from "@shared/utils/repo"; import { useNavigationStore } from "@stores/navigationStore"; -import { useCallback, useEffect } from "react"; +import { getRelativeDateGroup } from "@utils/time"; +import { Fragment, useCallback, useEffect, useMemo } from "react"; import type { TaskData, TaskGroup } from "../hooks/useSidebarData"; import { useSidebarStore } from "../stores/sidebarStore"; import { DraggableFolder } from "./DraggableFolder"; @@ -246,6 +247,20 @@ export function TaskListView({ const timestampKey: "lastActivityAt" | "createdAt" = sortMode === "updated" ? "lastActivityAt" : "createdAt"; + const dateGroupedTasks = useMemo(() => { + const groups: { label: string | null; tasks: TaskData[] }[] = []; + for (const task of flatTasks) { + const label = getRelativeDateGroup(task[timestampKey]); + const last = groups[groups.length - 1]; + if (last && last.label === label) { + last.tasks.push(task); + } else { + groups.push({ label, tasks: [task] }); + } + } + return groups; + }, [flatTasks, timestampKey]); + return ( {pinnedTasks.length > 0 && ( @@ -363,23 +378,30 @@ export function TaskListView({ ) : ( - {flatTasks.map((task) => ( - onTaskClick(task.id)} - onDoubleClick={() => onTaskDoubleClick(task.id)} - onContextMenu={(e, isPinned) => - onTaskContextMenu(task.id, e, isPinned) - } - onArchive={() => onTaskArchive(task.id)} - onTogglePin={() => onTaskTogglePin(task.id)} - onEditSubmit={(newTitle) => onTaskEditSubmit(task.id, newTitle)} - onEditCancel={onTaskEditCancel} - timestamp={task[timestampKey]} - /> + {dateGroupedTasks.map((group) => ( + + {group.label && } + {group.tasks.map((task) => ( + onTaskClick(task.id)} + onDoubleClick={() => onTaskDoubleClick(task.id)} + onContextMenu={(e, isPinned) => + onTaskContextMenu(task.id, e, isPinned) + } + onArchive={() => onTaskArchive(task.id)} + onTogglePin={() => onTaskTogglePin(task.id)} + onEditSubmit={(newTitle) => + onTaskEditSubmit(task.id, newTitle) + } + onEditCancel={onTaskEditCancel} + timestamp={task[timestampKey]} + /> + ))} + ))} {hasMore && (
diff --git a/apps/code/src/renderer/utils/time.ts b/apps/code/src/renderer/utils/time.ts index 5b49aa831..c57165fc7 100644 --- a/apps/code/src/renderer/utils/time.ts +++ b/apps/code/src/renderer/utils/time.ts @@ -50,3 +50,22 @@ export function formatRelativeTimeLong(timestamp: number | string): string { year: "numeric", }); } + +export function getRelativeDateGroup( + timestamp: number | string, +): string | null { + const date = + typeof timestamp === "string" ? new Date(timestamp) : new Date(timestamp); + const startOfToday = new Date(); + startOfToday.setHours(0, 0, 0, 0); + const startOfDate = new Date(date); + startOfDate.setHours(0, 0, 0, 0); + const days = Math.round( + (startOfToday.getTime() - startOfDate.getTime()) / 86_400_000, + ); + if (days <= 0) return null; + if (days === 1) return "Yesterday"; + if (days < 7) return "This week"; + if (days < 30) return "This month"; + return "Earlier"; +}