Localize default project (temporary solution)
This commit is contained in:
1 parent
0b2b0843aa
commit
102d3d7e79
5 files changed
+209
-37
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import {TextEncoder} from 'text-encoding';
|
||||
import projectJson from './project.json';
|
||||
import projectData from './project-data';
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
import popWav from '!arraybuffer-loader!./83a9787d4cb6f3b7632b4ddfebf74367.wav';
|
||||
@@ -10,34 +10,39 @@ import costume2 from '!raw-loader!./3696356a03a8d938318876a593572843.svg';
|
||||
/* eslint-enable import/no-unresolved */
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
export default [{
|
||||
id: 0,
|
||||
assetType: 'Project',
|
||||
dataFormat: 'JSON',
|
||||
data: JSON.stringify(projectJson)
|
||||
}, {
|
||||
id: '83a9787d4cb6f3b7632b4ddfebf74367',
|
||||
assetType: 'Sound',
|
||||
dataFormat: 'WAV',
|
||||
data: new Uint8Array(popWav)
|
||||
}, {
|
||||
id: '83c36d806dc92327b9e7049a565c6bff',
|
||||
assetType: 'Sound',
|
||||
dataFormat: 'WAV',
|
||||
data: new Uint8Array(meowWav)
|
||||
}, {
|
||||
id: 'cd21514d0531fdffb22204e0ec5ed84a',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(backdrop)
|
||||
}, {
|
||||
id: '09dc888b0b7df19f70d81588ae73420e',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(costume1)
|
||||
}, {
|
||||
id: '3696356a03a8d938318876a593572843',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(costume2)
|
||||
}];
|
||||
const defaultProject = translator => {
|
||||
const projectJson = projectData(translator);
|
||||
return [{
|
||||
id: 0,
|
||||
assetType: 'Project',
|
||||
dataFormat: 'JSON',
|
||||
data: JSON.stringify(projectJson)
|
||||
}, {
|
||||
id: '83a9787d4cb6f3b7632b4ddfebf74367',
|
||||
assetType: 'Sound',
|
||||
dataFormat: 'WAV',
|
||||
data: new Uint8Array(popWav)
|
||||
}, {
|
||||
id: '83c36d806dc92327b9e7049a565c6bff',
|
||||
assetType: 'Sound',
|
||||
dataFormat: 'WAV',
|
||||
data: new Uint8Array(meowWav)
|
||||
}, {
|
||||
id: 'cd21514d0531fdffb22204e0ec5ed84a',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(backdrop)
|
||||
}, {
|
||||
id: '09dc888b0b7df19f70d81588ae73420e',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(costume1)
|
||||
}, {
|
||||
id: '3696356a03a8d938318876a593572843',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(costume2)
|
||||
}];
|
||||
};
|
||||
|
||||
export default defaultProject;
|
||||
@@ -0,0 +1,150 @@
|
||||
import {defineMessages} from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
backdrop: {
|
||||
defaultMessage: 'backdrop1',
|
||||
description: 'Default name for the first backdrop',
|
||||
id: 'gui.defaultProject.backdrop'
|
||||
},
|
||||
pop: {
|
||||
defaultMessage: 'pop',
|
||||
description: 'Default name for the pop sound',
|
||||
id: 'gui.defaultProject.pop'
|
||||
},
|
||||
sprite: {
|
||||
defaultMessage: 'Sprite1',
|
||||
description: 'Name for the default sprite',
|
||||
id: 'gui.defaultProject.sprite'
|
||||
},
|
||||
costume1: {
|
||||
defaultMessage: 'costume1',
|
||||
description: 'Name for the first default costume',
|
||||
id: 'gui.defaultProject.costume1'
|
||||
},
|
||||
costume2: {
|
||||
defaultMessage: 'costume2',
|
||||
description: 'Name for the second default costume',
|
||||
id: 'gui.defaultProject.costume2'
|
||||
},
|
||||
meow: {
|
||||
defaultMessage: 'Meow',
|
||||
description: 'Name for the meow sound',
|
||||
id: 'gui.defaultProject.meow'
|
||||
},
|
||||
variable: {
|
||||
defaultMessage: 'my variable',
|
||||
description: 'Name for the default variable',
|
||||
id: 'gui.defaultProject.variable'
|
||||
}
|
||||
});
|
||||
|
||||
// use the default message if a translation function is not passed
|
||||
const defaultTranslator = msgObj => msgObj.defaultMessage;
|
||||
|
||||
/**
|
||||
* Generate a localized version of the default project
|
||||
* @param {function} translateFunction a function to use for translating the default names
|
||||
* @return {json} the project data json for the default project
|
||||
*/
|
||||
const projectData = translateFunction => {
|
||||
const translator = translateFunction || defaultTranslator;
|
||||
return ({
|
||||
targets: [
|
||||
{
|
||||
isStage: true,
|
||||
name: 'Stage',
|
||||
variables: {
|
||||
'`jEk@4|i[#Fk?(8x)AV.-my variable': [
|
||||
translator(messages.variable),
|
||||
0
|
||||
]
|
||||
},
|
||||
lists: {},
|
||||
broadcasts: {},
|
||||
blocks: {},
|
||||
currentCostume: 0,
|
||||
costumes: [
|
||||
{
|
||||
assetId: 'cd21514d0531fdffb22204e0ec5ed84a',
|
||||
name: translator(messages.backdrop),
|
||||
md5ext: 'cd21514d0531fdffb22204e0ec5ed84a.svg',
|
||||
dataFormat: 'svg',
|
||||
rotationCenterX: 240,
|
||||
rotationCenterY: 180
|
||||
}
|
||||
],
|
||||
sounds: [
|
||||
{
|
||||
assetId: '83a9787d4cb6f3b7632b4ddfebf74367',
|
||||
name: translator(messages.pop),
|
||||
dataFormat: 'wav',
|
||||
format: '',
|
||||
rate: 11025,
|
||||
sampleCount: 258,
|
||||
md5ext: '83a9787d4cb6f3b7632b4ddfebf74367.wav'
|
||||
}
|
||||
],
|
||||
volume: 100,
|
||||
tempo: 60,
|
||||
videoTransparency: 50,
|
||||
videoState: 'off'
|
||||
},
|
||||
{
|
||||
isStage: false,
|
||||
name: translator(messages.sprite),
|
||||
variables: {},
|
||||
lists: {},
|
||||
broadcasts: {},
|
||||
blocks: {},
|
||||
currentCostume: 0,
|
||||
costumes: [
|
||||
{
|
||||
assetId: '09dc888b0b7df19f70d81588ae73420e',
|
||||
name: translator(messages.costume1),
|
||||
bitmapResolution: 1,
|
||||
md5ext: '09dc888b0b7df19f70d81588ae73420e.svg',
|
||||
dataFormat: 'svg',
|
||||
rotationCenterX: 47,
|
||||
rotationCenterY: 55
|
||||
},
|
||||
{
|
||||
assetId: '3696356a03a8d938318876a593572843',
|
||||
name: translator(messages.costume2),
|
||||
bitmapResolution: 1,
|
||||
md5ext: '3696356a03a8d938318876a593572843.svg',
|
||||
dataFormat: 'svg',
|
||||
rotationCenterX: 47,
|
||||
rotationCenterY: 55
|
||||
}
|
||||
],
|
||||
sounds: [
|
||||
{
|
||||
assetId: '83c36d806dc92327b9e7049a565c6bff',
|
||||
name: translator(messages.meow),
|
||||
dataFormat: 'wav',
|
||||
format: '',
|
||||
rate: 22050,
|
||||
sampleCount: 18688,
|
||||
md5ext: '83c36d806dc92327b9e7049a565c6bff.wav'
|
||||
}
|
||||
],
|
||||
volume: 100,
|
||||
visible: true,
|
||||
x: 0,
|
||||
y: 0,
|
||||
size: 100,
|
||||
direction: 90,
|
||||
draggable: false,
|
||||
rotationStyle: 'all around'
|
||||
}
|
||||
],
|
||||
meta: {
|
||||
semver: '3.0.0',
|
||||
vm: '0.1.0',
|
||||
agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36' // eslint-disable-line max-len
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export default projectData;
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {connect} from 'react-redux';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
|
||||
import {setProjectId} from '../reducers/project-id';
|
||||
|
||||
@@ -24,6 +25,7 @@ const ProjectLoaderHOC = function (WrappedComponent) {
|
||||
};
|
||||
storage.setProjectHost(props.projectHost);
|
||||
storage.setAssetHost(props.assetHost);
|
||||
storage.setTranslatorFunction(props.intl.formatMessage);
|
||||
props.setProjectId(props.projectId);
|
||||
if (
|
||||
props.projectId !== '' &&
|
||||
@@ -88,6 +90,7 @@ const ProjectLoaderHOC = function (WrappedComponent) {
|
||||
}
|
||||
ProjectLoaderComponent.propTypes = {
|
||||
assetHost: PropTypes.string,
|
||||
intl: intlShape.isRequired,
|
||||
projectHost: PropTypes.string,
|
||||
projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
setProjectId: PropTypes.func
|
||||
@@ -104,7 +107,7 @@ const ProjectLoaderHOC = function (WrappedComponent) {
|
||||
setProjectId: id => dispatch(setProjectId(id))
|
||||
});
|
||||
|
||||
return connect(mapStateToProps, mapDispatchToProps)(ProjectLoaderComponent);
|
||||
return injectIntl(connect(mapStateToProps, mapDispatchToProps)(ProjectLoaderComponent));
|
||||
};
|
||||
|
||||
export {
|
||||
|
||||
+15
-1
@@ -1,6 +1,6 @@
|
||||
import ScratchStorage from 'scratch-storage';
|
||||
|
||||
import defaultProjectAssets from './default-project';
|
||||
import defaultProject from './default-project';
|
||||
|
||||
/**
|
||||
* Wrapper for ScratchStorage which adds default web sources.
|
||||
@@ -9,6 +9,7 @@ import defaultProjectAssets from './default-project';
|
||||
class Storage extends ScratchStorage {
|
||||
constructor () {
|
||||
super();
|
||||
const defaultProjectAssets = defaultProject(this.translator);
|
||||
defaultProjectAssets.forEach(asset => this.cache(
|
||||
this.AssetType[asset.assetType],
|
||||
this.DataFormat[asset.dataFormat],
|
||||
@@ -54,6 +55,19 @@ class Storage extends ScratchStorage {
|
||||
getAssetGetConfig (asset) {
|
||||
return `${this.assetHost}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`;
|
||||
}
|
||||
setTranslatorFunction (translator) {
|
||||
this.translator = translator;
|
||||
this.cacheDefaultProject();
|
||||
}
|
||||
cacheDefaultProject () {
|
||||
const defaultProjectAssets = defaultProject(this.translator);
|
||||
defaultProjectAssets.forEach(asset => this.cache(
|
||||
this.AssetType[asset.assetType],
|
||||
this.DataFormat[asset.dataFormat],
|
||||
asset.data,
|
||||
asset.id
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
const storage = new Storage();
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import ProjectLoaderHOC from '../../../src/lib/project-loader-hoc.jsx';
|
||||
import storage from '../../../src/lib/storage';
|
||||
import {mount} from 'enzyme';
|
||||
import {mountWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||
|
||||
jest.mock('react-ga');
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('ProjectLoaderHOC', () => {
|
||||
const WrappedComponent = ProjectLoaderHOC(Component);
|
||||
const originalLoad = storage.load;
|
||||
storage.load = jest.fn((type, id) => Promise.resolve({data: id}));
|
||||
const mounted = mount(
|
||||
const mounted = mountWithIntl(
|
||||
<WrappedComponent
|
||||
projectId="100"
|
||||
store={store}
|
||||
@@ -37,7 +37,7 @@ describe('ProjectLoaderHOC', () => {
|
||||
const WrappedComponent = ProjectLoaderHOC(Component);
|
||||
const originalLoad = storage.load;
|
||||
storage.load = jest.fn(() => Promise.resolve(null));
|
||||
const mounted = mount(<WrappedComponent store={store} />);
|
||||
const mounted = mountWithIntl(<WrappedComponent store={store} />);
|
||||
storage.load = originalLoad;
|
||||
const mountedDiv = mounted.find('div');
|
||||
expect(mountedDiv.exists()).toEqual(false);
|
||||
|
||||
Reference in new issue
Block a user