Merge pull request #44 from forensic-architecture/topic/source-fetch

Topic/source fetch
This commit is contained in:
Franc Camps-Febrer
2018-12-12 12:43:13 +01:00
committed by GitHub
12 changed files with 105 additions and 57 deletions

View File

@@ -16,6 +16,16 @@ const NARRATIVE_URL = urlFromEnv('NARRATIVE_EXT');
const SITES_URL = urlFromEnv('SITES_EXT');
const eventUrlMap = (event) => `${process.env.SERVER_ROOT}${process.env.EVENT_DESC_ROOT}/${(event.id) ? event.id : event}`;
const DEBUG_GER = 'DEBUG_GER'
function _debugger(value) {
console.log(value)
return {
type: DEBUG_GER,
value
}
}
/*
* Create an error notification object
* Types: ['error', 'warning', 'good', 'neural']
@@ -64,7 +74,7 @@ export function fetchDomain () {
.catch(handleError('sites'))
}
let tagsPromise
let tagsPromise = Promise.resolve([])
if (process.env.features.USE_TAGS) {
tagsPromise = fetch(TAG_URL)
.then(response => response.json())
@@ -118,7 +128,6 @@ export function updateDomain(domain) {
export function fetchSelected(selected) {
if (!selected || !selected.length || selected.length === 0) {
console.log('hitting base')
return updateSelected([])
}
return dispatch => {
@@ -127,6 +136,23 @@ export function fetchSelected(selected) {
dispatch(fetchSourceError('No source extension specified.'))
} else {
dispatch(toggleFetchingSources())
fetch(SOURCES_URL)
.then(response => {
if (!response.ok) {
throw new Error('No sources are available at the URL specified in the config specified.')
} else {
return response.json()
}
})
.then(sources => {
dispatch(_debugger(sources))
})
.catch(err => {
dispatch(fetchSourceError(err.message))
dispatch(toggleFetchingSources())
})
}
}

View File

@@ -89,8 +89,12 @@ class Card extends React.Component {
renderSource() {
return (
<CardSource
isLoading={this.props.isLoading}
language={this.props.language}
source={this.props.event.source}
source={{
...this.props.source,
error: this.props.sourceError
}}
/>
)
}
@@ -122,42 +126,31 @@ class Card extends React.Component {
}
}
renderLoadingCard() {
return (
<li className='event-card'>
<div className="card-bottomhalf">
<Spinner />
</div>
</li>
);
}
renderHeader() {
return (
<div className="card-collapsed">
<div className="card-row">
<div className="card-column">
{this.renderTimestamp()}
{this.renderLocation()}
</div>
{this.renderCategory()}
{/* {this.renderCategory()} */}
<br/>
{this.renderSummary()}
</div>
);
}
renderContent() {
if (!this.state.isHighlighted) {
return (
<div className="card-bottomhalf folded"></div>
);
} else {
if (this.state.isHighlighted) {
return (
<div className="card-bottomhalf">
{this.renderTags()}
{this.renderSource()}
{this.renderNarrative()}
</div>
);
)
} else {
return <div classname="card-bottomhalf"></div>
}
}
@@ -171,17 +164,13 @@ class Card extends React.Component {
}
render() {
if (this.props.isLoading) {
return this.renderLoadingCard();
} else {
return (
<li className='event-card'>
{this.renderHeader()}
{this.renderContent()}
{this.renderCaret()}
</li>
);
}
return (
<li className='event-card'>
{this.renderHeader()}
{this.renderContent()}
{this.renderCaret()}
</li>
);
}
}

View File

@@ -20,6 +20,7 @@ class CardStack extends React.Component {
return (
<Card
event={event}
sourceError={this.props.sourceError}
language={this.props.language}
isLoading={this.props.isLoading}
getNarrativeLinks={this.props.getNarrativeLinks}
@@ -89,9 +90,10 @@ class CardStack extends React.Component {
function mapStateToProps(state) {
return {
selected: state.app.selected,
sourceError: state.app.errors.source,
language: state.app.language,
isCardstack: state.app.flags.isCardstack,
isLoading: state.app.flags.isFetchingEvents
isLoading: state.app.flags.isFetchingSources
}
}

View File

@@ -64,7 +64,7 @@ class Dashboard extends React.Component {
}
getCategoryColor(category='other') {
return this.props.ui.style.categories[category] || this.props.style.categories['other']
return this.props.ui.style.categories[category] || this.props.ui.style.categories['other']
}
getNarrativeLinks(event) {

View File

@@ -1,17 +1,29 @@
import React from 'react';
import React from 'react'
import Spinner from './Spinner'
import copy from '../../js/data/copy.json';
import copy from '../../js/data/copy.json'
const CardSource = ({ source, language }) => {
const source_lang = copy[language].cardstack.source;
if (!source) source = copy[language].cardstack.unknown_source;
const CardSource = ({ source, language, isLoading, error }) => {
const source_lang = copy[language].cardstack.source
function renderSource() {
return source.error ? (
<div><small>{source.error}</small></div>
) : (
<div><p>TODO: display source properly.</p></div>
)
}
function renderContent() {
return isLoading ? <Spinner/> : renderSource()
}
return (
<div className="card-row card-cell source">
<div className="card-col card-cell source">
<h4>{source_lang}: </h4>
<p><small>{source}</small></p>
{renderContent()}
</div>
);
)
}
export default CardSource;
export default CardSource

View File

@@ -5,13 +5,12 @@ import copy from '../../js/data/copy.json';
const CardSummary = ({ language, description, isHighlighted }) => {
const summary = copy[language].cardstack.description;
const descriptionText = (isHighlighted) ? description : `${description.substring(0, 40)}...`;
return (
<div className="card-row summary">
<div className="card-cell">
<h4>{summary}</h4>
<p>{descriptionText}</p>
<p>{description}</p>
</div>
</div>
);

View File

@@ -1,10 +1,10 @@
import React from 'react';
const Spinner = ({}) => {
const Spinner = () => {
return (
<div className="spinner">
<div className="double-bounce1"></div>
<div className="double-bounce2"></div>
<div className="double-bounce-overlay"></div>
<div className="double-bounce"></div>
</div>
)
}

View File

@@ -137,7 +137,7 @@
"tags": "Tags",
"notags": "No known tags for this event.",
"source": "Source",
"unknown_source": "Unknown source. The relability of this event cannot be confirmed.",
"unknown_source": "The information for this source could not be retrieved.",
"category": "Category",
"communication": "Communication",
"transmitter": "Transmitter",

View File

@@ -16,6 +16,7 @@ import {
TOGGLE_INFOPOPUP,
TOGGLE_NOTIFICATIONS,
FETCH_ERROR,
FETCH_SOURCE_ERROR,
} from '../actions';
function updateHighlighted(appState, action) {
@@ -156,6 +157,16 @@ function toggleNotifications(appState, action) {
});
}
function fetchSourceError(appState, action) {
return {
...appState,
errors: {
...appState.errors,
source: action.msg
}
}
}
function app(appState = initial.app, action) {
@@ -186,6 +197,8 @@ function app(appState = initial.app, action) {
return toggleInfoPopup(appState, action);
case TOGGLE_NOTIFICATIONS:
return toggleNotifications(appState, action);
case FETCH_SOURCE_ERROR:
return fetchSourceError(appState, action);
default:
return appState;
}

View File

@@ -36,7 +36,7 @@
margin-right: 5px;
}
.card-row {
.card-row, .card-col {
display: flex;
flex-direction: row;
border-bottom: 1px solid $lightwhite;
@@ -53,6 +53,10 @@
}
}
.card-col {
flex-direction: column;
}
.card-cell {
a {
transition: color 0.2s;

View File

@@ -41,10 +41,10 @@ https://github.com/tobiasahlin/SpinKit/blob/master/LICENSE
height: 40px;
position: relative;
margin: 20px auto;
margin: 10px auto;
}
.double-bounce1, .double-bounce2 {
.double-bounce, .double-bounce-overlay {
width: 100%;
height: 100%;
border-radius: 50%;
@@ -58,20 +58,21 @@ https://github.com/tobiasahlin/SpinKit/blob/master/LICENSE
animation: sk-bounce 3.0s infinite ease-in-out;
}
.double-bounce2 {
.double-bounce-overlay {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
background-color: black;
}
@-webkit-keyframes sk-bounce {
0%, 100% { -webkit-transform: scale(0.0) }
0%, 100% { -webkit-transform: scale(0.3) }
50% { -webkit-transform: scale(1.0) }
}
@keyframes sk-bounce {
0%, 100% {
transform: scale(0.0);
-webkit-transform: scale(0.0);
transform: scale(0.3);
-webkit-transform: scale(0.3);
} 50% {
transform: scale(1.0);
-webkit-transform: scale(1.0);

View File

@@ -25,7 +25,9 @@ const initial = {
* or by the characteristics of the client, browser, etc.
*/
app: {
error: null,
errors: {
source: null,
},
highlighted: null,
selected: [],
narrative: null,