diff --git a/src/components/MapNarratives.jsx b/src/components/MapNarratives.jsx
index 8b92bb8..9d7248b 100644
--- a/src/components/MapNarratives.jsx
+++ b/src/components/MapNarratives.jsx
@@ -18,59 +18,79 @@ 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
- return 1
+ getStepStyle(name) {
+ if (name === 'None') return null
+ return this.props.narrativeProps.stepStyles[name]
}
hasNoLocation(step) {
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) {
+ 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
+ // 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])
+ if (step) {
+ 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 {
+ 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)}
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,
}}
>
)
+
}
renderNarrative(n) {
@@ -78,7 +98,7 @@ class MapNarratives extends React.Component {
return (
- {steps.map((s, idx) => this.renderNarrativeStep(n.steps, s, idx, n))}
+ {steps.map((s, idx) => this.renderNarrativeStep(idx, n))}
)
}
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 (
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/reducers/schema/eventSchema.js b/src/reducers/schema/eventSchema.js
index 614eba2..7e9b38a 100644
--- a/src/reducers/schema/eventSchema.js
+++ b/src/reducers/schema/eventSchema.js
@@ -16,6 +16,9 @@ const eventSchema = Joi.object().keys({
tags: Joi.string().allow(''),
comments: Joi.string().allow(''),
timestamp: Joi.string().required(),
+
+ // nested
+ narrative___stepStyles: Joi.array(),
});
export default eventSchema;
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,
+ }
}
}
},
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({