From: xangelo Date: Tue, 13 Feb 2024 16:18:30 +0000 (-0500) Subject: pagination over 100 feed items X-Git-Url: https://git.xangelo.ca/?a=commitdiff_plain;h=8bd839ef96d00f7612b1dad4fdde4493d919ed59;p=river.git pagination over 100 feed items --- diff --git a/src/server.ts b/src/server.ts index 58e726c..ec9b4d5 100644 --- a/src/server.ts +++ b/src/server.ts @@ -208,7 +208,8 @@ app.get('/feeds', async (req, res) => { const feedList: FeedSchemaWithUnread[] = await db.raw(` select f.*, - count(fe.feed_id) - sum(fe.is_read) as unread + sum(fe.is_read) as read, + count(fe.feed_id) as total from feeds f join feed_entry fe on fe.feed_id = f.id group by fe.feed_id @@ -223,12 +224,25 @@ group by fe.feed_id }); app.get('/feeds/:feed_id', async (req, res) => { + const page = parseInt(req.query?.page?.toString() ?? '1') - 1; + const feedEntries = await db.select('*').from('feed_entry').where({ feed_id: req.params.feed_id - }).orderBy('pub_date', 'desc').limit(100); + }).orderBy('pub_date', 'desc').limit(100).offset(page * 100); + + const feedData: FeedSchemaWithUnread[] = await db.raw(` +select + f.*, + sum(fe.is_read) as read, + count(fe.feed_id) as total +from feeds f +join feed_entry fe on fe.feed_id = f.id +where f.id = ? +group by fe.feed_id +`, [req.params.feed_id]); if(req.accepts('html')) { - res.send(renderReaderAppFeedEntries(feedEntries)) + res.send(renderReaderAppFeedEntries(page, feedData.pop(), feedEntries)) return; } res.json(feedEntries); diff --git a/src/types.ts b/src/types.ts index 121076f..abb7549 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,7 +11,8 @@ export type FeedSchema = { } & KnexTimestamps; export type FeedSchemaWithUnread = FeedSchema & { - unread: number + read: number + total: number } export type FeedEntrySchema = { diff --git a/src/views.ts b/src/views.ts index 2a88a8b..486fda1 100644 --- a/src/views.ts +++ b/src/views.ts @@ -28,7 +28,7 @@ export function renderFeedItem(entry: FeedWithEntrySchema): string { export function renderReaderAppFeedListItem(feed: FeedSchemaWithUnread, autoload: boolean = false): string { return ` -${feed.title} (${feed.unread}) +${feed.title} (${feed.total - feed.read}) `; } @@ -58,6 +58,29 @@ export function renderReaderAppFeedEntry(entry: FeedWithEntrySchema): string { } -export function renderReaderAppFeedEntries(list: FeedWithEntrySchema[]): string { - return list.map(renderReaderAppFeedEntry).join("\n"); +export function renderPagination(baseLink: string, currentPage: number, totalItems: number, itemsPerPage: number = 100): string { + let pageLinks: string[] = ['

']; + const pages = Math.ceil(totalItems/itemsPerPage); + for(let i = 1; i <= pages; ++i) { + if(i === (currentPage + 1)) { + pageLinks.push(i.toString()); + } + else { + pageLinks.push(``); + } + } + + pageLinks.push('

'); + return pageLinks.join("\n"); +} + +export function renderReaderAppFeedEntries(page: number, feed: FeedSchemaWithUnread, list: FeedWithEntrySchema[]): string { + return ` +

+ ${feed.title}
+ ${feed.url} +

+ ${list.map(renderReaderAppFeedEntry).join("\n")} + ${renderPagination(`/feeds/${feed.id}`, page, feed.total)} + `; }