mirror of
https://github.com/cloudreve/frontend.git
synced 2025-12-25 19:52:48 +00:00
151 lines
4.7 KiB
TypeScript
151 lines
4.7 KiB
TypeScript
import React, { useContext, useMemo } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Box, Grid, Stack, styled, Typography } from "@mui/material";
|
|
import { useAppSelector } from "../../../../redux/hooks.ts";
|
|
import { FileResponse, FileType } from "../../../../api/explorer.ts";
|
|
import DndWrappedFile from "../../Dnd/DndWrappedFile.tsx";
|
|
|
|
import { FmIndexContext } from "../../FmIndexContext.tsx";
|
|
import GridFile from "./GridFile.tsx";
|
|
|
|
export interface GridViewProps {
|
|
[key: string]: any;
|
|
}
|
|
|
|
export interface FmFile extends FileResponse {
|
|
id: string;
|
|
first?: boolean;
|
|
placeholder?: boolean;
|
|
}
|
|
|
|
interface listComponents {
|
|
Folders?: JSX.Element[];
|
|
Files: JSX.Element[];
|
|
}
|
|
|
|
const AutoFillGrid = styled(Grid)(({ theme }) => ({
|
|
[theme.breakpoints.down("md")]: {
|
|
gridTemplateColumns: "repeat(auto-fill,minmax(160px,1fr))!important",
|
|
},
|
|
[theme.breakpoints.up("md")]: {
|
|
gridTemplateColumns: "repeat(auto-fill,minmax(220px,1fr))!important",
|
|
},
|
|
gridGap: theme.spacing(2),
|
|
display: "grid!important",
|
|
padding: theme.spacing(1),
|
|
}));
|
|
|
|
const GridItem = styled(Grid)(() => ({
|
|
flex: "1 1 220px!important",
|
|
}));
|
|
|
|
export const loadingPlaceHolderNumb = 3;
|
|
|
|
const GridView = React.forwardRef(({ ...rest }: GridViewProps, ref) => {
|
|
const { t } = useTranslation("application");
|
|
const fmIndex = useContext(FmIndexContext);
|
|
const files = useAppSelector((state) => state.fileManager[fmIndex].list?.files);
|
|
const mixedType = useAppSelector((state) => state.fileManager[fmIndex].list?.mixed_type);
|
|
const pagination = useAppSelector((state) => state.fileManager[fmIndex].list?.pagination);
|
|
const showThumb = useAppSelector((state) => state.fileManager[fmIndex].showThumb);
|
|
const search_params = useAppSelector((state) => state.fileManager[fmIndex]?.search_params);
|
|
const list = useMemo(() => {
|
|
const list: listComponents = {
|
|
Files: [],
|
|
};
|
|
if (files) {
|
|
files.forEach((file, index) => {
|
|
if (file.type === FileType.folder && !mixedType) {
|
|
if (!list.Folders) {
|
|
list.Folders = [];
|
|
}
|
|
list.Folders.push(
|
|
<GridItem item key={`${file.id}`}>
|
|
<DndWrappedFile
|
|
component={GridFile}
|
|
search={search_params}
|
|
index={index}
|
|
showThumb={mixedType}
|
|
file={file}
|
|
/>
|
|
</GridItem>,
|
|
);
|
|
} else {
|
|
list.Files.push(
|
|
<GridItem item key={`${file.id}`}>
|
|
<DndWrappedFile
|
|
component={GridFile}
|
|
search={search_params}
|
|
index={index}
|
|
showThumb={showThumb}
|
|
file={file}
|
|
/>
|
|
</GridItem>,
|
|
);
|
|
}
|
|
});
|
|
|
|
// Add loading placeholder if there is next page
|
|
if (pagination && pagination.next_token) {
|
|
for (let i = 0; i < loadingPlaceHolderNumb; i++) {
|
|
const id = `loadingPlaceholder-${pagination.next_token}-${i}`;
|
|
const loadingPlaceholder = (
|
|
<GridItem item key={id}>
|
|
<DndWrappedFile
|
|
component={GridFile}
|
|
showThumb={list.Files.length > 0 ? showThumb : mixedType}
|
|
file={{
|
|
...files[0],
|
|
path: files[0].path + "/" + id,
|
|
id: `loadingPlaceholder-${pagination.next_token}-${i}`,
|
|
first: i == 0,
|
|
placeholder: true,
|
|
}}
|
|
/>
|
|
</GridItem>
|
|
);
|
|
const _ =
|
|
list.Files.length > 0 ? list.Files.push(loadingPlaceholder) : list.Folders?.push(loadingPlaceholder);
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}, [files, mixedType, pagination, showThumb]);
|
|
return (
|
|
<Box
|
|
ref={ref}
|
|
{...rest}
|
|
sx={{
|
|
p: 1,
|
|
}}
|
|
>
|
|
<Stack spacing={1}>
|
|
{list.Folders && list.Folders.length > 0 && (
|
|
<Box>
|
|
<Typography fontWeight={"medium"} sx={{ p: 1 }} variant="body2">
|
|
{t("fileManager.folders")}
|
|
</Typography>
|
|
<AutoFillGrid container alignItems="flex-start" spacing={0}>
|
|
{list.Folders.map((f) => f)}
|
|
</AutoFillGrid>
|
|
</Box>
|
|
)}
|
|
{list.Files.length > 0 && (
|
|
<Box>
|
|
{!mixedType && (
|
|
<Typography sx={{ p: 1 }} fontWeight={"medium"} variant="body2">
|
|
{t("fileManager.files")}
|
|
</Typography>
|
|
)}
|
|
<AutoFillGrid container alignItems="flex-start" spacing={0}>
|
|
{list.Files.map((f) => f)}
|
|
</AutoFillGrid>
|
|
</Box>
|
|
)}
|
|
</Stack>
|
|
</Box>
|
|
);
|
|
});
|
|
|
|
export default GridView;
|