diff --git a/src/components/App.jsx b/src/components/App.jsx
index ac12e14..f876253 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -1,13 +1,11 @@
import '../scss/main.scss'
import React from 'react'
-import Dashboard from './Dashboard.jsx'
+import Layout from './Layout'
class App extends React.Component {
render () {
return (
-
{
actions.updateSource(null)
diff --git a/src/components/Overlay/Content.js b/src/components/Overlay/Content.js
new file mode 100644
index 0000000..9c1db50
--- /dev/null
+++ b/src/components/Overlay/Content.js
@@ -0,0 +1,61 @@
+import React from 'react'
+import { Player } from 'video-react'
+import Img from 'react-image'
+import Md from './Md'
+import Spinner from '../presentational/Spinner'
+import NoSource from '../presentational/NoSource'
+
+export default ({ media, viewIdx }) => {
+ const el = document.querySelector(`.source-media-gallery`)
+ const shiftW = el ? el.getBoundingClientRect().width : 0
+
+ function renderMedia (media) {
+ const { path, type } = media
+ switch (type) {
+ case 'Image':
+ return (
+
+

}
+ unloader={}
+ />
+
+ )
+ case 'Video':
+ return (
+
+ )
+ case 'Text':
+ return (
+
+ }
+ unloader={() => this.renderError()}
+ />
+
+ )
+ default:
+ return (
+
+ )
+ }
+ }
+
+ return (
+
+ {media.map((m) => renderMedia(m))}
+
+ )
+}
diff --git a/src/components/Overlay/Controls.js b/src/components/Overlay/Controls.js
new file mode 100644
index 0000000..e547123
--- /dev/null
+++ b/src/components/Overlay/Controls.js
@@ -0,0 +1,36 @@
+import React from 'react'
+
+export default ({ viewIdx, paths, onShiftHandler }) => {
+ const backArrow = viewIdx !== 0 ? (
+ onShiftHandler(-1)}
+ >
+
+
+ ) : null
+ const forwardArrow = viewIdx < paths.length - 1 ? (
+ onShiftHandler(1)}
+ >
+
+
+ ) : null
+
+ if (paths.length > 1) {
+ return (
+
+ {backArrow}
+ {forwardArrow}
+
+ )
+ }
+ return (
+
+ )
+}
diff --git a/src/components/presentational/LoadingOverlay.js b/src/components/Overlay/Loading.js
similarity index 100%
rename from src/components/presentational/LoadingOverlay.js
rename to src/components/Overlay/Loading.js
diff --git a/src/components/Md.jsx b/src/components/Overlay/Md.js
similarity index 100%
rename from src/components/Md.jsx
rename to src/components/Overlay/Md.js
diff --git a/src/components/Overlay/Media.js b/src/components/Overlay/Media.js
new file mode 100644
index 0000000..158f8ae
--- /dev/null
+++ b/src/components/Overlay/Media.js
@@ -0,0 +1,77 @@
+import React from 'react'
+import Content from './Content'
+import Controls from './Controls'
+import { selectTypeFromPath } from '../../js/utilities'
+
+class SourceOverlay extends React.Component {
+ constructor () {
+ super()
+ this.state = { idx: 0 }
+ this.onShiftGallery = this.onShiftGallery.bind(this)
+ }
+
+ getTypeCounts (media) {
+ return media.reduce(
+ (acc, vl) => {
+ acc[vl.type] += 1
+ return acc
+ },
+ { Image: 0, Video: 0, Text: 0 }
+ )
+ }
+
+ onShiftGallery (shift) {
+ // no more left
+ if (this.state.idx === 0 && 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 })
+ }
+
+ render () {
+ if (typeof (this.props.source) !== 'object') {
+ return this.renderError()
+ }
+ const { url, title, paths, date, type, desc } = this.props.source
+
+ return (
+
+
e.stopPropagation()}>
+
+
+
+
+
{this.props.source.title.substring(0, 200)}
+
+
+
+
+
+
+
+ {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/SourceOverlay.jsx b/src/components/SourceOverlay.jsx
deleted file mode 100644
index 5b3a254..0000000
--- a/src/components/SourceOverlay.jsx
+++ /dev/null
@@ -1,216 +0,0 @@
-import React from 'react'
-import Img from 'react-image'
-import { Player } from 'video-react'
-import Md from './Md.jsx'
-import Spinner from './presentational/Spinner'
-import NoSource from './presentational/NoSource'
-// TODO: move render functions into presentational components
-
-class SourceOverlay extends React.Component {
- constructor () {
- super()
- this.state = { idx: 0 }
- }
-
- renderImage (path) {
- return (
-
-

}
- unloader={}
- />
-
- )
- }
-
- renderVideo (path) {
- return (
-
- )
- }
-
- renderText (path) {
- return (
-
- }
- unloader={() => this.renderError()}
- />
-
- )
- }
-
- renderNoSupport (ext) {
- return (
-
- )
- }
-
- toMedia (path) {
- let type
- switch (true) {
- case /\.(png|jpg)$/.test(path):
- type = 'Image'; break
- case /\.(mp4)$/.test(path):
- type = 'Video'; break
- case /\.(md)$/.test(path):
- type = 'Text'; break
- default:
- type = 'Unknown'; break
- }
- return { type, path }
- }
-
- getTypeCounts (media) {
- return media.reduce(
- (acc, vl) => {
- acc[vl.type] += 1
- return acc
- },
- { Image: 0, Video: 0, Text: 0 }
- )
- }
-
- _renderPath (media) {
- const { path, type } = media
- switch (type) {
- case 'Image':
- return this.renderImage(path)
- case 'Video':
- return this.renderVideo(path)
- case 'Text':
- return this.renderText(path)
- default:
- return this.renderNoSupport(path.split('.')[1])
- }
- }
-
- _renderCounts (counts) {
- const strFor = type =>
- counts[type] > 0
- ? `${counts[type]} ${type.toLowerCase()}${counts[type] > 1 ? 's' : ''}`
- : ''
- const img = strFor('Image')
- const vid = strFor('Video')
- const txt = strFor('Text')
-
- return (
-
- {img || ''}
- {(img && vid) ? `, ${vid}` : (vid || '')}
- {((img || vid) && txt) ? `, ${txt}` : (txt || '')}
-
- )
- }
-
- _renderContent (media) {
- const el = document.querySelector(`.source-media-gallery`)
- const shiftW = el ? el.getBoundingClientRect().width : 0
- return (
-
- {media.map((m) => this._renderPath(m))}
-
- )
- }
-
- onShiftGallery (shift) {
- // no more left
- if (this.state.idx === 0 && 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 ? (
- this.onShiftGallery(-1)}
- >
-
-
- ) : null
- const forwardArrow = this.state.idx < this.props.source.paths.length - 1 ? (
- this.onShiftGallery(1)}
- >
-
-
- ) : null
-
- if (this.props.source.paths.length > 1) {
- return (
-
- {backArrow}
- {forwardArrow}
-
- )
- }
- return (
-
- )
- }
-
- render () {
- if (typeof (this.props.source) !== 'object') {
- return this.renderError()
- }
- const { url, title, paths, date, type, desc } = this.props.source
- const media = paths.map(this.toMedia)
-
- return (
-
-
e.stopPropagation()}>
-
-
-
-
-
{this.props.source.title.substring(0, 200)}
-
-
- {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/js/utilities.js b/src/js/utilities.js
index 8d04788..00d9987 100644
--- a/src/js/utilities.js
+++ b/src/js/utilities.js
@@ -136,3 +136,18 @@ export function toggleFlagAC (flag) {
}
})
}
+
+export function selectTypeFromPath (path) {
+ let type
+ switch (true) {
+ case /\.(png|jpg)$/.test(path):
+ type = 'Image'; break
+ case /\.(mp4)$/.test(path):
+ type = 'Video'; break
+ case /\.(md)$/.test(path):
+ type = 'Text'; break
+ default:
+ type = 'Unknown'; break
+ }
+ return { type, path }
+}