render image grid for admin file list

This commit is contained in:
Kieran 2023-05-29 15:08:59 +01:00
parent f724203a93
commit 0786c6830c
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 125 additions and 3 deletions

View File

@ -4,7 +4,6 @@ import {useSelector} from "react-redux";
import {Navigate} from "react-router-dom";
import {AdminProfile} from "@void-cat/api";
import {FileList} from "../Components/Shared/FileList";
import {UserList} from "./UserList";
import {VoidButton} from "../Components/Shared/VoidButton";
import VoidModal from "../Components/Shared/VoidModal";
@ -12,6 +11,7 @@ import EditUser from "./EditUser";
import useApi from "Hooks/UseApi";
import {RootState} from "Store";
import ImageGrid from "../Components/Shared/ImageGrid";
export function Admin() {
const auth = useSelector((state: RootState) => state.login.jwt);
@ -41,7 +41,7 @@ export function Admin() {
]}/>
<h2>Files</h2>
<FileList loadPage={r => AdminApi.adminListFiles(r)} actions={(i) => {
<ImageGrid loadPage={r => AdminApi.adminListFiles(r)} actions={(i) => {
return <td>
<VoidButton onClick={() => deleteFile(i.id)}>Delete</VoidButton>
</td>

View File

@ -65,7 +65,7 @@ export function FileList(props: FileListProps) {
loadFileList().catch(console.error)
}, [page]);
if (accessDenied === true) {
if (accessDenied) {
return <h3>Access Denied</h3>;
}

View File

@ -0,0 +1,18 @@
.image-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.image-grid > div {
width: 100px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-grid img, .image-grid video, .image-grid audio {
width: stretch;
}

View File

@ -0,0 +1,103 @@
import "./ImageGrid.css";
import {ApiError, PagedRequest, PagedResponse, PagedSortBy, PageSortOrder, VoidFileResponse} from "@void-cat/api";
import {ReactNode, useEffect, useState} from "react";
import {useDispatch} from "react-redux";
import {logout} from "../../LoginState";
import {PageSelector} from "./PageSelector";
import {useNavigate} from "react-router-dom";
interface ImageGridProps {
actions?: (f: VoidFileResponse) => ReactNode
loadPage: (req: PagedRequest) => Promise<PagedResponse<any>>
}
export default function ImageGrid(props: ImageGridProps) {
const navigate = useNavigate();
const loadPage = props.loadPage;
const actions = props.actions;
const dispatch = useDispatch();
const [files, setFiles] = useState<PagedResponse<VoidFileResponse>>();
const [page, setPage] = useState(0);
const pageSize = 20;
const [accessDenied, setAccessDenied] = useState<boolean>();
async function loadFileList() {
try {
const pageReq = {
page: page,
pageSize,
sortBy: PagedSortBy.Date,
sortOrder: PageSortOrder.Dsc
};
const rsp = await loadPage(pageReq);
setFiles(rsp);
} catch (e) {
console.error(e);
if (e instanceof ApiError) {
if (e.statusCode === 401) {
dispatch(logout());
} else if (e.statusCode === 403) {
setAccessDenied(true);
}
}
}
}
useEffect(() => {
loadFileList().catch(console.error)
}, [page]);
function renderPreview(info: VoidFileResponse) {
const link = `/d/${info.id}`;
if (info.metadata) {
switch (info.metadata.mimeType) {
case "image/avif":
case "image/bmp":
case "image/gif":
case "image/svg+xml":
case "image/tiff":
case "image/webp":
case "image/jpg":
case "image/jpeg":
case "image/png": {
return <img src={link} alt={info.metadata.name}/>;
}
case "audio/aac":
case "audio/opus":
case "audio/wav":
case "audio/webm":
case "audio/midi":
case "audio/mpeg":
case "audio/ogg": {
return <audio src={link} controls/>;
}
case "video/x-msvideo":
case "video/mpeg":
case "video/ogg":
case "video/mp2t":
case "video/mp4":
case "video/matroksa":
case "video/x-matroska":
case "video/webm":
case "video/quicktime": {
return <video src={link}/>;
}
default: {
return <b>{info.metadata?.name ?? info.id}</b>
}
}
}
}
return <>
<div className="image-grid">
{files?.results.map(v => <div key={v.id} onClick={() => navigate(`/${v.id}`)}>
{renderPreview(v)}
</div>)}
</div>
<PageSelector onSelectPage={(x) => setPage(x)} page={page} total={files?.totalResults ?? 0}
pageSize={pageSize}/>
</>
}

View File

@ -3,6 +3,7 @@
grid-auto-flow: column;
width: min-content;
margin-top: 10px;
white-space: nowrap;
}
.page-buttons > div {