import GlobalHeader, { GlobalHeaderProps } from '@/components/GlobalHeader'; import TopNavHeader, { TopNavHeaderProps } from '@/components/TopNavHeader'; import { ConnectProps, ConnectState, SettingModelState } from '@/models/connect'; import React, { Component } from 'react'; import { formatMessage } from 'umi-plugin-react/locale'; import { Layout, message } from 'antd'; import { ClickParam } from 'antd/es/menu'; import { connect } from 'dva'; import Animate from 'rc-animate'; import router from 'umi/router'; import styles from './Header.less'; const { Header } = Layout; export interface HeaderViewProps extends ConnectProps, TopNavHeaderProps, GlobalHeaderProps { isMobile?: boolean; collapsed?: boolean; setting?: SettingModelState; autoHideHeader?: boolean; handleMenuCollapse?: (collapse: boolean) => void; } interface HeaderViewState { visible: boolean; } class HeaderView extends Component { static getDerivedStateFromProps(props: HeaderViewProps, state: HeaderViewState) { if (!props.autoHideHeader && !state.visible) { return { visible: true, }; } return null; } state = { visible: true, }; ticking: boolean = false; oldScrollTop: number = 0; componentDidMount() { document.addEventListener('scroll', this.handScroll, { passive: true }); } componentWillUnmount() { document.removeEventListener('scroll', this.handScroll); } getHeadWidth = () => { const { isMobile, collapsed, setting } = this.props; const { fixedHeader, layout } = setting!; if (isMobile || !fixedHeader || layout === 'topmenu') { return '100%'; } return collapsed ? 'calc(100% - 80px)' : 'calc(100% - 256px)'; }; handleNoticeClear = (type: string) => { const { dispatch } = this.props; message.success( `${formatMessage({ id: 'component.noticeIcon.cleared' })} ${formatMessage({ id: `component.globalHeader.${type}`, })}`, ); dispatch!({ type: 'global/clearNotices', payload: type, }); }; handleMenuClick = ({ key }: ClickParam) => { const { dispatch } = this.props; if (key === 'userCenter') { router.push('/account/center'); return; } if (key === 'triggerError') { router.push('/exception/trigger'); return; } if (key === 'userinfo') { router.push('/account/settings/base'); return; } if (key === 'logout') { dispatch!({ type: 'login/logout', }); } }; handleNoticeVisibleChange = (visible: boolean) => { if (visible) { const { dispatch } = this.props; dispatch!({ type: 'global/fetchNotices', }); } }; handScroll = () => { const { autoHideHeader } = this.props; const { visible } = this.state; if (!autoHideHeader) { return; } const scrollTop = document.body.scrollTop + document.documentElement.scrollTop; if (!this.ticking) { this.ticking = true; requestAnimationFrame(() => { if (this.oldScrollTop > scrollTop) { this.setState({ visible: true, }); } else if (scrollTop > 300 && visible) { this.setState({ visible: false, }); } else if (scrollTop < 300 && !visible) { this.setState({ visible: true, }); } this.oldScrollTop = scrollTop; this.ticking = false; }); } }; render() { const { isMobile, handleMenuCollapse, setting } = this.props; const { navTheme, layout, fixedHeader } = setting!; const { visible } = this.state; const isTop = layout === 'topmenu'; const width = this.getHeadWidth(); const HeaderDom = visible ? (
{isTop && !isMobile ? ( ) : ( )}
) : null; return ( {HeaderDom} ); } } export default connect(({ user, global, setting, loading }: ConnectState) => ({ currentUser: user.currentUser, collapsed: global.collapsed, fetchingMoreNotices: loading.effects['global/fetchMoreNotices'], fetchingNotices: loading.effects['global/fetchNotices'], notices: global.notices, setting, }))(HeaderView);