From 7b44dc8751d59a7431f196a7fb92897a894292d0 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Fri, 4 Jan 2019 13:46:14 +0000 Subject: [PATCH 1/4] allow movements --- src/reducers/schema/eventSchema.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/reducers/schema/eventSchema.js b/src/reducers/schema/eventSchema.js index 614eba2..edf80a2 100644 --- a/src/reducers/schema/eventSchema.js +++ b/src/reducers/schema/eventSchema.js @@ -12,6 +12,7 @@ const eventSchema = Joi.object().keys({ type: Joi.string().allow(''), category: Joi.string().required(), narratives: Joi.array(), + narrative___movements: Joi.array(), sources: Joi.array(), tags: Joi.string().allow(''), comments: Joi.string().allow(''), From f32f96cae3ae871b761614f0e0f0ca46535abcc4 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Fri, 4 Jan 2019 14:04:15 +0000 Subject: [PATCH 2/4] error for bad md extensions --- src/components/Md.jsx | 5 ++++- src/components/SourceOverlay.jsx | 23 ++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/components/Md.jsx b/src/components/Md.jsx index 2510359..eefb1ba 100644 --- a/src/components/Md.jsx +++ b/src/components/Md.jsx @@ -12,6 +12,9 @@ class Md extends React.Component { fetch(this.props.path) .then(resp => resp.text()) .then(text => { + if (text.length <= 0) + throw new Error() + this.setState({ md: marked(text) }) }) .catch(err => { @@ -34,7 +37,7 @@ class Md extends React.Component { Md.propTypes = { loader: PropTypes.func, - unloader: PropTypes.func, + unloader: PropTypes.func.isRequired, path: PropTypes.string.isRequired } diff --git a/src/components/SourceOverlay.jsx b/src/components/SourceOverlay.jsx index 452eebf..b9034ff 100644 --- a/src/components/SourceOverlay.jsx +++ b/src/components/SourceOverlay.jsx @@ -7,15 +7,21 @@ import NoSource from './presentational/NoSource' // TODO: move render functions into presentational components function SourceOverlay ({ source, onCancel }) { + function renderError() { + return ( + + ) + } + function renderImage(path) { return (
- } - unloader={} - /> + } + unloader={} + />
) } @@ -45,11 +51,6 @@ function SourceOverlay ({ source, onCancel }) { ) } - function renderError() { - return ( - - ) - } function renderNoSupport(ext) { return ( From bca43fab2b5df13dbe955e8ebfef86777b8c058f Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Fri, 4 Jan 2019 15:50:47 +0000 Subject: [PATCH 3/4] refactor MapNarratives in prep --- src/components/MapNarratives.jsx | 63 +++++++++++++++++++----------- src/reducers/schema/eventSchema.js | 4 +- webpack.config.js | 23 +++++------ 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/components/MapNarratives.jsx b/src/components/MapNarratives.jsx index 8b92bb8..6b901f1 100644 --- a/src/components/MapNarratives.jsx +++ b/src/components/MapNarratives.jsx @@ -18,21 +18,6 @@ class MapNarratives extends React.Component { return this.props.narrativeProps[styleName] } - getStrokeWidth(narrative, step) { - if (!step) return 0 - return this.getNarrativeStyle(narrative.id).strokeWidth - } - - getStrokeDashArray(narrative, step) { - if (!step) return 'none' - return (this.getNarrativeStyle(narrative.id).style === 'dotted') ? "2px 5px" : 'none' - } - - getStroke(narrative, step) { - if (!step || this.props.narrative === null) return 'none' - return this.getNarrativeStyle(narrative.id).stroke - } - getStrokeOpacity(narrative, step) { if (this.props.narrative === null) return 0 if (!step || narrative.id !== this.props.narrative.id) return 0.1 @@ -43,16 +28,39 @@ class MapNarratives extends React.Component { return (step.latitude === '' || step.longitude === '') } - renderNarrativeStep(allSteps, step, idx, n) { - const { x, y } = this.projectPoint([step.latitude, step.longitude]) - const step2 = allSteps[idx + 1] + renderNarrativeStep(idx, n, stepStyle = null) { + const step = n.steps[idx] + const step2 = n.steps[idx + 1] // don't draw if one of the steps has no location if (this.hasNoLocation(step) || this.hasNoLocation(step2)) return null + const { narrative } = this.props + const { x, y } = this.projectPoint([step.latitude, step.longitude]) const p2 = this.projectPoint([step2.latitude, step2.longitude]) + // 0 if not in narrative mode, 1 if active narrative, 0.1 if inactive + const strokeOpacity = (n === null) ? 0 + : (step && (n.id === narrative.id)) ? 1 : 0.1 + let strokeWidth = 0 + let strokeDasharray = 'none' + let stroke = 'none' + + // style narartive step if appropriate + if (step) { + // stepStyle only provided to functionl if NARRATIVE_STEP_STYLES enabled + if (!!stepStyle) { + console.log('TODO: step by step styling') + // otherwise steps are styled per narrative + } else { + const narStyle = this.getNarrativeStyle(n.id) + stroke = narStyle.stroke + strokeWidth = narStyle.strokeWidth + strokeDasharray = narStyle.strokeDasharray + } + } + return ( this.props.onSelectNarrative(n)} style={{ - strokeWidth: this.getStrokeWidth(n, step), - strokeDasharray: this.getStrokeDashArray(n, step), - strokeOpacity: this.getStrokeOpacity(n, step), - stroke: this.getStroke(n, step) + strokeWidth, + strokeDasharray, + strokeOpacity, + stroke, }} > @@ -78,7 +86,16 @@ class MapNarratives extends React.Component { return ( - {steps.map((s, idx) => this.renderNarrativeStep(n.steps, s, idx, n))} + {steps.map((s, idx) => { + if (process.env.features.NARRATIVE_STEP_STYLES) { + const _idx = s.narratives.indexOf(n.id) + const stepStyle = s.narrative___stepStyles[_idx] + if (stepStyle !== 'None') + return this.renderNarrativeStep(idx, n, stepStyle) + } else { + return this.renderNarrativeStep(idx, n) + } + })} ) } diff --git a/src/reducers/schema/eventSchema.js b/src/reducers/schema/eventSchema.js index edf80a2..7e9b38a 100644 --- a/src/reducers/schema/eventSchema.js +++ b/src/reducers/schema/eventSchema.js @@ -12,11 +12,13 @@ const eventSchema = Joi.object().keys({ type: Joi.string().allow(''), category: Joi.string().required(), narratives: Joi.array(), - narrative___movements: Joi.array(), sources: Joi.array(), tags: Joi.string().allow(''), comments: Joi.string().allow(''), timestamp: Joi.string().required(), + + // nested + narrative___stepStyles: Joi.array(), }); export default eventSchema; diff --git a/webpack.config.js b/webpack.config.js index 768e021..5475885 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,8 +1,6 @@ const webpack = require('webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -const userConfig = require('./config'); -const userConfigJSON = {}; const devMode = process.env.NODE_ENV !== 'production'; const path = require('path'); @@ -10,8 +8,16 @@ const path = require('path'); const APP_DIR = path.resolve(__dirname, './src'); const BUILD_DIR = path.resolve(__dirname, './build'); -for (const k in userConfig) { - userConfigJSON[k] = JSON.stringify(userConfig[k]); +/** env variables from config.js */ +const envConfig = require('./config'); +const userConfig = {} +const userFeatures = {} +for (const k in envConfig) { + userConfig[k] = JSON.stringify(envConfig[k]); +} + +for (const k in envConfig['features']) { + userFeatures[k] = JSON.stringify(envConfig['features'][k]) } const config = { @@ -59,14 +65,9 @@ const config = { plugins: [ new webpack.DefinePlugin({ 'process.env': { - ...userConfigJSON, + ...userConfig, 'NODE_ENV': JSON.stringify('production'), - 'features': { - 'USE_TAGS': JSON.stringify(userConfig.features.USE_TAGS), - 'USE_SEARCH': JSON.stringify(userConfig.features.USE_SEARCH), - 'USE_SITES': JSON.stringify(userConfig.features.USE_SITES), - 'USE_SOURCES': JSON.stringify(userConfig.features.USE_SOURCES) - } + 'features': userFeatures } }), new MiniCssExtractPlugin({ From 314c0540c1808f9486f42306da2e7de45e14747a Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Fri, 4 Jan 2019 16:39:15 +0000 Subject: [PATCH 4/4] allow stepStyles with feature flag --- src/components/MapNarratives.jsx | 71 +++++++++++++++++--------------- src/components/Toolbar.jsx | 4 +- src/store/initial.js | 22 +++++----- 3 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/components/MapNarratives.jsx b/src/components/MapNarratives.jsx index 6b901f1..9d7248b 100644 --- a/src/components/MapNarratives.jsx +++ b/src/components/MapNarratives.jsx @@ -18,17 +18,16 @@ class MapNarratives extends React.Component { return this.props.narrativeProps[styleName] } - getStrokeOpacity(narrative, step) { - if (this.props.narrative === null) return 0 - if (!step || narrative.id !== this.props.narrative.id) return 0.1 - return 1 + getStepStyle(name) { + if (name === 'None') return null + return this.props.narrativeProps.stepStyles[name] } hasNoLocation(step) { return (step.latitude === '' || step.longitude === '') } - renderNarrativeStep(idx, n, stepStyle = null) { + renderNarrativeStep(idx, n) { const step = n.steps[idx] const step2 = n.steps[idx + 1] @@ -36,37 +35,49 @@ class MapNarratives extends React.Component { if (this.hasNoLocation(step) || this.hasNoLocation(step2)) return null - const { narrative } = this.props - const { x, y } = this.projectPoint([step.latitude, step.longitude]) + // 0 if not in narrative mode, 1 if active narrative, 0.1 if inactive + let styles = { + strokeOpacity: (n === null) ? 0 + : (step && (n.id === this.props.narrative.id)) ? 1 : 0.1, + strokeWidth: 0, + strokeDasharray: 'none', + stroke: 'none' + } + + const p1 = this.projectPoint([step.latitude, step.longitude]) const p2 = this.projectPoint([step2.latitude, step2.longitude]) - // 0 if not in narrative mode, 1 if active narrative, 0.1 if inactive - const strokeOpacity = (n === null) ? 0 - : (step && (n.id === narrative.id)) ? 1 : 0.1 - let strokeWidth = 0 - let strokeDasharray = 'none' - let stroke = 'none' - - // style narartive step if appropriate if (step) { - // stepStyle only provided to functionl if NARRATIVE_STEP_STYLES enabled - if (!!stepStyle) { - console.log('TODO: step by step styling') + if (process.env.features.NARRATIVE_STEP_STYLES) { + const _idx = step.narratives.indexOf(n.id) + const stepStyle = step.narrative___stepStyles[_idx] + + return this._renderNarrativeStep( + p1, + p2, + { ...styles, ...this.getStepStyle(stepStyle) } + ) + // otherwise steps are styled per narrative } else { - const narStyle = this.getNarrativeStyle(n.id) - stroke = narStyle.stroke - strokeWidth = narStyle.strokeWidth - strokeDasharray = narStyle.strokeDasharray + styles = { + ...styles, + ...this.getNarrativeStyle(n.id) + } + return this._renderNarrativeStep(p1,p2,styles) } } + } + + _renderNarrativeStep(p1, p2, styles) { + const { stroke, strokeWidth, strokeDasharray, strokeOpacity } = styles return ( this.props.onSelectNarrative(n)} @@ -79,6 +90,7 @@ class MapNarratives extends React.Component { > ) + } renderNarrative(n) { @@ -86,16 +98,7 @@ class MapNarratives extends React.Component { return ( - {steps.map((s, idx) => { - if (process.env.features.NARRATIVE_STEP_STYLES) { - const _idx = s.narratives.indexOf(n.id) - const stepStyle = s.narrative___stepStyles[_idx] - if (stepStyle !== 'None') - return this.renderNarrativeStep(idx, n, stepStyle) - } else { - return this.renderNarrativeStep(idx, n) - } - })} + {steps.map((s, idx) => this.renderNarrativeStep(idx, n))} ) } diff --git a/src/components/Toolbar.jsx b/src/components/Toolbar.jsx index cb3b3da..542456f 100644 --- a/src/components/Toolbar.jsx +++ b/src/components/Toolbar.jsx @@ -29,7 +29,7 @@ class Toolbar extends React.Component { } renderSearch() { - if (this.props.features.USE_SEARCH) { + if (process.env.features.USE_SEARCH) { return ( diff --git a/src/store/initial.js b/src/store/initial.js index 8db1642..77e66d3 100644 --- a/src/store/initial.js +++ b/src/store/initial.js @@ -89,10 +89,6 @@ const initial = { duration: 10, active: false }], - features: { - USE_TAGS: process.env.features.USE_TAGS, - USE_SEARCH: process.env.features.USE_SEARCH - }, flags: { isFetchingDomain: false, isFetchingSources: false, @@ -120,16 +116,22 @@ const initial = { narratives: { default: { - style: 'solid', // ['dotted', 'solid'] - opacity: 0.9, // range between 0 and 1 - stroke: 'red', // Any hex or rgb code + opacity: 0.9, + stroke: 'red', strokeWidth: 3 }, narrative_1: { - style: 'solid', // ['dotted', 'solid'] - opacity: 0.4, // range between 0 and 1 - stroke: '#f18f01', // Any hex or rgb code + opacity: 0.4, + stroke: '#f18f01', strokeWidth: 3 + }, + // process.env.features.NARRATIVE_STEP_STYLES + stepStyles: { + Physical: { + stroke: 'yellow', + strokeWidth: 3, + opacity: 0.9, + } } } },