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
+1 -1
View File
@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.5303 11.7204L16.4462 11.6478C16.1526 11.4299 15.7359 11.4541 15.4697 11.7204L12.7503 14.4397L12.75 7.75003L12.7432 7.64826C12.6935 7.28218 12.3797 7.00003 12 7.00003L11.8982 7.00688C11.5322 7.05654 11.25 7.37033 11.25 7.75003L11.2503 14.4417L8.52961 11.7198L8.4455 11.6472C8.15193 11.4293 7.73527 11.4534 7.46895 11.7196C7.176 12.0124 7.17591 12.4873 7.46875 12.7803L11.4687 16.7818L11.5529 16.8544C11.8465 17.0724 12.2632 17.0482 12.5295 16.7819L16.5303 12.7811L16.6029 12.6969C16.8208 12.4033 16.7966 11.9867 16.5303 11.7204ZM6.25 3C4.45507 3 3 4.45507 3 6.25V17.75C3 19.5449 4.45507 21 6.25 21H17.75C19.5449 21 21 19.5449 21 17.75V6.25C21 4.45507 19.5449 3 17.75 3H6.25ZM4.5 6.25C4.5 5.2835 5.2835 4.5 6.25 4.5H17.75C18.7165 4.5 19.5 5.2835 19.5 6.25V17.75C19.5 18.7165 18.7165 19.5 17.75 19.5H6.25C5.2835 19.5 4.5 18.7165 4.5 17.75V6.25Z" fill="#616161"/>
<path d="M16.5303 11.7204L16.4462 11.6478C16.1526 11.4299 15.7359 11.4541 15.4697 11.7204L12.7503 14.4397L12.75 7.75003L12.7432 7.64826C12.6935 7.28218 12.3797 7.00003 12 7.00003L11.8982 7.00688C11.5322 7.05654 11.25 7.37033 11.25 7.75003L11.2503 14.4417L8.52961 11.7198L8.4455 11.6472C8.15193 11.4293 7.73527 11.4534 7.46895 11.7196C7.176 12.0124 7.17591 12.4873 7.46875 12.7803L11.4687 16.7818L11.5529 16.8544C11.8465 17.0724 12.2632 17.0482 12.5295 16.7819L16.5303 12.7811L16.6029 12.6969C16.8208 12.4033 16.7966 11.9867 16.5303 11.7204ZM6.25 3C4.45507 3 3 4.45507 3 6.25V17.75C3 19.5449 4.45507 21 6.25 21H17.75C19.5449 21 21 19.5449 21 17.75V6.25C21 4.45507 19.5449 3 17.75 3H6.25ZM4.5 6.25C4.5 5.2835 5.2835 4.5 6.25 4.5H17.75C18.7165 4.5 19.5 5.2835 19.5 6.25V17.75C19.5 18.7165 18.7165 19.5 17.75 19.5H6.25C5.2835 19.5 4.5 18.7165 4.5 17.75V6.25Z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 976 B

After

Width:  |  Height:  |  Size: 973 B

@@ -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 {