diff --git a/.github/config.yml b/.github/config.yml
new file mode 100644
index 00000000..b4ec5b1a
--- /dev/null
+++ b/.github/config.yml
@@ -0,0 +1,17 @@
+# Configuration for welcome - https://github.com/behaviorbot/welcome
+
+# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
+
+# Comment to be posted to on first time issues
+newIssueWelcomeComment: >
+ Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, be sure to follow the issue template if you haven't already.
+
+# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
+
+# Comment to be posted to on PRs from first time contributors in your repository
+newPRWelcomeComment: >
+ 🎉 Thanks for opening this pull request! Please check out our [contributing guidelines](https://github.com/processing/p5.js-web-editor/blob/master/CONTRIBUTING.md) if you haven't already.
+
+# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
+
+# Comment to be posted to on pull requests merged by a first time user
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index e57d651c..0f093be6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -46,4 +46,4 @@ deploy:
env:
global:
- - APP_IMAGE_NAME=p5jswebeditor_app
+ - APP_IMAGE_NAME=p5js-web-editor_app
diff --git a/client/components/Nav.jsx b/client/components/Nav.jsx
index 608ab477..1c3e43d8 100644
--- a/client/components/Nav.jsx
+++ b/client/components/Nav.jsx
@@ -131,12 +131,12 @@ class Nav extends React.PureComponent {
}
handleAddFile() {
- this.props.newFile();
+ this.props.newFile(this.props.rootFile.id);
this.setDropdown('none');
}
handleAddFolder() {
- this.props.newFolder();
+ this.props.newFolder(this.props.rootFile.id);
this.setDropdown('none');
}
@@ -174,7 +174,7 @@ class Nav extends React.PureComponent {
handleDownload() {
this.props.autosaveProject();
- this.props.exportProjectAsZip(this.props.project.id);
+ projectActions.exportProjectAsZip(this.props.project.id);
this.setDropdown('none');
}
@@ -719,7 +719,6 @@ Nav.propTypes = {
setToastText: PropTypes.func.isRequired,
saveProject: PropTypes.func.isRequired,
autosaveProject: PropTypes.func.isRequired,
- exportProjectAsZip: PropTypes.func.isRequired,
cloneProject: PropTypes.func.isRequired,
user: PropTypes.shape({
authenticated: PropTypes.bool.isRequired,
@@ -750,7 +749,10 @@ Nav.propTypes = {
setAllAccessibleOutput: PropTypes.func.isRequired,
newFile: PropTypes.func.isRequired,
newFolder: PropTypes.func.isRequired,
- layout: PropTypes.oneOf(['dashboard', 'project'])
+ layout: PropTypes.oneOf(['dashboard', 'project']),
+ rootFile: PropTypes.shape({
+ id: PropTypes.string.isRequired
+ }).isRequired
};
Nav.defaultProps = {
@@ -767,7 +769,8 @@ function mapStateToProps(state) {
return {
project: state.project,
user: state.user,
- unsavedChanges: state.ide.unsavedChanges
+ unsavedChanges: state.ide.unsavedChanges,
+ rootFile: state.files.filter(file => file.name === 'root')[0]
};
}
diff --git a/client/components/__test__/Nav.test.jsx b/client/components/__test__/Nav.test.jsx
index a056ccb3..f9261cfc 100644
--- a/client/components/__test__/Nav.test.jsx
+++ b/client/components/__test__/Nav.test.jsx
@@ -39,7 +39,12 @@ describe('Nav', () => {
},
startSketch: jest.fn(),
stopSketch: jest.fn(),
- setAllAccessibleOutput: jest.fn()
+ setAllAccessibleOutput: jest.fn(),
+ showToast: jest.fn(),
+ setToastText: jest.fn(),
+ rootFile: {
+ id: 'root-file'
+ }
};
const getWrapper = () => shallow();
diff --git a/client/modules/IDE/actions/files.js b/client/modules/IDE/actions/files.js
index ff56454a..0bbf292d 100644
--- a/client/modules/IDE/actions/files.js
+++ b/client/modules/IDE/actions/files.js
@@ -41,14 +41,7 @@ export function updateFileContent(id, content) {
export function createFile(formProps) {
return (dispatch, getState) => {
const state = getState();
- const selectedFile = state.files.find(file => file.isSelectedFile);
- const rootFile = state.files.find(file => file.name === 'root');
- let parentId;
- if (selectedFile.fileType === 'folder') {
- parentId = selectedFile.id;
- } else {
- parentId = rootFile.id;
- }
+ const { parentId } = state.ide;
if (state.project.id) {
const postParams = {
name: createUniqueName(formProps.name, parentId, state.files),
@@ -99,14 +92,7 @@ export function createFile(formProps) {
export function createFolder(formProps) {
return (dispatch, getState) => {
const state = getState();
- const selectedFile = state.files.find(file => file.isSelectedFile);
- const rootFile = state.files.find(file => file.name === 'root');
- let parentId;
- if (selectedFile.fileType === 'folder') {
- parentId = selectedFile.id;
- } else {
- parentId = rootFile.id;
- }
+ const { parentId } = state.ide;
if (state.project.id) {
const postParams = {
name: createUniqueName(formProps.name, parentId, state.files),
diff --git a/client/modules/IDE/actions/ide.js b/client/modules/IDE/actions/ide.js
index 1d7c2998..b6351a7d 100644
--- a/client/modules/IDE/actions/ide.js
+++ b/client/modules/IDE/actions/ide.js
@@ -62,9 +62,10 @@ export function resetSelectedFile(previousId) {
};
}
-export function newFile() {
+export function newFile(parentId) {
return {
- type: ActionTypes.SHOW_MODAL
+ type: ActionTypes.SHOW_MODAL,
+ parentId
};
}
@@ -122,9 +123,10 @@ export function closeProjectOptions() {
};
}
-export function newFolder() {
+export function newFolder(parentId) {
return {
- type: ActionTypes.SHOW_NEW_FOLDER_MODAL
+ type: ActionTypes.SHOW_NEW_FOLDER_MODAL,
+ parentId
};
}
diff --git a/client/modules/IDE/actions/uploader.js b/client/modules/IDE/actions/uploader.js
index a15d32d7..f2f12585 100644
--- a/client/modules/IDE/actions/uploader.js
+++ b/client/modules/IDE/actions/uploader.js
@@ -82,7 +82,7 @@ export function dropzoneSendingCallback(file, xhr, formData) {
Object.keys(file.postData).forEach((key) => {
formData.append(key, file.postData[key]);
});
- formData.append('Content-type', '');
+ formData.append('Content-type', file.type);
formData.append('Content-length', '');
formData.append('acl', 'public-read');
}
diff --git a/client/modules/IDE/components/AssetList.jsx b/client/modules/IDE/components/AssetList.jsx
index a658fedf..3bec6cc2 100644
--- a/client/modules/IDE/components/AssetList.jsx
+++ b/client/modules/IDE/components/AssetList.jsx
@@ -56,19 +56,21 @@ class AssetList extends React.Component {
- Name |
- Size |
- View |
- Sketch |
+ Name |
+ Size |
+ Sketch |
{assetList.map(asset =>
(
- {asset.name} |
+
+
+ {asset.name}
+
+ |
{prettyBytes(asset.size)} |
- View |
{asset.sketchName} |
))}
diff --git a/client/modules/IDE/components/Editor.jsx b/client/modules/IDE/components/Editor.jsx
index cb330b32..9c447cfa 100644
--- a/client/modules/IDE/components/Editor.jsx
+++ b/client/modules/IDE/components/Editor.jsx
@@ -108,7 +108,15 @@ class Editor extends React.Component {
delete this._cm.options.lint.options.errors;
this._cm.setOption('extraKeys', {
- Tab: cm => cm.replaceSelection(' '.repeat(INDENTATION_AMOUNT)),
+ Tab: (cm) => {
+ // might need to specify and indent more?
+ const selection = cm.doc.getSelection();
+ if (selection.length > 0) {
+ cm.execCommand('indentMore');
+ } else {
+ cm.replaceSelection(' '.repeat(INDENTATION_AMOUNT));
+ }
+ },
[`${metaKey}-Enter`]: () => null,
[`Shift-${metaKey}-Enter`]: () => null,
[`${metaKey}-F`]: 'findPersistent',
@@ -126,7 +134,7 @@ class Editor extends React.Component {
this.props.clearConsole();
this.props.startRefreshSketch();
}
- }, 400));
+ }, 1000));
this._cm.on('keyup', () => {
const temp = `line ${parseInt((this._cm.getCursor().line) + 1, 10)}`;
diff --git a/client/modules/IDE/components/FileNode.jsx b/client/modules/IDE/components/FileNode.jsx
index 1b28bd4e..12496b38 100644
--- a/client/modules/IDE/components/FileNode.jsx
+++ b/client/modules/IDE/components/FileNode.jsx
@@ -188,7 +188,7 @@ export class FileNode extends React.Component {