diff --git a/bun.lockb b/bun.lockb
index 118717e..0bff6c7 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index 7d03859..0a1b8f7 100644
--- a/package.json
+++ b/package.json
@@ -13,11 +13,11 @@
"@emotion/react": "^11.14.0",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.14.0",
- "@mui/icons-material": "^6.3.0",
- "@mui/material": "^6.3.0",
+ "@mui/icons-material": "^6.3.1",
+ "@mui/material": "^6.3.1",
"@mui/material-nextjs": "^6.3.1",
"@mui/x-charts": "^7.23.2",
- "@tailwindcss/typography": "^0.5.15",
+ "@tailwindcss/typography": "^0.5.16",
"@vercel/speed-insights": "^1.1.0",
"animate.css": "^4.1.1",
"axios": "^1.7.9",
@@ -37,18 +37,18 @@
"remark-rehype": "^11.1.1",
"sitemap": "^8.0.0",
"unified": "^11.0.5",
- "zustand": "^5.0.2"
+ "zustand": "^5.0.3"
},
"devDependencies": {
- "typescript": "^5",
- "@types/node": "^20",
- "@types/react": "^19",
- "@types/react-dom": "^19",
- "postcss": "^8",
- "tailwindcss": "^3.4.1",
- "eslint": "^9",
+ "typescript": "^5.7.3",
+ "@types/node": "^20.17.12",
+ "@types/react": "^19.0.4",
+ "@types/react-dom": "^19.0.2",
+ "postcss": "^8.4.49",
+ "tailwindcss": "^3.4.17",
+ "eslint": "^9.17.0",
"eslint-config-next": "15.1.3",
- "@eslint/eslintrc": "^3"
+ "@eslint/eslintrc": "^3.2.0"
},
"trustedDependencies": [
"@vercel/speed-insights"
diff --git a/src/components/attachments/AttachmentItem.tsx b/src/components/attachments/AttachmentItem.tsx
index a4e1530..8dbc60a 100644
--- a/src/components/attachments/AttachmentItem.tsx
+++ b/src/components/attachments/AttachmentItem.tsx
@@ -4,18 +4,26 @@ import { QuestionMark } from '@mui/icons-material'
import { Link, Paper, Typography } from '@mui/material'
import { ComponentProps } from 'react'
-export function AttachmentItem({ item, ...rest }: { item: SnAttachment } & ComponentProps<'div'>) {
+export function AttachmentItem({
+ item,
+ borderRadius,
+ ...rest
+}: { item: SnAttachment; borderRadius?: string } & ComponentProps<'div'>) {
switch (item.mimetype.split('/')[0]) {
case 'image':
return (
-
+
)
case 'video':
return (
-
+
)
default:
diff --git a/src/pages/attachments/index.tsx b/src/pages/attachments/index.tsx
new file mode 100644
index 0000000..177d0a0
--- /dev/null
+++ b/src/pages/attachments/index.tsx
@@ -0,0 +1,62 @@
+import { AttachmentItem } from '@/components/attachments/AttachmentItem'
+import { SnAttachment } from '@/services/attachment'
+import { sni } from '@/services/network'
+import { Box, ImageList, ImageListItem, Pagination, useMediaQuery, useTheme } from '@mui/material'
+import { GetServerSideProps, InferGetServerSidePropsType } from 'next'
+import { useRouter } from 'next/router'
+
+export const getServerSideProps: GetServerSideProps = async (context) => {
+ let page: number = parseInt(context.query.page as string)
+ if (isNaN(page)) page = 1
+
+ const countPerPage = 20
+
+ const { data: resp } = await sni.get<{ data: SnAttachment[]; count: number }>('/cgi/uc/attachments', {
+ params: {
+ take: countPerPage,
+ offset: (page - 1) * countPerPage,
+ },
+ })
+
+ const attachments = resp.data
+
+ return { props: { attachments, page, pages: Math.ceil(resp.count / countPerPage) } }
+}
+
+export default function AttachmentsPage({
+ attachments,
+ page,
+ pages,
+}: InferGetServerSidePropsType) {
+ const router = useRouter()
+ const theme = useTheme()
+ const breakpoints = useMediaQuery(theme.breakpoints.up('md'))
+
+ return (
+
+
+ {attachments.map((item: SnAttachment) => (
+
+
+
+ ))}
+
+
+
+ router.push('/attachments?page=' + page)} />
+
+
+ )
+}
diff --git a/src/pages/posts/index.tsx b/src/pages/posts/index.tsx
index 32f3295..99d49d9 100644
--- a/src/pages/posts/index.tsx
+++ b/src/pages/posts/index.tsx
@@ -2,18 +2,7 @@ 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,
- Button,
- Container,
- Divider,
- Grid2 as Grid,
- Link,
- Pagination,
- Paper,
- Typography,
-} from '@mui/material'
+import { Avatar, Box, Container, Divider, Grid2 as Grid, Link, Pagination, Paper, Typography } from '@mui/material'
import { GetServerSideProps, InferGetServerSidePropsType } from 'next'
import NextLink from 'next/link'
import { useRouter } from 'next/router'