import React from 'react'; import { List, Spin, ConfigProvider } from 'antd'; // eslint-disable-next-line import/no-unresolved import classNames from 'classnames'; import './style/list.less'; import { Alarm, Case, Notice, Unknown } from './templates'; import { MESSAGE_TYPE } from './constants'; const Empty = ({ emptyText, ...props }) => { const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext); const prefixCls = props.prefixCls || getPrefixCls(); return ( <div className={`${prefixCls}-notFound`}> <img src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg" alt="not found" /> <div>{emptyText}</div> </div> ); }; class NoticeList extends React.Component { constructor(props) { super(props); this.emptyText = props.emptyText; this.confirmRead = props.confirmRead; this.handlerSysDetail = props.handlerSysDetail; this.handlerUnknowDetail = props.handlerUnknowDetail; this.loadMore = props.loadMore; this.hasMore = props.hasMore; this.container = React.createRef(); this.state = { isLoading: false, }; this.mounted = false; this.handleScrollCallback = this.throttle(this.handleScroll.bind(this), 30).bind(this); } componentDidMount() { this.mounted = true; if (this.container.current) { this.container.current.addEventListener('scroll', this.handleScrollCallback); } } componentWillUnmount() { this.mounted = false; } throttle(fn, wait) { /* eslint-disable */ let pre = Date.now(); return function () { const context = this; // eslint-disable-next-line prefer-rest-params const args = arguments; const now = Date.now(); if (now - pre >= wait) { fn.apply(context, args); pre = Date.now(); } }; } handleScroll(e) { e.stopPropagation(); if (!this.mounted) return; if (!this.container.current) return; const { current } = this.container; if (current.scrollHeight - current.scrollTop - current.offsetHeight <= 100) { this.handleLoadMore(); } } handleLoadMore() { if (this.state.isLoading) return; if (!this.hasMore()) return; this.setState( { isLoading: true, }, () => { if (!this.loadMore) return; this.loadMore().then((data) => { if (!this.mounted) return; this.setState({ isLoading: false, }); }); }, ); } render() { const { getPrefixCls } = this.context; const prefixCls = this.props.prefixCls || getPrefixCls ? getPrefixCls('head-notifier-list') : ''; if (!this.props.data || this.props.data.length === 0) { return <Empty emptyText={this.emptyText} prefixCls={prefixCls} />; } return ( <div className={`${prefixCls}-container`} ref={this.container}> <List className={`${prefixCls}-list`} dataSource={this.props.data} renderItem={(item, i) => { const itemCls = classNames(`${prefixCls}-item`, { [`${prefixCls}-read`]: item.read, }); let messageTemplate = <></>; switch (item.infoClasses) { case MESSAGE_TYPE.ALARM_TYPE: messageTemplate = ( <Alarm message={item} confirmRead={this.confirmRead} config={this.props.config} handlerUnknowDetail={this.handlerUnknowDetail} /> ); break; case MESSAGE_TYPE.CASE_TYPE: messageTemplate = <Case message={item} confirmRead={this.confirmRead} handlerUnknowDetail={this.handlerUnknowDetail} />; break; case MESSAGE_TYPE.SYS_TYPE: messageTemplate = ( <Notice message={item} confirmRead={this.confirmRead} config={this.props.config} handlerSysDetail={this.handlerSysDetail} /> ); break; default: messageTemplate = ( <Unknown message={item} confirmRead={this.confirmRead} handlerUnknowDetail={this.handlerUnknowDetail} /> ); break; } return ( <List.Item className={itemCls} key={item.id || i}> {messageTemplate} </List.Item> ); }} /> <div className={`${prefixCls}-bottomBar`}> {this.state.isLoading ? ( <> <Spin /> 加载中... </> ) : this.hasMore() ? ( <span>下拉加载更多</span> ) : ( <span style={{ fontSize: '12px', color: 'rgba(0, 0, 0, 0.6)' }}> 已经没有更多消息了 </span> )} </div> </div> ); } } NoticeList.contextType = ConfigProvider.ConfigContext; export default NoticeList;