Merge branch 'upstream' into editor-accessibility-unique-key-warning
This commit is contained in:
commit
c245a6a21e
7 changed files with 113 additions and 54 deletions
|
@ -71,7 +71,8 @@ export function createFile(formProps) {
|
||||||
if (state.project.id) {
|
if (state.project.id) {
|
||||||
const postParams = {
|
const postParams = {
|
||||||
name: createUniqueName(formProps.name, state.files),
|
name: createUniqueName(formProps.name, state.files),
|
||||||
url: formProps.url
|
url: formProps.url,
|
||||||
|
content: formProps.content || ''
|
||||||
};
|
};
|
||||||
axios.post(`${ROOT_URL}/projects/${state.project.id}/files`, postParams, { withCredentials: true })
|
axios.post(`${ROOT_URL}/projects/${state.project.id}/files`, postParams, { withCredentials: true })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
@ -104,7 +105,8 @@ export function createFile(formProps) {
|
||||||
type: ActionTypes.CREATE_FILE,
|
type: ActionTypes.CREATE_FILE,
|
||||||
name: createUniqueName(formProps.name, state.files),
|
name: createUniqueName(formProps.name, state.files),
|
||||||
id: `${maxFileId + 1}`,
|
id: `${maxFileId + 1}`,
|
||||||
url: formProps.url
|
url: formProps.url,
|
||||||
|
content: formProps.content || ''
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ActionTypes.HIDE_MODAL
|
type: ActionTypes.HIDE_MODAL
|
||||||
|
|
|
@ -1,65 +1,116 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { createFile } from './files';
|
import { createFile } from './files';
|
||||||
|
const textFileRegex = /text\//;
|
||||||
|
|
||||||
const s3Bucket = `http://${process.env.S3_BUCKET}.s3.amazonaws.com/`;
|
const s3Bucket = `http://${process.env.S3_BUCKET}.s3.amazonaws.com/`;
|
||||||
const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api';
|
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) {
|
export function dropzoneAcceptCallback(file, done) {
|
||||||
return () => {
|
return () => {
|
||||||
file.postData = []; // eslint-disable-line
|
// for text files and small files
|
||||||
axios.post(`${ROOT_URL}/S3/sign`, {
|
// check mime type
|
||||||
name: file.name,
|
// if text, local interceptor
|
||||||
type: file.type,
|
console.log(file.type);
|
||||||
size: file.size,
|
if (file.type.match(textFileRegex)) {
|
||||||
// _csrf: document.getElementById('__createPostToken').value
|
localIntercept(file).then(result => {
|
||||||
},
|
file.content = result; // eslint-disable-line
|
||||||
{
|
done();
|
||||||
withCredentials: true
|
|
||||||
})
|
})
|
||||||
.then(response => {
|
.catch(result => {
|
||||||
file.custom_status = 'ready'; // eslint-disable-line
|
done(`Failed to download file ${file.name}: ${result}`);
|
||||||
file.postData = response.data; // eslint-disable-line
|
console.warn(file);
|
||||||
file.s3 = response.data.key; // eslint-disable-line
|
});
|
||||||
file.previewTemplate.className += ' uploading'; // eslint-disable-line
|
} else {
|
||||||
done();
|
file.postData = []; // eslint-disable-line
|
||||||
})
|
axios.post(`${ROOT_URL}/S3/sign`, {
|
||||||
.catch(response => {
|
name: file.name,
|
||||||
file.custom_status = 'rejected'; // eslint-disable-line
|
type: file.type,
|
||||||
if (response.data.responseText && response.data.responseText.message) {
|
size: file.size,
|
||||||
done(response.data.responseText.message);
|
// _csrf: document.getElementById('__createPostToken').value
|
||||||
}
|
},
|
||||||
done('error preparing the upload');
|
{
|
||||||
});
|
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) {
|
export function dropzoneSendingCallback(file, xhr, formData) {
|
||||||
return () => {
|
return () => {
|
||||||
Object.keys(file.postData).forEach(key => {
|
if (!file.type.match(textFileRegex)) {
|
||||||
formData.append(key, file.postData[key]);
|
Object.keys(file.postData).forEach(key => {
|
||||||
});
|
formData.append(key, file.postData[key]);
|
||||||
formData.append('Content-type', '');
|
});
|
||||||
formData.append('Content-length', '');
|
formData.append('Content-type', '');
|
||||||
formData.append('acl', 'public-read');
|
formData.append('Content-length', '');
|
||||||
|
formData.append('acl', 'public-read');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dropzoneCompleteCallback(file) {
|
export function dropzoneCompleteCallback(file) {
|
||||||
return (dispatch, getState) => { // eslint-disable-line
|
return (dispatch, getState) => { // eslint-disable-line
|
||||||
let inputHidden = '<input type="hidden" name="attachments[]" value="';
|
if (!file.type.match(textFileRegex)) {
|
||||||
const json = {
|
let inputHidden = '<input type="hidden" name="attachments[]" value="';
|
||||||
url: `${s3Bucket}${file.postData.key}`,
|
const json = {
|
||||||
originalFilename: file.name
|
url: `${s3Bucket}${file.postData.key}`,
|
||||||
};
|
originalFilename: file.name
|
||||||
console.log(json, JSON.stringify(json), JSON.stringify(json).replace('"', '\\"'));
|
};
|
||||||
inputHidden += `${window.btoa(JSON.stringify(json))}" />`;
|
console.log(json, JSON.stringify(json), JSON.stringify(json).replace('"', '\\"'));
|
||||||
// document.getElementById('uploader').appendChild(inputHidden);
|
inputHidden += `${window.btoa(JSON.stringify(json))}" />`;
|
||||||
document.getElementById('uploader').innerHTML += inputHidden;
|
// document.getElementById('uploader').appendChild(inputHidden);
|
||||||
|
document.getElementById('uploader').innerHTML += inputHidden;
|
||||||
|
|
||||||
const formParams = {
|
const formParams = {
|
||||||
name: file.name,
|
name: file.name,
|
||||||
url: `${s3Bucket}${file.postData.key}`
|
url: `${s3Bucket}${file.postData.key}`
|
||||||
};
|
};
|
||||||
createFile(formParams)(dispatch, getState);
|
createFile(formParams)(dispatch, getState);
|
||||||
|
} else {
|
||||||
|
const formParams = {
|
||||||
|
name: file.name,
|
||||||
|
content: file.content
|
||||||
|
};
|
||||||
|
console.log(formParams);
|
||||||
|
createFile(formParams)(dispatch, getState);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,8 @@ class Editor extends React.Component {
|
||||||
this.props.updateFileContent(this.props.file.name, this._cm.getValue());
|
this.props.updateFileContent(this.props.file.name, this._cm.getValue());
|
||||||
}));
|
}));
|
||||||
this._cm.on('keyup', () => {
|
this._cm.on('keyup', () => {
|
||||||
this.props.updateLineNumber(parseInt((this._cm.getCursor().line) + 1, 10));
|
const temp = `line ${parseInt((this._cm.getCursor().line) + 1, 10)}`;
|
||||||
|
document.getElementById('current-line').innerHTML = temp;
|
||||||
});
|
});
|
||||||
// this._cm.on('change', () => { // eslint-disable-line
|
// this._cm.on('change', () => { // eslint-disable-line
|
||||||
// // this.props.updateFileContent('sketch.js', this._cm.getValue());
|
// // this.props.updateFileContent('sketch.js', this._cm.getValue());
|
||||||
|
|
|
@ -28,7 +28,7 @@ class EditorAccessibility extends React.Component {
|
||||||
{messages}
|
{messages}
|
||||||
</ul>
|
</ul>
|
||||||
<p> Current line
|
<p> Current line
|
||||||
<span className="editor-linenumber" aria-live="polite" aria-atomic="true" id="current-line"> {this.props.lineNumber} </span>
|
<span className="editor-linenumber" aria-live="polite" aria-atomic="true" id="current-line"> </span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -23,11 +23,16 @@ class FileUploader extends React.Component {
|
||||||
maxThumbnailFilesize: 8, // 3MB
|
maxThumbnailFilesize: 8, // 3MB
|
||||||
thumbnailWidth: 200,
|
thumbnailWidth: 200,
|
||||||
thumbnailHeight: 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,application/json,application/x-font-ttf,application/x-font-truetype',
|
||||||
dictDefaultMessage: 'Drop files here to upload or click to use the file browser',
|
dictDefaultMessage: 'Drop files here to upload or click to use the file browser',
|
||||||
accept: this.props.dropzoneAcceptCallback,
|
accept: this.props.dropzoneAcceptCallback,
|
||||||
sending: this.props.dropzoneSendingCallback,
|
sending: this.props.dropzoneSendingCallback,
|
||||||
complete: this.props.dropzoneCompleteCallback
|
complete: this.props.dropzoneCompleteCallback,
|
||||||
|
error: (file, errorMessage) => {
|
||||||
|
console.log(file);
|
||||||
|
console.log(errorMessage);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ class PreviewFrame extends React.Component {
|
||||||
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
|
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
|
||||||
jsFileStrings = jsFileStrings || [];
|
jsFileStrings = jsFileStrings || [];
|
||||||
jsFileStrings.forEach(jsFileString => {
|
jsFileStrings.forEach(jsFileString => {
|
||||||
if (jsFileString.match(/^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg)('|")$/)) {
|
if (jsFileString.match(/^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json)('|")$/i)) {
|
||||||
const filePath = jsFileString.substr(1, jsFileString.length - 2);
|
const filePath = jsFileString.substr(1, jsFileString.length - 2);
|
||||||
let fileName = filePath;
|
let fileName = filePath;
|
||||||
if (fileName.match(/^\.\//)) {
|
if (fileName.match(/^\.\//)) {
|
||||||
|
|
|
@ -74,7 +74,7 @@ const files = (state = initialState, action) => {
|
||||||
case ActionTypes.RESET_PROJECT:
|
case ActionTypes.RESET_PROJECT:
|
||||||
return initialState;
|
return initialState;
|
||||||
case ActionTypes.CREATE_FILE:
|
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:
|
case ActionTypes.SHOW_FILE_OPTIONS:
|
||||||
return state.map(file => {
|
return state.map(file => {
|
||||||
if (file.id !== action.id) {
|
if (file.id !== action.id) {
|
||||||
|
@ -131,9 +131,9 @@ export const setSelectedFile = (state, id) =>
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getFile = (state, id) => state.filter(file => file.id === id)[0];
|
export const getFile = (state, id) => state.filter(file => file.id === id)[0];
|
||||||
export const getHTMLFile = (state) => state.filter(file => file.name.match(/.*\.html$/))[0];
|
export const getHTMLFile = (state) => state.filter(file => file.name.match(/.*\.html$/i))[0];
|
||||||
export const getJSFiles = (state) => state.filter(file => file.name.match(/.*\.js$/));
|
export const getJSFiles = (state) => state.filter(file => file.name.match(/.*\.js$/i));
|
||||||
export const getCSSFiles = (state) => state.filter(file => file.name.match(/.*\.css$/));
|
export const getCSSFiles = (state) => state.filter(file => file.name.match(/.*\.css$/i));
|
||||||
export const getLinkedFiles = (state) => state.filter(file => file.url);
|
export const getLinkedFiles = (state) => state.filter(file => file.url);
|
||||||
|
|
||||||
export default files;
|
export default files;
|
||||||
|
|
Loading…
Reference in a new issue