feat(library): show last edited time on book cards

This commit is contained in:
pj committed 2026-08-10 18:36:30 +05:30
1 parent 742e42d65b
commit efd45cf61e
6 files changed
+75 -22

No files matched your search

+7
View File
@@ -10,10 +10,12 @@ import { RowMenu } from "./RowMenu";
import { BackupButton } from "./BackupButton";
import { useBackup } from "../store/useBackup";
import { useBook } from "../store/useBook";
import { relativeTime } from "../time";
export function Library({ onOpen }: { onOpen: (book: Book) => void }) {
const [books, setBooks] = useState<BookSummary[]>([]);
const [loaded, setLoaded] = useState(false);
const [now, setNow] = useState(() => Date.now());
const [busy, setBusy] = useState(false);
const [pendingDelete, setPendingDelete] = useState<BookSummary | null>(null);
const notice = useBook((s) => s.notice);
@@ -30,6 +32,10 @@ export function Library({ onOpen }: { onOpen: (book: Book) => void }) {
useEffect(() => {
refresh();
}, []);
useEffect(() => {
const timer = setInterval(() => setNow(Date.now()), 60_000);
return () => clearInterval(timer);
}, []);
useEffect(() => {
if (restoreNonce) refresh();
}, [restoreNonce]);
@@ -125,6 +131,7 @@ export function Library({ onOpen }: { onOpen: (book: Book) => void }) {
>
<span className="card-title">{b.title || "Untitled"}</span>
{b.author && <span className="card-author">{b.author}</span>}
{b.updatedAt > 0 && <span className="card-meta">Edited {relativeTime(b.updatedAt, now)}</span>}
<RowMenu label="Book options" className="card-menu" onDelete={() => setPendingDelete(b)} />
</div>
),
+2 -21
View File
@@ -5,6 +5,7 @@ import { AddPageMenu } from "./AddPageMenu";
import { ConfirmDialog } from "./ConfirmDialog";
import { Icon } from "./Icon";
import { RowMenu } from "./RowMenu";
import { relativeTime } from "../time";
interface Row {
chapter: Chapter;
@@ -19,26 +20,6 @@ interface DropTarget {
index: number;
}
function formatEdited(ts: number, now: number): string {
const diff = Math.max(0, now - ts);
const min = 60_000;
const hour = 60 * min;
const day = 24 * hour;
if (diff < min) return "just now";
if (diff < hour) {
const m = Math.floor(diff / min);
return `${m} minute${m === 1 ? "" : "s"} ago`;
}
if (diff < day) {
const h = Math.floor(diff / hour);
return `${h} hour${h === 1 ? "" : "s"} ago`;
}
if (diff < 2 * day) return "yesterday";
const d = Math.floor(diff / day);
if (d < 7) return `${d} days ago`;
return new Date(ts).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
}
export function Sidebar({ onNavigate }: { onNavigate?: () => void }) {
const chapters = useBook((s) => s.book?.chapters ?? []);
const activeChapterId = useBook((s) => s.activeChapterId);
@@ -254,7 +235,7 @@ export function Sidebar({ onNavigate }: { onNavigate?: () => void }) {
</span>
)}
{row.chapter.id === activeChapterId && (
<span className="meta">Edited {formatEdited(row.chapter.updatedAt, now)}</span>
<span className="meta">Edited {relativeTime(row.chapter.updatedAt, now)}</span>
)}
</span>
<RowMenu
+1
View File
@@ -6,6 +6,7 @@ export interface BookSummary {
id: string;
title: string;
author: string;
updatedAt: number;
corrupt?: boolean;
}
+13
View File
@@ -1566,6 +1566,19 @@ body.resizing .sidebar {
color: var(--accent);
}
.card-meta {
position: absolute;
left: 14px;
right: 14px;
bottom: 14px;
font-family: var(--font-ui);
font-size: var(--t-1);
color: var(--ink-faint);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-action {
background: transparent;
border: 1px dashed var(--line-strong);
+19
View File
@@ -0,0 +1,19 @@
export function relativeTime(ts: number, now: number): string {
const diff = Math.max(0, now - ts);
const min = 60_000;
const hour = 60 * min;
const day = 24 * hour;
if (diff < min) return "just now";
if (diff < hour) {
const m = Math.floor(diff / min);
return `${m} minute${m === 1 ? "" : "s"} ago`;
}
if (diff < day) {
const h = Math.floor(diff / hour);
return `${h} hour${h === 1 ? "" : "s"} ago`;
}
if (diff < 2 * day) return "yesterday";
const d = Math.floor(diff / day);
if (d < 7) return `${d} days ago`;
return new Date(ts).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
}