mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-26 17:16:11 -05:00
Merge pull request #3564 from LLK/hotfix/project-creation-replication-lag
[Master] Work around replication lag problems on project creation
This commit is contained in:
commit
73cfd78b12
4 changed files with 110 additions and 3 deletions
25
package-lock.json
generated
25
package-lock.json
generated
|
@ -12032,6 +12032,24 @@
|
|||
"prepend-http": "^1.0.0",
|
||||
"query-string": "^4.1.0",
|
||||
"sort-keys": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"query-string": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
||||
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"npm-run-path": {
|
||||
|
@ -13907,11 +13925,12 @@
|
|||
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
||||
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
|
||||
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
"po2icu": "0.0.2",
|
||||
"postcss-loader": "2.0.10",
|
||||
"prop-types": "15.6.0",
|
||||
"query-string": "^5.1.1",
|
||||
"react": "16.2.0",
|
||||
"react-dom": "16.2.0",
|
||||
"react-intl": "2.8.0",
|
||||
|
|
|
@ -111,6 +111,7 @@ const PreviewPresentation = ({
|
|||
onSocialClosed,
|
||||
onToggleComments,
|
||||
onToggleStudio,
|
||||
onUpdateProjectData,
|
||||
onUpdateProjectId,
|
||||
onUpdateProjectThumbnail,
|
||||
originalInfo,
|
||||
|
@ -345,6 +346,7 @@ const PreviewPresentation = ({
|
|||
onProjectLoaded={onProjectLoaded}
|
||||
onRemixing={onRemixing}
|
||||
onSetProjectThumbnailer={onSetProjectThumbnailer}
|
||||
onUpdateProjectData={onUpdateProjectData}
|
||||
onUpdateProjectId={onUpdateProjectId}
|
||||
onUpdateProjectThumbnail={onUpdateProjectThumbnail}
|
||||
/>
|
||||
|
@ -725,6 +727,7 @@ PreviewPresentation.propTypes = {
|
|||
onSocialClosed: PropTypes.func,
|
||||
onToggleComments: PropTypes.func,
|
||||
onToggleStudio: PropTypes.func,
|
||||
onUpdateProjectData: PropTypes.func,
|
||||
onUpdateProjectId: PropTypes.func,
|
||||
onUpdateProjectThumbnail: PropTypes.func,
|
||||
originalInfo: projectShape,
|
||||
|
|
|
@ -8,7 +8,9 @@ const PropTypes = require('prop-types');
|
|||
const connect = require('react-redux').connect;
|
||||
const injectIntl = require('react-intl').injectIntl;
|
||||
const parser = require('scratch-parser');
|
||||
const queryString = require('query-string');
|
||||
|
||||
const api = require('../../lib/api');
|
||||
const Page = require('../../components/page/www/page.jsx');
|
||||
const storage = require('../../lib/storage.js').default;
|
||||
const log = require('../../lib/log');
|
||||
|
@ -36,6 +38,7 @@ const IntlGUI = injectIntl(GUI.default);
|
|||
const localStorageAvailable = 'localStorage' in window && window.localStorage !== null;
|
||||
|
||||
const initSentry = require('../../lib/sentry.js');
|
||||
const xhr = require('xhr');
|
||||
initSentry();
|
||||
|
||||
class Preview extends React.Component {
|
||||
|
@ -73,6 +76,7 @@ class Preview extends React.Component {
|
|||
'handleSeeInside',
|
||||
'handleSetProjectThumbnailer',
|
||||
'handleShare',
|
||||
'handleUpdateProjectData',
|
||||
'handleUpdateProjectId',
|
||||
'handleUpdateProjectTitle',
|
||||
'handleToggleComments',
|
||||
|
@ -219,6 +223,84 @@ class Preview extends React.Component {
|
|||
this.props.getRemixes(this.state.projectId);
|
||||
}
|
||||
}
|
||||
|
||||
// This is copy of what is in save-project-to-server in GUI that adds
|
||||
// an extra get of the project info from api. We do this to wait for replication
|
||||
// lag to pass. This is intended to be a temporary fix until we use the data
|
||||
// from the create request to fill the projectInfo state.
|
||||
handleUpdateProjectData (projectId, vmState, params) {
|
||||
const opts = {
|
||||
body: vmState,
|
||||
// If we set json:true then the body is double-stringified, so don't
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
withCredentials: true
|
||||
};
|
||||
const creatingProject = projectId === null || typeof projectId === 'undefined';
|
||||
const queryParams = {};
|
||||
if (params.hasOwnProperty('originalId')) queryParams.original_id = params.originalId;
|
||||
if (params.hasOwnProperty('isCopy')) queryParams.is_copy = params.isCopy;
|
||||
if (params.hasOwnProperty('isRemix')) queryParams.is_remix = params.isRemix;
|
||||
if (params.hasOwnProperty('title')) queryParams.title = params.title;
|
||||
let qs = queryString.stringify(queryParams);
|
||||
if (qs) qs = `?${qs}`;
|
||||
if (creatingProject) {
|
||||
Object.assign(opts, {
|
||||
method: 'post',
|
||||
url: `${this.props.projectHost}/${qs}`
|
||||
});
|
||||
} else {
|
||||
Object.assign(opts, {
|
||||
method: 'put',
|
||||
url: `${this.props.projectHost}/${projectId}${qs}`
|
||||
});
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
xhr(opts, (err, response) => {
|
||||
if (err) return reject(err);
|
||||
if (response.statusCode !== 200) return reject(response.statusCode);
|
||||
let body;
|
||||
try {
|
||||
// Since we didn't set json: true, we have to parse manually
|
||||
body = JSON.parse(response.body);
|
||||
} catch (e) {
|
||||
return reject(e);
|
||||
}
|
||||
body.id = projectId;
|
||||
if (creatingProject) {
|
||||
body.id = body['content-name'];
|
||||
}
|
||||
resolve(body);
|
||||
});
|
||||
}).then(body => {
|
||||
const fetchProjectInfo = (count, resolve) => {
|
||||
api({
|
||||
uri: `/projects/${body.id}`,
|
||||
authentication: this.props.user.token
|
||||
}, (err, projectInfo, response) => {
|
||||
if (err) {
|
||||
log.error(`Could not fetch project after creating: ${err}`);
|
||||
return resolve(body);
|
||||
}
|
||||
if (typeof body === 'undefined' || response.statusCode === 404) {
|
||||
// Retry after 500ms, 1.5s, 3.5s, 7.5s and then stop.
|
||||
if (count > 4) {
|
||||
return resolve(body);
|
||||
}
|
||||
return setTimeout(
|
||||
fetchProjectInfo.bind(this, count + 1, resolve),
|
||||
500 * Math.pow(2, count));
|
||||
}
|
||||
return resolve(body);
|
||||
});
|
||||
};
|
||||
if (creatingProject) {
|
||||
return new Promise((resolve, reject) => fetchProjectInfo(1, resolve, reject));
|
||||
}
|
||||
return body;
|
||||
});
|
||||
}
|
||||
setScreenFromOrientation () {
|
||||
/*
|
||||
* If the user is on a mobile device, switching to
|
||||
|
@ -702,6 +784,7 @@ class Preview extends React.Component {
|
|||
onSocialClosed={this.handleSocialClose}
|
||||
onToggleComments={this.handleToggleComments}
|
||||
onToggleStudio={this.handleToggleStudio}
|
||||
onUpdateProjectData={this.handleUpdateProjectData}
|
||||
onUpdateProjectId={this.handleUpdateProjectId}
|
||||
onUpdateProjectThumbnail={this.props.handleUpdateProjectThumbnail}
|
||||
/>
|
||||
|
@ -739,6 +822,7 @@ class Preview extends React.Component {
|
|||
onSetLanguage={this.handleSetLanguage}
|
||||
onShare={this.handleShare}
|
||||
onToggleLoginOpen={this.props.handleToggleLoginOpen}
|
||||
onUpdateProjectData={this.handleUpdateProjectData}
|
||||
onUpdateProjectId={this.handleUpdateProjectId}
|
||||
onUpdateProjectThumbnail={this.props.handleUpdateProjectThumbnail}
|
||||
onUpdateProjectTitle={this.handleUpdateProjectTitle}
|
||||
|
|
Loading…
Reference in a new issue