diff --git a/server/db.ts b/server/db.ts index 6bb4c5a..742e1fe 100644 --- a/server/db.ts +++ b/server/db.ts @@ -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); diff --git a/server/routes.ts b/server/routes.ts index ce1dcfb..e8e254f 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -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) => { diff --git a/web/src/App.tsx b/web/src/App.tsx index a14461c..3ee66d2 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -12,8 +12,15 @@ export default function App() { const sse = useSSE(); const stateQuery = useQuery({ queryKey: ['state'], queryFn: fetchState }); const [mobileView, setMobileView] = useState('prs'); + const [selectedPrId, setSelectedPrId] = useState(null); const state = stateQuery.data; + const selectedPr = state?.prs.find((p) => p.id === selectedPrId) ?? null; + + const selectPr = (id: string) => { + setSelectedPrId((cur) => (cur === id ? null : id)); + setMobileView('timeline'); + }; const lastSyncAt = sse.lastSync?.lastSyncAt ?? state?.lastSyncAt ?? null; const error = sse.lastSync ? sse.lastSync.error : (state?.lastSyncError ?? null); const unreadTotal = sse.lastSync?.unreadCount ?? state?.unreadTotal ?? 0; @@ -24,7 +31,7 @@ export default function App() {
{state ? ( - + ) : (
{stateQuery.isError ? 'Failed to load — is the server running?' : 'Loading…'} @@ -32,7 +39,7 @@ export default function App() { )}
- + setSelectedPrId(null)} />