Attachment list (Gallery)

This commit is contained in:
LittleSheep 2025-01-09 21:18:19 +08:00
parent 94ae812822
commit eaef7f304c
5 changed files with 86 additions and 27 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -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"

View File

@ -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 (
<Paper {...rest}>
<img src={getAttachmentUrl(item.rid)} alt={item.alt} style={{ objectFit: 'cover', borderRadius: '8px' }} />
<img
src={getAttachmentUrl(item.rid)}
alt={item.alt}
style={{ objectFit: 'cover', borderRadius: borderRadius ?? '8px' }}
/>
</Paper>
)
case 'video':
return (
<Paper {...rest}>
<video src={getAttachmentUrl(item.rid)} controls style={{ borderRadius: '8px' }} />
<video src={getAttachmentUrl(item.rid)} controls style={{ borderRadius: borderRadius ?? '8px' }} />
</Paper>
)
default:

View File

@ -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<typeof getServerSideProps>) {
const router = useRouter()
const theme = useTheme()
const breakpoints = useMediaQuery(theme.breakpoints.up('md'))
return (
<Box>
<ImageList variant="masonry" cols={breakpoints ? 3 : 2} gap={8} sx={{ mx: 2 }}>
{attachments.map((item: SnAttachment) => (
<ImageListItem key={item.rid}>
<AttachmentItem item={item} borderRadius="0" />
</ImageListItem>
))}
</ImageList>
<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('/attachments?page=' + page)} />
</Box>
</Box>
)
}

View File

@ -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'