diff --git a/package.json b/package.json index 299fd3b..e04491f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build": "NODE_ENV=production webpack --mode production", "test": "ava --verbose", "test-watch": "ava --watch", - "lint": "standard \"src/**/*.js\" \"test/**/*.js\"" + "lint": "standard \"src/**/*.js\" \"src/**/*.jsx\" \"test/**/*.js\"" }, "dependencies": { "babel-polyfill": "^6.26.0", diff --git a/src/components/App.jsx b/src/components/App.jsx index 5dc0868..ac12e14 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -1,16 +1,15 @@ -import '../scss/main.scss'; -import React from 'react'; -import Dashboard from './Dashboard.jsx'; +import '../scss/main.scss' +import React from 'react' +import Dashboard from './Dashboard.jsx' class App extends React.Component { - - render() { + render () { return (
- ); + ) } } -export default App; +export default App diff --git a/src/components/Card.jsx b/src/components/Card.jsx index b77e31c..74c2a37 100644 --- a/src/components/Card.jsx +++ b/src/components/Card.jsx @@ -1,59 +1,40 @@ import copy from '../js/data/copy.json' import { - isNotNullNorUndefined, parseDate, formatterWithYear } from '../js/utilities' import React from 'react' -import Spinner from './presentational/Spinner' import CardTimestamp from './presentational/Card/Timestamp' import CardLocation from './presentational/Card/Location' import CardCaret from './presentational/Card/Caret' import CardTags from './presentational/Card/Tags' import CardSummary from './presentational/Card/Summary' import CardSource from './presentational/Card/Source' -import CardCategory from './presentational/Card/Category' import CardNarrative from './presentational/Card/Narrative' class Card extends React.Component { - - constructor(props) { + constructor (props) { super(props) this.state = { isOpen: false } } - toggle() { + toggle () { this.setState({ isOpen: !this.state.isOpen }) } - makeTimelabel(timestamp) { + makeTimelabel (timestamp) { if (timestamp === null) return null const parsedTimestamp = parseDate(timestamp) const timelabel = formatterWithYear(parsedTimestamp) return timelabel } - renderCategory() { - const categoryTitle = copy[this.props.language].cardstack.category - const categoryLabel = this.props.event.category - const color = this.props.getCategoryColor(this.props.event.category) - - return null - // return ( - // - // ) - } - - renderSummary() { + renderSummary () { return ( ERROR: something went wrong loading sources, TODO: } - const source_lang = copy[this.props.language].cardstack.sources + const sourceLang = copy[this.props.language].cardstack.sources return (
-

{source_lang}:

+

{sourceLang}:

{this.props.event.sources.map(source => ( this.makeTimelabel(timestamp)} @@ -115,11 +96,10 @@ class Card extends React.Component { ) } - renderNarrative() { + renderNarrative () { const links = this.props.getNarrativeLinks(this.props.event) if (links !== null) { - return ( this.props.onSelect([event])} @@ -131,7 +111,7 @@ class Card extends React.Component { } } - renderMain() { + renderMain () { return (
@@ -144,7 +124,7 @@ class Card extends React.Component { ) } - renderExtra() { + renderExtra () { return (
{this.renderTags()} @@ -154,7 +134,7 @@ class Card extends React.Component { ) } - renderCaret() { + renderCaret () { return ( this.toggle()} @@ -163,10 +143,10 @@ class Card extends React.Component { ) } - render() { + render () { const { isSelected } = this.props return ( -
  • +
  • {this.renderMain()} {this.state.isOpen ? this.renderExtra() : null} {isSelected ? this.renderCaret() : null} diff --git a/src/components/CardStack.jsx b/src/components/CardStack.jsx index 4d37399..f2e908c 100644 --- a/src/components/CardStack.jsx +++ b/src/components/CardStack.jsx @@ -4,15 +4,11 @@ import * as selectors from '../selectors' import Card from './Card.jsx' import copy from '../js/data/copy.json' -import { - isNotNullNorUndefined -} from '../js/utilities.js' class CardStack extends React.Component { - renderCards(events, selections) { + renderCards (events, selections) { // if no selections provided, select all - if (!selections) - selections = events.map(e => true) + if (!selections) { selections = events.map(e => true) } return events.map((event, idx) => ( 0) { return this.renderCards(selected) @@ -40,7 +36,7 @@ class CardStack extends React.Component { return null } - renderNarrativeCards() { + renderNarrativeCards () { const { narrative } = this.props const showing = narrative.steps.slice(narrative.current) const selections = showing @@ -49,8 +45,8 @@ class CardStack extends React.Component { return this.renderCards(showing, selections) } - renderCardStackHeader() { - const header_lang = copy[this.props.language].cardstack.header + renderCardStackHeader () { + const headerLang = copy[this.props.language].cardstack.header return (
    this.props.onToggleCardstack()} > - -

    - {`${this.props.selected.length} ${header_lang}`} + +

    + {`${this.props.selected.length} ${headerLang}`}

    ) } - renderCardStackContent() { + renderCardStackContent () { return ( -
    +
      {this.renderSelectedCards()}
    @@ -76,9 +72,9 @@ class CardStack extends React.Component { ) } - renderNarrativeContent() { + renderNarrativeContent () { return ( -
    +
      {this.renderNarrativeCards()}
    @@ -86,14 +82,14 @@ class CardStack extends React.Component { ) } - render() { + render () { const { isCardstack, selected, narrative } = this.props if (selected.length > 0) { if (!narrative) { return (
    + return
    } } -function mapStateToProps(state) { +function mapStateToProps (state) { return { narrative: selectors.selectActiveNarrative(state), selected: selectors.selectSelected(state), diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index 7465bb7..fb60c28 100644 --- a/src/components/Dashboard.jsx +++ b/src/components/Dashboard.jsx @@ -14,10 +14,10 @@ import InfoPopUp from './InfoPopup.jsx' import Timeline from './Timeline.jsx' import Notification from './Notification.jsx' -import { parseDate, injectSource } from '../js/utilities' +import { parseDate } from '../js/utilities' class Dashboard extends React.Component { - constructor(props) { + constructor (props) { super(props) this.handleViewSource = this.handleViewSource.bind(this) @@ -30,28 +30,28 @@ class Dashboard extends React.Component { this.eventsById = {} } - componentDidMount() { + componentDidMount () { if (!this.props.app.isMobile) { this.props.actions.fetchDomain() .then(domain => this.props.actions.updateDomain(domain)) } } - handleHighlight(highlighted) { - this.props.actions.updateHighlighted((highlighted) ? highlighted : null) + handleHighlight (highlighted) { + this.props.actions.updateHighlighted((highlighted) || null) } - getEventById(eventId) { + getEventById (eventId) { if (this.eventsById[eventId]) return this.eventsById[eventId] this.eventsById[eventId] = this.props.domain.events.find(ev => ev.id === eventId) return this.eventsById[eventId] } - handleViewSource(source) { + handleViewSource (source) { this.props.actions.updateSource(source) } - handleSelect(selected) { + handleSelect (selected) { if (selected) { let eventsToSelect = selected.map(event => this.getEventById(event.id)) eventsToSelect = eventsToSelect.sort((a, b) => parseDate(a.timestamp) - parseDate(b.timestamp)) @@ -60,24 +60,23 @@ class Dashboard extends React.Component { } } - getCategoryColor(category) { + getCategoryColor (category) { return this.props.ui.style.categories[category] || this.props.ui.style.categories['default'] } - getNarrativeLinks(event) { + 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) { + setNarrative (narrative) { // only handleSelect if narrative is not null - if (!!narrative) - this.handleSelect([ narrative.steps[0] ]) + if (narrative) { this.handleSelect([ narrative.steps[0] ]) } this.props.actions.updateNarrative(narrative) } - moveInNarrative(amt) { + moveInNarrative (amt) { const { current } = this.props.app.narrativeState const { narrative } = this.props.app @@ -91,7 +90,7 @@ class Dashboard extends React.Component { } } - render() { + render () { const { actions, app, domain, ui } = this.props return (
    @@ -107,7 +106,7 @@ class Dashboard extends React.Component { methods={{ onSelect: this.handleSelect, onSelectNarrative: this.setNarrative, - getCategoryColor: this.getCategoryColor, + getCategoryColor: this.getCategoryColor }} /> this.getCategoryColor(category)} /> { - actions.updateSource(null)} + actions.updateSource(null) + } } /> ) : null} @@ -163,7 +163,7 @@ class Dashboard extends React.Component { } } -function mapDispatchToProps(dispatch) { +function mapDispatchToProps (dispatch) { return { actions: bindActionCreators(actions, dispatch) } @@ -172,5 +172,5 @@ function mapDispatchToProps(dispatch) { export default connect( state => state, // state => injectSource("Youtube - Novodvirske Tank Separatist Patrol Video"), - mapDispatchToProps, + mapDispatchToProps )(Dashboard) diff --git a/src/components/Icon.jsx b/src/components/Icon.jsx index 39cb53c..08d8557 100644 --- a/src/components/Icon.jsx +++ b/src/components/Icon.jsx @@ -1,32 +1,32 @@ -import React from 'react'; +import React from 'react' const Icon = ({ iconType }) => { if (iconType === 'personas') { return ( - - - - - - - - + + + + + + + + - ); + ) } else if (iconType === 'tipos') { - return ( - - - - - - ); + c0.228,0,0.449-0.021,0.674-0.034' /> + + + + ) } else if (iconType === 'hardware') { - return ( - - - - ); + C4.678,8.926,5.069,8.534,5.553,8.534L5.553,8.534z' /> + + ) } else if (iconType === 'escenas') { - return ( - - - - - - ); + return ( + + + + + + ) } else if (iconType === 'docs') { - return ( - - - - - - - - - - - - ) + c1.103,0,1.198,0.095,1.198,1.197V36.866z' /> + + + + + + + + + ) } else if (iconType === 'search') { return ( - - - + + + - ); + ) } } -export default Icon; +export default Icon diff --git a/src/components/InfoPopup.jsx b/src/components/InfoPopup.jsx index 6560759..df14cb8 100644 --- a/src/components/InfoPopup.jsx +++ b/src/components/InfoPopup.jsx @@ -1,22 +1,21 @@ -import React from 'react'; -import copy from '../js/data/copy.json'; +import React from 'react' +import copy from '../js/data/copy.json' // NB: should we make this componetn part of a future feature? -export default class InfoPopUp extends React.Component{ - - renderView2DCopy() { - return copy[this.props.app.language].legend.view2d.paragraphs.map(paragraph =>

    {paragraph}

    ); +export default class InfoPopUp extends React.Component { + renderView2DCopy () { + return copy[this.props.app.language].legend.view2d.paragraphs.map(paragraph =>

    {paragraph}

    ) } - renderCategoryColors() { - const colors = copy[this.props.app.language].legend.view2d.colors.slice(0); - colors.reverse(); + renderCategoryColors () { + const colors = copy[this.props.app.language].legend.view2d.colors.slice(0) + colors.reverse() return ( -
    +
    {colors.map((color, idx) => { return ( -
    -
    +
    +
    {color.label}
    ) @@ -25,51 +24,51 @@ export default class InfoPopUp extends React.Component{ ) } - renderView2DLegend() { + renderView2DLegend () { return (
    - + {this.renderView2DCopy()} -
    -
    - - - - - - +
    +
    + + + + + + {this.renderCategoryColors()}
    -
    - - - - +
    + + + + -
    -
    Comunicaciones
    +
    +
    Comunicaciones
    -
    - - +
    + + -
    -
    Ataques
    +
    +
    Ataques
    -
    - - - - - - +
    + + + + + + -
    -
    Rutas de bus
    +
    +
    Rutas de bus
    @@ -77,7 +76,7 @@ export default class InfoPopUp extends React.Component{ ) } - render() { + render () { return (
    {this.renderView2DLegend()}
    ) diff --git a/src/components/Map.jsx b/src/components/Map.jsx index d5c8d85..7074381 100644 --- a/src/components/Map.jsx +++ b/src/components/Map.jsx @@ -1,3 +1,4 @@ +/* global L */ import React from 'react' import { Portal } from 'react-portal' @@ -7,8 +8,6 @@ import * as selectors from '../selectors' import hash from 'object-hash' import 'leaflet' -import { isNotNullNorUndefined } from '../js/utilities' - import Sites from './presentational/Map/Sites.jsx' import Shapes from './presentational/Map/Shapes.jsx' import Events from './presentational/Map/Events.jsx' @@ -21,7 +20,7 @@ const supportedMapboxMap = ['streets', 'satellite'] const defaultToken = 'your_token' class Map extends React.Component { - constructor() { + constructor () { super() this.projectPoint = this.projectPoint.bind(this) this.svgRef = React.createRef() @@ -33,18 +32,18 @@ class Map extends React.Component { this.styleLocation = this.styleLocation.bind(this) } - componentDidMount(){ + componentDidMount () { if (this.map === null) { this.initializeMap() } } - componentWillReceiveProps(nextProps) { + componentWillReceiveProps (nextProps) { // Set appropriate zoom for narrative const { bounds } = nextProps.app.map - if (hash(bounds) !== hash(this.props.app.map.bounds) - && bounds !== null) { - this.map.fitBounds(bounds) + if (hash(bounds) !== hash(this.props.app.map.bounds) && + bounds !== null) { + this.map.fitBounds(bounds) } else { if (hash(nextProps.app.selected) !== hash(this.props.app.selected)) { // Fly to first of events selected @@ -57,7 +56,7 @@ class Map extends React.Component { } } - initializeMap() { + initializeMap () { /** * Creates a Leaflet map and a tilelayer for the map background */ @@ -69,22 +68,22 @@ class Map extends React.Component { .setMaxZoom(mapConf.maxZoom) .setMaxBounds(mapConf.maxBounds) - let s + let firstLayer if ((supportedMapboxMap.indexOf(this.props.ui.tiles) !== -1) && process.env.MAPBOX_TOKEN && process.env.MAPBOX_TOKEN !== defaultToken) { - s = L.tileLayer( + firstLayer = L.tileLayer( `http://a.tiles.mapbox.com/v4/mapbox.${this.props.ui.tiles}/{z}/{x}/{y}@2x.png?access_token=${process.env.MAPBOX_TOKEN}` ) } else if (process.env.MAPBOX_TOKEN && process.env.MAPBOX_TOKEN !== defaultToken) { - s = L.tileLayer( + firstLayer = L.tileLayer( `http://a.tiles.mapbox.com/styles/v1/${this.props.ui.tiles}/tiles/{z}/{x}/{y}?access_token=${process.env.MAPBOX_TOKEN}` ) } else { - s = L.tileLayer( + firstLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' ) } - s = s.addTo(map) + firstLayer.addTo(map) map.keyboard.disable() @@ -96,7 +95,7 @@ class Map extends React.Component { this.map = map } - alignLayers() { + alignLayers () { const mapNode = document.querySelector('.leaflet-map-pane') if (mapNode === null) return { transformX: 0, transformY: 0 } @@ -113,7 +112,7 @@ class Map extends React.Component { }) } - projectPoint(location) { + projectPoint (location) { const latLng = new L.LatLng(location[0], location[1]) return { x: this.map.latLngToLayerPoint(latLng).x + this.state.mapTransformX, @@ -121,7 +120,7 @@ class Map extends React.Component { } } - getClientDims() { + getClientDims () { const boundingClient = document.querySelector(`#${this.props.ui.dom.map}`).getBoundingClientRect() return { @@ -130,7 +129,7 @@ class Map extends React.Component { } } - renderTiles() { + renderTiles () { const pane = this.map.getPanes().overlayPane const { width, height } = this.getClientDims() @@ -140,15 +139,14 @@ class Map extends React.Component { ref={this.svgRef} width={width} height={height} - style={{ transform: `translate3d(${-this.state.mapTransformX}px, ${-this.state.mapTransformY}px, 0)`}} + style={{ transform: `translate3d(${-this.state.mapTransformX}px, ${-this.state.mapTransformY}px, 0)` }} className='leaflet-svg' - > - + /> ) } - renderSites() { + renderSites () { return ( div. */ - styleLocation(location) { + styleLocation (location) { const noEvents = location.events.length return [ null, @@ -200,7 +198,7 @@ class Map extends React.Component { ] } - renderEvents() { + renderEvents () { return ( @@ -235,11 +232,10 @@ class Map extends React.Component { ) } - - render() { + render () { const { isShowingSites } = this.props.app.flags const classes = this.props.app.narrative ? 'map-wrapper narrative-mode' : 'map-wrapper' - const innerMap = !!this.map ? ( + const innerMap = this.map ? ( {this.renderTiles()} {this.renderMarkers()} @@ -260,7 +256,7 @@ class Map extends React.Component { } } -function mapStateToProps(state) { +function mapStateToProps (state) { return { domain: { locations: selectors.selectLocations(state), @@ -289,4 +285,3 @@ function mapStateToProps(state) { } export default connect(mapStateToProps)(Map) - diff --git a/src/components/Md.jsx b/src/components/Md.jsx index 95060e0..118db53 100644 --- a/src/components/Md.jsx +++ b/src/components/Md.jsx @@ -1,31 +1,31 @@ -import React from 'react' +/* global fetch */ +import React from 'react' import PropTypes from 'prop-types' import marked from 'marked' class Md extends React.Component { - constructor(props) { + constructor (props) { super(props) this.state = { md: null, error: null } } - componentDidMount() { + componentDidMount () { fetch(this.props.path) .then(resp => resp.text()) .then(text => { - if (text.length <= 0) - throw new Error() + if (text.length <= 0) { throw new Error() } this.setState({ md: marked(text) }) }) - .catch(err => { + .catch(() => { this.setState({ error: true }) }) } - render() { + render () { if (this.state.md && !this.state.error) { return ( -
    +
    ) } else if (this.state.error) { return this.props.unloader ||
    Error: couldn't load source
    diff --git a/src/components/Notification.jsx b/src/components/Notification.jsx index df44225..4c4a6fb 100644 --- a/src/components/Notification.jsx +++ b/src/components/Notification.jsx @@ -1,34 +1,33 @@ -import React from 'react'; +import React from 'react' -export default class Notification extends React.Component{ - - constructor(props) { - super(); +export default class Notification extends React.Component { + constructor (props) { + super() this.state = { isExtended: false } } - toggleDetails() { - this.setState({ isExtended: !this.state.isExtended }); + toggleDetails () { + this.setState({ isExtended: !this.state.isExtended }) } - renderItems(items) { - if (!items) return ''; + renderItems (items) { + if (!items) return '' return (
    {items.map((item) => { if (item.error) { - return (

    {item.error.message}

    ); + return (

    {item.error.message}

    ) } - return ''; + return '' })}
    ) } - renderNotificationContent(notification) { - let { type, message, items } = notification; + renderNotificationContent (notification) { + let { type, message, items } = notification return (
    @@ -42,28 +41,28 @@ export default class Notification extends React.Component{ ) } - render() { + render () { const notificationsToRender = this.props.notifications.filter(n => !('isRead' in n && n.isRead)) if (notificationsToRender.length > 0) { return (
    {this.props.notifications.map((notification) => { return ( -
    this.toggleDetails() }> +
    this.toggleDetails()}> {this.renderNotificationContent(notification)}
    - ); + ) }) - } + }
    ) } - return (
    ); + return (
    ) } } diff --git a/src/components/Search.jsx b/src/components/Search.jsx index 3cbc40e..30e6bba 100644 --- a/src/components/Search.jsx +++ b/src/components/Search.jsx @@ -1,40 +1,41 @@ -import React from 'react'; -import copy from '../js/data/copy.json'; -import TagFilter from './TagFilter.jsx'; +/* global fetch */ +import React from 'react' +import copy from '../js/data/copy.json' +import TagFilter from './TagFilter.jsx' export default class Search extends React.Component { - constructor(props) { - super(props); + constructor (props) { + super(props) this.state = { searchValue: undefined, searchResults: [] } - this.handleSearchChange = this.handleSearchChange.bind(this); - this.handleSearchSubmit = this.handleSearchSubmit.bind(this); + this.handleSearchChange = this.handleSearchChange.bind(this) + this.handleSearchSubmit = this.handleSearchSubmit.bind(this) } - handleSearchSubmit(e) { - e.preventDefault(); + handleSearchSubmit (e) { + e.preventDefault() fetch(`api/search/${this.state.searchValue}`) .then(response => response.json()) .then(json => { this.setState({ searchResults: json.tags }) - }); + }) } - handleSearchChange(event) { - this.setState({ searchValue: event.target.value }); + handleSearchChange (event) { + this.setState({ searchValue: event.target.value }) } - renderSearchResults() { + renderSearchResults () { return ( this.state.searchResults.map(tag => { return ( - ); + ) }) - ); + ) } - render() { + render () { return ( -
    +

    {copy[this.props.language].toolbar.panels.search.title}

    @@ -66,6 +67,6 @@ export default class Search extends React.Component { {this.renderSearchResults()}
    - ); - } + ) } +} diff --git a/src/components/SourceOverlay.jsx b/src/components/SourceOverlay.jsx index ea1f08d..cce77f5 100644 --- a/src/components/SourceOverlay.jsx +++ b/src/components/SourceOverlay.jsx @@ -7,8 +7,7 @@ import NoSource from './presentational/NoSource' // TODO: move render functions into presentational components class SourceOverlay extends React.Component { - - constructor() { + constructor () { super() this.state = { @@ -16,29 +15,29 @@ class SourceOverlay extends React.Component { } } - renderError() { + renderError () { return ( - + ) } - renderImage(path) { + renderImage (path) { return (
    -
    } - unloader={} - /> +
    } + unloader={} + />
    ) } - renderVideo(path) { + renderVideo (path) { // NB: assume only one video return ( -
    +
    ) } - toMedia(path) { - let type; + toMedia (path) { + let type switch (true) { case /\.(png|jpg)$/.test(path): type = 'Image'; break @@ -82,7 +80,7 @@ class SourceOverlay extends React.Component { return { type, path } } - getTypeCounts(media) { + getTypeCounts (media) { let counts = { Image: 0, Video: 0, Text: 0 } media.forEach(m => { counts[m.type] += 1 @@ -90,7 +88,7 @@ class SourceOverlay extends React.Component { return counts } - _renderPath(media) { + _renderPath (media) { const { path, type } = media switch (type) { case 'Image': @@ -104,101 +102,99 @@ class SourceOverlay extends React.Component { } } - _renderCounts(counts) { + _renderCounts (counts) { const strFor = type => - counts[type] > 0 ? - `${counts[type]} ${type.toLowerCase()}${counts[type] > 1 ? 's': ''}` - : '' + counts[type] > 0 + ? `${counts[type]} ${type.toLowerCase()}${counts[type] > 1 ? 's' : ''}` + : '' const img = strFor('Image') const vid = strFor('Video') const txt = strFor('Text') return (
    - {img ? img : ''} - {(img && vid) ? `, ${vid}`: (vid || '')} - {((img || vid) && txt) ? `, ${txt}`: (txt || '')} + {img || ''} + {(img && vid) ? `, ${vid}` : (vid || '')} + {((img || vid) && txt) ? `, ${txt}` : (txt || '')}
    ) } - _renderContent(media) { - const el = document.querySelector(`.source-media-gallery`); - const shiftW = (!!el) ? el.getBoundingClientRect().width : 0; + _renderContent (media) { + const el = document.querySelector(`.source-media-gallery`) + const shiftW = (el) ? el.getBoundingClientRect().width : 0 return ( -
    +
    {media.map((m) => this._renderPath(m))}
    ) } - onShiftGallery(shift) { - if (this.state.idx === 0 && shift === -1) return; + onShiftGallery (shift) { + if (this.state.idx === 0 && shift === -1) return if (this.state.idx - 1 === this.props.source.paths.length && shift === 1) return - this.setState({ idx: this.state.idx+shift }); + this.setState({ idx: this.state.idx + shift }) } - _renderControls() { + _renderControls () { if (this.props.source.paths.length > 1) { return ( -
    -
    this.onShiftGallery(-1)}>
    -
    this.onShiftGallery(1)}>
    +
    +
    this.onShiftGallery(-1)}>
    +
    this.onShiftGallery(1)}>
    - ); + ) } return ( -
    - ); +
    + ) } render () { - if (typeof(this.props.source) !== 'object') { + if (typeof (this.props.source) !== 'object') { return this.renderError() } - const {id, url, title, paths, date, type, desc} = this.props.source + const { url, title, paths, date, type, desc } = this.props.source const media = paths.map(this.toMedia) - const counts = this.getTypeCounts(media) return ( -
    -
    { e.stopPropagation(); }}> -
    -
    - +
    +
    { e.stopPropagation() }}> +
    +
    +
    -
    {this.props.source.title}
    +
    {this.props.source.title}
    -
    +
    {this._renderContent(media)} {this._renderControls()}
    -
    -
    +
    +
    {/*

    {`${this.state.idx+1} / ${paths.length}`}

    */} - {title?

    {title}

    : null} + {title ?

    {title}

    : null}
    {desc}
    -
    +
    {type ?

    Media type

    : null} - {type ?

    perm_media{type}

    : null} + {type ?

    perm_media{type}

    : null}
    {date ?

    Date

    : null} - {date ?

    today{date}

    : null} + {date ?

    today{date}

    : null}
    {url ?

    Link

    : null} - {url ? linkLink to original URL : null} + {url ? linkLink to original URL : null}
    ) - } } diff --git a/src/components/TagFilter.jsx b/src/components/TagFilter.jsx index 316c339..c6618fc 100644 --- a/src/components/TagFilter.jsx +++ b/src/components/TagFilter.jsx @@ -1,48 +1,44 @@ -import React from 'react'; -import Checkbox from './presentational/Checkbox'; +import React from 'react' +import Checkbox from './presentational/Checkbox' class TagFilter extends React.Component { - constructor(props) { - super(props); - } - - isActive() { + isActive () { if (this.props.isCategory) { - return this.props.categoryFilters.includes(this.props.tag.id); + return this.props.categoryFilters.includes(this.props.tag.id) } - return this.props.tagFilters.includes(this.props.tag.id); + return this.props.tagFilters.includes(this.props.tag.id) } - onClickTag() { + onClickTag () { if (this.isActive()) { this.props.filter({ tags: this.props.tagFilters.filter(element => element !== this.props.tag.id) - }); + }) } else { this.props.filter({ tags: this.props.tagFilters.concat(this.props.tag.id) - }); + }) } } - onClickCategory() { + onClickCategory () { if (this.isActive()) { this.props.filter({ categories: this.props.categoryFilters.filter(element => element !== this.props.tag.id) - }); + }) } else { this.props.filter({ categories: this.props.categoryFilters.concat(this.props.tag.id) - }); + }) } } - renderTag() { - const tag = this.props.tag; - let classes = (this.isActive()) ? 'tag-filter active' : 'tag-filter'; - let label = `${tag.name} ( ${tag.mentions} )`; + renderTag () { + const tag = this.props.tag + let classes = (this.isActive()) ? 'tag-filter active' : 'tag-filter' + let label = `${tag.name} ( ${tag.mentions} )` if (this.props.isShowTree) { - label = `${tag.group} > ${tag.subgroup} > ${tag.name} ( ${tag.mentions} )`; + label = `${tag.group} > ${tag.subgroup} > ${tag.name} ( ${tag.mentions} )` } return (
  • this.onClickTag()} />
  • - ); + ) } - renderCategory() { - const category = this.props.categories[this.props.tag.id]; - let classes = (this.isActive()) ? 'tag-filter active' : 'tag-filter'; + renderCategory () { + const category = this.props.categories[this.props.tag.id] + let classes = (this.isActive()) ? 'tag-filter active' : 'tag-filter' if (category) { return ( @@ -74,15 +70,15 @@ class TagFilter extends React.Component { onClickCheckbox={() => this.onClickCategory()} /> - ); + ) } - return (
    ); + return (
    ) } - render() { - if (this.props.isCategory) return (this.renderCategory()); - return (this.renderTag()); + render () { + if (this.props.isCategory) return (this.renderCategory()) + return (this.renderTag()) } } -export default TagFilter; +export default TagFilter diff --git a/src/components/TagListPanel.jsx b/src/components/TagListPanel.jsx index 3406140..c153a7b 100644 --- a/src/components/TagListPanel.jsx +++ b/src/components/TagListPanel.jsx @@ -1,68 +1,67 @@ -import React from 'react'; -import Checkbox from './presentational/Checkbox'; -import copy from '../js/data/copy.json'; +import React from 'react' +import Checkbox from './presentational/Checkbox' +import copy from '../js/data/copy.json' class TagListPanel extends React.Component { - - constructor(props) { - super(props); + constructor (props) { + super(props) this.state = { treeComponents: [] } - this.treeComponents = []; - this.newTagFilters = []; + this.treeComponents = [] + this.newTagFilters = [] } - componentDidMount() { - this.computeTree(this.props.tags);//.children[this.props.tagType]); + componentDidMount () { + this.computeTree(this.props.tags)// .children[this.props.tagType]); } - componentWillReceiveProps(nextProps) { - this.computeTree(nextProps.tags);//.children[nextProps.tagType]); + componentWillReceiveProps (nextProps) { + this.computeTree(nextProps.tags)// .children[nextProps.tagType]); } - onClickCheckbox(obj, type) { + onClickCheckbox (obj, type) { obj.active = !obj.active - if (type === 'category') this.props.onCategoryFilter(obj); - if (type === 'tag') this.props.onTagFilter(obj); + if (type === 'category') this.props.onCategoryFilter(obj) + if (type === 'tag') this.props.onTagFilter(obj) } createNodeComponent (node, depth) { return (
  • - this.onClickCheckbox(node, 'tag')} - /> + this.onClickCheckbox(node, 'tag')} + />
  • - ); + ) } - traverseNodeAndCreateComponent(node, depth) { + traverseNodeAndCreateComponent (node, depth) { // add and create node component - const newComponent = this.createNodeComponent(node, depth); + const newComponent = this.createNodeComponent(node, depth) this.treeComponents.push(newComponent) - depth = depth + 1; + depth = depth + 1 if (Object.keys(node.children).length > 0) { Object.values(node.children).forEach((childNode) => { - this.traverseNodeAndCreateComponent(childNode, depth); - }); + this.traverseNodeAndCreateComponent(childNode, depth) + }) } } computeTree (node) { - this.treeComponents = []; - let depth = 0; - this.traverseNodeAndCreateComponent(node, depth); - this.setState({ treeComponents: this.treeComponents }); + this.treeComponents = [] + let depth = 0 + this.traverseNodeAndCreateComponent(node, depth) + this.setState({ treeComponents: this.treeComponents }) } - renderTree() { + renderTree () { return (

    {copy[this.props.language].toolbar.tags}

    @@ -71,13 +70,13 @@ class TagListPanel extends React.Component { ) } - renderCategoryTree() { + renderCategoryTree () { return (

    {copy[this.props.language].toolbar.categories}

    {this.props.categories.map(cat => { return (
  • @@ -87,22 +86,22 @@ class TagListPanel extends React.Component { onClickCheckbox={() => this.onClickCheckbox(cat, 'category')} />
  • ) - }) + }) }
    ) } - render() { + render () { return ( -
    +

    {copy[this.props.language].toolbar.explore_by_tag__title}

    {copy[this.props.language].toolbar.explore_by_tag__description}

    {this.renderCategoryTree()} {this.renderTree()}
    - ); + ) } } -export default TagListPanel; +export default TagListPanel diff --git a/src/components/Timeline.jsx b/src/components/Timeline.jsx index 840f05f..6bd810f 100644 --- a/src/components/Timeline.jsx +++ b/src/components/Timeline.jsx @@ -1,3 +1,4 @@ +/* global d3 */ import React from 'react' import { connect } from 'react-redux' import * as selectors from '../selectors' @@ -10,13 +11,12 @@ import Axis from './TimelineAxis.jsx' import Clip from './presentational/Timeline/Clip' import Handles from './presentational/Timeline/Handles.js' import ZoomControls from './presentational/Timeline/ZoomControls.js' -import Labels from './presentational/Timeline/Labels.js' import Markers from './presentational/Timeline/Markers.js' import Events from './presentational/Timeline/Events.js' import Categories from './TimelineCategories.jsx' class Timeline extends React.Component { - constructor(props) { + constructor (props) { super(props) this.styleDatetime = this.styleDatetime.bind(this) this.getDatetimeX = this.getDatetimeX.bind(this) @@ -33,12 +33,12 @@ class Timeline extends React.Component { } } - componentDidMount() { + componentDidMount () { this.computeDims() this.addEventListeners() } - componentWillReceiveProps(nextProps) { + componentWillReceiveProps (nextProps) { if (hash(nextProps) !== hash(this.props)) { this.setState({ timerange: nextProps.app.timeline.range, @@ -59,22 +59,21 @@ class Timeline extends React.Component { } } - addEventListeners() { + addEventListeners () { window.addEventListener('resize', () => { this.computeDims() }) let element = document.querySelector('.timeline-wrapper') - element.addEventListener("transitionend", (event) => { + element.addEventListener('transitionend', (event) => { this.computeDims() }) - } - makeScaleX() { + makeScaleX () { return d3.scaleTime() - .domain(this.state.timerange) - .range([this.state.dims.margin_left, this.state.dims.width - this.state.dims.width_controls]) + .domain(this.state.timerange) + .range([this.state.dims.margin_left, this.state.dims.width - this.state.dims.width_controls]) } - makeScaleY(categories) { + makeScaleY (categories) { const tickHeight = 15 const catsYpos = categories.map((g, i) => (i + 1) * this.state.dims.trackHeight / categories.length + tickHeight / 2) return d3.scaleOrdinal() @@ -82,7 +81,7 @@ class Timeline extends React.Component { .range(catsYpos) } - componentDidUpdate(prevProps, prevState) { + componentDidUpdate (prevProps, prevState) { if (prevState.timerange !== this.state.timerange) { this.setState({ scaleX: this.makeScaleX() }) } @@ -91,19 +90,19 @@ class Timeline extends React.Component { /** * Returns the time scale (x) extent in minutes */ - getTimeScaleExtent() { + getTimeScaleExtent () { if (!this.state.scaleX) return 0 const timeDomain = this.state.scaleX.domain() return (timeDomain[1].getTime() - timeDomain[0].getTime()) / 60000 } - onClickArrow() { + onClickArrow () { this.setState((prevState, props) => { - return {isFolded: !prevState.isFolded} + return { isFolded: !prevState.isFolded } }) } - computeDims() { + computeDims () { const dom = this.props.ui.dom.timeline if (document.querySelector(`#${dom}`) !== null) { const boundingClient = document.querySelector(`#${dom}`).getBoundingClientRect() @@ -114,18 +113,18 @@ class Timeline extends React.Component { width: boundingClient.width } }, - () => { - this.setState({ scaleX: this.makeScaleX() - }) + () => { + this.setState({ scaleX: this.makeScaleX() }) + }) } } - /** + /** * Shift time range by moving forward or backwards * @param {String} direction: 'forward' / 'backwards' */ - onMoveTime(direction) { + onMoveTime (direction) { this.props.methods.onSelect() const extent = this.getTimeScaleExtent() const newCentralTime = d3.timeMinute.offset(this.state.scaleX.domain()[0], extent / 2) @@ -145,11 +144,11 @@ class Timeline extends React.Component { }) } - onCenterTime(newCentralTime) { + onCenterTime (newCentralTime) { const extent = this.getTimeScaleExtent() - const domain0 = d3.timeMinute.offset(newCentralTime, -extent/2) - const domainF = d3.timeMinute.offset(newCentralTime, +extent/2) + const domain0 = d3.timeMinute.offset(newCentralTime, -extent / 2) + const domainF = d3.timeMinute.offset(newCentralTime, +extent / 2) this.setState({ timerange: [domain0, domainF] }, () => { this.props.methods.onUpdateTimerange(this.state.timerange) @@ -161,7 +160,7 @@ class Timeline extends React.Component { * WITHOUT updating the store, or data shown. * Used for updates in the middle of a transition, for performance purposes */ - onSoftTimeRangeUpdate(timerange) { + onSoftTimeRangeUpdate (timerange) { this.setState({ timerange }) } @@ -169,26 +168,26 @@ class Timeline extends React.Component { * Apply zoom level to timeline * @param {object} zoom: zoom level from zoomLevels */ - onApplyZoom(zoom) { + onApplyZoom (zoom) { const extent = this.getTimeScaleExtent() const newCentralTime = d3.timeMinute.offset(this.state.scaleX.domain()[0], extent / 2) this.setState({ timerange: [ d3.timeMinute.offset(newCentralTime, -zoom.duration / 2), d3.timeMinute.offset(newCentralTime, zoom.duration / 2) - ]}, () => { + ] }, () => { this.props.methods.onUpdateTimerange(this.state.timerange) }) } - toggleTransition(isTransition) { + toggleTransition (isTransition) { this.setState({ transitionDuration: (isTransition) ? 300 : 0 }) } /* * Setup drag behavior */ - onDragStart() { + onDragStart () { d3.event.sourceEvent.stopPropagation() this.setState({ dragPos0: d3.event.x @@ -200,7 +199,7 @@ class Timeline extends React.Component { /* * Drag and update */ - onDrag() { + onDrag () { const drag0 = this.state.scaleX.invert(this.state.dragPos0).getTime() const dragNow = this.state.scaleX.invert(d3.event.x).getTime() const timeShift = (drag0 - dragNow) / 1000 @@ -216,12 +215,12 @@ class Timeline extends React.Component { /** * Stop dragging and update data */ - onDragEnd() { + onDragEnd () { this.toggleTransition(true) this.props.methods.onUpdateTimerange(this.state.timerange) } - getDatetimeX(dt) { + getDatetimeX (dt) { return this.state.scaleX(parseDate(dt.timestamp)) } @@ -238,12 +237,12 @@ class Timeline extends React.Component { * at the second index is an optional function that renders additional * components in the div. */ - styleDatetime(timestamp, category) { + styleDatetime (timestamp, category) { return [] } - render() { - const { isNarrative, app, ui } = this.props + render () { + const { isNarrative, app } = this.props let classes = `timeline-wrapper ${(this.state.isFolded) ? ' folded' : ''}` classes += (app.narrative !== null) ? ' narrative-mode' : '' const { dims } = this.state @@ -257,8 +256,8 @@ class Timeline extends React.Component { onClick={() => { this.onClickArrow() }} hideInfo={isNarrative} /> -
    -
    +
    +
    - + /> - + /> - ); + ) } } -export default TimelineAxis; +export default TimelineAxis diff --git a/src/components/TimelineCategories.jsx b/src/components/TimelineCategories.jsx index 6ecdad4..da729a2 100644 --- a/src/components/TimelineCategories.jsx +++ b/src/components/TimelineCategories.jsx @@ -1,58 +1,58 @@ -import React from 'react'; +/* global d3 */ +import React from 'react' class TimelineCategories extends React.Component { - - constructor() { - super(); + constructor () { + super() this.grabRef = React.createRef() this.state = { isInitialized: false } } - componentDidUpdate() { + componentDidUpdate () { if (!this.state.isInitialized) { const drag = d3.drag() - .on('start', this.props.onDragStart) - .on('drag', this.props.onDrag) - .on('end', this.props.onDragEnd); + .on('start', this.props.onDragStart) + .on('drag', this.props.onDrag) + .on('end', this.props.onDragEnd) d3.select(this.grabRef.current) - .call(drag); + .call(drag) - this.setState({ isInitialized: true }); + this.setState({ isInitialized: true }) } } - renderCategory(category, idx) { - const dims = this.props.dims; + renderCategory (category, idx) { + const dims = this.props.dims return ( - - - {category.category} + + + {category.category} ) } render () { - const dims = this.props.dims; + const dims = this.props.dims return ( {this.props.categories.map((cat, idx) => this.renderCategory(cat, idx))} + /> - ); + ) } } -export default TimelineCategories; +export default TimelineCategories diff --git a/src/components/Toolbar.jsx b/src/components/Toolbar.jsx index 9129ea6..c2492d1 100644 --- a/src/components/Toolbar.jsx +++ b/src/components/Toolbar.jsx @@ -4,7 +4,7 @@ import { bindActionCreators } from 'redux' import * as actions from '../actions' import * as selectors from '../selectors' -import { Tab, Tabs, TabList, TabPanel } from 'react-tabs' +import { Tabs, TabPanel } from 'react-tabs' import Search from './Search.jsx' import TagListPanel from './TagListPanel.jsx' import ToolbarBottomActions from './ToolbarBottomActions.jsx' @@ -12,25 +12,25 @@ import copy from '../js/data/copy.json' import { trimAndEllipse } from '../js/utilities.js' class Toolbar extends React.Component { - constructor(props) { + constructor (props) { super(props) this.state = { _selected: -1 } } - selectTab(selected) { + selectTab (selected) { const _selected = (this.state._selected === selected) ? -1 : selected this.setState({ _selected }) } - renderClosePanel() { + renderClosePanel () { return ( -
    this.selectTab(-1)}> -
    +
    this.selectTab(-1)}> +
    - ) + ) } - renderSearch() { + renderSearch () { if (process.env.features.USE_SEARCH) { return ( @@ -47,19 +47,19 @@ class Toolbar extends React.Component { } } - goToNarrative(narrative) { + goToNarrative (narrative) { this.selectTab(-1) // set all unselected within this component this.props.methods.onSelectNarrative(narrative) } - renderToolbarNarrativePanel() { + renderToolbarNarrativePanel () { return (

    {copy[this.props.language].toolbar.narrative_panel_title}

    {copy[this.props.language].toolbar.narrative_summary}

    {this.props.narratives.map((narr) => { return ( -
    +
    */} - {/* */} - {/* */}
    @@ -35,4 +35,4 @@ function ToolbarBottomActions (props) { ) } -export default ToolbarBottomActions; +export default ToolbarBottomActions diff --git a/src/components/presentational/Icons/RefreshIcon.js b/src/components/presentational/Icons/RefreshIcon.js index b67c47a..c4e4009 100644 --- a/src/components/presentational/Icons/RefreshIcon.js +++ b/src/components/presentational/Icons/RefreshIcon.js @@ -1,6 +1,6 @@ import React from 'react' -const RefreshIcon = () => { +export default ({ isActive, isDisabled, onClickHandler }) => { return ( ( +const MapDefsMarkers = () => ( - - + + + + + - - - -); +) -export default MapDefsMarkers; \ No newline at end of file +export default MapDefsMarkers diff --git a/src/components/presentational/Map/Events.jsx b/src/components/presentational/Map/Events.jsx index 39a7901..968fddf 100644 --- a/src/components/presentational/Map/Events.jsx +++ b/src/components/presentational/Map/Events.jsx @@ -1,23 +1,23 @@ -import React from 'react'; -import { Portal } from 'react-portal'; +import React from 'react' +import { Portal } from 'react-portal' -function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation, narrative, onSelect, svg, locations }){ - function getLocationEventsDistribution(location) { - const eventCount = {}; - const categories = categories; +function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation, narrative, onSelect, svg, locations }) { + // function getLocationEventsDistribution (location) { + // const eventCount = {} + // + // categories.forEach(cat => { + // eventCount[cat.category] = [] + // }) + // + // location.events.forEach((event) => { + // ; + // eventCount[event.category].push(event) + // }) + // + // return eventCount + // } - categories.forEach(cat => { - eventCount[cat.category] = []; - }); - - location.events.forEach((event) => {; - eventCount[event.category].push(event); - }); - - return eventCount; - } - - function renderLocation(location) { + function renderLocation (location) { /** { events: [...], @@ -26,7 +26,7 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation, longitude: '32.2' } */ - const { x, y } = projectPoint([location.latitude, location.longitude]); + const { x, y } = projectPoint([location.latitude, location.longitude]) // const eventsByCategory = getLocationEventsDistribution(location); const locCategory = location.events.length > 0 ? location.events[0].category : 'default' @@ -37,7 +37,7 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation, const styles = ({ fill: getCategoryColor(locCategory), fillOpacity: 1, - ...customStyles[0] + ...extraStyles }) // in narrative mode, only render events in narrative @@ -53,16 +53,15 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation, return ( onSelect(location.events)} > - + /> {extraRender ? extraRender() : null} ) @@ -72,7 +71,7 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation, {locations.map(renderLocation)} - ); + ) } -export default MapEvents; +export default MapEvents diff --git a/src/components/presentational/Map/Narratives.jsx b/src/components/presentational/Map/Narratives.jsx index 84452e8..4424900 100644 --- a/src/components/presentational/Map/Narratives.jsx +++ b/src/components/presentational/Map/Narratives.jsx @@ -2,40 +2,39 @@ import React from 'react' import { Portal } from 'react-portal' function MapNarratives ({ styles, onSelectNarrative, svg, narrative, narratives, projectPoint }) { - function getNarrativeStyle(narrativeId) { + function getNarrativeStyle (narrativeId) { const styleName = (narrativeId && narrativeId in styles) ? narrativeId : 'default' return styles[styleName] } - function getStepStyle(name) { + function getStepStyle (name) { if (name === 'None') return null return styles.stepStyles[name] } - function hasNoLocation(step) { + function hasNoLocation (step) { return (step.latitude === '' || step.longitude === '') } - function renderNarrativeStep(idx, n) { + function renderNarrativeStep (idx, n) { const step = n.steps[idx] const step2 = n.steps[idx + 1] // don't draw if one of the steps has no location - if (hasNoLocation(step) || hasNoLocation(step2)) - return null + if (hasNoLocation(step) || hasNoLocation(step2)) { return null } // 0 if not in narrative mode, 1 if active narrative, 0.1 if inactive let styles = { - strokeOpacity: (n === null) ? 0 - : (step && (n.id === narrative.id)) ? 1 : 0.1, + strokeOpacity: (n === null) ? 0 + : (step && (n.id === narrative.id)) ? 1 : 0.1, strokeWidth: 0, strokeDasharray: 'none', stroke: 'none' } - const p1 = projectPoint([step.latitude, step.longitude]) + const p1 = projectPoint([step.latitude, step.longitude]) const p2 = projectPoint([step2.latitude, step2.longitude]) if (step) { @@ -55,40 +54,37 @@ function MapNarratives ({ styles, onSelectNarrative, svg, narrative, narratives, ...styles, ...getNarrativeStyle(n.id) } - return _renderNarrativeStep(p1,p2,styles) + return _renderNarrativeStep(p1, p2, styles) } } - } - function _renderNarrativeStep(p1, p2, styles) { + function _renderNarrativeStep (p1, p2, styles) { const { stroke, strokeWidth, strokeDasharray, strokeOpacity } = styles return ( onSelectNarrative(n)} + markerStart='none' + onClick={n => onSelectNarrative(n)} style={{ strokeWidth, strokeDasharray, strokeOpacity, - stroke, + stroke }} - > - + /> ) - } - function renderNarrative(n) { + function renderNarrative (n) { const steps = n.steps.slice(0, n.steps.length - 1) return ( - + {steps.map((s, idx) => renderNarrativeStep(idx, n))} ) diff --git a/src/components/presentational/Map/SelectedEvents.jsx b/src/components/presentational/Map/SelectedEvents.jsx index 88c3036..abbf984 100644 --- a/src/components/presentational/Map/SelectedEvents.jsx +++ b/src/components/presentational/Map/SelectedEvents.jsx @@ -1,31 +1,30 @@ -import React from 'react'; -import { Portal } from 'react-portal'; +import React from 'react' +import { Portal } from 'react-portal' class MapSelectedEvents extends React.Component { renderMarker (event) { - const { x, y } = this.props.projectPoint([event.latitude, event.longitude]); + const { x, y } = this.props.projectPoint([event.latitude, event.longitude]) return ( - + className='leaflet-interactive' + stroke='#ffffff' + stroke-opacity='1' + stroke-width='3' + stroke-linecap='' + stroke-linejoin='round' + stroke-dasharray='5,2' + fill='none' + d='M0,0a32,32 0 1,0 64,0 a32,32 0 1,0 -64,0 ' + /> - ); + ) } - render() { + render () { return ( {this.props.selected.map(s => this.renderMarker(s))} @@ -33,4 +32,4 @@ class MapSelectedEvents extends React.Component { ) } } -export default MapSelectedEvents; +export default MapSelectedEvents diff --git a/src/components/presentational/Map/Shapes.jsx b/src/components/presentational/Map/Shapes.jsx index 5fab671..b5d9a30 100644 --- a/src/components/presentational/Map/Shapes.jsx +++ b/src/components/presentational/Map/Shapes.jsx @@ -1,15 +1,15 @@ import React from 'react' import { Portal } from 'react-portal' -function MapShapes({ svg, shapes, projectPoint, styles }) { - function renderShape(shape) { +function MapShapes ({ svg, shapes, projectPoint, styles }) { + function renderShape (shape) { const lineCoords = [] const points = shape.points .map(projectPoint) points.forEach((p1, idx) => { if (idx < shape.points.length - 1) { - const p2 = points[idx+1] + const p2 = points[idx + 1] lineCoords.push({ x1: p1.x, y1: p1.y, @@ -27,11 +27,10 @@ function MapShapes({ svg, shapes, projectPoint, styles }) { return ( - + /> ) }) } @@ -40,12 +39,11 @@ function MapShapes({ svg, shapes, projectPoint, styles }) { return ( - + {shapes.map(renderShape)} ) - } export default MapShapes diff --git a/src/components/presentational/Map/Sites.jsx b/src/components/presentational/Map/Sites.jsx index 9d49885..45075de 100644 --- a/src/components/presentational/Map/Sites.jsx +++ b/src/components/presentational/Map/Sites.jsx @@ -1,25 +1,24 @@ -import React from 'react'; +import React from 'react' -function MapSites({ sites, projectPoint }) { - function renderSite(site) { - const { x, y } = projectPoint([site.latitude, site.longitude]); +function MapSites ({ sites, projectPoint }) { + function renderSite (site) { + const { x, y } = projectPoint([site.latitude, site.longitude]) return (
    + className='leaflet-tooltip site-label leaflet-zoom-animated leaflet-tooltip-top' + style={{ opacity: 1, transform: `translate3d(calc(${x}px - 50%), ${y - 25}px, 0px)` }}> {site.site}
    - ); + ) } - if (!sites || !sites.length) return null; + if (!sites || !sites.length) return null return ( -
    +
    {sites.map(renderSite)}
    ) - } -export default MapSites; +export default MapSites diff --git a/src/index.jsx b/src/index.jsx index 7342aea..7d5f83b 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,12 +1,12 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { Provider } from 'react-redux'; -import store from './store/index.js'; -import App from './components/App.jsx'; +import React from 'react' +import ReactDOM from 'react-dom' +import { Provider } from 'react-redux' +import store from './store/index.js' +import App from './components/App.jsx' ReactDOM.render( , document.getElementById('explore-app') -); +)