├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ ├── start-site-dev.yml │ └── start-site.yml ├── .gitignore ├── LICENSE ├── README.md ├── dist └── microbitMore.mjs ├── example └── test │ └── connection.sb3 ├── install-stretch3.sh ├── package.json ├── scratch-desktop ├── buildResources │ ├── ScratchDesktop.icns │ └── ScratchDesktop.ico └── src │ └── icon │ ├── ScratchDesktop.svg │ ├── ScratchMicrobitMoreDesktop.afdesign │ └── scratch-microbit-more-OSX.afdesign ├── scripts ├── build.js ├── change-logo.js ├── diff-scratch-desktop.js ├── install.js ├── scratch-desktop.patch ├── scratch-gui-logo.patch ├── scratch-gui-translation.patch ├── scratch-vm-desktop.patch ├── setup-desktop.js └── setup-local.js ├── site ├── favicon.ico ├── index.html └── scratch-logo.svg └── src ├── .eslintrc.js ├── block └── index.js └── entry ├── index.jsx ├── microbitMore-block.png ├── microbitMore-illustration.afdesign ├── microbitMore-illustration.svg ├── microbitMore-small.afdesign ├── microbitMore-small.svg ├── microbitMore.afdesign └── microbitMore.png /.eslintignore: -------------------------------------------------------------------------------- 1 | .build/* 2 | .dist/* 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": [ 3 | "eslint:recommended" 4 | ], 5 | "env": { 6 | "es6": true, 7 | "node": true 8 | }, 9 | "parserOptions": { 10 | "sourceType": "module", 11 | "ecmaVersion": 2017, 12 | }, 13 | "globals":{ 14 | }, 15 | "rules":{ 16 | 'arrow-body-style': [2, 'as-needed'], 17 | 'arrow-parens': [2, 'as-needed'], 18 | 'arrow-spacing': [2, { 19 | before: true, 20 | after: true 21 | }], 22 | 'indent': [2, 4, {"SwitchCase": 1}], 23 | 'no-confusing-arrow': [2], 24 | 'no-useless-computed-key': [2], 25 | 'no-useless-constructor': [2], 26 | 'no-var': [2], 27 | 'prefer-arrow-callback': [2], 28 | 'prefer-const': [2, {destructuring: 'all'}], 29 | 'prefer-template': [2], 30 | 'rest-spread-spacing': [2, 'never'], 31 | 'template-curly-spacing': [2, 'never'] 32 | } 33 | }; -------------------------------------------------------------------------------- /.github/workflows/start-site-dev.yml: -------------------------------------------------------------------------------- 1 | name: Start Dev Site 2 | on: 3 | push: 4 | branches: 5 | - develop 6 | tags: 7 | - "!*" 8 | 9 | jobs: 10 | build-deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | repository: yokobond/scratch-gui 16 | ref: xcratch 17 | path: ./scratch-gui 18 | - run: npm install 19 | working-directory: ./scratch-gui 20 | - uses: actions/checkout@v2 21 | with: 22 | repository: yokobond/scratch-microbit-more 23 | ref: develop 24 | path: ./scratch-microbit-more 25 | - run: node ./scripts/install.js --vm=../scratch-gui/node_modules/scratch-vm --gui=../scratch-gui --url="https://yokobond.github.io/scratch-microbit-more/dev/dist/microbitMore.mjs" -C 26 | working-directory: ./scratch-microbit-more 27 | - run: node ./scripts/change-logo.js -gui=../scratch-gui 28 | working-directory: ./scratch-microbit-more 29 | - run: npm run build 30 | working-directory: ./scratch-gui 31 | - run: cp ./scratch-microbit-more/site/index.html ./scratch-gui/build/index.html 32 | - run: cp ./scratch-microbit-more/site/favicon.ico ./scratch-gui/build/static/favicon.ico 33 | - run: cp -r ./scratch-microbit-more/dist ./scratch-gui/build/dist 34 | - run: cp -r ./scratch-microbit-more/example ./scratch-gui/build/example 35 | - uses: peaceiris/actions-gh-pages@v3 36 | with: 37 | deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} 38 | publish_dir: ./scratch-gui/build 39 | destination_dir: ./dev 40 | keep_files: true 41 | -------------------------------------------------------------------------------- /.github/workflows/start-site.yml: -------------------------------------------------------------------------------- 1 | name: Start Site 2 | on: 3 | push: 4 | branches: 5 | - trunk 6 | tags: 7 | - "!*" 8 | 9 | jobs: 10 | build-deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | repository: yokobond/scratch-gui 16 | ref: xcratch 17 | path: ./scratch-gui 18 | - run: npm install 19 | working-directory: ./scratch-gui 20 | - uses: actions/checkout@v2 21 | with: 22 | repository: yokobond/scratch-microbit-more 23 | ref: trunk 24 | path: ./scratch-microbit-more 25 | - run: node ./scripts/install.js --vm=../scratch-gui/node_modules/scratch-vm --gui=../scratch-gui --url="https://yokobond.github.io/scratch-microbit-more/dist/microbitMore.mjs" -C 26 | working-directory: ./scratch-microbit-more 27 | - run: node ./scripts/change-logo.js -gui=../scratch-gui 28 | working-directory: ./scratch-microbit-more 29 | - run: npm run build 30 | working-directory: ./scratch-gui 31 | - run: cp ./scratch-microbit-more/site/index.html ./scratch-gui/build/index.html 32 | - run: cp ./scratch-microbit-more/site/favicon.ico ./scratch-gui/build/static/favicon.ico 33 | - run: cp -r ./scratch-microbit-more/dist ./scratch-gui/build/dist 34 | - run: cp -r ./scratch-microbit-more/example ./scratch-gui/build/example 35 | - uses: peaceiris/actions-gh-pages@v3 36 | with: 37 | deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} 38 | publish_dir: ./scratch-gui/build 39 | keep_files: true 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.provisionprofile 2 | 3 | # Mac OS 4 | .DS_Store 5 | 6 | # NPM 7 | /node_modules 8 | npm-* 9 | 10 | # Testing 11 | /.nyc_output 12 | /coverage 13 | 14 | # Editor 15 | /.idea 16 | /.vscode 17 | 18 | # Build 19 | /build 20 | # /dist 21 | /playground 22 | /benchmark 23 | 24 | # Localization 25 | /translations 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Koji Yokokawa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **This project moved to a new repository [yokobond/mbit-more-v2](https://github.com/yokobond/mbit-more-v2).** 2 | 3 |

scratch-microbit-more

4 |

5 | Version 6 | 7 | Documentation 8 | 9 | 10 | Maintenance 11 | 12 | 13 | License: MIT 14 | 15 |

16 | 17 | > Full-functional extension of micro:bit for Scratch3 18 | 19 | ### ✨ Open [Microbit More Web-App](https://yokobond.github.io/scratch-microbit-more) 20 | 21 | ### 🏠 [Homepage](https://lab.yengawa.com/project/scratch-microbit-more/) 22 | 23 | ## Setup Development Environment 24 | 25 | Download the Scratch3 repositories according to the supporsed directory configuration. 26 | 27 | ``` 28 | . 29 | |-- scratch-microbit-more 30 | |-- scratch-vm 31 | |-- scratch-gui 32 | ``` 33 | 34 | Install node modules and setup to use local repo for development. 35 | 36 | ```sh 37 | cd ./scratch-microbit-more 38 | npm install 39 | npm run setup:local 40 | npm run install:local 41 | ``` 42 | 43 | ## Install into Scratch3 44 | 45 | To install this extention into your selfbuild Scratch3, execute `scripts/install.js` with options as follows. 46 | 47 | ```sh 48 | node ./scripts/install.js --gui="../scratch-gui" --vm="../scratch-gui/node_modules/scratch-vm" --url="https://yokobond.github.io/scratch-microbit-more/dist/microbitMore.mjs" 49 | ``` 50 | 51 | - --gui : location of scratch-gui from current dir. 52 | - --vm : location of scratch-vm form current dir. 53 | - --url : URL to get its module as a lodable extension for Xcratch. 54 | 55 | **CAUTION:** This script will change '`extension default`' in `scratch-gui/src/lib/libraries/extensions/index.jsx` as follows. 56 | 57 | change from the original code 58 | 59 | ```js 60 | export default [...]; 61 | ``` 62 | 63 | to 64 | 65 | ```js 66 | const extensions = [...]; 67 | export default extensions; 68 | ``` 69 | 70 | It may break installation mechanism of the other extensions. 71 | 72 | 73 | ## Xcratch Module Building 74 | 75 | Build module as loadable extension for [Xcratch](https://github.com/yokobond/xcratch). 76 | 77 | ```sh 78 | node ./scripts/build.js --name=microbitMore --block="./src/block" --entry="./src/entry" --vm="../scratch-vm" --gui="../scratch-gui" --output="./dist" 79 | ``` 80 | 81 | - --name: name of the module file (without '.mjs'). 82 | - --block : location of block files from current dir. 83 | - --entry : location of entry files from current dir. 84 | - --gui : location of scratch-gui from current dir. 85 | - --vm : location of scratch-vm form current dir. 86 | - --output : location to save module form current dir. 87 | 88 | ## Author 89 | 90 | 👤 **Koji Yokokawa** 91 | 92 | * Website: http://www.yengawa.com/ 93 | * Github: [@yokobond](https://github.com/yokobond) 94 | 95 | ## 🤝 Contributing 96 | 97 | Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/yokobond/scratch-microbit-more/issues). You can also take a look at the [contributing guide](https://github.com/yokobond/scratch-microbit-more/blob/master/CONTRIBUTING.md). 98 | 99 | ## Show your support 100 | 101 | Give a ⭐️ if this project helped you! 102 | 103 | 104 | ## 📝 License 105 | 106 | Copyright © 2020 [Koji Yokokawa](https://github.com/yokobond).
107 | This project is [MIT](https://github.com/yokobond/scratch-microbit-more/blob/trunk/LICENSE) licensed. 108 | 109 | *** 110 | _This README was generated with ❤️ by [readme-md-generator](https://github.com/kefranabg/readme-md-generator)_ -------------------------------------------------------------------------------- /example/test/connection.sb3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/example/test/connection.sb3 -------------------------------------------------------------------------------- /install-stretch3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## Install script for https://stretch3.github.io/ 4 | ## suppoesed dir configuration: 5 | ## scratch-gui 6 | ## - microbitMore 7 | 8 | LF=$(printf '\\\012_') 9 | LF=${LF%_} 10 | 11 | mkdir -p node_modules/scratch-vm/src/extensions/microbitMore 12 | cp microbitMore/src/block/index.js node_modules/scratch-vm/src/extensions/microbitMore/ 13 | mv node_modules/scratch-vm/src/extension-support/extension-manager.js node_modules/scratch-vm/src/extension-support/extension-manager.js_orig 14 | sed -e "s|class ExtensionManager {$|builtinExtensions['microbitMore'] = () => require('../extensions/microbitMore');${LF}${LF}class ExtensionManager {|g" node_modules/scratch-vm/src/extension-support/extension-manager.js_orig > node_modules/scratch-vm/src/extension-support/extension-manager.js 15 | 16 | mkdir -p src/lib/libraries/extensions/microbitMore 17 | cp microbitMore/src/entry/microbitMore.png src/lib/libraries/extensions/microbitMore/ 18 | cp microbitMore/src/entry/microbitMore-small.svg src/lib/libraries/extensions/microbitMore/ 19 | cp microbitMore/src/entry/microbitMore-illustration.svg src/lib/libraries/extensions/microbitMore/ 20 | mv src/lib/libraries/extensions/index.jsx src/lib/libraries/extensions/index.jsx_orig 21 | MICROBIT_MORE="\ 22 | {${LF}\ 23 | name: 'micro:bit MORE v0.5.0',${LF}\ 24 | extensionId: 'microbitMore',${LF}\ 25 | collaborator: 'Yengawa Lab',${LF}\ 26 | iconURL: microbitMoreIconURL,${LF}\ 27 | insetIconURL: microbitMoreInsetIconURL,${LF}\ 28 | description: (${LF}\ 29 | ${LF}\ 34 | ),${LF}\ 35 | featured: true,${LF}\ 36 | disabled: false,${LF}\ 37 | bluetoothRequired: true,${LF}\ 38 | internetConnectionRequired: false,${LF}\ 39 | launchPeripheralConnectionFlow: true,${LF}\ 40 | useAutoScan: false,${LF}\ 41 | connectionIconURL: microbitMoreConnectionIconURL,${LF}\ 42 | connectionSmallIconURL: microbitMoreConnectionSmallIconURL,${LF}\ 43 | connectingMessage: (${LF}\ 44 | ${LF}\ 49 | ),${LF}\ 50 | helpLink: 'https://lab.yengawa.com/project/scratch-microbit-more/'${LF}\ 51 | }," 52 | sed -e "s|^export default \[$|import microbitMoreIconURL from './microbitMore/microbitMore.png';${LF}import microbitMoreInsetIconURL from './microbitMore/microbitMore-small.svg';${LF}import microbitMoreConnectionIconURL from './microbitMore/microbitMore-illustration.svg';${LF}import microbitMoreConnectionSmallIconURL from './microbitMore/microbitMore-small.svg';${LF}${LF}export default [${LF}${MICROBIT_MORE}|g" src/lib/libraries/extensions/index.jsx_orig > src/lib/libraries/extensions/index.jsx 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scratch-microbit-more", 3 | "version": "0.5.0", 4 | "description": "Full-functional extension of micro:bit for Scratch3", 5 | "module": "./dist/microbitMore.mjs", 6 | "scratchExtension": { 7 | "block": "./dist/microbitMore.mjs", 8 | "entry": "./dist/microbitMore.entry.mjs" 9 | }, 10 | "scripts": { 11 | "setup:local": "node ./scripts/setup-local.js && npm run install:local", 12 | "setup:desktop": "node ./scripts/setup-desktop.js", 13 | "build:local": "rimraf ./build && mkdirp ./build && node ./scripts/build.js --name=microbitMore --block=\"./src/block\" --entry=\"./src/entry\" --vm=\"../scratch-vm\" --gui=\"../scratch-gui\" --output=\"./build\" --debug", 14 | "build:dist": "rimraf ./dist && mkdirp ./dist && node ./scripts/build.js --name=microbitMore --block=\"./src/block\" --entry=\"./src/entry\" --vm=\"../scratch-vm\" --gui=\"../scratch-gui\" --output=\"./dist\"", 15 | "install:local": "node ./scripts/install.js --link -C --vm=\"../scratch-vm\" --gui=\"../scratch-gui\" --url=\"http://127.0.0.1:5500/build/microbitMore.mjs\" && node ./scripts/change-logo.js --gui=\"../scratch-gui\"", 16 | "install:dev": "node ./scripts/install.js -C --gui=\"../scratch-gui\" --vm=\"../scratch-gui/node_modules/scratch-vm\" --url=\"https://yokobond.github.io/scratch-microbit-more/dev/dist/microbitMore.mjs\" && node ./scripts/change-logo.js --gui=\"../scratch-gui\"", 17 | "install:dist": "node ./scripts/install.js -C --gui=\"../scratch-gui\" --vm=\"../scratch-gui/node_modules/scratch-vm\" --url=\"https://yokobond.github.io/scratch-microbit-more/dist/microbitMore.mjs\" && node ./scripts/change-logo.js --gui=\"../scratch-gui\"", 18 | "install:desktop": "node ./scripts/install.js --link -C --vm=\"../scratch-desktop/node_modules/scratch-vm\" --gui=\"../scratch-desktop/node_modules/scratch-gui\" --url=\"https://yokobond.github.io/scratch-microbit-more/dist/microbitMore.mjs\" && node ./scripts/change-logo.js --gui=\"../scratch-desktop/node_modules/scratch-gui\"", 19 | "start:local": "cd ../scratch-gui && npm run start -- --https", 20 | "test": "echo \"Error: no test specified\" && exit 1" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/yokobond/scratch-microbit-more.git" 25 | }, 26 | "keywords": [ 27 | "scratch", 28 | "microbit" 29 | ], 30 | "author": "Koji Yokokawa", 31 | "license": "MIT", 32 | "bugs": { 33 | "url": "https://github.com/yokobond/scratch-microbit-more/issues" 34 | }, 35 | "homepage": "https://github.com/yokobond/scratch-microbit-more#readme", 36 | "devDependencies": { 37 | "@babel/core": "^7.11.6", 38 | "@babel/plugin-transform-react-jsx": "^7.10.4", 39 | "@babel/preset-env": "^7.11.5", 40 | "@babel/preset-react": "^7.10.4", 41 | "@rollup/plugin-babel": "^5.2.1", 42 | "@rollup/plugin-commonjs": "^15.0.0", 43 | "@rollup/plugin-image": "^2.0.5", 44 | "@rollup/plugin-multi-entry": "^4.0.0", 45 | "@rollup/plugin-node-resolve": "^9.0.0", 46 | "babel-eslint": "^10.1.0", 47 | "babel-loader": "^8.1.0", 48 | "command-line-args": "^5.1.1", 49 | "eslint": "^7.9.0", 50 | "eslint-config-scratch": "^6.0.0", 51 | "fs-extra": "^9.0.1", 52 | "mkdirp": "^1.0.4", 53 | "rimraf": "^3.0.2", 54 | "rollup": "^2.26.11", 55 | "rollup-plugin-node-builtins": "^2.1.2", 56 | "rollup-plugin-node-globals": "^1.4.0" 57 | }, 58 | "dependencies": {} 59 | } 60 | -------------------------------------------------------------------------------- /scratch-desktop/buildResources/ScratchDesktop.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/scratch-desktop/buildResources/ScratchDesktop.icns -------------------------------------------------------------------------------- /scratch-desktop/buildResources/ScratchDesktop.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/scratch-desktop/buildResources/ScratchDesktop.ico -------------------------------------------------------------------------------- /scratch-desktop/src/icon/ScratchMicrobitMoreDesktop.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/scratch-desktop/src/icon/ScratchMicrobitMoreDesktop.afdesign -------------------------------------------------------------------------------- /scratch-desktop/src/icon/scratch-microbit-more-OSX.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/scratch-desktop/src/icon/scratch-microbit-more-OSX.afdesign -------------------------------------------------------------------------------- /scripts/build.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | const commandLineArgs = require('command-line-args'); 4 | const rollup = require('rollup'); 5 | const babel = require('@rollup/plugin-babel').default; 6 | const commonjs = require('@rollup/plugin-commonjs'); 7 | const nodeResolve = require('@rollup/plugin-node-resolve').default; 8 | const nodeBuiltins = require('rollup-plugin-node-builtins'); 9 | const nodeGlobals = require('rollup-plugin-node-globals'); 10 | const importImage = require('@rollup/plugin-image'); 11 | const multi = require('@rollup/plugin-multi-entry'); 12 | 13 | const optionDefinitions = [ 14 | { 15 | name: 'name', 16 | type: String 17 | }, 18 | { 19 | name: 'block', 20 | type: String 21 | }, 22 | { 23 | name: 'entry', 24 | type: String 25 | }, 26 | { 27 | name: 'vm', 28 | type:String, 29 | defaultValue: '../scratch-vm' 30 | }, 31 | { 32 | name: 'gui', 33 | type:String, 34 | defaultValue: '../scratch-gui' 35 | }, 36 | { 37 | name: 'output', 38 | type:String, 39 | defaultValue: './build' 40 | }, 41 | { 42 | name: 'debug', 43 | type:Boolean 44 | } 45 | ]; 46 | 47 | // Read options 48 | const options = commandLineArgs(optionDefinitions); 49 | if (!options['name']) { 50 | throw('set --name '); 51 | } 52 | const moduleName = options['name']; 53 | if (!options['block']) { 54 | throw('set --block '); 55 | } 56 | const extSrcDir = path.resolve(process.cwd(), options['block']); 57 | if (!options['entry']) { 58 | throw('set --entry '); 59 | } 60 | const entrySrcDir = path.resolve(process.cwd(), options['entry']); 61 | const VmRoot = path.resolve(process.cwd(), options['vm']); 62 | console.log(`vm = ${VmRoot}`); 63 | const GuiRoot = path.resolve(process.cwd(), options['gui']); 64 | console.log(`gui = ${GuiRoot}`); 65 | const outputDir = path.resolve(process.cwd(), options['output']); 66 | console.log(`output = ${outputDir}`); 67 | 68 | const blockWorkingDir = path.resolve(VmRoot, `src/extensions/_${moduleName}`); 69 | const blockFile = path.resolve(blockWorkingDir, 'index.js'); 70 | 71 | const entryWorkingDir = path.resolve(GuiRoot, `src/lib/libraries/extensions/_${moduleName}`); 72 | const entryFile = path.resolve(entryWorkingDir, 'index.jsx'); 73 | 74 | const moduleFile = path.resolve(outputDir, `${moduleName}.mjs`); 75 | 76 | const rollupOptions = { 77 | inputOptions: { 78 | input: [entryFile, blockFile], 79 | plugins: [ 80 | multi(), 81 | importImage(), 82 | nodeResolve({browser: true, preferBuiltins: true}), 83 | commonjs({ 84 | }), 85 | nodeBuiltins(), 86 | nodeGlobals(), 87 | babel({ 88 | babelrc: false, 89 | presets: [ 90 | ['@babel/preset-env', 91 | { 92 | "modules": false, 93 | targets: { 94 | browsers: [ 95 | 'last 3 versions', 96 | 'Safari >= 8', 97 | 'iOS >= 8'] 98 | } 99 | } 100 | ], 101 | '@babel/preset-react' 102 | ], 103 | babelHelpers: 'bundled', 104 | plugins: [ 105 | '@babel/plugin-transform-react-jsx' 106 | ] 107 | }), 108 | ] 109 | }, 110 | outputOptions: { 111 | file: moduleFile, 112 | format: 'es', 113 | } 114 | } 115 | 116 | async function build() { 117 | // Copy module sources 118 | fs.copySync(extSrcDir, blockWorkingDir); 119 | fs.copySync(entrySrcDir, entryWorkingDir); 120 | console.log('\ncopy source to working dir'); 121 | console.log(blockWorkingDir); 122 | console.log(entryWorkingDir); 123 | 124 | // Build module. 125 | console.log('\nstart to build module ...'); 126 | const bundle = await rollup.rollup(rollupOptions.inputOptions); 127 | if (options['debug']) { 128 | console.log('\ncontent files\n----') 129 | bundle.watchFiles.forEach(fileName => console.log(fileName)); // an array of file names this bundle depends on 130 | console.log('----\n'); 131 | // show contents of the module 132 | bundle.generate(rollupOptions.outputOptions) 133 | .then(res => { 134 | for (const chunkOrAsset of res.output) { 135 | if (chunkOrAsset.type === 'asset') { 136 | console.log('Asset', chunkOrAsset); 137 | } else { 138 | console.log('Chunk', chunkOrAsset.modules); 139 | } 140 | } 141 | }) 142 | } 143 | // write the bundle to disk 144 | await bundle.write(rollupOptions.outputOptions); 145 | console.log(`\nsuccess to build module: ${moduleFile}`); 146 | 147 | // Clean up 148 | fs.removeSync(blockWorkingDir); 149 | fs.removeSync(entryWorkingDir); 150 | console.log('\nworking dir removed'); 151 | } 152 | 153 | try { 154 | build(); 155 | } catch (err) { 156 | console.error(err) 157 | } 158 | -------------------------------------------------------------------------------- /scripts/change-logo.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const { execSync } = require('child_process') 4 | 5 | function getArgs () { 6 | const args = {}; 7 | process.argv 8 | .slice(2, process.argv.length) 9 | .forEach( arg => { 10 | if (arg.slice(0,2) === '--') { 11 | // long arg 12 | const longArg = arg.split('='); 13 | const longArgFlag = longArg[0].slice(2,longArg[0].length); 14 | const longArgValue = longArg.length > 1 ? longArg[1] : true; 15 | args[longArgFlag] = longArgValue; 16 | } 17 | else if (arg[0] === '-') { 18 | // flags 19 | const flags = arg.slice(1,arg.length).split(''); 20 | flags.forEach(flag => { 21 | args[flag] = true; 22 | }); 23 | } 24 | }); 25 | return args; 26 | } 27 | 28 | const args = getArgs(); 29 | 30 | const GuiRoot = args['gui'] ? 31 | path.resolve(process.cwd(), args['gui']) 32 | : path.resolve(__dirname, '../../scratch-gui'); 33 | const GuiMenuBarLogoFile = path.resolve(GuiRoot, 'src/components/menu-bar/scratch-logo.svg'); 34 | 35 | // Change logo image of scratch-gui 36 | fs.copyFileSync(path.resolve(__dirname, '../site/scratch-logo.svg'), GuiMenuBarLogoFile); 37 | console.log(`Overwrite ${GuiMenuBarLogoFile} `); 38 | 39 | // Applay patch to scratch-gui 40 | try { 41 | execSync(`cd ${GuiRoot} && patch -p1 -N -s --no-backup-if-mismatch < ${path.resolve(__dirname, './scratch-gui-logo.patch')}`); 42 | console.log(`Patch ${path.resolve(__dirname, './scratch-gui-logo.patch')}`); 43 | } catch (err) { 44 | // already applyed? 45 | console.log(`Fail patch ${path.resolve(__dirname, './scratch-gui-logo.patch')}`); 46 | // console.error(err); 47 | } 48 | -------------------------------------------------------------------------------- /scripts/diff-scratch-desktop.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { execSync } = require('child_process'); 3 | 4 | const ExtRoot = path.resolve(__dirname, '../'); 5 | const DesktopRoot = path.resolve(__dirname, '../../scratch-desktop'); 6 | 7 | try { 8 | execSync(`cd ${DesktopRoot} && git diff -- . ':(exclude)package-lock.json' ':(exclude)buildResources' ':(exclude)src/icon' > ${path.join(ExtRoot, 'scripts', 'scratch-desktop.patch')}`); 9 | } catch (err) { 10 | console.error(err); 11 | } 12 | -------------------------------------------------------------------------------- /scripts/install.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const { execSync } = require('child_process') 4 | 5 | function getArgs() { 6 | const args = {}; 7 | process.argv 8 | .slice(2, process.argv.length) 9 | .forEach(arg => { 10 | if (arg.slice(0, 2) === '--') { 11 | // long arg 12 | const longArg = arg.split('='); 13 | const longArgFlag = longArg[0].slice(2, longArg[0].length); 14 | const longArgValue = longArg.length > 1 ? longArg[1] : true; 15 | args[longArgFlag] = longArgValue; 16 | } 17 | else if (arg[0] === '-') { 18 | // flags 19 | const flags = arg.slice(1, arg.length).split(''); 20 | flags.forEach(flag => { 21 | args[flag] = true; 22 | }); 23 | } 24 | }); 25 | return args; 26 | } 27 | 28 | const args = getArgs(); 29 | 30 | // Make symbolic link 31 | function makeSymbolickLink(to, from) { 32 | try { 33 | const stats = fs.lstatSync(from); 34 | if (stats.isSymbolicLink()) { 35 | if (fs.readlinkSync(from) === to) { 36 | console.log(`Already exists link: ${from} -> ${fs.readlinkSync(from)}`); 37 | return; 38 | } 39 | fs.unlink(from); 40 | } else { 41 | if (process.platform === 'win32') { 42 | execSync(`rd /s /q ${from}`); 43 | } else { 44 | execSync(`rm -r ${from}`); 45 | // fs.renameSync(from, `${from}~`); 46 | } 47 | } 48 | } catch (err) { 49 | // File not esists. 50 | } 51 | fs.symlinkSync(to, from); 52 | console.log(`Make link: ${from} -> ${fs.readlinkSync(from)}`); 53 | } 54 | 55 | // Copy directory after delete old one. 56 | function copyDir(from, to) { 57 | try { 58 | const stats = fs.lstatSync(to); 59 | if (stats.isSymbolicLink()) { 60 | fs.unlinkSync(to); 61 | } else { 62 | if (process.platform === 'win32') { 63 | execSync(`rd /s /q ${to}`); 64 | } else { 65 | execSync(`rm -r ${to}`); 66 | // fs.renameSync(to, `${to}~`); 67 | } 68 | } 69 | } catch (err) { 70 | // File not esists. 71 | } 72 | if (process.platform === 'win32') { 73 | execSync(`xcopy ${from} ${to} /I /Y`); 74 | } else { 75 | execSync(`mkdir -p ${to} && cp -r ${path.join(from, '*')} ${to}`); 76 | } 77 | 78 | console.log(`copy dir ${from} -> ${to}`); 79 | } 80 | 81 | const ExtId = 'microbitMore'; 82 | const ExtDirName = 'microbitMore'; 83 | 84 | const VmRoot = args['vm'] ? 85 | path.resolve(process.cwd(), args['vm']) : 86 | path.resolve(__dirname, '../../scratch-vm'); 87 | const GuiRoot = args['gui'] ? 88 | path.resolve(process.cwd(), args['gui']) : 89 | path.resolve(__dirname, '../../scratch-gui'); 90 | 91 | const ExtBlockPath = path.resolve(__dirname, '../src/block'); 92 | const ExtEntryPath = path.resolve(__dirname, '../src/entry'); 93 | 94 | const VmExtDirPath = path.resolve(VmRoot, `src/extensions/${ExtDirName}`); 95 | const GuiExtDirPath = path.resolve(GuiRoot, `src/lib/libraries/extensions/${ExtDirName}`); 96 | 97 | const EntryFile = path.resolve(GuiExtDirPath, './index.jsx'); 98 | const BlockFile = path.resolve(VmExtDirPath, './index.js'); 99 | 100 | const VmExtManagerFile = path.resolve(VmRoot, './src/extension-support/extension-manager.js'); 101 | const VmVirtualMachineFile = path.resolve(VmRoot, './src/virtual-machine.js'); 102 | const GuiExtIndexFile = path.resolve(GuiRoot, './src/lib/libraries/extensions/index.jsx'); 103 | 104 | let stdout; 105 | 106 | if (args['link']) { 107 | // Make symbolic link in scratch-vm. 108 | makeSymbolickLink(ExtBlockPath, VmExtDirPath); 109 | // Make symbolic link in scratch-gui. 110 | makeSymbolickLink(ExtEntryPath, GuiExtDirPath); 111 | } else { 112 | // Copy block dir to scratch-vm. 113 | copyDir(ExtBlockPath, VmExtDirPath); 114 | // Copy entry dir in scratch-gui. 115 | copyDir(ExtEntryPath, GuiExtDirPath); 116 | } 117 | 118 | // Replace URL in entry and block code. 119 | if (args['url']) { 120 | const url = args['url']; 121 | // Replace URL in entry 122 | let entryCode = fs.readFileSync(EntryFile, 'utf-8'); 123 | entryCode = entryCode.replace(/extensionURL:\s*[^,]+,/m, `extensionURL: '${url}',`); 124 | fs.writeFileSync(EntryFile, entryCode); 125 | console.log(`Entry: extensionURL = ${url}`); 126 | 127 | // Replace URL in entry 128 | let blockCode = fs.readFileSync(BlockFile, 'utf-8'); 129 | blockCode = blockCode.replace(/let\s+extensionURL\s+=\s+[^;]+;/m, `let extensionURL = '${url}';`); 130 | fs.writeFileSync(BlockFile, blockCode); 131 | console.log(`Block: extensionURL = ${url}`); 132 | } 133 | 134 | // Add the extension to extension manager of scratch-vm. 135 | let managerCode = fs.readFileSync(VmExtManagerFile, 'utf-8'); 136 | if (managerCode.includes(ExtId)) { 137 | console.log(`Already registered in manager: ${ExtId}`); 138 | } else { 139 | fs.copyFileSync(VmExtManagerFile, `${VmExtManagerFile}_orig`); 140 | managerCode = managerCode.replace(/builtinExtensions = {[\s\S]*?};/, `$&\n\nbuiltinExtensions.${ExtId} = () => require('../extensions/${ExtDirName}');`); 141 | fs.writeFileSync(VmExtManagerFile, managerCode); 142 | console.log(`Registered in manager: ${ExtId}`); 143 | } 144 | 145 | if (args['C']) { 146 | // Add the extension as a core extension. 147 | let vmCode = fs.readFileSync(VmVirtualMachineFile, 'utf-8'); 148 | if (vmCode.includes(ExtId)) { 149 | console.log(`Already added as a core extension: ${ExtId}`); 150 | } else { 151 | fs.copyFileSync(VmVirtualMachineFile, `${VmVirtualMachineFile}_orig`); 152 | vmCode = vmCode.replace(/CORE_EXTENSIONS = \[[\s\S]*?\];/, `$&\n\nCORE_EXTENSIONS.push('${ExtId}');`); 153 | fs.writeFileSync(VmVirtualMachineFile, vmCode); 154 | console.log(`Add as a core extension: ${ExtId}`); 155 | } 156 | } 157 | 158 | // Add the extension to list of scratch-gui. 159 | let indexCode = fs.readFileSync(GuiExtIndexFile, 'utf-8'); 160 | if (indexCode.includes(ExtId)) { 161 | console.log(`Already added to extrnsion list: ${ExtId}`); 162 | } else { 163 | fs.copyFileSync(GuiExtIndexFile, `${GuiExtIndexFile}_orig`); 164 | const immutableDefault = /^\s*export\s+default\s+\[/m 165 | if (immutableDefault.test(indexCode)) { 166 | // Make the list of extensions mutable. 167 | indexCode = indexCode.replace(immutableDefault, 'const extensions = ['); 168 | indexCode += '\nexport default extensions;'; 169 | } 170 | indexCode += `\n// Injected for extra extension ${ExtId}`; 171 | indexCode += `\nimport ${ExtId} from './${ExtDirName}/index.jsx';`; 172 | indexCode += `\nextensions.unshift(${ExtId});`; 173 | indexCode += '\n'; 174 | fs.writeFileSync(GuiExtIndexFile, indexCode); 175 | console.log(`Added to extrnsion list: ${ExtId}`); 176 | } 177 | 178 | // Applay patch fro translation to scratch-gui 179 | try { 180 | stdout = execSync(`cd ${GuiRoot} && patch -p1 -N -s --no-backup-if-mismatch < ${path.resolve(__dirname, './scratch-gui-translation.patch')}`); 181 | console.log(`stdout: ${stdout.toString()}`); 182 | } catch (err) { 183 | // already applyed 184 | console.log(`fail scratch-gui-translation.patch`); 185 | // console.error(err); 186 | } 187 | -------------------------------------------------------------------------------- /scripts/scratch-desktop.patch: -------------------------------------------------------------------------------- 1 | diff --git a/electron-builder.yaml b/electron-builder.yaml 2 | index e52e662..44ff2b6 100644 3 | --- a/electron-builder.yaml 4 | +++ b/electron-builder.yaml 5 | @@ -1,8 +1,8 @@ 6 | directories: 7 | buildResources: buildResources 8 | output: dist 9 | -appId: edu.mit.scratch.scratch-desktop 10 | -productName: "Scratch 3" 11 | +appId: com.yengawa.mbitmore 12 | +productName: "MicrobitMore Desktop" 13 | publish: # empty provider list = don't publish 14 | mac: 15 | category: public.app-category.education 16 | @@ -16,12 +16,12 @@ mac: 17 | hardenedRuntime: true 18 | icon: buildResources/ScratchDesktop.icns 19 | provisioningProfile: embedded.provisionprofile 20 | - artifactName: "Scratch ${version}.${ext}" 21 | + artifactName: "MicrobitMore Desktop ${version}.${ext}" 22 | target: 23 | - dmg 24 | - mas 25 | dmg: 26 | - title: "Scratch ${version}" 27 | + title: "MicrobitMore Desktop ${version}" 28 | mas: 29 | category: public.app-category.education 30 | entitlements: buildResources/entitlements.mas.plist 31 | @@ -37,10 +37,10 @@ win: 32 | - appx 33 | - nsis 34 | appx: 35 | - identityName: ScratchFoundation.ScratchDesktop 36 | - publisherDisplayName: "Scratch Foundation" 37 | - publisher: "CN=2EC43DF1-469A-4119-9AB9-568A0A1FF65F" 38 | - artifactName: "Scratch ${version}.${ext}" 39 | + identityName: YengawaLab.MicrobitMoreDesktop 40 | + publisherDisplayName: "YengawaLab" 41 | + publisher: "CN=YENGAWA-LAB" 42 | + artifactName: "MicrobitMore Desktop ${version}.${ext}" 43 | nsis: 44 | oneClick: false # allow user to choose per-user or per-machine 45 | - artifactName: "Scratch ${version} Setup.${ext}" 46 | + artifactName: "MicrobitMore Desktop ${version} Setup.${ext}" 47 | diff --git a/scripts/afterSign.js b/scripts/afterSign.js 48 | index fbe4fb0..326fe89 100644 49 | --- a/scripts/afterSign.js 50 | +++ b/scripts/afterSign.js 51 | @@ -2,7 +2,7 @@ const {notarize} = require('electron-notarize'); 52 | 53 | const notarizeMacBuild = async function (context) { 54 | // keep this in sync with appId in the electron-builder config 55 | - const appId = 'edu.mit.scratch.scratch-desktop'; 56 | + const appId = 'com.yengawa.mbitmore'; 57 | 58 | if (!process.env.AC_USERNAME) { 59 | console.error([ 60 | diff --git a/src/main/index.js b/src/main/index.js 61 | index 1688313..c3ff6a4 100644 62 | --- a/src/main/index.js 63 | +++ b/src/main/index.js 64 | @@ -43,6 +43,7 @@ const _windows = {}; 65 | // enable connecting to Scratch Link even if we DNS / Internet access is not available 66 | // this must happen BEFORE the app ready event! 67 | app.commandLine.appendSwitch('host-resolver-rules', 'MAP device-manager.scratch.mit.edu 127.0.0.1'); 68 | +app.commandLine.appendSwitch('enable-experimental-web-platform-features'); 69 | 70 | const displayPermissionDeniedWarning = (browserWindow, permissionType) => { 71 | let title; 72 | @@ -309,6 +310,27 @@ const createMainWindow = () => { 73 | window.show(); 74 | }); 75 | 76 | + // receive found devices from navigator.bluetooth.requestDevice() 77 | + webContents.on('select-bluetooth-device', (event, deviceList, callback) => { 78 | + event.preventDefault(); 79 | + if (window.bluetoothDeviceIdToConnect) { 80 | + callback(window.bluetoothDeviceIdToConnect); 81 | + window.bluetoothDeviceIdToConnect = null; 82 | + return; 83 | + } 84 | + webContents.send('discovered-bluetooth-devices', JSON.stringify(deviceList)); 85 | + }); 86 | + 87 | + // receive device to connect from renderer 88 | + ipcMain.on('connect-bluetooth-device', (_event, deviceId) => { 89 | + window.bluetoothDeviceIdToConnect = deviceId; 90 | + }); 91 | + 92 | + // receive device to connect from renderer 93 | + ipcMain.on('cancel-select-bluetooth-device', () => { 94 | + window.bluetoothDeviceIdToConnect = ''; // Cancel to requestDevice() reffered by document of Electron. 95 | + }); 96 | + 97 | return window; 98 | }; 99 | 100 | -------------------------------------------------------------------------------- /scripts/scratch-gui-logo.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/components/stage-header/stage-header.jsx b/src/components/stage-header/stage-header.jsx 2 | index 4084f6bfc..de6f65785 100644 3 | --- a/src/components/stage-header/stage-header.jsx 4 | +++ b/src/components/stage-header/stage-header.jsx 5 | @@ -68,7 +68,7 @@ const StageHeaderComponent = function (props) { 6 | const stageButton = showBranding ? ( 7 |
8 | 14 | diff --git a/src/playground/render-gui.jsx b/src/playground/render-gui.jsx 15 | index 0f15fbfa7..993894bba 100644 16 | --- a/src/playground/render-gui.jsx 17 | +++ b/src/playground/render-gui.jsx 18 | @@ -8,7 +8,7 @@ import HashParserHOC from '../lib/hash-parser-hoc.jsx'; 19 | import log from '../lib/log.js'; 20 | 21 | const onClickLogo = () => { 22 | - window.location = 'https://scratch.mit.edu'; 23 | + window.location = 'https://lab.yengawa.com/project/scratch-microbit-more/'; 24 | }; 25 | 26 | const handleTelemetryModalCancel = () => { 27 | -------------------------------------------------------------------------------- /scripts/scratch-gui-translation.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/containers/extension-library.jsx b/src/containers/extension-library.jsx 2 | index b46d992c0..b742e03c5 100644 3 | --- a/src/containers/extension-library.jsx 4 | +++ b/src/containers/extension-library.jsx 5 | @@ -51,6 +51,14 @@ class ExtensionLibrary extends React.PureComponent { 6 | rawURL: extension.iconURL || extensionIcon, 7 | ...extension 8 | })); 9 | + extensionLibraryContent.forEach(extension => { 10 | + if (extension.translationMap) { 11 | + Object.assign( 12 | + this.props.intl.messages, 13 | + extension.translationMap[this.props.intl.locale] 14 | + ); 15 | + } 16 | + }); 17 | return ( 18 | ${fs.readlinkSync(from)}`); 41 | // return; 42 | // } 43 | // fs.unlink(from); 44 | // } else { 45 | // // execSync(`rm -r ${from}`); 46 | // fs.renameSync(from, `${from}~`); 47 | // } 48 | // } catch (err) { 49 | // // File not esists. 50 | // } 51 | // fs.symlinkSync(to, from); 52 | // console.log(`Make link: ${from} -> ${fs.readlinkSync(from)}`); 53 | // } 54 | // makeSymbolickLink( 55 | // path.resolve(__dirname, '../../scratch-vm'), 56 | // path.resolve(DesktopRoot, './node_modules/scratch-vm') 57 | // ) 58 | 59 | // // Change WebBLE for Electron 60 | // fs.copyFileSync( 61 | // path.join(VmRoot, 'src', 'io', 'ble-web-electron.js'), 62 | // path.join(VmRoot, 'src', 'io', 'ble-web.js') 63 | // ); 64 | 65 | // Apply patch to scratch-vm 66 | try { 67 | stdout = execSync(`cd ${VmRoot} && patch -p1 -N -s --no-backup-if-mismatch < ${path.join(ExtRoot, 'scripts', 'scratch-vm-desktop.patch')}`); 68 | } catch (err) { 69 | console.log('fail to apply: scratch-vm-desktop.patch'); 70 | } 71 | 72 | // Change logo image of scratch-desktop 73 | fs.copyFileSync( 74 | path.join(ExtRoot, 'scratch-desktop', IcnsFilePath), 75 | path.join(DesktopRoot, IcnsFilePath) 76 | ); 77 | fs.copyFileSync( 78 | path.join(ExtRoot, 'scratch-desktop', IcoFilePath), 79 | path.join(DesktopRoot, IcoFilePath) 80 | ); 81 | fs.copyFileSync( 82 | path.join(ExtRoot, 'scratch-desktop', SvgFilePath), 83 | path.join(DesktopRoot, SvgFilePath) 84 | ); 85 | 86 | // Set provision profile for Mac app 87 | if (process.platform === 'darwin') { 88 | fs.copyFileSync( 89 | path.join(ExtRoot, 'scratch-desktop', ProvisionProfilePath), 90 | path.join(DesktopRoot, ProvisionProfilePath)); 91 | } 92 | -------------------------------------------------------------------------------- /scripts/setup-local.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | // const { execSync } = require('child_process') 4 | 5 | const VmRoot = path.resolve(__dirname, '../../scratch-vm'); 6 | const GuiRoot = path.resolve(__dirname, '../../scratch-gui'); 7 | 8 | // Make symbolic link 9 | function makeSymbolickLink(to, from) { 10 | try { 11 | const stats = fs.lstatSync(from); 12 | if (stats.isSymbolicLink()) { 13 | if (fs.readlinkSync(from) === to) { 14 | console.log(`Already exists link: ${from} -> ${fs.readlinkSync(from)}`); 15 | return; 16 | } 17 | fs.unlink(from); 18 | } else { 19 | // execSync(`rm -r ${from}`); 20 | fs.renameSync(from, `${from}~`); 21 | } 22 | } catch (err) { 23 | // File not esists. 24 | } 25 | fs.symlinkSync(to, from); 26 | console.log(`Make link: ${from} -> ${fs.readlinkSync(from)}`); 27 | } 28 | 29 | // Use local scratch-vm in scratch-gui 30 | makeSymbolickLink( 31 | VmRoot, 32 | path.resolve(GuiRoot, './node_modules/scratch-vm') 33 | ) 34 | -------------------------------------------------------------------------------- /site/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/site/favicon.ico -------------------------------------------------------------------------------- /site/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Scratch Microbit More 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /site/scratch-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/.eslintrc.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | module.exports = { 3 | root: true, 4 | extends: ['scratch', 'scratch/es6', 'scratch/react', 'plugin:import/errors'], 5 | env: { 6 | browser: true 7 | }, 8 | globals: { 9 | process: true 10 | }, 11 | rules: { 12 | 'import/no-mutable-exports': 'error', 13 | 'import/no-commonjs': 'error', 14 | 'import/no-amd': 'error', 15 | 'import/no-nodejs-modules': 'error', 16 | 'react/jsx-no-literals': 'error', 17 | 'no-confusing-arrow': ['error', { 18 | 'allowParens': true 19 | }] 20 | }, 21 | settings: { 22 | react: { 23 | version: '16.2' // Prevent 16.3 lifecycle method errors 24 | }, 25 | 'import/resolver': { 26 | webpack: { 27 | config: path.resolve(__dirname, '../webpack.config.js') 28 | } 29 | } 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /src/entry/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {FormattedMessage} from 'react-intl'; 3 | 4 | import microbitMoreIconURL from './microbitMore.png'; 5 | import microbitMoreInsetIconURL from './microbitMore-small.svg'; 6 | import microbitMoreConnectionIconURL from './microbitMore-illustration.svg'; 7 | import microbitMoreConnectionSmallIconURL from './microbitMore-small.svg'; 8 | 9 | const translationMap = { 10 | 'ja': { 11 | 'gui.extension.microbitMore.description': 'micro:bitのすべての機能で遊ぶ。' 12 | }, 13 | 'ja-Hira': { 14 | 'gui.extension.microbitMore.description': 'マイクロビットのすべてのきのうであそぶ。' 15 | } 16 | }; 17 | 18 | const entry = { 19 | name: 'micro:bit MORE v0.5.0', 20 | extensionId: 'microbitMore', 21 | extensionURL: 'https://yokobond.github.io/scratch-microbit-more/dist/microbitMore.mjs', 22 | collaborator: 'Yengawa Lab', 23 | iconURL: microbitMoreIconURL, 24 | insetIconURL: microbitMoreInsetIconURL, 25 | description: ( 26 | 31 | ), 32 | featured: true, 33 | disabled: false, 34 | bluetoothRequired: true, 35 | internetConnectionRequired: false, 36 | launchPeripheralConnectionFlow: true, 37 | useAutoScan: false, 38 | connectionIconURL: microbitMoreConnectionIconURL, 39 | connectionSmallIconURL: microbitMoreConnectionSmallIconURL, 40 | connectingMessage: ( 41 | 46 | ), 47 | helpLink: 'https://lab.yengawa.com/project/scratch-microbit-more/', 48 | translationMap: translationMap 49 | }; 50 | 51 | export {entry}; // loadable-extension needs this line. 52 | export default entry; 53 | -------------------------------------------------------------------------------- /src/entry/microbitMore-block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/src/entry/microbitMore-block.png -------------------------------------------------------------------------------- /src/entry/microbitMore-illustration.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/src/entry/microbitMore-illustration.afdesign -------------------------------------------------------------------------------- /src/entry/microbitMore-illustration.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/entry/microbitMore-small.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/src/entry/microbitMore-small.afdesign -------------------------------------------------------------------------------- /src/entry/microbitMore-small.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/entry/microbitMore.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/src/entry/microbitMore.afdesign -------------------------------------------------------------------------------- /src/entry/microbitMore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokobond/scratch-microbit-more/2e83c3196461823c80127174dff470bc8c57d27a/src/entry/microbitMore.png --------------------------------------------------------------------------------