mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-11 12:58:35 +03:00
fix source scrolling, layout and arrows
This commit is contained in:
@@ -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) {
|
||||
@@ -170,7 +170,7 @@ function mapDispatchToProps (dispatch) {
|
||||
}
|
||||
|
||||
export default connect(
|
||||
state => state,
|
||||
// state => injectSource("Youtube - Novodvirske Tank Separatist Patrol Video"),
|
||||
// state => state,
|
||||
state => injectSource("Hromadske.tv - Paratroopers Video"),
|
||||
mapDispatchToProps
|
||||
)(Dashboard)
|
||||
|
||||
@@ -9,16 +9,7 @@ import NoSource from './presentational/NoSource'
|
||||
class SourceOverlay extends React.Component {
|
||||
constructor () {
|
||||
super()
|
||||
|
||||
this.state = {
|
||||
idx: 0
|
||||
}
|
||||
}
|
||||
|
||||
renderError () {
|
||||
return (
|
||||
<NoSource failedUrls={['NOT ALL SOURCES AVAILABLE IN APPLICATION YET']} />
|
||||
)
|
||||
this.state = { idx: 0 }
|
||||
}
|
||||
|
||||
renderImage (path) {
|
||||
@@ -27,7 +18,7 @@ class SourceOverlay extends React.Component {
|
||||
<Img
|
||||
className='source-image'
|
||||
src={path}
|
||||
loader={<div style={{ width: '400px', height: '400px' }}><Spinner /></div>}
|
||||
loader={<div className='source-image-loader'><Spinner /></div>}
|
||||
unloader={<NoSource failedUrls={this.props.source.paths} />}
|
||||
/>
|
||||
</div>
|
||||
@@ -35,7 +26,6 @@ class SourceOverlay extends React.Component {
|
||||
}
|
||||
|
||||
renderVideo (path) {
|
||||
// NB: assume only one video
|
||||
return (
|
||||
<div className='media-player'>
|
||||
<Player
|
||||
@@ -81,11 +71,13 @@ class SourceOverlay extends React.Component {
|
||||
}
|
||||
|
||||
getTypeCounts (media) {
|
||||
let counts = { Image: 0, Video: 0, Text: 0 }
|
||||
media.forEach(m => {
|
||||
counts[m.type] += 1
|
||||
})
|
||||
return counts
|
||||
return media.reduce(
|
||||
(acc, vl) => {
|
||||
acc[vl.type] += 1
|
||||
return acc
|
||||
},
|
||||
{ Image: 0, Video: 0, Text: 0 }
|
||||
)
|
||||
}
|
||||
|
||||
_renderPath (media) {
|
||||
@@ -122,26 +114,52 @@ class SourceOverlay extends React.Component {
|
||||
|
||||
_renderContent (media) {
|
||||
const el = document.querySelector(`.source-media-gallery`)
|
||||
const shiftW = (el) ? el.getBoundingClientRect().width : 0
|
||||
const shiftW = el ? el.getBoundingClientRect().width : 0
|
||||
return (
|
||||
<div className='source-media-gallery' style={{ transition: 'transform 0.2s ease', transform: `translate(${this.state.idx * -shiftW}px)` }}>
|
||||
<div className='source-media-gallery' style={{ transform: `translate(${this.state.idx * -shiftW}px)` }}>
|
||||
{media.map((m) => this._renderPath(m))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
onShiftGallery (shift) {
|
||||
// no more left
|
||||
if (this.state.idx === 0 && shift === -1) return
|
||||
if (this.state.idx - 1 === this.props.source.paths.length && shift === 1) return
|
||||
// no more right
|
||||
if (this.state.idx === this.props.source.paths.length - 1 && shift === 1) return
|
||||
this.setState({ idx: this.state.idx + shift })
|
||||
}
|
||||
|
||||
_renderControls () {
|
||||
const backArrow = this.state.idx !== 0 ? (
|
||||
<div
|
||||
className='back'
|
||||
onClick={() => this.onShiftGallery(-1)}
|
||||
>
|
||||
<svg>
|
||||
<path d='M0,-7.847549217020565L6.796176979388489,3.9237746085102825L-6.796176979388489,3.9237746085102825Z' />
|
||||
</svg>
|
||||
</div>
|
||||
) : null
|
||||
|
||||
console.log(this.state.idx)
|
||||
console.log(this.props.source.paths.length)
|
||||
const forwardArrow = this.state.idx < this.props.source.paths.length - 1 ? (
|
||||
<div
|
||||
className='next'
|
||||
onClick={() => this.onShiftGallery(1)}
|
||||
>
|
||||
<svg>
|
||||
<path d='M0,-7.847549217020565L6.796176979388489,3.9237746085102825L-6.796176979388489,3.9237746085102825Z' />
|
||||
</svg>
|
||||
</div>
|
||||
) : null
|
||||
|
||||
if (this.props.source.paths.length > 1) {
|
||||
return (
|
||||
<div className='media-gallery-controls'>
|
||||
<div className='back' onClick={() => this.onShiftGallery(-1)}><svg><path d='M0,-7.847549217020565L6.796176979388489,3.9237746085102825L-6.796176979388489,3.9237746085102825Z' /></svg></div>
|
||||
<div className='next' onClick={() => this.onShiftGallery(1)}><svg><path d='M0,-7.847549217020565L6.796176979388489,3.9237746085102825L-6.796176979388489,3.9237746085102825Z' /></svg></div>
|
||||
{backArrow}
|
||||
{forwardArrow}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -159,7 +177,7 @@ class SourceOverlay extends React.Component {
|
||||
|
||||
return (
|
||||
<div className='mo-overlay' onClick={this.props.onCancel}>
|
||||
<div className='mo-container' onClick={(e) => { e.stopPropagation() }}>
|
||||
<div className='mo-container' onClick={e => e.stopPropagation()}>
|
||||
<div className='mo-header'>
|
||||
<div className='mo-header-close' onClick={this.props.onCancel}>
|
||||
<button className='side-menu-burg is-active'><span /></button>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
@import 'header';
|
||||
@import 'cardstack';
|
||||
@import 'narrativecard';
|
||||
@import 'mediaoverlay';
|
||||
@import 'sourceoverlay';
|
||||
@import 'map';
|
||||
@import 'timeline';
|
||||
@import 'tag-filters';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
$panel-width: 1000px;
|
||||
$panel-height: 700px;
|
||||
$panel-height: 1000px;
|
||||
$vimeo-width: $panel-width - 100;
|
||||
$vimeo-height: $panel-height / 2;
|
||||
|
||||
@@ -22,20 +22,18 @@ $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;
|
||||
// min-height: $panel-height;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 80vh;
|
||||
height: $panel-height;
|
||||
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);
|
||||
|
||||
.back, .next {
|
||||
width: 30px;
|
||||
max-width: 30px;
|
||||
max-height: 30px;
|
||||
height: 30px;
|
||||
background: $darkgrey;
|
||||
color: $offwhite;
|
||||
@@ -84,15 +82,13 @@ $header-inset: 10px;
|
||||
|
||||
.mo-media-container {
|
||||
flex: 1;
|
||||
/*display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;*/
|
||||
display: inline-block;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-height: 60vh;
|
||||
max-height: calc(#{$panel-height} - 100px);
|
||||
padding: 20px;
|
||||
font-family: "Lato", Helvetica, sans-serif;
|
||||
|
||||
@@ -109,7 +105,7 @@ $header-inset: 10px;
|
||||
.media-gallery-controls {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: -50%;
|
||||
}
|
||||
@@ -127,7 +123,7 @@ $header-inset: 10px;
|
||||
box-sizing: border-box;
|
||||
min-height: 100px;
|
||||
width: 100%;
|
||||
padding: $padding;
|
||||
// padding: $padding;
|
||||
|
||||
.mo-box-title {
|
||||
display: flex;
|
||||
@@ -184,20 +180,6 @@ $header-inset: 10px;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.media-player {
|
||||
min-width: $vimeo-width;
|
||||
max-width: $vimeo-width;
|
||||
min-height: $vimeo-height;
|
||||
max-height: $vimeo-height;
|
||||
border: none;
|
||||
|
||||
iframe, video {
|
||||
width: $vimeo-width;
|
||||
height: $vimeo-height - 50;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.media-controls {
|
||||
padding: 0 50px;
|
||||
}
|
||||
@@ -230,22 +212,22 @@ $header-inset: 10px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
transition: transform 0.6s ease 0s;
|
||||
width: 100%;
|
||||
// min-width: $panel-width - 30px;
|
||||
// min-height: $panel-height;
|
||||
margin: 0;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.source-text-container {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: $lightwhite;
|
||||
// background: $lightwhite;
|
||||
box-sizing: border-box;
|
||||
padding: 0 calc(50% - 400px);
|
||||
overflow-y: scroll;
|
||||
font-family: 'Merriweather', Georgia, serif;
|
||||
line-height: 1.5em;
|
||||
min-width: 100%;
|
||||
|
||||
a {
|
||||
color: $darkgrey;
|
||||
@@ -262,37 +244,36 @@ $header-inset: 10px;
|
||||
.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;
|
||||
// height: 100%;
|
||||
// min-width: calc(100% - 20px);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.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;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.source-image, .source-video {
|
||||
max-width: calc(100% - 20px);
|
||||
max-height: calc(100% - 20px);
|
||||
// max-width: calc(100% - 20px);
|
||||
// max-height: calc(100% - 20px);
|
||||
padding: 0px;
|
||||
font-family: 'Lato', Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.source-image-loader {
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.video-react .video-react-progress-control {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.video-react .video-react-control {
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user