Merge branch 'develop' into feature/mobile-settings-screen
This commit is contained in:
commit
7d6ba6f34f
7 changed files with 39 additions and 27 deletions
|
@ -155,18 +155,20 @@ export function saveProject(selectedFile = null, autosave = false) {
|
|||
if (!autosave) {
|
||||
if (state.ide.justOpenedProject && state.preferences.autosave) {
|
||||
dispatch(showToast(5500));
|
||||
dispatch(setToastText('Project saved.'));
|
||||
dispatch(setToastText('Sketch saved.'));
|
||||
setTimeout(() => dispatch(setToastText('Autosave enabled.')), 1500);
|
||||
dispatch(resetJustOpenedProject());
|
||||
} else {
|
||||
dispatch(showToast(1500));
|
||||
dispatch(setToastText('Project saved.'));
|
||||
dispatch(setToastText('Sketch saved.'));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
dispatch(endSavingProject());
|
||||
dispatch(setToastText('Failed to save sketch.'));
|
||||
dispatch(showToast(1500));
|
||||
if (response.status === 403) {
|
||||
dispatch(showErrorModal('staleSession'));
|
||||
} else if (response.status === 409) {
|
||||
|
@ -195,18 +197,20 @@ export function saveProject(selectedFile = null, autosave = false) {
|
|||
if (!autosave) {
|
||||
if (state.preferences.autosave) {
|
||||
dispatch(showToast(5500));
|
||||
dispatch(setToastText('Project saved.'));
|
||||
dispatch(setToastText('Sketch saved.'));
|
||||
setTimeout(() => dispatch(setToastText('Autosave enabled.')), 1500);
|
||||
dispatch(resetJustOpenedProject());
|
||||
} else {
|
||||
dispatch(showToast(1500));
|
||||
dispatch(setToastText('Project saved.'));
|
||||
dispatch(setToastText('Sketch saved.'));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
dispatch(endSavingProject());
|
||||
dispatch(setToastText('Failed to save sketch.'));
|
||||
dispatch(showToast(1500));
|
||||
if (response.status === 403) {
|
||||
dispatch(showErrorModal('staleSession'));
|
||||
} else {
|
||||
|
|
|
@ -237,16 +237,18 @@ class PreviewFrame extends React.Component {
|
|||
jsFileStrings.forEach((jsFileString) => {
|
||||
if (jsFileString.match(MEDIA_FILE_QUOTED_REGEX)) {
|
||||
const filePath = jsFileString.substr(1, jsFileString.length - 2);
|
||||
const quoteCharacter = jsFileString.substr(0, 1);
|
||||
const resolvedFile = resolvePathToFile(filePath, files);
|
||||
|
||||
if (resolvedFile) {
|
||||
if (resolvedFile.url) {
|
||||
newContent = newContent.replace(filePath, resolvedFile.url);
|
||||
newContent = newContent.replace(jsFileString, quoteCharacter + resolvedFile.url + quoteCharacter);
|
||||
} else if (resolvedFile.name.match(PLAINTEXT_FILE_REGEX)) {
|
||||
// could also pull file from API instead of using bloburl
|
||||
const blobURL = getBlobUrl(resolvedFile);
|
||||
this.props.setBlobUrl(resolvedFile, blobURL);
|
||||
const filePathRegex = new RegExp(filePath, 'gi');
|
||||
newContent = newContent.replace(filePathRegex, blobURL);
|
||||
|
||||
newContent = newContent.replace(jsFileString, quoteCharacter + blobURL + quoteCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -262,10 +264,11 @@ class PreviewFrame extends React.Component {
|
|||
cssFileStrings.forEach((cssFileString) => {
|
||||
if (cssFileString.match(MEDIA_FILE_QUOTED_REGEX)) {
|
||||
const filePath = cssFileString.substr(1, cssFileString.length - 2);
|
||||
const quoteCharacter = cssFileString.substr(0, 1);
|
||||
const resolvedFile = resolvePathToFile(filePath, files);
|
||||
if (resolvedFile) {
|
||||
if (resolvedFile.url) {
|
||||
newContent = newContent.replace(filePath, resolvedFile.url);
|
||||
newContent = newContent.replace(cssFileString, quoteCharacter + resolvedFile.url + quoteCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,15 @@ import AddToCollectionList from '../components/AddToCollectionList';
|
|||
import Feedback from '../components/Feedback';
|
||||
import { CollectionSearchbar } from '../components/Searchbar';
|
||||
|
||||
function getTitle(props) {
|
||||
const { id } = props.project;
|
||||
return id ? `p5.js Web Editor | ${props.project.name}` : 'p5.js Web Editor';
|
||||
}
|
||||
|
||||
function isUserOwner(props) {
|
||||
return props.project.owner && props.project.owner.id === props.user.id;
|
||||
}
|
||||
|
||||
class IDEView extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -92,7 +101,7 @@ class IDEView extends React.Component {
|
|||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.isUserOwner() && this.props.project.id) {
|
||||
if (isUserOwner(this.props) && this.props.project.id) {
|
||||
if (this.props.preferences.autosave && this.props.ide.unsavedChanges && !this.props.ide.justOpenedProject) {
|
||||
if (
|
||||
this.props.selectedFile.name === prevProps.selectedFile.name &&
|
||||
|
@ -123,21 +132,12 @@ class IDEView extends React.Component {
|
|||
this.autosaveInterval = null;
|
||||
}
|
||||
|
||||
getTitle = () => {
|
||||
const { id } = this.props.project;
|
||||
return id ? `p5.js Web Editor | ${this.props.project.name}` : 'p5.js Web Editor';
|
||||
}
|
||||
|
||||
isUserOwner() {
|
||||
return this.props.project.owner && this.props.project.owner.id === this.props.user.id;
|
||||
}
|
||||
|
||||
handleGlobalKeydown(e) {
|
||||
// 83 === s
|
||||
if (e.keyCode === 83 && ((e.metaKey && this.isMac) || (e.ctrlKey && !this.isMac))) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (this.isUserOwner() || (this.props.user.authenticated && !this.props.project.owner)) {
|
||||
if (isUserOwner(this.props) || (this.props.user.authenticated && !this.props.project.owner)) {
|
||||
this.props.saveProject(this.cmController.getContent());
|
||||
} else if (this.props.user.authenticated) {
|
||||
this.props.cloneProject();
|
||||
|
@ -208,7 +208,7 @@ class IDEView extends React.Component {
|
|||
return (
|
||||
<div className="ide">
|
||||
<Helmet>
|
||||
<title>{this.getTitle()}</title>
|
||||
<title>{getTitle(this.props)}</title>
|
||||
</Helmet>
|
||||
{this.props.toast.isVisible && <Toast />}
|
||||
<Nav
|
||||
|
@ -313,7 +313,7 @@ class IDEView extends React.Component {
|
|||
isExpanded={this.props.ide.sidebarIsExpanded}
|
||||
expandSidebar={this.props.expandSidebar}
|
||||
collapseSidebar={this.props.collapseSidebar}
|
||||
isUserOwner={this.isUserOwner()}
|
||||
isUserOwner={isUserOwner(this.props)}
|
||||
clearConsole={this.props.clearConsole}
|
||||
consoleEvents={this.props.console}
|
||||
showRuntimeErrorWarning={this.props.showRuntimeErrorWarning}
|
||||
|
|
|
@ -37,6 +37,11 @@ const getSortedCollections = createSelector(
|
|||
return orderBy(collections, 'name', 'desc');
|
||||
}
|
||||
return orderBy(collections, 'name', 'asc');
|
||||
} else if (field === 'numItems') {
|
||||
if (direction === DIRECTION.DESC) {
|
||||
return orderBy(collections, 'items.length', 'desc');
|
||||
}
|
||||
return orderBy(collections, 'items.length', 'asc');
|
||||
}
|
||||
const sortedCollections = [...collections].sort((a, b) => {
|
||||
const result =
|
||||
|
|
|
@ -69,9 +69,8 @@ Note that this is optional, unless you are working on the part of the applicatio
|
|||
If your S3 bucket is in the US East (N Virginia) region (us-east-1), you'll
|
||||
need to set a custom URL base for it, because it does not follow the standard
|
||||
naming pattern as the rest of the regions. Instead, add the following to your
|
||||
environment/.env file:
|
||||
|
||||
`S3_BUCKET_URL_BASE=https://s3.amazonaws.com`
|
||||
environment/.env file, changing `BUCKET_NAME` to your bucket name. This is necessary because this override is currently treated as the full path to the bucket rather than as a proper base url:
|
||||
`S3_BUCKET_URL_BASE=https://s3.amazonaws.com/{BUCKET_NAME}/`
|
||||
|
||||
If you've configured your S3 bucket and DNS records to use a custom domain
|
||||
name, you can also set it using this variable. I.e.:
|
||||
|
|
|
@ -34,6 +34,7 @@ export function serveProject(req, res) {
|
|||
resolveScripts(sketchDoc, files);
|
||||
resolveStyles(sketchDoc, files);
|
||||
|
||||
res.setHeader('Cache-Control', 'public, max-age=0');
|
||||
res.send(serializeDocument(sketchDoc));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -73,7 +73,7 @@ function getCategories() {
|
|||
function getSketchesInCategories(categories) {
|
||||
return Q.all(categories.map((category) => {
|
||||
const options = {
|
||||
url: `${category.url.replace('?ref=master', '')}?client_id=${clientId}&client_secret=${clientSecret}`,
|
||||
url: `${category.url.replace('?ref=main', '')}?client_id=${clientId}&client_secret=${clientSecret}`,
|
||||
method: 'GET',
|
||||
headers,
|
||||
json: true
|
||||
|
@ -107,7 +107,7 @@ function getSketchesInCategories(categories) {
|
|||
function getSketchContent(projectsInAllCategories) {
|
||||
return Q.all(projectsInAllCategories.map(projectsInOneCategory => Q.all(projectsInOneCategory.map((project) => {
|
||||
const options = {
|
||||
url: `${project.sketchUrl.replace('?ref=master', '')}?client_id=${clientId}&client_secret=${clientSecret}`,
|
||||
url: `${project.sketchUrl.replace('?ref=main', '')}?client_id=${clientId}&client_secret=${clientSecret}`,
|
||||
method: 'GET',
|
||||
headers
|
||||
};
|
||||
|
@ -264,7 +264,7 @@ function createProjectsInP5user(projectsInAllCategories) {
|
|||
const fileID = objectID().toHexString();
|
||||
newProject.files.push({
|
||||
name: assetName,
|
||||
url: `https://cdn.jsdelivr.net/gh/processing/p5.js-website@master/src/data/examples/assets/${assetName}`,
|
||||
url: `https://cdn.jsdelivr.net/gh/processing/p5.js-website@main/src/data/examples/assets/${assetName}`,
|
||||
id: fileID,
|
||||
_id: fileID,
|
||||
children: [],
|
||||
|
|
Loading…
Reference in a new issue