NoticeList.js 3.15 KB
Newer Older
1
import React from 'react';
何乐's avatar
何乐 committed
2
import { Avatar, List, Skeleton } from 'antd';
3 4 5
import classNames from 'classnames';
import styles from './NoticeList.less';

何乐's avatar
何乐 committed
6 7
let ListElement = null;

afc163's avatar
afc163 committed
8
export default function NoticeList({
jim's avatar
jim committed
9 10 11 12 13 14 15
  data = [],
  onClick,
  onClear,
  title,
  locale,
  emptyText,
  emptyImage,
何乐's avatar
何乐 committed
16 17 18 19 20
  loading,
  onLoadMore,
  visible,
  loadedAll = true,
  scrollToLoad = true,
jim's avatar
jim committed
21
  showClear = true,
何乐's avatar
何乐 committed
22 23
  skeletonCount = 5,
  skeletonProps = {},
afc163's avatar
afc163 committed
24
}) {
25 26 27
  if (data.length === 0) {
    return (
      <div className={styles.notFound}>
jim's avatar
jim committed
28
        {emptyImage ? <img src={emptyImage} alt="not found" /> : null}
afc163's avatar
afc163 committed
29
        <div>{emptyText || locale.emptyText}</div>
30 31 32
      </div>
    );
  }
何乐's avatar
何乐 committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
  const loadingList = Array.from({ length: loading ? skeletonCount : 0 }).map(() => ({ loading }));
  const LoadMore = loadedAll ? (
    <div className={classNames(styles.loadMore, styles.loadedAll)}>
      <span>{locale.loadedAll}</span>
    </div>
  ) : (
    <div className={styles.loadMore} onClick={onLoadMore}>
      <span>{locale.loadMore}</span>
    </div>
  );
  const onScroll = event => {
    if (!scrollToLoad || loading || loadedAll) return;
    if (typeof onLoadMore !== 'function') return;
    const { currentTarget: t } = event;
    if (t.scrollHeight - t.scrollTop - t.clientHeight <= 40) {
      onLoadMore(event);
      ListElement = t;
    }
  };
  if (!visible && ListElement) {
    try {
      ListElement.scrollTo(null, 0);
    } catch (err) {
      ListElement = null;
    }
  }
59 60
  return (
    <div>
何乐's avatar
何乐 committed
61 62
      <List className={styles.list} loadMore={LoadMore} onScroll={onScroll}>
        {[...data, ...loadingList].map((item, i) => {
63 64 65
          const itemCls = classNames(styles.item, {
            [styles.read]: item.read,
          });
66
          // eslint-disable-next-line no-nested-ternary
67 68 69 70
          const leftIcon = item.avatar ? (
            typeof item.avatar === 'string' ? (
              <Avatar className={styles.avatar} src={item.avatar} />
            ) : (
何乐's avatar
何乐 committed
71
              <span className={styles.iconElement}>{item.avatar}</span>
72 73 74
            )
          ) : null;

75
          return (
afc163's avatar
afc163 committed
76
            <List.Item className={itemCls} key={item.key || i} onClick={() => onClick(item)}>
何乐's avatar
何乐 committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
              <Skeleton avatar title={false} active {...skeletonProps} loading={item.loading}>
                <List.Item.Meta
                  className={styles.meta}
                  avatar={leftIcon}
                  title={
                    <div className={styles.title}>
                      {item.title}
                      <div className={styles.extra}>{item.extra}</div>
                    </div>
                  }
                  description={
                    <div>
                      <div className={styles.description} title={item.description}>
                        {item.description}
                      </div>
                      <div className={styles.datetime}>{item.datetime}</div>
afc163's avatar
afc163 committed
93
                    </div>
何乐's avatar
何乐 committed
94 95 96
                  }
                />
              </Skeleton>
afc163's avatar
afc163 committed
97
            </List.Item>
98 99
          );
        })}
afc163's avatar
afc163 committed
100
      </List>
jim's avatar
jim committed
101
      {showClear ? (
jim's avatar
jim committed
102
        <div className={styles.clear} onClick={onClear}>
103
          {locale.clear} {title}
jim's avatar
jim committed
104
        </div>
jim's avatar
jim committed
105
      ) : null}
106 107 108
    </div>
  );
}