From 2812720be6d24d81cf0b0d94d53a50b20cfe3126 Mon Sep 17 00:00:00 2001 From: Ray Schamp Date: Mon, 10 Dec 2018 18:21:28 -0500 Subject: [PATCH] Manually save using xhr Resolves #3950. Unfortunately the design of scratch-storage doesn't make having multiple distinct POST urls easy at the moment. So for the time being, just make this request ourselves. --- src/lib/project-saver-hoc.jsx | 51 +++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/lib/project-saver-hoc.jsx b/src/lib/project-saver-hoc.jsx index df1dce40dd9..744316abcb9 100644 --- a/src/lib/project-saver-hoc.jsx +++ b/src/lib/project-saver-hoc.jsx @@ -1,8 +1,10 @@ import bindAll from 'lodash.bindall'; import React from 'react'; import PropTypes from 'prop-types'; +import queryString from 'query-string'; import {connect} from 'react-redux'; import VM from 'scratch-vm'; +import xhr from 'xhr'; import log from '../lib/log'; import storage from '../lib/storage'; @@ -209,18 +211,45 @@ const ProjectSaverHOC = function (WrappedComponent) { ) ) ).then(() => { - const body = new FormData(); - const sb3Json = new Blob([this.props.vm.toJSON()], {type: 'application/json'}); - body.append('sb3_file', sb3Json, 'sb3_file'); - for (const key in requestParams) { - if (requestParams.hasOwnProperty(key)) body.append(key, requestParams[key]); + const opts = { + body: this.props.vm.toJSON(), + // 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'; + let qs = queryString.stringify(requestParams); + if (qs) qs = `?${qs}`; + if (creatingProject) { + Object.assign(opts, { + method: 'post', + url: `${storage.projectHost}/${qs}` + }); + } else { + Object.assign(opts, { + method: 'put', + url: `${storage.projectHost}/${projectId}${qs}` + }); } - return storage.store( - storage.AssetType.Project, - storage.DataFormat.JSON, - body, - projectId - ); + return new Promise((resolve, reject) => { + xhr(opts, (err, response) => { + if (err) return reject(err); + 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(response => { this.props.onSetProjectUnchanged();