mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-17 19:37:02 +00:00
feat: support multi files upload
This commit is contained in:
@@ -38,12 +38,16 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||
const { ticketId } = req.params;
|
||||
const { body }: MessageData = req.body;
|
||||
const media = req.file;
|
||||
const medias = req.files as Express.Multer.File[];
|
||||
|
||||
const ticket = await ShowTicketService(ticketId);
|
||||
|
||||
if (media) {
|
||||
await SendWhatsAppMedia({ media, ticket });
|
||||
if (medias) {
|
||||
await Promise.all(
|
||||
medias.map(async (media: Express.Multer.File) => {
|
||||
await SendWhatsAppMedia({ media, ticket });
|
||||
})
|
||||
);
|
||||
} else {
|
||||
await SendWhatsAppMessage({ body, ticket });
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import { Router } from "express";
|
||||
import multer from "multer";
|
||||
import isAuth from "../middleware/isAuth";
|
||||
import uploadConfig from "../config/upload";
|
||||
|
||||
import * as MessageController from "../controllers/MessageController";
|
||||
|
||||
const messageRoutes = Router();
|
||||
|
||||
const upload = multer(uploadConfig);
|
||||
|
||||
messageRoutes.get("/messages/:ticketId", isAuth, MessageController.index);
|
||||
|
||||
messageRoutes.post("/messages/:ticketId", isAuth, MessageController.store);
|
||||
messageRoutes.post(
|
||||
"/messages/:ticketId",
|
||||
isAuth,
|
||||
upload.array("medias"),
|
||||
MessageController.store
|
||||
);
|
||||
|
||||
messageRoutes.delete("/messages/:messageId", isAuth, MessageController.remove);
|
||||
|
||||
|
||||
@@ -4,11 +4,10 @@ import "express-async-errors";
|
||||
import express, { Request, Response, NextFunction } from "express";
|
||||
import cors from "cors";
|
||||
import cookieParser from "cookie-parser";
|
||||
import multer from "multer";
|
||||
import * as Sentry from "@sentry/node";
|
||||
|
||||
import "./database";
|
||||
import uploadConfig from "./config/upload";
|
||||
import "./database";
|
||||
import AppError from "./errors/AppError";
|
||||
import routes from "./routes";
|
||||
import { initIO } from "./libs/socket";
|
||||
@@ -16,7 +15,6 @@ import { StartWhatsAppSessions } from "./services/WbotServices/StartWhatsAppSess
|
||||
|
||||
Sentry.init({ dsn: process.env.SENTRY_DSN });
|
||||
|
||||
const upload = multer(uploadConfig);
|
||||
const app = express();
|
||||
|
||||
app.use(
|
||||
@@ -28,7 +26,6 @@ app.use(
|
||||
app.use(cookieParser());
|
||||
app.use(express.json());
|
||||
app.use(Sentry.Handlers.requestHandler());
|
||||
app.use(upload.single("media"));
|
||||
app.use("/public", express.static(uploadConfig.directory));
|
||||
app.use(routes);
|
||||
|
||||
|
||||
@@ -109,8 +109,7 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
const { ticketId } = useParams();
|
||||
const username = localStorage.getItem("username");
|
||||
|
||||
const mediaInitialState = { preview: "", raw: "", name: "" };
|
||||
const [media, setMedia] = useState(mediaInitialState);
|
||||
const [medias, setMedias] = useState([]);
|
||||
const [inputMessage, setInputMessage] = useState("");
|
||||
const [showEmoji, setShowEmoji] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -120,7 +119,7 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
return () => {
|
||||
setInputMessage("");
|
||||
setShowEmoji(false);
|
||||
setMedia({});
|
||||
setMedias([]);
|
||||
};
|
||||
}, [ticketId]);
|
||||
|
||||
@@ -133,23 +132,18 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
setInputMessage(prevState => prevState + emoji);
|
||||
};
|
||||
|
||||
const handleChangeMedia = e => {
|
||||
if (e.target.files.length) {
|
||||
setMedia({
|
||||
preview: URL.createObjectURL(e.target.files[0]),
|
||||
raw: e.target.files[0],
|
||||
name: e.target.files[0].name,
|
||||
});
|
||||
const handleChangeMedias = e => {
|
||||
if (!e.target.files) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedMedias = Array.from(e.target.files);
|
||||
setMedias(selectedMedias);
|
||||
};
|
||||
|
||||
const handleInputPaste = e => {
|
||||
if (e.clipboardData.files[0]) {
|
||||
setMedia({
|
||||
preview: URL.createObjectURL(e.clipboardData.files[0]),
|
||||
raw: e.clipboardData.files[0],
|
||||
name: e.clipboardData.files[0].name,
|
||||
});
|
||||
setMedias([e.clipboardData.files[0]]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -158,9 +152,11 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("media", media.raw);
|
||||
formData.append("fromMe", true);
|
||||
formData.append("body", media.name);
|
||||
medias.forEach(media => {
|
||||
formData.append("medias", media);
|
||||
formData.append("body", media.name);
|
||||
});
|
||||
|
||||
try {
|
||||
await api.post(`/messages/${ticketId}`, formData);
|
||||
@@ -178,7 +174,7 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
setMedia(mediaInitialState);
|
||||
setMedias([]);
|
||||
};
|
||||
|
||||
const handleSendMessage = async () => {
|
||||
@@ -267,13 +263,13 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
}
|
||||
};
|
||||
|
||||
if (media.preview)
|
||||
if (medias.length > 0)
|
||||
return (
|
||||
<Paper elevation={0} square className={classes.viewMediaInputWrapper}>
|
||||
<IconButton
|
||||
aria-label="cancel-upload"
|
||||
component="span"
|
||||
onClick={e => setMedia(mediaInitialState)}
|
||||
onClick={e => setMedias([])}
|
||||
>
|
||||
<CancelIcon className={classes.sendMessageIcons} />
|
||||
</IconButton>
|
||||
@@ -284,7 +280,7 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
</div>
|
||||
) : (
|
||||
<span>
|
||||
{media.name}
|
||||
{medias[0]?.name}
|
||||
{/* <img src={media.preview} alt=""></img> */}
|
||||
</span>
|
||||
)}
|
||||
@@ -321,11 +317,12 @@ const MessageInput = ({ ticketStatus }) => {
|
||||
) : null}
|
||||
|
||||
<input
|
||||
multiple
|
||||
type="file"
|
||||
id="upload-button"
|
||||
disabled={loading || recording || ticketStatus !== "open"}
|
||||
className={classes.uploadInput}
|
||||
onChange={handleChangeMedia}
|
||||
onChange={handleChangeMedias}
|
||||
/>
|
||||
<label htmlFor="upload-button">
|
||||
<IconButton
|
||||
|
||||
Reference in New Issue
Block a user