Refactor on upload media data fow

This commit is contained in:
Cássio Zen 2016-06-10 14:01:14 -03:00
parent 1ba98fdb5a
commit 1700f98e4e
8 changed files with 47 additions and 40 deletions

View File

@ -1,5 +1,10 @@
export const ADD_MEDIA = 'ADD_MEDIA'; export const ADD_MEDIA = 'ADD_MEDIA';
export const REMOVE_MEDIA = 'REMOVE_MEDIA';
export function addMedia(file) { export function addMedia(mediaProxy) {
return { type: ADD_MEDIA, payload: file }; return {type: ADD_MEDIA, payload: mediaProxy};
}
export function removeMedia(uri) {
return {type: REMOVE_MEDIA, payload: uri};
} }

View File

@ -3,7 +3,7 @@ import Widgets from './Widgets';
export default class ControlPane extends React.Component { export default class ControlPane extends React.Component {
controlFor(field) { controlFor(field) {
const { entry, getMedia, onChange, onAddMedia } = this.props; const { entry, getMedia, onChange, onAddMedia, onRemoveMedia } = this.props;
const widget = Widgets[field.get('widget')] || Widgets._unknown; const widget = Widgets[field.get('widget')] || Widgets._unknown;
return React.createElement(widget.Control, { return React.createElement(widget.Control, {
key: field.get('name'), key: field.get('name'),
@ -11,6 +11,7 @@ export default class ControlPane extends React.Component {
value: entry.getIn(['data', field.get('name')]), value: entry.getIn(['data', field.get('name')]),
onChange: (value) => onChange(entry.setIn(['data', field.get('name')], value)), onChange: (value) => onChange(entry.setIn(['data', field.get('name')], value)),
onAddMedia: onAddMedia, onAddMedia: onAddMedia,
onRemoveMedia: onRemoveMedia,
getMedia: getMedia getMedia: getMedia
}); });
} }

View File

@ -5,7 +5,7 @@ import PreviewPane from './PreviewPane';
export default class EntryEditor extends React.Component { export default class EntryEditor extends React.Component {
render() { render() {
const { collection, entry, getMedia, onChange, onAddMedia, onPersist } = this.props; const { collection, entry, getMedia, onChange, onAddMedia, onRemoveMedia, onPersist } = this.props;
return <div> return <div>
<h1>Entry in {collection.get('label')}</h1> <h1>Entry in {collection.get('label')}</h1>
<h2>{entry && entry.get('title')}</h2> <h2>{entry && entry.get('title')}</h2>
@ -17,6 +17,7 @@ export default class EntryEditor extends React.Component {
getMedia={getMedia} getMedia={getMedia}
onChange={onChange} onChange={onChange}
onAddMedia={onAddMedia} onAddMedia={onAddMedia}
onRemoveMedia={onRemoveMedia}
/> />
</div> </div>
<div className="cms-preview-pane" style={styles.pane}> <div className="cms-preview-pane" style={styles.pane}>

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { truncateMiddle } from '../../lib/textHelper'; import { truncateMiddle } from '../../lib/textHelper';
import MediaProxy from '../../valueObjects/MediaProxy';
const MAX_DISPLAY_LENGTH = 50; const MAX_DISPLAY_LENGTH = 50;
@ -7,11 +8,6 @@ export default class ImageControl extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = {
currentImage: props.value
};
this.revokeCurrentImage = this.revokeCurrentImage.bind(this);
this.handleChange = this.handleChange.bind(this); this.handleChange = this.handleChange.bind(this);
this.handleFileInputRef = this.handleFileInputRef.bind(this); this.handleFileInputRef = this.handleFileInputRef.bind(this);
this.handleClick = this.handleClick.bind(this); this.handleClick = this.handleClick.bind(this);
@ -20,12 +16,6 @@ export default class ImageControl extends React.Component {
this.renderImageName = this.renderImageName.bind(this); this.renderImageName = this.renderImageName.bind(this);
} }
revokeCurrentImage() {
if (this.state.currentImage) {
//this.props.onRemoveMedia(this.state.currentImage);
}
}
handleFileInputRef(el) { handleFileInputRef(el) {
this._fileInput = el; this._fileInput = el;
} }
@ -47,7 +37,7 @@ export default class ImageControl extends React.Component {
handleChange(e) { handleChange(e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
this.revokeCurrentImage();
const fileList = e.dataTransfer ? e.dataTransfer.files : e.target.files; const fileList = e.dataTransfer ? e.dataTransfer.files : e.target.files;
const files = [...fileList]; const files = [...fileList];
const imageType = /^image\//; const imageType = /^image\//;
@ -59,21 +49,25 @@ export default class ImageControl extends React.Component {
} }
}); });
this.props.onRemoveMedia(this.props.value);
if (file) { if (file) {
this.props.onAddMedia(file); const mediaProxy = new MediaProxy(file.name, file);
this.props.onChange(file.name); this.props.onAddMedia(mediaProxy);
this.setState({currentImage: file.name}); this.props.onChange(mediaProxy.uri);
} else { } else {
this.props.onChange(null); this.props.onChange(null);
this.setState({currentImage: null});
} }
} }
renderImageName() { renderImageName() {
if (!this.props.value) return null;
if (this.value instanceof MediaProxy) {
return truncateMiddle(this.props.value.uri, MAX_DISPLAY_LENGTH);
} else {
return truncateMiddle(this.props.value, MAX_DISPLAY_LENGTH);
}
if (!this.state.currentImage) return null;
return truncateMiddle(this.props.getMedia(this.state.currentImage).uri, MAX_DISPLAY_LENGTH);
} }
render() { render() {

View File

@ -7,7 +7,7 @@ import {
changeDraft, changeDraft,
persist persist
} from '../actions/entries'; } from '../actions/entries';
import { addMedia } from '../actions/media'; import { addMedia, removeMedia } from '../actions/media';
import { selectEntry, getMedia } from '../reducers'; import { selectEntry, getMedia } from '../reducers';
import EntryEditor from '../components/EntryEditor'; import EntryEditor from '../components/EntryEditor';
@ -40,7 +40,7 @@ class EntryPage extends React.Component {
render() { render() {
const { const {
entry, entryDraft, boundGetMedia, collection, handleDraftChange, handleAddMedia, handleDraftRemoveMedia entry, entryDraft, boundGetMedia, collection, changeDraft, addMedia, removeMedia
} = this.props; } = this.props;
if (entry == null || entryDraft.get('entry') == undefined || entry.get('isFetching')) { if (entry == null || entryDraft.get('entry') == undefined || entry.get('isFetching')) {
@ -51,8 +51,9 @@ class EntryPage extends React.Component {
entry={entryDraft.get('entry')} entry={entryDraft.get('entry')}
getMedia={boundGetMedia} getMedia={boundGetMedia}
collection={collection} collection={collection}
onChange={handleDraftChange} onChange={changeDraft}
onAddMedia={handleAddMedia} onAddMedia={addMedia}
onRemoveMedia={removeMedia}
onPersist={this.handlePersist} onPersist={this.handlePersist}
/> />
); );
@ -71,8 +72,9 @@ function mapStateToProps(state, ownProps) {
export default connect( export default connect(
mapStateToProps, mapStateToProps,
{ {
handleDraftChange: changeDraft, changeDraft,
handleAddMedia: addMedia, addMedia,
removeMedia,
loadEntry, loadEntry,
createDraft, createDraft,
discardDraft, discardDraft,

View File

@ -1,6 +1,6 @@
import { Map, List } from 'immutable'; import { Map, List } from 'immutable';
import { DRAFT_CREATE, DRAFT_DISCARD, DRAFT_CHANGE } from '../actions/entries'; import { DRAFT_CREATE, DRAFT_DISCARD, DRAFT_CHANGE } from '../actions/entries';
import { ADD_MEDIA } from '../actions/media'; import { ADD_MEDIA, REMOVE_MEDIA } from '../actions/media';
const initialState = Map({entry: Map(), mediaFiles: List()}); const initialState = Map({entry: Map(), mediaFiles: List()});
@ -22,7 +22,9 @@ const entryDraft = (state = Map(), action) => {
return state.set('entry', action.payload); return state.set('entry', action.payload);
case ADD_MEDIA: case ADD_MEDIA:
return state.update('mediaFiles', (list) => list.push(action.payload.name)); return state.update('mediaFiles', (list) => list.push(action.payload.uri));
case REMOVE_MEDIA:
return state.update('mediaFiles', (list) => list.filterNot((uri) => uri === action.payload));
default: default:
return state; return state;

View File

@ -1,11 +1,13 @@
import { Map } from 'immutable'; import { Map } from 'immutable';
import { ADD_MEDIA } from '../actions/media'; import { ADD_MEDIA, REMOVE_MEDIA } from '../actions/media';
import MediaProxy from '../valueObjects/MediaProxy'; import MediaProxy from '../valueObjects/MediaProxy';
const medias = (state = Map(), action) => { const medias = (state = Map(), action) => {
switch (action.type) { switch (action.type) {
case ADD_MEDIA: case ADD_MEDIA:
return state.set(action.payload.name, action.payload); return state.set(action.payload.uri, action.payload);
case REMOVE_MEDIA:
return state.delete(action.payload);
default: default:
return state; return state;
} }
@ -13,11 +15,10 @@ const medias = (state = Map(), action) => {
export default medias; export default medias;
export const getMedia = (state, filePath) => { export const getMedia = (state, uri) => {
const fileName = filePath.substring(filePath.lastIndexOf('/') + 1); if (state.has(uri)) {
if (state.has(fileName)) { return state.get(uri);
return new MediaProxy(fileName, window.URL.createObjectURL(state.get(fileName), {oneTimeOnly: true}));
} else { } else {
return new MediaProxy(filePath, null, filePath, true); return new MediaProxy(uri, null, true);
} }
}; };

View File

@ -3,11 +3,12 @@ export const setConfig = (configObj) => {
config = configObj; config = configObj;
}; };
export default function MediaProxy(value, objectURL, uri, uploaded = false) { export default function MediaProxy(value, file, uploaded = false) {
this.value = value; this.value = value;
this.file = file;
this.uploaded = uploaded; this.uploaded = uploaded;
this.uri = uri || config.media_folder && config.media_folder + '/' + value; this.uri = config.media_folder && !uploaded ? config.media_folder + '/' + value : value;
this.toString = function() { this.toString = function() {
return uploaded ? this.uri : objectURL; return uploaded ? this.uri : window.URL.createObjectURL(this.file, {oneTimeOnly: true});
}; };
} }