import { useRef, useEffect, FC, ReactElement } from "react"; import { useDrop } from "react-dnd"; import { NativeTypes } from "react-dnd-html5-backend"; import clsx from "clsx"; import { toast } from "react-hot-toast"; import Send from "../../../common/component/Send"; import Operations from "./Operations"; import useUploadFile from "../../../common/hook/useUploadFile"; import { useAppSelector } from "../../../app/store"; import LoginTip from "./LoginTip"; import useLicense from "../../../common/hook/useLicense"; import LicenseUpgradeTip from "./LicenseOutdatedTip"; import DnDTip from "./DnDTip"; import IconWarning from '../../../assets/icons/warning.svg'; import ImagePreview from "../../../common/component/ImagePreview"; import VirtualMessageFeed from "./VirtualMessageFeed"; interface Props { readonly?: boolean; header: ReactElement; aside?: ReactElement | null; users?: ReactElement | null; voice?: ReactElement | null; dropFiles?: File[]; context: "channel" | "user"; to: number; } const Layout: FC = ({ readonly = false, header, aside = null, users = null, voice = null, dropFiles = [], context = "channel", to }) => { // const { t } = useTranslation('chat'); const { reachLimit } = useLicense(); const { addStageFile } = useUploadFile({ context, id: to }); const messagesContainer = useRef(null); const { selects, channelsData, usersData, inputMode } = useAppSelector((store) => { return { inputMode: store.ui.inputMode, selects: store.ui.selectMessages[`${context}_${to}`], channelsData: store.channels.byId, usersData: store.users.byId }; }); const [{ isActive }, drop] = useDrop( () => ({ accept: [NativeTypes.FILE], drop({ files }) { // console.log("iii", inputMode); if (inputMode !== "text") { toast("DnD not allowed in this input mode", { icon: , }); return; }; if (files.length) { const filesData = files.map((file) => { const { size, type, name } = file; const url = URL.createObjectURL(file); return { size, type, name, url }; }); addStageFile(filesData); } }, collect: (monitor) => ({ isActive: monitor.canDrop() && monitor.isOver() }) }), [context, to, inputMode] ); useEffect(() => { if (dropFiles?.length) { const filesData = dropFiles.map((file) => { const { size, type, name } = file; const url = URL.createObjectURL(file); return { size, type, name, url }; }); addStageFile(filesData); } }, [dropFiles]); const name = context == "channel" ? channelsData[to]?.name : usersData[to]?.name; return ( <>
{header}
{/* 消息流 */} {/* 发送框 */}
{readonly ? ( ) : reachLimit ? ( ) : (
)} {selects && }
{aside &&
{aside}
} {users &&
{users}
} {voice &&
{voice}
} {!readonly && inputMode == "text" && isActive && ( )}
); }; export default Layout;