diff --git a/src/components/attachments/AttachmentItem.tsx b/src/components/attachments/AttachmentItem.tsx
new file mode 100644
index 0000000..63181a7
--- /dev/null
+++ b/src/components/attachments/AttachmentItem.tsx
@@ -0,0 +1,35 @@
+import { SnAttachment } from '@/services/attachment'
+import { getAttachmentUrl } from '@/services/network'
+import { QuestionMark } from '@mui/icons-material'
+import { Link, Paper, Typography } from '@mui/material'
+
+export function AttachmentItem({ item }: { item: SnAttachment }) {
+ switch (item.mimetype.split('/')[0]) {
+ case 'image':
+ return (
+
+
+
+ )
+ case 'video':
+ return (
+
+
+
+ )
+ default:
+ return (
+
+
+ Unknown
+ {item.name}
+
+ {item.mimetype}
+
+
+ Open in browser
+
+
+ )
+ }
+}
diff --git a/src/pages/posts/[...id].tsx b/src/pages/posts/[...id].tsx
index dfa4300..18da2c1 100644
--- a/src/pages/posts/[...id].tsx
+++ b/src/pages/posts/[...id].tsx
@@ -1,6 +1,19 @@
import { getAttachmentUrl, sni } from '@/services/network'
import { SnPost } from '@/services/post'
-import { Alert, AlertTitle, Avatar, Box, Collapse, Container, IconButton, Link, Typography } from '@mui/material'
+import { listAttachment, SnAttachment } from '@/services/attachment'
+import {
+ Grid2 as Grid,
+ Alert,
+ AlertTitle,
+ Avatar,
+ Box,
+ Collapse,
+ Container,
+ IconButton,
+ Link,
+ Typography,
+ Divider,
+} from '@mui/material'
import { GetServerSideProps, InferGetServerSidePropsType } from 'next'
import { useEffect, useMemo, useState } from 'react'
import { unified } from 'unified'
@@ -11,6 +24,7 @@ import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import CloseIcon from '@mui/icons-material/Close'
+import { AttachmentItem } from '@/components/attachments/AttachmentItem'
export const getServerSideProps = (async (context) => {
const id = context.params!.id as string[]
@@ -25,15 +39,19 @@ export const getServerSideProps = (async (context) => {
.process(post.body.content)
post.body.content = String(out)
}
- return { props: { post } }
+ let attachments: SnAttachment[] = []
+ if (post.body.attachments) {
+ attachments = await listAttachment(post.body.attachments)
+ }
+ return { props: { post, attachments } }
} catch (err) {
return {
notFound: true,
}
}
-}) satisfies GetServerSideProps<{ post: SnPost }>
+}) satisfies GetServerSideProps<{ post: SnPost; attachments: SnAttachment[] }>
-export default function Post({ post }: InferGetServerSidePropsType) {
+export default function Post({ post, attachments }: InferGetServerSidePropsType) {
const link = useMemo(() => `https://sn.solsynth.dev/posts/${post.id}`, [post])
const [openAppHint, setOpenAppHint] = useState()
@@ -84,7 +102,7 @@ export default function Post({ post }: InferGetServerSidePropsType
)}
-
+
@@ -97,9 +115,33 @@ export default function Post({ post }: InferGetServerSidePropsType
-
+
+ {(post.body.title || post.body.content) && (
+
+ {post.body.title && {post.body.title}}
+ {post.body.description && {post.body.description}}
+
+ )}
+
+
+ Published at {new Date(post.publishedAt ?? post.createdAt).toLocaleString()}
+
+
+
+
+
+
+
{post.body.content && }
+
+ {attachments && (
+
+ {attachments.map((a) => (
+
+ ))}
+
+ )}
>
)
diff --git a/src/services/attachment.ts b/src/services/attachment.ts
index 31f14ac..052a3f2 100644
--- a/src/services/attachment.ts
+++ b/src/services/attachment.ts
@@ -32,12 +32,12 @@ export interface SnAttachment {
metadata: Record
}
-async function getAttachment(id: string | number): Promise {
+export async function getAttachment(id: string | number): Promise {
const resp = await sni.get('/cgi/uc/attachments/' + id + '/meta')
return resp.data
}
-async function listAttachment(id: string[]): Promise {
+export async function listAttachment(id: string[]): Promise {
const resp = await sni.get<{ data: SnAttachment[] }>('/cgi/uc/attachments', {
params: {
id: id.join(','),