From 1209e9d0952af56218a75e2bda5867d5fe7611fd Mon Sep 17 00:00:00 2001 From: Tristan Yang Date: Tue, 30 May 2023 17:39:37 +0800 Subject: [PATCH] feat: file expired tip --- src/components/FileMessage/AudioMessage.tsx | 42 +++++-- .../FileMessage/OtherFileMessage.tsx | 116 ++++++++++++++++++ src/components/FileMessage/VideoMessage.tsx | 66 +++++++--- src/components/FileMessage/index.tsx | 61 +++------ 4 files changed, 207 insertions(+), 78 deletions(-) create mode 100644 src/components/FileMessage/OtherFileMessage.tsx 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 ( -
+
- + {name} {_size}
- - - + {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 && ( +
+ )} +
- + {name} {_size}
- - - + {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 ? ( - - ) : ( - - - - )} -
-
+ ); };