Per-PR timeline focus: click a card to filter activity, mark-PR-read, clear chip

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DgBEW6qAwgn2fcQbA2f4ZQ
This commit is contained in:
Joshua Coles
2026-07-28 15:12:29 +00:00
co-authored by Claude Fable 5
parent d14b6ebed3
commit 3b7850fe1a
8 changed files with 134 additions and 21 deletions
+10 -1
View File
@@ -195,9 +195,18 @@ export class Db {
return this.db.prepare('SELECT 1 FROM events WHERE id = ?').get(id) !== undefined;
}
timeline(opts: { limit: number; before?: string; unreadOnly?: boolean }): TimelinePage {
timeline(opts: {
limit: number;
before?: string;
unreadOnly?: boolean;
prId?: string;
}): TimelinePage {
const clauses = ["p.state != ''"];
const params: (string | number)[] = [];
if (opts.prId) {
clauses.push('e.pr_id = ?');
params.push(opts.prId);
}
if (opts.before) {
clauses.push('(e.created_at < ? OR (e.created_at = ? AND e.id < ?))');
const [createdAt, id] = splitCursor(opts.before);
+2 -1
View File
@@ -41,7 +41,8 @@ export function createApp({ db, triggerSync }: RouteDeps): Express {
const limit = Math.min(Number(req.query.limit) || 50, 200);
const before = typeof req.query.before === 'string' ? req.query.before : undefined;
const unreadOnly = req.query.unread === '1';
res.json(db.timeline({ limit, before, unreadOnly }));
const prId = typeof req.query.pr === 'string' ? req.query.pr : undefined;
res.json(db.timeline({ limit, before, unreadOnly, prId }));
});
app.post('/api/timeline/:id/read', (req, res) => {