diff --git a/src/components/FileMessage/AudioMessage.tsx b/src/components/FileMessage/AudioMessage.tsx
index ea68b818..cbc88cd0 100644
--- a/src/components/FileMessage/AudioMessage.tsx
+++ b/src/components/FileMessage/AudioMessage.tsx
@@ -4,6 +4,7 @@ import clsx from "clsx";
import IconDownload from "@/assets/icons/download.svg";
import IconAudio from "@/assets/icons/file.audio.svg";
import { formatBytes } from "../../utils";
+import { ExpireTip } from "./OtherFileMessage";
type Props = {
url: string;
@@ -14,32 +15,51 @@ type Props = {
const AudioMessage = ({ url, name, size, download }: Props) => {
const [canPlay, setCanPlay] = useState(false);
+ const [error, setError] = useState(false);
const handleCanPlay = () => {
setCanPlay(true);
};
+ const handleError = () => {
+ setError(true);
+ };
const _size = formatBytes(size);
return (
-
+
-
-
-
+ {error ? (
+
+ ) : (
+
+
+
+ )}
-
+ {!error && (
+
+ )}
);
};
diff --git a/src/components/FileMessage/OtherFileMessage.tsx b/src/components/FileMessage/OtherFileMessage.tsx
new file mode 100644
index 00000000..53c94cf5
--- /dev/null
+++ b/src/components/FileMessage/OtherFileMessage.tsx
@@ -0,0 +1,116 @@
+import { useEffect, useState } from "react";
+import { useTranslation } from "react-i18next";
+import clsx from "clsx";
+
+import { User } from "@/types/user";
+import { formatBytes, fromNowTime, getFileIcon } from "@/utils";
+import IconClose from "@/assets/icons/close.circle.svg";
+import IconDownload from "@/assets/icons/download.svg";
+import IconInfo from "@/assets/icons/info.svg";
+import Progress from "./Progress";
+
+const ExpireTip = () => {
+ const { t } = useTranslation("chat");
+ return (
+
+ {t("file_expired")}
+
+ );
+};
+
+type Props = {
+ content: string;
+ sending: boolean;
+ content_type: string;
+ name: string;
+ progress: number;
+ size: number;
+ created_at: number;
+ from_user: User;
+ handleCancel: () => void;
+};
+
+const OtherFileMessage = ({
+ content,
+ sending,
+ content_type,
+ name,
+ progress,
+ size,
+ created_at,
+ from_user,
+ handleCancel
+}: Props) => {
+ const [error, setError] = useState(false);
+ const icon = getFileIcon(content_type, name, "w-9 h-auto");
+ useEffect(() => {
+ if (content) {
+ fetch(content)
+ .then((resp) => {
+ console.log("fetch", resp.status);
+ if (resp.status >= 400) {
+ setError(true);
+ }
+ })
+ .catch((error) => {
+ console.log("fetch error", error);
+ setError(true);
+ });
+ }
+ }, [content]);
+
+ return (
+
+
+ {icon}
+
+
+ {name}
+
+
+ {sending ? (
+
+ ) : (
+ <>
+ {formatBytes(size)}
+ {fromNowTime(created_at)}
+ {from_user && (
+
+ by {from_user.name}
+
+ )}
+ >
+ )}
+
+
+ {sending ? (
+
+ ) : error ? (
+
+ ) : (
+
+
+
+ )}
+
+
+ );
+};
+
+export default OtherFileMessage;
+export { ExpireTip };
diff --git a/src/components/FileMessage/VideoMessage.tsx b/src/components/FileMessage/VideoMessage.tsx
index 14458ad6..6fbad18b 100644
--- a/src/components/FileMessage/VideoMessage.tsx
+++ b/src/components/FileMessage/VideoMessage.tsx
@@ -1,9 +1,11 @@
import { SyntheticEvent, useState } from "react";
import { Orbit } from "@uiball/loaders";
+import clsx from "clsx";
import IconDownload from "@/assets/icons/download.svg";
import IconVideo from "@/assets/icons/file.video.svg";
import { formatBytes } from "../../utils";
+import { ExpireTip } from "./OtherFileMessage";
// import clsx from 'clsx';
@@ -39,39 +41,63 @@ const VideoMessage = ({ url, name, size, download }: Props) => {
};
const tipClass = "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2";
return (
-
-
-
+
+ {!error && (
+
+ )}
+
-
-
-
+ {error ? (
+
+ ) : (
+
+
+
+ )}
- {!canPlay ? (
+ {!canPlay && !error ? (
- ) : error ? (
-
Error
) : null}
-
+ {!error && (
+
+ )}
);
};
diff --git a/src/components/FileMessage/index.tsx b/src/components/FileMessage/index.tsx
index 60a4645a..a7a66f55 100644
--- a/src/components/FileMessage/index.tsx
+++ b/src/components/FileMessage/index.tsx
@@ -1,17 +1,14 @@
import { FC, useEffect, useState } from "react";
-import clsx from "clsx";
import { useAppSelector } from "@/app/store";
import { ChatContext } from "@/types/common";
import useRemoveLocalMessage from "@/hooks/useRemoveLocalMessage";
import useSendMessage from "@/hooks/useSendMessage";
import useUploadFile from "@/hooks/useUploadFile";
-import { formatBytes, fromNowTime, getFileIcon, getImageSize, isImage } from "@/utils";
-import IconClose from "@/assets/icons/close.circle.svg";
-import IconDownload from "@/assets/icons/download.svg";
+import { getImageSize, isImage } from "@/utils";
import AudioMessage from "./AudioMessage";
import ImageMessage from "./ImageMessage";
-import Progress from "./Progress";
+import OtherFileMessage from "./OtherFileMessage";
import VideoMessage from "./VideoMessage";
const isLocalFile = (content: string) => {
@@ -133,7 +130,6 @@ const FileMessage: FC
= ({
}, [sendMessageSuccess, content]);
if (!properties) return null;
- const icon = getFileIcon(content_type, name, "w-9 h-auto");
if (!content || !name) return null;
@@ -151,6 +147,7 @@ const FileMessage: FC = ({
thumbnail={thumbnail}
/>
);
+
// video
if (content_type.startsWith("video") && !sending)
return ;
@@ -158,47 +155,17 @@ const FileMessage: FC = ({
if (content_type.startsWith("audio") && !sending)
return ;
return (
-
-
- {icon}
-
-
- {name}
-
-
- {sending ? (
-
- ) : (
- <>
- {formatBytes(size)}
- {fromNowTime(created_at)}
- {fromUser && (
-
- by {fromUser.name}
-
- )}
- >
- )}
-
-
- {sending ? (
-
- ) : (
-
-
-
- )}
-
-
+
);
};