refactor: audio and video message

This commit is contained in:
Tristan Yang
2022-12-12 19:51:55 +08:00
parent 6cc7bc466b
commit d9d175375d
6 changed files with 112 additions and 4 deletions
@@ -0,0 +1,32 @@
// import { useState } from 'react';
import { formatBytes } from '../../utils';
import IconDownload from "../../../assets/icons/download.svg";
import IconAudio from "../../../assets/icons/file.audio.svg";
type Props = {
url: string,
name: string,
size: number,
download: string
}
const AudioMessage = ({ url, name, size, download }: Props) => {
const _size = formatBytes(size);
return (
<div className='w-96 flex flex-col gap-2 px-3 py-2 rounded-md border border-solid border-gray-300 overflow-hidden bg-[#f1f3f4]'>
<div className="flex justify-between z-30 overflow-hidden">
<div className="flex gap-2 ">
<IconAudio className="w-9 h-auto" />
<div className="flex flex-col gap-1 text-sm text-gray-700">
<span title={name} className='font-bold whitespace-nowrap text-ellipsis w-[240px] overflow-hidden'>{name}</span>
<span>{_size}</span>
</div>
</div>
<a href={download} className="mt-2"><IconDownload className="download_icon gray" /></a>
</div>
<audio src={url} controls className="w-full object-cover z-10" />
</div>
);
};
export default AudioMessage;
@@ -0,0 +1,44 @@
import { useState } from 'react';
import { formatBytes } from '../../utils';
import IconDownload from "../../../assets/icons/download.svg";
import IconVideo from "../../../assets/icons/file.video.svg";
type Props = {
url: string,
name: string,
size: number,
download: string
}
const VideoMessage = ({ url, name, size, download }: Props) => {
const [playing, setPlaying] = useState(false);
const _size = formatBytes(size);
const handlePlaying = () => {
setPlaying(true);
};
const handlePause = () => {
setPlaying(false);
};
return (
<div className='w-96 h-52 relative rounded-md border border-solid border-gray-300 overflow-hidden group'>
{!playing &&
<>
<div className="absolute top-0 left-0 w-full h-full bg-black/40 z-20 group-hover:hidden"></div>
<div className="absolute top-0 left-0 w-full flex justify-between z-30 px-3 py-2 overflow-hidden group-hover:bg-black/20">
<div className="flex gap-2 ">
<IconVideo className="w-9 h-auto" />
<div className="flex flex-col gap-1 text-sm text-white">
<span title={name} className='font-bold whitespace-nowrap text-ellipsis w-[240px] overflow-hidden'>{name}</span>
<span>{_size}</span>
</div>
</div>
<a href={download} className="mt-2"><IconDownload className="fill-white" /></a>
</div>
</>
}
<video onPlaying={handlePlaying} onPause={handlePause} src={url} controls className="absolute left-0 top-0 w-full h-full object-cover z-10" />
</div>
);
};
export default VideoMessage;
+25 -3
View File
@@ -6,10 +6,12 @@ import useRemoveLocalMessage from "../../hook/useRemoveLocalMessage";
import useUploadFile from "../../hook/useUploadFile";
import useSendMessage from "../../hook/useSendMessage";
import Progress from "./Progress";
import { getFileIcon, formatBytes, isImage, getImageSize, ImageSize } from "../../utils";
import { getFileIcon, formatBytes, isImage, getImageSize } from "../../utils";
import { useAppSelector } from "../../../app/store";
import IconDownload from "../../../assets/icons/download.svg";
import IconClose from "../../../assets/icons/close.circle.svg";
import VideoMessage from "./VideoMessage";
import AudioMessage from "./AudioMessage";
const isLocalFile = (content: string) => {
return content.startsWith("blob:");
@@ -41,7 +43,7 @@ const FileMessage: FC<Props> = ({
thumbnail = "",
properties = { local_id: 0, name: "", size: 0, content_type: "" }
}) => {
const [imageSize, setImageSize] = useState<ImageSize | null>(null);
const [imageSize, setImageSize] = useState(null);
const [uploadingFile, setUploadingFile] = useState(false);
const removeLocalMessage = useRemoveLocalMessage({ context, id: to });
const {
@@ -120,7 +122,7 @@ const FileMessage: FC<Props> = ({
if (!content || !name) return null;
const sending = uploadingFile || isSending;
// image
if (isImage(content_type, size))
return (
<ImageMessage
@@ -133,6 +135,26 @@ const FileMessage: FC<Props> = ({
thumbnail={thumbnail}
/>
);
// video
if (content_type.startsWith("video") && !sending)
return (
<VideoMessage
size={size}
url={content}
name={name}
download={download}
/>
);
// audio
if (content_type.startsWith("audio") && !sending)
return (
<AudioMessage
size={size}
url={content}
name={name}
download={download}
/>
);
return (
<Styled className={`file_message ${sending ? "sending" : ""}`}>
<div className="basic">
@@ -22,6 +22,7 @@ const Styled = styled.div`
.icon {
width: 36px;
height: 48px;
}
.info {
display: flex;
@@ -52,6 +53,9 @@ const Styled = styled.div`
}
.download {
white-space: nowrap;
svg path{
fill: #616161;
}
}
.cancel {
cursor: pointer;
+6
View File
@@ -82,6 +82,12 @@ const StyledMsg = styled.div`
padding: 2px;
color: #1fe1f9;
}
/* 下载图标颜色 */
.download_icon.gray{
path{
fill: #616161;
}
}
}
}
&.archive {