diff --git a/src/actions/index.js b/src/actions/index.js
index b2734d9..6526f5b 100644
--- a/src/actions/index.js
+++ b/src/actions/index.js
@@ -34,9 +34,12 @@ export function fetchDomain () {
.then(response => response.json())
.catch(() => handleError(domainMsg('categories')))
- const narPromise = fetch(NARRATIVE_URL)
- .then(response => response.json())
- .catch(() => handleError(domainMsg('narratives')))
+ let narPromise = Promise.resolve([])
+ if (process.env.features.USE_CATEGORIES) {
+ narPromise = fetch(NARRATIVE_URL)
+ .then(response => response.json())
+ .catch(() => handleError(domainMsg('narratives')))
+ }
let sitesPromise = Promise.resolve([])
if (process.env.features.USE_SITES) {
diff --git a/src/components/TimelineAxis.jsx b/src/components/TimelineAxis.jsx
index b6e4cb3..92f6192 100644
--- a/src/components/TimelineAxis.jsx
+++ b/src/components/TimelineAxis.jsx
@@ -69,7 +69,7 @@ class TimelineAxis extends React.Component {
/>
diff --git a/src/components/presentational/Map/Events.jsx b/src/components/presentational/Map/Events.jsx
index 3df2a34..519cc71 100644
--- a/src/components/presentational/Map/Events.jsx
+++ b/src/components/presentational/Map/Events.jsx
@@ -94,6 +94,7 @@ function MapEvents ({ getCategoryColor, categories, projectPoint, styleLocation,
longitude: '32.2'
}
*/
+ if (!location.latitude || !location.longitude) return null
const { x, y } = projectPoint([location.latitude, location.longitude])
// in narrative mode, only render events in narrative
diff --git a/src/components/presentational/Timeline/DatetimeBar.js b/src/components/presentational/Timeline/DatetimeBar.js
index 0509e01..9660baf 100644
--- a/src/components/presentational/Timeline/DatetimeBar.js
+++ b/src/components/presentational/Timeline/DatetimeBar.js
@@ -21,5 +21,3 @@ export default ({
height={height}
/>
)
-
-// export default () => null
diff --git a/src/components/presentational/Timeline/Events.js b/src/components/presentational/Timeline/Events.js
index bcb79c1..61bef45 100644
--- a/src/components/presentational/Timeline/Events.js
+++ b/src/components/presentational/Timeline/Events.js
@@ -136,22 +136,27 @@ const TimelineEvents = ({
// })
// })
- let projects
+ let renderProjects = () => null
if (process.env.features.ASSOCIATIVE_EVENTS_BY_TAG) {
- projects = datetimes[1]
+ const projects = datetimes[1]
datetimes = datetimes[0]
+ renderProjects = function () {
+ return
+ {projects.map(project => )}
+
+ }
}
return (
- {projects.map(project => ())}
+ {renderProjects()}
{datetimes.map(datetime => renderDatetime(datetime))}
)
diff --git a/src/reducers/schema/eventSchema.js b/src/reducers/schema/eventSchema.js
index 794d6ed..0465ca1 100644
--- a/src/reducers/schema/eventSchema.js
+++ b/src/reducers/schema/eventSchema.js
@@ -23,7 +23,7 @@ const eventSchema = Joi.object().keys({
narrative___stepStyles: Joi.array()
})
.and('latitude', 'longitude')
- .and('date', 'time', 'timestamp')
+ .and('date', 'timestamp')
.or('timestamp', 'latitude')
export default eventSchema
diff --git a/src/selectors/index.js b/src/selectors/index.js
index 6ca51b2..b8555e4 100644
--- a/src/selectors/index.js
+++ b/src/selectors/index.js
@@ -60,6 +60,9 @@ export const selectEvents = createSelector(
export const selectNarratives = createSelector(
[getEvents, getNarratives, getSources],
(events, narrativesMeta, sources) => {
+ if (!process.env.features.USE_NARRATIVES) {
+ return []
+ }
const narratives = {}
const narrativeSkeleton = id => ({ id, steps: [] })
@@ -157,7 +160,16 @@ export const selectDatetimes = createSelector(
const datetimes = {}
events.forEach(event => {
const { timestamp } = event
- const dtKey = `${timestamp}_1`
+ /** Create timestamp with fresh dtKey always by default */
+ let dtIdx = 1
+ let dtKey = `${timestamp}_${dtIdx}`
+ let tsExists = datetimes.hasOwnProperty(dtKey)
+ while (tsExists) {
+ dtIdx += 1
+ dtKey = `${timestamp}_${dtIdx}`
+ tsExists = datetimes.hasOwnProperty(dtKey)
+ }
+
if (IS_PROJ) {
const project = event.tags.length >= 1 ? event.tags[0] : null
event = { ...event, project }
@@ -170,64 +182,85 @@ export const selectDatetimes = createSelector(
}
}
}
- const tsExists = datetimes.hasOwnProperty(dtKey)
- const isLocated = !!event.latitude && !!event.longitude
- if (IS_PROJ && !isLocated && event.project !== null && tsExists) {
- if (tsExists) {
- alert('not yet handling cases with multiple... talk to lk@forensic-architecture.org')
+
+ /** We need to work out whether we can add the event to an existing
+ * timestamp, or whether we need to create a new one. What determines
+ * this is whether or not ALL events in a timestamp have a matching
+ * project. We not only need to check the current dtKey, but also all
+ * dtKeys that have the same timestamp.
+ *
+ * It's a pretty whack algorithm, but I think it does what it's supposed
+ * to. This is only run when projects are showing.
+ * TODO: find a more module way to interface with this code.
+ */
+ let shouldCreate = true
+ if (IS_PROJ && dtIdx >= 2 && !(!!event.latitude && !!event.longitude) && event.project !== null) {
+ const allExistingIdxs = [...Array(dtIdx - 1).keys()].map(k => k + 1)
+ let foundMatching = false
+ allExistingIdxs.forEach(_idx => {
+ const _dtKey = `${timestamp}_${_idx}`
+ const isSameTimestampAndAllSameProjects = datetimes[_dtKey].events.every(ev => ev.project === event.project)
+ if (isSameTimestampAndAllSameProjects) {
+ dtKey = _dtKey
+ foundMatching = true
+ }
+ })
+ if (!foundMatching) {
+ shouldCreate = true
}
- } else if (tsExists) {
- datetimes[dtKey].events.push(event)
- } else {
+ }
+ if (shouldCreate) {
datetimes[dtKey] = {
timestamp: event.timestamp,
date: event.date,
time: event.time,
events: [event]
}
+ } else {
+ datetimes[dtKey].events.push(event)
}
})
- const projKeys = Object.keys(projects)
- function checkActive (pj, dt) {
- return dt >= projects[pj].start && dt <= projects[pj].end
- }
+
const output = []
- let sortedDts = Object.keys(datetimes)
- sortedDts.sort((a, b) => {
- const x = a.substring(0, a.length - 2)
- const y = b.substring(0, b.length - 2)
- return new Date(x) - new Date(y)
- })
- sortedDts.forEach(dt => {
- const activeProjects = []
- projKeys.forEach((k, idx) => {
- if (checkActive(k, dt)) activeProjects.push(k)
+ if (IS_PROJ) {
+ const projKeys = Object.keys(projects)
+ let sortedDts = Object.keys(datetimes)
+
+ sortedDts.sort((a, b) => {
+ const x = a.substring(0, a.length - 2)
+ const y = b.substring(0, b.length - 2)
+ return new Date(x) - new Date(y)
})
- output.push({
- ...datetimes[dt],
- events: datetimes[dt].events.map(ev => {
- let projectOffset = (activeProjects.indexOf(ev.project) + 1) * (2.5 * sizes.eventDotR)
- if (ev.project !== null && !projects[ev.project].hasOwnProperty('offset')) {
- projects[ev.project].offset = projectOffset
- projects[ev.project].category = ev.category
- } else if (ev.project !== null) {
- projectOffset = projects[ev.project].offset
- }
- return {
- ...ev,
- projectOffset
- }
+ sortedDts.forEach(dt => {
+ const activeProjects = []
+ projKeys.forEach((k, idx) => {
+ if (dt >= projects[k].start && dt <= projects[k].end) activeProjects.push(k)
+ })
+ output.push({
+ ...datetimes[dt],
+ events: datetimes[dt].events.map(ev => {
+ let projectOffset = (activeProjects.indexOf(ev.project) + 1) * (2.5 * sizes.eventDotR)
+ if (ev.project !== null && !projects[ev.project].hasOwnProperty('offset')) {
+ projects[ev.project].offset = projectOffset
+ projects[ev.project].category = ev.category
+ } else if (ev.project !== null) {
+ projectOffset = projects[ev.project].offset
+ }
+ return {
+ ...ev,
+ projectOffset
+ }
+ })
})
})
- })
- const projectsOut = []
- Object.keys(projects).forEach(projId => {
- projectsOut.push({ ...projects[projId], id: projId })
- })
- if (IS_PROJ) {
+ const projectsOut = []
+ Object.keys(projects).forEach(projId => {
+ projectsOut.push({ ...projects[projId], id: projId })
+ })
return [output, projectsOut]
}
- return output
+
+ return Object.values(datetimes)
}
)