最新分类版本

This commit is contained in:
2023-07-08 17:44:51 +08:00
parent fd0bdd7c12
commit fdf7493195
6 changed files with 215 additions and 70 deletions

25
src/CategoryNav.js Normal file
View File

@@ -0,0 +1,25 @@
import React from 'react';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
const CategoryNav = ({ categories, currentCategory, onCategoryChange }) => {
const handleChange = (event, newValue) => {
onCategoryChange(newValue);
};
return (
<Tabs
value={currentCategory}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
centered
>
{categories.map((category, idx) => (
<Tab key={category.label} label={category.label} value={idx} />
))}
</Tabs>
);
};
export default CategoryNav;

View File

@@ -9,13 +9,24 @@ import Typography from '@mui/material/Typography';
import Pagination from '@mui/material/Pagination';
import { Link } from 'react-router-dom';
import CircularProgress from '@mui/material/CircularProgress';
import ConfigContext from './Config';
import ConfigContext from './Config';
import MovieCard from './MovieCard';
import CategoryNav from './CategoryNav';
const Main = () => {
const config = useContext(ConfigContext);
const [currentCategory, setCurrentCategory] = useState(0);
const categories = [
{ label: '15min', idx: 0 },
{ label: '30min', idx: 1 },
{ label: '60min', idx: 2 },
{ label: '大于60min', idx: 3 },
];
const [pagination, setPagination] = useState({
movies: [],
page: 1,
@@ -25,24 +36,37 @@ const Main = () => {
const [loading, setLoading] = useState(false);
const limit = 12;
const limit = 20;
const fetchMovies = async (page) => {
const handleCategoryChange = (category) => {
setCurrentCategory(category);
fetchMovies(category, 1);
};
const fetchMovies = async (category, page) => {
setLoading(true);
try {
const response = await axios.get(
`${config.Host}/movie/?page=${page}&limit=${limit}`
`${config.Host}/movie/?page=${page}&limit=${limit}&category=${category}`
);
if (response.status === 200) {
const data = response.data.data;
setPagination({
movies: data.items,
page: page,
total: data.total,
length: Math.ceil(data.total / limit),
});
localStorage.setItem('lastPage', page);
console.log(`${config.Host}/movie/?page=${page}&limit=${limit}&category=${category}`);
if (data.items.length === 0 && page > 1) {
// 如果返回的数据为空且请求的页码大于1则尝试获取上一页的数据
fetchMovies(page - 1);
} else {
setPagination({
movies: data.items,
page: page,
total: data.total,
length: Math.ceil(data.total / limit),
});
localStorage.setItem('lastPage', page);
}
}
} catch (error) {
console.error('Error fetching movies:', error);
@@ -53,11 +77,11 @@ const Main = () => {
useEffect(() => {
const lastPage = localStorage.getItem('lastPage') || 1;
fetchMovies(lastPage);
fetchMovies(currentCategory, lastPage);
}, []);
const handlePageChange = (event, value) => {
fetchMovies(value);
fetchMovies(currentCategory, value);
};
const truncateFilename = (filename, maxLength) => {
@@ -65,9 +89,15 @@ const Main = () => {
? filename.substring(0, maxLength - 3) + '...'
: filename;
};
return (
<Container style={{ marginTop: 20 }}>
<CategoryNav
categories={categories}
currentCategory={currentCategory}
onCategoryChange={handleCategoryChange}
/>
<div style={{ textAlign: 'center', marginBottom: 20 }}>
<Pagination
count={pagination.length}
@@ -79,6 +109,8 @@ const Main = () => {
/>
</div>
<div>
{loading ? (
<div
@@ -92,50 +124,34 @@ const Main = () => {
<CircularProgress />
</div>
) : (
<Grid container spacing={2} style={{ marginTop: 3 }}>
{pagination.movies.map((item) => (
<Grid
item
xs={6}
sm={4}
md={3}
lg={2}
style={{ display: 'flex', justifyContent: 'space-between' }}
key={item.filename}
{pagination.movies.map((item) => (
<Grid
item
xs={6}
sm={4}
md={3}
lg={2}
style={{ display: 'flex', justifyContent: 'space-between' }}
key={item.filename}
>
<Link
to={`/res/${item.filename}`}
style={{ textDecoration: 'none', paddingBottom: 10 }}
>
<Link
to={`/res/${item.filename}`}
style={{ textDecoration: 'none', paddingBottom: 10 }}
>
<Card
style={{
width: '100%',
height: 200,
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
transition: 'box-shadow 0.3s ease-in-out',
'&:hover': {
boxShadow: '0 8px 12px rgba(0, 0, 0, 0.2)',
},
}}
>
<CardMedia
component="img"
height="120"
image={`${config.Host}/res/${item.image}`}
/>
<CardContent>
<Typography>
{truncateFilename(item.filename, 15)}
</Typography>
</CardContent>
</Card>
</Link>
</Grid>
))}
</Grid>
<MovieCard movie={item} config={config} />
</Link>
</Grid>
))}
</Grid>
)}
</div>
<div style={{ textAlign: 'center', marginTop: 20 }}>
<Pagination
count={pagination.length}

41
src/MovieCard.js Normal file
View File

@@ -0,0 +1,41 @@
import React from 'react';
import Card from '@mui/material/Card';
import CardMedia from '@mui/material/CardMedia';
import CardContent from '@mui/material/CardContent';
import Typography from '@mui/material/Typography';
const MovieCard = ({ movie, config }) => {
const truncateFilename = (filename, maxLength) => {
return filename.length > maxLength
? filename.substring(0, maxLength - 3) + '...'
: filename;
};
return (
<Card
style={{
width: '100%',
height: 200,
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
transition: 'box-shadow 0.3s ease-in-out',
'&:hover': {
boxShadow: '0 8px 12px rgba(0, 0, 0, 0.2)',
},
}}
>
<CardMedia
component="img"
height="120"
image={`${config.Host}/res/${movie.image}`}
/>
<CardContent>
<Typography>{truncateFilename(movie.filename, 15)}</Typography>
<Typography variant="body2" color="textSecondary">
时长: {movie.duration} min
</Typography>
</CardContent>
</Card>
);
};
export default MovieCard;

View File

@@ -16,6 +16,7 @@ const VideoPlayer = () => {
{filename}
</Typography>
<video
autoPlay={true}
controls
style={{ width: '100%', maxHeight: '70vh' }}
src={`${config.Host}/res/${filename}`}