Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b5eb032ad | ||
|
|
8d3a85860e | ||
|
|
cbb265e9f0 | ||
|
|
948fb2f747 | ||
|
|
b0ca6dfcaa | ||
|
|
61eb31ea66 | ||
|
|
b5a3a53780 | ||
|
|
a6302ecc14 | ||
|
|
2a9d74adb4 | ||
|
|
e5772a5902 | ||
|
|
f7244e6c89 | ||
|
|
1476c88a54 | ||
|
|
c061f2e2f0 | ||
|
|
dc49c0ebe4 | ||
|
|
11d4273982 | ||
|
|
7755f76215 | ||
|
|
6e44bfea95 | ||
|
|
fa8ceacbcf | ||
|
|
d19c468336 | ||
|
|
86edd829c0 | ||
|
|
bdc9c1e7de | ||
|
|
6e007b1e4a | ||
|
|
356c1d9811 | ||
|
|
723a2bf117 | ||
|
|
7b7e5e6e72 | ||
|
|
3fcbf74c71 | ||
|
|
8f4a6ce255 | ||
|
|
9e0853aa9a | ||
|
|
c4480b9ade | ||
|
|
1a588880bf | ||
|
|
e2c2392a70 | ||
|
|
5160b5ae22 | ||
|
|
8be847b68a | ||
|
|
e7ed24f1ef | ||
|
|
13e324b52d | ||
|
|
5c7b221799 | ||
|
|
7398a30223 | ||
|
|
637b9fd225 | ||
|
|
88442708c2 | ||
|
|
d7759317c4 | ||
|
|
fd3045eb9d | ||
|
|
09ae22f329 | ||
|
|
365e3b3bce | ||
|
|
a6fe8585fb | ||
|
|
930b2ec05c | ||
|
|
c9d1535967 | ||
|
|
550849c93f | ||
|
|
8128902cd6 | ||
|
|
b350049ca7 | ||
|
|
e0e07929e8 | ||
|
|
128b196220 | ||
|
|
5b806dff27 | ||
|
|
9c5d358c3e | ||
|
|
ab89ee1a4f | ||
|
|
dc82e5f653 | ||
|
|
7fb3a81a66 | ||
|
|
d958b14b8d | ||
|
|
0a6c75eb93 | ||
|
|
7c5a4fc682 | ||
|
|
ca8caa8504 | ||
|
|
339dfe0b08 | ||
|
|
b9cefd325b | ||
|
|
fa974c68bd | ||
|
|
3c47e0e040 | ||
|
|
34a9a97201 | ||
|
|
f6847e3aea | ||
|
|
e27021cbf4 | ||
|
|
3dc6413ea4 | ||
|
|
53c04a1ad9 | ||
|
|
b2486380fb | ||
|
|
9f41ddaaa2 | ||
|
|
ef4d8c6e8d | ||
|
|
a6245b87f6 | ||
|
|
fa4541e85c | ||
|
|
376f5626a4 | ||
|
|
e17dc90983 | ||
|
|
a63385343a | ||
|
|
3c3206d8e2 | ||
|
|
f6c8feae6e | ||
|
|
98a007a17e | ||
|
|
3e0d5b9ede | ||
|
|
555082bb1d | ||
|
|
5c95c352c3 | ||
|
|
3b4758ca5c | ||
|
|
38455a7108 | ||
|
|
ebe310bc65 | ||
|
|
5bc3198263 | ||
|
|
5d6669db6d | ||
|
|
519ffe3b91 | ||
|
|
717c773800 | ||
|
|
935a4520da | ||
|
|
7685dad40a | ||
|
|
699671bde5 | ||
|
|
7facbf35b2 | ||
|
|
b54fe54b4a | ||
|
|
796339dcfe | ||
|
|
1721a322c2 | ||
|
|
3125097b83 | ||
|
|
aa0c40fca1 | ||
|
|
2d61027bbe | ||
|
|
2dac3cae81 | ||
|
|
43d3df2ffd | ||
|
|
44ffaeee2c | ||
|
|
0bf4e2c781 | ||
|
|
d342b82219 | ||
|
|
227581ebcf | ||
|
|
eb74d6c033 | ||
|
|
a2035a68e4 | ||
|
|
1b055af545 | ||
|
|
5b79947178 | ||
|
|
9e329b999e | ||
|
|
e5e0c3dd28 | ||
|
|
e810422429 | ||
|
|
8b2c590309 | ||
|
|
d92ef0c807 | ||
|
|
faa14b7add | ||
|
|
abbc8ddad0 | ||
|
|
551e03b256 | ||
|
|
f65f80160f | ||
|
|
5438c14bdb | ||
|
|
8f3d84ec60 | ||
|
|
c3df930bea | ||
|
|
4513a45306 | ||
|
|
a94a83dc4f | ||
|
|
e1e5c8352c | ||
|
|
98ceb00bb4 | ||
|
|
77974839b0 | ||
|
|
706341011a | ||
|
|
4a26810956 | ||
|
|
92fd318aa8 | ||
|
|
bc2555ddc4 | ||
|
|
8ee9794304 | ||
|
|
30388ffa4f | ||
|
|
fdea0a1620 | ||
|
|
41e2909782 | ||
|
|
4048ed8c84 | ||
|
|
7a21b17d0c | ||
|
|
72bc6f3005 | ||
|
|
a8a7e0c92f | ||
|
|
a11fcfe373 | ||
|
|
52a3600819 | ||
|
|
bec6223e6e | ||
|
|
333b91ccfd | ||
|
|
a3266fe641 | ||
|
|
10449a21b5 | ||
|
|
29f5d2a872 | ||
|
|
f8b3e4961c | ||
|
|
cca701e954 | ||
|
|
89c0807cba | ||
|
|
544a4c745d | ||
|
|
f6e9a7dd23 | ||
|
|
69132b6f43 | ||
|
|
aa88e2c6a6 | ||
|
|
b89734b0e9 | ||
|
|
d5eb058d00 | ||
|
|
fe308b6b58 | ||
|
|
ab14942c80 | ||
|
|
908cb2e5c6 | ||
|
|
6935aa0820 | ||
|
|
4ec8ac16a8 | ||
|
|
bfe2877d0b | ||
|
|
9d50e9a165 | ||
|
|
eb496cfe75 | ||
|
|
dfd01da913 | ||
|
|
c8bdb6ce09 | ||
|
|
3169c03e66 | ||
|
|
26323cccf2 | ||
|
|
2bb9a61539 | ||
|
|
4efd3fcbad | ||
|
|
170705440a | ||
|
|
a52fdaa032 | ||
|
|
6d972da227 | ||
|
|
96bd677ef9 | ||
|
|
b77bc7a8b4 | ||
|
|
7f06f55f83 | ||
|
|
04381439c2 | ||
|
|
7b658c60c7 | ||
|
|
0c68103eb6 | ||
|
|
65c787d0da | ||
|
|
0b40daf936 | ||
|
|
75607ebbe3 | ||
|
|
58b178f679 | ||
|
|
ffeebb03bd | ||
|
|
7c1f0d2739 | ||
|
|
ac0c6a4305 | ||
|
|
ff776dc90c | ||
|
|
516baedad9 | ||
|
|
d83ec5a0b5 | ||
|
|
1c8ba1d1eb | ||
|
|
16024769c8 | ||
|
|
ed9316266e | ||
|
|
103f55bd6e | ||
|
|
009d9db74f | ||
|
|
416bc85455 | ||
|
|
88a5ab8052 | ||
|
|
31454f7ca0 | ||
|
|
bfd0712c83 | ||
|
|
3c9d482a02 | ||
|
|
5c3694ec19 | ||
|
|
997abfeb27 | ||
|
|
df77245f0d | ||
|
|
5e2ea2ee64 | ||
|
|
655af4ed31 | ||
|
|
9d385faa84 | ||
|
|
455808fe26 | ||
|
|
c2dbdc6279 | ||
|
|
8faf8af5da | ||
|
|
cfaf1ee049 | ||
|
|
29d9bb0d41 | ||
|
|
9d185bd6c8 | ||
|
|
7c26245c53 | ||
|
|
4dc3f73e74 | ||
|
|
1a66060aa2 | ||
|
|
cf9e165ccf | ||
|
|
e877486daa | ||
|
|
1eb095e235 | ||
|
|
905e938c57 | ||
|
|
fe8b914f8d | ||
|
|
a48cc065c0 | ||
|
|
6e50909e0f | ||
|
|
6480b262de | ||
|
|
a0745e4f40 | ||
|
|
8eb9e37d67 | ||
|
|
69506d9c1d | ||
|
|
d37f1fcae1 | ||
|
|
dfb7b55145 | ||
|
|
6e335085d1 | ||
|
|
cde9660b12 | ||
|
|
abe782cdba | ||
|
|
96f3377733 | ||
|
|
e43011233f | ||
|
|
7c4d92ac08 | ||
|
|
3033717d67 | ||
|
|
5a2bec60d9 | ||
|
|
7e2f9b8361 | ||
|
|
5c1d3e38bd | ||
|
|
f8243eae9e | ||
|
|
14ead16a8a | ||
|
|
c064eaed4e | ||
|
|
5758626777 | ||
|
|
934396d87a | ||
|
|
130c5de4b0 | ||
|
|
09bcfba800 | ||
|
|
cb928b8490 | ||
|
|
4aba90c8fb | ||
|
|
308568a332 | ||
|
|
c87560aabc | ||
|
|
13f72153a3 | ||
|
|
b435ac3101 | ||
|
|
0d7a05d37a | ||
|
|
0fbbf55b51 | ||
|
|
a9c624b746 | ||
|
|
0caee112e0 | ||
|
|
17e28b2a24 | ||
|
|
7fcbae60bc | ||
|
|
9aabea4065 | ||
|
|
8a1b104f28 | ||
|
|
8f35eacf9f | ||
|
|
327983fc8c | ||
|
|
57ede34c29 | ||
|
|
d76eacd7e5 | ||
|
|
32f9ae614c | ||
|
|
490c56e46e | ||
|
|
c5290a2640 | ||
|
|
00f07c3801 | ||
|
|
a441cbbe60 | ||
|
|
8656148a91 | ||
|
|
b32e0ca6d7 | ||
|
|
5b4daec4ab | ||
|
|
aed66d49cf | ||
|
|
5d5331b0ad | ||
|
|
83b48a683a | ||
|
|
93477a19d6 | ||
|
|
a87b08d791 | ||
|
|
494269bcf5 | ||
|
|
c684774f06 | ||
|
|
9296438911 | ||
|
|
e9a9767f67 | ||
|
|
174bd295e1 | ||
|
|
57a9e0b8ca | ||
|
|
e89a8eab11 | ||
|
|
98274c8b8e | ||
|
|
c8617289bc | ||
|
|
e82e370e83 | ||
|
|
e2adf9bf14 | ||
|
|
881e17dc67 | ||
|
|
021063470d | ||
|
|
2b5196106a | ||
|
|
628bc2cd26 | ||
|
|
6d5a6d407b | ||
|
|
ce6df3633a | ||
|
|
fecc6f4f6f | ||
|
|
839deda612 | ||
|
|
dac1ece8fd | ||
|
|
fc8c242173 | ||
|
|
866af2f766 | ||
|
|
4fab686aea | ||
|
|
bfae437886 | ||
|
|
c9a989bfab | ||
|
|
9bd2ca246b | ||
|
|
f2b9732748 | ||
|
|
fda637edba | ||
|
|
a8ea46a357 | ||
|
|
37826cb901 | ||
|
|
6fec13c941 | ||
|
|
656e8c2c77 | ||
|
|
f86fd4995f | ||
|
|
596bdad97a | ||
|
|
2522ad378a | ||
|
|
09d9b51c20 | ||
|
|
3f73c6df7b | ||
|
|
fb85d6ab51 | ||
|
|
97b056ea87 | ||
|
|
05027a5aee | ||
|
|
f5d1dd7e03 | ||
|
|
e0f8497b48 | ||
|
|
0abb94bc81 | ||
|
|
66b3f43581 | ||
|
|
e0db28d82b | ||
|
|
cf86e4c432 | ||
|
|
28cd140d9f | ||
|
|
00a4db1213 | ||
|
|
5f6b89ec2a | ||
|
|
a4cb3b1eb5 | ||
|
|
8e3bd8c631 | ||
|
|
a74bb9afc7 | ||
|
|
a082d8329e | ||
|
|
9f9a780093 | ||
|
|
8c36ad3cc2 | ||
|
|
1b2555c7de | ||
|
|
996ed08908 | ||
|
|
1a194a13e6 | ||
|
|
634c780ce1 | ||
|
|
7709580710 | ||
|
|
db487efd62 | ||
|
|
b26ac6d62b | ||
|
|
e5ba46f499 | ||
|
|
2d1638e909 | ||
|
|
437106fa33 | ||
|
|
1fd9a1f689 | ||
|
|
33f3d1d79b | ||
|
|
5051ba2105 | ||
|
|
551b7b98ce | ||
|
|
a3e8dd1aab | ||
|
|
bb0e1e54cd | ||
|
|
98ec67d728 | ||
|
|
f773ee2dab | ||
|
|
a7487fb26d | ||
|
|
3adacd3f2a | ||
|
|
1dd3e1d26a | ||
|
|
ce5aa9fb7a | ||
|
|
846a174f13 | ||
|
|
c779c5fe77 | ||
|
|
e2a2dcf0fd | ||
|
|
3e33c10b04 | ||
|
|
f0ba4180c7 | ||
|
|
f6b9f11d3b | ||
|
|
d71a9114b7 | ||
|
|
5c4f50c1b8 | ||
|
|
4d671ddfab | ||
|
|
94901b33fe | ||
|
|
f6dc2726b5 | ||
|
|
7b4c0657c6 | ||
|
|
39279fa0ef | ||
|
|
5f2f95a6db | ||
|
|
790fc13157 | ||
|
|
face0d20d4 | ||
|
|
5c16407818 | ||
|
|
d8201fd4ad | ||
|
|
2b1cd4951d | ||
|
|
849fe8fc0c | ||
|
|
f600e6095e | ||
|
|
d952f774dd | ||
|
|
38ee27d896 | ||
|
|
73e1bc352b | ||
|
|
46ce75bf2a | ||
|
|
2c285fee8a | ||
|
|
d1c3cf8bb0 | ||
|
|
a09c7ddb53 | ||
|
|
fec81c93a3 | ||
|
|
2b3c70dfc3 | ||
|
|
db9236bef2 | ||
|
|
fb383ee5f5 | ||
|
|
3a33e7ea86 | ||
|
|
8e51409e20 | ||
|
|
f29b82b636 | ||
|
|
31625d6807 | ||
|
|
dadef73bfa | ||
|
|
268ad88281 | ||
|
|
51f9aafec1 | ||
|
|
6ea53f63ae | ||
|
|
e746b98d83 | ||
|
|
f72d0b5985 | ||
|
|
832dabbb51 | ||
|
|
c5b5931e11 | ||
|
|
f0e518df8a | ||
|
|
158409d4d8 | ||
|
|
abf49b3115 | ||
|
|
4af0d9fe27 | ||
|
|
a627552c8e | ||
|
|
127e1a9632 | ||
|
|
438e0f9cf7 | ||
|
|
1e532745b7 | ||
|
|
db811553c9 | ||
|
|
ef05591d20 | ||
|
|
c83d85e368 | ||
|
|
d8d39b1d61 | ||
|
|
f364994a46 | ||
|
|
9273612f99 | ||
|
|
880bc530b7 | ||
|
|
c109c10db6 | ||
|
|
5258254562 | ||
|
|
43a0ed8635 | ||
|
|
f2122bab42 | ||
|
|
c29e943c6b | ||
|
|
d3cc72db4d | ||
|
|
b2b4da2f68 | ||
|
|
782fc9aebf | ||
|
|
7c557db8b4 | ||
|
|
b76593cabb | ||
|
|
ced6e8df18 | ||
|
|
0ea314d98a | ||
|
|
fe00c71d28 | ||
|
|
22d96ca94b | ||
|
|
08ec713bff | ||
|
|
e9c9758618 | ||
|
|
e51ec837e8 | ||
|
|
6468395ba5 | ||
|
|
686dbb5245 | ||
|
|
8783d1dfa7 | ||
|
|
c6ab3c8e42 | ||
|
|
26de4b2e51 | ||
|
|
0dd0fd8e7a | ||
|
|
8fcfe7c7d7 | ||
|
|
2de31ba0ed | ||
|
|
742e9e327a | ||
|
|
9efcadad5d | ||
|
|
a4ea94bd39 | ||
|
|
60f2f85734 | ||
|
|
6d5183f99d | ||
|
|
3b340d02af | ||
|
|
2ab48e011e | ||
|
|
ce82a52fce | ||
|
|
9a2990f301 | ||
|
|
d431c3f8ba | ||
|
|
2d3632b014 | ||
|
|
d301794463 | ||
|
|
1a2c3bd0b7 | ||
|
|
9977ec63d5 | ||
|
|
0f803dfc41 | ||
|
|
6f101523b4 | ||
|
|
e3dbf435da | ||
|
|
215019262b | ||
|
|
40a5ff783a | ||
|
|
1cfccde0c4 | ||
|
|
0b557ab520 | ||
|
|
2c6519a129 | ||
|
|
1aa241749b | ||
|
|
ac0705c12c | ||
|
|
96668b5b04 | ||
|
|
65642edc15 | ||
|
|
86b6e12453 |
No files matched your search
@@ -25,6 +25,7 @@ before_deploy:
|
||||
if [ -z "$BEFORE_DEPLOY_RAN" ]; then
|
||||
npm --no-git-tag-version version $RELEASE_VERSION
|
||||
if [ "$TRAVIS_BRANCH" == "master" ]; then export NPM_TAG=stable; fi
|
||||
if [[ "$TRAVIS_BRANCH" == hotfix/* ]]; then export NPM_TAG=hotfix; fi # double brackets are important for matching the wildcard
|
||||
git config --global user.email $(git log --pretty=format:"%ae" -n1)
|
||||
git config --global user.name $(git log --pretty=format:"%an" -n1)
|
||||
export BEFORE_DEPLOY_RAN=true
|
||||
@@ -36,6 +37,7 @@ deploy:
|
||||
- master
|
||||
- develop
|
||||
- smoke
|
||||
- hotfix/*
|
||||
condition: $TRAVIS_EVENT_TYPE != cron
|
||||
skip_cleanup: true
|
||||
email: $NPM_EMAIL
|
||||
@@ -65,7 +67,7 @@ deploy:
|
||||
- provider: script
|
||||
on:
|
||||
all_branches: true
|
||||
condition: $TRAVIS_EVENT_TYPE != cron
|
||||
condition: $TRAVIS_EVENT_TYPE != cron && ! $TRAVIS_BRANCH =~ ^greenkeeper/
|
||||
skip_cleanup: true
|
||||
script: npm run deploy -- -x -e $TRAVIS_BRANCH -r https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git
|
||||
- provider: script
|
||||
|
||||
@@ -30,29 +30,38 @@ Then go to [http://localhost:8601/](http://localhost:8601/) - the playground out
|
||||
|
||||
## Developing alongside other Scratch repositories
|
||||
|
||||
### Linking this code to another project's `node_modules/scratch-gui`
|
||||
### Getting another repo to point to this code
|
||||
|
||||
|
||||
If you wish to develop `scratch-gui` alongside other scratch repositories that depend on it, you may wish
|
||||
to have the other repositories use your local `scratch-gui` build instead of fetching the current production
|
||||
version of the scratch-gui that is found by default using `npm install`.
|
||||
|
||||
Here's how to link your local `scratch-gui` code to another project's `node_modules/scratch-gui`.
|
||||
|
||||
#### Configuration
|
||||
|
||||
If you wish to develop scratch-gui alongside other scratch repositories that depend on it, you may wish
|
||||
to have the other repositories use your local scratch-gui build instead of fetching the current production
|
||||
version of the scratch-gui that is found by default using `npm install`.
|
||||
1. In your local `scratch-gui` repository's top level:
|
||||
1. Make sure you have run `npm install`
|
||||
2. Build the `dist` directory by running `BUILD_MODE=dist npm run build`
|
||||
3. Establish a link to this repository by running `npm link`
|
||||
|
||||
To do this:
|
||||
1. Make sure you have run `npm install` from this (scratch-gui) repository's top level
|
||||
2. Make sure you have run `npm install` from the top level of each repository (such as scratch-www) that depends on scratch-gui
|
||||
3. From this (scratch-gui) repository's top level, build the `dist` directory by running `BUILD_MODE=dist npm run build`
|
||||
4. From this (scratch-gui) repository's top level, establish a link to this repository by running `npm link`
|
||||
5. From the top level of each repository that depends on scratch-gui, run `npm link scratch-gui`
|
||||
6. Build or run the repositories that depend on scratch-gui
|
||||
2. From the top level of each repository (such as `scratch-www`) that depends on `scratch-gui`:
|
||||
1. Make sure you have run `npm install`
|
||||
2. Run `npm link scratch-gui`
|
||||
3. Build or run the repositoriy
|
||||
|
||||
Instead of `BUILD_MODE=dist npm run build` you can also use `BUILD_MODE=dist npm run watch`, however this may be unreliable.
|
||||
#### Using `npm run watch`
|
||||
|
||||
Instead of `BUILD_MODE=dist npm run build`, you can use `BUILD_MODE=dist npm run watch` instead. This will watch for changes to your `scratch-gui` code, and automatically rebuild when there are changes. Sometimes this has been unreliable; if you are having problems, try going back to `BUILD_MODE=dist npm run build` until you resolve them.
|
||||
|
||||
#### Oh no! It didn't work!
|
||||
* Follow the recipe above step by step and don't change the order. It is especially important to run npm first because installing after the linking will reset the linking.
|
||||
* Make sure the repositories are siblings on your machine's file tree.
|
||||
* If you have multiple Terminal tabs or windows open for the different Scratch repositories, make sure to use the same node version in all of them.
|
||||
* In the worst case unlink the repositories by running `npm unlink` in both, and start over.
|
||||
|
||||
If you can't get linking to work right, try:
|
||||
* Follow the recipe above step by step and don't change the order. It is especially important to run `npm install` _before_ `npm link`, because installing after the linking will reset the linking.
|
||||
* Make sure the repositories are siblings on your machine's file tree, like `.../.../MY_SCRATCH_DEV_DIRECTORY/scratch-gui/` and `.../.../MY_SCRATCH_DEV_DIRECTORY/scratch-www/`.
|
||||
* Consistent node.js version: If you have multiple Terminal tabs or windows open for the different Scratch repositories, make sure to use the same node version in all of them.
|
||||
* If nothing else works, unlink the repositories by running `npm unlink` in both, and start over.
|
||||
|
||||
## Testing
|
||||
### Documentation
|
||||
@@ -121,6 +130,66 @@ If you want to watch the browser as it runs the test, rather than running headle
|
||||
USE_HEADLESS=no $(npm bin)/jest --runInBand test/integration/backpack.test.js
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Ignoring optional dependencies
|
||||
|
||||
When running `npm install`, you can get warnings about optionsl dependencies:
|
||||
|
||||
```
|
||||
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
|
||||
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.2.7
|
||||
```
|
||||
|
||||
You can suppress them by adding the `no-optional` switch:
|
||||
|
||||
```
|
||||
npm install --no-optional
|
||||
```
|
||||
|
||||
Further reading: [Stack Overflow](https://stackoverflow.com/questions/36725181/not-compatible-with-your-operating-system-or-architecture-fsevents1-0-11)
|
||||
|
||||
### Resolving dependencies
|
||||
|
||||
When installing for the first time, you can get warnings which need to be resolved:
|
||||
|
||||
```
|
||||
npm WARN eslint-config-scratch@5.0.0 requires a peer of babel-eslint@^8.0.1 but none was installed.
|
||||
npm WARN eslint-config-scratch@5.0.0 requires a peer of eslint@^4.0 but none was installed.
|
||||
npm WARN scratch-paint@0.2.0-prerelease.20190318170811 requires a peer of react-intl-redux@^0.7 but none was installed.
|
||||
npm WARN scratch-paint@0.2.0-prerelease.20190318170811 requires a peer of react-responsive@^4 but none was installed.
|
||||
```
|
||||
|
||||
You can check which versions are available:
|
||||
|
||||
```
|
||||
npm view react-intl-redux@0.* version
|
||||
```
|
||||
|
||||
You will neet do install the required version:
|
||||
|
||||
```
|
||||
npm install --no-optional --save-dev react-intl-redux@^0.7
|
||||
```
|
||||
|
||||
The dependency itself might have more missing dependencies, which will show up like this:
|
||||
|
||||
```
|
||||
user@machine:~/sources/scratch/scratch-gui (491-translatable-library-objects)$ npm install --no-optional --save-dev react-intl-redux@^0.7
|
||||
scratch-gui@0.1.0 /media/cuideigin/Linux/sources/scratch/scratch-gui
|
||||
├── react-intl-redux@0.7.0
|
||||
└── UNMET PEER DEPENDENCY react-responsive@5.0.0
|
||||
```
|
||||
|
||||
You will need to install those as well:
|
||||
|
||||
```
|
||||
npm install --no-optional --save-dev react-responsive@^5.0.0
|
||||
```
|
||||
|
||||
Further reading: [Stack Overflow](https://stackoverflow.com/questions/46602286/npm-requires-a-peer-of-but-all-peers-are-in-package-json-and-node-modules)
|
||||
|
||||
|
||||
## Publishing to GitHub Pages
|
||||
You can publish the GUI to github.io so that others on the Internet can view it.
|
||||
[Read the wiki for a step-by-step guide.](https://github.com/LLK/scratch-gui/wiki/Publishing-to-GitHub-Pages)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"babel-loader": "^8.0.4",
|
||||
"base64-loader": "1.0.0",
|
||||
"bowser": "1.9.4",
|
||||
"chromedriver": "2.44.1",
|
||||
"chromedriver": "74.0.0",
|
||||
"classnames": "2.2.6",
|
||||
"computed-style-to-inline-style": "3.0.0",
|
||||
"copy-webpack-plugin": "^4.5.1",
|
||||
@@ -56,7 +56,7 @@
|
||||
"eslint": "^5.0.1",
|
||||
"eslint-config-scratch": "^5.0.0",
|
||||
"eslint-plugin-import": "^2.8.0",
|
||||
"eslint-plugin-react": "7.11.1",
|
||||
"eslint-plugin-react": "^7.12.4",
|
||||
"file-loader": "2.0.0",
|
||||
"get-float-time-domain-data": "0.1.0",
|
||||
"get-user-media-promise": "1.1.4",
|
||||
@@ -90,7 +90,7 @@
|
||||
"react-dom": "16.2.0",
|
||||
"react-draggable": "3.0.5",
|
||||
"react-ga": "2.5.3",
|
||||
"react-intl": "2.4.0",
|
||||
"react-intl": "2.9.0",
|
||||
"react-modal": "3.6.1",
|
||||
"react-popover": "0.5.10",
|
||||
"react-redux": "5.0.7",
|
||||
@@ -105,13 +105,13 @@
|
||||
"redux-throttle": "0.1.1",
|
||||
"rimraf": "^2.6.1",
|
||||
"scratch-audio": "0.1.0-prerelease.20190114210212",
|
||||
"scratch-blocks": "0.1.0-prerelease.1549990124",
|
||||
"scratch-l10n": "3.1.20190213142844",
|
||||
"scratch-paint": "0.2.0-prerelease.20190114205252",
|
||||
"scratch-render": "0.1.0-prerelease.20190213183713",
|
||||
"scratch-storage": "1.2.2",
|
||||
"scratch-svg-renderer": "0.2.0-prerelease.20190125192231",
|
||||
"scratch-vm": "0.2.0-prerelease.20190213190040",
|
||||
"scratch-l10n": "3.3.20190619145905",
|
||||
"scratch-blocks": "0.1.0-prerelease.1559136797",
|
||||
"scratch-paint": "0.2.0-prerelease.20190524133325",
|
||||
"scratch-render": "0.1.0-prerelease.20190605151415",
|
||||
"scratch-storage": "1.3.2",
|
||||
"scratch-svg-renderer": "0.2.0-prerelease.20190523193400",
|
||||
"scratch-vm": "0.2.0-prerelease.20190610152034",
|
||||
"selenium-webdriver": "3.6.0",
|
||||
"startaudiocontext": "1.2.1",
|
||||
"style-loader": "^0.23.0",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
color: $ui-white;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
font-size: .8125rem;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,18 @@
|
||||
@import "../../css/colors.css";
|
||||
@import "../../css/z-index.css";
|
||||
|
||||
.card-container-overlay {
|
||||
position: fixed;
|
||||
pointer-events: none;
|
||||
z-index: $z-index-card;
|
||||
}
|
||||
|
||||
.card-container {
|
||||
position:absolute;
|
||||
pointer-events: auto;
|
||||
z-index: $z-index-card;
|
||||
margin: 0.5rem 2rem;
|
||||
min-width: 468px;
|
||||
}
|
||||
|
||||
.left-card, .right-card {
|
||||
@@ -104,11 +112,38 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-buttons-hidden {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
.header-buttons-right {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.header-buttons img {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.shrink-expand-button {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.shrink-expand-button:hover, .all-button:hover {
|
||||
background-color: $ui-black-transparent;
|
||||
}
|
||||
|
||||
.remove-button, .all-button {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.75rem;
|
||||
@@ -127,6 +162,7 @@
|
||||
}
|
||||
|
||||
.step-body {
|
||||
width: 100%;
|
||||
background: $ui-white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -137,11 +173,13 @@
|
||||
}
|
||||
|
||||
.step-video {
|
||||
height: 337px;
|
||||
height: 256px;
|
||||
}
|
||||
|
||||
.step-image {
|
||||
max-width: 450px;
|
||||
max-height: 200px;
|
||||
object-fit: contain;
|
||||
background: #F9F9F9;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 0.5rem;
|
||||
@@ -188,7 +226,7 @@
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
height: 1rem;
|
||||
height: 1.25rem;
|
||||
margin: .125rem 0; /* To offset the .25rem difference in icon size */
|
||||
}
|
||||
|
||||
@@ -240,14 +278,6 @@
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.video-cover {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.steps-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -267,3 +297,7 @@
|
||||
background: $ui-white;
|
||||
box-shadow: 0px 0px 0px 2px $ui-black-transparent;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Fragment} from 'react';
|
||||
import classNames from 'classnames';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import Draggable from 'react-draggable';
|
||||
|
||||
import styles from './card.css';
|
||||
|
||||
import shrinkIcon from './icon--shrink.svg';
|
||||
import expandIcon from './icon--expand.svg';
|
||||
|
||||
import rightArrow from './icon--next.svg';
|
||||
import leftArrow from './icon--prev.svg';
|
||||
|
||||
@@ -12,9 +16,10 @@ import helpIcon from '../../lib/assets/icon--tutorials.svg';
|
||||
import closeIcon from './icon--close.svg';
|
||||
|
||||
import {translateVideo} from '../../lib/libraries/decks/translate-video.js';
|
||||
import {translateImage} from '../../lib/libraries/decks/translate-image.js';
|
||||
|
||||
const CardHeader = ({onCloseCards, onShowAll, totalSteps, step}) => (
|
||||
<div className={styles.headerButtons}>
|
||||
const CardHeader = ({onCloseCards, onShrinkExpandCards, onShowAll, totalSteps, step, expanded}) => (
|
||||
<div className={expanded ? styles.headerButtons : classNames(styles.headerButtons, styles.headerButtonsHidden)}>
|
||||
<div
|
||||
className={styles.allButton}
|
||||
onClick={onShowAll}
|
||||
@@ -40,49 +45,104 @@ const CardHeader = ({onCloseCards, onShowAll, totalSteps, step}) => (
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
<div
|
||||
className={styles.removeButton}
|
||||
onClick={onCloseCards}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Close"
|
||||
description="Title for button to close how-to card"
|
||||
id="gui.cards.close"
|
||||
/>
|
||||
<img
|
||||
className={styles.closeIcon}
|
||||
src={closeIcon}
|
||||
/>
|
||||
<div className={styles.headerButtonsRight}>
|
||||
<div
|
||||
className={styles.shrinkExpandButton}
|
||||
onClick={onShrinkExpandCards}
|
||||
>
|
||||
<img
|
||||
draggable={false}
|
||||
src={expanded ? shrinkIcon : expandIcon}
|
||||
/>
|
||||
{expanded ?
|
||||
<FormattedMessage
|
||||
defaultMessage="Shrink"
|
||||
description="Title for button to shrink how-to card"
|
||||
id="gui.cards.shrink"
|
||||
/> :
|
||||
<FormattedMessage
|
||||
defaultMessage="Expand"
|
||||
description="Title for button to expand how-to card"
|
||||
id="gui.cards.expand"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<div
|
||||
className={styles.removeButton}
|
||||
onClick={onCloseCards}
|
||||
>
|
||||
<img
|
||||
className={styles.closeIcon}
|
||||
src={closeIcon}
|
||||
/>
|
||||
<FormattedMessage
|
||||
defaultMessage="Close"
|
||||
description="Title for button to close how-to card"
|
||||
id="gui.cards.close"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
// Video step needs to know if the card is being dragged to cover the video
|
||||
// so that the mouseup is not swallowed by the iframe.
|
||||
const VideoStep = ({video, dragging}) => (
|
||||
<div className={styles.stepVideo}>
|
||||
{dragging ? (
|
||||
<div className={styles.videoCover} />
|
||||
) : null}
|
||||
<iframe
|
||||
allowFullScreen
|
||||
allowTransparency="true"
|
||||
frameBorder="0"
|
||||
height="338"
|
||||
scrolling="no"
|
||||
src={`https://fast.wistia.net/embed/iframe/${video}?seo=false&videoFoam=true`}
|
||||
title="📹"
|
||||
width="600"
|
||||
/>
|
||||
<script
|
||||
async
|
||||
src="https://fast.wistia.net/assets/external/E-v1.js"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
class VideoStep extends React.Component {
|
||||
|
||||
componentDidMount () {
|
||||
const script = document.createElement('script');
|
||||
script.src = `https://fast.wistia.com/embed/medias/${this.props.video}.jsonp`;
|
||||
script.async = true;
|
||||
script.setAttribute('id', 'wistia-video-content');
|
||||
document.body.appendChild(script);
|
||||
|
||||
const script2 = document.createElement('script');
|
||||
script2.src = 'https://fast.wistia.com/assets/external/E-v1.js';
|
||||
script2.async = true;
|
||||
script2.setAttribute('id', 'wistia-video-api');
|
||||
document.body.appendChild(script2);
|
||||
}
|
||||
|
||||
// We use the Wistia API here to update or pause the video dynamically:
|
||||
// https://wistia.com/support/developers/player-api
|
||||
componentDidUpdate (prevProps) {
|
||||
// Get a handle on the currently loaded video
|
||||
const video = window.Wistia.api(prevProps.video);
|
||||
|
||||
// Reset the video source if a new video has been chosen from the library
|
||||
if (prevProps.video !== this.props.video) {
|
||||
video.replaceWith(this.props.video);
|
||||
}
|
||||
|
||||
// Pause the video if the modal is being shrunken
|
||||
if (!this.props.expanded) {
|
||||
video.pause();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
const script = document.getElementById('wistia-video-content');
|
||||
script.parentNode.removeChild(script);
|
||||
|
||||
const script2 = document.getElementById('wistia-video-api');
|
||||
script2.parentNode.removeChild(script2);
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className={styles.stepVideo}>
|
||||
<div
|
||||
className={`wistia_embed wistia_async_${this.props.video}`}
|
||||
id="video-div"
|
||||
style={{height: `257px`, width: `466px`}}
|
||||
>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
VideoStep.propTypes = {
|
||||
dragging: PropTypes.bool.isRequired,
|
||||
expanded: PropTypes.bool.isRequired,
|
||||
video: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
@@ -106,13 +166,13 @@ ImageStep.propTypes = {
|
||||
title: PropTypes.node.isRequired
|
||||
};
|
||||
|
||||
const NextPrevButtons = ({isRtl, onNextStep, onPrevStep}) => (
|
||||
const NextPrevButtons = ({isRtl, onNextStep, onPrevStep, expanded}) => (
|
||||
<Fragment>
|
||||
{onNextStep ? (
|
||||
<div>
|
||||
<div className={isRtl ? styles.leftCard : styles.rightCard} />
|
||||
<div className={expanded ? (isRtl ? styles.leftCard : styles.rightCard) : styles.hidden} />
|
||||
<div
|
||||
className={isRtl ? styles.leftButton : styles.rightButton}
|
||||
className={expanded ? (isRtl ? styles.leftButton : styles.rightButton) : styles.hidden}
|
||||
onClick={onNextStep}
|
||||
>
|
||||
<img
|
||||
@@ -124,9 +184,9 @@ const NextPrevButtons = ({isRtl, onNextStep, onPrevStep}) => (
|
||||
) : null}
|
||||
{onPrevStep ? (
|
||||
<div>
|
||||
<div className={isRtl ? styles.rightCard : styles.leftCard} />
|
||||
<div className={expanded ? (isRtl ? styles.rightCard : styles.leftCard) : styles.hidden} />
|
||||
<div
|
||||
className={isRtl ? styles.rightButton : styles.leftButton}
|
||||
className={expanded ? (isRtl ? styles.rightButton : styles.leftButton) : styles.hidden}
|
||||
onClick={onPrevStep}
|
||||
>
|
||||
<img
|
||||
@@ -140,13 +200,16 @@ const NextPrevButtons = ({isRtl, onNextStep, onPrevStep}) => (
|
||||
);
|
||||
|
||||
NextPrevButtons.propTypes = {
|
||||
expanded: PropTypes.bool.isRequired,
|
||||
isRtl: PropTypes.bool,
|
||||
onNextStep: PropTypes.func,
|
||||
onPrevStep: PropTypes.func
|
||||
};
|
||||
CardHeader.propTypes = {
|
||||
expanded: PropTypes.bool.isRequired,
|
||||
onCloseCards: PropTypes.func.isRequired,
|
||||
onShowAll: PropTypes.func.isRequired,
|
||||
onShrinkExpandCards: PropTypes.func.isRequired,
|
||||
step: PropTypes.number,
|
||||
totalSteps: PropTypes.number
|
||||
};
|
||||
@@ -218,78 +281,113 @@ const Cards = props => {
|
||||
locale,
|
||||
onActivateDeckFactory,
|
||||
onCloseCards,
|
||||
onShrinkExpandCards,
|
||||
onDrag,
|
||||
onStartDrag,
|
||||
onEndDrag,
|
||||
onShowAll,
|
||||
onNextStep,
|
||||
onPrevStep,
|
||||
showVideos,
|
||||
step,
|
||||
expanded,
|
||||
...posProps
|
||||
} = props;
|
||||
let {x, y} = posProps;
|
||||
|
||||
if (activeDeckId === null) return;
|
||||
|
||||
// Tutorial cards need to calculate their own dragging bounds
|
||||
// to allow for dragging the cards off the left, right and bottom
|
||||
// edges of the workspace.
|
||||
const cardHorizontalDragOffset = 400; // ~80% of card width
|
||||
const cardVerticalDragOffset = expanded ? 257 : 0; // ~80% of card height, if expanded
|
||||
const menuBarHeight = 48; // TODO: get pre-calculated from elsewhere?
|
||||
const wideCardWidth = 500;
|
||||
|
||||
if (x === 0 && y === 0) {
|
||||
// initialize positions
|
||||
x = isRtl ? -292 : 292;
|
||||
// The tallest cards are about 385px high, and the default position is pinned
|
||||
x = isRtl ? (-190 - wideCardWidth - cardHorizontalDragOffset) : 292;
|
||||
x += cardHorizontalDragOffset;
|
||||
// The tallest cards are about 320px high, and the default position is pinned
|
||||
// to near the bottom of the blocks palette to allow room to work above.
|
||||
const tallCardHeight = 385;
|
||||
const tallCardHeight = 320;
|
||||
const bottomMargin = 60; // To avoid overlapping the backpack region
|
||||
y = window.innerHeight - tallCardHeight - bottomMargin;
|
||||
y = window.innerHeight - tallCardHeight - bottomMargin - menuBarHeight;
|
||||
}
|
||||
|
||||
const steps = content[activeDeckId].steps;
|
||||
|
||||
return (
|
||||
<Draggable
|
||||
bounds="parent"
|
||||
position={{x: x, y: y}}
|
||||
onDrag={onDrag}
|
||||
onStart={onStartDrag}
|
||||
onStop={onEndDrag}
|
||||
// Custom overlay to act as the bounding parent for the draggable, using values from above
|
||||
<div
|
||||
className={styles.cardContainerOverlay}
|
||||
style={{
|
||||
width: `${window.innerWidth + (2 * cardHorizontalDragOffset)}px`,
|
||||
height: `${window.innerHeight - menuBarHeight + cardVerticalDragOffset}px`,
|
||||
top: `${menuBarHeight}px`,
|
||||
left: `${-cardHorizontalDragOffset}px`
|
||||
}}
|
||||
>
|
||||
<div className={styles.cardContainer}>
|
||||
<div className={styles.card}>
|
||||
<CardHeader
|
||||
step={step}
|
||||
totalSteps={steps.length}
|
||||
onCloseCards={onCloseCards}
|
||||
onShowAll={onShowAll}
|
||||
/>
|
||||
<div className={styles.stepBody}>
|
||||
{steps[step].deckIds ? (
|
||||
<PreviewsStep
|
||||
content={content}
|
||||
deckIds={steps[step].deckIds}
|
||||
onActivateDeckFactory={onActivateDeckFactory}
|
||||
onShowAll={onShowAll}
|
||||
/>
|
||||
) : (
|
||||
steps[step].video ? (
|
||||
<VideoStep
|
||||
dragging={dragging}
|
||||
video={translateVideo(steps[step].video, locale)}
|
||||
<Draggable
|
||||
bounds="parent"
|
||||
cancel="#video-div" // disable dragging on video div
|
||||
position={{x: x, y: y}}
|
||||
onDrag={onDrag}
|
||||
onStart={onStartDrag}
|
||||
onStop={onEndDrag}
|
||||
>
|
||||
<div className={styles.cardContainer}>
|
||||
<div className={styles.card}>
|
||||
<CardHeader
|
||||
expanded={expanded}
|
||||
step={step}
|
||||
totalSteps={steps.length}
|
||||
onCloseCards={onCloseCards}
|
||||
onShowAll={onShowAll}
|
||||
onShrinkExpandCards={onShrinkExpandCards}
|
||||
/>
|
||||
<div className={expanded ? styles.stepBody : styles.hidden}>
|
||||
{steps[step].deckIds ? (
|
||||
<PreviewsStep
|
||||
content={content}
|
||||
deckIds={steps[step].deckIds}
|
||||
onActivateDeckFactory={onActivateDeckFactory}
|
||||
onShowAll={onShowAll}
|
||||
/>
|
||||
) : (
|
||||
<ImageStep
|
||||
image={steps[step].image}
|
||||
title={steps[step].title}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{steps[step].trackingPixel && steps[step].trackingPixel}
|
||||
steps[step].video ? (
|
||||
showVideos ? (
|
||||
<VideoStep
|
||||
dragging={dragging}
|
||||
expanded={expanded}
|
||||
video={translateVideo(steps[step].video, locale)}
|
||||
/>
|
||||
) : ( // Else show the deck image and title
|
||||
<ImageStep
|
||||
image={content[activeDeckId].img}
|
||||
title={content[activeDeckId].name}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<ImageStep
|
||||
image={translateImage(steps[step].image, locale)}
|
||||
title={steps[step].title}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{steps[step].trackingPixel && steps[step].trackingPixel}
|
||||
</div>
|
||||
<NextPrevButtons
|
||||
expanded={expanded}
|
||||
isRtl={isRtl}
|
||||
onNextStep={step < steps.length - 1 ? onNextStep : null}
|
||||
onPrevStep={step > 0 ? onPrevStep : null}
|
||||
/>
|
||||
</div>
|
||||
<NextPrevButtons
|
||||
isRtl={isRtl}
|
||||
onNextStep={step < steps.length - 1 ? onNextStep : null}
|
||||
onPrevStep={step > 0 ? onPrevStep : null}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Draggable>
|
||||
</Draggable>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -308,6 +406,7 @@ Cards.propTypes = {
|
||||
})
|
||||
}),
|
||||
dragging: PropTypes.bool.isRequired,
|
||||
expanded: PropTypes.bool.isRequired,
|
||||
isRtl: PropTypes.bool.isRequired,
|
||||
locale: PropTypes.string.isRequired,
|
||||
onActivateDeckFactory: PropTypes.func.isRequired,
|
||||
@@ -317,10 +416,21 @@ Cards.propTypes = {
|
||||
onNextStep: PropTypes.func.isRequired,
|
||||
onPrevStep: PropTypes.func.isRequired,
|
||||
onShowAll: PropTypes.func,
|
||||
onShrinkExpandCards: PropTypes.func.isRequired,
|
||||
onStartDrag: PropTypes.func,
|
||||
showVideos: PropTypes.bool,
|
||||
step: PropTypes.number.isRequired,
|
||||
x: PropTypes.number,
|
||||
y: PropTypes.number
|
||||
};
|
||||
|
||||
export default Cards;
|
||||
Cards.defaultProps = {
|
||||
showVideos: true
|
||||
};
|
||||
|
||||
export {
|
||||
Cards as default,
|
||||
// Others exported for testability
|
||||
ImageStep,
|
||||
VideoStep
|
||||
};
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>General/Check Copy</title>
|
||||
<!-- Generator: Sketch 53.2 (72643) - https://sketchapp.com -->
|
||||
<title>Extensions/Connection/Close</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M10,7.73577763 L12.2675846,5.46819305 C12.8909754,4.84480221 13.8988379,4.84194841 14.5284447,5.47155526 C15.1536925,6.096803 15.1476685,7.11655392 14.531807,7.73241542 L12.2642224,10 L14.531807,12.2675846 C15.1551978,12.8909754 15.1580516,13.8988379 14.5284447,14.5284447 C13.903197,15.1536925 12.8834461,15.1476685 12.2675846,14.531807 L10,12.2642224 L7.73241542,14.531807 C7.10902458,15.1551978 6.10116212,15.1580516 5.47155526,14.5284447 C4.84630752,13.903197 4.85233155,12.8834461 5.46819305,12.2675846 L7.73577763,10 L5.46819305,7.73241542 C4.84480221,7.10902458 4.84194841,6.10116212 5.47155526,5.47155526 C6.096803,4.84630752 7.11655392,4.85233155 7.73241542,5.46819305 L10,7.73577763 Z" id="path-1"></path>
|
||||
<path d="M15.464935,15.467297 C14.7644059,16.1777705 13.6185877,16.1777705 12.9081142,15.467297 L9.99881899,12.5580018 L7.08841885,15.467297 C6.38236506,16.1733508 5.23765187,16.1733508 4.53159807,15.467297 C4.17912364,15.1148226 4.00012409,14.6485398 4.00012409,14.1888866 C4.00012409,13.7281285 4.17912364,13.2629506 4.53159807,12.9104762 L7.44089328,10.001181 L4.52717833,7.08636112 C4.17359897,6.73278176 3.99459941,6.26760391 4.00012409,5.80242606 C4.00012409,5.34166795 4.17359897,4.88201477 4.52717833,4.52954034 C5.23212719,3.82348655 6.37684038,3.82348655 7.08399911,4.52954034 L9.99881899,7.44325529 L12.9125339,4.52954034 C13.6185877,3.82348655 14.7644059,3.82348655 15.4704597,4.52954034 C16.1765134,5.2344892 16.1765134,6.38030733 15.4704597,7.08636112 L12.5545348,10.001181 L15.4704597,12.914896 C16.1765134,13.6209497 16.1765134,14.7557185 15.464935,15.467297" id="path-1"></path>
|
||||
</defs>
|
||||
<g id="General/Check-Copy" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Extensions/Connection/Close" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<use id="close-icon" fill="#FFFFFF" xlink:href="#path-1"></use>
|
||||
<g id="Color/White" mask="url(#mask-2)" fill="#FFFFFF">
|
||||
<use id="close" fill="#FFFFFF" xlink:href="#path-1"></use>
|
||||
<g id="White" mask="url(#mask-2)" fill="#FFFFFF">
|
||||
<rect id="Color" x="0" y="0" width="20" height="20"></rect>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 53.2 (72643) - https://sketchapp.com -->
|
||||
<title>Tutorials/Expand</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M4.5,2 L15.5,2 C16.8807119,2 18,3.11928813 18,4.5 L18,5.5 C18,5.77614237 17.7761424,6 17.5,6 L2.5,6 C2.22385763,6 2,5.77614237 2,5.5 L2,4.5 C2,3.11928813 3.11928813,2 4.5,2 Z M2.5,7 L17.5,7 C17.7761424,7 18,7.22385763 18,7.5 L18,15.5 C18,16.8807119 16.8807119,18 15.5,18 L4.5,18 C3.11928813,18 2,16.8807119 2,15.5 L2,7.5 C2,7.22385763 2.22385763,7 2.5,7 Z M9.65509466,15.1636146 C9.745416,15.2533569 9.86700241,15.3031495 9.99727357,15.3031495 C10.1275447,15.3031495 10.2491311,15.2533569 10.3394525,15.1636146 L12.1574588,13.3456082 C12.3004676,13.2025994 12.3415754,12.9993764 12.2657286,12.8158388 C12.1898819,12.6334592 12.0109762,12.5153467 11.8100691,12.5153467 L11.1506075,12.5153467 L10.7899012,9.98808625 C10.7464775,9.64474938 10.4703026,9.36567961 10.1124912,9.30951827 C10.0783312,9.30546539 10.0435922,9.30314946 10.0094322,9.30314946 C9.61282891,9.30314946 9.27586085,9.59785176 9.22548933,9.98519134 L8.8740467,12.5153467 L8.18447804,12.5153467 C7.9858869,12.5153467 7.81450796,12.6265114 7.73692425,12.8065751 C7.65876155,12.9866388 7.69639544,13.1962306 7.83708829,13.3456082 L9.65509466,15.1636146 Z" id="path-1"></path>
|
||||
</defs>
|
||||
<g id="Tutorials/Expand" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="Combined-Shape" fill-rule="nonzero"></g>
|
||||
<g id="White" mask="url(#mask-2)" fill="#FFFFFF">
|
||||
<rect id="Color" x="0" y="0" width="20" height="20"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 53.2 (72643) - https://sketchapp.com -->
|
||||
<title>Tutorials/Shink</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M2.5,8 C2.22385763,8 2,7.77614237 2,7.5 C2,7.22385763 2.22385763,7 2.5,7 L3.5,7 C3.77614237,7 4,7.22385763 4,7.5 C4,7.77614237 3.77614237,8 3.5,8 L2.5,8 Z M5.5,8 C5.22385763,8 5,7.77614237 5,7.5 C5,7.22385763 5.22385763,7 5.5,7 L6.5,7 C6.77614237,7 7,7.22385763 7,7.5 C7,7.77614237 6.77614237,8 6.5,8 L5.5,8 Z M8.5,8 C8.22385763,8 8,7.77614237 8,7.5 C8,7.22385763 8.22385763,7 8.5,7 L9.5,7 C9.77614237,7 10,7.22385763 10,7.5 C10,7.77614237 9.77614237,8 9.5,8 L8.5,8 Z M11.5,8 C11.2238576,8 11,7.77614237 11,7.5 C11,7.22385763 11.2238576,7 11.5,7 L12.5,7 C12.7761424,7 13,7.22385763 13,7.5 C13,7.77614237 12.7761424,8 12.5,8 L11.5,8 Z M14.5,8 C14.2238576,8 14,7.77614237 14,7.5 C14,7.22385763 14.2238576,7 14.5,7 L15.5,7 C15.7761424,7 16,7.22385763 16,7.5 C16,7.77614237 15.7761424,8 15.5,8 L14.5,8 Z M17,7.5 C17,7.22385763 17.2238576,7 17.5,7 C17.7761424,7 18,7.22385763 18,7.5 L18,8.5 C18,8.77614237 17.7761424,9 17.5,9 C17.2238576,9 17,8.77614237 17,8.5 L17,7.5 Z M17,10.5 C17,10.2238576 17.2238576,10 17.5,10 C17.7761424,10 18,10.2238576 18,10.5 L18,11.5 C18,11.7761424 17.7761424,12 17.5,12 C17.2238576,12 17,11.7761424 17,11.5 L17,10.5 Z M17,13.5 C17,13.2238576 17.2238576,13 17.5,13 C17.7761424,13 18,13.2238576 18,13.5 L18,14.5 C18,14.7761424 17.7761424,15 17.5,15 C17.2238576,15 17,14.7761424 17,14.5 L17,13.5 Z M16.8130884,16.2258789 C16.9469778,15.9843665 17.2513011,15.8971208 17.4928135,16.0310102 C17.7343259,16.1648996 17.8215716,16.4692229 17.6876822,16.7107353 C17.4827416,17.0804113 17.1867239,17.3929429 16.8289716,17.6178178 C16.59518,17.7647739 16.286523,17.6943798 16.1395669,17.4605882 C15.9926108,17.2267966 16.0630049,16.9181396 16.2967965,16.7711835 C16.5118233,16.6360225 16.6900031,16.4479027 16.8130884,16.2258789 Z M14.5614675,17 C14.8376098,17 15.0614675,17.2238576 15.0614675,17.5 C15.0614675,17.7761424 14.8376098,18 14.5614675,18 L13.5614675,18 C13.2853251,18 13.0614675,17.7761424 13.0614675,17.5 C13.0614675,17.2238576 13.2853251,17 13.5614675,17 L14.5614675,17 Z M11.5614675,17 C11.8376098,17 12.0614675,17.2238576 12.0614675,17.5 C12.0614675,17.7761424 11.8376098,18 11.5614675,18 L10.5614675,18 C10.2853251,18 10.0614675,17.7761424 10.0614675,17.5 C10.0614675,17.2238576 10.2853251,17 10.5614675,17 L11.5614675,17 Z M8.56146746,17 C8.83760983,17 9.06146746,17.2238576 9.06146746,17.5 C9.06146746,17.7761424 8.83760983,18 8.56146746,18 L7.56146746,18 C7.28532508,18 7.06146746,17.7761424 7.06146746,17.5 C7.06146746,17.2238576 7.28532508,17 7.56146746,17 L8.56146746,17 Z M5.56146746,17 C5.83760983,17 6.06146746,17.2238576 6.06146746,17.5 C6.06146746,17.7761424 5.83760983,18 5.56146746,18 L4.56146746,18 C4.28532508,18 4.06146746,17.7761424 4.06146746,17.5 C4.06146746,17.2238576 4.28532508,17 4.56146746,17 L5.56146746,17 Z M3.22779886,16.2951753 C3.37445671,16.5291541 3.30366909,16.8377211 3.06969027,16.9843789 C2.83571145,17.1310368 2.52714447,17.0602491 2.38048662,16.8262703 C2.15682122,16.4694332 2.02609629,16.0609535 2.00352115,15.6335963 C1.98895424,15.3578384 2.20069137,15.1224836 2.47644927,15.1079167 C2.75220716,15.0933498 2.98756192,15.3050869 3.00212882,15.5808448 C3.01567642,15.8373067 3.0937811,16.0813625 3.22779886,16.2951753 Z M3,13.6229349 C3,13.8990773 2.77614237,14.1229349 2.5,14.1229349 C2.22385763,14.1229349 2,13.8990773 2,13.6229349 L2,12.6229349 C2,12.3467925 2.22385763,12.1229349 2.5,12.1229349 C2.77614237,12.1229349 3,12.3467925 3,12.6229349 L3,13.6229349 Z M3,10.6229349 C3,10.8990773 2.77614237,11.1229349 2.5,11.1229349 C2.22385763,11.1229349 2,10.8990773 2,10.6229349 L2,9.62293492 C2,9.34679254 2.22385763,9.12293492 2.5,9.12293492 C2.77614237,9.12293492 3,9.34679254 3,9.62293492 L3,10.6229349 Z M3,7.62293492 C3,7.89907729 2.77614237,8.12293492 2.5,8.12293492 C2.22385763,8.12293492 2,7.89907729 2,7.62293492 L2,7.5 C2,7.22385763 2.22385763,7 2.5,7 C2.77614237,7 3,7.22385763 3,7.5 L3,7.62293492 Z M4.5,2 L15.5,2 C16.8807119,2 18,3.11928813 18,4.5 L18,5.5 C18,5.77614237 17.7761424,6 17.5,6 L2.5,6 C2.22385763,6 2,5.77614237 2,5.5 L2,4.5 C2,3.11928813 3.11928813,2 4.5,2 Z M10.3449053,9.44268434 L12.1629117,11.2606907 C12.3036046,11.4100683 12.3412384,11.6196601 12.2630758,11.7997238 C12.185492,11.9797875 12.0141131,12.0909522 11.815522,12.0909522 L11.1259533,12.0909522 L10.7745107,14.6211076 C10.7241392,15.0084472 10.3871711,15.3031495 9.99056779,15.3031495 C9.9564078,15.3031495 9.92166882,15.3008335 9.88750883,15.2967806 C9.52969739,15.2406193 9.25352253,14.9615495 9.21009882,14.6182127 L8.84939246,12.0909522 L8.18993091,12.0909522 C7.98902384,12.0909522 7.81011812,11.9728397 7.73427135,11.7904601 C7.65842459,11.6069225 7.69953238,11.4036995 7.84254116,11.2606907 L9.66054753,9.44268434 C9.75086886,9.35294199 9.87245528,9.30314946 10.0027264,9.30314946 C10.1329976,9.30314946 10.254584,9.35294199 10.3449053,9.44268434 Z" id="path-1"></path>
|
||||
</defs>
|
||||
<g id="Tutorials/Shink" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="Rectangle" fill-rule="nonzero"></g>
|
||||
<g id="White" mask="url(#mask-2)" fill="#FFFFFF">
|
||||
<rect id="Color" x="0" y="0" width="20" height="20"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
@@ -45,8 +45,8 @@ const AutoScanningStep = props => (
|
||||
src={radarIcon}
|
||||
/>
|
||||
<img
|
||||
className={styles.peripheralButtonImage}
|
||||
src={props.peripheralButtonImage}
|
||||
className={styles.connectionTipIcon}
|
||||
src={props.connectionTipIconURL}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)}
|
||||
@@ -142,9 +142,9 @@ const AutoScanningStep = props => (
|
||||
);
|
||||
|
||||
AutoScanningStep.propTypes = {
|
||||
connectionTipIconURL: PropTypes.string,
|
||||
onRefresh: PropTypes.func,
|
||||
onStartScan: PropTypes.func,
|
||||
peripheralButtonImage: PropTypes.string,
|
||||
phase: PropTypes.oneOf(Object.keys(PHASES))
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ const ConnectedStep = props => (
|
||||
<div className={styles.peripheralActivity}>
|
||||
<img
|
||||
className={styles.peripheralActivityIcon}
|
||||
src={props.peripheralImage}
|
||||
src={props.connectionIconURL}
|
||||
/>
|
||||
<img
|
||||
className={styles.bluetoothConnectedIcon}
|
||||
@@ -64,9 +64,9 @@ const ConnectedStep = props => (
|
||||
);
|
||||
|
||||
ConnectedStep.propTypes = {
|
||||
connectionIconURL: PropTypes.string.isRequired,
|
||||
onCancel: PropTypes.func,
|
||||
onDisconnect: PropTypes.func,
|
||||
peripheralImage: PropTypes.string.isRequired
|
||||
onDisconnect: PropTypes.func
|
||||
};
|
||||
|
||||
export default ConnectedStep;
|
||||
@@ -18,7 +18,7 @@ const ConnectingStep = props => (
|
||||
<div className={styles.peripheralActivity}>
|
||||
<img
|
||||
className={styles.peripheralActivityIcon}
|
||||
src={props.peripheralImage}
|
||||
src={props.connectionIconURL}
|
||||
/>
|
||||
<img
|
||||
className={styles.bluetoothConnectingIcon}
|
||||
@@ -63,8 +63,8 @@ const ConnectingStep = props => (
|
||||
|
||||
ConnectingStep.propTypes = {
|
||||
connectingMessage: PropTypes.node.isRequired,
|
||||
onDisconnect: PropTypes.func,
|
||||
peripheralImage: PropTypes.string.isRequired
|
||||
connectionIconURL: PropTypes.string.isRequired,
|
||||
onDisconnect: PropTypes.func
|
||||
};
|
||||
|
||||
export default ConnectingStep;
|
||||
@@ -162,7 +162,7 @@
|
||||
height: 80px; */
|
||||
}
|
||||
|
||||
.peripheral-button-image {
|
||||
.connection-tip-icon {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ const ConnectionModalComponent = props => (
|
||||
className={styles.modalContent}
|
||||
contentLabel={props.name}
|
||||
headerClassName={styles.header}
|
||||
headerImage={props.smallPeripheralImage}
|
||||
headerImage={props.connectionSmallIconURL}
|
||||
id="connectionModal"
|
||||
onHelp={props.onHelp}
|
||||
onRequestClose={props.onCancel}
|
||||
@@ -44,17 +44,21 @@ const ConnectionModalComponent = props => (
|
||||
);
|
||||
|
||||
ConnectionModalComponent.propTypes = {
|
||||
connectingMessage: PropTypes.node,
|
||||
connectingMessage: PropTypes.node.isRequired,
|
||||
connectionSmallIconURL: PropTypes.string,
|
||||
connectionTipIconURL: PropTypes.string,
|
||||
name: PropTypes.node,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
onHelp: PropTypes.func.isRequired,
|
||||
peripheralButtonImage: PropTypes.string,
|
||||
phase: PropTypes.oneOf(Object.keys(PHASES)).isRequired,
|
||||
smallPeripheralImage: PropTypes.string,
|
||||
title: PropTypes.string.isRequired,
|
||||
useAutoScan: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
ConnectionModalComponent.defaultProps = {
|
||||
connectingMessage: 'Connecting'
|
||||
};
|
||||
|
||||
export {
|
||||
ConnectionModalComponent as default,
|
||||
PHASES
|
||||
|
||||
@@ -17,7 +17,7 @@ const ErrorStep = props => (
|
||||
<div className={styles.peripheralActivity}>
|
||||
<img
|
||||
className={styles.peripheralActivityIcon}
|
||||
src={props.peripheralImage}
|
||||
src={props.connectionIconURL}
|
||||
/>
|
||||
</div>
|
||||
</Box>
|
||||
@@ -70,9 +70,9 @@ const ErrorStep = props => (
|
||||
);
|
||||
|
||||
ErrorStep.propTypes = {
|
||||
connectionIconURL: PropTypes.string.isRequired,
|
||||
onHelp: PropTypes.func,
|
||||
onScanning: PropTypes.func,
|
||||
peripheralImage: PropTypes.string.isRequired
|
||||
onScanning: PropTypes.func
|
||||
};
|
||||
|
||||
export default ErrorStep;
|
||||
@@ -1,34 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="52px" height="52px" viewBox="0 0 52 52" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 51.1 (57501) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>scratchlink</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M6.599912,0 L37.399912,0 C41.045312,0 43.999912,2.95504 43.999912,6.6 L43.999912,37.4 C43.999912,41.04496 41.045312,44 37.399912,44 L6.599912,44 C2.954952,44 -8.8e-05,41.04496 -8.8e-05,37.4 L-8.8e-05,6.6 C-8.8e-05,2.95504 2.954952,0 6.599912,0" id="path-1"></path>
|
||||
<filter x="-13.6%" y="-13.6%" width="127.3%" height="127.3%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feMorphology radius="2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feColorMatrix values="0 0 0 0 0.298039216 0 0 0 0 0.592156863 0 0 0 0 1 0 0 0 0.25 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="R1_Extension" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="No-Comms-with-Scratch-Link-or-Bluetooth" transform="translate(-506.000000, -262.000000)">
|
||||
<g id="No-connection-v2" transform="translate(-2.000000, 0.000000)">
|
||||
<g id="Modal" transform="translate(407.000000, 187.000000)">
|
||||
<g id="Scratch-Link" transform="translate(53.000000, 75.000000)">
|
||||
<g id="scratchlink" transform="translate(52.000000, 4.000000)">
|
||||
<g id="Fill-1">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#25AFF4" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<path d="M35.854764,19.82882 C36.027684,20.8681 36.062444,21.91574 35.988084,22.9427 L39.440764,24.78542 C39.984604,25.05162 40.240684,25.68522 40.034324,26.25458 L38.559444,30.3237 C38.353084,30.89438 37.748524,31.2169 37.159364,31.07082 L33.333564,30.26386 C32.718004,31.10382 32.018404,31.8835 31.217604,32.56902 L32.519124,36.64606 C32.716684,37.21982 32.448724,37.85034 31.898724,38.10686 L27.975684,39.93638 C27.425684,40.19246 26.770524,39.9927 26.458124,39.47262 L24.171444,35.85494 C23.131724,36.02742 22.084524,36.06218 21.057124,35.98826 L19.215724,39.43918 C18.949084,39.9839 18.314604,40.23998 17.744364,40.0323 L13.669084,38.54906 C13.099284,38.34138 12.777644,37.7377 12.923284,37.14898 L13.730684,33.32186 C12.896444,32.71818 12.116324,32.01858 11.431244,31.21778 L7.354204,32.5193 C6.780004,32.71686 6.149924,32.4489 5.893404,31.8989 L4.063884,27.97542 C3.807364,27.42542 4.007564,26.7707 4.527204,26.45786 L8.133884,24.1769 C7.972404,23.13146 7.920924,22.0781 8.006284,21.04586 L4.556684,19.20446 C4.011524,18.93782 3.755884,18.30202 3.964004,17.73178 L5.449444,13.66838 C5.658004,13.09902 6.262124,12.77826 6.850404,12.92478 L10.666964,13.73614 C11.270204,12.9019 11.981684,12.1165 12.782044,11.43098 L11.480964,7.35394 C11.283404,6.78018 11.551364,6.14966 12.101364,5.89314 L16.024404,4.06362 C16.574404,3.8071 17.229564,4.0073 17.541964,4.52782 L19.828644,8.14506 C20.868364,7.97258 21.927444,7.9321 22.960564,7.9893 L24.796244,4.55466 C25.062884,4.01038 25.697364,3.75474 26.266724,3.96198 L30.325724,5.4395 C30.895524,5.64674 31.217164,6.25086 31.071084,6.83914 L30.263684,10.6667 C31.109804,11.2651 31.883764,11.98186 32.580724,12.77694 L36.646324,11.4807 C37.220084,11.28314 37.850164,11.5511 38.106684,12.1011 L39.936204,16.02458 C40.192724,16.57458 39.992524,17.2293 39.472444,17.54214 L35.854764,19.82882 Z" id="Fill-4" fill-opacity="0.15" fill="#231F20"></path>
|
||||
<path d="M30.417684,24.430956 C30.445844,26.694756 29.431644,28.874076 27.638204,30.404836 C26.209964,31.635956 24.408604,32.343916 22.535524,32.412996 C21.669604,33.092796 20.619324,33.496276 19.495124,33.567996 C19.375004,33.575476 19.254884,33.580316 19.134764,33.580316 C16.263324,33.580316 13.845964,31.337196 13.626404,28.473236 C13.623764,28.439796 13.621124,28.394036 13.618484,28.335076 C13.615844,28.314836 13.613644,28.294156 13.613644,28.271276 C13.557324,27.065236 13.585484,26.068636 13.621124,25.435036 C13.654564,24.850276 13.674804,23.797356 13.677444,23.552276 L13.677444,23.536876 C13.692844,22.680636 13.904924,21.845516 14.290804,21.096636 C14.180804,20.258876 14.183444,19.361716 14.300924,18.421876 L14.316324,18.276236 C14.318964,18.258196 14.318964,18.237516 14.321164,18.219916 C14.323804,18.204516 14.326444,18.186916 14.329084,18.168876 C14.425884,17.368956 14.594844,16.058196 15.310284,14.714436 C16.500924,12.460756 18.759444,11.116996 21.350164,11.116996 L21.460164,11.116996 C22.275044,10.662476 23.192444,10.419596 24.134924,10.419596 L24.234804,10.419596 C27.234284,10.473276 29.674524,12.951356 29.674524,15.945996 C29.674524,15.979436 29.572004,19.571596 29.457164,20.800516 C30.078004,21.886436 30.404924,23.117996 30.417684,24.430956" id="Fill-6" fill="#FFFFFF"></path>
|
||||
<path d="M27.86278,24.459116 C27.88302,25.959076 27.19354,27.425596 25.96946,28.470596 C24.92974,29.367316 23.60094,29.863196 22.2343,29.863196 C21.9989,29.860556 21.7613,29.847796 21.52898,29.816996 C21.4753,29.888716 21.41898,29.957796 21.36046,30.023796 C20.83378,30.619116 20.10822,30.971996 19.31622,31.017756 C19.25506,31.023036 19.1961,31.025676 19.13494,31.025676 C17.58922,31.025676 16.28858,29.814356 16.17374,28.271276 C16.1711,28.240476 16.16846,28.209676 16.16846,28.176676 L16.16626,28.153796 C16.11478,27.055116 16.1403,26.150476 16.1711,25.585956 C16.20938,24.931676 16.23006,23.820236 16.23226,23.579996 C16.24502,22.828916 16.53366,22.146916 17.00138,21.628156 C16.76906,20.823396 16.69514,19.857596 16.8377,18.715356 L16.85574,18.549476 C16.85838,18.536716 16.85838,18.523956 16.86102,18.511196 C16.94286,17.841516 17.06518,16.852836 17.56854,15.907716 C18.32006,14.486956 19.69946,13.672076 21.3499,13.672076 C21.4423,13.672076 21.5391,13.674716 21.63854,13.679556 C21.81278,13.689676 21.98878,13.710356 22.15994,13.741156 C22.69674,13.258036 23.40954,12.959276 24.19142,12.974236 C25.80622,13.002396 27.11918,14.336476 27.11918,15.945996 C27.11918,15.981636 26.97618,20.281756 26.9071,20.654876 C26.86618,20.887196 26.79754,21.109396 26.70778,21.319276 C27.45138,22.177276 27.85266,23.248236 27.86278,24.459116" id="Fill-8" fill="#F9A83A"></path>
|
||||
<path d="M21.41766,21.36794 C20.65162,21.2487 20.24286,20.7361 20.44614,19.15034 L20.46946,18.95894 C20.64018,17.58174 20.78362,17.27506 21.44626,17.3107 C21.6403,17.32302 21.86382,17.44578 22.0869,17.62882 C22.29414,17.86862 22.75394,18.17882 23.0131,18.79306 C23.19922,19.24362 23.26302,19.53754 23.28942,19.85434 L23.33078,20.24242 L23.33078,20.24066 C23.38534,20.50642 23.58906,20.7251 23.87066,20.77218 C24.23278,20.83862 24.58258,20.5975 24.64638,20.2345 C24.6543,20.19138 24.81886,16.01534 24.81886,15.94714 C24.81886,15.5793 24.52362,15.28054 24.15358,15.27438 C23.78354,15.27218 23.4839,15.5727 23.4839,15.93966 C23.4839,15.94802 23.48214,16.52442 23.47026,17.10522 C22.94358,16.53322 22.26994,16.01974 21.5149,15.9753 C19.49574,15.8675 19.2753,17.72386 19.14242,18.79394 L19.12218,18.98358 C18.85026,21.09778 19.55514,22.43186 21.21218,22.69146 C23.0131,22.97394 24.21518,23.38754 24.22618,24.49546 C24.23278,24.92622 24.00618,25.36842 23.61106,25.70766 C23.13454,26.1129 22.49654,26.2955 21.89594,26.19694 C21.70938,26.16834 21.5347,26.1173 21.3675,26.06142 C21.13166,25.9303 20.53678,25.56818 20.23538,25.15106 C19.98106,24.79906 19.89306,24.24554 19.86534,23.89442 C19.86886,23.7369 19.8693,23.6335 19.8693,23.62162 C19.8759,23.25202 19.57934,22.95062 19.2137,22.94182 C18.84234,22.9339 18.5383,23.23222 18.53126,23.60138 C18.53126,23.6137 18.51454,24.92226 18.46658,25.7103 C18.39794,26.97926 18.46658,28.05462 18.46658,28.10126 C18.49386,28.46998 18.8111,28.74806 19.18026,28.72342 C19.54766,28.70362 19.82838,28.38418 19.80286,28.01502 C19.80286,28.0093 19.76986,27.48878 19.77426,26.76806 C20.26398,27.0809 20.90726,27.38494 21.67418,27.51562 C22.67298,27.68326 23.6951,27.39418 24.47522,26.72318 C25.17482,26.12522 25.57522,25.30858 25.56422,24.48182 C25.54002,22.01254 22.75394,21.57914 21.41766,21.36794" id="Fill-10" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg width="52px" height="52px" viewBox="0 0 52 52" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
style="enable-background:new 0 0 52 52;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#0FBD8C;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#F9A83A;}
|
||||
</style>
|
||||
<title>Scratch Link</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="_x35_2x52-for-the-dialog">
|
||||
<g id="Group">
|
||||
<path id="bg" class="st0" d="M41.4,5c3.1,0,5.6,2.5,5.6,5.6v30.8c0,3.1-2.5,5.6-5.6,5.6H10.6C7.5,47,5,44.5,5,41.4V10.6
|
||||
C5,7.5,7.5,5,10.6,5H41.4z"/>
|
||||
<path id="scratch-outline-2" class="st1" d="M28.8,28.9c0,2.7-1.1,5.4-3.2,7.2c-1.7,1.5-3.8,2.3-5.9,2.4c-1,0.8-2.2,1.3-3.5,1.4
|
||||
c-0.1,0-0.3,0-0.4,0c-3.3,0-6.1-2.7-6.4-6.2c0,0,0-0.1,0-0.2c0,0,0,0,0-0.1c-0.1-1.5,0-2.7,0-3.4c0-0.7,0.1-2,0.1-2.3v0
|
||||
c0-1,0.3-2,0.7-2.9c-0.1-1-0.1-2.1,0-3.2l0-0.2c0,0,0,0,0-0.1c0,0,0,0,0-0.1c0.1-1,0.3-2.5,1.1-4.2c1.4-2.7,4-4.3,7-4.3h0.1
|
||||
c0.9-0.5,2-0.8,3.1-0.8h0.1c3.5,0.1,6.3,3.1,6.3,6.7c0,0-0.1,4.4-0.3,5.9C28.4,25.9,28.7,27.4,28.8,28.9"/>
|
||||
<path id="scratch-outline-1" class="st2" d="M25.8,29c0,1.8-0.8,3.6-2.2,4.8c-1.2,1.1-2.8,1.7-4.3,1.7c-0.3,0-0.5,0-0.8-0.1
|
||||
c-0.1,0.1-0.1,0.2-0.2,0.2c-0.6,0.7-1.5,1.1-2.4,1.2c-0.1,0-0.1,0-0.2,0c-1.8,0-3.3-1.5-3.4-3.3c0,0,0-0.1,0-0.1l0,0
|
||||
c-0.1-1.3,0-2.4,0-3.1c0-0.8,0.1-2.1,0.1-2.4c0-0.9,0.3-1.7,0.9-2.4c-0.3-1-0.4-2.1-0.2-3.5l0-0.2c0,0,0,0,0,0
|
||||
c0.1-0.8,0.2-2,0.8-3.1c0.9-1.7,2.5-2.7,4.4-2.7c0.1,0,0.2,0,0.3,0c0.2,0,0.4,0,0.6,0.1c0.6-0.6,1.5-0.9,2.4-0.9
|
||||
c1.9,0,3.4,1.6,3.4,3.6c0,0-0.2,5.2-0.2,5.7c0,0.3-0.1,0.5-0.2,0.8C25.3,26.2,25.8,27.5,25.8,29"/>
|
||||
<path id="scratch-fill" class="st1" d="M18.3,25.3c-0.9-0.1-1.4-0.8-1.1-2.7l0-0.2c0.2-1.7,0.4-2,1.1-2c0.2,0,0.5,0.2,0.7,0.4
|
||||
c0.2,0.3,0.8,0.7,1.1,1.4c0.2,0.5,0.3,0.9,0.3,1.3l0,0.5v0c0.1,0.3,0.3,0.6,0.6,0.6c0.4,0.1,0.8-0.2,0.9-0.6
|
||||
c0-0.1,0.2-5.1,0.2-5.2c0-0.4-0.3-0.8-0.8-0.8c-0.4,0-0.8,0.4-0.8,0.8c0,0,0,0.7,0,1.4c-0.6-0.7-1.4-1.3-2.3-1.4
|
||||
c-2.3-0.1-2.6,2.1-2.8,3.4l0,0.2c-0.3,2.5,0.5,4.2,2.4,4.5c2.1,0.3,3.5,0.8,3.5,2.2c0,0.5-0.3,1.1-0.7,1.5c-0.6,0.5-1.3,0.7-2,0.6
|
||||
c-0.2,0-0.4-0.1-0.6-0.2c-0.3-0.2-1-0.6-1.3-1.1c-0.3-0.4-0.4-1.1-0.4-1.5c0-0.2,0-0.3,0-0.3c0-0.4-0.3-0.8-0.8-0.8
|
||||
c-0.4,0-0.8,0.3-0.8,0.8c0,0,0,1.6-0.1,2.5c-0.1,1.5,0,2.8,0,2.9c0,0.4,0.4,0.8,0.8,0.8c0.4,0,0.8-0.4,0.7-0.9c0,0,0-0.6,0-1.5
|
||||
c0.6,0.4,1.3,0.7,2.2,0.9c1.2,0.2,2.3-0.1,3.3-1c0.8-0.7,1.3-1.7,1.3-2.7C23.1,26,19.9,25.5,18.3,25.3"/>
|
||||
<path id="signal" class="st1" d="M37.7,36.9c-0.2,0-0.4-0.1-0.5-0.2c-0.3-0.3-0.3-0.8,0-1.1c2.6-2.6,4-6,4-9.6
|
||||
c0-3.6-1.4-7.1-4-9.7c-0.3-0.3-0.3-0.8,0-1.1c0.3-0.3,0.8-0.3,1,0c2.8,2.9,4.4,6.7,4.4,10.7c0,4-1.6,7.9-4.4,10.7
|
||||
C38.1,36.9,37.9,36.9,37.7,36.9z M35,33.5c-0.2,0-0.4-0.1-0.5-0.2c-0.3-0.3-0.3-0.8,0-1.1c1.7-1.7,2.6-3.9,2.6-6.3
|
||||
c0-2.4-0.9-4.6-2.6-6.3c-0.3-0.3-0.3-0.8,0-1.1c0.3-0.3,0.8-0.3,1,0c1.9,2,3,4.6,3,7.3c0,2.8-1.1,5.4-3,7.3
|
||||
C35.4,33.5,35.2,33.5,35,33.5z M32.3,30.1c-0.2,0-0.4-0.1-0.5-0.2c-0.3-0.3-0.3-0.8,0-1.1c0.8-0.8,1.2-1.8,1.2-2.9
|
||||
c0-1.1-0.4-2.1-1.2-2.9c-0.3-0.3-0.3-0.8,0-1.1c0.3-0.3,0.8-0.3,1,0c1,1,1.6,2.4,1.6,3.9c0,1.5-0.6,2.9-1.6,3.9
|
||||
C32.7,30.1,32.5,30.1,32.3,30.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 3.2 KiB |
@@ -23,7 +23,7 @@ class PeripheralTile extends React.Component {
|
||||
<Box className={styles.peripheralTileName}>
|
||||
<img
|
||||
className={styles.peripheralTileImage}
|
||||
src={this.props.smallPeripheralImage}
|
||||
src={this.props.connectionSmallIconURL}
|
||||
/>
|
||||
<Box className={styles.peripheralTileNameWrapper}>
|
||||
<Box className={styles.peripheralTileNameLabel}>
|
||||
@@ -77,11 +77,11 @@ class PeripheralTile extends React.Component {
|
||||
}
|
||||
|
||||
PeripheralTile.propTypes = {
|
||||
connectionSmallIconURL: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
onConnecting: PropTypes.func,
|
||||
peripheralId: PropTypes.string,
|
||||
rssi: PropTypes.number,
|
||||
smallPeripheralImage: PropTypes.string
|
||||
rssi: PropTypes.number
|
||||
};
|
||||
|
||||
export default PeripheralTile;
|
||||
@@ -34,11 +34,11 @@ const ScanningStep = props => (
|
||||
<div className={styles.peripheralTilePane}>
|
||||
{props.peripheralList.map(peripheral =>
|
||||
(<PeripheralTile
|
||||
connectionSmallIconURL={props.connectionSmallIconURL}
|
||||
key={peripheral.peripheralId}
|
||||
name={peripheral.name}
|
||||
peripheralId={peripheral.peripheralId}
|
||||
rssi={peripheral.rssi}
|
||||
smallPeripheralImage={props.smallPeripheralImage}
|
||||
onConnecting={props.onConnecting}
|
||||
/>)
|
||||
)}
|
||||
@@ -86,6 +86,7 @@ const ScanningStep = props => (
|
||||
);
|
||||
|
||||
ScanningStep.propTypes = {
|
||||
connectionSmallIconURL: PropTypes.string,
|
||||
onConnecting: PropTypes.func,
|
||||
onRefresh: PropTypes.func,
|
||||
peripheralList: PropTypes.arrayOf(PropTypes.shape({
|
||||
@@ -93,8 +94,7 @@ ScanningStep.propTypes = {
|
||||
rssi: PropTypes.number,
|
||||
peripheralId: PropTypes.string
|
||||
})),
|
||||
scanning: PropTypes.bool.isRequired,
|
||||
smallPeripheralImage: PropTypes.string
|
||||
scanning: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
ScanningStep.defaultProps = {
|
||||
|
||||
@@ -33,6 +33,6 @@
|
||||
border-top: 1px solid $ui-black-transparent;
|
||||
}
|
||||
|
||||
.menu-item-bordered:hover {
|
||||
.menu-item-danger:hover {
|
||||
background: $error-primary;
|
||||
}
|
||||
@@ -25,9 +25,17 @@ const BorderedMenuItem = props => (
|
||||
/>
|
||||
);
|
||||
|
||||
const DangerousMenuItem = props => (
|
||||
<MenuItem
|
||||
{...props}
|
||||
attributes={{className: classNames(styles.menuItem, styles.menuItemBordered, styles.menuItemDanger)}}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
export {
|
||||
BorderedMenuItem,
|
||||
DangerousMenuItem,
|
||||
StyledContextMenu as ContextMenu,
|
||||
StyledMenuItem as MenuItem
|
||||
};
|
||||
@@ -97,6 +97,7 @@ const GUIComponent = props => {
|
||||
onActivateTab,
|
||||
onClickLogo,
|
||||
onExtensionButtonClick,
|
||||
onProjectTelemetryEvent,
|
||||
onRequestCloseBackdropLibrary,
|
||||
onRequestCloseCostumeLibrary,
|
||||
onRequestCloseTelemetryModal,
|
||||
@@ -217,6 +218,7 @@ const GUIComponent = props => {
|
||||
onCloseAccountNav={onCloseAccountNav}
|
||||
onLogOut={onLogOut}
|
||||
onOpenRegistration={onOpenRegistration}
|
||||
onProjectTelemetryEvent={onProjectTelemetryEvent}
|
||||
onSeeCommunity={onSeeCommunity}
|
||||
onShare={onShare}
|
||||
onToggleLoginOpen={onToggleLoginOpen}
|
||||
|
||||
@@ -178,6 +178,10 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.featured-extension-metadata-detail img{
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
.coming-soon-text {
|
||||
position: absolute;
|
||||
background-color: $data-primary;
|
||||
|
||||
@@ -72,12 +72,12 @@ class LibraryItemComponent extends React.PureComponent {
|
||||
<div
|
||||
className={styles.featuredExtensionMetadataDetail}
|
||||
>
|
||||
<img
|
||||
src={this.props.bluetoothRequired ?
|
||||
bluetoothIconURL :
|
||||
internetConnectionIconURL
|
||||
}
|
||||
/>
|
||||
{this.props.bluetoothRequired ? (
|
||||
<img src={bluetoothIconURL} />
|
||||
) : null}
|
||||
{this.props.internetConnectionRequired ? (
|
||||
<img src={internetConnectionIconURL} />
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
overflow-y: auto;
|
||||
height: auto;
|
||||
padding: 0.5rem;
|
||||
height: calc(100% - $library-header-height);
|
||||
}
|
||||
|
||||
.library-scroll-grid.withFilterBar {
|
||||
@@ -59,3 +60,11 @@
|
||||
height: $library-filter-bar-height;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.spinner-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import Modal from '../../containers/modal.jsx';
|
||||
import Divider from '../divider/divider.jsx';
|
||||
import Filter from '../filter/filter.jsx';
|
||||
import TagButton from '../../containers/tag-button.jsx';
|
||||
import analytics from '../../lib/analytics';
|
||||
import Spinner from '../spinner/spinner.jsx';
|
||||
|
||||
import styles from './library.css';
|
||||
|
||||
@@ -45,9 +45,16 @@ class LibraryComponent extends React.Component {
|
||||
this.state = {
|
||||
selectedItem: null,
|
||||
filterQuery: '',
|
||||
selectedTag: ALL_TAG.tag
|
||||
selectedTag: ALL_TAG.tag,
|
||||
loaded: false
|
||||
};
|
||||
}
|
||||
componentDidMount () {
|
||||
// Allow the spinner to display before loading the content
|
||||
setTimeout(() => {
|
||||
this.setState({loaded: true});
|
||||
});
|
||||
}
|
||||
componentDidUpdate (prevProps, prevState) {
|
||||
if (prevState.filterQuery !== this.state.filterQuery ||
|
||||
prevState.selectedTag !== this.state.selectedTag) {
|
||||
@@ -60,7 +67,6 @@ class LibraryComponent extends React.Component {
|
||||
}
|
||||
handleClose () {
|
||||
this.props.onRequestClose();
|
||||
analytics.pageview(`/${this.props.id}/search?q=${this.state.filterQuery}`);
|
||||
}
|
||||
handleTagClick (tag) {
|
||||
this.setState({
|
||||
@@ -164,7 +170,7 @@ class LibraryComponent extends React.Component {
|
||||
})}
|
||||
ref={this.setFilteredDataRef}
|
||||
>
|
||||
{this.getFilteredData().map((dataItem, index) => (
|
||||
{this.state.loaded ? this.getFilteredData().map((dataItem, index) => (
|
||||
<LibraryItem
|
||||
bluetoothRequired={dataItem.bluetoothRequired}
|
||||
collaborator={dataItem.collaborator}
|
||||
@@ -185,7 +191,14 @@ class LibraryComponent extends React.Component {
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
onSelect={this.handleSelect}
|
||||
/>
|
||||
))}
|
||||
)) : (
|
||||
<div className={styles.spinnerWrapper}>
|
||||
<Spinner
|
||||
large
|
||||
level="primary"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
color: $ui-white;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 48.1 (47250) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Feedback</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Feedback" fill="#4C97FF">
|
||||
<path d="M12.3811686,14.2770244 C12.3811686,14.3987659 12.3515563,14.506558 12.306433,14.6257633 L11.4998525,16.6002595 C11.2770558,16.478518 10.93299,16.3846755 10.4704753,16.3846755 C10.0234717,16.3846755 9.6949171,16.478518 9.47071028,16.58631 L8.66412979,14.6257633 C8.60490535,14.506558 8.59080429,14.3848164 8.59080429,14.2643429 C8.60490535,14.2503934 8.60490535,14.2237624 8.60490535,14.2098129 L8.60490535,14.1705005 C8.60490535,13.9828155 8.67964095,13.7938625 8.813601,13.6188589 C9.1576668,13.1775457 9.79926492,12.9086997 10.4859864,12.9086997 C11.1727079,12.9086997 11.8143061,13.1775457 12.1428607,13.6188589 C12.2472085,13.7684996 12.3360452,13.9409669 12.3670675,14.103289 C12.3811686,14.1565509 12.3811686,14.2098129 12.3811686,14.2643429 L12.3811686,14.2770244 Z M8.60490535,5.94153049 C8.60490535,5.50782611 8.89115681,5.12865181 9.33393002,4.89024122 C9.59056927,4.7520138 9.91771381,4.9143359 9.91771381,5.18445004 L9.91771381,11.6621167 C9.91771381,11.8168299 9.80490535,11.9550573 9.63851287,11.9918334 C9.46789007,12.0311458 9.3029077,12.0831396 9.14638596,12.1452786 C8.89115681,12.2467299 8.60490535,12.0844078 8.60490535,11.8345839 L8.60490535,5.94153049 Z M12.3670675,5.94153049 L12.3670675,11.8333158 C12.3670675,12.0780671 12.0892767,12.2505343 11.8410981,12.1516193 C11.6775258,12.0844078 11.5054929,12.032414 11.3278196,11.9931016 C11.1529665,11.9550573 11.0373378,11.8054166 11.0373378,11.6443627 L11.0373378,5.18191375 C11.0373378,4.9143359 11.3630722,4.75074565 11.6211216,4.88770493 C12.0709453,5.12611553 12.3670675,5.50528983 12.3670675,5.94153049 Z M10.4859864,1.48528137 C8.82911216,1.48528137 7.48528137,2.53149809 7.48528137,3.82119796 L7.48528137,14.2237624 C7.48528137,14.4786589 7.5148936,14.7335553 7.62065153,14.9757703 L9.1576668,18.7066425 C9.3522614,19.177123 9.87400053,19.4852814 10.4859864,19.4852814 C11.0979723,19.4852814 11.6197115,19.177123 11.8143061,18.7066425 L13.3513213,14.9757703 C13.4556692,14.7335553 13.4852814,14.4786589 13.4852814,14.2237624 L13.4852814,3.82119796 C13.4852814,2.53149809 12.1428607,1.48528137 10.4859864,1.48528137 Z" id="feedback" transform="translate(10.485281, 10.485281) rotate(45.000000) translate(-10.485281, -10.485281) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
@@ -1,11 +1,14 @@
|
||||
import classNames from 'classnames';
|
||||
import {connect} from 'react-redux';
|
||||
import {compose} from 'redux';
|
||||
import {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import bindAll from 'lodash.bindall';
|
||||
import bowser from 'bowser';
|
||||
import React from 'react';
|
||||
|
||||
import VM from 'scratch-vm';
|
||||
|
||||
import Box from '../box/box.jsx';
|
||||
import Button from '../button/button.jsx';
|
||||
import CommunityButton from './community-button.jsx';
|
||||
@@ -25,6 +28,7 @@ import LoginDropdown from './login-dropdown.jsx';
|
||||
import SB3Downloader from '../../containers/sb3-downloader.jsx';
|
||||
import DeletionRestorer from '../../containers/deletion-restorer.jsx';
|
||||
import TurboMode from '../../containers/turbo-mode.jsx';
|
||||
import MenuBarHOC from '../../containers/menu-bar-hoc.jsx';
|
||||
|
||||
import {openTipsLibrary} from '../../reducers/modals';
|
||||
import {setPlayer} from '../../reducers/mode';
|
||||
@@ -55,11 +59,12 @@ import {
|
||||
loginMenuOpen
|
||||
} from '../../reducers/menus';
|
||||
|
||||
import collectMetadata from '../../lib/collect-metadata';
|
||||
|
||||
import styles from './menu-bar.css';
|
||||
|
||||
import helpIcon from '../../lib/assets/icon--tutorials.svg';
|
||||
import mystuffIcon from './icon--mystuff.png';
|
||||
import feedbackIcon from './icon--feedback.svg';
|
||||
import profileIcon from './icon--profile.png';
|
||||
import remixIcon from './icon--remix.svg';
|
||||
import dropdownCaret from './dropdown-caret.svg';
|
||||
@@ -146,10 +151,10 @@ class MenuBar extends React.Component {
|
||||
'handleClickSaveAsCopy',
|
||||
'handleClickSeeCommunity',
|
||||
'handleClickShare',
|
||||
'handleCloseFileMenuAndThen',
|
||||
'handleKeyPress',
|
||||
'handleLanguageMouseUp',
|
||||
'handleRestoreOption',
|
||||
'handleSaveToComputer',
|
||||
'restoreOptionMessage'
|
||||
]);
|
||||
}
|
||||
@@ -160,17 +165,14 @@ class MenuBar extends React.Component {
|
||||
document.removeEventListener('keydown', this.handleKeyPress);
|
||||
}
|
||||
handleClickNew () {
|
||||
let readyToReplaceProject = true;
|
||||
// if the project is dirty, and user owns the project, we will autosave.
|
||||
// but if they are not logged in and can't save, user should consider
|
||||
// downloading or logging in first.
|
||||
// Note that if user is logged in and editing someone else's project,
|
||||
// they'll lose their work.
|
||||
if (this.props.projectChanged && !this.props.canCreateNew) {
|
||||
readyToReplaceProject = confirm( // eslint-disable-line no-alert
|
||||
this.props.intl.formatMessage(sharedMessages.replaceProjectWarning)
|
||||
);
|
||||
}
|
||||
const readyToReplaceProject = this.props.confirmReadyToReplaceProject(
|
||||
this.props.intl.formatMessage(sharedMessages.replaceProjectWarning)
|
||||
);
|
||||
this.props.onRequestCloseFile();
|
||||
if (readyToReplaceProject) {
|
||||
this.props.onClickNew(this.props.canSave && this.props.canCreateNew);
|
||||
@@ -190,8 +192,8 @@ class MenuBar extends React.Component {
|
||||
this.props.onRequestCloseFile();
|
||||
}
|
||||
handleClickSeeCommunity (waitForUpdate) {
|
||||
if (this.props.canSave) { // save before transitioning to project page
|
||||
this.props.autoUpdateProject();
|
||||
if (this.props.shouldSaveBeforeTransition()) {
|
||||
this.props.autoUpdateProject(); // save before transitioning to project page
|
||||
waitForUpdate(true); // queue the transition to project page
|
||||
} else {
|
||||
waitForUpdate(false); // immediately transition to project page
|
||||
@@ -216,12 +218,6 @@ class MenuBar extends React.Component {
|
||||
this.props.onRequestCloseEdit();
|
||||
};
|
||||
}
|
||||
handleCloseFileMenuAndThen (fn) {
|
||||
return () => {
|
||||
this.props.onRequestCloseFile();
|
||||
fn();
|
||||
};
|
||||
}
|
||||
handleKeyPress (event) {
|
||||
const modifier = bowser.mac ? event.metaKey : event.ctrlKey;
|
||||
if (modifier && event.key === 's') {
|
||||
@@ -229,6 +225,16 @@ class MenuBar extends React.Component {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
handleSaveToComputer (downloadProjectCallback) {
|
||||
return () => {
|
||||
this.props.onRequestCloseFile();
|
||||
downloadProjectCallback();
|
||||
if (this.props.onProjectTelemetryEvent) {
|
||||
const metadata = collectMetadata(this.props.vm, this.props.projectTitle, this.props.locale);
|
||||
this.props.onProjectTelemetryEvent('projectDidSave', metadata);
|
||||
}
|
||||
};
|
||||
}
|
||||
handleLanguageMouseUp (e) {
|
||||
if (!this.props.languageMenuOpen) {
|
||||
this.props.onClickLanguage(e);
|
||||
@@ -385,27 +391,25 @@ class MenuBar extends React.Component {
|
||||
</MenuSection>
|
||||
)}
|
||||
<MenuSection>
|
||||
<SBFileUploader onUpdateProjectTitle={this.props.onUpdateProjectTitle}>
|
||||
<SBFileUploader
|
||||
canSave={this.props.canSave}
|
||||
userOwnsProject={this.props.userOwnsProject}
|
||||
onUpdateProjectTitle={this.props.onUpdateProjectTitle}
|
||||
>
|
||||
{(className, renderFileInput, loadProject) => (
|
||||
<MenuItem
|
||||
className={className}
|
||||
onClick={loadProject}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Load from your computer"
|
||||
description={
|
||||
'Menu bar item for uploading a project from your computer'
|
||||
}
|
||||
id="gui.menuBar.uploadFromComputer"
|
||||
/>
|
||||
{this.props.intl.formatMessage(sharedMessages.loadFromComputerTitle)}
|
||||
{renderFileInput()}
|
||||
</MenuItem>
|
||||
)}
|
||||
</SBFileUploader>
|
||||
<SB3Downloader>{(className, downloadProject) => (
|
||||
<SB3Downloader>{(className, downloadProjectCallback) => (
|
||||
<MenuItem
|
||||
className={className}
|
||||
onClick={this.handleCloseFileMenuAndThen(downloadProject)}
|
||||
onClick={this.handleSaveToComputer(downloadProjectCallback)}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Save to your computer"
|
||||
@@ -638,25 +642,6 @@ class MenuBar extends React.Component {
|
||||
) : (
|
||||
// ******** no login session is available, so don't show login stuff
|
||||
<React.Fragment>
|
||||
<div className={classNames(styles.menuBarItem, styles.feedbackButtonWrapper)}>
|
||||
<a
|
||||
className={styles.feedbackLink}
|
||||
href="https://scratch.mit.edu/discuss/topic/312261/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<Button
|
||||
className={styles.feedbackButton}
|
||||
iconSrc={feedbackIcon}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Give Feedback"
|
||||
description="Label for feedback form modal button"
|
||||
id="gui.menuBar.giveFeedback"
|
||||
/>
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
{this.props.showComingSoon ? (
|
||||
<React.Fragment>
|
||||
<MenuBarItemTooltip id="mystuff">
|
||||
@@ -720,6 +705,7 @@ MenuBar.propTypes = {
|
||||
canSave: PropTypes.bool,
|
||||
canShare: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
confirmReadyToReplaceProject: PropTypes.func,
|
||||
editMenuOpen: PropTypes.bool,
|
||||
enableCommunity: PropTypes.bool,
|
||||
fileMenuOpen: PropTypes.bool,
|
||||
@@ -729,6 +715,7 @@ MenuBar.propTypes = {
|
||||
isShowingProject: PropTypes.bool,
|
||||
isUpdating: PropTypes.bool,
|
||||
languageMenuOpen: PropTypes.bool,
|
||||
locale: PropTypes.string.isRequired,
|
||||
loginMenuOpen: PropTypes.bool,
|
||||
onClickAccount: PropTypes.func,
|
||||
onClickEdit: PropTypes.func,
|
||||
@@ -743,6 +730,7 @@ MenuBar.propTypes = {
|
||||
onLogOut: PropTypes.func,
|
||||
onOpenRegistration: PropTypes.func,
|
||||
onOpenTipLibrary: PropTypes.func,
|
||||
onProjectTelemetryEvent: PropTypes.func,
|
||||
onRequestCloseAccount: PropTypes.func,
|
||||
onRequestCloseEdit: PropTypes.func,
|
||||
onRequestCloseFile: PropTypes.func,
|
||||
@@ -752,19 +740,21 @@ MenuBar.propTypes = {
|
||||
onShare: PropTypes.func,
|
||||
onToggleLoginOpen: PropTypes.func,
|
||||
onUpdateProjectTitle: PropTypes.func,
|
||||
projectChanged: PropTypes.bool,
|
||||
projectTitle: PropTypes.string,
|
||||
renderLogin: PropTypes.func,
|
||||
sessionExists: PropTypes.bool,
|
||||
shouldSaveBeforeTransition: PropTypes.func,
|
||||
showComingSoon: PropTypes.bool,
|
||||
username: PropTypes.string
|
||||
userOwnsProject: PropTypes.bool,
|
||||
username: PropTypes.string,
|
||||
vm: PropTypes.instanceOf(VM).isRequired
|
||||
};
|
||||
|
||||
MenuBar.defaultProps = {
|
||||
onShare: () => {}
|
||||
};
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const loadingState = state.scratchGui.projectState.loadingState;
|
||||
const user = state.session && state.session.session && state.session.session.user;
|
||||
return {
|
||||
@@ -775,11 +765,14 @@ const mapStateToProps = state => {
|
||||
isUpdating: getIsUpdating(loadingState),
|
||||
isShowingProject: getIsShowingProject(loadingState),
|
||||
languageMenuOpen: languageMenuOpen(state),
|
||||
locale: state.locales.locale,
|
||||
loginMenuOpen: loginMenuOpen(state),
|
||||
projectChanged: state.scratchGui.projectChanged,
|
||||
projectTitle: state.scratchGui.projectTitle,
|
||||
sessionExists: state.session && typeof state.session.session !== 'undefined',
|
||||
username: user ? user.username : null
|
||||
username: user ? user.username : null,
|
||||
userOwnsProject: ownProps.authorUsername && user &&
|
||||
(ownProps.authorUsername === user.username),
|
||||
vm: state.scratchGui.vm
|
||||
};
|
||||
};
|
||||
|
||||
@@ -803,7 +796,11 @@ const mapDispatchToProps = dispatch => ({
|
||||
onSeeCommunity: () => dispatch(setPlayer(true))
|
||||
});
|
||||
|
||||
export default injectIntl(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(MenuBar));
|
||||
export default compose(
|
||||
injectIntl,
|
||||
MenuBarHOC,
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)
|
||||
)(MenuBar);
|
||||
@@ -37,6 +37,10 @@
|
||||
background-color: $ui-black-transparent;
|
||||
}
|
||||
|
||||
.menu-item.hoverable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-section {
|
||||
border-top: 1px solid $ui-black-transparent;
|
||||
}
|
||||
@@ -39,7 +39,11 @@ const MenuItem = ({
|
||||
onClick
|
||||
}) => (
|
||||
<li
|
||||
className={classNames(styles.menuItem, className)}
|
||||
className={classNames(
|
||||
styles.menuItem,
|
||||
styles.hoverable,
|
||||
className
|
||||
)}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||
import Draggable from 'react-draggable';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import {ContextMenuTrigger} from 'react-contextmenu';
|
||||
import {ContextMenu, MenuItem} from '../context-menu/context-menu.jsx';
|
||||
import {BorderedMenuItem, ContextMenu, MenuItem} from '../context-menu/context-menu.jsx';
|
||||
import Box from '../box/box.jsx';
|
||||
import DefaultMonitor from './default-monitor.jsx';
|
||||
import LargeMonitor from './large-monitor.jsx';
|
||||
@@ -84,6 +84,14 @@ const MonitorComponent = props => (
|
||||
id="gui.monitor.contextMenu.slider"
|
||||
/>
|
||||
</MenuItem>}
|
||||
{props.onSliderPromptOpen && props.mode === 'slider' &&
|
||||
<BorderedMenuItem onClick={props.onSliderPromptOpen}>
|
||||
<FormattedMessage
|
||||
defaultMessage="change slider range"
|
||||
description="Menu item to change the slider range"
|
||||
id="gui.monitor.contextMenu.sliderRange"
|
||||
/>
|
||||
</BorderedMenuItem>}
|
||||
{props.onImport &&
|
||||
<MenuItem onClick={props.onImport}>
|
||||
<FormattedMessage
|
||||
@@ -122,7 +130,8 @@ MonitorComponent.propTypes = {
|
||||
onNextMode: PropTypes.func.isRequired,
|
||||
onSetModeToDefault: PropTypes.func,
|
||||
onSetModeToLarge: PropTypes.func,
|
||||
onSetModeToSlider: PropTypes.func
|
||||
onSetModeToSlider: PropTypes.func,
|
||||
onSliderPromptOpen: PropTypes.func
|
||||
};
|
||||
|
||||
MonitorComponent.defaultProps = {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
@import "../../css/colors.css";
|
||||
@import "../../css/units.css";
|
||||
|
||||
.modal-content {
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.body {
|
||||
background: $ui-white;
|
||||
padding: 1.5rem 2.25rem;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: 500;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
|
||||
.min-input, .max-input {
|
||||
margin-bottom: 1.5rem;
|
||||
width: 100%;
|
||||
border: 1px solid $ui-black-transparent;
|
||||
border-radius: 5px;
|
||||
padding: 0 1rem;
|
||||
height: 3rem;
|
||||
color: $text-primary-transparent;
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
.button-row {
|
||||
font-weight: bolder;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.button-row button {
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.25rem;
|
||||
background: white;
|
||||
border: 1px solid $ui-black-transparent;
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.button-row button.ok-button {
|
||||
background: $motion-primary;
|
||||
border: $motion-primary;
|
||||
color: white;
|
||||
}
|
||||
|
||||
[dir="ltr"] .button-row button + button {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
[dir="rtl"] .button-row button + button {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import {defineMessages, FormattedMessage, intlShape, injectIntl} from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import Box from '../box/box.jsx';
|
||||
import Modal from '../../containers/modal.jsx';
|
||||
|
||||
import styles from './slider-prompt.css';
|
||||
|
||||
|
||||
const messages = defineMessages({
|
||||
minValue: {
|
||||
defaultMessage: 'Minimum value',
|
||||
description: 'Label of slider modal',
|
||||
id: 'gui.sliderModal.min'
|
||||
},
|
||||
maxValue: {
|
||||
defaultMessage: 'Maximum value',
|
||||
description: 'Label of slider modal',
|
||||
id: 'gui.sliderModal.max'
|
||||
},
|
||||
title: {
|
||||
defaultMessage: 'Change slider range',
|
||||
description: 'Title of slider modal',
|
||||
id: 'gui.sliderModal.title'
|
||||
}
|
||||
});
|
||||
|
||||
const SliderPromptComponent = props => (
|
||||
<Modal
|
||||
className={styles.modalContent}
|
||||
contentLabel={props.intl.formatMessage(messages.title)}
|
||||
id="sliderPrompt"
|
||||
onRequestClose={props.onCancel}
|
||||
>
|
||||
<Box className={styles.body}>
|
||||
<Box className={styles.label}>
|
||||
{props.intl.formatMessage(messages.minValue)}
|
||||
</Box>
|
||||
<Box>
|
||||
<input
|
||||
className={styles.minInput}
|
||||
name={props.intl.formatMessage(messages.minValue)}
|
||||
pattern="-?[0-9]*(\.[0-9]+)?"
|
||||
type="text"
|
||||
value={props.minValue}
|
||||
onChange={props.onChangeMin}
|
||||
onKeyPress={props.onKeyPress}
|
||||
/>
|
||||
</Box>
|
||||
<Box className={styles.label}>
|
||||
{props.intl.formatMessage(messages.maxValue)}
|
||||
</Box>
|
||||
<Box>
|
||||
<input
|
||||
className={styles.maxInput}
|
||||
name={props.intl.formatMessage(messages.maxValue)}
|
||||
pattern="-?[0-9]*(\.[0-9]+)?"
|
||||
type="text"
|
||||
value={props.maxValue}
|
||||
onChange={props.onChangeMax}
|
||||
onKeyPress={props.onKeyPress}
|
||||
/>
|
||||
</Box>
|
||||
<Box className={styles.buttonRow}>
|
||||
<button
|
||||
className={styles.cancelButton}
|
||||
onClick={props.onCancel}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
description="Button in prompt for cancelling the dialog"
|
||||
id="gui.sliderPrompt.cancel"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
className={styles.okButton}
|
||||
onClick={props.onOk}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="OK"
|
||||
description="Button in prompt for confirming the dialog"
|
||||
id="gui.sliderPrompt.ok"
|
||||
/>
|
||||
</button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
SliderPromptComponent.propTypes = {
|
||||
intl: intlShape,
|
||||
maxValue: PropTypes.string,
|
||||
minValue: PropTypes.string,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
onChangeMax: PropTypes.func.isRequired,
|
||||
onChangeMin: PropTypes.func.isRequired,
|
||||
onKeyPress: PropTypes.func.isRequired,
|
||||
onOk: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default injectIntl(SliderPromptComponent);
|
||||
@@ -39,6 +39,16 @@
|
||||
height: .5rem;
|
||||
}
|
||||
|
||||
.large {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.large::before, .large::after {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
@@ -71,3 +81,10 @@
|
||||
.spinner.info::after {
|
||||
border-top-color: $ui-white;
|
||||
}
|
||||
|
||||
.spinner.primary {
|
||||
border-color: $motion-transparent;
|
||||
}
|
||||
.spinner.primary::after {
|
||||
border-top-color: $motion-primary;
|
||||
}
|
||||
@@ -8,7 +8,8 @@ const SpinnerComponent = function (props) {
|
||||
const {
|
||||
className,
|
||||
level,
|
||||
small
|
||||
small,
|
||||
large
|
||||
} = props;
|
||||
return (
|
||||
<div
|
||||
@@ -16,18 +17,24 @@ const SpinnerComponent = function (props) {
|
||||
className,
|
||||
styles.spinner,
|
||||
styles[level],
|
||||
{[styles.small]: small}
|
||||
{
|
||||
[styles.small]: small,
|
||||
[styles.large]: large
|
||||
}
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
SpinnerComponent.propTypes = {
|
||||
className: PropTypes.string,
|
||||
large: PropTypes.bool,
|
||||
level: PropTypes.string,
|
||||
small: PropTypes.bool
|
||||
};
|
||||
SpinnerComponent.defaultProps = {
|
||||
className: '',
|
||||
level: 'info'
|
||||
large: false,
|
||||
level: 'info',
|
||||
small: false
|
||||
};
|
||||
export default SpinnerComponent;
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
import CloseButton from '../close-button/close-button.jsx';
|
||||
import styles from './sprite-selector-item.css';
|
||||
import {ContextMenuTrigger} from 'react-contextmenu';
|
||||
import {BorderedMenuItem, ContextMenu, MenuItem} from '../context-menu/context-menu.jsx';
|
||||
import {DangerousMenuItem, ContextMenu, MenuItem} from '../context-menu/context-menu.jsx';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
// react-contextmenu requires unique id to match trigger and context menu
|
||||
@@ -74,13 +74,13 @@ const SpriteSelectorItem = props => (
|
||||
</MenuItem>
|
||||
) : null }
|
||||
{props.onDeleteButtonClick ? (
|
||||
<BorderedMenuItem onClick={props.onDeleteButtonClick}>
|
||||
<DangerousMenuItem onClick={props.onDeleteButtonClick}>
|
||||
<FormattedMessage
|
||||
defaultMessage="delete"
|
||||
description="Menu item to delete in the right click menu"
|
||||
id="gui.spriteSelectorItem.contextMenuDelete"
|
||||
/>
|
||||
</BorderedMenuItem>
|
||||
</DangerousMenuItem>
|
||||
) : null }
|
||||
</ContextMenu>
|
||||
) : null}
|
||||
|
||||
@@ -67,7 +67,7 @@ class AutoScanningStep extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<ScanningStepComponent
|
||||
peripheralButtonImage={this.props.peripheralButtonImage}
|
||||
connectionTipIconURL={this.props.connectionTipIconURL}
|
||||
phase={this.state.phase}
|
||||
title={this.props.extensionId}
|
||||
onRefresh={this.handleRefresh}
|
||||
@@ -78,9 +78,9 @@ class AutoScanningStep extends React.Component {
|
||||
}
|
||||
|
||||
AutoScanningStep.propTypes = {
|
||||
connectionTipIconURL: PropTypes.string,
|
||||
extensionId: PropTypes.string.isRequired,
|
||||
onConnecting: PropTypes.func.isRequired,
|
||||
peripheralButtonImage: PropTypes.string,
|
||||
vm: PropTypes.instanceOf(VM).isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -2,10 +2,8 @@ import bindAll from 'lodash.bindall';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
||||
import {connect} from 'react-redux';
|
||||
import VM from 'scratch-vm';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import backdropLibraryContent from '../lib/libraries/backdrops.json';
|
||||
import backdropTags from '../lib/libraries/backdrop-tags';
|
||||
import LibraryComponent from '../components/library/library.jsx';
|
||||
@@ -34,13 +32,8 @@ class BackdropLibrary extends React.Component {
|
||||
bitmapResolution: item.info.length > 2 ? item.info[2] : 1,
|
||||
skinId: null
|
||||
};
|
||||
this.props.vm.setEditingTarget(this.props.stageID);
|
||||
// Do not switch to stage, just add the backdrop
|
||||
this.props.vm.addBackdrop(item.md5, vmBackdrop);
|
||||
analytics.event({
|
||||
category: 'library',
|
||||
action: 'Select Backdrop',
|
||||
label: item.name
|
||||
});
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
@@ -59,17 +52,7 @@ class BackdropLibrary extends React.Component {
|
||||
BackdropLibrary.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
onRequestClose: PropTypes.func,
|
||||
stageID: PropTypes.string.isRequired,
|
||||
vm: PropTypes.instanceOf(VM).isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
stageID: state.scratchGui.targets.stage.id
|
||||
});
|
||||
|
||||
const mapDispatchToProps = () => ({});
|
||||
|
||||
export default injectIntl(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(BackdropLibrary));
|
||||
export default injectIntl(BackdropLibrary);
|
||||
@@ -83,12 +83,15 @@ class Backpack extends React.Component {
|
||||
}
|
||||
handleDrop (dragInfo) {
|
||||
let payloader = null;
|
||||
let presaveAsset = null;
|
||||
switch (dragInfo.dragType) {
|
||||
case DragConstants.COSTUME:
|
||||
payloader = costumePayload;
|
||||
presaveAsset = dragInfo.payload.asset;
|
||||
break;
|
||||
case DragConstants.SOUND:
|
||||
payloader = soundPayload;
|
||||
presaveAsset = dragInfo.payload.asset;
|
||||
break;
|
||||
case DragConstants.SPRITE:
|
||||
payloader = spritePayload;
|
||||
@@ -102,6 +105,19 @@ class Backpack extends React.Component {
|
||||
// Creating the payload is async, so set loading before starting
|
||||
this.setState({loading: true}, () => {
|
||||
payloader(dragInfo.payload, this.props.vm)
|
||||
.then(payload => {
|
||||
// Force the asset to save to the asset server before storing in backpack
|
||||
// Ensures any asset present in the backpack is also on the asset server
|
||||
if (presaveAsset && !presaveAsset.clean) {
|
||||
return storage.store(
|
||||
presaveAsset.assetType,
|
||||
presaveAsset.dataFormat,
|
||||
presaveAsset.data,
|
||||
presaveAsset.assetId
|
||||
).then(() => payload);
|
||||
}
|
||||
return payload;
|
||||
})
|
||||
.then(payload => saveBackpackObject({
|
||||
host: this.props.host,
|
||||
token: this.props.token,
|
||||
|
||||
@@ -96,6 +96,21 @@ class Blocks extends React.Component {
|
||||
);
|
||||
this.workspace = this.ScratchBlocks.inject(this.blocks, workspaceConfig);
|
||||
|
||||
// Register buttons under new callback keys for creating variables,
|
||||
// lists, and procedures from extensions.
|
||||
|
||||
const toolboxWorkspace = this.workspace.getFlyout().getWorkspace();
|
||||
|
||||
const varListButtonCallback = type =>
|
||||
(() => this.ScratchBlocks.Variables.createVariable(this.workspace, null, type));
|
||||
const procButtonCallback = () => {
|
||||
this.ScratchBlocks.Procedures.createProcedureDefCallback_(this.workspace);
|
||||
};
|
||||
|
||||
toolboxWorkspace.registerButtonCallback('MAKE_A_VARIABLE', varListButtonCallback(''));
|
||||
toolboxWorkspace.registerButtonCallback('MAKE_A_LIST', varListButtonCallback('list'));
|
||||
toolboxWorkspace.registerButtonCallback('MAKE_A_PROCEDURE', procButtonCallback);
|
||||
|
||||
// Store the xml of the toolbox that is actually rendered.
|
||||
// This is used in componentDidUpdate instead of prevProps, because
|
||||
// the xml can change while e.g. on the costumes tab.
|
||||
@@ -162,6 +177,7 @@ class Blocks extends React.Component {
|
||||
this.setLocale();
|
||||
} else {
|
||||
this.props.vm.refreshWorkspace();
|
||||
this.requestToolboxUpdate();
|
||||
}
|
||||
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import {connect} from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
activateDeck,
|
||||
closeCards,
|
||||
shrinkExpandCards,
|
||||
nextStep,
|
||||
prevStep,
|
||||
dragCard,
|
||||
@@ -15,17 +18,43 @@ import {
|
||||
} from '../reducers/modals';
|
||||
|
||||
import CardsComponent from '../components/cards/cards.jsx';
|
||||
import {loadImageData} from '../lib/libraries/decks/translate-image.js';
|
||||
import {notScratchDesktop} from '../lib/isScratchDesktop';
|
||||
|
||||
class Cards extends React.Component {
|
||||
componentDidMount () {
|
||||
if (this.props.locale !== 'en') {
|
||||
loadImageData(this.props.locale);
|
||||
}
|
||||
}
|
||||
componentDidUpdate (prevProps) {
|
||||
if (this.props.locale !== prevProps.locale) {
|
||||
loadImageData(this.props.locale);
|
||||
}
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<CardsComponent {...this.props} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Cards.propTypes = {
|
||||
locale: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
visible: state.scratchGui.cards.visible,
|
||||
content: state.scratchGui.cards.content,
|
||||
activeDeckId: state.scratchGui.cards.activeDeckId,
|
||||
step: state.scratchGui.cards.step,
|
||||
expanded: state.scratchGui.cards.expanded,
|
||||
x: state.scratchGui.cards.x,
|
||||
y: state.scratchGui.cards.y,
|
||||
isRtl: state.locales.isRtl,
|
||||
locale: state.locales.locale,
|
||||
dragging: state.scratchGui.cards.dragging
|
||||
dragging: state.scratchGui.cards.dragging,
|
||||
showVideos: notScratchDesktop()
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
@@ -35,6 +64,7 @@ const mapDispatchToProps = dispatch => ({
|
||||
dispatch(closeCards());
|
||||
},
|
||||
onCloseCards: () => dispatch(closeCards()),
|
||||
onShrinkExpandCards: () => dispatch(shrinkExpandCards()),
|
||||
onNextStep: () => dispatch(nextStep()),
|
||||
onPrevStep: () => dispatch(prevStep()),
|
||||
onDrag: (e_, data) => dispatch(dragCard(data.x, data.y)),
|
||||
@@ -45,4 +75,4 @@ const mapDispatchToProps = dispatch => ({
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(CardsComponent);
|
||||
)(Cards);
|
||||
@@ -107,15 +107,15 @@ class ConnectionModal extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<ConnectionModalComponent
|
||||
connectingMessage={this.state.extension.connectingMessage}
|
||||
connectingMessage={this.state.extension && this.state.extension.connectingMessage}
|
||||
connectionIconURL={this.state.extension && this.state.extension.connectionIconURL}
|
||||
connectionSmallIconURL={this.state.extension && this.state.extension.connectionSmallIconURL}
|
||||
connectionTipIconURL={this.state.extension && this.state.extension.connectionTipIconURL}
|
||||
extensionId={this.props.extensionId}
|
||||
name={this.state.extension.name}
|
||||
peripheralButtonImage={this.state.extension.peripheralButtonImage}
|
||||
peripheralImage={this.state.extension.peripheralImage}
|
||||
name={this.state.extension && this.state.extension.name}
|
||||
phase={this.state.phase}
|
||||
smallPeripheralImage={this.state.extension.smallPeripheralImage}
|
||||
title={this.props.extensionId}
|
||||
useAutoScan={this.state.extension.useAutoScan}
|
||||
useAutoScan={this.state.extension && this.state.extension.useAutoScan}
|
||||
vm={this.props.vm}
|
||||
onCancel={this.handleCancel}
|
||||
onConnected={this.handleConnected}
|
||||
|
||||
@@ -4,7 +4,6 @@ import React from 'react';
|
||||
import VM from 'scratch-vm';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import ControlsComponent from '../components/controls/controls.jsx';
|
||||
|
||||
class Controls extends React.Component {
|
||||
@@ -24,19 +23,11 @@ class Controls extends React.Component {
|
||||
this.props.vm.start();
|
||||
}
|
||||
this.props.vm.greenFlag();
|
||||
analytics.event({
|
||||
category: 'general',
|
||||
action: 'Green Flag'
|
||||
});
|
||||
}
|
||||
}
|
||||
handleStopAllClick (e) {
|
||||
e.preventDefault();
|
||||
this.props.vm.stopAll();
|
||||
analytics.event({
|
||||
category: 'general',
|
||||
action: 'Stop Button'
|
||||
});
|
||||
}
|
||||
render () {
|
||||
const {
|
||||
|
||||
@@ -4,7 +4,6 @@ import React from 'react';
|
||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
||||
import VM from 'scratch-vm';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import costumeLibraryContent from '../lib/libraries/costumes.json';
|
||||
import spriteTags from '../lib/libraries/sprite-tags';
|
||||
import LibraryComponent from '../components/library/library.jsx';
|
||||
@@ -38,11 +37,6 @@ class CostumeLibrary extends React.PureComponent {
|
||||
skinId: null
|
||||
};
|
||||
this.props.vm.addCostumeFromLibrary(item.md5, vmCostume);
|
||||
analytics.event({
|
||||
category: 'library',
|
||||
action: 'Select Costume',
|
||||
label: item.name
|
||||
});
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,6 @@ import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
||||
|
||||
import extensionLibraryContent from '../lib/libraries/extensions/index.jsx';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import LibraryComponent from '../components/library/library.jsx';
|
||||
import extensionIcon from '../components/action-menu/icon--sprite.svg';
|
||||
|
||||
@@ -46,18 +45,6 @@ class ExtensionLibrary extends React.PureComponent {
|
||||
});
|
||||
}
|
||||
}
|
||||
let gaLabel = '';
|
||||
if (typeof (item.name) === 'string') {
|
||||
gaLabel = item.name;
|
||||
} else {
|
||||
// Name is localized, get the default message for the gaLabel
|
||||
gaLabel = item.name.props.defaultMessage;
|
||||
}
|
||||
analytics.event({
|
||||
category: 'library',
|
||||
action: 'Select Extension',
|
||||
label: gaLabel
|
||||
});
|
||||
}
|
||||
render () {
|
||||
const extensionLibraryThumbnailData = extensionLibraryContent.map(extension => ({
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import {connect} from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import bindAll from 'lodash.bindall';
|
||||
import React from 'react';
|
||||
|
||||
const MenuBarHOC = function (WrappedComponent) {
|
||||
class MenuBarContainer extends React.PureComponent {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
bindAll(this, [
|
||||
'confirmReadyToReplaceProject',
|
||||
'shouldSaveBeforeTransition'
|
||||
]);
|
||||
}
|
||||
confirmReadyToReplaceProject (message) {
|
||||
let readyToReplaceProject = true;
|
||||
if (this.props.projectChanged && !this.props.canCreateNew) {
|
||||
readyToReplaceProject = this.props.confirmWithMessage(message);
|
||||
}
|
||||
return readyToReplaceProject;
|
||||
}
|
||||
shouldSaveBeforeTransition () {
|
||||
return (this.props.canSave && this.props.projectChanged);
|
||||
}
|
||||
render () {
|
||||
const {
|
||||
/* eslint-disable no-unused-vars */
|
||||
projectChanged,
|
||||
/* eslint-enable no-unused-vars */
|
||||
...props
|
||||
} = this.props;
|
||||
return (<WrappedComponent
|
||||
confirmReadyToReplaceProject={this.confirmReadyToReplaceProject}
|
||||
shouldSaveBeforeTransition={this.shouldSaveBeforeTransition}
|
||||
{...props}
|
||||
/>);
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarContainer.propTypes = {
|
||||
canCreateNew: PropTypes.bool,
|
||||
canSave: PropTypes.bool,
|
||||
confirmWithMessage: PropTypes.func,
|
||||
projectChanged: PropTypes.bool
|
||||
};
|
||||
MenuBarContainer.defaultProps = {
|
||||
// default to using standard js confirm
|
||||
confirmWithMessage: message => (confirm(message)) // eslint-disable-line no-alert
|
||||
};
|
||||
const mapStateToProps = state => ({
|
||||
projectChanged: state.scratchGui.projectChanged
|
||||
});
|
||||
const mapDispatchToProps = () => ({});
|
||||
// Allow incoming props to override redux-provided props. Used to mock in tests.
|
||||
const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(
|
||||
{}, stateProps, dispatchProps, ownProps
|
||||
);
|
||||
return connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
mergeProps
|
||||
)(MenuBarContainer);
|
||||
};
|
||||
|
||||
export default MenuBarHOC;
|
||||
@@ -9,6 +9,7 @@ import {addMonitorRect, getInitialPosition, resizeMonitorRect, removeMonitorRect
|
||||
import {getVariable, setVariableValue} from '../lib/variable-utils';
|
||||
import importCSV from '../lib/import-csv';
|
||||
import downloadBlob from '../lib/download-blob';
|
||||
import SliderPrompt from './slider-prompt.jsx';
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {Map} from 'immutable';
|
||||
@@ -42,10 +43,16 @@ class Monitor extends React.Component {
|
||||
'handleSetModeToDefault',
|
||||
'handleSetModeToLarge',
|
||||
'handleSetModeToSlider',
|
||||
'handleSliderPromptClose',
|
||||
'handleSliderPromptOk',
|
||||
'handleSliderPromptOpen',
|
||||
'handleImport',
|
||||
'handleExport',
|
||||
'setElement'
|
||||
]);
|
||||
this.state = {
|
||||
sliderPrompt: false
|
||||
};
|
||||
}
|
||||
componentDidMount () {
|
||||
let rect;
|
||||
@@ -135,6 +142,23 @@ class Monitor extends React.Component {
|
||||
mode: 'slider'
|
||||
}));
|
||||
}
|
||||
handleSliderPromptClose () {
|
||||
this.setState({sliderPrompt: false});
|
||||
}
|
||||
handleSliderPromptOpen () {
|
||||
this.setState({sliderPrompt: true});
|
||||
}
|
||||
handleSliderPromptOk (min, max, isDiscrete) {
|
||||
const realMin = Math.min(min, max);
|
||||
const realMax = Math.max(min, max);
|
||||
this.props.vm.runtime.requestUpdateMonitor(Map({
|
||||
id: this.props.id,
|
||||
sliderMin: realMin,
|
||||
sliderMax: realMax,
|
||||
isDiscrete: isDiscrete
|
||||
}));
|
||||
this.handleSliderPromptClose();
|
||||
}
|
||||
setElement (monitorElt) {
|
||||
this.element = monitorElt;
|
||||
}
|
||||
@@ -164,25 +188,35 @@ class Monitor extends React.Component {
|
||||
const showSliderOption = availableModes(this.props.opcode).indexOf('slider') !== -1;
|
||||
const isList = this.props.mode === 'list';
|
||||
return (
|
||||
<MonitorComponent
|
||||
componentRef={this.setElement}
|
||||
{...monitorProps}
|
||||
draggable={this.props.draggable}
|
||||
height={this.props.height}
|
||||
isDiscrete={this.props.isDiscrete}
|
||||
max={this.props.max}
|
||||
min={this.props.min}
|
||||
mode={this.props.mode}
|
||||
targetId={this.props.targetId}
|
||||
width={this.props.width}
|
||||
onDragEnd={this.handleDragEnd}
|
||||
onExport={isList ? this.handleExport : null}
|
||||
onImport={isList ? this.handleImport : null}
|
||||
onNextMode={this.handleNextMode}
|
||||
onSetModeToDefault={isList ? null : this.handleSetModeToDefault}
|
||||
onSetModeToLarge={isList ? null : this.handleSetModeToLarge}
|
||||
onSetModeToSlider={showSliderOption ? this.handleSetModeToSlider : null}
|
||||
/>
|
||||
<React.Fragment>
|
||||
{this.state.sliderPrompt && <SliderPrompt
|
||||
isDiscrete={this.props.isDiscrete}
|
||||
maxValue={parseFloat(this.props.max)}
|
||||
minValue={parseFloat(this.props.min)}
|
||||
onCancel={this.handleSliderPromptClose}
|
||||
onOk={this.handleSliderPromptOk}
|
||||
/>}
|
||||
<MonitorComponent
|
||||
componentRef={this.setElement}
|
||||
{...monitorProps}
|
||||
draggable={this.props.draggable}
|
||||
height={this.props.height}
|
||||
isDiscrete={this.props.isDiscrete}
|
||||
max={this.props.max}
|
||||
min={this.props.min}
|
||||
mode={this.props.mode}
|
||||
targetId={this.props.targetId}
|
||||
width={this.props.width}
|
||||
onDragEnd={this.handleDragEnd}
|
||||
onExport={isList ? this.handleExport : null}
|
||||
onImport={isList ? this.handleImport : null}
|
||||
onNextMode={this.handleNextMode}
|
||||
onSetModeToDefault={isList ? null : this.handleSetModeToDefault}
|
||||
onSetModeToLarge={isList ? null : this.handleSetModeToLarge}
|
||||
onSetModeToSlider={showSliderOption ? this.handleSetModeToSlider : null}
|
||||
onSliderPromptOpen={this.handleSliderPromptOpen}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import log from '../lib/log';
|
||||
import sharedMessages from '../lib/shared-messages';
|
||||
|
||||
@@ -95,21 +94,28 @@ class SBFileUploader extends React.Component {
|
||||
intl,
|
||||
isShowingWithoutId,
|
||||
loadingState,
|
||||
projectChanged
|
||||
projectChanged,
|
||||
userOwnsProject
|
||||
} = this.props;
|
||||
|
||||
const thisFileInput = e.target;
|
||||
if (thisFileInput.files) { // Don't attempt to load if no file was selected
|
||||
this.fileToUpload = thisFileInput.files[0];
|
||||
|
||||
// Allow upload to continue only after confirmation if the project
|
||||
// has changed and is not showing with ID. If it has an ID, this operation
|
||||
// does not currently overwrite that project, so it is safe to do without confirmation.
|
||||
const uploadAllowed = (isShowingWithoutId && projectChanged) ?
|
||||
confirm(intl.formatMessage(sharedMessages.replaceProjectWarning)) : // eslint-disable-line no-alert
|
||||
true;
|
||||
|
||||
if (uploadAllowed) this.props.requestProjectUpload(loadingState);
|
||||
// If user owns the project, or user has changed the project,
|
||||
// we must confirm with the user that they really intend to replace it.
|
||||
// (If they don't own the project and haven't changed it, no need to confirm.)
|
||||
let uploadAllowed = true;
|
||||
if (userOwnsProject || (projectChanged && isShowingWithoutId)) {
|
||||
uploadAllowed = confirm( // eslint-disable-line no-alert
|
||||
intl.formatMessage(sharedMessages.replaceProjectWarning)
|
||||
);
|
||||
}
|
||||
if (uploadAllowed) {
|
||||
this.props.requestProjectUpload(loadingState);
|
||||
} else {
|
||||
this.props.closeFileMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
// called when file upload raw data is available in the reader
|
||||
@@ -119,17 +125,6 @@ class SBFileUploader extends React.Component {
|
||||
const filename = this.fileToUpload && this.fileToUpload.name;
|
||||
this.props.vm.loadProject(this.reader.result)
|
||||
.then(() => {
|
||||
analytics.event({
|
||||
category: 'project',
|
||||
action: 'Import Project File',
|
||||
nonInteraction: true
|
||||
});
|
||||
// Remove the hash if any (without triggering a hash change event or a reload)
|
||||
try { // Can fail e.g. when GUI is loaded from static file (integration tests)
|
||||
history.replaceState({}, document.title, '.');
|
||||
} catch {
|
||||
// No fallback, just do not trigger promise catch below
|
||||
}
|
||||
this.props.onLoadingFinished(this.props.loadingState, true);
|
||||
// Reset the file input after project is loaded
|
||||
// This is necessary in case the user wants to reload a project
|
||||
@@ -176,6 +171,7 @@ SBFileUploader.propTypes = {
|
||||
canSave: PropTypes.bool, // eslint-disable-line react/no-unused-prop-types
|
||||
children: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
closeFileMenu: PropTypes.func,
|
||||
intl: intlShape.isRequired,
|
||||
isLoadingUpload: PropTypes.bool,
|
||||
isShowingWithoutId: PropTypes.bool,
|
||||
@@ -185,6 +181,7 @@ SBFileUploader.propTypes = {
|
||||
onUpdateProjectTitle: PropTypes.func,
|
||||
projectChanged: PropTypes.bool,
|
||||
requestProjectUpload: PropTypes.func,
|
||||
userOwnsProject: PropTypes.bool,
|
||||
vm: PropTypes.shape({
|
||||
loadProject: PropTypes.func
|
||||
})
|
||||
@@ -204,6 +201,7 @@ const mapStateToProps = state => {
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
closeFileMenu: () => dispatch(closeFileMenu()),
|
||||
onLoadingFinished: (loadingState, success) => {
|
||||
dispatch(onLoadedProject(loadingState, ownProps.canSave, success));
|
||||
dispatch(closeLoadingProject());
|
||||
|
||||
@@ -54,10 +54,10 @@ class ScanningStep extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<ScanningStepComponent
|
||||
connectionSmallIconURL={this.props.connectionSmallIconURL}
|
||||
peripheralList={this.state.peripheralList}
|
||||
phase={this.state.phase}
|
||||
scanning={this.state.scanning}
|
||||
smallPeripheralImage={this.props.smallPeripheralImage}
|
||||
title={this.props.extensionId}
|
||||
onConnected={this.props.onConnected}
|
||||
onConnecting={this.props.onConnecting}
|
||||
@@ -68,10 +68,10 @@ class ScanningStep extends React.Component {
|
||||
}
|
||||
|
||||
ScanningStep.propTypes = {
|
||||
connectionSmallIconURL: PropTypes.string,
|
||||
extensionId: PropTypes.string.isRequired,
|
||||
onConnected: PropTypes.func.isRequired,
|
||||
onConnecting: PropTypes.func.isRequired,
|
||||
smallPeripheralImage: PropTypes.string,
|
||||
vm: PropTypes.instanceOf(VM).isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import bindAll from 'lodash.bindall';
|
||||
import SliderPromptComponent from '../components/slider-prompt/slider-prompt.jsx';
|
||||
|
||||
class SliderPrompt extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
bindAll(this, [
|
||||
'handleOk',
|
||||
'handleCancel',
|
||||
'handleChangeMin',
|
||||
'handleChangeMax',
|
||||
'handleKeyPress',
|
||||
'validates',
|
||||
'shouldBeDiscrete'
|
||||
]);
|
||||
|
||||
const {isDiscrete, minValue, maxValue} = this.props;
|
||||
this.state = {
|
||||
// For internal use, convert values to strings based on isDiscrete
|
||||
// This is because `<input />` always returns values as strings.
|
||||
minValue: isDiscrete ? minValue.toFixed(0) : minValue.toFixed(2),
|
||||
maxValue: isDiscrete ? maxValue.toFixed(0) : maxValue.toFixed(2)
|
||||
};
|
||||
}
|
||||
handleKeyPress (event) {
|
||||
if (event.key === 'Enter') this.handleOk();
|
||||
}
|
||||
handleOk () {
|
||||
const {minValue, maxValue} = this.state;
|
||||
if (!this.validates(minValue, maxValue)) {
|
||||
this.props.onCancel();
|
||||
return;
|
||||
}
|
||||
this.props.onOk(
|
||||
parseFloat(minValue),
|
||||
parseFloat(maxValue),
|
||||
this.shouldBeDiscrete(minValue, maxValue));
|
||||
}
|
||||
handleCancel () {
|
||||
this.props.onCancel();
|
||||
}
|
||||
handleChangeMin (e) {
|
||||
this.setState({minValue: e.target.value});
|
||||
}
|
||||
handleChangeMax (e) {
|
||||
this.setState({maxValue: e.target.value});
|
||||
}
|
||||
shouldBeDiscrete (min, max) {
|
||||
return min.indexOf('.') + max.indexOf('.') === -2; // Both -1
|
||||
}
|
||||
validates (min, max) {
|
||||
return isFinite(min) && isFinite(max);
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<SliderPromptComponent
|
||||
maxValue={this.state.maxValue}
|
||||
minValue={this.state.minValue}
|
||||
onCancel={this.handleCancel}
|
||||
onChangeMax={this.handleChangeMax}
|
||||
onChangeMin={this.handleChangeMin}
|
||||
onKeyPress={this.handleKeyPress}
|
||||
onOk={this.handleOk}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SliderPrompt.propTypes = {
|
||||
isDiscrete: PropTypes.bool,
|
||||
maxValue: PropTypes.number,
|
||||
minValue: PropTypes.number,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
onOk: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
SliderPrompt.defaultProps = {
|
||||
maxValue: 100,
|
||||
minValue: 0,
|
||||
isDiscrete: true
|
||||
};
|
||||
|
||||
export default SliderPrompt;
|
||||
@@ -5,7 +5,6 @@ import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
||||
import VM from 'scratch-vm';
|
||||
import AudioEngine from 'scratch-audio';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import LibraryComponent from '../components/library/library.jsx';
|
||||
|
||||
import soundIcon from '../components/asset-panel/icon--sound.svg';
|
||||
@@ -125,11 +124,6 @@ class SoundLibrary extends React.PureComponent {
|
||||
this.props.vm.addSound(vmSound).then(() => {
|
||||
this.props.onNewSound();
|
||||
});
|
||||
analytics.event({
|
||||
category: 'library',
|
||||
action: 'Select Sound',
|
||||
label: soundItem.name
|
||||
});
|
||||
}
|
||||
render () {
|
||||
// @todo need to use this hack to avoid library using md5 for image
|
||||
|
||||
@@ -4,7 +4,6 @@ import React from 'react';
|
||||
import {injectIntl, intlShape, defineMessages} from 'react-intl';
|
||||
import VM from 'scratch-vm';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import spriteLibraryContent from '../lib/libraries/sprites.json';
|
||||
import randomizeSpritePosition from '../lib/randomize-sprite-position';
|
||||
import spriteTags from '../lib/libraries/sprite-tags';
|
||||
@@ -32,11 +31,6 @@ class SpriteLibrary extends React.PureComponent {
|
||||
this.props.vm.addSprite(JSON.stringify(item.json)).then(() => {
|
||||
this.props.onActivateBlocksTab();
|
||||
});
|
||||
analytics.event({
|
||||
category: 'library',
|
||||
action: 'Select Sprite',
|
||||
label: item.name
|
||||
});
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
|
||||
@@ -50,7 +50,7 @@ class StageSelector extends React.Component {
|
||||
'setFileInput'
|
||||
]);
|
||||
}
|
||||
addBackdropFromLibraryItem (item) {
|
||||
addBackdropFromLibraryItem (item, shouldActivateTab = true) {
|
||||
const vmBackdrop = {
|
||||
name: item.name,
|
||||
md5: item.md5,
|
||||
@@ -59,25 +59,30 @@ class StageSelector extends React.Component {
|
||||
bitmapResolution: item.info.length > 2 ? item.info[2] : 1,
|
||||
skinId: null
|
||||
};
|
||||
this.handleNewBackdrop(vmBackdrop);
|
||||
this.handleNewBackdrop(vmBackdrop, shouldActivateTab);
|
||||
}
|
||||
handleClick () {
|
||||
this.props.onSelect(this.props.id);
|
||||
}
|
||||
handleNewBackdrop (backdrops_) {
|
||||
handleNewBackdrop (backdrops_, shouldActivateTab = true) {
|
||||
const backdrops = Array.isArray(backdrops_) ? backdrops_ : [backdrops_];
|
||||
return Promise.all(backdrops.map(backdrop =>
|
||||
this.props.vm.addBackdrop(backdrop.md5, backdrop)
|
||||
)).then(() =>
|
||||
this.props.onActivateTab(COSTUMES_TAB_INDEX)
|
||||
);
|
||||
)).then(() => {
|
||||
if (shouldActivateTab) {
|
||||
return this.props.onActivateTab(COSTUMES_TAB_INDEX);
|
||||
}
|
||||
});
|
||||
}
|
||||
handleSurpriseBackdrop () {
|
||||
handleSurpriseBackdrop (e) {
|
||||
e.stopPropagation(); // Prevent click from falling through to selecting stage.
|
||||
// @todo should this not add a backdrop you already have?
|
||||
const item = backdropLibraryContent[Math.floor(Math.random() * backdropLibraryContent.length)];
|
||||
this.addBackdropFromLibraryItem(item);
|
||||
this.addBackdropFromLibraryItem(item, false);
|
||||
}
|
||||
handleEmptyBackdrop () {
|
||||
handleEmptyBackdrop (e) {
|
||||
e.stopPropagation(); // Prevent click from falling through to stage selector, select it manually below
|
||||
this.props.vm.setEditingTarget(this.props.id);
|
||||
this.handleNewBackdrop(emptyCostume(this.props.intl.formatMessage(sharedMessages.backdrop, {index: 1})));
|
||||
}
|
||||
handleBackdropUpload (e) {
|
||||
@@ -85,6 +90,7 @@ class StageSelector extends React.Component {
|
||||
this.props.onShowImporting();
|
||||
handleFileUpload(e.target, (buffer, fileType, fileName, fileIndex, fileCount) => {
|
||||
costumeUpload(buffer, fileType, storage, vmCostumes => {
|
||||
this.props.vm.setEditingTarget(this.props.id);
|
||||
vmCostumes.forEach((costume, i) => {
|
||||
costume.name = `${fileName}${i ? i + 1 : ''}`;
|
||||
});
|
||||
@@ -96,7 +102,8 @@ class StageSelector extends React.Component {
|
||||
}, this.props.onCloseImporting);
|
||||
}, this.props.onCloseImporting);
|
||||
}
|
||||
handleFileUploadClick () {
|
||||
handleFileUploadClick (e) {
|
||||
e.stopPropagation(); // Prevent click from selecting the stage, that is handled manually in backdrop upload
|
||||
this.fileInput.click();
|
||||
}
|
||||
handleMouseEnter () {
|
||||
|
||||
@@ -112,7 +112,9 @@ class Stage extends React.Component {
|
||||
}
|
||||
startColorPickingLoop () {
|
||||
this.intervalId = setInterval(() => {
|
||||
this.setState({colorInfo: this.getColorInfo(this.pickX, this.pickY)});
|
||||
if (typeof this.pickX === 'number') {
|
||||
this.setState({colorInfo: this.getColorInfo(this.pickX, this.pickY)});
|
||||
}
|
||||
}, 30);
|
||||
}
|
||||
stopColorPickingLoop () {
|
||||
@@ -175,9 +177,11 @@ class Stage extends React.Component {
|
||||
const {x, y} = getEventXY(e);
|
||||
const mousePosition = [x - this.rect.left, y - this.rect.top];
|
||||
|
||||
// Set the pickX/Y for the color picker loop to pick up
|
||||
this.pickX = mousePosition[0];
|
||||
this.pickY = mousePosition[1];
|
||||
if (this.props.isColorPicking) {
|
||||
// Set the pickX/Y for the color picker loop to pick up
|
||||
this.pickX = mousePosition[0];
|
||||
this.pickY = mousePosition[1];
|
||||
}
|
||||
|
||||
if (this.state.mouseDown && !this.state.isDragging) {
|
||||
const distanceFromMouseDown = Math.sqrt(
|
||||
@@ -231,38 +235,11 @@ class Stage extends React.Component {
|
||||
this.onStopDrag(mousePosition[0], mousePosition[1]);
|
||||
}
|
||||
this.props.vm.postIOData('mouse', data);
|
||||
}
|
||||
onMouseDown (e) {
|
||||
this.updateRect();
|
||||
const {x, y} = getEventXY(e);
|
||||
const mousePosition = [x - this.rect.left, y - this.rect.top];
|
||||
if (e.button === 0 || (window.TouchEvent && e instanceof TouchEvent)) {
|
||||
this.setState({
|
||||
mouseDown: true,
|
||||
mouseDownPosition: mousePosition,
|
||||
mouseDownTimeoutId: setTimeout(
|
||||
this.onStartDrag.bind(this, mousePosition[0], mousePosition[1]),
|
||||
400
|
||||
)
|
||||
});
|
||||
}
|
||||
const data = {
|
||||
isDown: true,
|
||||
x: mousePosition[0],
|
||||
y: mousePosition[1],
|
||||
canvasWidth: this.rect.width,
|
||||
canvasHeight: this.rect.height
|
||||
};
|
||||
this.props.vm.postIOData('mouse', data);
|
||||
if (e.preventDefault) {
|
||||
// Prevent default to prevent touch from dragging page
|
||||
e.preventDefault();
|
||||
// But we do want any active input to be blurred
|
||||
if (document.activeElement && document.activeElement.blur) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}
|
||||
if (this.props.isColorPicking) {
|
||||
|
||||
if (this.props.isColorPicking &&
|
||||
mousePosition[0] > 0 && mousePosition[0] < this.rect.width &&
|
||||
mousePosition[1] > 0 && mousePosition[1] < this.rect.height
|
||||
) {
|
||||
const {r, g, b} = this.state.colorInfo.color;
|
||||
const componentToString = c => {
|
||||
const hex = c.toString(16);
|
||||
@@ -271,6 +248,47 @@ class Stage extends React.Component {
|
||||
const colorString = `#${componentToString(r)}${componentToString(g)}${componentToString(b)}`;
|
||||
this.props.onDeactivateColorPicker(colorString);
|
||||
this.setState({colorInfo: null});
|
||||
this.pickX = null;
|
||||
this.pickY = null;
|
||||
}
|
||||
}
|
||||
onMouseDown (e) {
|
||||
this.updateRect();
|
||||
const {x, y} = getEventXY(e);
|
||||
const mousePosition = [x - this.rect.left, y - this.rect.top];
|
||||
if (this.props.isColorPicking) {
|
||||
// Set the pickX/Y for the color picker loop to pick up
|
||||
this.pickX = mousePosition[0];
|
||||
this.pickY = mousePosition[1];
|
||||
// Immediately update the color picker info
|
||||
this.setState({colorInfo: this.getColorInfo(this.pickX, this.pickY)});
|
||||
} else {
|
||||
if (e.button === 0 || (window.TouchEvent && e instanceof TouchEvent)) {
|
||||
this.setState({
|
||||
mouseDown: true,
|
||||
mouseDownPosition: mousePosition,
|
||||
mouseDownTimeoutId: setTimeout(
|
||||
this.onStartDrag.bind(this, mousePosition[0], mousePosition[1]),
|
||||
400
|
||||
)
|
||||
});
|
||||
}
|
||||
const data = {
|
||||
isDown: true,
|
||||
x: mousePosition[0],
|
||||
y: mousePosition[1],
|
||||
canvasWidth: this.rect.width,
|
||||
canvasHeight: this.rect.height
|
||||
};
|
||||
this.props.vm.postIOData('mouse', data);
|
||||
if (e.preventDefault) {
|
||||
// Prevent default to prevent touch from dragging page
|
||||
e.preventDefault();
|
||||
// But we do want any active input to be blurred
|
||||
if (document.activeElement && document.activeElement.blur) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
onWheel (e) {
|
||||
@@ -320,7 +338,6 @@ class Stage extends React.Component {
|
||||
if (this.state.dragId) return;
|
||||
const drawableId = this.renderer.pick(x, y);
|
||||
if (drawableId === null) return;
|
||||
const drawableData = this.renderer.extractDrawable(drawableId, x, y);
|
||||
const targetId = this.props.vm.getTargetIdForDrawableId(drawableId);
|
||||
if (targetId === null) return;
|
||||
|
||||
@@ -332,6 +349,9 @@ class Stage extends React.Component {
|
||||
// Dragging always brings the target to the front
|
||||
target.goToFront();
|
||||
|
||||
// Extract the drawable art
|
||||
const drawableData = this.renderer.extractDrawable(drawableId, x, y);
|
||||
|
||||
this.props.vm.startDrag(targetId);
|
||||
this.setState({
|
||||
isDragging: true,
|
||||
@@ -403,6 +423,7 @@ class Stage extends React.Component {
|
||||
Stage.propTypes = {
|
||||
isColorPicking: PropTypes.bool,
|
||||
isFullScreen: PropTypes.bool.isRequired,
|
||||
isStarted: PropTypes.bool,
|
||||
micIndicator: PropTypes.bool,
|
||||
onActivateColorPicker: PropTypes.func,
|
||||
onDeactivateColorPicker: PropTypes.func,
|
||||
|
||||
@@ -105,7 +105,10 @@ class TargetPane extends React.Component {
|
||||
}
|
||||
}
|
||||
handleSurpriseSpriteClick () {
|
||||
const item = spriteLibraryContent[Math.floor(Math.random() * spriteLibraryContent.length)];
|
||||
const surpriseSprites = spriteLibraryContent.filter(sprite =>
|
||||
(sprite.tags.indexOf('letters') === -1) && (sprite.tags.indexOf('numbers') === -1)
|
||||
);
|
||||
const item = surpriseSprites[Math.floor(Math.random() * surpriseSprites.length)];
|
||||
randomizeSpritePosition(item);
|
||||
this.props.vm.addSprite(JSON.stringify(item.json))
|
||||
.then(this.handleActivateBlocksTab);
|
||||
|
||||
@@ -62,10 +62,16 @@ class TipsLibrary extends React.PureComponent {
|
||||
}
|
||||
render () {
|
||||
const decksLibraryThumbnailData = Object.keys(decksLibraryContent)
|
||||
.filter(id =>
|
||||
.filter(id => {
|
||||
if (notScratchDesktop()) return true; // Do not filter anything in online editor
|
||||
const deck = decksLibraryContent[id];
|
||||
// Scratch Desktop doesn't want tutorials with `requiredProjectId`
|
||||
notScratchDesktop() || !decksLibraryContent[id].hasOwnProperty('requiredProjectId')
|
||||
)
|
||||
if (deck.hasOwnProperty('requiredProjectId')) return false;
|
||||
// Scratch Desktop should not load tutorials that are _only_ videos
|
||||
if (deck.steps.filter(s => s.title).length === 0) return false;
|
||||
// Allow any other tutorials
|
||||
return true;
|
||||
})
|
||||
.map(id => ({
|
||||
rawURL: decksLibraryContent[id].img,
|
||||
id: id,
|
||||
|
||||
@@ -113,7 +113,8 @@ const AppStateHOC = function (WrappedComponent, localesOnly) {
|
||||
}
|
||||
AppStateWrapper.propTypes = {
|
||||
isFullScreen: PropTypes.bool,
|
||||
isPlayerOnly: PropTypes.bool
|
||||
isPlayerOnly: PropTypes.bool,
|
||||
showTelemetryModal: PropTypes.bool
|
||||
};
|
||||
return AppStateWrapper;
|
||||
};
|
||||
|
||||
@@ -246,10 +246,7 @@ export default function (vm) {
|
||||
lookupBlocks = vm.runtime.flyoutBlocks;
|
||||
}
|
||||
const sort = function (options) {
|
||||
options.sort((str1, str2) => str1.localeCompare(str2, [], {
|
||||
sensitivity: 'base',
|
||||
numeric: true
|
||||
}));
|
||||
options.sort(ScratchBlocks.scratchBlocksUtils.compareStrings);
|
||||
};
|
||||
// Get all the stage variables (no lists) so we can add them to menu when the stage is selected.
|
||||
const stageVariableOptions = vm.runtime.getTargetForStage().getAllVariableNamesInScopeByType('');
|
||||
@@ -323,5 +320,26 @@ export default function (vm) {
|
||||
vm.runtime.emit('PLAY_NOTE', noteNum, extensionId);
|
||||
};
|
||||
|
||||
// Use a collator's compare instead of localeCompare which internally
|
||||
// creates a collator. Using this is a lot faster in browsers that create a
|
||||
// collator for every localeCompare call.
|
||||
const collator = new Intl.Collator([], {
|
||||
sensitivity: 'base',
|
||||
numeric: true
|
||||
});
|
||||
ScratchBlocks.scratchBlocksUtils.compareStrings = function (str1, str2) {
|
||||
return collator.compare(str1, str2);
|
||||
};
|
||||
|
||||
// Blocks wants to know if 3D CSS transforms are supported. The cross
|
||||
// section of browsers Scratch supports and browsers that support 3D CSS
|
||||
// transforms will make the return always true.
|
||||
//
|
||||
// Shortcutting to true lets us skip an expensive style recalculation when
|
||||
// first loading the Scratch editor.
|
||||
ScratchBlocks.utils.is3dSupported = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
return ScratchBlocks;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Report a telemetry event.
|
||||
* @param {string} event - one of `projectWasCreated`, `projectDidLoad`, `projectDidSave`, `projectWasUploaded`
|
||||
*/
|
||||
// TODO make a telemetry HOC and move this stuff there
|
||||
const collectMetadata = function (vm, projectName = '', locale = '') {
|
||||
// TODO move most or all of this into a collectMetadata() method on the VM/Runtime
|
||||
const metadata = {
|
||||
projectName: projectName,
|
||||
language: locale,
|
||||
spriteCount: 0,
|
||||
blocksCount: 0,
|
||||
costumesCount: 0,
|
||||
listsCount: 0,
|
||||
scriptCount: 0,
|
||||
soundsCount: 0,
|
||||
variablesCount: 0
|
||||
};
|
||||
|
||||
for (const target of vm.runtime.targets) {
|
||||
++metadata.spriteCount;
|
||||
metadata.blocksCount += Object.keys(target.sprite.blocks._blocks).length;
|
||||
metadata.costumesCount += target.sprite.costumes_.length;
|
||||
metadata.scriptCount += target.sprite.blocks._scripts.length;
|
||||
metadata.soundsCount += target.sprite.sounds.length;
|
||||
for (const variableName in target.variables) {
|
||||
const variable = target.variables[variableName];
|
||||
if (variable.type === 'list') {
|
||||
++metadata.listsCount;
|
||||
} else {
|
||||
++metadata.variablesCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return metadata;
|
||||
};
|
||||
|
||||
export default collectMetadata;
|
||||
@@ -1,42 +0,0 @@
|
||||
<svg version="1.1" id="cat" x="0px" y="0px" width="95px" height="111px" viewBox="0 0 95 111" enable-background="new 0 0 95 111" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<g id="Layer_3">
|
||||
<path fill="#FAA51D" stroke="#000000" d="M22.462,79.039c-2.415-0.451-5.304-1.309-7.742-3.503
		C9.268,70.629,7.526,62.535,3.672,64.622c-3.856,2.088-3.782,15.165,8.353,19.194c4.182,1.391,7.998,1.396,11.091,1.312
		c0.811-0.025,7.717-0.654,10.079-4.074c2.361-3.42,0.719-4.272-0.09-4.744C32.295,75.838,25.878,79.677,22.462,79.039z"/>
|
||||
<path fill="#FFFFFF" d="M4.236,64.877c-1.989,0.613-3.075,4.998-2.076,8.484c0.998,3.49,2.634,5.022,3.863,6.398
		c1.528,1.038-0.72-2.402,1.361-4.15c2.075-1.744,5.733-0.914,5.733-0.914s-2.909-3.987-4.57-6.396
		C6.975,65.988,6.359,64.375,4.236,64.877z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FAA51D" d="M38.217,86.756c0,0-8.832,6.2-17.071,8.412l0.086,0.215c1.247,1.824,5.87,7.497-0.334,9.496
		c-5.333,1.717-15.12-13.104-10.821-15.902c2.626-1.713,4.892-0.252,4.892-0.252s3.474-1.07,6.001-2.345
		c4.303-2.161,5.784-3.453,5.784-3.453s4.184-4.306,6.856-4.137C36.281,78.96,41.669,83.504,38.217,86.756z"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M21.232,95.383c1.247,1.824,5.87,7.497-0.334,9.496
		c-5.333,1.717-15.329-13.344-11.03-16.145c2.626-1.713,5.101-0.01,5.101-0.01s3.474-1.072,6.001-2.348
		c4.303-2.161,5.784-3.453,5.784-3.453"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M38.217,86.756c0,0-10.123,7.107-18.804,8.819"/>
|
||||
</g>
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M52.169,74.885c0,0,1.235,0.165,4.744,3.676
	c3.509,3.508,6.026,2.16,8.911,0.724c2.877-1.443,10.537-6.126,6.49-9.817c-4.049-3.688-6.207,1.146-9.715,2.405
	c-3.512,1.26-5.061-2.487-6.858-4.287c-0.589-0.593-1.188-1.099-1.729-1.505c0,0-0.971-0.76-1.906,2.79
	C51.172,72.412,50.162,73.415,52.169,74.885z"/>
|
||||
<g id="Layer_2_1_">
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M46.753,82.012c1.188-0.912,2.397-2.402,3.951-4.713
		c1.296-1.927,2.7-5.578,2.7-5.578c0.875-2.521,1.934-6.576-1.902-7.296c-1.553-0.291-4.079-0.098-7.67-0.776
		c-3.593-0.681-6.798-2.522-9.517,2.233c-2.718,4.757-9.59,8.271-1.056,16.563c0,0,4.901,3.842,10.764,9.639
		c4.831,4.775,12.045,10.602,12.045,10.602s18.972,2.188,19.535-0.693c1.922-9.79-14.777-6.911-14.777-6.911
		s-4.605-3.933-6.725-5.794c-3.478-3.059-11.125-10.771-11.125-10.771"/>
|
||||
<path fill="#FFFFFF" d="M51.253,75.434c0,0,2.47-2.66-2.469-5.317c-4.939-2.657-7.213-0.017-8.739,1.521
		c-2.644,2.655,3.443,6.611,3.443,6.611l3.176,3.204c0,0,1.738-1.647,2.499-2.979C50.036,77.26,51.253,75.434,51.253,75.434"/>
|
||||
</g>
|
||||
<g id="Layer_8"/>
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M29.926,73.218c0.749-0.571,2.889-2.202,4.854-3.657
	c2.428-1.799,6.117-5.849,1.077-7.646c-5.04-1.801-7.507,1.604-11.519,4.946c-2.159,1.801-5.308,2.699-4.319,6.209
	c0.993,3.511,4.862,13.408,11.789,10.17c6.929-3.239-1.799-9.18-3.06-11.157"/>
|
||||
<g id="Layer_2">
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M52.709,14.156c-1.54-0.143-4.75-0.316-6.518-0.231
		c-4.728,0.225-9.224,1.928-9.224,1.928L23.949,7.357l2.235,18.906c0.646-0.782-10.555,12.804-3.479,24.224
		c7.08,11.426,22.233,16.518,40.988,12.792c18.755-3.729,23.229-14.531,21.986-20.246c-1.242-5.714-8.322-7.823-8.322-7.823
		s-0.09-4.48-3.328-9.97c-1.926-3.268-8.348-8.041-8.348-8.041L62.822,5.647l-7.452,7.204L52.709,14.156z"/>
|
||||
<path fill="#FFFFFF" d="M76.42,35.066l-2.482-2.064l-9.115,2.661c0,0,0,3.419-4.367,4.367c-4.37,0.951-11.211-2.277-11.211-2.277
		L41.46,41.17c0,0-8.437,0.928-8.739,6.081C32.048,58.704,46.1,63.479,51.425,63.783c2.905,0.167,8.235-0.338,12.277-1.141
		c17.752-3.234,22.551-13.919,21.31-19.635c-1.242-5.714-7.978-7.196-7.978-7.196L76.42,35.066z"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M10.673,46.155c0,0,4.107,0.374,5.974,0.268
		c1.865-0.107,5.492-0.587,5.492-0.587"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M81.656,40.671c0,0,4.549-0.743,6.859-1.549
		c2.715-0.942,4.543-2.545,4.543-2.545"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M22.337,41.909c0,0-2.384-1.777-6.117-3.43
		c-4.134-1.831-6.405-2.303-6.405-2.303"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M82.117,46.622c0,0,2.726,1.104,5.533,1.385
		c2.77,0.276,4.646,0.11,4.646,0.11"/>
|
||||
<path fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" d="M52.35,14.212
		c2.84,0.7,3.887,1.469,3.887,1.469"/>
|
||||
<line fill="none" stroke="#000000" x1="33.898" y1="13.684" x2="39.956" y2="18.042"/>
|
||||
</g>
|
||||
<g id="Layer_5">
|
||||
<path fill="#FFFFFF" stroke="#231F20" d="M71.84,25.366c2.924,4.479,3.033,9.591,0.242,11.415
		c-2.793,1.825-7.426-0.332-10.354-4.813c-2.933-4.48-3.037-9.589-0.244-11.415C64.275,18.73,68.913,20.884,71.84,25.366z"/>
|
||||
<path fill="#231F20" d="M71.089,32.522c0,1.08-0.802,1.956-1.8,1.956c-0.993,0-1.803-0.877-1.803-1.956
		c0-1.08,0.81-1.958,1.803-1.958C70.287,30.564,71.089,31.442,71.089,32.522"/>
|
||||
</g>
|
||||
<g id="Layer_7">
|
||||
<path fill="#FFFFFF" stroke="#231F20" d="M47.867,28.619c2.926,4.48,2.619,9.862-0.681,12.015
		c-3.302,2.159-8.351,0.272-11.276-4.208c-2.928-4.48-2.624-9.86,0.678-12.017C39.891,22.253,44.938,24.137,47.867,28.619z"/>
|
||||
<path fill="#231F20" d="M46.079,34.507c0,1.081-0.803,1.957-1.801,1.957c-0.992,0-1.803-0.878-1.803-1.957
		c0-1.08,0.811-1.957,1.803-1.957C45.274,32.55,46.079,33.427,46.079,34.507"/>
|
||||
</g>
|
||||
<path fill="#5E4A42" stroke="#000000" d="M59.766,37.926c1.854,0,4.555-0.284,4.697,0.569c0.143,0.855-1.709,4.203-2.988,4.345
	c-1.283,0.142-6.125-2.353-6.195-3.919C55.206,37.355,58.055,37.926,59.766,37.926z"/>
|
||||
<g id="Layer_4">
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M46.774,45.235c0,0,10.347,3.054,14.217,3.897
		c3.868,0.842,10.851,1.684,10.851,1.684s-7.99,10.245-17.328,7.644C45.176,55.863,45.345,49.975,46.774,45.235z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.5 KiB |
@@ -1,37 +0,0 @@
|
||||
<svg version="1.1" id="cat" x="0px" y="0px" width="95px" height="111px" viewBox="0 0 95 111" enable-background="new 0 0 95 111" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<g id="Layer_8">
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M23.754,82.506c-2.871-1.402-10.511-2.518-14.771-6.695
		c-9.431-9.246-3.824-21.732,0.704-21.797c3.611-0.061,3.363,5.482,4.622,11.145c0.875,3.939,1.673,6.988,6.407,9.674
		c4.735,2.688,6.918,2.916,6.918,2.916s3.258,0.791,1.596,2.562C27.568,82.076,23.754,82.506,23.754,82.506z"/>
|
||||
<path fill="#FFFFFF" d="M14.291,66.369c-0.115-0.459-0.222-0.928-0.33-1.413c-1.172-5.271-0.941-10.432-4.303-10.377
		c-3.433,0.05-7.53,7.771-4.19,15.285c0.193-0.143,0.399-0.336,0.569-0.588c0.451-0.664,0.821-2.969,2.654-3.688
		C9.989,65.082,12.778,65.869,14.291,66.369z"/>
|
||||
</g>
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M52.543,61.473c0,0,1.455,2.342,1.519,4.969
	c0.065,2.723-0.351,6.984,1.804,8.158c3.381,1.842,9.959-0.463,10.174,5.191c0.211,5.652-10.152,3.623-13.299,2.547
	c-2.695-0.926-4.559-1.758-5.18-5.182c0,0-3.764-13.969-0.196-15.59C50.933,59.945,52.543,61.473,52.543,61.473z"/>
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M14.61,89.584c0,0,1.504,10.391-5.922,8.387
	c-5.586-1.51-5.705-20.68-0.406-20.691c3.237-0.006,4.425,2.859,4.425,2.859s4.385,4.812,6.95,4.312
	c2.565-0.502,7.978-6.703,7.978-6.703s2.875-2.539,6.146,0.023c3.271,2.561,1.521,6.178,1.521,6.178s-6.07,7.072-11.014,8.072
	c-4.945,1.002-9.375-2.568-11.58-3.451"/>
|
||||
<g id="Layer_6">
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M42.435,76.238c0,0,4.866,4.062,8.166,7.52
		c4.384,4.592-3.339,15.039-3.339,15.039s11.234,6.467,2.998,11c-2.657,1.467-15.661-13.225-15.661-13.225s7.979-7.475,4.972-10.172
		c-4.964-4.449-10.771-4.959-11.6-9.824c-0.502-2.957,0.613-4.502,2.658-7.053c1.354-1.689,2.084-3.182,2.084-3.182
		s1.135-7.238,4.289-8.254c3.153-1.014,8.842,0.057,10.758,0.395c1.914,0.338,6.645,1.877,4.617,9.922c0,0-1.451,3.771-2.789,5.762
		c-1.604,2.389-2.854,3.924-4.08,4.867"/>
|
||||
<path fill="#FFFFFF" d="M50.182,72.631c0,0,2.55-2.748-2.551-5.494c-5.102-2.746-7.449-0.016-9.024,1.572
		c-2.731,2.742,3.334,7.453,3.334,7.453l3.383,2.564c0,0,1.916-1.582,2.701-2.957C48.807,74.396,50.182,72.631,50.182,72.631"/>
|
||||
</g>
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M24.428,65.395c0.939,0.057,3.625,0.213,6.064,0.391
	c3.014,0.217,8.451-0.451,5.801-5.098c-2.649-4.65-6.74-3.674-11.961-3.754c-2.812-0.043-5.785-1.412-7.322,1.895
	c-1.534,3.312-5.051,13.338,2.313,15.396c7.366,2.057,4.618-8.137,4.95-10.457"/>
|
||||
<g id="Layer_2">
|
||||
<path fill="#FAA51D" stroke="#231F20" stroke-width="1.2" d="M51.709,10.156c-1.54-0.143-4.75-0.316-6.518-0.231
		c-4.728,0.225-9.224,1.928-9.224,1.928L22.949,3.357l2.235,18.906c0.646-0.782-10.555,12.804-3.479,24.224
		c7.08,11.426,22.233,16.518,40.988,12.792c18.755-3.728,23.229-14.531,21.986-20.246c-1.242-5.714-8.322-7.823-8.322-7.823
		s-0.09-4.48-3.328-9.97c-1.926-3.268-8.348-8.041-8.348-8.041L61.822,1.647L54.37,8.851L51.709,10.156z"/>
|
||||
<path fill="#FFFFFF" d="M75.42,31.066l-2.483-2.064l-9.115,2.661c0,0,0,3.419-4.367,4.367c-4.37,0.951-11.211-2.277-11.211-2.277
		l-7.784,3.417c0,0-8.437,0.928-8.739,6.081C31.048,54.704,45.1,59.478,50.425,59.783c2.905,0.167,8.235-0.337,12.277-1.14
		c17.752-3.235,22.551-13.92,21.309-19.635c-1.242-5.714-7.977-7.196-7.977-7.196L75.42,31.066z"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M9.673,42.155c0,0,4.107,0.374,5.974,0.268
		c1.865-0.107,5.492-0.587,5.492-0.587"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M80.656,36.671c0,0,4.549-0.743,6.859-1.549
		c2.715-0.942,4.543-2.545,4.543-2.545"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M21.337,37.909c0,0-2.384-1.777-6.117-3.43
		c-4.134-1.831-6.405-2.303-6.405-2.303"/>
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M81.117,42.622c0,0,2.726,1.104,5.533,1.385
		c2.77,0.276,4.647,0.11,4.647,0.11"/>
|
||||
<path fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" d="M51.349,10.212
		c2.84,0.7,3.888,1.469,3.888,1.469"/>
|
||||
<line fill="none" stroke="#000000" x1="32.898" y1="9.684" x2="38.956" y2="14.042"/>
|
||||
</g>
|
||||
<g id="Layer_5">
|
||||
<path fill="#FFFFFF" stroke="#231F20" d="M70.84,21.366c2.924,4.479,3.033,9.591,0.242,11.415
		c-2.793,1.825-7.426-0.332-10.354-4.813c-2.932-4.48-3.037-9.589-0.244-11.415C63.275,14.73,67.913,16.884,70.84,21.366z"/>
|
||||
<path fill="#231F20" d="M70.089,28.522c0,1.08-0.802,1.956-1.8,1.956c-0.993,0-1.803-0.877-1.803-1.956
		c0-1.08,0.81-1.958,1.803-1.958C69.287,26.564,70.089,27.442,70.089,28.522"/>
|
||||
</g>
|
||||
<g id="Layer_7">
|
||||
<path fill="#FFFFFF" stroke="#231F20" d="M46.867,24.619c2.926,4.48,2.619,9.862-0.681,12.015
		c-3.302,2.159-8.351,0.272-11.276-4.208c-2.928-4.48-2.624-9.86,0.678-12.017C38.891,18.253,43.938,20.137,46.867,24.619z"/>
|
||||
<path fill="#231F20" d="M45.079,30.507c0,1.081-0.803,1.957-1.801,1.957c-0.992,0-1.803-0.878-1.803-1.957
		c0-1.08,0.811-1.957,1.803-1.957C44.274,28.55,45.079,29.427,45.079,30.507"/>
|
||||
</g>
|
||||
<path fill="#5E4A42" stroke="#000000" d="M58.766,33.926c1.854,0,4.555-0.284,4.697,0.569c0.143,0.855-1.709,4.203-2.988,4.345
	c-1.283,0.142-6.125-2.353-6.195-3.919C54.206,33.355,57.055,33.926,58.766,33.926z"/>
|
||||
<g id="Layer_4">
|
||||
<path fill="none" stroke="#231F20" stroke-width="1.2" d="M45.774,41.235c0,0,10.347,3.054,14.217,3.897
		c3.868,0.842,10.851,1.684,10.851,1.684s-7.99,10.245-17.328,7.644C44.176,51.863,44.345,45.975,45.774,41.235z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.1 KiB |
@@ -0,0 +1,42 @@
|
||||
<svg width="96px" height="101px" viewBox="0 0 96 101" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.5 (67469) - http://www.bohemiancoding.com/sketch -->
|
||||
<g>
|
||||
<title>costume1.1</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="costume1" transform="translate(-13.000000, -10.000000)">
|
||||
<g id="costume1.1" transform="translate(13.000000, 10.000000)">
|
||||
<g id="tail" transform="translate(0.000000, 59.000000)">
|
||||
<path d="M21.9,14.8 C19.5,14.3 16.6,13.5 14.2,11.3 C8.7,6.4 7,-1.7 3.2,0.4 C-0.7,2.5 -0.6,15.6 11.6,19.6 C15.8,21 19.6,21 22.7,20.9 C23.5,20.9 30.4,20.2 32.8,16.8 C35.2,13.4 33.5,12.5 32.7,12.1 C31.8,11.6 25.3,15.4 21.9,14.8 Z" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3.8,0.6 C1.8,1.2 0.8,5.4 1.8,8.9 C2.8,12.4 4.4,14.2 5.7,15.5 C5.5,14.8 5.1,12.6 6.8,11.3 C8.9,9.6 12.6,10.5 12.6,10.5 C12.6,10.5 9.5,6.7 7.9,4 C6.3,1.7 5.8,0.2 3.8,0.6 Z" id="detail" fill="#FFFFFF"/>
|
||||
</g>
|
||||
<path d="M37.7,81.5 C35.9,82.7 29.7,87.1 21.8,89.6 L21.4,89.7 C21,89.8 20.8,90.3 21,90.7 C22.7,93.1 25.8,97.9 20.3,99.6 C15,101.3 5.1,87.2 9.3,83.5 C11.2,82.1 12.9,82.8 13.8,83.2 C14.3,83.4 14.8,83.4 15.3,83.3 C16.5,82.9 18.7,82.1 20.4,81.2 C24.7,79 25.7,78.1 27.7,76.6 C29.7,75.1 34.3,71.4 38,74.6 C41.2,77.3 39.4,80.3 37.7,81.5 Z" id="leg" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M53.6,60.7 C54.1,61.1 60.2,68.3 62.2,66.5 C64.6,64.4 67.9,60.3 71.5,63.6 C75.1,66.9 68.3,72.5 65.4,74 C58.5,77.1 52.9,71.2 51.7,69.6 C50.5,68 48.4,65.3 48.4,62.7 C48.5,59.9 51.9,59.2 53.6,60.7 Z" id="arm" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="body-and-leg" transform="translate(28.000000, 57.000000)">
|
||||
<path d="M18.2,19.7 C19.4,18.8 20.6,17.3 22.2,15 C23.5,13.1 24.9,9.4 24.9,9.4 C25.8,6.9 26.4,2.1 23.1,2.2 C20.9,2.3 18.9,2 15.5,1.5 C9.5,0.3 8.4,-0.5 5.9,3.6 C3.2,8.4 -3.7,11.9 4.8,20.2 C4.8,20.2 9.7,24 15.6,29.8 C19.6,33.7 25.9,39.3 28.1,41.2 C28.6,41.6 29.2,41.8 29.8,41.9 C39.5,42.8 46.7,41.8 46.7,37.5 C46.7,30.3 32.4,32.8 32.4,32.8 C32.4,32.8 27.8,28.9 25.7,27 L18.2,19.7 Z" id="body" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M22.6,13 C22.6,13 24.5,10.5 20.2,7.8 C15.7,4.9 14,8.1 12.2,10.5 C10.2,13.6 12.2,15.1 14.2,16.9 C15.8,18.4 17.3,19.6 17.3,19.6 C17.3,19.6 20.4,17.5 22.6,13 Z" id="tummy" fill="#FFFFFF"/>
|
||||
</g>
|
||||
<path d="M30.2,68.4 C32.4,71.2 35.8,74.7 31.5,77.6 C25.6,80.9 20.7,70.9 19.7,67.4 C18.8,64.3 21.4,62.3 23.6,60.6 C27.9,57.5 31.5,54.7 35.5,56.2 C40.5,58 36.9,62 34.4,63.8 C32.9,64.9 31.4,66.1 30.3,66.8 C30,67.3 29.9,67.9 30.2,68.4 Z" id="arm" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="head" transform="translate(14.000000, 0.000000)">
|
||||
<path d="M39.1,9 C36.8,8.6 34.4,8.4 31.6,8.6 C26.9,8.8 22.4,10.5 22.4,10.5 L10.3,2.6 C9.9,2.4 9.4,2.7 9.5,3.1 L11.6,21 C12.2,20.2 1,33.8 8.1,45.2 C15.2,56.6 30.3,61.7 49.1,58 C67.9,54.3 72.3,43.5 71.1,37.8 C69.9,32.1 62.8,30 62.8,30 C62.8,30 62.7,25.5 59.5,20 C57.6,16.7 51.2,12 51.2,12 L48.6,1.3 C48.5,0.9 48,0.8 47.7,1 L39.1,9 Z" stroke="#001026" stroke-width="1.2" fill="#FFAB19"/>
|
||||
<path d="M62.5,30.4 C62.5,30.4 69.4,32.2 70.6,37.9 C71.8,43.6 67,53.9 48.4,57.5 C24.2,62.5 12.7,48.1 19.4,37.5 C26.1,26.8 37.6,35.9 46,35.3 C53.2,34.8 54,28.5 62.5,30.4 Z" id="face" fill="#FFFFFF"/>
|
||||
<path d="M31,41.1 C31,40.7 31.4,40.4 31.8,40.5 C33.7,41.2 39.1,42.8 45.1,43.2 C50.5,43.5 53.7,43.2 55.2,42.9 C55.7,42.8 56.1,43.3 55.9,43.8 C55,46.5 51.2,54 40.7,53.4 C31.6,52.4 30.7,46 31,41.1 Z" id="mouth" stroke="#001026" stroke-width="1.2" fill="#FFFFFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M69,35.4 C69,35.4 76.2,35.3 80.9,31.5" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M69.4,41.3 C69.4,41.3 73.3,43.2 79.6,42.7" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M45.6,32.7 C47.7,32.7 49.9,32.9 50,33.6 C50.1,35 48.6,37.8 47,37.9 C45.2,38.1 41,35.6 41,34 C40.9,32.8 43.6,32.7 45.6,32.7 Z" id="nose" stroke="#001026" stroke-width="1.2" fill="#001026" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M0.6,31.2 C0.6,31.2 9.2,34 12.7,37.1" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M1.3,41.2 C1.3,41.2 8.7,42.3 13,40.6" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="eye" transform="translate(44.000000, 15.000000)">
|
||||
<path d="M13.4,6 C16.3,10.5 16.4,15.6 13.6,17.4 C10.8,19.2 6.2,17.1 3.2,12.6 C0.3,8.1 0.2,3 3,1.2 C5.8,-0.7 10.5,1.5 13.4,6 Z" id="pupil" stroke="#001026" stroke-width="1.2" fill="#FFFFFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13,11.7 C13,12.8 12.2,13.7 11.2,13.7 C10.2,13.7 9.4,12.8 9.4,11.7 C9.4,10.6 10.2,9.7 11.2,9.7 C12.2,9.7 13,10.6 13,11.7" id="pupil" fill="#001026"/>
|
||||
</g>
|
||||
<g id="eye" transform="translate(19.000000, 18.000000)">
|
||||
<path d="M13.6,5.8 C16.6,10.2 16.4,15.6 13.7,17.5 C10.4,19.4 6,18 3,13.6 C-0.1,9.2 -0.3,3.5 2.8,1.3 C5.9,-1 10.6,1.4 13.6,5.8 Z" stroke="#001026" stroke-width="1.2" fill="#FFFFFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13,11.6 C13,12.7 12.2,13.6 11.2,13.6 C10.2,13.6 9.4,12.7 9.4,11.6 C9.4,10.5 10.2,9.6 11.2,9.6 C12.2,9.7 13,10.5 13,11.6" id="pupil" fill="#001026"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,42 @@
|
||||
<svg width="93px" height="106px" viewBox="0 0 93 106" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.5 (67469) - http://www.bohemiancoding.com/sketch -->
|
||||
<g>
|
||||
<title>costume2.1</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="cotsume2" transform="translate(-16.000000, -10.000000)">
|
||||
<g id="costume2.1" transform="translate(16.250000, 9.500000)">
|
||||
<g id="tail" transform="translate(0.000000, 53.000000)">
|
||||
<path d="M12,14.8 C8.9,7 10.6,0 6.3,0.4 C1.9,0.8 -3.2,12.5 6.4,21.1 C15.3,29 24.4,26.1 28,24 C31.5,21.8 28.8,20.6 28.2,19.8 C27.6,19 16.4,26.1 12,14.8 Z" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.8,0.9 C4.3,0.5 2.1,4.1 1.6,7.6 C1.4,11.2 2,13.3 2.7,15 C2.8,14.3 3.7,11.9 6.6,11.4 C9,11 10.6,13 10.6,13 C10.6,13 9.6,10 9.1,5.6 C8.7,2.9 8.8,1.3 6.8,0.9 Z" id="detail" fill="#FFFFFF"/>
|
||||
</g>
|
||||
<path d="M32.9,83.2 C32.2,84.1 30.2,87.6 25.4,90.6 C22.1,92.7 13.6,89.2 13.6,89.2 C14.5,98.4 7,98.2 5.6,95.2 C4.5,92.8 4.7,82.5 6.9,81.7 C10.3,80.5 14.9,82.5 19,82.5 C20.2,82.5 21.5,79.9 24.3,77.1 C26.3,75.1 28.9,71.4 33.1,74 C36.7,76.3 34.8,80.5 32.9,83.2 Z" id="leg" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M50.1,62 C50.4,64.2 50.6,72.6 53,73.9 C55.3,75.1 62.3,73.1 62.7,78 C63.1,82.8 56.6,82.9 51.2,81.4 C44.2,79.5 41,68.8 45,62.2 C46.5,59.9 49.8,59.7 50.1,62 Z" id="arm" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="body-and-leg" transform="translate(24.000000, 57.000000)">
|
||||
<path d="M18.2,21.3 C19.4,20.4 21.2,18 22.8,15.6 C24.1,13.7 25.5,10 25.5,10 C26.4,7.5 27,2.7 23.7,2.8 C21.5,2.9 19.5,2.6 16.1,2.1 C10.1,0.9 8.9,-0.3 6.5,4.2 C2,12.5 -4,18.4 4.2,23.2 C6.2,24.4 9.4,26.4 12.2,28.4 C14.2,30.3 11.2,34.4 9.1,36.8 C8.2,37.9 8.2,39.5 9.3,40.6 C16.6,47.7 18.8,50.2 21.6,47.1 C25.4,42.9 19.4,38.8 19.4,38.8 C19.4,38.8 24.2,31.3 23.6,28 C22.9,24.8 18.2,21.3 18.2,21.3 Z" id="body" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M22.7284271,14.6028611 C22.7284271,14.6028611 24.6284271,12.1028611 20.3284271,9.40286109 C15.8284271,6.50286109 14.1284271,9.70286109 12.3284271,12.1028611 C10.3284271,15.2028611 12.3284271,16.7028611 14.3284271,18.5028611 C15.9284271,20.0028611 17.4284271,21.2028611 17.4284271,21.2028611 C17.4284271,21.2028611 20.5284271,19.1028611 22.7284271,14.6028611 Z" id="tummy" fill="#FFFFFF"/>
|
||||
</g>
|
||||
<path d="M32.3,65.2 C30.1,66.2 26,64.4 24.9,64.6 C24.6,64.7 22.8,69.9 21.7,73 C20.2,77.4 13.4,76.1 13,71.5 C12.7,67.2 16.6,58.9 17.9,57.4 C20.8,53.9 30.6591797,56.7082962 37.2463379,58.456543" id="arm" stroke="#001026" stroke-width="1.2" fill="#FFAB19" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="head" transform="translate(10.750000, 0.500000)">
|
||||
<path d="M39.1,9 C36.8,8.6 34.4,8.4 31.6,8.6 C26.9,8.8 22.4,10.5 22.4,10.5 L10.3,2.6 C9.9,2.4 9.4,2.7 9.5,3.1 L11.6,21 C12.2,20.2 1,33.8 8.1,45.2 C15.2,56.6 30.3,61.7 49.1,58 C67.9,54.3 72.3,43.5 71.1,37.8 C69.9,32.1 62.8,30 62.8,30 C62.8,30 62.7,25.5 59.5,20 C57.6,16.7 51.2,12 51.2,12 L48.6,1.3 C48.5,0.9 48,0.8 47.7,1 L39.1,9 Z" stroke="#001026" stroke-width="1.2" fill="#FFAB19"/>
|
||||
<path d="M62.5,30.4 C62.5,30.4 69.4,32.2 70.6,37.9 C71.8,43.6 67,53.9 48.4,57.5 C24.2,62.5 12.7,48.1 19.4,37.5 C26.1,26.8 37.6,35.9 46,35.3 C53.2,34.8 54,28.5 62.5,30.4 Z" id="face" fill="#FFFFFF"/>
|
||||
<path d="M31,41.1 C31,40.7 31.4,40.4 31.8,40.5 C33.7,41.2 39.1,42.8 45.1,43.2 C50.5,43.5 53.7,43.2 55.2,42.9 C55.7,42.8 56.1,43.3 55.9,43.8 C55,46.5 51.2,54 40.7,53.4 C31.6,52.4 30.7,46 31,41.1 Z" id="mouth" stroke="#001026" stroke-width="1.2" fill="#FFFFFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M69,35.4 C69,35.4 76.2,35.3 80.9,31.5" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M69.4,41.3 C69.4,41.3 73.3,43.2 79.6,42.7" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M45.6,32.7 C47.7,32.7 49.9,32.9 50,33.6 C50.1,35 48.6,37.8 47,37.9 C45.2,38.1 41,35.6 41,34 C40.9,32.8 43.6,32.7 45.6,32.7 Z" id="nose" stroke="#001026" stroke-width="1.2" fill="#001026" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M0.6,31.2 C0.6,31.2 9.2,34 12.7,37.1" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M1.3,41.2 C1.3,41.2 8.7,42.3 13,40.6" id="whisker" stroke="#001026" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="eye" transform="translate(44.000000, 15.000000)">
|
||||
<path d="M13.4,6 C16.3,10.5 16.4,15.6 13.6,17.4 C10.8,19.2 6.2,17.1 3.2,12.6 C0.3,8.1 0.2,3 3,1.2 C5.8,-0.7 10.5,1.5 13.4,6 Z" id="pupil" stroke="#001026" stroke-width="1.2" fill="#FFFFFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13,11.7 C13,12.8 12.2,13.7 11.2,13.7 C10.2,13.7 9.4,12.8 9.4,11.7 C9.4,10.6 10.2,9.7 11.2,9.7 C12.2,9.7 13,10.6 13,11.7" id="pupil" fill="#001026"/>
|
||||
</g>
|
||||
<g id="eye" transform="translate(19.000000, 18.000000)">
|
||||
<path d="M13.6,5.8 C16.6,10.2 16.4,15.6 13.7,17.5 C10.4,19.4 6,18 3,13.6 C-0.1,9.2 -0.3,3.5 2.8,1.3 C5.9,-1 10.6,1.4 13.6,5.8 Z" stroke="#001026" stroke-width="1.2" fill="#FFFFFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13,11.6 C13,12.7 12.2,13.6 11.2,13.6 C10.2,13.6 9.4,12.7 9.4,11.6 C9.4,10.5 10.2,9.6 11.2,9.6 C12.2,9.7 13,10.5 13,11.6" id="pupil" fill="#001026"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -4,8 +4,8 @@ import projectData from './project-data';
|
||||
import popWav from '!arraybuffer-loader!./83a9787d4cb6f3b7632b4ddfebf74367.wav';
|
||||
import meowWav from '!arraybuffer-loader!./83c36d806dc92327b9e7049a565c6bff.wav';
|
||||
import backdrop from '!raw-loader!./cd21514d0531fdffb22204e0ec5ed84a.svg';
|
||||
import costume1 from '!raw-loader!./09dc888b0b7df19f70d81588ae73420e.svg';
|
||||
import costume2 from '!raw-loader!./3696356a03a8d938318876a593572843.svg';
|
||||
import costume1 from '!raw-loader!./b7853f557e4426412e64bb3da6531a99.svg';
|
||||
import costume2 from '!raw-loader!./e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg';
|
||||
/* eslint-enable import/no-unresolved */
|
||||
|
||||
const defaultProject = translator => {
|
||||
@@ -40,12 +40,12 @@ const defaultProject = translator => {
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(backdrop)
|
||||
}, {
|
||||
id: '09dc888b0b7df19f70d81588ae73420e',
|
||||
id: 'b7853f557e4426412e64bb3da6531a99',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(costume1)
|
||||
}, {
|
||||
id: '3696356a03a8d938318876a593572843',
|
||||
id: 'e6ddc55a6ddd9cc9d84fe0b4c21e016f',
|
||||
assetType: 'ImageVector',
|
||||
dataFormat: 'SVG',
|
||||
data: encoder.encode(costume2)
|
||||
|
||||
@@ -118,15 +118,14 @@ const costumeUpload = function (fileData, fileType, storage, handleCostume, hand
|
||||
}
|
||||
case 'image/gif': {
|
||||
let costumes = [];
|
||||
const onFrame = (frameNumber, dataUrl) => {
|
||||
gifDecoder(fileData, (frameNumber, dataUrl, numFrames) => {
|
||||
costumeUpload(dataUrl, 'image/png', storage, costumes_ => {
|
||||
costumes = costumes.concat(costumes_);
|
||||
if (frameNumber === numFrames - 1) {
|
||||
handleCostume(costumes);
|
||||
}
|
||||
}, handleError);
|
||||
};
|
||||
const onDone = () => {
|
||||
handleCostume(costumes);
|
||||
};
|
||||
gifDecoder(fileData, {onFrame, onDone});
|
||||
});
|
||||
return; // Abandon this load, do not try to load gif itself
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import {GifReader} from 'omggif';
|
||||
|
||||
export default (arrayBuffer, {onFrame, onDone}) => {
|
||||
export default (arrayBuffer, onFrame) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const gifReader = new GifReader(new Uint8Array(arrayBuffer));
|
||||
const numFrames = gifReader.numFrames();
|
||||
canvas.width = gifReader.width;
|
||||
canvas.height = gifReader.height;
|
||||
|
||||
@@ -14,7 +15,6 @@ export default (arrayBuffer, {onFrame, onDone}) => {
|
||||
const framePixels = [];
|
||||
gifReader.decodeAndBlitFrameRGBA(i, framePixels);
|
||||
const {x, y, width, height, disposal} = gifReader.frameInfo(i);
|
||||
|
||||
for (let row = 0; row < height; row++) {
|
||||
for (let column = 0; column < width; column++) {
|
||||
const indexOffset = 4 * (x + (y * canvas.width));
|
||||
@@ -47,16 +47,12 @@ export default (arrayBuffer, {onFrame, onDone}) => {
|
||||
break;
|
||||
|
||||
}
|
||||
onFrame(i, dataUrl);
|
||||
onFrame(i, dataUrl, numFrames);
|
||||
|
||||
if (i < gifReader.numFrames() - 1) {
|
||||
if (i < numFrames - 1) {
|
||||
setTimeout(() => {
|
||||
loadFrame(i + 1);
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
onDone();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Andie-a",
|
||||
"md5": "419ff5a76adbb4b076c072f68267fdeb.svg",
|
||||
"md5": "d2c433e02481b10584e34ccdcf5a046a.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -87,14 +87,33 @@
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
86,
|
||||
81,
|
||||
80,
|
||||
65,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Andie-b",
|
||||
"md5": "a6a766912b4e43064ee3f389c72925b4.svg",
|
||||
"md5": "045f92ad80d72521098ede6d7c80549a.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
"basketball",
|
||||
"people",
|
||||
"wheelchair",
|
||||
"handicap",
|
||||
"handicapable",
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
40,
|
||||
91,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Andie-c",
|
||||
"md5": "c9bad70ad371b8d6d97daed7ab9def98.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -107,32 +126,13 @@
|
||||
],
|
||||
"info": [
|
||||
46,
|
||||
106,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Andie-c",
|
||||
"md5": "fac1025857d2c28391cb31f39a80df54.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
"basketball",
|
||||
"people",
|
||||
"wheelchair",
|
||||
"handicap",
|
||||
"handicapable",
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
52,
|
||||
65,
|
||||
49,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Andie-d",
|
||||
"md5": "7af50835e05d43e5e07cd2d641e7401e.svg",
|
||||
"md5": "7c9db638cd671898ff07771112faff0f.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -144,8 +144,8 @@
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
87,
|
||||
72,
|
||||
71,
|
||||
57,
|
||||
1
|
||||
]
|
||||
},
|
||||
@@ -1069,7 +1069,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Ben-a",
|
||||
"md5": "4386d05d5abd6e1aa0a93b7b447d1b39.svg",
|
||||
"md5": "322e13bd17d02acfdc048a5ef2167be8.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -1079,14 +1079,14 @@
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
53,
|
||||
54,
|
||||
69,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ben-b",
|
||||
"md5": "90db137cd0743204d02fdc9be1c8eb94.svg",
|
||||
"md5": "59ba1e80ba75b1d06c37db4b9b4fde27.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -1096,14 +1096,14 @@
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
53,
|
||||
67,
|
||||
54,
|
||||
69,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ben-c",
|
||||
"md5": "5f05d41ede773b3bb379286e86a5b869.svg",
|
||||
"md5": "940ec2fa85d666dde95a51bcbccd266e.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -1113,14 +1113,14 @@
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
73,
|
||||
71,
|
||||
72,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ben-d",
|
||||
"md5": "6f6e246567c0639c758ed4f6930be76f.svg",
|
||||
"md5": "3043a50a91b9d484a8cd32eb82f2d88f.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -1130,8 +1130,8 @@
|
||||
"alex eben meyer"
|
||||
],
|
||||
"info": [
|
||||
42,
|
||||
72,
|
||||
44,
|
||||
71,
|
||||
1
|
||||
]
|
||||
},
|
||||
@@ -3628,16 +3628,17 @@
|
||||
},
|
||||
{
|
||||
"name": "Earth",
|
||||
"md5": "d9df2cf4f6eb2460d0de3e4f1e05f40b.svg",
|
||||
"md5": "64220361b80d2812e9f27fc88ef39027.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"space",
|
||||
"planet",
|
||||
"earth"
|
||||
"earth",
|
||||
"globe"
|
||||
],
|
||||
"info": [
|
||||
41,
|
||||
40,
|
||||
55,
|
||||
55,
|
||||
1
|
||||
]
|
||||
},
|
||||
@@ -6178,7 +6179,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Jordyn-a",
|
||||
"md5": "8355df83cca2baa0fdf6269d1311f1ea.svg",
|
||||
"md5": "2f59adebc2c0feb9ebfabd7ee9642f2b.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -6189,13 +6190,13 @@
|
||||
],
|
||||
"info": [
|
||||
51,
|
||||
63,
|
||||
62,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Jordyn-b",
|
||||
"md5": "2e2c43bbd7b18524fb132f1426ca3134.svg",
|
||||
"md5": "075f382883e60dba8094b3dc30918f60.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -6212,7 +6213,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Jordyn-c",
|
||||
"md5": "5c0d24c53805e16358a2f6f6cc4a456e.svg",
|
||||
"md5": "fbe81c40d4a880c8799c458359758629.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -6223,13 +6224,13 @@
|
||||
],
|
||||
"info": [
|
||||
68,
|
||||
61,
|
||||
62,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Jordyn-d",
|
||||
"md5": "ebe2b20b99c1e1b373fd2b02be48aab9.svg",
|
||||
"md5": "68a784d4d0340475a6e6feff3b28b470.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"sports",
|
||||
@@ -6240,7 +6241,7 @@
|
||||
],
|
||||
"info": [
|
||||
40,
|
||||
61,
|
||||
62,
|
||||
1
|
||||
]
|
||||
},
|
||||
@@ -9660,7 +9661,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Sun",
|
||||
"md5": "55c931c65456822c0c56a2b30e3e550d.svg",
|
||||
"md5": "14b0508da0dc30e83b2bede13c1be1e9.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"space",
|
||||
@@ -9671,8 +9672,8 @@
|
||||
"nuclear"
|
||||
],
|
||||
"info": [
|
||||
72,
|
||||
72,
|
||||
54,
|
||||
54,
|
||||
1
|
||||
]
|
||||
},
|
||||
@@ -10582,6 +10583,24 @@
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Wizard Girl",
|
||||
"md5": "dd40d3a2565990bcc24d2b36cd446394.svg",
|
||||
"type": "costume",
|
||||
"tags": [
|
||||
"people",
|
||||
"female",
|
||||
"girl",
|
||||
"wizard",
|
||||
"magic",
|
||||
"fantasy"
|
||||
],
|
||||
"info": [
|
||||
80,
|
||||
91,
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Wizard Hat",
|
||||
"md5": "2da561a7e5cbfcda613f4750020d4aa5.svg",
|
||||
@@ -12682,4 +12701,4 @@
|
||||
1
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 308 KiB |
@@ -0,0 +1,349 @@
|
||||
// Intro
|
||||
import introMove from './steps/intro-move.en.gif';
|
||||
import introSayHello from './steps/intro-say-hello.en.gif';
|
||||
|
||||
// Text to Speech
|
||||
import speechAddExtension from './steps/speech-add-extension.en.gif';
|
||||
import speechSaySomething from './steps/speech-say-something.en.gif';
|
||||
import speechSetVoice from './steps/speech-set-voice.en.gif';
|
||||
import speechMoveAround from './steps/speech-move-around.en.gif';
|
||||
import speechAddBackdrop from './steps/speech-add-backdrop.en.gif';
|
||||
import speechAddSprite from './steps/speech-add-sprite.en.gif';
|
||||
import speechSong from './steps/speech-song.en.gif';
|
||||
import speechChangeColor from './steps/speech-change-color.en.gif';
|
||||
import speechSpin from './steps/speech-spin.en.gif';
|
||||
import speechGrowShrink from './steps/speech-grow-shrink.en.gif';
|
||||
|
||||
// Cartoon Network
|
||||
import cnShowCharacter from './steps/cn-show-character.en.gif';
|
||||
import cnSay from './steps/cn-say.en.gif';
|
||||
import cnGlide from './steps/cn-glide.en.gif';
|
||||
import cnPickSprite from './steps/cn-pick-sprite.en.gif';
|
||||
import cnCollect from './steps/cn-collect.en.gif';
|
||||
import cnVariable from './steps/cn-variable.en.gif';
|
||||
import cnScore from './steps/cn-score.en.gif';
|
||||
import cnBackdrop from './steps/cn-backdrop.en.gif';
|
||||
|
||||
// Add sprite
|
||||
import addSprite from './steps/add-sprite.en.gif';
|
||||
|
||||
// Animate a name
|
||||
import namePickLetter from './steps/name-pick-letter.en.gif';
|
||||
import namePlaySound from './steps/name-play-sound.en.gif';
|
||||
import namePickLetter2 from './steps/name-pick-letter2.en.gif';
|
||||
import nameChangeColor from './steps/name-change-color.en.gif';
|
||||
import nameSpin from './steps/name-spin.en.gif';
|
||||
import nameGrow from './steps/name-grow.en.gif';
|
||||
|
||||
// Make-Music
|
||||
import musicPickInstrument from './steps/music-pick-instrument.en.gif';
|
||||
import musicPlaySound from './steps/music-play-sound.en.gif';
|
||||
import musicMakeSong from './steps/music-make-song.en.gif';
|
||||
import musicMakeBeat from './steps/music-make-beat.en.gif';
|
||||
import musicMakeBeatbox from './steps/music-make-beatbox.en.gif';
|
||||
|
||||
// Chase-Game
|
||||
import chaseGameAddBackdrop from './steps/chase-game-add-backdrop.en.gif';
|
||||
import chaseGameAddSprite1 from './steps/chase-game-add-sprite1.en.gif';
|
||||
import chaseGameRightLeft from './steps/chase-game-right-left.en.gif';
|
||||
import chaseGameUpDown from './steps/chase-game-up-down.en.gif';
|
||||
import chaseGameAddSprite2 from './steps/chase-game-add-sprite2.en.gif';
|
||||
import chaseGameMoveRandomly from './steps/chase-game-move-randomly.en.gif';
|
||||
import chaseGamePlaySound from './steps/chase-game-play-sound.en.gif';
|
||||
import chaseGameAddVariable from './steps/chase-game-add-variable.en.gif';
|
||||
import chaseGameChangeScore from './steps/chase-game-change-score.en.gif';
|
||||
|
||||
// Clicker-Game (Pop Game)
|
||||
import popGamePickSprite from './steps/pop-game-pick-sprite.en.gif';
|
||||
import popGamePlaySound from './steps/pop-game-play-sound.en.gif';
|
||||
import popGameAddScore from './steps/pop-game-add-score.en.gif';
|
||||
import popGameChangeScore from './steps/pop-game-change-score.en.gif';
|
||||
import popGameRandomPosition from './steps/pop-game-random-position.en.gif';
|
||||
import popGameChangeColor from './steps/pop-game-change-color.en.gif';
|
||||
import popGameResetScore from './steps/pop-game-reset-score.en.gif';
|
||||
|
||||
// Animate A Character
|
||||
import animateCharPickBackdrop from './steps/animate-char-pick-backdrop.en.gif';
|
||||
import animateCharPickSprite from './steps/animate-char-pick-sprite.en.gif';
|
||||
import animateCharSaySomething from './steps/animate-char-say-something.en.gif';
|
||||
import animateCharAddSound from './steps/animate-char-add-sound.en.gif';
|
||||
import animateCharTalk from './steps/animate-char-talk.en.gif';
|
||||
import animateCharMove from './steps/animate-char-move.en.gif';
|
||||
import animateCharJump from './steps/animate-char-jump.en.gif';
|
||||
import animateCharChangeColor from './steps/animate-char-change-color.en.gif';
|
||||
|
||||
// Tell A Story
|
||||
import storyPickBackdrop from './steps/story-pick-backdrop.en.gif';
|
||||
import storyPickSprite from './steps/story-pick-sprite.en.gif';
|
||||
import storySaySomething from './steps/story-say-something.en.gif';
|
||||
import storyPickSprite2 from './steps/story-pick-sprite2.en.gif';
|
||||
import storyFlip from './steps/story-flip.en.gif';
|
||||
import storyConversation from './steps/story-conversation.en.gif';
|
||||
import storyPickBackdrop2 from './steps/story-pick-backdrop2.en.gif';
|
||||
import storySwitchBackdrop from './steps/story-switch-backdrop.en.gif';
|
||||
import storyHideCharacter from './steps/story-hide-character.en.gif';
|
||||
import storyShowCharacter from './steps/story-show-character.en.gif';
|
||||
|
||||
// Video Sensing
|
||||
import videoAddExtension from './steps/video-add-extension.en.gif';
|
||||
import videoPet from './steps/video-pet.en.gif';
|
||||
import videoAnimate from './steps/video-animate.en.gif';
|
||||
import videoPop from './steps/video-pop.en.gif';
|
||||
|
||||
// Make it Fly
|
||||
import flyChooseBackdrop from './steps/fly-choose-backdrop.en.gif';
|
||||
import flyChooseCharacter from './steps/fly-choose-character.en.gif';
|
||||
import flySaySomething from './steps/fly-say-something.en.gif';
|
||||
import flyMoveArrows from './steps/fly-make-interactive.en.gif';
|
||||
import flyChooseObject from './steps/fly-object-to-collect.en.gif';
|
||||
import flyFlyingObject from './steps/fly-flying-heart.en.gif';
|
||||
import flySelectFlyingSprite from './steps/fly-select-flyer.en.jpg';
|
||||
import flyAddScore from './steps/fly-add-score.en.gif';
|
||||
import flyKeepScore from './steps/fly-keep-score.en.gif';
|
||||
import flyAddScenery from './steps/fly-choose-scenery.en.gif';
|
||||
import flyMoveScenery from './steps/fly-move-scenery.en.gif';
|
||||
import flySwitchLooks from './steps/fly-switch-costume.en.gif';
|
||||
|
||||
// Pong
|
||||
import pongAddBackdrop from './steps/pong-add-backdrop.en.png';
|
||||
import pongAddBallSprite from './steps/pong-add-ball-sprite.en.png';
|
||||
import pongBounceAround from './steps/pong-bounce-around.en.gif';
|
||||
import pongAddPaddle from './steps/pong-add-a-paddle.en.gif';
|
||||
import pongMoveThePaddle from './steps/pong-move-the-paddle.en.gif';
|
||||
import pongSelectBallSprite from './steps/pong-select-ball.en.png';
|
||||
import pongAddMoreCodeToBall from './steps/pong-add-code-to-ball.en.png';
|
||||
import pongAddAScore from './steps/pong-add-score.en.gif';
|
||||
import pongChooseScoreFromMenu from './steps/pong-choose-score.en.png';
|
||||
import pongInsertChangeScoreBlock from './steps/pong-insert-change-score.en.png';
|
||||
import pongResetScore from './steps/pong-reset-score.en.png';
|
||||
import pongAddLineSprite from './steps/pong-add-line.en.gif';
|
||||
import pongGameOver from './steps/pong-game-over.en.png';
|
||||
|
||||
// Imagine If
|
||||
import imagineTypeWhatYouWant from './steps/imagine-type-what-you-want.en.png';
|
||||
import imagineClickGreenFlag from './steps/imagine-click-green-flag.en.png';
|
||||
import imagineChooseBackdrop from './steps/imagine-choose-backdrop.en.png';
|
||||
import imagineChooseSprite from './steps/imagine-choose-any-sprite.en.png';
|
||||
import imagineFlyAround from './steps/imagine-fly-around.en.png';
|
||||
import imagineChooseAnotherSprite from './steps/imagine-choose-another-sprite.en.png';
|
||||
import imagineLeftRight from './steps/imagine-left-right.en.png';
|
||||
import imagineUpDown from './steps/imagine-up-down.en.png';
|
||||
import imagineChangeCostumes from './steps/imagine-change-costumes.en.png';
|
||||
import imagineGlideToPoint from './steps/imagine-glide-to-point.en.png';
|
||||
import imagineGrowShrink from './steps/imagine-grow-shrink.en.png';
|
||||
import imagineChooseAnotherBackdrop from './steps/imagine-choose-another-backdrop.en.png';
|
||||
import imagineSwitchBackdrops from './steps/imagine-switch-backdrops.en.gif';
|
||||
import imagineRecordASound from './steps/imagine-record-a-sound.en.gif';
|
||||
import imagineChooseSound from './steps/imagine-choose-sound.en.png';
|
||||
|
||||
// Add a Backdrop
|
||||
import addBackdrop from './steps/add-backdrop.en.png';
|
||||
|
||||
// Add Effectsf
|
||||
import addEffects from './steps/add-effects.en.png';
|
||||
|
||||
// Hide and Show
|
||||
import hideAndShow from './steps/hide-show.en.png';
|
||||
|
||||
// Switch Costumes
|
||||
import switchCostumes from './steps/switch-costumes.en.png';
|
||||
|
||||
// Change Size
|
||||
import changeSize from './steps/change-size.en.png';
|
||||
|
||||
// Spin
|
||||
import spinTurn from './steps/spin-turn.en.png';
|
||||
import spinPointInDirection from './steps/spin-point-in-direction.en.png';
|
||||
|
||||
// Record a Sound
|
||||
import recordASoundSoundsTab from './steps/record-a-sound-sounds-tab.en.png';
|
||||
import recordASoundClickRecord from './steps/record-a-sound-click-record.en.png';
|
||||
import recordASoundPressRecordButton from './steps/record-a-sound-press-record-button.en.png';
|
||||
import recordASoundChooseSound from './steps/record-a-sound-choose-sound.en.png';
|
||||
import recordASoundPlayYourSound from './steps/record-a-sound-play-your-sound.en.png';
|
||||
|
||||
// Use Arrow Keys
|
||||
import moveArrowKeysLeftRight from './steps/move-arrow-keys-left-right.en.png';
|
||||
import moveArrowKeysUpDown from './steps/move-arrow-keys-up-down.en.png';
|
||||
|
||||
// Glide Around
|
||||
import glideAroundBackAndForth from './steps/glide-around-back-and-forth.en.png';
|
||||
import glideAroundPoint from './steps/glide-around-point.en.png';
|
||||
|
||||
const enImages = {
|
||||
// Intro
|
||||
introMove: introMove,
|
||||
introSayHello: introSayHello,
|
||||
|
||||
// Text to Speech
|
||||
speechAddExtension: speechAddExtension,
|
||||
speechSaySomething: speechSaySomething,
|
||||
speechSetVoice: speechSetVoice,
|
||||
speechMoveAround: speechMoveAround,
|
||||
speechAddBackdrop: speechAddBackdrop,
|
||||
speechAddSprite: speechAddSprite,
|
||||
speechSong: speechSong,
|
||||
speechChangeColor: speechChangeColor,
|
||||
speechSpin: speechSpin,
|
||||
speechGrowShrink: speechGrowShrink,
|
||||
|
||||
// Cartoon Network
|
||||
cnShowCharacter: cnShowCharacter,
|
||||
cnSay: cnSay,
|
||||
cnGlide: cnGlide,
|
||||
cnPickSprite: cnPickSprite,
|
||||
cnCollect: cnCollect,
|
||||
cnVariable: cnVariable,
|
||||
cnScore: cnScore,
|
||||
cnBackdrop: cnBackdrop,
|
||||
|
||||
// Add sprite
|
||||
addSprite: addSprite,
|
||||
|
||||
// Animate a name
|
||||
namePickLetter: namePickLetter,
|
||||
namePlaySound: namePlaySound,
|
||||
namePickLetter2: namePickLetter2,
|
||||
nameChangeColor: nameChangeColor,
|
||||
nameSpin: nameSpin,
|
||||
nameGrow: nameGrow,
|
||||
|
||||
// Make-Music
|
||||
musicPickInstrument: musicPickInstrument,
|
||||
musicPlaySound: musicPlaySound,
|
||||
musicMakeSong: musicMakeSong,
|
||||
musicMakeBeat: musicMakeBeat,
|
||||
musicMakeBeatbox: musicMakeBeatbox,
|
||||
|
||||
// Chase-Game
|
||||
chaseGameAddBackdrop: chaseGameAddBackdrop,
|
||||
chaseGameAddSprite1: chaseGameAddSprite1,
|
||||
chaseGameRightLeft: chaseGameRightLeft,
|
||||
chaseGameUpDown: chaseGameUpDown,
|
||||
chaseGameAddSprite2: chaseGameAddSprite2,
|
||||
chaseGameMoveRandomly: chaseGameMoveRandomly,
|
||||
chaseGamePlaySound: chaseGamePlaySound,
|
||||
chaseGameAddVariable: chaseGameAddVariable,
|
||||
chaseGameChangeScore: chaseGameChangeScore,
|
||||
|
||||
// Make-A-Pop/Clicker Game
|
||||
popGamePickSprite: popGamePickSprite,
|
||||
popGamePlaySound: popGamePlaySound,
|
||||
popGameAddScore: popGameAddScore,
|
||||
popGameChangeScore: popGameChangeScore,
|
||||
popGameRandomPosition: popGameRandomPosition,
|
||||
popGameChangeColor: popGameChangeColor,
|
||||
popGameResetScore: popGameResetScore,
|
||||
|
||||
// Animate A Character
|
||||
animateCharPickBackdrop: animateCharPickBackdrop,
|
||||
animateCharPickSprite: animateCharPickSprite,
|
||||
animateCharSaySomething: animateCharSaySomething,
|
||||
animateCharAddSound: animateCharAddSound,
|
||||
animateCharTalk: animateCharTalk,
|
||||
animateCharMove: animateCharMove,
|
||||
animateCharJump: animateCharJump,
|
||||
animateCharChangeColor: animateCharChangeColor,
|
||||
|
||||
// Tell A Story
|
||||
storyPickBackdrop: storyPickBackdrop,
|
||||
storyPickSprite: storyPickSprite,
|
||||
storySaySomething: storySaySomething,
|
||||
storyPickSprite2: storyPickSprite2,
|
||||
storyFlip: storyFlip,
|
||||
storyConversation: storyConversation,
|
||||
storyPickBackdrop2: storyPickBackdrop2,
|
||||
storySwitchBackdrop: storySwitchBackdrop,
|
||||
storyHideCharacter: storyHideCharacter,
|
||||
storyShowCharacter: storyShowCharacter,
|
||||
|
||||
// Video Sensing
|
||||
videoAddExtension: videoAddExtension,
|
||||
videoPet: videoPet,
|
||||
videoAnimate: videoAnimate,
|
||||
videoPop: videoPop,
|
||||
|
||||
// Make it Fly
|
||||
flyChooseBackdrop: flyChooseBackdrop,
|
||||
flyChooseCharacter: flyChooseCharacter,
|
||||
flySaySomething: flySaySomething,
|
||||
flyMoveArrows: flyMoveArrows,
|
||||
flyChooseObject: flyChooseObject,
|
||||
flyFlyingObject: flyFlyingObject,
|
||||
flySelectFlyingSprite: flySelectFlyingSprite,
|
||||
flyAddScore: flyAddScore,
|
||||
flyKeepScore: flyKeepScore,
|
||||
flyAddScenery: flyAddScenery,
|
||||
flyMoveScenery: flyMoveScenery,
|
||||
flySwitchLooks: flySwitchLooks,
|
||||
|
||||
// Pong
|
||||
pongAddBackdrop: pongAddBackdrop,
|
||||
pongAddBallSprite: pongAddBallSprite,
|
||||
pongBounceAround: pongBounceAround,
|
||||
pongAddPaddle: pongAddPaddle,
|
||||
pongMoveThePaddle: pongMoveThePaddle,
|
||||
pongSelectBallSprite: pongSelectBallSprite,
|
||||
pongAddMoreCodeToBall: pongAddMoreCodeToBall,
|
||||
pongAddAScore: pongAddAScore,
|
||||
pongChooseScoreFromMenu: pongChooseScoreFromMenu,
|
||||
pongInsertChangeScoreBlock: pongInsertChangeScoreBlock,
|
||||
pongResetScore: pongResetScore,
|
||||
pongAddLineSprite: pongAddLineSprite,
|
||||
pongGameOver: pongGameOver,
|
||||
|
||||
// Imagine If
|
||||
imagineTypeWhatYouWant: imagineTypeWhatYouWant,
|
||||
imagineClickGreenFlag: imagineClickGreenFlag,
|
||||
imagineChooseBackdrop: imagineChooseBackdrop,
|
||||
imagineChooseSprite: imagineChooseSprite,
|
||||
imagineFlyAround: imagineFlyAround,
|
||||
imagineChooseAnotherSprite: imagineChooseAnotherSprite,
|
||||
imagineLeftRight: imagineLeftRight,
|
||||
imagineUpDown: imagineUpDown,
|
||||
imagineChangeCostumes: imagineChangeCostumes,
|
||||
imagineGlideToPoint: imagineGlideToPoint,
|
||||
imagineGrowShrink: imagineGrowShrink,
|
||||
imagineChooseAnotherBackdrop: imagineChooseAnotherBackdrop,
|
||||
imagineSwitchBackdrops: imagineSwitchBackdrops,
|
||||
imagineRecordASound: imagineRecordASound,
|
||||
imagineChooseSound: imagineChooseSound,
|
||||
|
||||
// Add a Backdrop
|
||||
addBackdrop: addBackdrop,
|
||||
|
||||
// Add Effects
|
||||
addEffects: addEffects,
|
||||
|
||||
// Hide and Show
|
||||
hideAndShow: hideAndShow,
|
||||
|
||||
// Switch Costumes
|
||||
switchCostumes: switchCostumes,
|
||||
|
||||
// Change Size
|
||||
changeSize: changeSize,
|
||||
|
||||
// Spin
|
||||
spinTurn: spinTurn,
|
||||
spinPointInDirection: spinPointInDirection,
|
||||
|
||||
// Record a Sound
|
||||
recordASoundSoundsTab: recordASoundSoundsTab,
|
||||
recordASoundClickRecord: recordASoundClickRecord,
|
||||
recordASoundPressRecordButton: recordASoundPressRecordButton,
|
||||
recordASoundChooseSound: recordASoundChooseSound,
|
||||
recordASoundPlayYourSound: recordASoundPlayYourSound,
|
||||
|
||||
// Use Arrow Keys
|
||||
moveArrowKeysLeftRight: moveArrowKeysLeftRight,
|
||||
moveArrowKeysUpDown: moveArrowKeysUpDown,
|
||||
|
||||
// Glide Around
|
||||
glideAroundBackAndForth: glideAroundBackAndForth,
|
||||
glideAroundPoint: glideAroundPoint
|
||||
|
||||
};
|
||||
|
||||
|
||||
export {enImages};
|
||||
@@ -0,0 +1,188 @@
|
||||
// Intro
|
||||
import introMove from './steps/intro-move.es.gif';
|
||||
import introSayHello from './steps/intro-say-hello.es.gif';
|
||||
|
||||
// Text to Speech
|
||||
// import speechAddExtension from './steps/speech-add-extension.es.gif';
|
||||
// import speechSaySomething from './steps/speech-say-something.es.gif';
|
||||
// import speechSetVoice from './steps/speech-set-voice.es.gif';
|
||||
// import speechMoveAround from './steps/speech-move-around.es.gif';
|
||||
// import speechAddBackdrop from './steps/speech-add-backdrop.es.gif';
|
||||
// import speechAddSprite from './steps/speech-add-sprite.es.gif';
|
||||
// import speechSong from './steps/speech-song.es.gif';
|
||||
// import speechChangeColor from './steps/speech-change-color.es.gif';
|
||||
// import speechSpin from './steps/speech-spin.es.gif';
|
||||
// import speechGrowShrink from './steps/speech-grow-shrink.es.gif';
|
||||
//
|
||||
// // Cartoon Network
|
||||
// import cnShowCharacter from './steps/cn-show-character.es.gif';
|
||||
// import cnSay from './steps/cn-say.es.gif';
|
||||
// import cnGlide from './steps/cn-glide.es.gif';
|
||||
// import cnPickSprite from './steps/cn-pick-sprite.es.gif';
|
||||
// import cnCollect from './steps/cn-collect.es.gif';
|
||||
// import cnVariable from './steps/cn-variable.es.gif';
|
||||
// import cnScore from './steps/cn-score.es.gif';
|
||||
// import cnBackdrop from './steps/cn-backdrop.es.gif';
|
||||
|
||||
// Add sprite
|
||||
import addSprite from './steps/add-sprite.es.gif';
|
||||
|
||||
// Animate a name
|
||||
import namePickLetter from './steps/name-pick-letter.es.gif';
|
||||
import namePlaySound from './steps/name-play-sound.es.gif';
|
||||
import namePickLetter2 from './steps/name-pick-letter2.es.gif';
|
||||
import nameChangeColor from './steps/name-change-color.es.gif';
|
||||
import nameSpin from './steps/name-spin.es.gif';
|
||||
import nameGrow from './steps/name-grow.es.gif';
|
||||
|
||||
// Make-Music
|
||||
import musicPickInstrument from './steps/music-pick-instrument.es.gif';
|
||||
import musicPlaySound from './steps/music-play-sound.es.gif';
|
||||
import musicMakeSong from './steps/music-make-song.es.gif';
|
||||
import musicMakeBeat from './steps/music-make-beat.es.gif';
|
||||
import musicMakeBeatbox from './steps/music-make-beatbox.es.gif';
|
||||
|
||||
// Chase-Game
|
||||
import chaseGameAddBackdrop from './steps/chase-game-add-backdrop.es.gif';
|
||||
import chaseGameAddSprite1 from './steps/chase-game-add-sprite1.es.gif';
|
||||
import chaseGameRightLeft from './steps/chase-game-right-left.es.gif';
|
||||
import chaseGameUpDown from './steps/chase-game-up-down.es.gif';
|
||||
import chaseGameAddSprite2 from './steps/chase-game-add-sprite2.es.gif';
|
||||
import chaseGameMoveRandomly from './steps/chase-game-move-randomly.es.gif';
|
||||
import chaseGamePlaySound from './steps/chase-game-play-sound.es.gif';
|
||||
import chaseGameAddVariable from './steps/chase-game-add-variable.es.gif';
|
||||
import chaseGameChangeScore from './steps/chase-game-change-score.es.gif';
|
||||
|
||||
// Clicker-Game (Pop Game)
|
||||
import popGamePickSprite from './steps/pop-game-pick-sprite.es.gif';
|
||||
import popGamePlaySound from './steps/pop-game-play-sound.es.gif';
|
||||
import popGameAddScore from './steps/pop-game-add-score.es.gif';
|
||||
import popGameChangeScore from './steps/pop-game-change-score.es.gif';
|
||||
import popGameRandomPosition from './steps/pop-game-random-position.es.gif';
|
||||
import popGameChangeColor from './steps/pop-game-change-color.es.gif';
|
||||
import popGameResetScore from './steps/pop-game-reset-score.es.gif';
|
||||
|
||||
// Animate A Character
|
||||
import animateCharPickBackdrop from './steps/animate-char-pick-backdrop.es.gif';
|
||||
import animateCharPickSprite from './steps/animate-char-pick-sprite.es.gif';
|
||||
import animateCharSaySomething from './steps/animate-char-say-something.es.gif';
|
||||
import animateCharAddSound from './steps/animate-char-add-sound.es.gif';
|
||||
import animateCharTalk from './steps/animate-char-talk.es.gif';
|
||||
import animateCharMove from './steps/animate-char-move.es.gif';
|
||||
import animateCharJump from './steps/animate-char-jump.es.gif';
|
||||
import animateCharChangeColor from './steps/animate-char-change-color.es.gif';
|
||||
|
||||
// Tell A Story
|
||||
import storyPickBackdrop from './steps/story-pick-backdrop.es.gif';
|
||||
import storyPickSprite from './steps/story-pick-sprite.es.gif';
|
||||
import storySaySomething from './steps/story-say-something.es.gif';
|
||||
import storyPickSprite2 from './steps/story-pick-sprite2.es.gif';
|
||||
import storyFlip from './steps/story-flip.es.gif';
|
||||
import storyConversation from './steps/story-conversation.es.gif';
|
||||
import storyPickBackdrop2 from './steps/story-pick-backdrop2.es.gif';
|
||||
import storySwitchBackdrop from './steps/story-switch-backdrop.es.gif';
|
||||
import storyHideCharacter from './steps/story-hide-character.es.gif';
|
||||
import storyShowCharacter from './steps/story-show-character.es.gif';
|
||||
|
||||
// Video Sensing
|
||||
import videoAddExtension from './steps/video-add-extension.es.gif';
|
||||
import videoPet from './steps/video-pet.es.gif';
|
||||
import videoAnimate from './steps/video-animate.es.gif';
|
||||
import videoPop from './steps/video-pop.es.gif';
|
||||
|
||||
const esImages = {
|
||||
// Intro
|
||||
introMove: introMove,
|
||||
introSayHello: introSayHello,
|
||||
|
||||
// // Text to Speech
|
||||
// speechAddExtension: speechAddExtension,
|
||||
// speechSaySomething: speechSaySomething,
|
||||
// speechSetVoice: speechSetVoice,
|
||||
// speechMoveAround: speechMoveAround,
|
||||
// speechAddBackdrop: speechAddBackdrop,
|
||||
// speechAddSprite: speechAddSprite,
|
||||
// speechSong: speechSong,
|
||||
// speechChangeColor: speechChangeColor,
|
||||
// speechSpin: speechSpin,
|
||||
// speechGrowShrink: speechGrowShrink,
|
||||
//
|
||||
// // Cartoon Network
|
||||
// cnShowCharacter: cnShowCharacter,
|
||||
// cnSay: cnSay,
|
||||
// cnGlide: cnGlide,
|
||||
// cnPickSprite: cnPickSprite,
|
||||
// cnCollect: cnCollect,
|
||||
// cnVariable: cnVariable,
|
||||
// cnScore: cnScore,
|
||||
// cnBackdrop: cnBackdrop,
|
||||
|
||||
// Add sprite
|
||||
addSprite: addSprite,
|
||||
|
||||
// Animate a name
|
||||
namePickLetter: namePickLetter,
|
||||
namePlaySound: namePlaySound,
|
||||
namePickLetter2: namePickLetter2,
|
||||
nameChangeColor: nameChangeColor,
|
||||
nameSpin: nameSpin,
|
||||
nameGrow: nameGrow,
|
||||
|
||||
// Make-Music
|
||||
musicPickInstrument: musicPickInstrument,
|
||||
musicPlaySound: musicPlaySound,
|
||||
musicMakeSong: musicMakeSong,
|
||||
musicMakeBeat: musicMakeBeat,
|
||||
musicMakeBeatbox: musicMakeBeatbox,
|
||||
|
||||
// Chase-Game
|
||||
chaseGameAddBackdrop: chaseGameAddBackdrop,
|
||||
chaseGameAddSprite1: chaseGameAddSprite1,
|
||||
chaseGameRightLeft: chaseGameRightLeft,
|
||||
chaseGameUpDown: chaseGameUpDown,
|
||||
chaseGameAddSprite2: chaseGameAddSprite2,
|
||||
chaseGameMoveRandomly: chaseGameMoveRandomly,
|
||||
chaseGamePlaySound: chaseGamePlaySound,
|
||||
chaseGameAddVariable: chaseGameAddVariable,
|
||||
chaseGameChangeScore: chaseGameChangeScore,
|
||||
|
||||
// Make-A-Pop/Clicker Game
|
||||
popGamePickSprite: popGamePickSprite,
|
||||
popGamePlaySound: popGamePlaySound,
|
||||
popGameAddScore: popGameAddScore,
|
||||
popGameChangeScore: popGameChangeScore,
|
||||
popGameRandomPosition: popGameRandomPosition,
|
||||
popGameChangeColor: popGameChangeColor,
|
||||
popGameResetScore: popGameResetScore,
|
||||
|
||||
// Animate A Character
|
||||
animateCharPickBackdrop: animateCharPickBackdrop,
|
||||
animateCharPickSprite: animateCharPickSprite,
|
||||
animateCharSaySomething: animateCharSaySomething,
|
||||
animateCharAddSound: animateCharAddSound,
|
||||
animateCharTalk: animateCharTalk,
|
||||
animateCharMove: animateCharMove,
|
||||
animateCharJump: animateCharJump,
|
||||
animateCharChangeColor: animateCharChangeColor,
|
||||
|
||||
// Tell A Story
|
||||
storyPickBackdrop: storyPickBackdrop,
|
||||
storyPickSprite: storyPickSprite,
|
||||
storySaySomething: storySaySomething,
|
||||
storyPickSprite2: storyPickSprite2,
|
||||
storyFlip: storyFlip,
|
||||
storyConversation: storyConversation,
|
||||
storyPickBackdrop2: storyPickBackdrop2,
|
||||
storySwitchBackdrop: storySwitchBackdrop,
|
||||
storyHideCharacter: storyHideCharacter,
|
||||
storyShowCharacter: storyShowCharacter,
|
||||
|
||||
// Video Sensing
|
||||
videoAddExtension: videoAddExtension,
|
||||
videoPet: videoPet,
|
||||
videoAnimate: videoAnimate,
|
||||
videoPop: videoPop
|
||||
|
||||
};
|
||||
|
||||
export {esImages};
|
||||
|
Before Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 652 KiB |
|
After Width: | Height: | Size: 802 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 718 KiB |
|
After Width: | Height: | Size: 487 KiB |
|
After Width: | Height: | Size: 872 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 669 KiB |
|
After Width: | Height: | Size: 487 KiB |
|
After Width: | Height: | Size: 541 KiB |