diff --git a/client/modules/IDE/actions/project.js b/client/modules/IDE/actions/project.js index 2e2bca0b..9055d484 100644 --- a/client/modules/IDE/actions/project.js +++ b/client/modules/IDE/actions/project.js @@ -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 { diff --git a/client/modules/IDE/components/PreviewFrame.jsx b/client/modules/IDE/components/PreviewFrame.jsx index 9f429546..3b193a8f 100644 --- a/client/modules/IDE/components/PreviewFrame.jsx +++ b/client/modules/IDE/components/PreviewFrame.jsx @@ -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); } } } diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx index 9ff8351d..fbb3dafc 100644 --- a/client/modules/IDE/pages/IDEView.jsx +++ b/client/modules/IDE/pages/IDEView.jsx @@ -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 (