diff --git a/package.json b/package.json
index c5d556e..45e07bd 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"marked": "^0.6.0",
"normalizr": "^3.2.3",
"object-hash": "^1.3.0",
+ "ramda": "^0.26.1",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-image": "^1.5.1",
diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx
index e0a59aa..5817f83 100644
--- a/src/components/Dashboard.jsx
+++ b/src/components/Dashboard.jsx
@@ -14,7 +14,7 @@ import InfoPopUp from './InfoPopup.jsx'
import Timeline from './Timeline.jsx'
import Notification from './Notification.jsx'
-import { parseDate } from '../js/utilities'
+import { parseDate, injectSource } from '../js/utilities'
class Dashboard extends React.Component {
constructor(props) {
@@ -60,8 +60,8 @@ class Dashboard extends React.Component {
}
}
- getCategoryColor(category='other') {
- return this.props.ui.style.categories[category] || this.props.ui.style.categories['other']
+ getCategoryColor(category) {
+ return this.props.ui.style.categories[category] || this.props.ui.style.categories['default']
}
getNarrativeLinks(event) {
@@ -171,5 +171,6 @@ function mapDispatchToProps(dispatch) {
export default connect(
state => state,
+ // state => injectSource("Youtube - Novodvirske Tank Separatist Patrol Video"),
mapDispatchToProps,
)(Dashboard)
diff --git a/src/components/Md.jsx b/src/components/Md.jsx
index eefb1ba..95060e0 100644
--- a/src/components/Md.jsx
+++ b/src/components/Md.jsx
@@ -25,7 +25,7 @@ class Md extends React.Component {
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/SourceOverlay.jsx b/src/components/SourceOverlay.jsx
index ea94e2d..9191307 100644
--- a/src/components/SourceOverlay.jsx
+++ b/src/components/SourceOverlay.jsx
@@ -6,27 +6,36 @@ import Spinner from './presentational/Spinner'
import NoSource from './presentational/NoSource'
// TODO: move render functions into presentational components
-function SourceOverlay ({ source, onCancel }) {
- function renderError() {
+class SourceOverlay extends React.Component {
+
+ constructor() {
+ super()
+
+ this.state = {
+ idx: 0
+ }
+ }
+
+ renderError() {
return (
)
}
- function renderImage(path) {
+ renderImage(path) {
return (

}
- unloader={}
+ unloader={}
/>
)
}
- function renderVideo(path) {
+ renderVideo(path) {
// NB: assume only one video
return (
@@ -39,26 +48,26 @@ function SourceOverlay ({ source, onCancel }) {
)
}
- function renderText(path) {
+ renderText(path) {
return (
}
- unloader={renderError()}
+ unloader={() => this.renderError()}
/>
)
}
- function renderNoSupport(ext) {
+ renderNoSupport(ext) {
return (
)
}
- function toMedia(path) {
+ toMedia(path) {
let type;
switch (true) {
case /\.(png|jpg)$/.test(path):
@@ -73,7 +82,7 @@ function SourceOverlay ({ source, onCancel }) {
return { type, path }
}
- function getTypeCounts(media) {
+ getTypeCounts(media) {
let counts = { Image: 0, Video: 0, Text: 0 }
media.forEach(m => {
counts[m.type] += 1
@@ -81,21 +90,21 @@ function SourceOverlay ({ source, onCancel }) {
return counts
}
- function _renderPath(media) {
+ _renderPath(media) {
const { path, type } = media
switch (type) {
case 'Image':
- return renderImage(path)
+ return this.renderImage(path)
case 'Video':
- return renderVideo(path)
+ return this.renderVideo(path)
case 'Text':
- return renderText(path)
+ return this.renderText(path)
default:
- return renderNoSupport(path.split('.')[1])
+ return this.renderNoSupport(path.split('.')[1])
}
}
- function _renderCounts(counts) {
+ _renderCounts(counts) {
const strFor = type =>
counts[type] > 0 ?
`${counts[type]} ${type.toLowerCase()}${counts[type] > 1 ? 's': ''}`
@@ -113,52 +122,84 @@ function SourceOverlay ({ source, onCancel }) {
)
}
- function _renderContent(media) {
+ _renderContent(media) {
+ const el = document.querySelector(`.source-media-gallery`);
+ const shiftW = (!!el) ? el.getBoundingClientRect().width : 0;
return (
-
- {media.map(_renderPath)}
-
+
+ {media.map((m) => this._renderPath(m))}
+
)
}
- if (typeof(source) !== 'object') {
- return renderError()
+ 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 });
}
- const {id, url, title, paths, date, type, desc} = source
- const media = paths.map(toMedia)
- const counts = getTypeCounts(media)
+ _renderControls() {
+ if (this.props.source.paths.length > 1) {
+ return (
+
+
this.onShiftGallery(-1)}>
+
+
+ );
+ }
+ return (
+
+ );
+ }
- return (
-
-
{ e.stopPropagation(); }}>
-
-
-
+ render () {
+ if (typeof(this.props.source) !== 'object') {
+ return this.renderError()
+ }
+ const {id, url, title, paths, date, type, desc} = this.props.source
+ const media = paths.map(this.toMedia)
+ const counts = this.getTypeCounts(media)
+
+ return (
+
+
{ e.stopPropagation(); }}>
+
+
+
+
+
{this.props.source.title}
-
{source.title}
-
-
- {_renderContent(media)}
-
-
-
- {title?
{title}
: null}
-
{_renderCounts(counts)}
-
- {type ?
Media type
: null}
- {type ?
perm_media{type}
: null}
- {date ?
Date
: null}
- {date ?
today{date}
: null}
- {url ?
Link
: null}
- {url ?
linkLink to original URL : null}
- {desc ?
: null}
- {desc ?
{desc}
: null}
+
+ {this._renderContent(media)}
+ {this._renderControls()}
+
+
+
+
{`${this.state.idx+1} / ${paths.length}`}
+ {title?
{title}
: null}
+
{desc}
+
+
+
+
+ {type ?
Media type
: null}
+ {type ?
perm_media{type}
: null}
+
+
+ {date ?
Date
: null}
+ {date ?
today{date}
: null}
+
+
+
-
- )
+ )
+
+ }
}
export default SourceOverlay
diff --git a/src/components/Timeline.jsx b/src/components/Timeline.jsx
index 5c42e17..8d7104b 100644
--- a/src/components/Timeline.jsx
+++ b/src/components/Timeline.jsx
@@ -20,6 +20,7 @@ class Timeline extends React.Component {
super(props);
this.styleDatetime = this.styleDatetime.bind(this)
this.getDatetimeX = this.getDatetimeX.bind(this)
+ this.onApplyZoom = this.onApplyZoom.bind(this)
this.svgRef = React.createRef()
this.state = {
isFolded: false,
@@ -99,6 +100,7 @@ class Timeline extends React.Component {
* Returns the time scale (x) extent in minutes
*/
getTimeScaleExtent() {
+ if (!this.state.scaleX) return 0
const timeDomain = this.state.scaleX.domain();
return (timeDomain[1].getTime() - timeDomain[0].getTime()) / 60000;
}
@@ -153,7 +155,7 @@ class Timeline extends React.Component {
this.setState({ timerange: [domain0, domainF] }, () => {
this.props.methods.onUpdateTimerange(this.state.timerange);
- });
+ });
}
/**
@@ -284,9 +286,10 @@ class Timeline extends React.Component {
onMoveTime={(dir) => { this.onMoveTime(dir) }}
/>
{ this.onApplyZoom(zoom); }}
+ onApplyZoom={this.onApplyZoom}
/>
-
+
);
}
}
-export default TimelineAxis;
\ No newline at end of file
+export default TimelineAxis;
diff --git a/src/components/TimelineCategories.jsx b/src/components/TimelineCategories.jsx
index c90697c..25dce29 100644
--- a/src/components/TimelineCategories.jsx
+++ b/src/components/TimelineCategories.jsx
@@ -59,4 +59,4 @@ class TimelineCategories extends React.Component {
}
}
-export default TimelineCategories;
\ No newline at end of file
+export default TimelineCategories;
diff --git a/src/components/ToolbarBottomActions.jsx b/src/components/ToolbarBottomActions.jsx
index 7e20bd2..e20a4be 100644
--- a/src/components/ToolbarBottomActions.jsx
+++ b/src/components/ToolbarBottomActions.jsx
@@ -14,7 +14,7 @@ function ToolbarBottomActions (props) {
{/* isEnabled={this.props.viewFilters.routes} */}
{/* /> */}
{/* {
- const classes = (isEnabled) ? 'action-button enabled' : 'action-button disabled';
+const SitesIcon = ({ isActive, isDisabled, onClickHandler }) => {
+ let classes = (isActive) ? 'action-button enabled' : 'action-button';
+ if (isDisabled) {
+ classes = 'action-button disabled'
+ }
return (
)
} else {
diff --git a/src/components/presentational/TimelineLabels.js b/src/components/presentational/TimelineLabels.js
index 3f165aa..36466ba 100644
--- a/src/components/presentational/TimelineLabels.js
+++ b/src/components/presentational/TimelineLabels.js
@@ -22,23 +22,23 @@ const TimelineLabels = ({ dims, timelabels }) => {
y2="20"
>
-
- {formatterWithYear(timelabels[0])}
-
-
- {formatterWithYear(timelabels[1])}
-
+ {/*
*/}
+ {/* {formatterWithYear(timelabels[0])} */}
+ {/* */}
+ {/*
*/}
+ {/* {formatterWithYear(timelabels[1])} */}
+ {/* */}
)
}
-export default TimelineLabels;
\ No newline at end of file
+export default TimelineLabels;
diff --git a/src/components/presentational/TimelineZoomControls.js b/src/components/presentational/TimelineZoomControls.js
index 9b4f6c2..3c0a564 100644
--- a/src/components/presentational/TimelineZoomControls.js
+++ b/src/components/presentational/TimelineZoomControls.js
@@ -1,11 +1,11 @@
import React from 'react';
-const TimelineZoomControls = ({ zoomLevels, dims, onApplyZoom }) => {
-
+const TimelineZoomControls = ({ extent, zoomLevels, dims, onApplyZoom }) => {
function renderZoom(zoom, idx) {
+ const isActive = (zoom.duration === extent)
return (
onApplyZoom(zoom)}
@@ -22,4 +22,4 @@ const TimelineZoomControls = ({ zoomLevels, dims, onApplyZoom }) => {
);
}
-export default TimelineZoomControls;
\ No newline at end of file
+export default TimelineZoomControls;
diff --git a/src/js/utilities.js b/src/js/utilities.js
index 5568b17..dc242c3 100644
--- a/src/js/utilities.js
+++ b/src/js/utilities.js
@@ -108,13 +108,15 @@ export function insetSourceFrom(allSources) {
* view that source modal by default
*/
export function injectSource(id) {
- return state => ({
- ...state,
- app: {
- ...state.app,
- source: state.domain.sources[id]
+ return state => {
+ return {
+ ...state,
+ app: {
+ ...state.app,
+ source: state.domain.sources[id]
+ }
}
- })
+ }
}
export function urlFromEnv(ext) {
diff --git a/src/reducers/app.js b/src/reducers/app.js
index b7164ea..43e39aa 100644
--- a/src/reducers/app.js
+++ b/src/reducers/app.js
@@ -1,4 +1,5 @@
import initial from '../store/initial.js'
+import { parseDate } from '../js/utilities'
import {
UPDATE_HIGHLIGHTED,
@@ -35,49 +36,49 @@ function updateSelected(appState, action) {
}
function updateNarrative(appState, action) {
- let minTime = appState.filters.timerange[0];
- let maxTime = appState.filters.timerange[1];
+ let minTime = appState.filters.timerange[0]
+ let maxTime = appState.filters.timerange[1]
- let cornerBound0 = [180, 180];
- let cornerBound1 = [-180, -180];
+ let cornerBound0 = [180, 180]
+ let cornerBound1 = [-180, -180]
// Compute narrative time range and map bounds
if (!!action.narrative) {
- minTime = parseDate('2100-01-01T00:00:00');
- maxTime = parseDate('1900-01-01T00:00:00');
+ minTime = parseDate('2100-01-01T00:00:00')
+ maxTime = parseDate('1900-01-01T00:00:00')
// Find max and mins coordinates of narrative events
action.narrative.steps.forEach(step => {
- const stepTime = parseDate(step.timestamp);
- if (stepTime < minTime) minTime = stepTime;
- if (stepTime > maxTime) maxTime = stepTime;
+ const stepTime = parseDate(step.timestamp)
+ if (stepTime < minTime) minTime = stepTime
+ if (stepTime > maxTime) maxTime = stepTime
if (!!step.longitude && !!step.latitude) {
- if (+step.longitude < cornerBound0[1]) cornerBound0[1] = +step.longitude;
- if (+step.longitude > cornerBound1[1]) cornerBound1[1] = +step.longitude;
- if (+step.latitude < cornerBound0[0]) cornerBound0[0] = +step.latitude;
- if (+step.latitude > cornerBound1[0]) cornerBound1[0] = +step.latitude;
+ if (+step.longitude < cornerBound0[1]) cornerBound0[1] = +step.longitude
+ if (+step.longitude > cornerBound1[1]) cornerBound1[1] = +step.longitude
+ if (+step.latitude < cornerBound0[0]) cornerBound0[0] = +step.latitude
+ if (+step.latitude > cornerBound1[0]) cornerBound1[0] = +step.latitude
}
- });
+ })
// Adjust bounds to center around first event, while keeping visible all others
// Takes first event, finds max ditance with first attempt bounds, and use this max distance
// on the other side, both in latitude and longitude
- const first = action.narrative.steps[0];
+ const first = action.narrative.steps[0]
if (!!first.longitude && !!first.latitude) {
- const firstToLong0 = Math.abs(+first.longitude - cornerBound0[1]);
- const firstToLong1 = Math.abs(+first.longitude - cornerBound1[1]);
- const firstToLat0 = Math.abs(+first.latitude - cornerBound0[0]);
- const firstToLat1 = Math.abs(+first.latitude - cornerBound1[0]);
+ const firstToLong0 = Math.abs(+first.longitude - cornerBound0[1])
+ const firstToLong1 = Math.abs(+first.longitude - cornerBound1[1])
+ const firstToLat0 = Math.abs(+first.latitude - cornerBound0[0])
+ const firstToLat1 = Math.abs(+first.latitude - cornerBound1[0])
- if (firstToLong0 > firstToLong1) cornerBound1[1] = +first.longitude + firstToLong0;
- if (firstToLong0 < firstToLong1) cornerBound0[1] = +first.longitude - firstToLong1;
- if (firstToLat0 > firstToLat1) cornerBound1[0] = +first.latitude + firstToLat0;
- if (firstToLat0 < firstToLat1) cornerBound0[0] = +first.latitude - firstToLat1;
+ if (firstToLong0 > firstToLong1) cornerBound1[1] = +first.longitude + firstToLong0
+ if (firstToLong0 < firstToLong1) cornerBound0[1] = +first.longitude - firstToLong1
+ if (firstToLat0 > firstToLat1) cornerBound1[0] = +first.latitude + firstToLat0
+ if (firstToLat0 < firstToLat1) cornerBound0[0] = +first.latitude - firstToLat1
}
-
+
// Add some buffer on both sides of the time extent
- minTime = new Date(minTime.getTime() - Math.abs((maxTime - minTime) / 10));
- maxTime = new Date(maxTime.getTime() + Math.abs((maxTime - minTime) / 10));
+ minTime = new Date(minTime.getTime() - Math.abs((maxTime - minTime) / 10))
+ maxTime = new Date(maxTime.getTime() + Math.abs((maxTime - minTime) / 10))
}
return {
@@ -138,14 +139,14 @@ function updateTagFilters(appState, action) {
function updateCategoryFilters(appState, action) {
const categoryFilters = appState.filters.categories.slice(0)
- const catFilter = categoryFilters.find(cF => cF.category === action.category.category);
+ const catFilter = categoryFilters.find(cF => cF.category === action.category.category)
if (!catFilter) {
categoryFilters.push(action.category)
} else {
- catFilter.active = (!!action.category.active);
+ catFilter.active = (!!action.category.active)
}
-
+
return Object.assign({}, appState, {
filters: Object.assign({}, appState.filters, {
diff --git a/src/reducers/schema/eventSchema.js b/src/reducers/schema/eventSchema.js
index ae308e0..fb42cf5 100644
--- a/src/reducers/schema/eventSchema.js
+++ b/src/reducers/schema/eventSchema.js
@@ -3,22 +3,25 @@ import Joi from 'joi';
const eventSchema = Joi.object().keys({
id: Joi.string().required(),
description: Joi.string().allow('').required(),
- date: Joi.string().required(),
- time: Joi.string().required(),
+ date: Joi.string().allow(''),
+ time: Joi.string().allow(''),
time_precision: Joi.string().allow(''),
- location: Joi.string().allow('').required(),
- latitude: Joi.string().allow('').required(),
- longitude: Joi.string().allow('').required(),
+ location: Joi.string().allow(''),
+ latitude: Joi.string().allow(''),
+ longitude: Joi.string().allow(''),
type: Joi.string().allow(''),
category: Joi.string().required(),
narratives: Joi.array(),
sources: Joi.array(),
tags: Joi.array().allow(''),
comments: Joi.string().allow(''),
- timestamp: Joi.string().required(),
+ timestamp: Joi.string(),
// nested
narrative___stepStyles: Joi.array(),
-});
+})
+ .and('latitude', 'longitude')
+ .and('date', 'time', 'timestamp')
+ .or('timestamp', 'latitude')
-export default eventSchema;
+export default eventSchema
diff --git a/src/scss/cardstack.scss b/src/scss/cardstack.scss
index a79a44e..230d63c 100644
--- a/src/scss/cardstack.scss
+++ b/src/scss/cardstack.scss
@@ -2,16 +2,16 @@
@import 'card';
$card-width: 370px;
-$narrative-info-max-height: 170px;
+$narrative-info-max-height: 200px;
$timeline-height: 170px;
.card-stack {
position: absolute;
top: 10px;
right: 10px;
- max-height: calc(100% - 208px);
+ max-height: calc(100% - 180px);
height: auto;
- overflow: hidden;
+ overflow-y: scroll;
box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
z-index: $header;
color: white;
diff --git a/src/scss/mediaoverlay.scss b/src/scss/mediaoverlay.scss
index d48a851..0bad5a2 100644
--- a/src/scss/mediaoverlay.scss
+++ b/src/scss/mediaoverlay.scss
@@ -1,7 +1,8 @@
-$panel-width: 800px;
+$panel-width: 1000px;
$panel-height: 700px;
$vimeo-width: $panel-width - 100;
$vimeo-height: $panel-height / 2;
+
$padding: 20px;
$header-inset: 10px;
@@ -20,6 +21,7 @@ $header-inset: 10px;
}
.mo-container {
+ background-color: rgba(239, 239, 239, 0.9);
// max-width: $panel-width;
// min-width: $panel-width;
// max-height: $panel-height;
@@ -27,43 +29,30 @@ $header-inset: 10px;
display: flex;
flex-direction: column;
align-items: center;
- max-height: 80vh;
+ height: 80vh;
+ width: $panel-width;
max-width: 90vw;
box-shadow: 0 19px 19px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
- .mo-media-container {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
-}
-
-.mo-header {
- min-height: 42px;
- max-height: 42px;
- margin-bottom: 2px;
- border-radius: 2px;
- width: 100%;
- display: flex;
- flex-direction: row;
- background-color: black;
- color: white;
-
- .mo-header-close {
- display: flex;
- justify-content: center;
- align-items: center;
- margin-left: $header-inset + 8px;
+ .back, .next {
+ width: 30px;
+ height: 30px;
+ background: $darkgrey;
+ color: $offwhite;
+ cursor: pointer;
+ box-shadow: 0 19px 19px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
+ svg path { fill: $offwhite; }
+ z-index: 1;
}
- .mo-header-text {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: flex-end;
- padding-right: $padding;
- font-family: "Lato", Helvetica, sans-serif;
+ .back {
+ left: 10px;
+ svg path { transform: translate(17px,15px)rotate(-90deg)}
+ }
+ .next {
+ margin-left: calc(100% - 60px);
+ right: 10px;
+ svg path { transform: translate(17px,15px)rotate(90deg)}
}
}
@@ -94,12 +83,17 @@ $header-inset: 10px;
}
.mo-media-container {
- background-color: rgba(239, 239, 239, 0.9);
+ flex: 1;
+ /*display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;*/
+ display: inline-block;
+ overflow-x: hidden;
box-sizing: border-box;
- min-width: 100%;
+ width: 100%;
max-height: 60vh;
padding: 20px;
- overflow-y: auto;
font-family: "Lato", Helvetica, sans-serif;
.media-player {
@@ -112,6 +106,14 @@ $header-inset: 10px;
flex-direction: column;
}
+ .media-gallery-controls {
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-top: -50%;
+ }
+
// NB: topcushion seems to be necessary with certain overflows..
&.topcushion {
padding-top: 150px;
@@ -119,23 +121,24 @@ $header-inset: 10px;
}
.mo-meta-container {
- background-color: rgba(239, 239, 239, 0.9);
display: flex;
- justify-content: center;
- box-sizing: border-box;
- min-height: 100px;
- min-width: $panel-width;
- max-width: $panel-height;
- display: flex;
- justify-content: center;
+ flex-direction: column;
+ justify-content: center;
box-sizing: border-box;
min-height: 100px;
width: 100%;
padding: $padding;
+ .mo-box-title {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ }
+
.mo-box {
display: flex;
- flex-direction: column;
+ flex-direction: row;
+ justify-content: space-around;
max-width: $panel-width;
width: 100%;
padding: $padding 0;
@@ -148,7 +151,7 @@ $header-inset: 10px;
text-transform: uppercase;
font-size: $xsmall;
color: $darkwhite;
- font-weight: 100;
+ font-weight: 100;
}
p {
@@ -160,7 +163,7 @@ $header-inset: 10px;
font-size: $normal;
color: $darkwhite;
margin-right: 5px;
- }
+ }
a {
font-size: $large;
@@ -223,19 +226,73 @@ $header-inset: 10px;
}
}
-.source-image-container, .source-text-container {
- padding: $padding;
- display: inline-block;
- align-items: center;
+.source-media-gallery {
+ display: flex;
+ flex-direction: row;
+ height: 100%;
+ transition: transform 0.6s ease 0s;
+ width: 100%;
+ // min-width: $panel-width - 30px;
+ // min-height: $panel-height;
+}
+
+.source-text-container {
+ padding: 20px;
+ display: flex;
+ justify-content: center;
+ background: $lightwhite;
+ box-sizing: border-box;
+ padding: 0 calc(50% - 400px);
+ overflow-y: scroll;
+ font-family: 'Merriweather', Georgia, serif;
+ line-height: 1.5em;
+
+ a {
+ color: $darkgrey;
+ border-bottom: 1px solid $red;
+ &:hover { border-bottom: 1px solid $darkgrey; color: $darkgrey; }
+ }
+
+ .md-container {
+ width: 100%;
+ overflow-wrap: break-word;
+ }
+}
+
+.source-image-container, .media-player {
+ display: flex;
+ justify-content: center;
+ width: calc(100% - 20px);
+ height: 100%;
+ min-width: calc(100% - 20px);
+ margin: 0 10px;
+ background: $lightwhite;
+ border-radius: 2px;
+}
+
+.media-player {
+ box-sizing: border-box;
+ width: 100%;
+ min-width: 100%;
+ max-width: 100%;
+ height: 100%;
+ min-height: 100%;
+ max-height: 100%;
+ padding: 20px 10%;
+ align-self: center;
}
.source-image, .source-video {
max-width: calc(100% - 20px);
- max-height: 350px !important;
- // height: 100%;
- padding: 10px;
+ max-height: calc(100% - 20px);
+ padding: 0px;
+ font-family: 'Lato', Helvetica, sans-serif;
}
-.media-player {
- overflow-y: hidden;
+.video-react .video-react-progress-control {
+ align-self: center;
}
+
+.video-react .video-react-control {
+ min-height: 100%;
+}
\ No newline at end of file
diff --git a/src/scss/narrativecard.scss b/src/scss/narrativecard.scss
index 9bf86a4..adf5e8b 100644
--- a/src/scss/narrativecard.scss
+++ b/src/scss/narrativecard.scss
@@ -1,4 +1,4 @@
-$narrative-info-width: 370px;
+$narrative-info-width: 386px;
$timeline-height: 170px;
/*
@@ -8,8 +8,8 @@ NARRATIVE INFO
position: fixed;
top: 30px;
left: auto;
- right: 10px;
- height: 170px;
+ right: 9px;
+ height: 205px;
width: $narrative-info-width;
box-sizing: border-box;
max-height: calc(100% - 250px);
@@ -39,7 +39,8 @@ NARRATIVE INFO
}
.narrative-info-desc {
- overflow: auto;
+ height: 153px;
+ overflow-y: auto;
}
p {
@@ -117,7 +118,7 @@ NARRATIVE INFO
&.right {
// right: calc(#{$narrative-info-width} + 10px);
- right: 10px;
+ right: 25px;
}
.material-icons {
diff --git a/src/scss/toolbar.scss b/src/scss/toolbar.scss
index 0d9d400..29a81ef 100644
--- a/src/scss/toolbar.scss
+++ b/src/scss/toolbar.scss
@@ -96,6 +96,10 @@
}
}
+ &:hover {
+ cursor: pointer;
+ }
+
&:hover:not(.disabled) {
transition: 0.2s ease;
border: 1px solid $offwhite;
diff --git a/src/store/initial.js b/src/store/initial.js
index dbfbd19..9cb4a2a 100644
--- a/src/store/initial.js
+++ b/src/store/initial.js
@@ -1,3 +1,5 @@
+import { mergeDeepLeft } from 'ramda'
+
const initial = {
/*
* The Domain or 'domain' of this state refers to the tree of data
@@ -38,8 +40,8 @@ const initial = {
},
filters: {
timerange: [
- d3.timeParse("%Y-%m-%dT%H:%M:%S")("2013-02-23T12:00:00"),
- d3.timeParse("%Y-%m-%dT%H:%M:%S")("2016-02-23T12:00:00")
+ new Date(2013, 2, 23, 12),
+ new Date(2016, 2, 23, 12)
],
mapBounds: null,
tags: [],
@@ -51,45 +53,18 @@ const initial = {
sites: true
},
},
- base_uri: 'http://127.0.0.1:8000/', // Modify accordingly on production setup.
isMobile: (/Mobi/.test(navigator.userAgent)),
language: 'en-US',
- mapAnchor: process.env.MAP_ANCHOR,
- zoomLevels: [{
- label: '3 years',
- duration: 1576800,
- active: false
- },
- {
- label: '3 months',
- duration: 129600,
- active: false
- },
- {
- label: '3 days',
- duration: 4320,
- active: false
- },
- {
- label: '12 hours',
- duration: 720,
- active: false
- },
- {
- label: '2 hours',
- duration: 120,
- active: false
- },
- {
- label: '30 min',
- duration: 30,
- active: false
- },
- {
- label: '10 min',
- duration: 10,
- active: false
- }],
+ mapAnchor: [31.356397, 34.784818],
+ zoomLevels: [
+ { label: '3 years', duration: 1576800 },
+ { label: '3 months', duration: 129600 },
+ { label: '3 days', duration: 4320 },
+ { label: '12 hours', duration: 720 },
+ { label: '2 hours', duration: 120 },
+ { label: '30 min', duration: 30 },
+ { label: '10 min', duration: 10 }
+ ],
flags: {
isFetchingDomain: false,
isFetchingSources: false,
@@ -108,30 +83,13 @@ const initial = {
ui: {
style: {
categories: {
- default: 'yellow',
- // Add here other categories to differentiate by color, like:
- alpha: '#00ff00',
- beta: '#ff0000',
- other: '#f3de2c'
+ default: '#f3de2c',
},
narratives: {
default: {
opacity: 0.9,
stroke: 'red',
strokeWidth: 3
- },
- narrative_1: {
- opacity: 0.4,
- stroke: '#f18f01',
- strokeWidth: 3
- },
- // process.env.features.NARRATIVE_STEP_STYLES
- stepStyles: {
- Physical: {
- stroke: 'yellow',
- strokeWidth: 3,
- opacity: 0.9,
- }
}
}
},
@@ -143,4 +101,15 @@ const initial = {
}
};
-export default initial;
+let appStore;
+if (process.env.store) {
+ appStore = mergeDeepLeft(process.env.store, initial);
+} else {
+ appStore = initial
+}
+
+// NB: config.js dates get implicitly converted to strings in mergeDeepLeft
+appStore.app.filters.timerange[0] = new Date(appStore.app.filters.timerange[0])
+appStore.app.filters.timerange[1] = new Date(appStore.app.filters.timerange[1])
+
+export default appStore
diff --git a/yarn.lock b/yarn.lock
index 9f5e536..2f8e62f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5059,6 +5059,11 @@ quick-lru@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8"
+ramda@^0.26.1:
+ version "0.26.1"
+ resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
+ integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==
+
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"