import React, { Component } from 'react' import { Link } from 'react-router-dom' import { ReactSortable } from "react-sortablejs" import actions from 'app/actions' import { capitalize, preloadImage, simpleArraysEqual } from 'app/utils' import { DISPLAY_SIZE, DISPLAY_QUALITY, THUMBNAIL_SIZE, THUMBNAIL_QUALITY } from 'app/constants' import { TextInput, LabelDescription, FileInputField, Select, TextArea, Checkbox, SubmitButton, Loader } from 'app/common' import { renderThumbnail } from 'app/common/upload.helpers' import GalleryImageForm from './media.formGalleryImage' export default class MediaGalleryForm extends Component { state = { loading: false, edit_image_id: 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.uploadSize = this.uploadSize.bind(this) this.handleSaveItem = this.handleSaveItem.bind(this) } 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(files) { const { data } = this.props this.setState({ loading: true }) this.uploadFullsize(files) .then(() => { this.setState({ loading: false }) }) } uploadFullsize(files) { const { data } = this.props // first, upload all the fullsize files let fullsizeUploadPromises = files.map(file => { return this.uploadSize(file, 'fullsize') }) // when these are done return Promise.all(fullsizeUploadPromises).then(results => { // get the added IDs in order const added_image_order = results.map(result => result.id) // append the new IDs to the image order const new_image_order = (data.settings.image_order || []).concat(added_image_order) // add the images to the lookup const image_lookup = results.reduce((a,b) => { a[b.id] = b return a }, (data.settings.image_lookup || {})) // add these images to the settings object this.handleSettingsChange('multiple', { image_order: new_image_order, image_lookup: image_lookup, thumbnail_lookup: data.settings.thumbnail_lookup || {}, }) return this.uploadResizedFiles(files, added_image_order) }) } uploadResizedFiles(files, added_image_order) { return ( this.uploadThumbnails(files, added_image_order, 'thumbnail', THUMBNAIL_SIZE, THUMBNAIL_QUALITY) .then(() => { return this.uploadThumbnails(files, added_image_order, 'display', DISPLAY_SIZE, DISPLAY_QUALITY) }) ) } uploadThumbnails(files, added_image_order, tag, maxSide, quality) { const { data } = this.props // construct thumbnails and upload these const thumbnailUploadPromises = files.map(file => { return this.uploadThumbnail(file, tag, maxSide, quality) }) // once the thumbnails are done uploading... return Promise.all(thumbnailUploadPromises).then(thumbnail_results => { // decide which lookup we're adding to const tag_lookup_name = tag + '_lookup' const tag_lookup = data.settings[tag_lookup_name] || {} // add them to the thumbnail lookup, keyed off the ID of the fullsize image const thumbnail_lookup = thumbnail_results.reduce((a, b, i) => { const id = added_image_order[i] a[id] = b return a }, tag_lookup) // update the settings object this.handleSettingsChange('multiple', { [tag_lookup_name]: thumbnail_lookup, }) }) } uploadThumbnail(file, tag, maxSide, quality) { return new Promise((resolve, reject) => { const type = (file.name.match('.png') !== -1) ? 'image/png' : 'image/jpg' const fr = new FileReader() fr.onload = fileReaderEvent => { fr.onload = null const image = new Image() image.onload = () => { image.onload = null const thumbnailCanvas = renderThumbnail(image, { maxSide }) thumbnailCanvas.toBlob(thumbnail => { this.uploadSize(thumbnail, tag, file.name) .then(res => { resolve(res) }) .catch(err => { reject(err) }) }, type, quality) } image.src = fileReaderEvent.target.result } fr.readAsDataURL(file) }) } uploadSize(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 }) } handleOrderChanged(new_image_order) { // console.log(new_image_order) const image_order = new_image_order.map(el => el.id) if (!simpleArraysEqual(image_order, this.props.data.settings.image_order)) { console.log('order changed', image_order) this.handleSettingsChange('image_order', image_order) } } handleSaveItem(id, item) { const caption_lookup = data.settings.caption_lookup || {} caption_lookup[id] = item this.handleSettingsChange('caption_lookup', caption_lookup) this.setState({ edit_image_id: null }) } render() { const { data } = this.props const { image_order, image_lookup, thumbnail_lookup, caption_lookup } = data.settings const { loading, edit_image_id } = this.state // console.log(data) return (