2017-06-04 02:39:38 +03:00
import React from 'react' ;
import PropTypes from 'prop-types' ;
import classNames from 'classnames' ;
2017-07-21 21:33:16 +03:00
import { defineMessages , FormattedMessage , injectIntl } from 'react-intl' ;
import ImmutablePropTypes from 'react-immutable-proptypes' ;
2017-06-04 02:39:38 +03:00
2017-12-04 09:26:40 +02:00
import NotificationPurgeButtonsContainer from 'flavours/glitch/containers/notification_purge_buttons_container' ;
2017-07-21 21:33:16 +03:00
const messages = defineMessages ( {
2017-07-26 03:01:27 +03:00
show : { id : 'column_header.show_settings' , defaultMessage : 'Show settings' } ,
hide : { id : 'column_header.hide_settings' , defaultMessage : 'Hide settings' } ,
2017-07-28 01:54:48 +03:00
moveLeft : { id : 'column_header.moveLeft_settings' , defaultMessage : 'Move column to the left' } ,
moveRight : { id : 'column_header.moveRight_settings' , defaultMessage : 'Move column to the right' } ,
2017-07-30 19:36:28 +03:00
enterNotifCleaning : { id : 'notification_purge.start' , defaultMessage : 'Enter notification cleaning mode' } ,
2017-07-21 21:33:16 +03:00
} ) ;
@ injectIntl
2017-06-23 20:36:54 +03:00
export default class ColumnHeader extends React . PureComponent {
2017-06-04 02:39:38 +03:00
static contextTypes = {
router : PropTypes . object ,
} ;
static propTypes = {
2017-07-26 03:01:27 +03:00
intl : PropTypes . object . isRequired ,
2018-03-28 20:56:46 +03:00
title : PropTypes . node ,
icon : PropTypes . string ,
2017-06-04 02:39:38 +03:00
active : PropTypes . bool ,
2017-07-21 21:33:16 +03:00
localSettings : ImmutablePropTypes . map ,
2017-06-04 02:39:38 +03:00
multiColumn : PropTypes . bool ,
2018-03-28 20:56:46 +03:00
extraButton : PropTypes . node ,
2017-06-05 18:10:40 +03:00
showBackButton : PropTypes . bool ,
2017-07-21 21:33:16 +03:00
notifCleaning : PropTypes . bool , // true only for the notification column
notifCleaningActive : PropTypes . bool ,
2017-07-30 19:36:28 +03:00
onEnterCleaningMode : PropTypes . func ,
2017-06-04 02:39:38 +03:00
children : PropTypes . node ,
pinned : PropTypes . bool ,
onPin : PropTypes . func ,
onMove : PropTypes . func ,
onClick : PropTypes . func ,
2017-07-21 21:33:16 +03:00
intl : PropTypes . object . isRequired ,
2017-06-04 02:39:38 +03:00
} ;
state = {
collapsed : true ,
animating : false ,
2017-07-30 19:36:28 +03:00
animatingNCD : false ,
2017-06-04 02:39:38 +03:00
} ;
2019-04-15 23:23:05 +03:00
historyBack = ( skip ) => {
2018-12-19 14:13:24 +02:00
// if history is exhausted, or we would leave mastodon, just go to root.
if ( window . history . state ) {
2019-04-15 23:23:05 +03:00
const state = this . context . router . history . location . state ;
if ( skip && state && state . mastodonBackSteps ) {
this . context . router . history . go ( - state . mastodonBackSteps ) ;
} else {
this . context . router . history . goBack ( ) ;
}
2018-12-19 14:13:24 +02:00
} else {
this . context . router . history . push ( '/' ) ;
}
}
2017-06-04 02:39:38 +03:00
handleToggleClick = ( e ) => {
e . stopPropagation ( ) ;
this . setState ( { collapsed : ! this . state . collapsed , animating : true } ) ;
}
handleTitleClick = ( ) => {
this . props . onClick ( ) ;
}
handleMoveLeft = ( ) => {
this . props . onMove ( - 1 ) ;
}
handleMoveRight = ( ) => {
this . props . onMove ( 1 ) ;
}
2019-04-15 23:23:05 +03:00
handleBackClick = ( event ) => {
this . historyBack ( event . shiftKey ) ;
2017-06-04 02:39:38 +03:00
}
handleTransitionEnd = ( ) => {
this . setState ( { animating : false } ) ;
}
2017-07-30 19:36:28 +03:00
handleTransitionEndNCD = ( ) => {
this . setState ( { animatingNCD : false } ) ;
}
2018-12-19 14:13:24 +02:00
handlePin = ( ) => {
if ( ! this . props . pinned ) {
this . historyBack ( ) ;
}
this . props . onPin ( ) ;
}
2017-07-30 19:36:28 +03:00
onEnterCleaningMode = ( ) => {
this . setState ( { animatingNCD : true } ) ;
this . props . onEnterCleaningMode ( ! this . props . notifCleaningActive ) ;
}
2017-06-04 02:39:38 +03:00
render ( ) {
2018-12-19 14:13:24 +02:00
const { intl , icon , active , children , pinned , multiColumn , extraButton , showBackButton , intl : { formatMessage } , notifCleaning , notifCleaningActive } = this . props ;
2017-07-30 19:36:28 +03:00
const { collapsed , animating , animatingNCD } = this . state ;
2017-07-21 21:33:16 +03:00
let title = this . props . title ;
2017-06-12 21:02:17 +03:00
const wrapperClassName = classNames ( 'column-header__wrapper' , {
'active' : active ,
} ) ;
2017-06-04 02:39:38 +03:00
const buttonClassName = classNames ( 'column-header' , {
'active' : active ,
} ) ;
const collapsibleClassName = classNames ( 'column-header__collapsible' , {
'collapsed' : collapsed ,
'animating' : animating ,
} ) ;
const collapsibleButtonClassName = classNames ( 'column-header__button' , {
'active' : ! collapsed ,
} ) ;
2017-07-30 19:36:28 +03:00
const notifCleaningButtonClassName = classNames ( 'column-header__button' , {
'active' : notifCleaningActive ,
} ) ;
const notifCleaningDrawerClassName = classNames ( 'ncd column-header__collapsible' , {
'collapsed' : ! notifCleaningActive ,
'animating' : animatingNCD ,
} ) ;
2017-06-04 02:39:38 +03:00
let extraContent , pinButton , moveButtons , backButton , collapseButton ;
2017-07-30 19:36:28 +03:00
//*glitch
const msgEnterNotifCleaning = intl . formatMessage ( messages . enterNotifCleaning ) ;
2017-06-04 02:39:38 +03:00
if ( children ) {
extraContent = (
< div key = 'extra-content' className = 'column-header__collapsible__extra' >
{ children }
< / d i v >
) ;
}
if ( multiColumn && pinned ) {
2018-12-19 14:13:24 +02:00
pinButton = < button key = 'pin-button' className = 'text-btn column-header__setting-btn' onClick = { this . handlePin } > < i className = 'fa fa fa-times' / > < FormattedMessage id = 'column_header.unpin' defaultMessage = 'Unpin' / > < / b u t t o n > ;
2017-06-04 02:39:38 +03:00
moveButtons = (
< div key = 'move-buttons' className = 'column-header__setting-arrows' >
2017-07-28 01:54:48 +03:00
< button title = { formatMessage ( messages . moveLeft ) } aria - label = { formatMessage ( messages . moveLeft ) } className = 'text-btn column-header__setting-btn' onClick = { this . handleMoveLeft } > < i className = 'fa fa-chevron-left' / > < / b u t t o n >
< button title = { formatMessage ( messages . moveRight ) } aria - label = { formatMessage ( messages . moveRight ) } className = 'text-btn column-header__setting-btn' onClick = { this . handleMoveRight } > < i className = 'fa fa-chevron-right' / > < / b u t t o n >
2017-06-04 02:39:38 +03:00
< / d i v >
) ;
} else if ( multiColumn ) {
2018-12-19 14:13:24 +02:00
pinButton = < button key = 'pin-button' className = 'text-btn column-header__setting-btn' onClick = { this . handlePin } > < i className = 'fa fa fa-plus' / > < FormattedMessage id = 'column_header.pin' defaultMessage = 'Pin' / > < / b u t t o n > ;
2017-06-05 18:10:40 +03:00
}
2017-06-04 02:39:38 +03:00
2017-06-05 18:10:40 +03:00
if ( ! pinned && ( multiColumn || showBackButton ) ) {
2017-06-04 02:39:38 +03:00
backButton = (
< button onClick = { this . handleBackClick } className = 'column-header__back-button' >
< i className = 'fa fa-fw fa-chevron-left column-back-button__icon' / >
< FormattedMessage id = 'column_back_button.label' defaultMessage = 'Back' / >
< / b u t t o n >
) ;
}
const collapsedContent = [
extraContent ,
] ;
if ( multiColumn ) {
collapsedContent . push ( moveButtons ) ;
collapsedContent . push ( pinButton ) ;
}
if ( children || multiColumn ) {
2018-03-28 20:56:46 +03:00
collapseButton = < button className = { collapsibleButtonClassName } title = { formatMessage ( collapsed ? messages . show : messages . hide ) } aria - label = { formatMessage ( collapsed ? messages . show : messages . hide ) } aria - pressed = { collapsed ? 'false' : 'true' } onClick = { this . handleToggleClick } > < i className = 'fa fa-sliders' / > < / b u t t o n > ;
2017-06-04 02:39:38 +03:00
}
2018-03-28 20:56:46 +03:00
const hasTitle = icon && title ;
2017-06-04 02:39:38 +03:00
return (
2017-06-12 21:02:17 +03:00
< div className = { wrapperClassName } >
2018-03-16 18:19:38 +02:00
< h1 className = { buttonClassName } >
2018-03-28 20:56:46 +03:00
{ hasTitle && (
< button onClick = { this . handleTitleClick } >
< i className = { ` fa fa-fw fa- ${ icon } column-header__icon ` } / >
{ title }
< / b u t t o n >
) }
{ ! hasTitle && backButton }
2017-06-04 02:39:38 +03:00
< div className = 'column-header__buttons' >
2018-03-28 20:56:46 +03:00
{ hasTitle && backButton }
{ extraButton }
2017-07-30 19:36:28 +03:00
{ notifCleaning ? (
< button
aria - label = { msgEnterNotifCleaning }
title = { msgEnterNotifCleaning }
onClick = { this . onEnterCleaningMode }
className = { notifCleaningButtonClassName }
>
< i className = 'fa fa-eraser' / >
< / b u t t o n >
) : null }
2017-06-04 02:39:38 +03:00
{ collapseButton }
< / d i v >
2017-07-28 01:54:48 +03:00
< / h 1 >
2017-06-04 02:39:38 +03:00
2017-07-30 19:36:28 +03:00
{ notifCleaning ? (
< div className = { notifCleaningDrawerClassName } onTransitionEnd = { this . handleTransitionEndNCD } >
< div className = 'column-header__collapsible-inner nopad-drawer' >
{ ( notifCleaningActive || animatingNCD ) ? ( < NotificationPurgeButtonsContainer / > ) : null }
< / d i v >
< / d i v >
) : null }
2017-09-30 05:29:56 +03:00
< div className = { collapsibleClassName } tabIndex = { collapsed ? - 1 : null } onTransitionEnd = { this . handleTransitionEnd } >
2017-06-25 00:18:11 +03:00
< div className = 'column-header__collapsible-inner' >
2017-06-04 02:39:38 +03:00
{ ( ! collapsed || animating ) && collapsedContent }
< / d i v >
< / d i v >
< / d i v >
) ;
}
}