Add post RSS feed

This commit is contained in:
LittleSheep 2025-01-08 13:52:35 +08:00
parent 2be8508914
commit fff10245ea
4 changed files with 106 additions and 10 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -23,6 +23,7 @@
"axios": "^1.7.9",
"axios-case-converter": "^1.1.1",
"cookies-next": "^5.0.2",
"feed": "^4.2.2",
"next": "15.1.3",
"next-nprogress-bar": "^2.4.3",
"react": "^19.0.0",

72
src/pages/posts/feed.ts Normal file
View File

@ -0,0 +1,72 @@
import { sni } from '@/services/network'
import { SnPost } from '@/services/post'
import { GetServerSideProps } from 'next'
import { Feed } from 'feed'
function generateFeed(posts: SnPost[]): string {
const feed = new Feed({
title: 'Solar Network Posts',
description: 'All posts on the Solar Network platform, and now you can view them via the RSS feed!',
id: 'https://solsynth.dev/posts',
link: 'https://solsynth.dev/posts',
favicon: 'https://solsynth.dev/favicon.png',
copyright: `All rights reserved ${new Date().getFullYear()} © Solsynth LLC & Post Publishers`,
updated: new Date(posts[0].createdAt),
generator: 'Capital',
feedLinks: {
json: 'https://example.com/json',
atom: 'https://example.com/atom',
},
})
for (const p of posts) {
feed.addItem({
id: p.id.toString(),
title: p.body.title ?? `Post #${p.id}`,
description: p.body.description,
link:
p.alias && p.aliasPrefix
? `https://solsynth.dev/posts/${p.aliasPrefix}/${p.alias}`
: `https://solsynth.dev/posts/${p.id}`,
content: p.body.content,
date: new Date(p.publishedAt ?? p.createdAt),
published: new Date(p.publishedAt ?? p.createdAt),
copyright: `All right reserved ${new Date().getFullYear()} © @${p.publisher.name}`,
author: [
{
name: `@${p.publisher.name}`,
},
],
})
}
return feed.rss2()
}
export const getServerSideProps: GetServerSideProps = async ({ res, query }) => {
let page: number = parseInt(query.page as string)
if (isNaN(page)) page = 1
const countPerPage = 20
const { data: resp } = await sni.get<{ data: SnPost[] }>('/cgi/co/posts', {
params: {
take: countPerPage,
offset: (page - 1) * countPerPage,
},
})
const sitemap = generateFeed(resp.data)
res.setHeader('Content-Type', 'text/xml')
res.write(sitemap)
res.end()
return {
props: {},
}
}
export default function PostSiteMap() {
// getServerSideProps will do the heavy lifting
}

View File

@ -2,9 +2,20 @@ import { AttachmentItem } from '@/components/attachments/AttachmentItem'
import { SnAttachment, listAttachment } from '@/services/attachment'
import { getAttachmentUrl, sni } from '@/services/network'
import { SnPost } from '@/services/post'
import { Avatar, Box, Container, Divider, Grid2 as Grid, Pagination, Paper, Typography } from '@mui/material'
import {
Avatar,
Box,
Button,
Container,
Divider,
Grid2 as Grid,
Link,
Pagination,
Paper,
Typography,
} from '@mui/material'
import { GetServerSideProps, InferGetServerSidePropsType } from 'next'
import Link from 'next/link'
import NextLink from 'next/link'
import { useRouter } from 'next/router'
import rehypeSanitize from 'rehype-sanitize'
import rehypeStringify from 'rehype-stringify'
@ -86,7 +97,7 @@ export default function PostList({ posts, page, pages }: InferGetServerSideProps
</Box>
</Box>
<Link href={`/posts/${p.id}`} passHref>
<NextLink href={`/posts/${p.id}`} passHref>
<Box>
<Box sx={{ mt: 1.5, mb: 1 }} display="flex" flexDirection="column" gap={0.5}>
{(p.body.title || p.body.content) && (
@ -108,7 +119,7 @@ export default function PostList({ posts, page, pages }: InferGetServerSideProps
{p.body.content && <div dangerouslySetInnerHTML={{ __html: p.body.content }} />}
</Box>
</Box>
</Link>
</NextLink>
{p.attachments && (
<Grid
@ -131,12 +142,24 @@ export default function PostList({ posts, page, pages }: InferGetServerSideProps
</Paper>
))}
<Pagination
count={pages}
page={page}
sx={{ mx: 'auto', mb: 5, mt: 3 }}
onChange={(_, page) => router.push('/posts?page=' + page)}
/>
<Box
sx={{
mx: 'auto',
mb: 5,
mt: 3,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
placeItems: 'center',
gap: 1.5,
textAlign: 'center',
}}
>
<Pagination count={pages} page={page} onChange={(_, page) => router.push('/posts?page=' + page)} />
<NextLink passHref href="/posts/feed" target="_blank" prefetch={false}>
<Link fontSize={13}>RSS Feed</Link>
</NextLink>
</Box>
</Container>
)
}