import React from 'react' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' import * as actions from '../actions' import MediaOverlay from './Overlay/Media' import LoadingOverlay from './Overlay/Loading' import Map from './Map.jsx' import Toolbar from './Toolbar/Layout' import CardStack from './CardStack.jsx' import NarrativeControls from './presentational/Narrative/Controls.js' import InfoPopUp from './InfoPopup.jsx' import Timeline from './Timeline.jsx' import Notification from './Notification.jsx' import StaticPage from './StaticPage' import TemplateCover from './TemplateCover' import colors from '../common/global' import { binarySearch } from '../common/utilities' import { isMobile } from 'react-device-detect' class Dashboard extends React.Component { constructor (props) { super(props) this.handleViewSource = this.handleViewSource.bind(this) this.handleHighlight = this.handleHighlight.bind(this) this.setNarrative = this.setNarrative.bind(this) this.moveInNarrative = this.moveInNarrative.bind(this) this.handleSelect = this.handleSelect.bind(this) this.getCategoryColor = this.getCategoryColor.bind(this) } componentDidMount () { if (!this.props.app.isMobile) { this.props.actions.fetchDomain() .then(domain => this.props.actions.updateDomain(domain)) .then(({ domain }) => { if (domain.categories.length >= 4) { this.props.actions.updateDimensions({ marginTop: 0 }) } }) } } handleHighlight (highlighted) { this.props.actions.updateHighlighted((highlighted) || null) } handleViewSource (source) { this.props.actions.updateSource(source) } handleSelect (selected, axis) { const matchedEvents = [] const TIMELINE_AXIS = 0 if (axis === TIMELINE_AXIS) { matchedEvents.push(selected) // find in events const { events } = this.props.domain const idx = binarySearch( events, selected, (e1, e2) => { return e1.datetime - e2.datetime } ) // check events before let ptr = idx - 1 while (events[idx].datetime === events[ptr].datetime) { matchedEvents.push(events[ptr]) ptr -= 1 } // check events after if (idx < events.length - 1) { ptr = idx + 1 while (events[idx].datetime === events[ptr].datetime) { matchedEvents.push(events[ptr]) ptr += 1 } } } else { // Map... const std = { ...selected } delete std.sources Object.values(std).forEach(ev => matchedEvents.push(ev)) } this.props.actions.updateSelected(matchedEvents) } getCategoryColor (category) { if (!this.props.features.USE_CATEGORIES) { return colors.fallbackEventColor } const cat = this.props.ui.style.categories[category] if (cat) { return cat } else { return this.props.ui.style.categories['default'] } } getNarrativeLinks (event) { const narrative = this.props.domain.narratives.find(nv => nv.id === event.narrative) if (narrative) return narrative.byId[event.id] return null } setNarrative (narrative) { // only handleSelect if narrative is not null if (narrative) { this.props.actions.clearFilter('filters') this.props.actions.clearFilter('categories') this.handleSelect([ narrative.steps[0] ]) } this.props.actions.updateNarrative(narrative) } moveInNarrative (amt) { const { current } = this.props.app.narrativeState const { narrative } = this.props.app if (amt === 1) { this.handleSelect([ narrative.steps[current + 1] ]) this.props.actions.incrementNarrativeCurrent() } if (amt === -1) { this.handleSelect([ narrative.steps[current - 1] ]) this.props.actions.decrementNarrativeCurrent() } } render () { const { actions, app, domain, ui, features } = this.props if (isMobile || window.innerWidth < 1000) { return (
{features.USE_COVER && ( {/* enable USE_COVER in config.js features, and customise your header */} {/* pass 'actions.toggleCover' as a prop to your custom header */} { /* eslint-disable no-undef */ alert('This platform is not suitable for mobile. Please re-visit the site on a device with a larger screen.') /* eslint-enable no-undef */ }} /> )}
) } return (
actions.toggleFilter('filters', filter), onCategoryFilter: category => actions.toggleFilter('categories', category), onSelectNarrative: this.setNarrative }} /> this.handleSelect(ev, 1), onSelectNarrative: this.setNarrative, getCategoryColor: this.getCategoryColor }} /> this.handleSelect(ev, 0), onUpdateTimerange: actions.updateTimeRange, getCategoryColor: this.getCategoryColor }} /> actions.updateSelected([])} getNarrativeLinks={event => this.getNarrativeLinks(event)} getCategoryColor={this.getCategoryColor} /> this.moveInNarrative(1), onPrev: () => this.moveInNarrative(-1), onSelectNarrative: this.setNarrative }} /> {app.source ? ( { actions.updateSource(null) } } /> ) : null} {features.USE_COVER && ( {/* enable USE_COVER in config.js features, and customise your header */} {/* pass 'actions.toggleCover' as a prop to your custom header */} )}
) } } function mapDispatchToProps (dispatch) { return { actions: bindActionCreators(actions, dispatch) } } export default connect( state => state, mapDispatchToProps )(Dashboard)