fix file dragndrop
This commit is contained in:
parent
2203ad6d23
commit
f6c8b3b13b
@ -13,344 +13,243 @@ import CloseBold from "@icons/CloseBold";
|
||||
import UploadIcon from "@icons/UploadIcon";
|
||||
|
||||
import { sendAnswer, sendFile } from "@api/quizRelase";
|
||||
import { useQuizData } from "@contexts/QuizDataContext";
|
||||
import Info from "@icons/Info";
|
||||
import type { UploadFileType } from "@model/questionTypes/file";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import type { DragEvent } from "react";
|
||||
import { useState, type ChangeEvent } from "react";
|
||||
import { useState } from "react";
|
||||
import { useRootContainerSize } from "../../../contexts/RootContainerWidthContext";
|
||||
import type { QuizQuestionFile } from "../../../model/questionTypes/file";
|
||||
import { useQuizData } from "@contexts/QuizDataContext";
|
||||
import { ACCEPT_SEND_FILE_TYPES_MAP, MAX_FILE_SIZE, UPLOAD_FILE_DESCRIPTIONS_MAP } from "../tools/fileUpload";
|
||||
|
||||
type ModalWarningType = "errorType" | "errorSize" | "picture" | "video" | "audio" | "document" | null;
|
||||
|
||||
type FileProps = {
|
||||
currentQuestion: QuizQuestionFile;
|
||||
};
|
||||
|
||||
const CurrentModal = ({ status }: { status: "errorType" | "errorSize" | "picture" | "video" | "audio" | "document" | ""; }) => {
|
||||
switch (status) {
|
||||
case 'errorType':
|
||||
return (<>
|
||||
<Typography>Выбран некорректный тип файла</Typography>
|
||||
</>);
|
||||
case 'errorSize':
|
||||
return (<>
|
||||
<Typography>Файл слишком большой. Максимальный размер 50 МБ</Typography>
|
||||
</>);
|
||||
default:
|
||||
return (<>
|
||||
<Typography>Допустимые расширения файлов:</Typography>
|
||||
<Typography>{
|
||||
//@ts-ignore
|
||||
ACCEPT_SEND_FILE_TYPES_MAP[status].join(" ")}</Typography>
|
||||
</>);
|
||||
}
|
||||
};
|
||||
|
||||
const ACCEPT_SEND_FILE_TYPES_MAP = {
|
||||
picture: [
|
||||
".jpeg",
|
||||
".jpg",
|
||||
".png",
|
||||
".ico",
|
||||
".gif",
|
||||
".tiff",
|
||||
".webp",
|
||||
".eps",
|
||||
".svg"
|
||||
],
|
||||
video: [
|
||||
".mp4",
|
||||
".mov",
|
||||
".wmv",
|
||||
".avi",
|
||||
".avchd",
|
||||
".flv",
|
||||
".f4v",
|
||||
".swf",
|
||||
".mkv",
|
||||
".webm",
|
||||
".mpeg-2"
|
||||
],
|
||||
audio: [
|
||||
".aac",
|
||||
".aiff",
|
||||
".dsd",
|
||||
".flac",
|
||||
".mp3",
|
||||
".mqa",
|
||||
".ogg",
|
||||
".wav",
|
||||
".wma"
|
||||
],
|
||||
document: [
|
||||
".doc",
|
||||
".docx",
|
||||
".dotx",
|
||||
".rtf",
|
||||
".odt",
|
||||
".pdf",
|
||||
".txt",
|
||||
".xls",
|
||||
".ppt",
|
||||
".xlsx",
|
||||
".pptx",
|
||||
".pages",
|
||||
],
|
||||
|
||||
};
|
||||
|
||||
|
||||
const UPLOAD_FILE_DESCRIPTIONS_MAP: Record<
|
||||
UploadFileType,
|
||||
{ title: string; description: string; }
|
||||
> = {
|
||||
picture: {
|
||||
title: "Добавить изображение",
|
||||
description: "Принимает изображения",
|
||||
},
|
||||
video: {
|
||||
title: "Добавить видео",
|
||||
description: "Принимает .mp4 и .mov формат — максимум 50мб",
|
||||
},
|
||||
audio: { title: "Добавить аудиофайл", description: "Принимает аудиофайлы" },
|
||||
document: { title: "Добавить документ", description: "Принимает документы" },
|
||||
} as const;
|
||||
|
||||
export const File = ({ currentQuestion }: FileProps) => {
|
||||
const theme = useTheme();
|
||||
const { answers } = useQuizViewStore();
|
||||
const { quizId } = useQuizData();
|
||||
const [statusModal, setStatusModal] = useState<"errorType" | "errorSize" | "picture" | "video" | "audio" | "document" | "">("");
|
||||
const [readySend, setReadySend] = useState(true)
|
||||
const [modalWarningType, setModalWarningType] = useState<ModalWarningType>(null);
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
const [isDropzoneHighlighted, setIsDropzoneHighlighted] = useState<boolean>(false);
|
||||
const isMobile = useRootContainerSize() < 500;
|
||||
|
||||
const answer = answers.find(
|
||||
({ questionId }) => questionId === currentQuestion.id
|
||||
)?.answer as string;
|
||||
const isMobile = useRootContainerSize() < 500;
|
||||
const uploadFile = async ({ target }: ChangeEvent<HTMLInputElement>) => {
|
||||
if (readySend) {
|
||||
setReadySend(false)
|
||||
const file = target.files?.[0];
|
||||
if (file) {
|
||||
if (file.size <= 52428800) {
|
||||
//проверяем на соответствие
|
||||
console.log(file.name.toLowerCase());
|
||||
if (ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].find((ednding => {
|
||||
console.log(ednding);
|
||||
console.log(file.name.toLowerCase().endsWith(ednding));
|
||||
return file.name.toLowerCase().endsWith(ednding);
|
||||
}))) {
|
||||
|
||||
//Нужный формат
|
||||
console.log(file);
|
||||
try {
|
||||
const uploadFile = async (file: File | undefined) => {
|
||||
if (isSending) return;
|
||||
if (!file) return;
|
||||
if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");
|
||||
|
||||
const data = await sendFile({
|
||||
questionId: currentQuestion.id,
|
||||
body: {
|
||||
file: file,
|
||||
name: file.name
|
||||
},
|
||||
qid: quizId,
|
||||
});
|
||||
console.log(data);
|
||||
const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].some(
|
||||
fileType => file.name.toLowerCase().endsWith(fileType)
|
||||
);
|
||||
|
||||
await sendAnswer({
|
||||
questionId: currentQuestion.id,
|
||||
body: `https://storage.yandexcloud.net/squizanswer/${quizId}/${currentQuestion.id}/${data.data.fileIDMap[currentQuestion.id]}`,
|
||||
qid: quizId,
|
||||
});
|
||||
if (!isFileTypeAccepted) return setModalWarningType("errorType");
|
||||
|
||||
updateAnswer(
|
||||
currentQuestion.id,
|
||||
`${file.name}|${URL.createObjectURL(file)}`,
|
||||
0
|
||||
);
|
||||
setIsSending(true);
|
||||
try {
|
||||
const data = await sendFile({
|
||||
questionId: currentQuestion.id,
|
||||
body: {
|
||||
file: file,
|
||||
name: file.name
|
||||
},
|
||||
qid: quizId,
|
||||
});
|
||||
console.log(data);
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
enqueueSnackbar("ответ не был засчитан");
|
||||
}
|
||||
await sendAnswer({
|
||||
questionId: currentQuestion.id,
|
||||
body: `https://storage.yandexcloud.net/squizanswer/${quizId}/${currentQuestion.id}/${data.data.fileIDMap[currentQuestion.id]}`,
|
||||
qid: quizId,
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
//неподходящий формат
|
||||
setStatusModal("errorType");
|
||||
}
|
||||
} else {
|
||||
|
||||
setStatusModal("errorSize");
|
||||
}
|
||||
|
||||
}
|
||||
setReadySend(true)
|
||||
updateAnswer(currentQuestion.id, `${file.name}|${URL.createObjectURL(file)}`, 0);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
enqueueSnackbar("ответ не был засчитан");
|
||||
}
|
||||
|
||||
setIsSending(false);
|
||||
};
|
||||
|
||||
const onDrop = (event: React.DragEvent<HTMLDivElement>) => {
|
||||
event.preventDefault();
|
||||
setIsDropzoneHighlighted(false);
|
||||
|
||||
const file = event.dataTransfer.files[0];
|
||||
|
||||
uploadFile(file);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Typography variant="h5" color={theme.palette.text.primary} sx={{ wordBreak: "break-word" }}>{currentQuestion.title}</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
marginTop: "20px",
|
||||
maxWidth: answer?.split("|")[0] ? "640px" : "600px",
|
||||
}}
|
||||
>
|
||||
{answer?.split("|")[0] && (
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "15px" }}>
|
||||
<Typography color={theme.palette.text.primary}>Вы загрузили:</Typography>
|
||||
<Box
|
||||
<Box>
|
||||
<Typography
|
||||
variant="h5"
|
||||
color={theme.palette.text.primary}
|
||||
sx={{ wordBreak: "break-word" }}
|
||||
>{currentQuestion.title}</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
marginTop: "20px",
|
||||
maxWidth: answer?.split("|")[0] ? "640px" : "600px",
|
||||
}}
|
||||
>
|
||||
{answer?.split("|")[0] ? (
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "15px" }}>
|
||||
<Typography color={theme.palette.text.primary}>Вы загрузили:</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
padding: "5px 5px 5px 16px",
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
borderRadius: "8px",
|
||||
color: "#FFFFFF",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
overflow: "hidden",
|
||||
gap: "15px",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
padding: "5px 5px 5px 16px",
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
borderRadius: "8px",
|
||||
color: "#FFFFFF",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
whiteSpace: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
gap: "15px",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
whiteSpace: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{answer?.split("|")[0]}</Typography>
|
||||
<IconButton
|
||||
sx={{ p: 0 }}
|
||||
onClick={async () => {
|
||||
if (answer.length > 0) {
|
||||
setReadySend(false)
|
||||
await sendAnswer({
|
||||
questionId: currentQuestion.id,
|
||||
body: "",
|
||||
qid: quizId,
|
||||
})
|
||||
}
|
||||
console.log(answer)
|
||||
updateAnswer(currentQuestion.id, "", 0);
|
||||
setReadySend(true)
|
||||
}}
|
||||
>
|
||||
<CloseBold />
|
||||
</IconButton>
|
||||
</Box>
|
||||
{answer?.split("|")[0]}</Typography>
|
||||
<IconButton
|
||||
sx={{ p: 0 }}
|
||||
onClick={async () => {
|
||||
if (answer.length > 0) {
|
||||
setIsSending(true);
|
||||
await sendAnswer({
|
||||
questionId: currentQuestion.id,
|
||||
body: "",
|
||||
qid: quizId,
|
||||
});
|
||||
}
|
||||
console.log(answer);
|
||||
updateAnswer(currentQuestion.id, "", 0);
|
||||
setIsSending(false);
|
||||
}}
|
||||
>
|
||||
<CloseBold />
|
||||
</IconButton>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{!answer?.split("|")[0] && (
|
||||
<Box sx={{
|
||||
</Box>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center"
|
||||
}}>
|
||||
{
|
||||
|
||||
readySend ? <>
|
||||
<ButtonBase component="label" sx={{ justifyContent: "flex-start", width: "100%" }}>
|
||||
<input
|
||||
onChange={uploadFile}
|
||||
hidden
|
||||
accept={ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].join(",")}
|
||||
multiple
|
||||
type="file"
|
||||
/>
|
||||
<Box
|
||||
onDragOver={(event: DragEvent<HTMLDivElement>) =>
|
||||
event.preventDefault()
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isSending ?
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "120px",
|
||||
maxWidth: "560px",
|
||||
}}
|
||||
/>
|
||||
:
|
||||
<ButtonBase
|
||||
component="label"
|
||||
sx={{ justifyContent: "flex-start", width: "100%" }}
|
||||
>
|
||||
<input
|
||||
onChange={e => uploadFile(e.target.files?.[0])}
|
||||
hidden
|
||||
accept={ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].join(",")}
|
||||
multiple
|
||||
type="file"
|
||||
/>
|
||||
<Box
|
||||
onDragEnter={() => !answer?.split("|")[0] && setIsDropzoneHighlighted(true)}
|
||||
onDragLeave={() => setIsDropzoneHighlighted(false)}
|
||||
onDragOver={(e) => e.preventDefault()}
|
||||
onDrop={onDrop}
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: isMobile ? undefined : "120px",
|
||||
display: "flex",
|
||||
gap: "50px",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
padding: "33px 44px 33px 55px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
border: `1px solid ${isDropzoneHighlighted ? "red" : "#9A9AAF"}`,
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
>
|
||||
<UploadIcon />
|
||||
<Box>
|
||||
<Typography
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: isMobile ? undefined : "120px",
|
||||
display: "flex",
|
||||
gap: "50px",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "center",
|
||||
padding: "33px 44px 33px 55px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
border: `1px solid #9A9AAF`,
|
||||
// border: `1px solid ${theme.palette.grey2.main}`,
|
||||
borderRadius: "8px",
|
||||
color: "#9A9AAF",
|
||||
// color: theme.palette.grey2.main,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
<UploadIcon />
|
||||
<Box>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#9A9AAF",
|
||||
// color: theme.palette.grey2.main,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{
|
||||
UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type]
|
||||
.title
|
||||
}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#9A9AAF",
|
||||
// color: theme.palette.grey2.main,
|
||||
fontSize: "16px",
|
||||
lineHeight: "19px",
|
||||
}}
|
||||
>
|
||||
{
|
||||
UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type]
|
||||
.description
|
||||
}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</ButtonBase>
|
||||
|
||||
|
||||
</> :
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "120px",
|
||||
maxWidth: "560px",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
<Info sx={{ width: "40px", height: "40px" }} color={theme.palette.primary.main} onClick={() => setStatusModal(currentQuestion.content.type)} />
|
||||
</Box>
|
||||
)}
|
||||
{answer && currentQuestion.content.type === "picture" && (
|
||||
<img
|
||||
src={answer.split("|")[1]}
|
||||
alt=""
|
||||
style={{
|
||||
marginTop: "15px",
|
||||
maxWidth: "300px",
|
||||
maxHeight: "300px",
|
||||
}}
|
||||
{UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type].title}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#9A9AAF",
|
||||
// color: theme.palette.grey2.main,
|
||||
fontSize: "16px",
|
||||
lineHeight: "19px",
|
||||
}}
|
||||
>
|
||||
{UPLOAD_FILE_DESCRIPTIONS_MAP[currentQuestion.content.type].description}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</ButtonBase>
|
||||
}
|
||||
<Info
|
||||
sx={{ width: "40px", height: "40px" }}
|
||||
color={theme.palette.primary.main}
|
||||
onClick={() => setModalWarningType(currentQuestion.content.type)}
|
||||
/>
|
||||
)}
|
||||
{answer && currentQuestion.content.type === "video" && (
|
||||
<video
|
||||
src={answer.split("|")[1]}
|
||||
style={{
|
||||
marginTop: "15px",
|
||||
maxWidth: "300px",
|
||||
maxHeight: "300px",
|
||||
objectFit: "cover",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
{answer && currentQuestion.content.type === "picture" && (
|
||||
<img
|
||||
src={answer.split("|")[1]}
|
||||
alt=""
|
||||
style={{
|
||||
marginTop: "15px",
|
||||
maxWidth: "300px",
|
||||
maxHeight: "300px",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{answer && currentQuestion.content.type === "video" && (
|
||||
<video
|
||||
src={answer.split("|")[1]}
|
||||
style={{
|
||||
marginTop: "15px",
|
||||
maxWidth: "300px",
|
||||
maxHeight: "300px",
|
||||
objectFit: "cover",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Modal
|
||||
open={Boolean(statusModal)}
|
||||
onClose={() => setStatusModal("")}
|
||||
open={modalWarningType !== null}
|
||||
onClose={() => setModalWarningType(null)}
|
||||
>
|
||||
<Box sx={{
|
||||
position: 'absolute',
|
||||
@ -363,10 +262,25 @@ export const File = ({ currentQuestion }: FileProps) => {
|
||||
boxShadow: 24,
|
||||
p: 4,
|
||||
}}>
|
||||
<CurrentModal status={statusModal} />
|
||||
<CurrentModal status={modalWarningType} />
|
||||
</Box>
|
||||
</Modal>
|
||||
</>
|
||||
</Box>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
const CurrentModal = ({ status }: { status: ModalWarningType; }) => {
|
||||
|
||||
switch (status) {
|
||||
case null: return null;
|
||||
case 'errorType': return <Typography>Выбран некорректный тип файла</Typography>;
|
||||
case 'errorSize': return <Typography>Файл слишком большой. Максимальный размер 50 МБ</Typography>;
|
||||
default: return (
|
||||
<>
|
||||
<Typography>Допустимые расширения файлов:</Typography>
|
||||
<Typography>{
|
||||
ACCEPT_SEND_FILE_TYPES_MAP[status].join(" ")}</Typography>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -1,63 +0,0 @@
|
||||
import { ChangeEvent, useEffect, useRef, useState } from "react";
|
||||
import { Box, Button, Typography } from "@mui/material";
|
||||
|
||||
import type {
|
||||
QuizQuestionFile,
|
||||
UploadFileType,
|
||||
} from "@model/questionTypes/file";
|
||||
|
||||
const UPLOAD_FILE_TYPES_MAP: Record<UploadFileType, string> = {
|
||||
picture: "image/*",
|
||||
video: "video/*",
|
||||
audio: "audio/*",
|
||||
document:
|
||||
".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,.pdf",
|
||||
} as const;
|
||||
|
||||
interface Props {
|
||||
question: QuizQuestionFile;
|
||||
}
|
||||
|
||||
export default function File({ question }: Props) {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [acceptedType, setAcceptedType] = useState<any>(
|
||||
UPLOAD_FILE_TYPES_MAP.picture
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setAcceptedType(UPLOAD_FILE_TYPES_MAP[question.content.type]);
|
||||
}, [question.content.type]);
|
||||
|
||||
function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
|
||||
if (!event.target.files?.[0]) return setFile(null);
|
||||
setFile(event.target.files[0]);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "start",
|
||||
gap: 1,
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6" data-cy="question-title">{question.title}</Typography>
|
||||
<Button variant="contained" onClick={() => fileInputRef.current?.click()}>
|
||||
Загрузить файл
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
onChange={handleFileChange}
|
||||
type="file"
|
||||
accept={acceptedType}
|
||||
data-cy="file-upload-input"
|
||||
style={{
|
||||
display: "none",
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
{file && <Typography data-cy="chosen-file-name">Выбран файл: {file.name}</Typography>}
|
||||
</Box>
|
||||
);
|
||||
}
|
69
lib/components/ViewPublicationPage/tools/fileUpload.ts
Normal file
69
lib/components/ViewPublicationPage/tools/fileUpload.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { UploadFileType } from "@model/questionTypes/file";
|
||||
|
||||
|
||||
export const MAX_FILE_SIZE = 5 * 2 ** 20;
|
||||
|
||||
export const UPLOAD_FILE_DESCRIPTIONS_MAP = {
|
||||
picture: {
|
||||
title: "Добавить изображение",
|
||||
description: "Принимает изображения",
|
||||
},
|
||||
video: {
|
||||
title: "Добавить видео",
|
||||
description: "Принимает .mp4 и .mov формат — максимум 50мб",
|
||||
},
|
||||
audio: { title: "Добавить аудиофайл", description: "Принимает аудиофайлы" },
|
||||
document: { title: "Добавить документ", description: "Принимает документы" },
|
||||
} as const satisfies Record<UploadFileType, { title: string; description: string; }>;
|
||||
|
||||
export const ACCEPT_SEND_FILE_TYPES_MAP = {
|
||||
picture: [
|
||||
".jpeg",
|
||||
".jpg",
|
||||
".png",
|
||||
".ico",
|
||||
".gif",
|
||||
".tiff",
|
||||
".webp",
|
||||
".eps",
|
||||
".svg"
|
||||
],
|
||||
video: [
|
||||
".mp4",
|
||||
".mov",
|
||||
".wmv",
|
||||
".avi",
|
||||
".avchd",
|
||||
".flv",
|
||||
".f4v",
|
||||
".swf",
|
||||
".mkv",
|
||||
".webm",
|
||||
".mpeg-2"
|
||||
],
|
||||
audio: [
|
||||
".aac",
|
||||
".aiff",
|
||||
".dsd",
|
||||
".flac",
|
||||
".mp3",
|
||||
".mqa",
|
||||
".ogg",
|
||||
".wav",
|
||||
".wma"
|
||||
],
|
||||
document: [
|
||||
".doc",
|
||||
".docx",
|
||||
".dotx",
|
||||
".rtf",
|
||||
".odt",
|
||||
".pdf",
|
||||
".txt",
|
||||
".xls",
|
||||
".ppt",
|
||||
".xlsx",
|
||||
".pptx",
|
||||
".pages",
|
||||
],
|
||||
} as const;
|
Loading…
Reference in New Issue
Block a user