UNPKG

z-react-ui

Version:

z-react-ui,是一款基于 Dumi,由 React + TypeScript 开发的组件库 🎉。

127 lines (117 loc) 5.3 kB
import React, { useCallback, useEffect, useLayoutEffect, useRef, forwardRef, useImperativeHandle } from 'react'; import { usePrefixCls } from '@/_hooks'; import classNames from 'classnames'; import { getTimeText, diffHalfHour } from '@/_utils/chat/getTimeText'; import { isLoginerFn, getLayout, msgTypeToContentType } from '@/_utils/chat'; import ChatItem from './ChatItem'; import { useThrottleFn, usePersistFn } from 'ahooks'; import { staticImgPrefix } from '@/_config'; // #----------- 上: ts类型定义 ----------- 分割线 ----------- 下: JS代码 ----------- var defaultFieldNames = { id: 'id', avatarSrc: 'avatarSrc', createTime: 'createTime', msgType: 'msgType', msgId: 'msgId', msgContent: 'msgContent', userId: 'userId', userName: 'userName' }; // 消息类型 var defaultMsgTypeManage = { system: [0], text: [1], img: [3], audio: [34], groupInvite: [49] }; var defaultFn = function defaultFn() { return ''; }; var ChatPanel = function ChatPanel(_ref, ref) { var dataSource = _ref.dataSource, _ref$fieldNames = _ref.fieldNames, fieldNames = _ref$fieldNames === void 0 ? defaultFieldNames : _ref$fieldNames, _ref$msgTypeManage = _ref.msgTypeManage, msgTypeManage = _ref$msgTypeManage === void 0 ? defaultMsgTypeManage : _ref$msgTypeManage, loginId = _ref.loginId, _ref$loadMore = _ref.loadMore, loadMore = _ref$loadMore === void 0 ? defaultFn : _ref$loadMore, _ref$isLoading = _ref.isLoading, isLoading = _ref$isLoading === void 0 ? true : _ref$isLoading, _ref$hasMore = _ref.hasMore, hasMore = _ref$hasMore === void 0 ? true : _ref$hasMore, _ref$reachedTopThresh = _ref.reachedTopThreshold, reachedTopThreshold = _ref$reachedTopThresh === void 0 ? 100 : _ref$reachedTopThresh; var prefixCls = usePrefixCls('chat-list'); var largeImgPrefixCls = usePrefixCls('large-img'); var scrollRef = useRef(); var queryHistoryMsg = usePersistFn(loadMore); var handleScroll = useCallback(function (e) { if (!hasMore || !isLoading) return; var scrollTop = scrollRef.current.scrollTop; if (scrollTop < reachedTopThreshold && typeof queryHistoryMsg === 'function') { queryHistoryMsg(); } }, [reachedTopThreshold, hasMore, isLoading]); var _useThrottleFn = useThrottleFn(handleScroll, { wait: 200 }), throttleScroll = _useThrottleFn.run; // 初始化时,将聊天内容拉到最低, 时机:图片获取后 useLayoutEffect(function () { var imgArr = document.querySelectorAll(".".concat(prefixCls, " .").concat(largeImgPrefixCls, "-img")); Array.from(imgArr).forEach(function (item) { item.onload = handleRearchBottom; item.onerror = handleRearchBottom; }); handleRearchBottom(); }, []); // 聊天列表触底 var handleRearchBottom = useCallback(function () { var scrollHeight = scrollRef.current.scrollHeight; var clientheight = scrollRef.current.clientHeight; scrollRef.current.scrollTo(0, Math.abs(scrollHeight - clientheight)); }, []); useEffect(function () { scrollRef.current.addEventListener('scroll', throttleScroll); return function () { scrollRef.current.removeEventListener('scroll', throttleScroll); }; }, [throttleScroll]); useImperativeHandle(ref, function () { return { chatListRearchBottom: handleRearchBottom }; }, [handleRearchBottom]); return ( /*#__PURE__*/ // <div className={classNames(prefixCls,`${prefixCls}-transparent-scroll-bar`)} ref={scrollRef}> React.createElement("div", { className: classNames(prefixCls), ref: scrollRef }, hasMore ? isLoading ? /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-loading-msg-panel") }, /*#__PURE__*/React.createElement("img", { src: "".concat(staticImgPrefix, "/common/loading@2x.png"), alt: "\u52A0\u8F7D\u6D88\u606F", draggable: "false" })) : null : /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-loading-msg-panel") }, "\u6CA1\u6709\u66F4\u591A\u4E86"), Array.isArray(dataSource) ? dataSource.map(function (item, index) { var preData = index !== 0 ? dataSource[index - 1] : {}; var isLoginer = isLoginerFn(loginId, item.userId); var contentType = msgTypeToContentType(item.msgType); return /*#__PURE__*/React.createElement("div", { key: item.id, className: classNames("".concat(prefixCls, "-row-list")) }, index === 0 ? /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-sender-time-list") }, /*#__PURE__*/React.createElement("span", null, getTimeText(item.createTime).parser1())) : // 当前消息与上一条消息发送时间间隔30(暂定)分钟就显示 !diffHalfHour(preData.createTime, item.createTime) ? /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-sender-time-list") }, /*#__PURE__*/React.createElement("span", null, getTimeText(item.createTime).parser1())) : null, /*#__PURE__*/React.createElement(ChatItem, { layout: getLayout(isLoginer, contentType), contentType: contentType, chatItem: item })); }) : null) ); }; export default /*#__PURE__*/forwardRef(ChatPanel);