Fix save on pressing play with new project -- show save button first time around (as isPlaying get reset when URL is change on save)
This commit is contained in:
parent
c1810ed47f
commit
f181bc6cb7
5 changed files with 76 additions and 47 deletions
|
@ -127,6 +127,7 @@ function getSynchedProject(currentState, responseProject) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveProject(selectedFile = null, autosave = false, mobile = false) {
|
export function saveProject(selectedFile = null, autosave = false, mobile = false) {
|
||||||
|
console.trace('saving inproject.js');
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
if (state.project.isSaving) {
|
if (state.project.isSaving) {
|
||||||
|
|
|
@ -59,7 +59,9 @@ class PreviewFrame extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
// console.log(this.props, prevProps);
|
if (prevProps.isPlaying === true && this.props.isPlaying === false) {
|
||||||
|
console.trace('update', this.props, prevProps);
|
||||||
|
}
|
||||||
if (shouldRenderSketch(this.props, prevProps)) this.renderSketch();
|
if (shouldRenderSketch(this.props, prevProps)) this.renderSketch();
|
||||||
// small bug - if autorefresh is on, and the usr changes files
|
// small bug - if autorefresh is on, and the usr changes files
|
||||||
// in the sketch, preview will reload
|
// in the sketch, preview will reload
|
||||||
|
@ -339,72 +341,81 @@ class PreviewFrame extends React.Component {
|
||||||
// console.log('changed and requiring reload:', changedFiles, filesRequiringReload, filesToHotSwap);
|
// console.log('changed and requiring reload:', changedFiles, filesRequiringReload, filesToHotSwap);
|
||||||
|
|
||||||
let saving;
|
let saving;
|
||||||
if (changedFiles.length > 0) {
|
console.log('is saving...', this.props);
|
||||||
|
if (changedFiles.length > 0 || this.props.project.updatedAt === '') {
|
||||||
saving = this.props.saveProject();
|
saving = this.props.saveProject();
|
||||||
} else {
|
} else {
|
||||||
// can be done pretier: a promise that always resolves
|
// can be done pretier: a promise that always resolves
|
||||||
saving = new Promise((resolve, err) => resolve());
|
saving = new Promise((resolve, err) => resolve());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('saving:', saving);
|
||||||
|
|
||||||
if (saving === null) {
|
if (saving === null) {
|
||||||
// console.log('Error saving... not authenticated?');
|
console.log('Error saving... not authenticated?');
|
||||||
this.props.stopSketch(); // prevent crazy loop of renderSketch() through componentDidUpdate()
|
this.props.stopSketch(); // prevent crazy loop of renderSketch() through componentDidUpdate()
|
||||||
} else {
|
} else {
|
||||||
saving.catch(() => {
|
saving.catch(() => {
|
||||||
// console.log('Error when saving... not authenticated? Redirect!');
|
console.log('Error when saving... not authenticated? Redirect!');
|
||||||
this.props.stopSketch(); // prevent crazy loop of renderSketch() through componentDidUpdate()
|
this.props.stopSketch(); // prevent crazy loop of renderSketch() through componentDidUpdate()
|
||||||
|
// this.props.clearConsole(); // introduces bug: causes nested compnonentDidUpdate()
|
||||||
});
|
});
|
||||||
|
|
||||||
saving.then(() => {
|
saving.then(() => {
|
||||||
|
console.log('play!', this.props.isPlaying);
|
||||||
if (this.props.isPlaying) {
|
if (this.props.isPlaying) {
|
||||||
this.props.clearConsole();
|
|
||||||
doc.removeAttribute('srcdoc');
|
doc.removeAttribute('srcdoc');
|
||||||
|
|
||||||
const source = `${window.location.origin}/${this.props.project.owner.username}/sketches/${this.props.project.id}/index.html`;
|
if (typeof this.props.project.owner === 'undefined') {
|
||||||
// console.log('FILES', this.props.files, doc.src, source, lastUpdate);
|
console.error('no owner for project?', this.props.project);
|
||||||
if (doc.src === source) {
|
|
||||||
// const newFiles = this.props.files.filter(file => new Date(file.updatedAt) > lastUpdate);
|
|
||||||
if (this.props.unsavedChanges) {
|
|
||||||
// console.log('unsaved changes');
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('doc', doc);
|
|
||||||
// we need a hard reload
|
|
||||||
if (filesRequiringReload.length > 0) {
|
|
||||||
doc.src = source; // for now...
|
|
||||||
} else {
|
|
||||||
// if (doc.contentWindow.document.querySelector('script[src="/assets/hotswap.js"]') == null) {
|
|
||||||
// const headEl = doc.contentWindow.document.querySelector('head');
|
|
||||||
// const srcEl = doc.contentWindow.document.createElement('script');
|
|
||||||
// srcEl.src = '/assets/hotswap.js';
|
|
||||||
// headEl.appendChild(srcEl);
|
|
||||||
// }
|
|
||||||
|
|
||||||
console.log('Hot swap (..append):', filesToHotSwap);
|
|
||||||
const headEl = doc.contentWindow.document.querySelector('head');
|
|
||||||
const updatevar = Date.now();
|
|
||||||
filesToHotSwap.forEach((file) => {
|
|
||||||
// doc.contentWindow.postMessage({ 'action': 'code', 'contents': file.content }, '*');
|
|
||||||
const srcEl = doc.contentWindow.document.createElement('script');
|
|
||||||
srcEl.src = `${file.name}?changed=${updatevar}`;
|
|
||||||
srcEl.onload = 'setupAssets();'; // (re)load assets
|
|
||||||
headEl.appendChild(srcEl);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// if ( this.props.htmlFile.content === doc.contentWindow)
|
|
||||||
// TODO: don't set, but update only (will be hard... :-P)
|
|
||||||
} else {
|
} else {
|
||||||
doc.src = source;
|
const source = `${window.location.origin}/${this.props.project.owner.username}/sketches/${this.props.project.id}/index.html`;
|
||||||
}
|
// console.log('FILES', this.props.files, doc.src, source, lastUpdate);
|
||||||
// lastUpdate = new Date();
|
if (doc.src === source) {
|
||||||
if (this.props.endSketchRefresh) {
|
// const newFiles = this.props.files.filter(file => new Date(file.updatedAt) > lastUpdate);
|
||||||
this.props.endSketchRefresh();
|
if (this.props.unsavedChanges) {
|
||||||
|
// console.log('unsaved changes');
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('doc', doc);
|
||||||
|
// we need a hard reload
|
||||||
|
if (filesRequiringReload.length > 0) {
|
||||||
|
doc.src = source; // for now...
|
||||||
|
} else {
|
||||||
|
// if (doc.contentWindow.document.querySelector('script[src="/assets/hotswap.js"]') == null) {
|
||||||
|
// const headEl = doc.contentWindow.document.querySelector('head');
|
||||||
|
// const srcEl = doc.contentWindow.document.createElement('script');
|
||||||
|
// srcEl.src = '/assets/hotswap.js';
|
||||||
|
// headEl.appendChild(srcEl);
|
||||||
|
// }
|
||||||
|
|
||||||
|
console.log('Hot swap (..append):', filesToHotSwap);
|
||||||
|
const headEl = doc.contentWindow.document.querySelector('head');
|
||||||
|
const updatevar = Date.now();
|
||||||
|
filesToHotSwap.forEach((file) => {
|
||||||
|
// doc.contentWindow.postMessage({ 'action': 'code', 'contents': file.content }, '*');
|
||||||
|
const srcEl = doc.contentWindow.document.createElement('script');
|
||||||
|
srcEl.src = `${file.name}?changed=${updatevar}`;
|
||||||
|
srcEl.onload = 'setupAssets();'; // (re)load assets
|
||||||
|
headEl.appendChild(srcEl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// if ( this.props.htmlFile.content === doc.contentWindow)
|
||||||
|
// TODO: don't set, but update only (will be hard... :-P)
|
||||||
|
} else {
|
||||||
|
doc.src = source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doc.removeAttribute('src');
|
doc.removeAttribute('src');
|
||||||
doc.srcdoc = '';
|
doc.srcdoc = '';
|
||||||
srcDoc.set(doc, ' ');
|
srcDoc.set(doc, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevent looping
|
||||||
|
if (this.props.endSketchRefresh) {
|
||||||
|
this.props.endSketchRefresh();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +474,7 @@ PreviewFrame.propTypes = {
|
||||||
}),
|
}),
|
||||||
updatedAt: PropTypes.string,
|
updatedAt: PropTypes.string,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
clearConsole: PropTypes.func.isRequired,
|
// clearConsole: PropTypes.func,
|
||||||
unsavedChanges: PropTypes.bool,
|
unsavedChanges: PropTypes.bool,
|
||||||
cmController: PropTypes.shape({
|
cmController: PropTypes.shape({
|
||||||
getContent: PropTypes.func
|
getContent: PropTypes.func
|
||||||
|
@ -473,7 +484,7 @@ PreviewFrame.propTypes = {
|
||||||
PreviewFrame.defaultProps = {
|
PreviewFrame.defaultProps = {
|
||||||
fullView: false,
|
fullView: false,
|
||||||
unsavedChanges: false,
|
unsavedChanges: false,
|
||||||
cmController: {}
|
cmController: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PreviewFrame;
|
export default PreviewFrame;
|
||||||
|
|
|
@ -60,7 +60,9 @@ class Toolbar extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const playButtonClass = classNames({
|
const playButtonClass = classNames({
|
||||||
'toolbar__play-button': true,
|
'toolbar__play-button': true,
|
||||||
'toolbar__play-button--selected': this.props.isPlaying
|
'toolbar__play-button--selected': this.props.isPlaying,
|
||||||
|
'toolbar__play-button--saved': this.props.isSaved,
|
||||||
|
'toolbar__play-button--unsaved': !this.props.isSaved
|
||||||
});
|
});
|
||||||
const stopButtonClass = classNames({
|
const stopButtonClass = classNames({
|
||||||
'toolbar__stop-button': true,
|
'toolbar__stop-button': true,
|
||||||
|
@ -176,6 +178,7 @@ class Toolbar extends React.Component {
|
||||||
|
|
||||||
Toolbar.propTypes = {
|
Toolbar.propTypes = {
|
||||||
isPlaying: PropTypes.bool.isRequired,
|
isPlaying: PropTypes.bool.isRequired,
|
||||||
|
isSaved: PropTypes.bool.isRequired,
|
||||||
preferencesIsVisible: PropTypes.bool.isRequired,
|
preferencesIsVisible: PropTypes.bool.isRequired,
|
||||||
stopSketch: PropTypes.func.isRequired,
|
stopSketch: PropTypes.func.isRequired,
|
||||||
setProjectName: PropTypes.func.isRequired,
|
setProjectName: PropTypes.func.isRequired,
|
||||||
|
@ -215,6 +218,7 @@ function mapStateToProps(state) {
|
||||||
infiniteLoop: state.ide.infiniteLoop,
|
infiniteLoop: state.ide.infiniteLoop,
|
||||||
isPlaying: state.ide.isPlaying,
|
isPlaying: state.ide.isPlaying,
|
||||||
owner: state.project.owner,
|
owner: state.project.owner,
|
||||||
|
isSaved: state.project.updatedAt !== '',
|
||||||
preferencesIsVisible: state.ide.preferencesIsVisible,
|
preferencesIsVisible: state.ide.preferencesIsVisible,
|
||||||
project: state.project,
|
project: state.project,
|
||||||
};
|
};
|
||||||
|
|
|
@ -174,12 +174,13 @@ class IDEView extends React.Component {
|
||||||
this.autosaveInterval = null;
|
this.autosaveInterval = null;
|
||||||
}
|
}
|
||||||
saveProject() {
|
saveProject() {
|
||||||
|
console.trace('saving!');
|
||||||
// return a Promise to save or null
|
// return a Promise to save or null
|
||||||
if (
|
if (
|
||||||
isUserOwner(this.props) ||
|
isUserOwner(this.props) ||
|
||||||
(this.props.user.authenticated && !this.props.project.owner)
|
(this.props.user.authenticated && !this.props.project.owner)
|
||||||
) {
|
) {
|
||||||
console.log('project to save:', this.props.project);
|
console.trace('project to save:', this.props.project);
|
||||||
return this.props.saveProject(this.cmController.getContent());
|
return this.props.saveProject(this.cmController.getContent());
|
||||||
} else if (this.props.user.authenticated) {
|
} else if (this.props.user.authenticated) {
|
||||||
return this.props.cloneProject();
|
return this.props.cloneProject();
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
.toolbar__play-button {
|
.toolbar__play-button {
|
||||||
|
&--unsaved {
|
||||||
|
// for some reason, I cannot manage to have PreviewFrame save _and_ actuall yload the project (it stops the playback)
|
||||||
|
// pressing twice works. So just show a floppy the first time around :-)
|
||||||
|
svg {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&::after{
|
||||||
|
content: '\1F4BE'; // save floppy
|
||||||
|
}
|
||||||
|
// background-color: blue !important;
|
||||||
|
}
|
||||||
|
|
||||||
@include themify() {
|
@include themify() {
|
||||||
@extend %toolbar-button;
|
@extend %toolbar-button;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
Loading…
Reference in a new issue