mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-12 05:18:34 +03:00
WIP: render all cards in narrative
This commit is contained in:
@@ -1,28 +1,28 @@
|
||||
import copy from '../js/data/copy.json';
|
||||
import copy from '../js/data/copy.json'
|
||||
import {
|
||||
isNotNullNorUndefined,
|
||||
parseDate,
|
||||
formatterWithYear
|
||||
} from '../js/utilities';
|
||||
import React from 'react';
|
||||
} from '../js/utilities'
|
||||
import React from 'react'
|
||||
|
||||
import Spinner from './presentational/Spinner';
|
||||
import CardTimestamp from './presentational/CardTimestamp';
|
||||
import CardLocation from './presentational/CardLocation';
|
||||
import CardCaret from './presentational/CardCaret';
|
||||
import CardTags from './presentational/CardTags';
|
||||
import CardSummary from './presentational/CardSummary';
|
||||
import CardSource from './presentational/CardSource';
|
||||
import CardCategory from './presentational/CardCategory';
|
||||
import CardNarrative from './presentational/CardNarrative';
|
||||
import Spinner from './presentational/Spinner'
|
||||
import CardTimestamp from './presentational/CardTimestamp'
|
||||
import CardLocation from './presentational/CardLocation'
|
||||
import CardCaret from './presentational/CardCaret'
|
||||
import CardTags from './presentational/CardTags'
|
||||
import CardSummary from './presentational/CardSummary'
|
||||
import CardSource from './presentational/CardSource'
|
||||
import CardCategory from './presentational/CardCategory'
|
||||
import CardNarrative from './presentational/CardNarrative'
|
||||
|
||||
class Card extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
super(props)
|
||||
this.state = {
|
||||
isHighlighted: false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
toggle() {
|
||||
@@ -30,24 +30,24 @@ class Card extends React.Component {
|
||||
isHighlighted: !this.state.isHighlighted
|
||||
}, () => {
|
||||
if (!this.state.isHighlighted) {
|
||||
this.props.onHighlight(this.props.event);
|
||||
this.props.onHighlight(this.props.event)
|
||||
} else {
|
||||
this.props.onHighlight(null);
|
||||
this.props.onHighlight(null)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
makeTimelabel(timestamp) {
|
||||
if (timestamp === null) return null;
|
||||
const parsedTimestamp = parseDate(timestamp);
|
||||
const timelabel = formatterWithYear(parsedTimestamp);
|
||||
return timelabel;
|
||||
if (timestamp === null) return null
|
||||
const parsedTimestamp = parseDate(timestamp)
|
||||
const timelabel = formatterWithYear(parsedTimestamp)
|
||||
return timelabel
|
||||
}
|
||||
|
||||
renderCategory() {
|
||||
const categoryTitle = copy[this.props.language].cardstack.category;
|
||||
const categoryLabel = this.props.event.category;
|
||||
const color = this.props.getCategoryColor(this.props.event.category);
|
||||
const categoryTitle = copy[this.props.language].cardstack.category
|
||||
const categoryLabel = this.props.event.category
|
||||
const color = this.props.getCategoryColor(this.props.event.category)
|
||||
|
||||
return (
|
||||
<CardCategory
|
||||
@@ -55,7 +55,7 @@ class Card extends React.Component {
|
||||
categoryLabel={categoryLabel}
|
||||
color={color}
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
renderSummary() {
|
||||
@@ -117,11 +117,11 @@ class Card extends React.Component {
|
||||
language={this.props.language}
|
||||
timestamp={this.props.event.timestamp}
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
renderNarrative() {
|
||||
const links = this.props.getNarrativeLinks(this.props.event);
|
||||
const links = this.props.getNarrativeLinks(this.props.event)
|
||||
|
||||
if (links !== null) {
|
||||
|
||||
@@ -147,7 +147,7 @@ class Card extends React.Component {
|
||||
<br/>
|
||||
{this.renderSummary()}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
@@ -180,8 +180,8 @@ class Card extends React.Component {
|
||||
{this.renderContent()}
|
||||
{this.renderCaret()}
|
||||
</li>
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Card;
|
||||
export default Card
|
||||
|
||||
@@ -1,44 +1,47 @@
|
||||
import React from 'react';
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import * as selectors from '../selectors'
|
||||
|
||||
import Card from './Card.jsx';
|
||||
import copy from '../js/data/copy.json';
|
||||
import Card from './Card.jsx'
|
||||
import copy from '../js/data/copy.json'
|
||||
import {
|
||||
isNotNullNorUndefined
|
||||
} from '../js/utilities.js';
|
||||
} from '../js/utilities.js'
|
||||
|
||||
class CardStack extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
renderCards(events) {
|
||||
return events.map(event => (
|
||||
<Card
|
||||
event={event}
|
||||
sourceError={this.props.sourceError}
|
||||
language={this.props.language}
|
||||
isLoading={this.props.isLoading}
|
||||
getNarrativeLinks={this.props.getNarrativeLinks}
|
||||
getCategoryGroup={this.props.getCategoryGroup}
|
||||
getCategoryColor={this.props.getCategoryColor}
|
||||
getCategoryLabel={this.props.getCategoryLabel}
|
||||
onViewSource={this.props.onViewSource}
|
||||
onHighlight={this.props.onHighlight}
|
||||
onSelect={this.props.onSelect}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
||||
renderCards() {
|
||||
if (this.props.selected.length > 0) {
|
||||
return this.props.selected.map((event) => {
|
||||
return (
|
||||
<Card
|
||||
event={event}
|
||||
sourceError={this.props.sourceError}
|
||||
language={this.props.language}
|
||||
isLoading={this.props.isLoading}
|
||||
getNarrativeLinks={this.props.getNarrativeLinks}
|
||||
getCategoryGroup={this.props.getCategoryGroup}
|
||||
getCategoryColor={this.props.getCategoryColor}
|
||||
getCategoryLabel={this.props.getCategoryLabel}
|
||||
onViewSource={this.props.onViewSource}
|
||||
onHighlight={this.props.onHighlight}
|
||||
onSelect={this.props.onSelect}
|
||||
/>
|
||||
);
|
||||
});
|
||||
renderSelectedCards() {
|
||||
const { selected } = this.props
|
||||
if (selected.length > 0) {
|
||||
return this.renderCards(selected)
|
||||
}
|
||||
return '';
|
||||
return null
|
||||
}
|
||||
|
||||
renderNarrativeCards() {
|
||||
const { narrative } = this.props
|
||||
return this.renderCards(narrative.steps)
|
||||
}
|
||||
|
||||
renderCardStackHeader() {
|
||||
const header_lang = copy[this.props.language].cardstack.header;
|
||||
const header_lang = copy[this.props.language].cardstack.header
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -58,34 +61,59 @@ class CardStack extends React.Component {
|
||||
return (
|
||||
<div id="card-stack-content" className="card-stack-content">
|
||||
<ul>
|
||||
{this.renderCards()}
|
||||
{this.renderSelectedCards()}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
renderNarrativeContent() {
|
||||
return (
|
||||
<div id="card-stack-content" className="card-stack-content">
|
||||
<ul>
|
||||
{this.renderNarrativeCards()}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isCardstack, isNarrative, selected } = this.props
|
||||
const { isCardstack, selected, narrative } = this.props
|
||||
|
||||
if (selected.length > 0) {
|
||||
return (
|
||||
<div
|
||||
id="card-stack"
|
||||
className={`card-stack
|
||||
${isNarrative ? 'narrative-mode' : ''}
|
||||
if (!narrative) {
|
||||
return (
|
||||
<div
|
||||
id="card-stack"
|
||||
className={`card-stack
|
||||
${isCardstack ? '' : ' folded'}`
|
||||
}
|
||||
>
|
||||
{this.renderCardStackHeader()}
|
||||
{this.renderCardStackContent()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
>
|
||||
{this.renderCardStackHeader()}
|
||||
{this.renderCardStackContent()}
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
id="card-stack"
|
||||
className={`card-stack narrative-mode
|
||||
${isCardstack ? '' : ' folded'}`
|
||||
}
|
||||
>
|
||||
{this.renderNarrativeContent()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
return <div/>;
|
||||
|
||||
return <div/>
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
narrative: selectors.selectActiveNarrative(state),
|
||||
selected: selectors.selectSelected(state),
|
||||
sourceError: state.app.errors.source,
|
||||
language: state.app.language,
|
||||
|
||||
@@ -127,7 +127,6 @@ class Dashboard extends React.Component {
|
||||
}}
|
||||
/>
|
||||
<CardStack
|
||||
isNarrative={!!app.narrative}
|
||||
onViewSource={this.handleViewSource}
|
||||
onSelect={this.handleSelect}
|
||||
onHighlight={this.handleHighlight}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@import 'card';
|
||||
|
||||
$card-width: 370px;
|
||||
$narrative-info-max-height: 250px;
|
||||
$narrative-info-max-height: 170px;
|
||||
$timeline-height: 170px;
|
||||
|
||||
.card-stack {
|
||||
@@ -20,7 +20,7 @@ $timeline-height: 170px;
|
||||
&.narrative-mode {
|
||||
right: auto;
|
||||
left: 10px;
|
||||
top: $narrative-info-max-height;
|
||||
top: $narrative-info-max-height + 12px;
|
||||
height: calc(100% - #{$narrative-info-max-height} - #{$timeline-height});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ NARRATIVE INFO
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
// height: auto;
|
||||
height: auto;
|
||||
max-height: 500px;
|
||||
height: 170px;
|
||||
width: $narrative-info-width;
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
|
||||
Reference in New Issue
Block a user