summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-11-25 22:19:15 +0100
committerJules Laplace <julescarbon@gmail.com>2018-11-25 22:19:15 +0100
commitee3d0d98e19f1d8177d85af1866fd0ee431fe9ea (patch)
tree41372528e78d4328bc2a47bbbabac7e809c58894 /client
parent255b8178af1e25a71fd23703d30c0d1f74911f47 (diff)
moving stuff
Diffstat (limited to 'client')
-rw-r--r--client/actions.js9
-rw-r--r--client/app.js46
-rw-r--r--client/common/activeLink.component.js16
-rw-r--r--client/common/classifier.component.js99
-rw-r--r--client/common/common.css347
-rw-r--r--client/common/detectionBoxes.component.js15
-rw-r--r--client/common/detectionList.component.js16
-rw-r--r--client/common/footer.component.js10
-rw-r--r--client/common/gate.component.js21
-rw-r--r--client/common/header.component.js1
-rw-r--r--client/common/index.js36
-rw-r--r--client/common/keyframe.component.js118
-rw-r--r--client/common/keyframes.component.js95
-rw-r--r--client/common/loader.component.js10
-rw-r--r--client/common/sidebar.component.js37
-rw-r--r--client/common/table.component.js121
-rw-r--r--client/common/video.component.js47
-rw-r--r--client/index.js19
-rw-r--r--client/metadata/index.js25
-rw-r--r--client/session.js5
-rw-r--r--client/store.js38
-rw-r--r--client/types.js21
-rw-r--r--client/util.js167
23 files changed, 0 insertions, 1319 deletions
diff --git a/client/actions.js b/client/actions.js
deleted file mode 100644
index ba899f06..00000000
--- a/client/actions.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as search from './search/search.actions'
-import * as review from './review/review.actions'
-import * as metadata from './metadata/metadata.actions'
-
-export {
- search,
- review,
- metadata,
-}
diff --git a/client/app.js b/client/app.js
deleted file mode 100644
index 6c008ec6..00000000
--- a/client/app.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import React, { Component } from 'react'
-import { ConnectedRouter } from 'connected-react-router'
-import { Route, Switch } from 'react-router'
-
-import { Header, Sidebar, Footer } from './common'
-import * as Metadata from './metadata'
-import * as Search from './search'
-import * as Review from './review'
-
-export default class App extends Component {
- render() {
- return (
- <ConnectedRouter history={this.props.history}>
- <div>
- <Header />
- <div className='app'>
- <Route path="/metadata/" component={Sidebar} />
- <div className='body'>
- <Route path="/search/" component={Search.Menu} />
- <Route path="/metadata/:hash/" component={Metadata.Heading} />
- <Switch>
- <Route exact path="/metadata/:hash/summary/" component={Metadata.Summary} />
- <Route exact path="/metadata/:hash/mediaRecord/" component={Metadata.MediaRecord} />
- <Route exact path="/metadata/:hash/mediaInfo/" component={Metadata.MediaInfo} />
- <Route exact path="/metadata/:hash/keyframe/:frame/" component={Metadata.KeyframeSingle} />
- <Route exact path="/metadata/:hash/keyframe/" component={Metadata.KeyframeList} />
- <Route exact path="/metadata/:hash/coco/" component={Metadata.Coco} />
- <Route exact path="/metadata/:hash/places365/" component={Metadata.Places365} />
- <Route exact path="/metadata/:hash/sugarcube/" component={Metadata.Sugarcube} />
- <Route exact path="/metadata/:hash/" component={Metadata.Summary} />
- <Route exact path="/metadata/" render={() => <div className='notFound'><h4>NOT FOUND</h4></div>} />
- <Route exact path="/search/" component={Search.Container} />
- <Route exact path="/search/keyframe/:verified/:hash/:frame/" component={Search.Container} />
- <Route exact path="/search/keyframe/:hash/:frame/" component={Search.Container} />
- <Route exact path="/search/browse/:hash/" component={Search.Browse} />
- <Route exact path="/search/random/" component={Search.Random} />
- <Route exact path="/search/review/" component={Review.Saved} />
- </Switch>
- </div>
- </div>
- <Footer />
- </div>
- </ConnectedRouter>
- )
- }
-}
diff --git a/client/common/activeLink.component.js b/client/common/activeLink.component.js
deleted file mode 100644
index 59f63881..00000000
--- a/client/common/activeLink.component.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from 'react'
-import { NavLink } from 'react-router-dom'
-
-export default function ActiveLink({
- to,
- className = 'navlink',
- children
-}) {
- return (
- <span className={className}>
- <NavLink to={to}>
- {children}
- </NavLink>
- </span>
- )
-}
diff --git a/client/common/classifier.component.js b/client/common/classifier.component.js
deleted file mode 100644
index af6a4934..00000000
--- a/client/common/classifier.component.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import React, { Component } from 'react'
-import { courtesyS } from '../util'
-
-import { TableTuples, DetectionList, Keyframe } from '.'
-
-export default class Classifier extends Component {
- render() {
- const {
- tag,
- sha256,
- verified,
- keyframes = {},
- labels,
- summary,
- aspectRatio = 1.777,
- showAll,
- } = this.props
- let totalDetections = 0
- const keys = Object
- .keys(keyframes)
- .map(s => parseInt(s, 10))
- const validKeyframes = keys
- .sort((a, b) => a - b)
- .map(frame => {
- const detections = keyframes[frame]
- if (detections.length || showAll) {
- totalDetections += detections.length
- return { frame, detections }
- }
- return null
- })
- .filter(f => !!f)
- const detectionLookup = validKeyframes
- .reduce((a, b) => {
- b.detections.reduce((aa, { idx }) => {
- if (!(idx in aa)) aa[idx] = [labels[idx], 0]
- aa[idx][1] += 1
- return aa
- }, a)
- return a
- }, {})
- const detectionCounts = Object.keys(detectionLookup)
- .map(idx => detectionLookup[idx])
- .sort((a, b) => b[1] - a[1])
-
- if (summary) {
- return (
- <div>
- <h3>{tag}{' Detections'}</h3>
- <TableTuples
- list={detectionCounts}
- />
- </div>
- )
- }
- return (
- <div>
- <h2>{tag}</h2>
- <h3>Detections</h3>
- <TableTuples
- list={detectionCounts}
- />
- <h3>Frames</h3>
- <ul className='meta'>
- <li>
- {'Displaying '}{validKeyframes.length}{' / '}{courtesyS(keys.length, 'frame')}
- </li>
- <li>
- {courtesyS(totalDetections, 'detection')}{' found'}
- </li>
- </ul>
- <div className='thumbnails'>
- {validKeyframes.map(({ frame, detections }) => (
- <Keyframe
- key={frame}
- sha256={sha256}
- frame={frame}
- verified={verified}
- size='th'
- showFrame
- showTimestamp
- aspectRatio={aspectRatio}
- detectionList={[
- { labels, detections }
- ]}
- >
- <DetectionList
- labels={labels}
- detections={detections}
- width={160}
- height={90}
- />
- </Keyframe>
- ))}
- </div>
- </div>
- )
- }
-}
diff --git a/client/common/common.css b/client/common/common.css
deleted file mode 100644
index 4b939df0..00000000
--- a/client/common/common.css
+++ /dev/null
@@ -1,347 +0,0 @@
-/* css boilerplate */
-
-* { box-sizing: border-box; }
-html,body {
- margin: 0; padding: 0;
- width: 100%; height: 100%;
-}
-body {
- font-family: Helvetica, sans-serif;
- font-weight: 300;
-}
-
-h1 {
-
-}
-h2 {
- font-weight: normal;
- margin: 10px 0;
- padding: 3px;
- font-size: 24px;
-}
-h3 {
- font-weight: normal;
- margin: 10px 0 0 0;
- padding: 3px;
- font-size: 18px;
-}
-h4 {
- font-weight: 300;
- font-size: 12px;
- letter-spacing: 2px;
- color: #888;
- text-transform: uppercase;
- margin: 5px 10px;
- margin-top: 20px;
-}
-h4:first-child {
- margin-top: 10px;
-}
-
-.app {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
-}
-
-/* header stuff */
-
-header {
- width: 100%;
- background: #11f;
- color: white;
- align-items: stretch;
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- z-index: 3;
-}
-header > section {
- justify-content: flex-start;
- align-items: center;
- display: flex;
- flex: 1 0;
- font-weight: bold;
-}
-header > section:last-of-type {
- justify-content: flex-end;
-}
-
-/* sidebar / body columns */
-
-.sidebar {
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
- align-items: flex-start;
- height: 100%;
- float: left;
- width: 200px;
- flex: 0 0 200px;
- padding: 10px;
- margin-right: 10px;
-}
-.sidebar a {
- display: block;
- padding: 10px 10px;
- text-decoration: none;
- color: #444;
-}
-.sidebar a.active {
- font-weight: bold;
- color: #222;
-}
-.body {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
- flex-grow: 1;
-}
-.body > div {
- padding-bottom: 40px;
-}
-
-/* buttons / forms */
-
-.btn:focus, .btn:hover {
- background: #f1f1fc;
- color: #4b48d6 !important;
- text-decoration: none;
-}
-.btn {
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- background: #fff;
- border: .05rem solid;
- border-radius: 2px;
- margin-right: 5px;
- color: #11f;
- cursor: pointer;
- display: inline-block;
- font-size: .8rem;
- height: 1.8rem;
- line-height: 1rem;
- outline: none;
- padding: .35rem .4rem;
- text-align: center;
- text-decoration: none;
- -webkit-transition: all .2s ease;
- -o-transition: all .2s ease;
- transition: all .2s ease;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- vertical-align: middle;
- white-space: nowrap;
-}
-.btn.reset,
-.btn.panic {
- color: #b00;
-}
-.btn.btn-primary {
- background: #11f;
- border-color: #11f;
- color: white;
-}
-.btn[disabled] {
- color: #bbb !important;
- border-color: #bbb !important;
- background: white !important;
- cursor: default;
-}
-.btn.btn-primary:focus,
-.btn.btn-primary:hover {
- background: #0808ee;
- color: white !important;
-}
-.row .btn {
- margin: 0 5px 0 0;
-}
-input[type=text] {
- border: 1px solid #888;
- padding: 4px;
- font-size: 15px;
-}
-
-
-/* tables on metadata pages */
-
-table {
- border: 0;
- margin: 0;
- padding: 0;
- border-spacing: 0;
-}
-.tableObject td,
-.tableObject th {
- padding: 3px;
- vertical-align: top;
-}
-.tableObject hr {
- width: 100%;
- color: transparent;
- border: 0;
- border-bottom: 1px solid #bbb;
- align: left;
- margin: 3px 0;
- padding: 0;
-}
-.tableObject th,
-.tableTuples th {
- min-width: 145px;
- text-align: left;
- text-transform: capitalize;
- padding: 3px;
- padding-right: 10px;
- font-weight: 300;
- color: #333;
-}
-.tableTuples td {
- text-align: right;
- padding: 3px;
-}
-.tableObject td {
- font-weight: normal;
- color: #000;
-}
-.tableObject .tableObject {
- border: 1px solid #ddd;
-}
-.tableArray {
- border: 1px solid #ddd;
- border-spacing: 0;
-}
-.tableArray td {
- border-bottom: 1px solid #ddd;
-}
-.gray {
- font-size: 12px;
- color: #888;
- display: block;
-}
-.sha256.heading {
- margin: 20px 0 0px;
-}
-.gray span {
- padding-right: 5px;
-}
-.gray {
- margin-bottom: 10px;
-}
-.gray a {
- color: #666;
-}
-
-.verified {
- color: #080;
- font-weight: bold;
-}
-.unverified {
- color: #f00;
- font-weight: 300;
-}
-
-.loading, .error {
- font-weight: normal;
- margin: 10px 0;
- padding: 3px;
- font-size: 24px;
-}
-
-.title {
- text-transform: capitalize;
-}
-.rect {
- position: absolute;
-}
-.rect { border: 1px solid rgba(0,0,255); background-color: rgba(0,0,255,0.1); }
-
-/* videos / video preloader */
-
-video {
- max-width: 640px;
- margin: 10px 0;
-}
-.video {
- margin: 0 0 10px 0;
-}
-.video .bg {
- cursor: pointer;
- position: relative;
- background-size: cover;
-}
-.video .play {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate3d(-50%, -50%, 0);
- width: 20%;
- height: 20%;
- background-image: url(/search/static/img/play.png);
- background-position: center center;
- background-size: contain;
- background-repeat: no-repeat;
-}
-.desktop .video .play:hover {
- -webkit-filter: invert(60%) sepia(100%) saturate(500%) hue-rotate(160deg);
-}
-
-/* spectre.css loader */
-
-.loaderWrapper {
- display: inline-block;
- position: relative;
- width: .8rem;
- height: .8rem;
- padding: 10px;
-}
-.loader {
- color: transparent !important;
- min-height: .8rem;
- pointer-events: none;
- position: relative;
-}
-
-.loader::after {
- animation: loader 500ms infinite linear;
- border: .1rem solid #5755d9;
- border-radius: 50%;
- border-right-color: transparent;
- border-top-color: transparent;
- content: "";
- display: block;
- height: .8rem;
- left: 50%;
- margin-left: -.4rem;
- margin-top: -.4rem;
- position: absolute;
- top: 50%;
- width: .8rem;
- z-index: 1;
-}
-
-.loader.loader-lg {
- min-height: 2rem;
-}
-
-.loader.loader-lg::after {
- height: 1.6rem;
- margin-left: -.8rem;
- margin-top: -.8rem;
- width: 1.6rem;
-}
-
-@keyframes loader {
- 0% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(360deg);
- }
-} \ No newline at end of file
diff --git a/client/common/detectionBoxes.component.js b/client/common/detectionBoxes.component.js
deleted file mode 100644
index c4872ea8..00000000
--- a/client/common/detectionBoxes.component.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react'
-
-import { px } from '../util'
-
-export default function DetectionBoxes({ detections, width, height }) {
- return detections.map(({ rect }, i) => (
- rect &&
- <div className='rect' key={i} style={{
- left: px(rect[0], width),
- top: px(rect[1], height),
- width: px(rect[2] - rect[0], width),
- height: px(rect[3] - rect[1], height),
- }} />
- ))
-}
diff --git a/client/common/detectionList.component.js b/client/common/detectionList.component.js
deleted file mode 100644
index 416e66d8..00000000
--- a/client/common/detectionList.component.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from 'react'
-
-export default function DetectionList({ detections, labels, tag, showEmpty }) {
- return (
- <span className='detectionList'>
- {tag && <h3>{tag}</h3>}
- {!detections.length && showEmpty && <label><small>No detections</small></label>}
- {detections.map(({ idx, score, rect }, i) => (
- <label key={i}>
- <small className='title'>{(labels[idx] || 'Unknown').replace(/_/, ' ')}</small>
- <small>{score.toFixed(2)}</small>
- </label>
- ))}
- </span>
- )
-}
diff --git a/client/common/footer.component.js b/client/common/footer.component.js
deleted file mode 100644
index 7c82b44b..00000000
--- a/client/common/footer.component.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react'
-import { Link } from 'react-router-dom'
-import { connect } from 'react-redux'
-
-export default function Footer(props) {
- return (
- <footer>
- </footer>
- );
-}
diff --git a/client/common/gate.component.js b/client/common/gate.component.js
deleted file mode 100644
index 9bf9287b..00000000
--- a/client/common/gate.component.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react'
-import { connect } from 'react-redux'
-
-function Gate(props) {
- const { app, tag, View } = props
- const data = app[tag]
- if (!data) return null
- if (data === 'loading') {
- return <div className='tableObject loading'>{tag}{': Loading'}</div>
- }
- if (data.err) {
- return <div className='tableObject error'>{tag}{' Error: '}{data.err}</div>
- }
- return <View data={data} {...props} />
-}
-
-const mapStateToProps = state => ({
- app: state.metadata
-})
-
-export default connect(mapStateToProps)(Gate)
diff --git a/client/common/header.component.js b/client/common/header.component.js
deleted file mode 100644
index 84fe306f..00000000
--- a/client/common/header.component.js
+++ /dev/null
@@ -1 +0,0 @@
-/* imported from main vcat application */
diff --git a/client/common/index.js b/client/common/index.js
deleted file mode 100644
index ad9fe5e1..00000000
--- a/client/common/index.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import Header from 'vcat-header'
-
-import ActiveLink from './activeLink.component'
-import Classifier from './classifier.component'
-import DetectionBoxes from './detectionBoxes.component'
-import DetectionList from './detectionList.component'
-// import Header from './header.component'
-import Footer from './footer.component'
-import Loader from './loader.component'
-import Sidebar from './sidebar.component'
-import Gate from './gate.component'
-import Keyframe from './keyframe.component'
-import Keyframes from './keyframes.component'
-import Video from './video.component'
-import { TableObject, TableArray, TableTuples, TableRow, TableCell } from './table.component'
-import './common.css'
-
-export {
- Header,
- Footer,
- Sidebar,
- Loader,
- Gate,
- TableObject,
- TableArray,
- TableTuples,
- TableRow,
- TableCell,
- ActiveLink,
- Classifier,
- DetectionList,
- DetectionBoxes,
- Keyframe,
- Keyframes,
- Video,
-}
diff --git a/client/common/keyframe.component.js b/client/common/keyframe.component.js
deleted file mode 100644
index c77db3ac..00000000
--- a/client/common/keyframe.component.js
+++ /dev/null
@@ -1,118 +0,0 @@
-import React from 'react'
-import { Link } from 'react-router-dom'
-import { imageUrl, timestamp, keyframeUri, widths, verify } from '../util'
-import { DetectionBoxes } from '.'
-
-import * as searchActions from '../search/search.actions'
-
-export default function Keyframe({
- verified,
- sha256,
- frame,
- score,
- isSaved,
- fps = 25,
- size = 'th',
- className,
- showHash,
- showFrame,
- showTimestamp,
- showScore,
- showSearchButton,
- showSaveButton,
- to,
- children,
- detectionList = [],
- aspectRatio = 1.777,
- onClick,
- reviewActions,
-}) {
- if (!sha256) return null
- const width = widths[size]
- const height = Math.round(width / aspectRatio)
- return (
- <div className={(className || 'keyframe') + (isSaved ? ' isSaved' : '')}>
- <div className="thumbnail">
- <PossiblyExternalLink to={to || keyframeUri(sha256, frame)} onClick={onClick}>
- <img
- alt={'Frame #' + frame}
- src={imageUrl(verified, sha256, frame, size)}
- width={width}
- height={height}
- onClick={onClick}
- />
- {detectionList.map(({ labels, detections }, i) => (
- <DetectionBoxes
- key={i}
- labels={labels}
- detections={detections}
- width={width}
- height={height}
- />
- ))}
- </PossiblyExternalLink>
- {(reviewActions && (showSearchButton || showSaveButton)) &&
- <label className='searchButtons'>
- {showSearchButton &&
- <Link
- to={searchActions.publicUrl.searchByVerifiedFrame(verified, sha256, frame)}
- className='btn'
- >
- Search
- </Link>
- }
- {showSaveButton && (isSaved
- ? <button
- onClick={() => reviewActions.unsave({ hash: sha256, frame, verified })}
- className={'btn btn-primary saved'}
- >
- {'Saved'}
- </button>
- : <button
- onClick={() => reviewActions.save({ hash: sha256, frame, verified })}
- className={'btn btn save'}
- >
- {'Save'}
- </button>
- )}
- </label>
- }
- </div>
- {(showHash || showFrame || showTimestamp || showScore) &&
- <label>
- {showHash &&
- <small>
- <Link to={searchActions.publicUrl.browse(sha256)}>
- <span
- title={sha256}
- className={'sha256 ' + verify(verified)}
- >
- {'▶ '}
- {sha256.substr(0, 6)}
- </span>
- </Link>
- </small>
- }
- {showFrame &&
- <small>
- <span>{'Frame #'}{frame}</span>
- </small>
- }
- {showTimestamp && <small>{timestamp(frame, fps)}</small>}
- {showScore && !!score && <small>{score}</small>}
- </label>
- }
- {children}
- </div>
- )
-}
-
-const PossiblyExternalLink = props => {
- if (props.onClick) {
- return props.children
- }
- if (props.to.match(/^http/)) {
- return <a href={props.to} target='_blank' rel='noopener noreferrer'>{props.children}</a>
- }
- return <Link {...props} />
-}
diff --git a/client/common/keyframes.component.js b/client/common/keyframes.component.js
deleted file mode 100644
index 62eda45e..00000000
--- a/client/common/keyframes.component.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import React from 'react'
-import { Link } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-
-import { Keyframe } from '.'
-import * as reviewActions from '../review/review.actions'
-import * as searchActions from '../search/search.actions'
-
-function Keyframes(props) {
- // console.log(props)
- let {
- frames,
- groupByHash,
- } = props
- let minDistance = 0
- if (frames && frames.length) {
- minDistance = frames[0].distance || 0
- }
- if (!groupByHash) {
- return (
- <KeyframeList
- minDistance={minDistance}
- {...props}
- />
- )
- }
- const frameGroups = frames.reduce((a, b) => {
- if (a[b.hash]) {
- a[b.hash].push(b)
- } else {
- a[b.hash] = [b]
- }
- return a
- }, {})
- return Object.keys(frameGroups)
- .map(hash => [frameGroups[hash].length, hash])
- .sort((a, b) => b[0] - a[0])
- .map(([count, hash]) => (
- <KeyframeList
- {...props}
- count={count}
- key={hash}
- minDistance={minDistance}
- frames={frameGroups[hash]}
- label={hash}
- />
- ))
-}
-
-function KeyframeList(props) {
- let {
- saved = {},
- frames,
- options,
- review,
- search,
- minDistance,
- label,
- count,
- ...frameProps
- } = props
- if (!frames) return null
- return (
- <div className={label ? 'keyframes keyframeGroup' : 'keyframes'}>
- {label && <h4><Link to={searchActions.publicUrl.browse(label)}>{label}</Link> ({count})</h4>}
- {frames.map(({ hash, frame, verified, distance }) => (
- <Keyframe
- key={hash + '_' + frame}
- sha256={hash}
- frame={frame}
- score={100 - Math.round(distance - minDistance) + '%'}
- verified={verified}
- isSaved={!!saved[hash] && !!saved[hash].frames && !!saved[hash].frames[parseInt(frame, 10)]}
- size={options.thumbnailSize}
- onClick={() => review.toggleSaved({ verified, hash, frame })}
- reviewActions={review}
- {...frameProps}
- />
- ))}
- </div>
- )
-}
-
-const mapStateToProps = state => ({
- saved: state.review.saved,
- options: state.search.options,
-})
-
-const mapDispatchToProps = dispatch => ({
- review: bindActionCreators({ ...reviewActions }, dispatch),
- search: bindActionCreators({ ...searchActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(Keyframes)
diff --git a/client/common/loader.component.js b/client/common/loader.component.js
deleted file mode 100644
index 6795424b..00000000
--- a/client/common/loader.component.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import React, { Component } from 'react'
-
-export default function Loader() {
- return (
- <div className='loaderWrapper'>
- <div className='loader'>
- </div>
- </div>
- )
-} \ No newline at end of file
diff --git a/client/common/sidebar.component.js b/client/common/sidebar.component.js
deleted file mode 100644
index 487f3289..00000000
--- a/client/common/sidebar.component.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import React, { Component } from 'react'
-import { NavLink } from 'react-router-dom'
-import { connect } from 'react-redux'
-
-class Sidebar extends Component {
- render() {
- const { hash } = this.props
- if (!hash) {
- return (
- <div className="sidebar">
- </div>
- )
- }
- return (
- <div className="sidebar">
- <h4>Media</h4>
- <NavLink to={'/metadata/' + hash + '/summary/'}>Summary</NavLink>
- <NavLink to={'/metadata/' + hash + '/mediaRecord/'}>Media Record</NavLink>
- <NavLink to={'/metadata/' + hash + '/mediaInfo/'}>Media Info</NavLink>
- <NavLink to={'/metadata/' + hash + '/sugarcube/'}>Sugarcube</NavLink>
-
- <h4>Keyframes</h4>
- <NavLink to={'/metadata/' + hash + '/keyframe/'}>Keyframe</NavLink>
-
- <h4>Detectors</h4>
- <NavLink to={'/metadata/' + hash + '/places365/'}>Places 365</NavLink>
- <NavLink to={'/metadata/' + hash + '/coco/'}>Coco</NavLink>
- </div>
- )
- }
-}
-
-const mapStateToProps = state => ({
- hash: state.metadata.hash,
-})
-
-export default connect(mapStateToProps)(Sidebar)
diff --git a/client/common/table.component.js b/client/common/table.component.js
deleted file mode 100644
index 76a1d57c..00000000
--- a/client/common/table.component.js
+++ /dev/null
@@ -1,121 +0,0 @@
-import React from 'react'
-
-import { formatName } from '../util'
-
-const __HR__ = '__HR__'
-
-export function TableObject({ tag, object, order, summary }) {
- if (!object) return null
- if (object === 'loading') {
- return <div className='tableObject loading'>{tag}{': Loading'}</div>
- }
- if (object.err) {
- return <div className='tableObject error'>{tag}{' Error: '}{object.err}</div>
- }
- let objects = Object.keys(object)
- if (order) {
- const grouped = objects.reduce((a, b) => {
- const index = order.indexOf(b)
- if (index !== -1) {
- a.order.push([index, b])
- } else {
- a.alpha.push(b)
- }
- return a
- }, { order: [], alpha: [] })
- objects = grouped.order
- .sort((a, b) => a[0] - b[0])
- .map(([i, s]) => s)
- if (!summary) {
- objects = objects
- // .concat([__HR__])
- .concat(grouped.alpha.sort())
- }
- } else {
- objects = objects.sort()
- }
- return (
- <div>
- {tag && <h3>{tag}</h3>}
- <table className={'tableObject ' + tag}>
- <tbody>
- {objects.map((key, i) => (
- <TableRow key={key + '_' + i} name={key} value={object[key]} />
- ))}
- </tbody>
- </table>
- </div>
- )
-}
-
-export function TableArray({ tag, list }) {
- if (!list) return null
- return (
- <div>
- {tag && <h3>{tag}</h3>}
- <table className={'tableArray ' + tag}>
- <tbody>
- {list.map((value, i) => (
- <tr key={tag + '_' + i}>
- <TableCell value={value} />
- </tr>
- ))}
- </tbody>
- </table>
- </div>
- )
-}
-
-export function TableTuples({ tag, list }) {
- if (!list) return null
- return (
- <div>
- {tag && <h3>{tag}</h3>}
- <table className={'tableTuples ' + tag}>
- <tbody>
- {list.map(([key, ...values], i) => (
- <tr key={tag + '_' + i}>
- <th>{formatName(key)}</th>
- {values.map((value, j) => (
- <TableCell key={i + '_' + j} value={value} />
- ))}
- </tr>
- ))}
- </tbody>
- </table>
- </div>
- )
-}
-
-export function TableRow({ name, value }) {
- if (name === __HR__) {
- return (
- <tr>
- <th className='tr'>
- <hr />
- </th>
- </tr>
- )
- }
- return (
- <tr>
- <th>{formatName(name)}</th>
- <TableCell name={name} value={value} />
- </tr>
- )
-}
-
-export function TableCell({ value }) {
- if (value && typeof value === 'object') {
- if (value._raw) {
- value = value.value
- } else if (value.length) {
- value = <TableArray nested tag={''} list={value} />
- } else {
- value = <TableObject nested tag={''} object={value} />
- }
- }
- return (
- <td>{value}</td>
- )
-}
diff --git a/client/common/video.component.js b/client/common/video.component.js
deleted file mode 100644
index e5525bf6..00000000
--- a/client/common/video.component.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import React, { Component } from 'react'
-import { connect } from 'react-redux'
-import { imageUrl, widths } from '../util'
-
-import { Gate } from '.'
-
-class Video extends Component {
- state = {
- playing: false,
- }
-
- render() {
- const { app, data, size } = this.props
- const { playing } = this.state
- const { sugarcube } = data.metadata
- const url = sugarcube.fp.replace('/var/www/files/', 'https://cube.syrianarchive.org/')
- const { sha256, verified } = app.mediainfo
- const { video } = app.mediainfo.metadata.mediainfo
- const keyframe = app.keyframe.metadata.keyframe.basic[0]
- return (
- <div className='video'>
- {playing
- ? <video src={url} autoPlay controls muted />
- : <div
- className='bg'
- style={{
- width: widths[size || 'sm'],
- height: widths[size || 'sm'] / video.aspect_ratio,
- backgroundImage: 'url(' + imageUrl(verified, sha256, keyframe, size) + ')',
- }}
- onClick={() => this.setState({ playing: true })}
- >
- <div className='play'></div>
- </div>
- }
- </div>
- )
- }
-}
-
-const mapStateToProps = () => ({
- tag: 'sugarcube',
-})
-
-export default connect(mapStateToProps)(props => (
- <Gate View={Video} {...props} />
-))
diff --git a/client/index.js b/client/index.js
deleted file mode 100644
index eddc5fb2..00000000
--- a/client/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
-import { AppContainer } from 'react-hot-loader'
-import { Provider } from 'react-redux'
-
-import App from './app'
-
-import { store, history } from './store'
-
-const container = document.createElement('div')
-document.body.appendChild(container)
-
-ReactDOM.render(
- <AppContainer>
- <Provider store={store}>
- <App history={history} />
- </Provider>
- </AppContainer>, container
-)
diff --git a/client/metadata/index.js b/client/metadata/index.js
deleted file mode 100644
index 0eef814e..00000000
--- a/client/metadata/index.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import Heading from './heading.component'
-import MediaInfo from './mediaInfo.component'
-import MediaRecord from './mediaRecord.component'
-import Summary from './summary.component'
-import KeyframeList from './keyframeList.component'
-import KeyframeSingle from './keyframeSingle.component'
-import KeyframeStatus from './keyframeStatus.component'
-import Coco from './coco.component'
-import Places365 from './places365.component'
-import Sugarcube from './sugarcube.component'
-
-import './metadata.css'
-
-export {
- Heading,
- MediaRecord,
- MediaInfo,
- Summary,
- KeyframeList,
- KeyframeSingle,
- KeyframeStatus,
- Coco,
- Places365,
- Sugarcube,
-}
diff --git a/client/session.js b/client/session.js
deleted file mode 100644
index 5bfae7eb..00000000
--- a/client/session.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Storage from 'store2'
-
-const session = Storage.namespace('vcat.search')
-
-export default session
diff --git a/client/store.js b/client/store.js
deleted file mode 100644
index 043af351..00000000
--- a/client/store.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { applyMiddleware, compose, combineReducers, createStore } from 'redux'
-import { connectRouter, routerMiddleware } from 'connected-react-router'
-import { createBrowserHistory } from 'history'
-import thunk from 'redux-thunk'
-import { login } from './util'
-
-import metadataReducer from './metadata/metadata.reducer'
-import searchReducer from './search/search.reducer'
-import reviewReducer from './review/review.reducer'
-
-const rootReducer = combineReducers({
- auth: (state = login()) => state,
- metadata: metadataReducer,
- search: searchReducer,
- review: reviewReducer,
-})
-
-function configureStore(initialState = {}, history) {
- const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
-
- const store = createStore(
- connectRouter(history)(rootReducer), // new root reducer with router state
- initialState,
- composeEnhancers(
- applyMiddleware(
- thunk,
- routerMiddleware(history)
- ),
- ),
- )
-
- return store
-}
-
-const history = createBrowserHistory()
-const store = configureStore({}, history)
-
-export { store, history }
diff --git a/client/types.js b/client/types.js
deleted file mode 100644
index e3c64691..00000000
--- a/client/types.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export const asType = (type, name) => [type, name].join('_').toUpperCase()
-export const tagAsType = (type, names) => (
- names.reduce((tags, name) => {
- tags[name] = asType(type, name)
- return tags
- }, {})
-)
-
-export const metadata = tagAsType('metadata', [
- 'loading', 'loaded', 'loaded_many', 'error', 'set_hash'
-])
-
-export const search = tagAsType('search', [
- 'loading', 'loaded', 'error', 'panic', 'update_options',
-])
-
-export const review = tagAsType('review', [
- 'loading', 'loaded', 'error', 'save', 'unsave', 'refresh', 'clear', 'dedupe', 'create', 'set_count'
-])
-
-export const init = '@@INIT'
diff --git a/client/util.js b/client/util.js
deleted file mode 100644
index ad303c64..00000000
--- a/client/util.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Mobile check */
-
-export const isiPhone = !!((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)))
-export const isiPad = !!(navigator.userAgent.match(/iPad/i))
-export const isAndroid = !!(navigator.userAgent.match(/Android/i))
-export const isMobile = isiPhone || isiPad || isAndroid
-export const isDesktop = !isMobile
-
-const htmlClassList = document.body.parentNode.classList
-htmlClassList.add(isDesktop ? 'desktop' : 'mobile')
-
-/* Default image dimensions */
-
-export const widths = {
- th: 160,
- sm: 320,
- md: 640,
- lg: 1280,
-}
-
-/* Formatting functions */
-
-const acronyms = 'id url cc sa fp md5 sha256'.split(' ').map(s => '_' + s)
-const acronymsUpperCase = acronyms.map(s => s.toUpperCase())
-
-export const formatName = s => {
- acronyms.forEach((acronym, i) => s = s.replace(acronym, acronymsUpperCase[i]))
- return s.replace(/_/g, ' ')
-}
-
-// Use to pad frame numbers with zeroes
-export const pad = (n, m) => {
- let s = String(n || 0)
- while (s.length < m) {
- s = '0' + s
- }
- return s
-}
-
-// Verified is 0/1 when retrieved from SQL, but 'verified' or 'unverified' when retrieved elsewhere
-export const isVerified = verified => verified === 1 || verified === '1' || verified === 'verified'
-export const verify = verified => isVerified(verified) ? 'verified' : 'unverified'
-
-export const courtesyS = (n, s) => n + ' ' + (n === 1 ? s : s + 's')
-
-export const padSeconds = n => n < 10 ? '0' + n : n
-
-export const timestamp = (n = 0, fps = 25) => {
- n /= fps
- let s = padSeconds(Math.round(n) % 60)
- n = Math.floor(n / 60)
- if (n > 60) {
- return Math.floor(n / 60) + ':' + padSeconds(n % 60) + ':' + s
- }
- return (n % 60) + ':' + s
-}
-
-export const percent = n => (n * 100).toFixed(1) + '%'
-
-export const px = (n, w) => Math.round(n * w) + 'px'
-
-export const clamp = (n, a, b) => n < a ? a : n < b ? n : b
-
-/* URLs */
-
-export const hashPath = sha256 => {
- if (!sha256 || sha256.length < 9) {
- throw new Error('Invalid sha256')
- }
- return [
- sha256.slice(0, 3),
- sha256.slice(3, 6),
- sha256.slice(6, 9),
- sha256,
- ].join('/')
-}
-
-export const imageUrl = (verified, sha256, frame, size = 'th') => [
- 'https://' + process.env.S3_HOST + '/v1/media/keyframes',
- isVerified(verified) ? null : 'unverified',
- hashPath(sha256),
- pad(frame, 6),
- size,
- 'index.jpg'
-].filter(s => !!s).join('/')
-
-export const metadataUri = (sha256, tag) => '/metadata/' + sha256 + '/' + tag + '/'
-export const keyframeUri = (sha256, frame) => '/metadata/' + sha256 + '/keyframe/' + pad(frame, 6) + '/'
-
-export const preloadImage = opt => {
- let { verified, hash, frame, url } = opt
- if (hash && frame) {
- url = imageUrl(verified, hash, frame, 'md')
- }
- const image = new Image()
- let loaded = false
- image.onload = () => {
- if (loaded) return
- loaded = true
- image.onload = null
- }
- // console.log(img.src)
- image.crossOrigin = 'anonymous'
- image.src = url
- if (image.complete) {
- image.onload()
- }
-}
-
-/* AJAX */
-
-let cachedAuth = null
-let token = ''
-let username = ''
-
-export const post = (uri, data, credentials) => {
- login()
- let headers
- if (data instanceof FormData) {
- headers = {
- Accept: 'application/json, application/xml, text/play, text/html, *.*',
- }
- } else {
- headers = {
- Accept: 'application/json, application/xml, text/play, text/html, *.*',
- 'Content-Type': 'application/json; charset=utf-8',
- }
- data = JSON.stringify(data)
- }
- let opt = {
- method: 'POST',
- body: data,
- headers,
- credentials: 'include',
- }
- if (credentials) {
- headers.Authorization = 'Token ' + token
- }
- // console.log(headers)
- // headers['X-CSRFToken'] = csrftoken
- return fetch(uri, opt).then(res => res.json())
-}
-
-// api queries
-export const login = () => {
- if (cachedAuth) return cachedAuth
- const isLocal = (window.location.hostname === '0.0.0.0' || window.location.hostname === '127.0.0.1')
- try {
- const auth = JSON.parse(JSON.parse(localStorage.getItem('persist:root')).auth)
- // console.log('auth', auth)
- token = auth.token
- username = auth.user.username
- if (token) {
- console.log('logged in', username)
- }
- cachedAuth = auth
- if (!token && !isLocal) {
- window.location.href = '/'
- }
- return auth
- } catch (e) {
- if (!isLocal) {
- window.location.href = '/'
- }
- return {}
- }
-}