mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-12 21:38:35 +03:00
Remove unnecessary renders in map / timeline and style narrative mode
This commit is contained in:
committed by
Lachlan Kermode
parent
3e9b621655
commit
0bc4ddc54e
@@ -26,6 +26,7 @@ class NarrativeCard extends React.Component {
|
||||
componentDidUpdate() {
|
||||
if (this.props.narrative !== null) {
|
||||
const step = this.props.narrative.steps[this.state.step];
|
||||
console.log(step)
|
||||
this.props.onSelect([step]);
|
||||
}
|
||||
}
|
||||
@@ -34,7 +35,7 @@ class NarrativeCard extends React.Component {
|
||||
return (
|
||||
<button
|
||||
className="side-menu-burg is-active"
|
||||
onClick={() => { this.props.actions.updateNarrative(null); }}
|
||||
onClick={() => { this.props.onSelectNarrative(null); }}
|
||||
>
|
||||
<span></span>
|
||||
</button>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import * as selectors from '../selectors';
|
||||
import hash from 'object-hash';
|
||||
|
||||
import copy from '../js/data/copy.json';
|
||||
import { formatterWithYear } from '../js/utilities';
|
||||
import { formatterWithYear, isNotNullNorUndefined } from '../js/utilities';
|
||||
import TimelineHeader from './presentational/TimelineHeader';
|
||||
import TimelineLogic from '../js/timeline/timeline.js';
|
||||
|
||||
@@ -21,7 +22,9 @@ class Timeline extends React.Component {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.timeline.update(nextProps.domain, nextProps.app);
|
||||
if (hash(nextProps) !== hash(this.props)) {
|
||||
this.timeline.update(nextProps.domain, nextProps.app);
|
||||
}
|
||||
}
|
||||
|
||||
onClickArrow() {
|
||||
@@ -32,7 +35,7 @@ class Timeline extends React.Component {
|
||||
|
||||
render() {
|
||||
let classes = `timeline-wrapper ${(this.state.isFolded) ? ' folded' : ''}`;
|
||||
|
||||
classes += (this.props.app.narrative !== null) ? ' narrative-mode' : '';
|
||||
return (
|
||||
<div className={classes}>
|
||||
<TimelineHeader
|
||||
@@ -60,7 +63,8 @@ function mapStateToProps(state) {
|
||||
timerange: selectors.getTimeRange(state),
|
||||
selected: state.app.selected,
|
||||
language: state.app.language,
|
||||
zoomLevels: state.app.zoomLevels
|
||||
zoomLevels: state.app.zoomLevels,
|
||||
narrative: state.app.narrative
|
||||
},
|
||||
ui: {
|
||||
dom: state.ui.dom,
|
||||
|
||||
@@ -7,6 +7,7 @@ import Search from './Search.jsx';
|
||||
import TagListPanel from './TagListPanel.jsx';
|
||||
import ToolbarBottomActions from './ToolbarBottomActions.jsx';
|
||||
import copy from '../js/data/copy.json';
|
||||
import { isNotNullNorUndefined } from '../js/utilities.js';
|
||||
|
||||
class Toolbar extends React.Component {
|
||||
|
||||
@@ -174,8 +175,9 @@ class Toolbar extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const isNarrative = isNotNullNorUndefined(this.props.narrative);
|
||||
return (
|
||||
<div id="toolbar-wrapper" className={`toolbar-wrapper ${this.props.narrative ? 'narrative-mode' : ''}`}>
|
||||
<div id="toolbar-wrapper" className={`toolbar-wrapper ${(isNarrative) ? 'narrative-mode' : ''}`}>
|
||||
{this.renderToolbarTabs()}
|
||||
{this.renderToolbarPanels()}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import * as selectors from '../selectors'
|
||||
import hash from 'object-hash';
|
||||
|
||||
import Map from '../js/map/map.js'
|
||||
import { areEqual } from '../js/utilities.js'
|
||||
|
||||
@@ -15,7 +17,9 @@ class Viewport extends React.Component {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.map.update(nextProps.domain, nextProps.app)
|
||||
if (hash(nextProps) !== hash(this.props)) {
|
||||
this.map.update(nextProps.domain, nextProps.app)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -430,10 +430,11 @@ Stop and start the development process in terminal after you have added your tok
|
||||
}
|
||||
|
||||
if (isNewAppProps) {
|
||||
app.views = newApp.views;
|
||||
app.selected = newApp.selected;
|
||||
app.highlighted = newApp.highlighted;
|
||||
app.mapAnchor = newApp.mapAnchor;
|
||||
app.narrative = newApp.narrative;
|
||||
app.views = newApp.views;
|
||||
}
|
||||
|
||||
if (isNewDomain || isNewAppProps) renderDomain();
|
||||
|
||||
@@ -19,13 +19,13 @@ export default function(newApp, ui, methods) {
|
||||
const domain = {
|
||||
events: [],
|
||||
categories: [],
|
||||
narratives: []
|
||||
}
|
||||
const app = {
|
||||
selected: [],
|
||||
highlighted: null,
|
||||
zoomLevels: newApp.zoomLevels,
|
||||
timerange: newApp.timerange,
|
||||
language: newApp.language
|
||||
selected: [],
|
||||
language: newApp.language,
|
||||
zoomLevels: newApp.zoomLevels
|
||||
}
|
||||
|
||||
// Dimension of the client
|
||||
@@ -517,6 +517,8 @@ export default function(newApp, ui, methods) {
|
||||
* @param {Object} app: Redux state app subtree
|
||||
*/
|
||||
function updateAxis() {
|
||||
updateTimeRange();
|
||||
|
||||
scale.x = d3.scaleTime()
|
||||
.domain(app.timerange)
|
||||
.range([margin.left, WIDTH]);
|
||||
@@ -544,35 +546,39 @@ export default function(newApp, ui, methods) {
|
||||
* @param {Object} newApp: object of time range and selected events
|
||||
*/
|
||||
function update(newDomain, newApp) {
|
||||
if (hash(domain) !== hash(newDomain)) {
|
||||
const isNewDomain = (hash(domain) !== hash(newDomain));
|
||||
const isNewAppProps = (hash(app) !== hash(newApp));
|
||||
|
||||
if (isNewDomain) {
|
||||
domain.categories = newDomain.categories;
|
||||
domain.events = newDomain.events;
|
||||
updateAxis();
|
||||
renderContext();
|
||||
domain.narratives = newDomain.narratives;
|
||||
}
|
||||
if (hash(app) !== hash(newApp)) {
|
||||
|
||||
if (isNewAppProps) {
|
||||
app.timerange = newApp.timerange;
|
||||
app.selected = newApp.selected.slice(0);
|
||||
updateTimeRange();
|
||||
renderTimeLabels();
|
||||
renderEventsAndHighlight();
|
||||
}
|
||||
|
||||
if (isNewDomain || isNewAppProps) renderContent();
|
||||
if (isNewAppProps) renderContext();
|
||||
}
|
||||
|
||||
function renderContext() {
|
||||
renderAxis();
|
||||
renderTimeControls();
|
||||
renderTimeLabels();
|
||||
}
|
||||
|
||||
function renderEventsAndHighlight() {
|
||||
function renderContent() {
|
||||
updateAxis();
|
||||
renderAxis();
|
||||
renderEvents();
|
||||
renderHighlight();
|
||||
}
|
||||
|
||||
function render() {
|
||||
renderContext();
|
||||
renderEventsAndHighlight();
|
||||
renderContent();
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -32,6 +32,7 @@ function updateSelected(appState, action) {
|
||||
}
|
||||
|
||||
function updateNarrative(appState, action) {
|
||||
console.log('this happens')
|
||||
if (action.narrative === null) {
|
||||
return Object.assign({}, appState, {
|
||||
narrative: action.narrative,
|
||||
@@ -43,7 +44,7 @@ function updateNarrative(appState, action) {
|
||||
// Add some margin to the datetime extent
|
||||
minDate = minDate - ((maxDate - minDate) / 20);
|
||||
maxDate = maxDate + ((maxDate - minDate) / 20);
|
||||
return appState;
|
||||
|
||||
return Object.assign({}, appState, {
|
||||
narrative: action.narrative,
|
||||
filters: Object.assign({}, appState.filters, {
|
||||
|
||||
@@ -115,11 +115,17 @@ const initial = {
|
||||
|
||||
narratives: {
|
||||
default: {
|
||||
style: 'solid', // ['dotted', 'solid']
|
||||
opacity: 0.5, // range between 0 and 1
|
||||
stroke: 'transparent', // Any hex or rgb code
|
||||
strokeWidth: 2
|
||||
style: 'dotted', // ['dotted', 'solid']
|
||||
opacity: 0.9, // range between 0 and 1
|
||||
stroke: 'red', // Any hex or rgb code
|
||||
strokeWidth: 3
|
||||
},
|
||||
narrative_1: {
|
||||
style: 'solid', // ['dotted', 'solid']
|
||||
opacity: 0.4, // range between 0 and 1
|
||||
stroke: '#f18f01', // Any hex or rgb code
|
||||
strokeWidth: 3
|
||||
}
|
||||
}
|
||||
},
|
||||
dom: {
|
||||
|
||||
Reference in New Issue
Block a user