Header.js 4.25 KB
Newer Older
jim's avatar
jim committed
1
import React, { PureComponent } from 'react';
2
import { formatMessage } from 'umi/locale';
jim's avatar
jim committed
3 4 5
import { Layout, message } from 'antd';
import Animate from 'rc-animate';
import { connect } from 'dva';
zinkey's avatar
zinkey committed
6
import router from 'umi/router';
7 8
import GlobalHeader from '@/components/GlobalHeader';
import TopNavHeader from '@/components/TopNavHeader';
jim's avatar
jim committed
9
import styles from './Header.less';
10
import Authorized from '@/utils/Authorized';
jim's avatar
jim committed
11 12 13 14 15 16 17

const { Header } = Layout;

class HeaderView extends PureComponent {
  state = {
    visible: true,
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
18

19 20 21 22 23 24 25 26 27
  static getDerivedStateFromProps(props, state) {
    if (!props.autoHideHeader && !state.visible) {
      return {
        visible: true,
      };
    }
    return null;
  }

jim's avatar
jim committed
28
  componentDidMount() {
29
    document.addEventListener('scroll', this.handScroll, { passive: true });
jim's avatar
jim committed
30
  }
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
31

jim's avatar
jim committed
32
  componentWillUnmount() {
33
    document.removeEventListener('scroll', this.handScroll);
jim's avatar
jim committed
34
  }
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
35

jim's avatar
jim committed
36
  getHeadWidth = () => {
37 38 39
    const { isMobile, collapsed, setting } = this.props;
    const { fixedHeader, layout } = setting;
    if (isMobile || !fixedHeader || layout === 'topmenu') {
jim's avatar
jim committed
40 41
      return '100%';
    }
42
    return collapsed ? 'calc(100% - 80px)' : 'calc(100% - 256px)';
jim's avatar
jim committed
43
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
44

jim's avatar
jim committed
45
  handleNoticeClear = type => {
46
    message.success(`${formatMessage({ id: 'component.noticeIcon.cleared' })} ${type}`);
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
47 48
    const { dispatch } = this.props;
    dispatch({
jim's avatar
jim committed
49 50 51 52
      type: 'global/clearNotices',
      payload: type,
    });
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
53

jim's avatar
jim committed
54
  handleMenuClick = ({ key }) => {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
55
    const { dispatch } = this.props;
jim's avatar
jim committed
56
    if (key === 'userCenter') {
zinkey's avatar
zinkey committed
57
      router.push('/account/center');
jim's avatar
jim committed
58 59 60
      return;
    }
    if (key === 'triggerError') {
zinkey's avatar
zinkey committed
61
      router.push('/exception/trigger');
jim's avatar
jim committed
62 63 64
      return;
    }
    if (key === 'userinfo') {
zinkey's avatar
zinkey committed
65
      router.push('/account/settings/base');
jim's avatar
jim committed
66 67 68
      return;
    }
    if (key === 'logout') {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
69
      dispatch({
jim's avatar
jim committed
70 71 72 73
        type: 'login/logout',
      });
    }
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
74

jim's avatar
jim committed
75
  handleNoticeVisibleChange = visible => {
jim's avatar
jim committed
76
    if (visible) {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
77 78
      const { dispatch } = this.props;
      dispatch({
jim's avatar
jim committed
79 80 81 82
        type: 'global/fetchNotices',
      });
    }
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
83

84
  handScroll = () => {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
85 86 87
    const { autoHideHeader } = this.props;
    const { visible } = this.state;
    if (!autoHideHeader) {
jim's avatar
jim committed
88 89
      return;
    }
90
    const scrollTop = document.body.scrollTop + document.documentElement.scrollTop;
jim's avatar
jim committed
91 92
    if (!this.ticking) {
      requestAnimationFrame(() => {
93 94 95 96 97 98 99
        if (this.oldScrollTop > scrollTop) {
          this.setState({
            visible: true,
          });
          this.scrollTop = scrollTop;
          return;
        }
100
        if (scrollTop > 300 && visible) {
jim's avatar
jim committed
101 102 103 104
          this.setState({
            visible: false,
          });
        }
105
        if (scrollTop < 300 && !visible) {
jim's avatar
jim committed
106 107 108 109
          this.setState({
            visible: true,
          });
        }
110
        this.oldScrollTop = scrollTop;
jim's avatar
jim committed
111 112 113
        this.ticking = false;
      });
    }
114
    this.ticking = false;
jim's avatar
jim committed
115
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
116

jim's avatar
jim committed
117
  render() {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
118
    const { isMobile, handleMenuCollapse, setting } = this.props;
afc163's avatar
afc163 committed
119
    const { navTheme, layout, fixedHeader } = setting;
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
120
    const { visible } = this.state;
jim's avatar
jim committed
121
    const isTop = layout === 'topmenu';
122
    const width = this.getHeadWidth();
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
123
    const HeaderDom = visible ? (
124
      <Header style={{ padding: 0, width }} className={fixedHeader ? styles.fixedHeader : ''}>
jim's avatar
jim committed
125 126
        {isTop && !isMobile ? (
          <TopNavHeader
afc163's avatar
afc163 committed
127
            theme={navTheme}
jim's avatar
jim committed
128 129 130
            mode="horizontal"
            Authorized={Authorized}
            onCollapse={handleMenuCollapse}
jim's avatar
jim committed
131
            onNoticeClear={this.handleNoticeClear}
jim's avatar
jim committed
132 133 134 135 136 137 138
            onMenuClick={this.handleMenuClick}
            onNoticeVisibleChange={this.handleNoticeVisibleChange}
            {...this.props}
          />
        ) : (
          <GlobalHeader
            onCollapse={handleMenuCollapse}
jim's avatar
jim committed
139
            onNoticeClear={this.handleNoticeClear}
jim's avatar
jim committed
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
            onMenuClick={this.handleMenuClick}
            onNoticeVisibleChange={this.handleNoticeVisibleChange}
            {...this.props}
          />
        )}
      </Header>
    ) : null;
    return (
      <Animate component="" transitionName="fade">
        {HeaderDom}
      </Animate>
    );
  }
}

export default connect(({ user, global, setting, loading }) => ({
  currentUser: user.currentUser,
  collapsed: global.collapsed,
  fetchingNotices: loading.effects['global/fetchNotices'],
  notices: global.notices,
jim's avatar
jim committed
160
  setting,
jim's avatar
jim committed
161
}))(HeaderView);