diff --git a/client/modules/IDE/actions/files.js b/client/modules/IDE/actions/files.js index 32e67835..d9bb8e9f 100644 --- a/client/modules/IDE/actions/files.js +++ b/client/modules/IDE/actions/files.js @@ -104,7 +104,8 @@ export function createFile(formProps) { type: ActionTypes.CREATE_FILE, name: createUniqueName(formProps.name, state.files), id: `${maxFileId + 1}`, - url: formProps.url + url: formProps.url, + content: formProps.content || '' }); dispatch({ type: ActionTypes.HIDE_MODAL diff --git a/client/modules/IDE/actions/uploader.js b/client/modules/IDE/actions/uploader.js index c8a44d3f..ee305990 100644 --- a/client/modules/IDE/actions/uploader.js +++ b/client/modules/IDE/actions/uploader.js @@ -4,62 +4,111 @@ import { createFile } from './files'; const s3Bucket = `http://${process.env.S3_BUCKET}.s3.amazonaws.com/`; const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api'; +function localIntercept(file, options = {}) { + return new Promise((resolve, reject) => { + if (!options.readType) { + // const mime = file.type; + // const textType = a(_textTypes).any(type => { + // const re = new RegExp(type); + // return re.test(mime); + // }); + // options.readType = textType ? 'readAsText' : 'readAsDataURL'; + options.readType = 'readAsText'; // eslint-disable-line + } + const reader = new window.FileReader(); + reader.onload = () => { + resolve(reader.result); + }; + reader.onerror = () => { + reject(reader.result); + }; + + // run the reader + reader[options.readType](file); + }); +} + export function dropzoneAcceptCallback(file, done) { return () => { - file.postData = []; // eslint-disable-line - axios.post(`${ROOT_URL}/S3/sign`, { - name: file.name, - type: file.type, - size: file.size, - // _csrf: document.getElementById('__createPostToken').value - }, - { - withCredentials: true + // for text files and small files + // check mime type + // if text, local interceptor + if (file.type.match(/text\//)) { + localIntercept(file).then(result => { + file.content = result; // eslint-disable-line + done(); }) - .then(response => { - file.custom_status = 'ready'; // eslint-disable-line - file.postData = response.data; // eslint-disable-line - file.s3 = response.data.key; // eslint-disable-line - file.previewTemplate.className += ' uploading'; // eslint-disable-line - done(); - }) - .catch(response => { - file.custom_status = 'rejected'; // eslint-disable-line - if (response.data.responseText && response.data.responseText.message) { - done(response.data.responseText.message); - } - done('error preparing the upload'); - }); + .catch(result => { + done(`Failed to download file ${file.name}: ${result}`); + console.warn(file); + }); + } else { + file.postData = []; // eslint-disable-line + axios.post(`${ROOT_URL}/S3/sign`, { + name: file.name, + type: file.type, + size: file.size, + // _csrf: document.getElementById('__createPostToken').value + }, + { + withCredentials: true + }) + .then(response => { + file.custom_status = 'ready'; // eslint-disable-line + file.postData = response.data; // eslint-disable-line + file.s3 = response.data.key; // eslint-disable-line + file.previewTemplate.className += ' uploading'; // eslint-disable-line + done(); + }) + .catch(response => { + file.custom_status = 'rejected'; // eslint-disable-line + if (response.data.responseText && response.data.responseText.message) { + done(response.data.responseText.message); + } + done('error preparing the upload'); + }); + } }; } export function dropzoneSendingCallback(file, xhr, formData) { return () => { - Object.keys(file.postData).forEach(key => { - formData.append(key, file.postData[key]); - }); - formData.append('Content-type', ''); - formData.append('Content-length', ''); - formData.append('acl', 'public-read'); + if (!file.type.match(/text\//)) { + Object.keys(file.postData).forEach(key => { + formData.append(key, file.postData[key]); + }); + formData.append('Content-type', ''); + formData.append('Content-length', ''); + formData.append('acl', 'public-read'); + } }; } export function dropzoneCompleteCallback(file) { return (dispatch, getState) => { // eslint-disable-line - let inputHidden = '`; - // document.getElementById('uploader').appendChild(inputHidden); - document.getElementById('uploader').innerHTML += inputHidden; + if (!file.type.match(/text\//)) { + let inputHidden = '`; + // document.getElementById('uploader').appendChild(inputHidden); + document.getElementById('uploader').innerHTML += inputHidden; - const formParams = { - name: file.name, - url: `${s3Bucket}${file.postData.key}` - }; - createFile(formParams)(dispatch, getState); + const formParams = { + name: file.name, + url: `${s3Bucket}${file.postData.key}` + }; + createFile(formParams)(dispatch, getState); + } else { + const formParams = { + name: file.name, + content: file.content + }; + console.log(formParams); + createFile(formParams)(dispatch, getState); + } }; } diff --git a/client/modules/IDE/components/FileUploader.js b/client/modules/IDE/components/FileUploader.js index 817dd4ee..a034715d 100644 --- a/client/modules/IDE/components/FileUploader.js +++ b/client/modules/IDE/components/FileUploader.js @@ -23,7 +23,8 @@ class FileUploader extends React.Component { maxThumbnailFilesize: 8, // 3MB thumbnailWidth: 200, thumbnailHeight: 200, - acceptedFiles: 'image/bmp,image/gif,image/jpg,image/jpeg,image/png,audio/*', + // TODO what is a good list of MIME types???? + acceptedFiles: 'image/*,audio/*,text/javascript,text/html,text/css', dictDefaultMessage: 'Drop files here to upload or click to use the file browser', accept: this.props.dropzoneAcceptCallback, sending: this.props.dropzoneSendingCallback, diff --git a/client/modules/IDE/reducers/files.js b/client/modules/IDE/reducers/files.js index 150bda18..ff1a5a16 100644 --- a/client/modules/IDE/reducers/files.js +++ b/client/modules/IDE/reducers/files.js @@ -74,7 +74,7 @@ const files = (state = initialState, action) => { case ActionTypes.RESET_PROJECT: return initialState; case ActionTypes.CREATE_FILE: - return [...state, { name: action.name, id: action.id, content: '', url: action.url }]; + return [...state, { name: action.name, id: action.id, content: action.content, url: action.url }]; case ActionTypes.SHOW_FILE_OPTIONS: return state.map(file => { if (file.id !== action.id) {