refactor: add use-download-files hook for downloading files on chat (#3399)

* feat: add useGetDownloadFileMutation hook for downloading files

This commit adds a new hook called useGetDownloadFileMutation to handle the downloading of files in the frontend. The hook takes in the path and filename as parameters and uses the fetch API to download the file. It then creates a URL object for the downloaded file and sets it as the href of a dynamically created anchor element. Finally, it triggers a click event on the anchor element to initiate the file download. The URL object is revoked after the download is complete.

* feat: add use-download-files hook for downloading files on chat

This commit adds a new hook called use-download-files to handle the downloading of files in the frontend. The hook takes in the path and filename as parameters and uses the fetch API to download the file. It then creates a URL object for the downloaded file and sets it as the href of a dynamically created anchor element. Finally, it triggers a click event on the anchor element to initiate the file download. The URL object is revoked after the download is complete.

* [autofix.ci] apply automated fixes

* feat: refactor file download handling in chat view

Refactor the file download handling in the chat view by introducing a new hook called `use-download-files`. This hook takes in the path and filename as parameters and uses the fetch API to download the file. It creates a URL object for the downloaded file and sets it as the href of a dynamically created anchor element. Finally, it triggers a click event on the anchor element to initiate the file download. The URL object is revoked after the download is complete.

* remove console.log

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com>
This commit is contained in:
anovazzi1 2024-08-19 10:06:40 -03:00 committed by GitHub
commit 0f2729da8d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 58 additions and 56 deletions

View file

@ -1,3 +1,4 @@
export * from "./use-download-files";
export * from "./use-get-download-images";
export * from "./use-get-profile-pictures";
export * from "./use-post-upload-file";

View file

@ -0,0 +1,45 @@
import { keepPreviousData } from "@tanstack/react-query";
import {
useMutationFunctionType,
useQueryFunctionType,
} from "../../../../types/api";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";
interface DownloadImagesQueryParams {
path: string;
filename: string;
}
export const useGetDownloadFileMutation: useMutationFunctionType<
DownloadImagesQueryParams
> = (params, options) => {
const { mutate } = UseRequestProcessor();
const getDownloadImagesFn = async () => {
if (!params) return;
// need to use fetch because axios convert blob data to string, and this convertion can corrupt the file
const response = await fetch(`${getURL("FILES")}/download/${params.path}`);
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", params.filename); // Set the filename
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
return {};
};
const queryResult = mutate(
["useGetDownloadFileMutation", params.path],
getDownloadImagesFn,
options,
);
return queryResult;
};

View file

@ -24,12 +24,7 @@ export default function FileCardWrapper({
{formatFileName(name, 50)}
<ForwardedIconComponent name={show ? "ChevronDown" : "ChevronRight"} />
</span>
<FileCard
showFile={show}
fileName={name}
fileType={type}
content={path}
/>
<FileCard showFile={show} fileName={name} fileType={type} path={path} />
</div>
);
}

View file

@ -1,3 +1,4 @@
import { useGetDownloadFileMutation } from "@/controllers/API/queries/files";
import { useState } from "react";
import { ForwardedIconComponent } from "../../../../../components/genericIconComponent";
import { BACKEND_URL, BASE_URL_API } from "../../../../../constants/constants";
@ -6,18 +7,20 @@ import { fileCardPropsType } from "../../../../../types/components";
import formatFileName from "../filePreviewChat/utils/format-file-name";
import DownloadButton from "./components/downloadButton/downloadButton";
import getClasses from "./utils/get-classes";
import handleDownload from "./utils/handle-download";
const imgTypes = new Set(["png", "jpg", "jpeg", "gif", "webp", "image"]);
export default function FileCard({
fileName,
content,
path,
fileType,
showFile = true,
}: fileCardPropsType): JSX.Element | undefined {
const [isHovered, setIsHovered] = useState(false);
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
const { mutate } = useGetDownloadFileMutation({
filename: fileName,
path: path,
});
function handleMouseEnter(): void {
setIsHovered(true);
}
@ -27,7 +30,7 @@ export default function FileCard({
const fileWrapperClasses = getClasses(isHovered);
const imgSrc = `${BASE_URL_API}files/images/${content}`;
const imgSrc = `${BASE_URL_API}files/images/${path}`;
if (showFile) {
if (imgTypes.has(fileType)) {
@ -46,7 +49,7 @@ export default function FileCard({
/>
<DownloadButton
isHovered={isHovered}
handleDownload={() => handleDownload({ fileName, content })}
handleDownload={() => mutate(undefined)}
/>
</div>
</div>
@ -56,7 +59,7 @@ export default function FileCard({
return (
<div
className={fileWrapperClasses}
onClick={() => handleDownload({ fileName, content })}
onClick={() => mutate(undefined)}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
@ -69,7 +72,7 @@ export default function FileCard({
</div>
<DownloadButton
isHovered={isHovered}
handleDownload={() => handleDownload({ fileName, content })}
handleDownload={() => mutate(undefined)}
/>
</div>
);

View file

@ -1,41 +0,0 @@
import {
BACKEND_URL,
BASE_URL_API,
} from "../../../../../../constants/constants";
let isDownloading = false;
export default async function handleDownload({
fileName,
content,
}: {
fileName: string;
content: string;
}): Promise<void> {
if (isDownloading) return;
try {
isDownloading = true;
const response = await fetch(`${BASE_URL_API}files/download/${content}`);
if (!response.ok) {
throw new Error("Network response was not ok");
}
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", fileName); // Set the filename
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url); // Clean up the URL object
} catch (error) {
console.error("Failed to download file:", error);
} finally {
isDownloading = false;
}
}

View file

@ -80,7 +80,6 @@ export default function ChatView({
const is_ai =
sender === "Machine" || sender === null || sender === undefined;
return {
isSend: !is_ai,
message,

View file

@ -617,7 +617,7 @@ export interface Props {
export type fileCardPropsType = {
fileName: string;
content: string;
path: string;
fileType: string;
showFile?: boolean;
};