|
13 | 13 | import type { BranchTimeline as BranchTimelineData } from '../../types'; |
14 | 14 | import TimelineRow from './TimelineRow.svelte'; |
15 | 15 | import type { TimelineItemType, TimelineBadge } from './TimelineRow.svelte'; |
| 16 | + import { |
| 17 | + formatRelativeTime, |
| 18 | + formatRelativeTimeSeconds, |
| 19 | + minuteNow, |
| 20 | + } from '../../shared/relativeTime.svelte'; |
16 | 21 | import { |
17 | 22 | collectRunningSessionIds, |
18 | 23 | createLiveSessionHints, |
|
222 | 227 |
|
223 | 228 | // Merge commits, notes, and reviews into a single sorted list |
224 | 229 | let items = $derived.by(() => { |
| 230 | + const nowMs = minuteNow.now(); |
225 | 231 | const all: DisplayItem[] = []; |
226 | 232 | const deletingCommitIds = new Set( |
227 | 233 | deletingItems.filter((item) => item.type === 'commit').map((item) => item.id) |
|
260 | 266 | secondaryMeta = liveHint ?? 'Generating commit'; |
261 | 267 | } else { |
262 | 268 | type = 'commit'; |
263 | | - secondaryMeta = formatRelativeTime(commit.timestamp); |
| 269 | + secondaryMeta = formatRelativeTimeSeconds(commit.timestamp, nowMs); |
264 | 270 | } |
265 | 271 |
|
266 | 272 | all.push({ |
|
300 | 306 | secondaryMeta = liveHint ?? 'Generating note'; |
301 | 307 | } else { |
302 | 308 | type = 'note'; |
303 | | - secondaryMeta = formatRelativeTimeMs(note.createdAt); |
| 309 | + secondaryMeta = formatRelativeTime(note.createdAt, nowMs); |
304 | 310 | } |
305 | 311 |
|
306 | 312 | all.push({ |
|
357 | 363 | meta = liveHint ?? 'Generating review'; |
358 | 364 | } else { |
359 | 365 | type = 'review'; |
360 | | - meta = formatRelativeTimeMs(review.createdAt); |
| 366 | + meta = formatRelativeTime(review.createdAt, nowMs); |
361 | 367 | } |
362 | 368 |
|
363 | 369 | all.push({ |
|
382 | 388 | key: `image-${image.id}`, |
383 | 389 | type: 'image' as TimelineItemType, |
384 | 390 | title: image.filename, |
385 | | - secondaryMeta: isDeleting ? 'Deleting...' : formatRelativeTimeMs(image.createdAt), |
| 391 | + secondaryMeta: isDeleting ? 'Deleting...' : formatRelativeTime(image.createdAt, nowMs), |
386 | 392 | deleting: isDeleting, |
387 | 393 | timestamp: Math.floor(image.createdAt / 1000), |
388 | 394 | order: 0, |
|
496 | 502 | onDeleteImage(item.imageId); |
497 | 503 | } |
498 | 504 | } |
499 | | -
|
500 | | - function formatRelativeTime(timestamp: number): string { |
501 | | - const date = new Date(timestamp * 1000); |
502 | | - const now = new Date(); |
503 | | - const diffMs = now.getTime() - date.getTime(); |
504 | | - const diffMins = Math.floor(diffMs / 60000); |
505 | | - const diffHours = Math.floor(diffMins / 60); |
506 | | - const diffDays = Math.floor(diffHours / 24); |
507 | | -
|
508 | | - if (diffMins < 1) return 'just now'; |
509 | | - if (diffMins < 60) return `${diffMins}m ago`; |
510 | | - if (diffHours < 24) return `${diffHours}h ago`; |
511 | | - if (diffDays < 7) return `${diffDays}d ago`; |
512 | | - return date.toLocaleDateString(); |
513 | | - } |
514 | | -
|
515 | | - function formatRelativeTimeMs(timestamp: number): string { |
516 | | - return formatRelativeTime(Math.floor(timestamp / 1000)); |
517 | | - } |
518 | 505 | </script> |
519 | 506 |
|
520 | 507 | {#if items.length === 0 && !onNewNote && !onNewCommit && !onNewReview && pendingDropNotes.length === 0 && pendingItems.length === 0} |
|
0 commit comments