diff --git a/src/app.ts b/src/app.ts index 565e915..138348c 100644 --- a/src/app.ts +++ b/src/app.ts @@ -76,6 +76,7 @@ import { hashtagTimelineController, homeTimelineController, publicTimelineController, + suggestedTimelineController, } from '@/controllers/api/timelines.ts'; import { trendingStatusesController, trendingTagsController } from '@/controllers/api/trends.ts'; import { indexController } from '@/controllers/site.ts'; @@ -194,6 +195,7 @@ app.post('/api/v2/media', mediaController); app.get('/api/v1/timelines/home', requireSigner, homeTimelineController); app.get('/api/v1/timelines/public', publicTimelineController); app.get('/api/v1/timelines/tag/:hashtag', hashtagTimelineController); +app.get('/api/v1/timeines/suggested', suggestedTimelineController); app.get('/api/v1/preferences', preferencesController); app.get('/api/v1/search', searchController); diff --git a/src/controllers/api/timelines.ts b/src/controllers/api/timelines.ts index 8ea66ba..5d7862b 100644 --- a/src/controllers/api/timelines.ts +++ b/src/controllers/api/timelines.ts @@ -7,6 +7,7 @@ import { getFeedPubkeys } from '@/queries.ts'; import { booleanParamSchema } from '@/schema.ts'; import { hydrateEvents } from '@/storages/hydrate.ts'; import { paginated, paginationSchema } from '@/utils/api.ts'; +import { getTagSet } from '@/utils/tags.ts'; import { renderReblog, renderStatus } from '@/views/mastodon/statuses.ts'; const homeTimelineController: AppController = async (c) => { @@ -25,7 +26,7 @@ const publicTimelineController: AppController = (c) => { const params = paginationSchema.parse(c.req.query()); const { local, instance } = publicQuerySchema.parse(c.req.query()); - const filter: NostrFilter = { kinds: [1, 6], ...params }; + const filter: NostrFilter = { kinds: [1], ...params }; if (local) { filter.search = `domain:${Conf.url.host}`; @@ -42,6 +43,19 @@ const hashtagTimelineController: AppController = (c) => { return renderStatuses(c, [{ kinds: [1], '#t': [hashtag], ...params }]); }; +const suggestedTimelineController: AppController = async (c) => { + const store = c.get('store'); + const params = paginationSchema.parse(c.req.query()); + + const [follows] = await store.query( + [{ kinds: [3], authors: [Conf.pubkey], limit: 1 }], + ); + + const authors = [...getTagSet(follows?.tags ?? [], 'p')]; + + return renderStatuses(c, [{ authors, kinds: [1], ...params }]); +}; + /** Render statuses for timelines. */ async function renderStatuses(c: AppContext, filters: NostrFilter[]) { const { signal } = c.req.raw; @@ -71,4 +85,4 @@ async function renderStatuses(c: AppContext, filters: NostrFilter[]) { return paginated(c, events, statuses); } -export { hashtagTimelineController, homeTimelineController, publicTimelineController }; +export { hashtagTimelineController, homeTimelineController, publicTimelineController, suggestedTimelineController };