mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-11 21:08:36 +03:00
map and cards clickable
This commit is contained in:
@@ -260,6 +260,14 @@ export function decrementNarrativeCurrent () {
|
||||
}
|
||||
}
|
||||
|
||||
export const SELECT_NARRATIVE_EVENT = 'SELECT_NARRATIVE_EVENT'
|
||||
export function selectNarrativeEvent (idx) {
|
||||
return {
|
||||
type: SELECT_NARRATIVE_EVENT,
|
||||
idx
|
||||
}
|
||||
}
|
||||
|
||||
export const UPDATE_SOURCE = 'UPDATE_SOURCE'
|
||||
export function updateSource (source) {
|
||||
return {
|
||||
|
||||
@@ -163,8 +163,8 @@ class Card extends React.Component {
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
render () {
|
||||
const { isSelected, idx } = this.props
|
||||
|
||||
return (
|
||||
@@ -172,6 +172,7 @@ class Card extends React.Component {
|
||||
className={`event-card ${isSelected ? 'selected' : ''}`}
|
||||
id={`event-card-${idx}`}
|
||||
ref={this.props.innerRef}
|
||||
onClick={(e) => {this.props.onClick(idx);} }
|
||||
>
|
||||
{this.renderMain()}
|
||||
{this.state.isOpen ? this.renderExtra() : null}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
import * as selectors from '../selectors'
|
||||
import * as actions from '../actions'
|
||||
|
||||
import Card from './Card.jsx'
|
||||
import copy from '../common/data/copy.json'
|
||||
@@ -8,6 +10,7 @@ import copy from '../common/data/copy.json'
|
||||
class CardStack extends React.Component {
|
||||
constructor () {
|
||||
super()
|
||||
this.onCardClick = this.onCardClick.bind(this)
|
||||
this.refs = {}
|
||||
this.refCardStack = React.createRef()
|
||||
this.refCardStackContent = React.createRef()
|
||||
@@ -61,6 +64,7 @@ class CardStack extends React.Component {
|
||||
this.refs[idx] = thisRef
|
||||
return (<Card
|
||||
event={event}
|
||||
idx={idx}
|
||||
ref={thisRef}
|
||||
sourceError={this.props.sourceError}
|
||||
language={this.props.language}
|
||||
@@ -74,10 +78,15 @@ class CardStack extends React.Component {
|
||||
onHighlight={this.props.onHighlight}
|
||||
onSelect={this.props.onSelect}
|
||||
features={this.props.features}
|
||||
onClick={this.onCardClick}
|
||||
/>)
|
||||
})
|
||||
}
|
||||
|
||||
onCardClick (idx) {
|
||||
this.props.actions.selectNarrativeEvent(idx)
|
||||
}
|
||||
|
||||
renderSelectedCards () {
|
||||
const { selected } = this.props
|
||||
if (selected.length > 0) {
|
||||
@@ -126,7 +135,7 @@ class CardStack extends React.Component {
|
||||
renderNarrativeContent () {
|
||||
return (
|
||||
<div id='card-stack-content' className='card-stack-content'
|
||||
ref={this.refCardStackContent}
|
||||
ref={this.refCardStackContent}
|
||||
>
|
||||
<ul>
|
||||
{this.renderNarrativeCards()}
|
||||
@@ -185,4 +194,10 @@ function mapStateToProps (state) {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(CardStack)
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators(actions, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(CardStack)
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
import React from 'react'
|
||||
import { Portal } from 'react-portal'
|
||||
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
import * as selectors from '../selectors'
|
||||
import * as actions from '../actions'
|
||||
|
||||
import hash from 'object-hash'
|
||||
import 'leaflet'
|
||||
@@ -30,6 +32,7 @@ class Map extends React.Component {
|
||||
mapTransformY: 0
|
||||
}
|
||||
this.styleLocation = this.styleLocation.bind(this)
|
||||
this.onSelectNarrativeEvent = this.onSelectNarrativeEvent.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
@@ -202,6 +205,11 @@ class Map extends React.Component {
|
||||
return [null, null]
|
||||
}
|
||||
|
||||
onSelectNarrativeEvent (idx) {
|
||||
console.log(idx)
|
||||
this.props.actions.selectNarrativeEvent(idx)
|
||||
}
|
||||
|
||||
renderEvents () {
|
||||
return (
|
||||
<Events
|
||||
@@ -214,7 +222,7 @@ class Map extends React.Component {
|
||||
selected={this.props.app.selected}
|
||||
narrative={this.props.app.narrative}
|
||||
onSelect={this.props.methods.onSelect}
|
||||
onSelectNarrative={this.props.methods.onSelectNarrative}
|
||||
onSelectNarrative={this.onSelectNarrativeEvent}
|
||||
getCategoryColor={this.props.methods.getCategoryColor}
|
||||
eventRadius={this.props.ui.eventRadius}
|
||||
/>
|
||||
@@ -298,4 +306,10 @@ function mapStateToProps (state) {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(Map)
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators(actions, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Map)
|
||||
|
||||
@@ -13,7 +13,8 @@ function MapEvents ({
|
||||
onSelect,
|
||||
svg,
|
||||
locations,
|
||||
eventRadius
|
||||
eventRadius,
|
||||
onSelectNarrative
|
||||
}) {
|
||||
function getCoordinatesForPercent (radius, percent) {
|
||||
const x = radius * Math.cos(2 * Math.PI * percent)
|
||||
@@ -110,6 +111,9 @@ function MapEvents ({
|
||||
|
||||
// in narrative mode, only render events in narrative
|
||||
// TODO: move this to a selector
|
||||
// Gets around if block scope
|
||||
var narrativeIdx = false;
|
||||
|
||||
if (narrative) {
|
||||
const { steps } = narrative
|
||||
const onlyIfInNarrative = e => steps.map(s => s.id).includes(e.id)
|
||||
@@ -117,6 +121,11 @@ function MapEvents ({
|
||||
|
||||
if (eventsInNarrative.length <= 0) {
|
||||
return null
|
||||
} else {
|
||||
// choose the first event at a given location
|
||||
const locationEventId = eventsInNarrative[0].id;
|
||||
const narrativeIdxObj = steps.find(s => s.id == locationEventId)
|
||||
narrativeIdx = steps.indexOf(narrativeIdxObj)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +136,7 @@ function MapEvents ({
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
const isSelected = selected.reduce((acc, event) => {
|
||||
const isSelected = selected.reduce((acc, event) => {
|
||||
return acc || (event.latitude === location.latitude && event.longitude === location.longitude)
|
||||
}, false)
|
||||
|
||||
@@ -136,7 +145,7 @@ function MapEvents ({
|
||||
<g
|
||||
className={`location-event ${narrative ? 'no-hover' : ''}`}
|
||||
transform={`translate(${x}, ${y})`}
|
||||
onClick={(!narrative) ? () => onSelect(location.events) : null}
|
||||
onClick={(!narrative) ? () => onSelect(location.events) : () => {onSelectNarrative(narrativeIdx); onSelect(location.events)}}
|
||||
>
|
||||
{renderLocationSlicesByCategory(location)}
|
||||
{extraRender ? extraRender() : null}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
UPDATE_NARRATIVE,
|
||||
INCREMENT_NARRATIVE_CURRENT,
|
||||
DECREMENT_NARRATIVE_CURRENT,
|
||||
SELECT_NARRATIVE_EVENT,
|
||||
UPDATE_SOURCE,
|
||||
TOGGLE_LANGUAGE,
|
||||
TOGGLE_SITES,
|
||||
@@ -120,6 +121,17 @@ function decrementNarrativeCurrent (appState, action) {
|
||||
}
|
||||
}
|
||||
|
||||
function selectNarrativeEvent (appState, action) {
|
||||
appState.narrativeState.current = action.idx
|
||||
|
||||
return {
|
||||
...appState,
|
||||
narrativeState: {
|
||||
current: appState.narrativeState.current
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFilter (appState, action) {
|
||||
if (!(action.value instanceof Array)) {
|
||||
action.value = [action.value]
|
||||
@@ -249,6 +261,8 @@ function app (appState = initial.app, action) {
|
||||
return incrementNarrativeCurrent(appState, action)
|
||||
case DECREMENT_NARRATIVE_CURRENT:
|
||||
return decrementNarrativeCurrent(appState, action)
|
||||
case SELECT_NARRATIVE_EVENT:
|
||||
return selectNarrativeEvent(appState, action)
|
||||
case UPDATE_SOURCE:
|
||||
return updateSource(appState, action)
|
||||
/* toggles */
|
||||
|
||||
Reference in New Issue
Block a user