summaryrefslogtreecommitdiff
path: root/animism-align/frontend/views/media
diff options
context:
space:
mode:
Diffstat (limited to 'animism-align/frontend/views/media')
-rw-r--r--animism-align/frontend/views/media/components/media.form.js272
-rw-r--r--animism-align/frontend/views/media/components/media.formImage.js172
-rw-r--r--animism-align/frontend/views/media/components/media.formImageSelection.js213
-rw-r--r--animism-align/frontend/views/media/components/media.formVideo.js111
-rw-r--r--animism-align/frontend/views/media/components/media.indexOptions.js65
-rw-r--r--animism-align/frontend/views/media/components/media.menu.js58
-rw-r--r--animism-align/frontend/views/media/containers/media.edit.js57
-rw-r--r--animism-align/frontend/views/media/containers/media.index.js115
-rw-r--r--animism-align/frontend/views/media/containers/media.new.js81
-rw-r--r--animism-align/frontend/views/media/media.actions.js9
-rw-r--r--animism-align/frontend/views/media/media.container.js38
-rw-r--r--animism-align/frontend/views/media/media.css70
-rw-r--r--animism-align/frontend/views/media/media.reducer.js22
13 files changed, 0 insertions, 1283 deletions
diff --git a/animism-align/frontend/views/media/components/media.form.js b/animism-align/frontend/views/media/components/media.form.js
deleted file mode 100644
index 1463041..0000000
--- a/animism-align/frontend/views/media/components/media.form.js
+++ /dev/null
@@ -1,272 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-
-import { session } from '../../../session'
-import { capitalize } from '../../../util'
-
-import { TextInput, LabelDescription, Select, TextArea, Checkbox, SubmitButton, Loader } from '../../../common'
-
-import MediaImageForm from './media.formImage'
-import MediaVideoForm from './media.formVideo'
-
-const newMedia = () => ({
- type: 'image',
- tag: 'media',
- url: '',
- title: '',
- author: '',
- pre_title: '',
- post_title: '',
- translated_title: '',
- date: '',
- source: '',
- medium: '',
- start_ts: 0,
- settings: {},
-})
-
-const MEDIA_TYPES = [
- 'image', 'video'
-].map(name => ({ name, label: capitalize(name) }))
-
-export default class MediaForm extends Component {
- state = {
- title: "",
- submitTitle: "",
- data: { ...newMedia() },
- errorFields: new Set([]),
- }
-
- constructor(props) {
- super(props)
- this.handleKeyDown = this.handleKeyDown.bind(this)
- this.handleSelect = this.handleSelect.bind(this)
- this.handleChange = this.handleChange.bind(this)
- this.handleSettingsChange = this.handleSettingsChange.bind(this)
- this.handleSettingsChangeEvent = this.handleSettingsChangeEvent.bind(this)
- this.handleSubmit = this.handleSubmit.bind(this)
- }
-
- componentDidMount() {
- const { data, isNew } = this.props
- const title = isNew ? 'New media' : 'Editing ' + data.title
- const submitTitle = isNew ? "Add Media" : "Save Changes"
- this.setState({
- title,
- submitTitle,
- errorFields: new Set([]),
- data: {
- ...newMedia(),
- ...data
- },
- })
- window.addEventListener('keydown', this.handleKeyDown)
- }
-
- componentWillUnmount() {
- window.removeEventListener('keydown', this.handleKeyDown)
- }
-
- handleKeyDown(e) {
- // console.log(e, e.keyCode)
- if ((e.ctrlKey || e.metaKey) && e.keyCode === 83) {
- if (e) {
- e.preventDefault()
- }
- this.handleSubmit()
- }
- }
-
- handleChange(e) {
- const { name, value } = e.target
- this.handleSelect(name, value)
- }
-
- handleSelect(name, value) {
- const { errorFields } = this.state
- if (errorFields.has(name)) {
- errorFields.delete(name)
- }
- this.setState({
- errorFields,
- data: {
- ...this.state.data,
- [name]: value,
- }
- })
- }
-
- handleSettingsChangeEvent(e) {
- const { name, value } = e.target
- this.handleSettingsChange(name, value)
- }
-
- handleSettingsChange(name, value) {
- console.log(name, value)
- if (name !== 'multiple') {
- value = { [name]: value }
- }
- this.setState({
- data: {
- ...this.state.data,
- settings: {
- ...this.state.data.settings,
- ...value,
- }
- }
- })
- }
-
- handleSubmit(e) {
- if (e) {
- e.preventDefault()
- }
- const { isNew, onSubmit } = this.props
- const { data } = this.state
- const requiredKeys = "author title date".split(" ")
- const validKeys = "type tag url title author pre_title post_title translated_title date source medium start_ts settings".split(" ")
- const validData = validKeys.reduce((a,b) => { a[b] = data[b]; return a }, {})
- const errorFields = requiredKeys.filter(key => !validData[key])
- if (errorFields.length) {
- console.log('error', errorFields, validData)
- this.setState({ errorFields: new Set(errorFields) })
- } else {
- if (isNew) {
- // side effect: set username if we're creating a new media
- // session.set('username', data.username)
- } else {
- validData.id = data.id
- }
- console.log('submit', validData)
- onSubmit(validData)
- }
- }
-
- render() {
- const { isNew } = this.props
- const { title, submitTitle, errorFields, data } = this.state
- // console.log(data)
- return (
- <div className='form'>
- <h1>{title}</h1>
- <form onSubmit={this.handleSubmit}>
- <Select
- title='Media Type'
- name='type'
- selected={data.type}
- options={MEDIA_TYPES}
- onChange={this.handleSelect}
- />
-
- {data.type === 'image' &&
- <MediaImageForm
- data={data}
- onChange={this.handleSelect}
- onSettingsChange={this.handleSettingsChange}
- />
- }
-
- {data.type === 'video' &&
- <MediaVideoForm
- data={data}
- onChange={this.handleSelect}
- onSettingsChange={this.handleSettingsChange}
- />
- }
-
- <TextInput
- title="Author"
- name="author"
- required
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
- <TextInput
- title="Title"
- name="title"
- required
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
- <TextInput
- title="Title Prefix"
- name="pre_title"
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
- <TextInput
- title="Title Suffix"
- name="post_title"
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
- <TextInput
- title="Translated Title"
- name="translated_title"
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
- <TextInput
- title="Date"
- name="date"
- required
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
- <TextInput
- title="Medium"
- name="medium"
- required
- data={data}
- onChange={this.handleChange}
- />
- <TextInput
- title="Source"
- name="source"
- placeholder="Courtesy of / Copyright"
- required
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
- <TextArea
- title="Citation"
- name="bibliography"
- placeholder="Use if special HTML formatting needed"
- data={data.settings}
- onChange={this.handleSettingsChangeEvent}
- />
- <Checkbox
- label="Hide in list of works"
- name="hide_in_bibliography"
- checked={data.settings.hide_in_bibliography}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <TextArea
- title="Description"
- name="description"
- data={data}
- onChange={this.handleChange}
- />
- <SubmitButton
- title={submitTitle}
- onClick={this.handleSubmit}
- />
- {!!errorFields.size &&
- <label>
- <span></span>
- <span>Please complete the required fields</span>
- </label>
- }
- </form>
- </div>
- )
- }
-}
diff --git a/animism-align/frontend/views/media/components/media.formImage.js b/animism-align/frontend/views/media/components/media.formImage.js
deleted file mode 100644
index 4a97112..0000000
--- a/animism-align/frontend/views/media/components/media.formImage.js
+++ /dev/null
@@ -1,172 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-
-import { session } from '../../../session'
-import actions from '../../../actions'
-import { capitalize, preloadImage, cropImage } from '../../../util'
-
-import { TextInput, LabelDescription, UploadImage, Select, TextArea, Checkbox, SubmitButton, Loader } from '../../../common'
-import { renderThumbnail } from '../../../common/upload.helpers'
-
-import ImageSelection from './media.formImageSelection'
-
-const DISPLAY_SIZE = 1024
-const DISPLAY_QUALITY= 80
-const THUMBNAIL_SIZE = 320
-const THUMBNAIL_QUALITY = 80
-
-export default class MediaImageForm extends Component {
- state = {
- img: null,
- }
-
- constructor(props) {
- super(props)
- this.handleSelect = this.handleSelect.bind(this)
- this.handleChange = this.handleChange.bind(this)
- this.handleSettingsChange = this.handleSettingsChange.bind(this)
- this.handleUpload = this.handleUpload.bind(this)
- this.handleCrop = this.handleCrop.bind(this)
- this.replaceTaggedSize = this.replaceTaggedSize.bind(this)
- this.uploadTaggedSize = this.uploadTaggedSize.bind(this)
- }
-
- componentDidMount() {
- // this.setState({ })
- if (this.props.data.settings.fullsize) {
- preloadImage(this.props.data.settings.fullsize.url)
- .then(img => this.setState({ img }))
- }
- }
-
- handleChange(e) {
- const { name, value } = e.target
- this.handleSelect(name, value)
- }
-
- handleSelect(name, value) {
- this.props.onSelect(name, value)
- }
-
- handleSettingsChange(name, value) {
- this.props.onSettingsChange(name, value)
- }
-
- handleUpload({ file, img, canvas, blob }) {
- // sizes: fullsize, display, thumbnail
- this.replaceTaggedSize(file, 'fullsize')
- .then(data => {
- this.setState({ img })
- this.props.onSettingsChange('multiple', {
- fullsize: data,
- crop: {},
- })
- return this.replaceTaggedSize(blob, 'display', file.name)
- }).then(data => {
- this.props.onSettingsChange('multiple', {
- display: data,
- })
- this.uploadThumbnail(img)
- })
- }
-
- uploadThumbnail(img) {
- const { fn } = this.props.data.settings.fullsize
- const thumbnailCanvas = renderThumbnail(img, { maxSide: THUMBNAIL_SIZE })
- thumbnailCanvas.toBlob(thumbnail => {
- this.replaceTaggedSize(thumbnail, 'thumbnail', fn).then(data => {
- this.props.onSettingsChange('multiple', {
- thumbnail: data,
- })
- })
- }, 'image/jpeg', THUMBNAIL_QUALITY)
- }
-
- replaceTaggedSize(image, tag, fn) {
- // when we upload an image, if the image already exists in this "position"
- // on the record, we should also delete it
- if (this.props.data.settings[tag] && this.props.data.settings[tag].id) {
- return new Promise((resolve, reject) => {
- actions.upload.destroy(this.props.data.settings[tag])
- .then(() => {
- console.log('destroy successful')
- this.uploadTaggedSize(image, tag, fn).then(data => resolve(data))
- })
- .catch(() => {
- console.log('error deleting the image')
- this.uploadTaggedSize(image, tag, fn).then(data => resolve(data))
- })
- })
- }
- return this.uploadTaggedSize(image, tag, fn)
- }
-
- uploadTaggedSize(image, tag, fn) {
- console.log('uploading size', tag)
- const uploadData = {
- image,
- tag,
- username: 'animism',
- }
- if (fn) {
- uploadData['__image_filename'] = fn
- }
- // console.log(uploadData)
- return actions.upload.upload(uploadData).then(data => {
- // console.log(data)
- return data.res
- })
- }
-
- handleCrop(crop) {
- // when cropping an image, re-upload the display image and thumbnail
- // console.log(crop)
- cropImage(this.state.img, crop, DISPLAY_SIZE)
- .then(canvas => {
- canvas.toBlob(blob => {
- // console.log(canvas, canvas.width, canvas.height, blob)
- this.replaceTaggedSize(blob, 'display', this.props.data.settings.fullsize.fn)
- .then(data => {
- this.props.onSettingsChange('multiple', {
- crop,
- display: data,
- })
- this.uploadThumbnail(canvas)
- })
- }, 'image/jpeg', DISPLAY_QUALITY)
- })
- }
-
- render() {
- const { data } = this.props
- // console.log(data)
- return (
- <div className='imageForm'>
- {!data.url &&
- <label className={'text fileInput'}>
- <span>{"Upload image"}</span>
- <div className="row">
- <button>
- {"Choose image"}
- </button>
- <UploadImage
- onUpload={this.handleUpload}
- maxSide={DISPLAY_SIZE}
- quality={DISPLAY_QUALITY}
- />
- </div>
- </label>
- }
- {data.settings.fullsize &&
- <div>
- <ImageSelection
- url={data.settings.fullsize.url}
- crop={data.settings.crop}
- onCrop={this.handleCrop}
- />
- </div>
- }
- </div>
- )
- }
-}
diff --git a/animism-align/frontend/views/media/components/media.formImageSelection.js b/animism-align/frontend/views/media/components/media.formImageSelection.js
deleted file mode 100644
index 5572793..0000000
--- a/animism-align/frontend/views/media/components/media.formImageSelection.js
+++ /dev/null
@@ -1,213 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-import toBlob from 'data-uri-to-blob'
-
-import { clamp } from '../../../util'
-import { Loader } from '../../../common'
-
-const defaultState = {
- dragging: false,
- draggingBox: false,
- bounds: null,
- mouseX: 0,
- mouseY: 0,
- box: {
- x: 0,
- y: 0,
- w: 0,
- h: 0,
- }
-}
-
-export default class ImageSelection extends Component {
- state = {
- ...defaultState
- }
-
- constructor() {
- super()
- // bind these events in the constructor, so we can remove event listeners later
- this.handleMouseDown = this.handleMouseDown.bind(this)
- this.handleMouseDownOnBox = this.handleMouseDownOnBox.bind(this)
- this.handleMouseMove = this.handleMouseMove.bind(this)
- this.handleMouseUp = this.handleMouseUp.bind(this)
- this.handleWindowResize = this.handleWindowResize.bind(this)
- }
-
- componentDidMount() {
- document.body.addEventListener('mousemove', this.handleMouseMove)
- document.body.addEventListener('mouseup', this.handleMouseUp)
- window.addEventListener('resize', this.handleWindowResize)
- }
-
- componentDidUpdate(prevProps) {
- if (this.state.bounds && this.props.url !== prevProps.url) {
- this.setState({
- ...defaultState,
- bounds: this.getBoundingClientRect(),
- box: this.props.crop || defaultState.box,
- })
- }
- }
-
- componentWillUnmount() {
- document.body.removeEventListener('mousemove', this.handleMouseMove)
- document.body.removeEventListener('mouseup', this.handleMouseUp)
- window.removeEventListener('resize', this.handleWindowResize)
- }
-
- getBoundingClientRect() {
- if (!this.imgRef) return null
- const rect = this.imgRef.getBoundingClientRect()
- const scrollTop = document.body.scrollTop || document.body.parentNode.scrollTop
- const scrollLeft = document.body.scrollLeft || document.body.parentNode.scrollLeft
- const bounds = {
- top: rect.top + scrollTop,
- left: rect.left + scrollLeft,
- width: rect.width,
- height: rect.height,
- }
- return bounds
- }
-
- handleLoad() {
- const bounds = this.getBoundingClientRect()
- const box = this.props.crop || defaultState.box
- this.setState({ bounds, box })
- }
-
- handleWindowResize() {
- if (!this.imgRef) return
- const bounds = this.getBoundingClientRect()
- this.setState({ bounds })
- }
-
- handleMouseDown(e) {
- e.preventDefault()
- const bounds = this.getBoundingClientRect()
- const mouseX = e.pageX
- const mouseY = e.pageY
- const x = (mouseX - bounds.left) / bounds.width
- const y = (mouseY - bounds.top) / bounds.height
- const w = 1 / bounds.width
- const h = 1 / bounds.height
- this.setState({
- dragging: true,
- bounds,
- mouseX,
- mouseY,
- box: {
- x, y, w, h,
- }
- })
- }
-
- handleMouseDownOnBox(e) {
- const bounds = this.getBoundingClientRect()
- const mouseX = e.pageX
- const mouseY = e.pageY
- this.setState({
- draggingBox: true,
- bounds,
- mouseX,
- mouseY,
- initialBox: {
- ...this.state.box
- },
- box: {
- ...this.state.box
- }
- })
- }
-
- handleMouseMove(e) {
- const {
- dragging, draggingBox,
- bounds, mouseX, mouseY, initialBox, box
- } = this.state
- if (dragging) {
- e.preventDefault()
- let { x, y } = box
- let dx = (e.pageX - mouseX) / bounds.width
- let dy = (e.pageY - mouseY) / bounds.height
- let w = clamp(dx, 0.0, 1.0 - x)
- let h = clamp(dy, 0.0, 1.0 - y)
- this.setState({
- box: {
- x, y, w, h,
- }
- })
- } else if (draggingBox) {
- e.preventDefault()
- let { x, y, w, h } = initialBox
- let dx = (e.pageX - mouseX) / bounds.width
- let dy = (e.pageY - mouseY) / bounds.height
- this.setState({
- box: {
- x: clamp(x + dx, 0, 1.0 - w),
- y: clamp(y + dy, 0, 1.0 - h),
- w,
- h,
- }
- })
- }
- }
-
- handleMouseUp(e) {
- const { onCrop } = this.props
- const { dragging, draggingBox, bounds, box } = this.state
- if (!dragging && !draggingBox) return
- e.preventDefault()
- const { x, y, w, h } = box
- let url = window.location.pathname
- this.setState({
- dragging: false,
- draggingBox: false,
- })
- if (w < 10 / bounds.width || h < 10 / bounds.height) {
- this.setState({ box: { ...defaultState.box }})
- onCrop({})
- } else {
- // pass the box dimensions up - do the search again
- onCrop(box)
- }
- }
-
- render() {
- const { url } = this.props
- const { bounds, box } = this.state
- const { x, y, w, h } = box
- return (
- <div className="imageSelection">
- <img
- src={url}
- ref={ref => this.imgRef = ref}
- onMouseDown={this.handleMouseDown}
- onLoad={this.handleLoad.bind(this)}
- crossOrigin='anonymous'
- />
- {!!w &&
- <div
- className="box"
- style={{
- left: x * bounds.width,
- top: y * bounds.height,
- width: w * bounds.width,
- height: h * bounds.height,
- }}
- onMouseDown={this.handleMouseDownOnBox}
- />
- }
- </div>
- )
- }
-}
-
-const boxToFixed = ({ x, y, w, h }) => ({
- x: x.toFixed(3),
- y: y.toFixed(3),
- w: w.toFixed(3),
- h: h.toFixed(3),
-})
diff --git a/animism-align/frontend/views/media/components/media.formVideo.js b/animism-align/frontend/views/media/components/media.formVideo.js
deleted file mode 100644
index 89954b9..0000000
--- a/animism-align/frontend/views/media/components/media.formVideo.js
+++ /dev/null
@@ -1,111 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import VimeoPlayer from '@u-wave/react-vimeo'
-
-import { capitalize } from '../../../util'
-import { TextInput, LabelDescription, Select, TextArea, Checkbox, SubmitButton, Loader } from '../../../common'
-
-import { getVimeoMetadata } from '../media.actions'
-
-export default class MediaVideoForm extends Component {
- state = {
- }
-
- constructor(props) {
- super(props)
- this.handleSelect = this.handleSelect.bind(this)
- this.handleChange = this.handleChange.bind(this)
- this.handleSettingsChange = this.handleSettingsChange.bind(this)
- }
-
- handleChange(e) {
- let { name, value } = e.target
- return this.handleSelect(name, value)
- }
-
- handleSelect(name, value) {
- value = value.trim()
- if (name === 'url') {
- getVimeoMetadata(value)
- .then(data => {
- console.log('video metadata', data)
- this.props.onChange(name, value)
- setTimeout(() => {
- this.props.onSettingsChange('video', {
- thumbnail_url: data.thumbnail_url,
- duration: data.duration,
- video_id: data.video_id,
- })
- }, 20)
- })
- } else {
- this.props.onChange(name, value)
- }
- }
-
- handleSettingsChange(e) {
- let { name, value } = e.target
- this.props.onSettingsChange(name, value)
- }
-
- handleSettingsSelect(name, value) {
- this.props.onSettingsChange(name, value)
- }
-
- render() {
- const { data } = this.props
- return (
- <div className='videoForm'>
- <TextInput
- title="Video URL"
- name="url"
- required
- data={data}
- onChange={this.handleChange}
- autoComplete="off"
- />
-
- {data.url &&
- <div>
- <LabelDescription className='video'>
- <VimeoPlayer video={data.url} />
- </LabelDescription>
-
- {data.settings.video && data.settings.video.thumbnail &&
- <LabelDescription className='thumbnail'>
- <img src={data.settings.video.thumbnail} />
- </LabelDescription>
- }
-
- <TextInput
- title="Start time"
- name="video_start_time"
- data={data.settings}
- placeholder="0:00"
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
-
- <TextInput
- title="End time"
- name="video_end_time"
- data={data.settings}
- placeholder="0:00"
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
-
- <TextInput
- title="Original duration"
- name="original_duration"
- data={data.settings}
- placeholder="0:00"
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- }
- </div>
- )
- }
-}
diff --git a/animism-align/frontend/views/media/components/media.indexOptions.js b/animism-align/frontend/views/media/components/media.indexOptions.js
deleted file mode 100644
index 5dbc415..0000000
--- a/animism-align/frontend/views/media/components/media.indexOptions.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-
-import actions from '../../../actions'
-
-import { Select, Checkbox } from '../../../common'
-
-const thumbnailOptions = [
- { name: 'th', label: 'Thumbnails', },
- { name: 'sm', label: 'Small', },
- { name: 'md', label: 'Medium', },
- { name: 'lg', label: 'Large', },
- { name: 'orig', label: 'Original', },
-]
-
-const sortOptions = [
- { name: 'id-asc', label: 'Most recent' },
- { name: 'id-desc', label: 'Oldest first' },
- { name: 'username-asc', label: 'Username (A-Z)' },
- { name: 'username-desc', label: 'Username (Z-A)' },
- { name: 'author-asc', label: 'Author (A-Z)' },
- { name: 'author-desc', label: 'Author (Z-A)' },
- { name: 'title-asc', label: 'Title (A-Z)' },
- { name: 'title-desc', label: 'Title (Z-A)' },
- // { name: '-asc', label: '' },
- // { name: '-desc', label: '' },
- // { name: '-asc', label: '' },
- // { name: '-desc', label: '' },
- // { name: '-asc', label: '' },
- // { name: '-desc', label: '' },
-]
-
-class IndexOptions extends Component {
- render() {
- const { options } = this.props
- return (
- <div className='row menubar'>
- <div />
- <Select
- name={'sort'}
- options={sortOptions}
- selected={options.sort}
- onChange={actions.upload.updateOption}
- />
- <Select
- name={'thumbnailSize'}
- options={thumbnailOptions}
- selected={options.thumbnailSize}
- onChange={actions.upload.updateOption}
- />
- </div>
- )
- }
-}
-
-const mapStateToProps = state => ({
- options: state.upload.options,
-})
-
-const mapDispatchToProps = dispatch => ({
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(IndexOptions)
diff --git a/animism-align/frontend/views/media/components/media.menu.js b/animism-align/frontend/views/media/components/media.menu.js
deleted file mode 100644
index 153a5c1..0000000
--- a/animism-align/frontend/views/media/components/media.menu.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import React, { Component } from 'react'
-import { Route, Link } from 'react-router-dom'
-import { connect } from 'react-redux'
-
-import { history } from '../../../store'
-import actions from '../../../actions'
-import { MenuButton, FileInput } from '../../../common'
-
-const mapStateToProps = state => ({
- media: state.media,
-})
-
-export default class MediaMenu extends Component {
- render() {
- return (
- <div className='menuButtons'>
- <Route exact path='/media/:id/show/' component={MediaShowMenu} />
- <Route exact path='/media/:id/edit/' component={MediaEditMenu} />
- <Route exact path='/media/new/' component={MediaNewMenu} />
- <Route exact path='/media/' component={MediaIndexMenu} />
- </div>
- )
- }
-}
-
-const MediaIndexMenu = () => ([
- <MenuButton key='new' name="new" href="/media/new/" />,
-])
-
-const MediaShowMenu = connect(mapStateToProps)((props) => ([
- <MenuButton key='back' name="back" href="/media/" />,
- <MenuButton key='edit' name="edit" href={"/media/" + props.match.params.id + "/edit/"} />,
- <MenuButton key='delete' name="delete" onClick={() => {
- const { res: media } = props.media.show
- if (confirm("Really delete this media?")) {
- actions.media.destroy(media).then(() => {
- history.push('/media/')
- })
- }
- }} />,
-]))
-
-const MediaNewMenu = (props) => ([
- <MenuButton key='back' name="back" href="/media/" />,
-])
-
-const MediaEditMenu = connect(mapStateToProps)((props) => ([
- <MenuButton key='back' name="back" href="/media/" />,
- <MenuButton key='copy' name="copy" href={"/media/" + props.match.params.id + '/copy/'} label="Make a copy" />,
- <MenuButton key='delete' name="delete" onClick={() => {
- const { res: media } = props.media.show
- if (confirm("Really delete this media?")) {
- actions.media.destroy(media).then(() => {
- history.push('/media/')
- })
- }
- }} />,
-]))
diff --git a/animism-align/frontend/views/media/containers/media.edit.js b/animism-align/frontend/views/media/containers/media.edit.js
deleted file mode 100644
index 143cdfe..0000000
--- a/animism-align/frontend/views/media/containers/media.edit.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { connect } from 'react-redux'
-
-import { history } from '../../../store'
-import actions from '../../../actions'
-
-import { Loader } from '../../../common'
-
-import MediaForm from '../components/media.form'
-import MediaMenu from '../components/media.menu'
-
-class MediaEdit extends Component {
- componentDidMount() {
- console.log(this.props.match.params.id)
- actions.media.show(this.props.match.params.id)
- }
-
- handleSubmit(data) {
- actions.media.update(data)
- .then(response => {
- // response
- console.log(response)
- history.push('/media/')
- })
- }
-
- render() {
- const { show } = this.props.media
- if (show.loading || !show.res) {
- return (
- <div className='form'>
- <Loader />
- </div>
- )
- }
- return (
- <div className='row formContainer'>
- <MediaMenu mediaActions={this.props.mediaActions} />
- <MediaForm
- data={show.res}
- onSubmit={this.handleSubmit.bind(this)}
- />
- </div>
- )
- }
-}
-
-const mapStateToProps = state => ({
- media: state.media,
-})
-
-const mapDispatchToProps = dispatch => ({
- // mediaActions: bindActionCreators({ ...mediaActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(MediaEdit)
diff --git a/animism-align/frontend/views/media/containers/media.index.js b/animism-align/frontend/views/media/containers/media.index.js
deleted file mode 100644
index a865522..0000000
--- a/animism-align/frontend/views/media/containers/media.index.js
+++ /dev/null
@@ -1,115 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-
-import { formatDateTime } from '../../../util'
-import { MenuButton, SmallMenuButton, Loader } from '../../../common'
-import actions from '../../../actions'
-
-import { thumbnailURL } from '../../align/align.util'
-
-import MediaIndexOptions from '../components/media.indexOptions'
-import MediaMenu from '../components/media.menu'
-
-// const { result, collectionLookup } = this.props
-
-class MediaIndex extends Component {
- componentDidMount() {
- // this.fetch(false)
- }
-
- componentDidUpdate(prevProps) {
- if (this.props.media.options.sort !== prevProps.media.options.sort) {
- this.fetch(false)
- }
- }
-
- fetch(load_more) {
- const { options, index } = this.props.media
- const { order: index_order } = index
- const [ sort, order ] = options.sort.split(' ')
- actions.media.index({
- sort, order, limit: 5000, // offset: load_more ? index_order.length : 0,
- }, load_more)
- }
-
- render() {
- const { mediaActions } = this.props
- const { options } = this.props.media
- const { loading, lookup, order } = this.props.media.index
- if (loading) {
- return (
- <section>
- <MediaIndexOptions />
- <div className="row">
- {order && !!order.length &&
- <div className={'results ' + options.thumbnailSize}>
- {order.map(id => <MediaItem key={id} data={lookup[id]} />)}
- </div>
- }
- </div>
- <Loader />
- </section>
- )
- }
- if (!lookup || !order.length) {
- return (
- <section>
- <MediaIndexOptions />
- <div className="row">
- <MediaMenu />
- <p className='gray'>
- {"No media"}
- </p>
- </div>
- </section>
- )
- }
- return (
- <section>
- <MediaIndexOptions />
- <div className="row">
- <MediaMenu />
- <div className={'results ' + options.thumbnailSize}>
- <h2>Images</h2>
- {order.filter(id => lookup[id].type === 'image').map(id => <MediaItem key={id} data={lookup[id]} />)}
- <h2>Video</h2>
- {order.filter(id => lookup[id].type === 'video').map(id => <MediaItem key={id} data={lookup[id]} />)}
- </div>
- </div>
- {order.length >= 50 && <button className='loadMore' onClick={() => this.fetch(true)}>Load More</button>}
- </section>
- )
- }
-}
-
-const MediaItem = ({ data }) => {
- // console.log(data)
- return (
- <div className='cell'>
- <div className='img'>
- <Link to={"/media/" + data.id + "/edit/"}>
- <img src={thumbnailURL(data)} alt={data.title} />
- </Link>
- </div>
- <div className='meta center'>
- <div>
- <i>{data.title}</i><br />
- {data.author}<br />
- {data.date}
- </div>
- </div>
- </div>
- )
-}
-
-const mapStateToProps = state => ({
- media: state.media,
-})
-
-const mapDispatchToProps = dispatch => ({
- // uploadActions: bindActionCreators({ ...uploadActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(MediaIndex)
diff --git a/animism-align/frontend/views/media/containers/media.new.js b/animism-align/frontend/views/media/containers/media.new.js
deleted file mode 100644
index 80879cb..0000000
--- a/animism-align/frontend/views/media/containers/media.new.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { connect } from 'react-redux'
-
-import { history } from '../../../store'
-import actions from '../../../actions'
-
-import MediaForm from '../components/media.form'
-import MediaMenu from '../components/media.menu'
-
-class MediaNew extends Component {
- state = {
- loading: true,
- initialData: {},
- }
-
- componentDidMount() {
- // console.log(this.props.match.params.id)
- if (this.props.match.params && this.props.match.params.id) {
- actions.media.show(this.props.match.params.id)
- .then(data => {
- const { id, ...initialData } = data.res
- delete initialData.settings.video
- delete initialData.settings.crop
- delete initialData.settings.display
- delete initialData.settings.fullsize
- delete initialData.settings.thumbnail
- delete initialData.settings.bibliography
- console.log("copying", id)
- this.setState({
- loading: false,
- initialData,
- })
- })
- } else {
- this.setState({ loading: false })
- }
- }
-
- handleSubmit(data) {
- console.log(data)
- actions.media.create(data)
- .then(res => {
- console.log(res)
- if (res.res && res.res.id) {
- history.push('/media/')
- }
- })
- .catch(err => {
- console.error('error')
- })
- }
-
- render() {
- if (this.state.loading) {
- return (
- <div className='row formContainer' />
- )
- }
- return (
- <div className='row formContainer'>
- <MediaMenu />
- <MediaForm
- isNew
- data={this.state.initialData}
- onSubmit={this.handleSubmit.bind(this)}
- />
- </div>
- )
- }
-}
-
-const mapStateToProps = state => ({
- media: state.media,
-})
-
-const mapDispatchToProps = dispatch => ({
- // uploadActions: bindActionCreators({ ...uploadActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(MediaNew)
diff --git a/animism-align/frontend/views/media/media.actions.js b/animism-align/frontend/views/media/media.actions.js
deleted file mode 100644
index 1f1ab01..0000000
--- a/animism-align/frontend/views/media/media.actions.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as types from '../../types'
-import { capitalize, api } from '../../util'
-
-export const getVimeoMetadata = url => {
- return api(() => {}, types.vimeo, 'vimeo', 'https://vimeo.com/api/oembed.json', { url })
- .then(data => {
- return data
- })
-}
diff --git a/animism-align/frontend/views/media/media.container.js b/animism-align/frontend/views/media/media.container.js
deleted file mode 100644
index 97a5b08..0000000
--- a/animism-align/frontend/views/media/media.container.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import React, { Component } from 'react'
-import { Route, Link } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-
-import './media.css'
-
-import actions from '../../actions'
-
-import MediaIndex from './containers/media.index'
-// import MediaShow from './containers/media.show'
-import MediaNew from './containers/media.new'
-import MediaEdit from './containers/media.edit'
-
-class Container extends Component {
- render() {
- return (
- <div className='media'>
- <Route exact path='/media/:id/copy/' component={MediaNew} />
- <Route exact path='/media/:id/edit/' component={MediaEdit} />
- <Route exact path='/media/new/' component={MediaNew} />
- <Route exact path='/media/' component={MediaIndex} />
- </div>
- )
- }
-}
-/*
- <Route exact path='/media/:id/show/' component={MediaShow} />
-*/
-const mapStateToProps = state => ({
- media: state.media,
-})
-
-const mapDispatchToProps = dispatch => ({
- // uploadActions: bindActionCreators({ ...uploadActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(Container)
diff --git a/animism-align/frontend/views/media/media.css b/animism-align/frontend/views/media/media.css
deleted file mode 100644
index a2d95c8..0000000
--- a/animism-align/frontend/views/media/media.css
+++ /dev/null
@@ -1,70 +0,0 @@
-.app > .media {
- width: 100%;
- height: calc(100% - 3.125rem);
- overflow: scroll;
-}
-
-.results .cell {
- margin-bottom: 1rem;
- margin-right: 1rem;
-}
-.results h2 {
- display: block;
- width: 100%;
-}
-.media .results .meta > div {
- max-width: 100%;
-}
-
-/* new / edit media forms */
-
-.formContainer {
- padding-top: 1rem;
-}
-
-.imageForm,
-.videoForm {
- padding: 1rem 1rem 0.5rem 1rem;
- margin: 1rem 0;
- position: relative;
- left: -1rem;
- border-radius: 10px;
-}
-
-/* image form */
-
-.imageForm {
- background: #315;
-}
-.imageForm .fileInput .row {
- position: relative;
-}
-
-/* video form */
-
-.videoForm {
- background: #314;
-}
-.videoForm .thumbnail img {
- max-height: 200px;
-}
-
-/* image crop */
-
-.imageSelection {
- width: 30rem;
- position: relative;
-}
-.imageSelection img {
- display: block;
- max-width: 100%;
- max-height: 20rem;
-}
-.imageSelection img.loading {
- opacity: 0.5;
-}
-.imageSelection .box {
- position: absolute;
- background: rgba(255,32,64,0.05);
- border: 1px solid #f24;
-}
diff --git a/animism-align/frontend/views/media/media.reducer.js b/animism-align/frontend/views/media/media.reducer.js
deleted file mode 100644
index cb9b91d..0000000
--- a/animism-align/frontend/views/media/media.reducer.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import * as types from '../../types'
-import { session, getDefault, getDefaultInt } from '../../session'
-
-import { crudState, crudReducer } from '../../api/crud.reducer'
-
-const initialState = crudState('media', {
- options: {
- sort: 'author asc',
- thumbnailSize: getDefault('upload.thumbnailSize', 'small'),
- }
-})
-
-const reducer = crudReducer('media')
-
-export default function mediaReducer(state = initialState, action) {
- // console.log(action.type, action)
- state = reducer(state, action)
- switch (action.type) {
- default:
- return state
- }
-}