Merge pull request #3401 from LLK/develop
Bring in develop to 9/25/19 release branch
|
@ -35,7 +35,7 @@ env:
|
|||
- CLOUDDATA_HOST=${CLOUDDATA_HOST:-$CLOUDDATA_HOST_STAGING}
|
||||
- RECAPTCHA_SITE_KEY_master=6LeRbUwUAAAAAFYhKgk3G9OKWqE_OJ7Z-7VTUCbl
|
||||
- RECAPTCHA_SITE_KEY_STAGING=6LfukK4UAAAAAFR44yoZMhv8fj6xh-PMiIxwryG3
|
||||
- RECAPTCHA_SITE=RECAPTCHA_SITE_KEY_$TRAVIS_BRANCH
|
||||
- RECAPTCHA_SITE_KEY_VAR=RECAPTCHA_SITE_KEY_$TRAVIS_BRANCH
|
||||
- RECAPTCHA_SITE_KEY=${!RECAPTCHA_SITE_KEY_VAR}
|
||||
- RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY:-$RECAPTCHA_SITE_KEY_STAGING}
|
||||
- ROOT_URL_master=https://scratch.mit.edu
|
||||
|
|
96
package-lock.json
generated
|
@ -5,9 +5,9 @@
|
|||
"requires": true,
|
||||
"dependencies": {
|
||||
"@babel/cli": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.6.0.tgz",
|
||||
"integrity": "sha512-1CTDyGUjQqW3Mz4gfKZ04KGOckyyaNmKneAMlABPS+ZyuxWv3FrVEVz7Ag08kNIztVx8VaJ8YgvYLSNlMKAT5Q==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.6.2.tgz",
|
||||
"integrity": "sha512-JDZ+T/br9pPfT2lmAMJypJDTTTHM9ePD/ED10TRjRzJVdEVy+JB3iRlhzYmTt5YkNgHvxWGlUVnLtdv6ruiDrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chokidar": "^2.1.8",
|
||||
|
@ -479,17 +479,17 @@
|
|||
}
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.0.tgz",
|
||||
"integrity": "sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.2.tgz",
|
||||
"integrity": "sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/generator": "^7.6.0",
|
||||
"@babel/helpers": "^7.6.0",
|
||||
"@babel/parser": "^7.6.0",
|
||||
"@babel/generator": "^7.6.2",
|
||||
"@babel/helpers": "^7.6.2",
|
||||
"@babel/parser": "^7.6.2",
|
||||
"@babel/template": "^7.6.0",
|
||||
"@babel/traverse": "^7.6.0",
|
||||
"@babel/traverse": "^7.6.2",
|
||||
"@babel/types": "^7.6.0",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"debug": "^4.1.0",
|
||||
|
@ -510,22 +510,21 @@
|
|||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz",
|
||||
"integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz",
|
||||
"integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.6.0",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0",
|
||||
"trim-right": "^1.0.1"
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz",
|
||||
"integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz",
|
||||
"integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/template": {
|
||||
|
@ -540,16 +539,16 @@
|
|||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz",
|
||||
"integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz",
|
||||
"integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/generator": "^7.6.0",
|
||||
"@babel/generator": "^7.6.2",
|
||||
"@babel/helper-function-name": "^7.1.0",
|
||||
"@babel/helper-split-export-declaration": "^7.4.4",
|
||||
"@babel/parser": "^7.6.0",
|
||||
"@babel/parser": "^7.6.2",
|
||||
"@babel/types": "^7.6.0",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
|
@ -686,33 +685,32 @@
|
|||
}
|
||||
},
|
||||
"@babel/helpers": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.0.tgz",
|
||||
"integrity": "sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz",
|
||||
"integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/template": "^7.6.0",
|
||||
"@babel/traverse": "^7.6.0",
|
||||
"@babel/traverse": "^7.6.2",
|
||||
"@babel/types": "^7.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/generator": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz",
|
||||
"integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz",
|
||||
"integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.6.0",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0",
|
||||
"trim-right": "^1.0.1"
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz",
|
||||
"integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz",
|
||||
"integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/template": {
|
||||
|
@ -727,16 +725,16 @@
|
|||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz",
|
||||
"integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz",
|
||||
"integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/generator": "^7.6.0",
|
||||
"@babel/generator": "^7.6.2",
|
||||
"@babel/helper-function-name": "^7.1.0",
|
||||
"@babel/helper-split-export-declaration": "^7.4.4",
|
||||
"@babel/parser": "^7.6.0",
|
||||
"@babel/parser": "^7.6.2",
|
||||
"@babel/types": "^7.6.0",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
|
@ -1018,9 +1016,9 @@
|
|||
}
|
||||
},
|
||||
"@types/babel__generator": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.0.2.tgz",
|
||||
"integrity": "sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz",
|
||||
"integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.0.0"
|
||||
|
@ -15561,15 +15559,15 @@
|
|||
}
|
||||
},
|
||||
"scratch-gui": {
|
||||
"version": "0.1.0-prerelease.20190918163722",
|
||||
"resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20190918163722.tgz",
|
||||
"integrity": "sha512-2BM65eEvknpgrlkZgYP31H4v4rUsYuacY2NBBLwZ+zBScIsYMrfuxr2zPtvtxOkjYf9yH6TJef8/i/YZmPtfhw==",
|
||||
"version": "0.1.0-prerelease.20190925145604",
|
||||
"resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20190925145604.tgz",
|
||||
"integrity": "sha512-NEL0AMDJaNNnl5mbN0YNL4rxxQW8nlsxAn9ZYUGScqoCLdHB30+0ipEWCnVLacIHCkbq1FcPXD237IOvnfT+8A==",
|
||||
"dev": true
|
||||
},
|
||||
"scratch-l10n": {
|
||||
"version": "3.5.20190917223712",
|
||||
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.5.20190917223712.tgz",
|
||||
"integrity": "sha512-kWkeUD5An4RwbAVZU7OUqS25D1rrdI73ZYhNn3tQhGu545JaITZf37AvVQW4DyZU+wFHQ1G30nWls7bXZLEPbA==",
|
||||
"version": "3.5.20190924223720",
|
||||
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.5.20190924223720.tgz",
|
||||
"integrity": "sha512-5bNisTEe9WJI+w3TQQ7XVutoFZuBKtHLLfijFd2vOkLv93XoxEQvpW62uz34uyj2tX9N8JPzCB+KaJalC+Z8Mg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/cli": "^7.1.2",
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
"redux-mock-store": "^1.2.3",
|
||||
"redux-thunk": "2.0.1",
|
||||
"sass-loader": "6.0.6",
|
||||
"scratch-gui": "0.1.0-prerelease.20190918163722",
|
||||
"scratch-gui": "0.1.0-prerelease.20190925145604",
|
||||
"scratch-l10n": "latest",
|
||||
"selenium-webdriver": "3.6.0",
|
||||
"slick-carousel": "1.6.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const bindAll = require('lodash.bindall');
|
||||
const React = require('react');
|
||||
|
||||
const OS_ENUM = require('./os-enum.js');
|
||||
const detectOS = require('../../lib/detect-os.js').default;
|
||||
|
||||
class ExtensionLanding extends React.Component {
|
||||
constructor (props) {
|
||||
|
@ -10,16 +10,8 @@ class ExtensionLanding extends React.Component {
|
|||
'onSetOS'
|
||||
]);
|
||||
|
||||
// @todo use bowser for browser detection
|
||||
let detectedOS = OS_ENUM.WINDOWS;
|
||||
if (window.navigator && window.navigator.platform) {
|
||||
if (window.navigator.platform === 'MacIntel') {
|
||||
detectedOS = OS_ENUM.MACOS;
|
||||
}
|
||||
}
|
||||
|
||||
this.state = {
|
||||
OS: detectedOS
|
||||
OS: detectOS()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ const React = require('react');
|
|||
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
|
||||
const {CHROME_APP_RELEASED} = require('../../lib/feature-flags.js');
|
||||
|
||||
require('./extension-landing.scss');
|
||||
|
||||
const ExtensionRequirements = props => (
|
||||
|
@ -12,13 +14,64 @@ const ExtensionRequirements = props => (
|
|||
<FormattedMessage id="extensionHeader.requirements" />
|
||||
</span>
|
||||
<FlexRow className="extension-requirements">
|
||||
{props.children}
|
||||
{props.bluetoothStandard ? (
|
||||
<React.Fragment>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/windows.svg"
|
||||
/>
|
||||
Windows 10 version 1709+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/mac.svg"
|
||||
/>
|
||||
macOS 10.13+
|
||||
</span>
|
||||
{CHROME_APP_RELEASED && (
|
||||
<React.Fragment>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="svgs/extensions/chromeos.svg"
|
||||
/>
|
||||
ChromeOS
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="svgs/extensions/android.svg"
|
||||
/>
|
||||
Android 5.0+
|
||||
</span>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<span>
|
||||
<img src="/svgs/extensions/bluetooth.svg" />
|
||||
Bluetooth
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/scratch-link.svg"
|
||||
/>
|
||||
Scratch Link
|
||||
</span>
|
||||
</React.Fragment>
|
||||
) : props.children}
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
);
|
||||
|
||||
ExtensionRequirements.propTypes = {
|
||||
bluetoothStandard: PropTypes.bool,
|
||||
children: PropTypes.node
|
||||
};
|
||||
|
||||
ExtensionRequirements.defaultProps = {
|
||||
bluetoothStandard: false
|
||||
};
|
||||
|
||||
module.exports = ExtensionRequirements;
|
||||
|
|
|
@ -2,13 +2,14 @@ const PropTypes = require('prop-types');
|
|||
const FormattedMessage = require('react-intl').FormattedMessage;
|
||||
const React = require('react');
|
||||
|
||||
const OS_ENUM = require('./os-enum.js');
|
||||
const OS_ENUM = require('../../lib/os-enum.js');
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
const Step = require('../../components/steps/step.jsx');
|
||||
|
||||
require('./extension-landing.scss');
|
||||
|
||||
// Assumes this will only be called with an OS that needs Scratch Link
|
||||
const InstallScratchLink = ({
|
||||
currentOS
|
||||
}) => (
|
||||
|
@ -37,20 +38,20 @@ const InstallScratchLink = ({
|
|||
<img
|
||||
alt=""
|
||||
className="store-badge"
|
||||
src={`/images/scratchlink/${
|
||||
src={`/images/badges/${
|
||||
currentOS === OS_ENUM.WINDOWS ? 'windows' : 'mac'
|
||||
}-store-badge.svg`}
|
||||
/>
|
||||
</a>
|
||||
<span className="horizontal-divider">
|
||||
<FormattedMessage id="installScratchLink.or" />
|
||||
<FormattedMessage id="installScratch.or" />
|
||||
</span>
|
||||
<a
|
||||
href={`https://downloads.scratch.mit.edu/link/${
|
||||
currentOS === OS_ENUM.WINDOWS ? 'windows' : 'mac'
|
||||
}.zip`}
|
||||
>
|
||||
<FormattedMessage id="installScratchLink.directDownload" />
|
||||
<FormattedMessage id="installScratch.directDownload" />
|
||||
</a>
|
||||
</div>
|
||||
</Step>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
width: 1rem;
|
||||
height: 1rem;
|
||||
margin-left: .375rem;
|
||||
margin-top: -.25rem;
|
||||
border-radius: 50%;
|
||||
background-color: $type-gray-60percent;
|
||||
background-image: url("/svgs/info-button/info-button.svg");
|
||||
|
|
146
src/components/install-scratch/install-scratch.jsx
Normal file
|
@ -0,0 +1,146 @@
|
|||
const PropTypes = require('prop-types');
|
||||
const FormattedMessage = require('react-intl').FormattedMessage;
|
||||
const React = require('react');
|
||||
|
||||
const OS_ENUM = require('../../lib/os-enum.js');
|
||||
const {CHROME_APP_RELEASED} = require('../../lib/feature-flags.js');
|
||||
|
||||
const {isDownloaded, isFromGooglePlay} = require('./install-util.js');
|
||||
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
const Step = require('../../components/steps/step.jsx');
|
||||
|
||||
require('./install-scratch.scss');
|
||||
|
||||
const InstallScratch = ({
|
||||
currentOS
|
||||
}) => (
|
||||
<div className="blue install-scratch">
|
||||
<FlexRow className="inner column">
|
||||
<h2 className="title">
|
||||
{CHROME_APP_RELEASED ? (
|
||||
<FormattedMessage
|
||||
id="installScratch.appHeaderTitle"
|
||||
values={{operatingsystem: currentOS}}
|
||||
/>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
{isDownloaded(currentOS) && (
|
||||
<FormattedMessage id="installScratch.desktopHeaderTitle" />
|
||||
)}
|
||||
{isFromGooglePlay(currentOS) && (
|
||||
<FormattedMessage
|
||||
id="installScratch.appHeaderTitle"
|
||||
values={{operatingsystem: currentOS}}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
</h2>
|
||||
<Steps>
|
||||
<div className="step">
|
||||
<Step
|
||||
compact
|
||||
number={1}
|
||||
>
|
||||
<span className="step-description">
|
||||
<React.Fragment>
|
||||
{isDownloaded(currentOS) && (
|
||||
<FormattedMessage
|
||||
id={CHROME_APP_RELEASED ? 'installScratch.downloadScratchAppGeneric' :
|
||||
'installScratch.downloadScratchDesktop'}
|
||||
values={{operatingsystem: currentOS}}
|
||||
/>
|
||||
)}
|
||||
{isFromGooglePlay(currentOS) && (
|
||||
<FormattedMessage id="installScratch.getScratchAppPlay" />
|
||||
)}
|
||||
</React.Fragment>
|
||||
</span>
|
||||
<div className="downloads-container">
|
||||
{currentOS === OS_ENUM.WINDOWS && (
|
||||
<a
|
||||
className="ms-badge"
|
||||
href="https://www.microsoft.com/store/apps/9pfgj25jl6x3?cid=storebadge&ocid=badge"
|
||||
>
|
||||
<img
|
||||
src="images/badges/windows-store-badge.svg"
|
||||
/>
|
||||
</a>
|
||||
)}
|
||||
{currentOS === OS_ENUM.MACOS && (
|
||||
<a
|
||||
className="macos-badge"
|
||||
href="https://apps.apple.com/us/app/scratch-desktop/id1446785996?mt=12"
|
||||
>
|
||||
<img
|
||||
src="images/badges/mac-store-badge.svg"
|
||||
/>
|
||||
</a>
|
||||
)}
|
||||
{isFromGooglePlay(currentOS) && (
|
||||
<a
|
||||
className="play-badge"
|
||||
href="https://play.google.com/store/apps/details?id=org.scratch"
|
||||
>
|
||||
<img
|
||||
src="images/badges/google-play-badge.png"
|
||||
/>
|
||||
</a>
|
||||
|
||||
)}
|
||||
{isDownloaded(currentOS) && (
|
||||
<React.Fragment>
|
||||
<span className="horizontal-divider">
|
||||
<FormattedMessage id="installScratch.or" />
|
||||
</span>
|
||||
<a
|
||||
href={
|
||||
currentOS === OS_ENUM.WINDOWS ?
|
||||
'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop%20Setup%203.6.0.exe' :
|
||||
'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop-3.6.0.dmg'
|
||||
}
|
||||
|
||||
>
|
||||
<FormattedMessage id="installScratch.directDownload" />
|
||||
</a>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
</Step>
|
||||
|
||||
</div>
|
||||
{isDownloaded(currentOS) && (
|
||||
<Step
|
||||
compact
|
||||
number={2}
|
||||
>
|
||||
<span className="step-description">
|
||||
{currentOS === OS_ENUM.WINDOWS ?
|
||||
<FormattedMessage id="download.winMoveToApplications" /> :
|
||||
<FormattedMessage id="download.macMoveToApplications" />
|
||||
}
|
||||
</span>
|
||||
|
||||
<div className="step-image">
|
||||
<img
|
||||
alt=""
|
||||
className="screenshot"
|
||||
src={`/images/download/${
|
||||
currentOS === OS_ENUM.WINDOWS ? 'windows' : 'mac'
|
||||
}-install.png`}
|
||||
/>
|
||||
</div>
|
||||
</Step>
|
||||
)}
|
||||
</Steps>
|
||||
</FlexRow>
|
||||
</div>
|
||||
);
|
||||
|
||||
InstallScratch.propTypes = {
|
||||
currentOS: PropTypes.string
|
||||
};
|
||||
|
||||
module.exports = InstallScratch;
|
95
src/components/install-scratch/install-scratch.scss
Normal file
|
@ -0,0 +1,95 @@
|
|||
@import "../../colors";
|
||||
@import "../../frameless";
|
||||
|
||||
#view {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.install-scratch {
|
||||
padding: 2rem 0;
|
||||
|
||||
.inner {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.downloads-container {
|
||||
text-align: center;
|
||||
|
||||
.horizontal-divider {
|
||||
display: block;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.horizontal-divider:before,
|
||||
.horizontal-divider:after {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
background-color: $ui-dark-gray;
|
||||
width: 50%;
|
||||
height: 1px;
|
||||
vertical-align: middle;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.horizontal-divider:before {
|
||||
right: .5em;
|
||||
margin-left: -50%;
|
||||
}
|
||||
|
||||
.horizontal-divider:after {
|
||||
left: .5em;
|
||||
margin-right: -50%;
|
||||
}
|
||||
}
|
||||
|
||||
.step-image {
|
||||
height: 14rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 2rem;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.legacy-link {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.download-button {
|
||||
display: inline-block;
|
||||
margin: .5em 0;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
background-color: $ui-blue;
|
||||
cursor: pointer;
|
||||
padding: 1rem 2rem;
|
||||
color: $ui-white;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.macos-badge img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.ms-badge img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.play-badge img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.download-image {
|
||||
width: 100%;
|
||||
max-width: $cols6;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.blue {
|
||||
background-color: $ui-blue-10percent;
|
||||
}
|
||||
}
|
13
src/components/install-scratch/install-util.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const OS_ENUM = require('../../lib/os-enum.js');
|
||||
|
||||
module.exports = {};
|
||||
|
||||
module.exports.isDownloaded = os => {
|
||||
if (os === OS_ENUM.WINDOWS || os === OS_ENUM.MACOS) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
module.exports.isFromGooglePlay = os => {
|
||||
if (os === OS_ENUM.ANDROID || os === OS_ENUM.CHROMEOS) return true;
|
||||
return false;
|
||||
};
|
|
@ -85,7 +85,8 @@ class BirthDateStep extends React.Component {
|
|||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
isSubmitting
|
||||
isSubmitting,
|
||||
setFieldError
|
||||
} = props;
|
||||
return (
|
||||
<JoinFlowStep
|
||||
|
@ -116,9 +117,13 @@ class BirthDateStep extends React.Component {
|
|||
options={birthMonthOptions}
|
||||
validate={this.validateSelect}
|
||||
validationClassName={classNames(
|
||||
'validation-birthdate',
|
||||
'validation-birthdate-month',
|
||||
'validation-left'
|
||||
)}
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
onFocus={() => setFieldError('birth_month', null)}
|
||||
/* eslint-enable react/jsx-no-bind */
|
||||
/>
|
||||
<FormikSelect
|
||||
className={classNames(
|
||||
|
@ -131,7 +136,13 @@ class BirthDateStep extends React.Component {
|
|||
name="birth_year"
|
||||
options={birthYearOptions}
|
||||
validate={this.validateSelect}
|
||||
validationClassName="validation-birthdate-year"
|
||||
validationClassName={classNames(
|
||||
'validation-birthdate',
|
||||
'validation-birthdate-year'
|
||||
)}
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
onFocus={() => setFieldError('birth_year', null)}
|
||||
/* eslint-enable react/jsx-no-bind */
|
||||
/>
|
||||
</div>
|
||||
<div className="join-flow-privacy-message">
|
||||
|
|
|
@ -30,7 +30,7 @@ class CountryStep extends React.Component {
|
|||
this.countryOptions = [...countryData.registrationCountryOptions];
|
||||
this.countryOptions.unshift({ // add placeholder as first option
|
||||
disabled: true,
|
||||
label: this.props.intl.formatMessage({id: 'general.country'}),
|
||||
label: this.props.intl.formatMessage({id: 'registration.selectCountry'}),
|
||||
value: 'null'
|
||||
});
|
||||
}
|
||||
|
@ -64,7 +64,8 @@ class CountryStep extends React.Component {
|
|||
const {
|
||||
errors,
|
||||
handleSubmit,
|
||||
isSubmitting
|
||||
isSubmitting,
|
||||
setFieldError
|
||||
} = props;
|
||||
return (
|
||||
<JoinFlowStep
|
||||
|
@ -92,7 +93,13 @@ class CountryStep extends React.Component {
|
|||
name="country"
|
||||
options={this.countryOptions}
|
||||
validate={this.validateSelect}
|
||||
validationClassName="validation-full-width-input"
|
||||
validationClassName={classNames(
|
||||
'validation-full-width-input',
|
||||
'validation-country'
|
||||
)}
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
onFocus={() => setFieldError('country', null)}
|
||||
/* eslint-enable react/jsx-no-bind */
|
||||
/>
|
||||
{/* note that this is a hidden checkbox the user will never see */}
|
||||
<FormikCheckbox
|
||||
|
|
|
@ -56,7 +56,11 @@ class EmailStep extends React.Component {
|
|||
this.emailInput = emailInputRef;
|
||||
}
|
||||
onCaptchaError () {
|
||||
// TODO send user to error step once we have one.
|
||||
this.props.onRegistrationError(
|
||||
this.props.intl.formatMessage({
|
||||
id: 'registation.troubleReload'
|
||||
})
|
||||
);
|
||||
}
|
||||
onCaptchaLoad () {
|
||||
this.setState({captchaIsLoading: false});
|
||||
|
@ -64,9 +68,9 @@ class EmailStep extends React.Component {
|
|||
if (!this.grecaptcha) {
|
||||
// According to the reCaptcha documentation, this callback shouldn't get
|
||||
// called unless window.grecaptcha exists. This is just here to be extra defensive.
|
||||
// TODO: Put up the error screen when we have one.
|
||||
this.onCaptchaError();
|
||||
return;
|
||||
}
|
||||
// TODO: Add in error callback for render once we have an error screen.
|
||||
this.widgetId = this.grecaptcha.render(this.captchaRef,
|
||||
{
|
||||
callback: this.captchaSolved,
|
||||
|
@ -208,6 +212,7 @@ class EmailStep extends React.Component {
|
|||
EmailStep.propTypes = {
|
||||
intl: intlShape,
|
||||
onNextStep: PropTypes.func,
|
||||
onRegistrationError: PropTypes.func,
|
||||
waiting: PropTypes.bool
|
||||
};
|
||||
|
||||
|
|
|
@ -66,8 +66,14 @@ class GenderStep extends React.Component {
|
|||
}
|
||||
handleValidSubmit (formData, formikBag) {
|
||||
formikBag.setSubmitting(false);
|
||||
if (!formData.gender || formData.gender === 'null') {
|
||||
formData.gender = 'Prefer not to say';
|
||||
// handle defaults:
|
||||
// when gender is specifically made blank, use "(blank)"
|
||||
if (!formData.gender || formData.gender === '') {
|
||||
formData.gender = '(blank)';
|
||||
}
|
||||
// when user clicks Next without making any selection, use "(skipped)"
|
||||
if (formData.gender === 'null') {
|
||||
formData.gender = '(skipped)';
|
||||
}
|
||||
delete formData.custom;
|
||||
this.props.onNextStep(formData);
|
||||
|
@ -102,20 +108,20 @@ class GenderStep extends React.Component {
|
|||
id="GenderRadioOptionFemale"
|
||||
label={this.props.intl.formatMessage({id: 'general.female'})}
|
||||
selectedValue={values.gender}
|
||||
value="Female"
|
||||
value="female"
|
||||
onSetFieldValue={setFieldValue}
|
||||
/>
|
||||
<GenderOption
|
||||
id="GenderRadioOptionMale"
|
||||
label={this.props.intl.formatMessage({id: 'general.male'})}
|
||||
selectedValue={values.gender}
|
||||
value="Male"
|
||||
value="male"
|
||||
onSetFieldValue={setFieldValue}
|
||||
/>
|
||||
<GenderOption
|
||||
label={this.props.intl.formatMessage({id: 'general.nonBinary'})}
|
||||
selectedValue={values.gender}
|
||||
value="Non-binary"
|
||||
value="non-binary"
|
||||
onSetFieldValue={setFieldValue}
|
||||
/>
|
||||
<div
|
||||
|
@ -155,7 +161,7 @@ class GenderStep extends React.Component {
|
|||
id="GenderRadioOptionPreferNot"
|
||||
label={this.props.intl.formatMessage({id: 'registration.genderOptionPreferNotToSay'})}
|
||||
selectedValue={values.gender}
|
||||
value="Prefer not to say"
|
||||
value="(Prefer not to say)"
|
||||
onSetFieldValue={setFieldValue}
|
||||
/>
|
||||
<div className="join-flow-privacy-message join-flow-gender-privacy">
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
.join-flow-description {
|
||||
font-size: .875rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.37500rem;
|
||||
line-height: 1.125rem;
|
||||
margin-top: 0.78125rem;
|
||||
margin-bottom: 1.875rem;
|
||||
text-align: center;
|
||||
|
|
|
@ -39,28 +39,40 @@
|
|||
}
|
||||
|
||||
.validation-full-width-input {
|
||||
transform: translate(21.5625rem, 0);
|
||||
transform: translate(21.8125rem, 0);
|
||||
}
|
||||
|
||||
.validation-birthdate-month {
|
||||
transform: translate(-9.25rem, 0);
|
||||
width: 7.25rem;
|
||||
transform: translate(-9.875rem, 0);
|
||||
}
|
||||
|
||||
.validation-birthdate-year {
|
||||
transform: translate(8.75rem, 0);
|
||||
width: 7.25rem;
|
||||
transform: translate(9.375rem, 0);
|
||||
}
|
||||
|
||||
@media #{$intermediate-and-smaller} {
|
||||
.validation-full-width-input {
|
||||
transform: unset;
|
||||
margin-bottom: .75rem;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.validation-birthdate-input {
|
||||
.validation-country {
|
||||
top: .5rem;
|
||||
}
|
||||
|
||||
.validation-birthdate {
|
||||
transform: unset;
|
||||
width: 8rem;
|
||||
top: .5rem;
|
||||
width: 19rem;
|
||||
}
|
||||
|
||||
.validation-birthdate-month {
|
||||
margin-right: -9.25rem;
|
||||
}
|
||||
|
||||
.validation-birthdate-year {
|
||||
margin-left: -9.625rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,8 +126,6 @@
|
|||
}
|
||||
|
||||
.join-flow-inner-gender-step {
|
||||
/* need height so that flex will adjust children proportionately */
|
||||
height: 27.25rem;
|
||||
padding-top: 2.625rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
@ -177,7 +187,7 @@
|
|||
.gender-radio-row {
|
||||
transition: all .125s ease;
|
||||
width: 20.875rem;
|
||||
height: 2.85rem;
|
||||
min-height: 2.85rem;
|
||||
background-color: $ui-gray;
|
||||
border-radius: .5rem;
|
||||
margin: 0 auto 0.375rem;
|
||||
|
|
|
@ -23,6 +23,7 @@ class JoinFlow extends React.Component {
|
|||
super(props);
|
||||
bindAll(this, [
|
||||
'handleAdvanceStep',
|
||||
'handleRegistrationError',
|
||||
'handlePrepareToRegister',
|
||||
'handleRegistrationResponse',
|
||||
'handleSubmitRegistration'
|
||||
|
@ -34,6 +35,14 @@ class JoinFlow extends React.Component {
|
|||
waiting: false
|
||||
};
|
||||
}
|
||||
handleRegistrationError (message) {
|
||||
if (!message) {
|
||||
message = this.props.intl.formatMessage({
|
||||
id: 'registration.generalError'
|
||||
});
|
||||
}
|
||||
this.setState({registrationError: message});
|
||||
}
|
||||
handlePrepareToRegister (newFormData) {
|
||||
newFormData = newFormData || {};
|
||||
const newState = {
|
||||
|
@ -143,8 +152,10 @@ class JoinFlow extends React.Component {
|
|||
<EmailStep
|
||||
waiting={this.state.waiting}
|
||||
onNextStep={this.handlePrepareToRegister}
|
||||
onRegistrationError={this.handleRegistrationError}
|
||||
/>
|
||||
<WelcomeStep
|
||||
createProjectOnComplete={this.props.createProjectOnComplete}
|
||||
email={this.state.formData.email}
|
||||
username={this.state.formData.username}
|
||||
onNextStep={this.props.onCompleteRegistration}
|
||||
|
@ -157,6 +168,7 @@ class JoinFlow extends React.Component {
|
|||
}
|
||||
|
||||
JoinFlow.propTypes = {
|
||||
createProjectOnComplete: PropTypes.bool,
|
||||
intl: intlShape,
|
||||
onCompleteRegistration: PropTypes.func,
|
||||
refreshSession: PropTypes.func
|
||||
|
|
|
@ -45,7 +45,7 @@ class WelcomeStep extends React.Component {
|
|||
descriptionClassName="join-flow-welcome-description"
|
||||
headerImgSrc="/images/join-flow/welcome-header.png"
|
||||
innerClassName="join-flow-inner-welcome-step"
|
||||
nextButton={
|
||||
nextButton={this.props.createProjectOnComplete ? (
|
||||
<React.Fragment>
|
||||
<FormattedMessage id="registration.makeProject" />
|
||||
<img
|
||||
|
@ -53,7 +53,9 @@ class WelcomeStep extends React.Component {
|
|||
src="/svgs/project/r-arrow.svg"
|
||||
/>
|
||||
</React.Fragment>
|
||||
}
|
||||
) : (
|
||||
<FormattedMessage id="general.done" />
|
||||
)}
|
||||
title={`${this.props.intl.formatMessage(
|
||||
{id: 'registration.welcomeStepTitleNonEducator'},
|
||||
{username: this.props.username}
|
||||
|
@ -79,6 +81,7 @@ class WelcomeStep extends React.Component {
|
|||
}
|
||||
|
||||
WelcomeStep.propTypes = {
|
||||
createProjectOnComplete: PropTypes.bool,
|
||||
email: PropTypes.string,
|
||||
intl: intlShape,
|
||||
onNextStep: PropTypes.func,
|
||||
|
|
|
@ -49,6 +49,8 @@ class Modal extends React.Component {
|
|||
}}
|
||||
{...omit(this.props, ['className', 'overlayClassName'])}
|
||||
>
|
||||
|
||||
{this.props.showCloseButton && (
|
||||
<div
|
||||
className="modal-content-close"
|
||||
onClick={this.handleRequestClose}
|
||||
|
@ -56,9 +58,11 @@ class Modal extends React.Component {
|
|||
<img
|
||||
alt="close-icon"
|
||||
className="modal-content-close-img"
|
||||
draggable="false"
|
||||
src="/svgs/modal/close-x.svg"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{this.props.children}
|
||||
</ReactModal>
|
||||
);
|
||||
|
@ -69,7 +73,11 @@ Modal.propTypes = {
|
|||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
overlayClassName: PropTypes.string,
|
||||
showCloseButton: PropTypes.bool,
|
||||
useStandardSizes: PropTypes.bool
|
||||
};
|
||||
|
||||
Modal.defaultProps = {
|
||||
showCloseButton: true
|
||||
};
|
||||
module.exports = Modal;
|
||||
|
|
|
@ -6,26 +6,32 @@ const JoinFlow = require('../../join-flow/join-flow.jsx');
|
|||
require('./modal.scss');
|
||||
|
||||
const JoinModal = ({
|
||||
onCompleteRegistration, // eslint-disable-line no-unused-vars
|
||||
createProjectOnComplete,
|
||||
onCompleteRegistration,
|
||||
onRequestClose,
|
||||
...modalProps
|
||||
}) => (
|
||||
<Modal
|
||||
isOpen
|
||||
showCloseButton
|
||||
useStandardSizes
|
||||
className="mod-join"
|
||||
shouldCloseOnOverlayClick={false}
|
||||
onRequestClose={onRequestClose}
|
||||
{...modalProps}
|
||||
>
|
||||
<JoinFlow
|
||||
createProjectOnComplete={createProjectOnComplete}
|
||||
onCompleteRegistration={onCompleteRegistration}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
JoinModal.propTypes = {
|
||||
createProjectOnComplete: PropTypes.bool,
|
||||
onCompleteRegistration: PropTypes.func,
|
||||
onRequestClose: PropTypes.func
|
||||
onRequestClose: PropTypes.func,
|
||||
showCloseButton: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = JoinModal;
|
||||
|
|
|
@ -4,11 +4,12 @@ const FormattedMessage = require('react-intl').FormattedMessage;
|
|||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
|
||||
const {CHROME_APP_RELEASED} = require('../../lib/feature-flags.js');
|
||||
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const Button = require('../../components/forms/button.jsx');
|
||||
|
||||
const OS_ENUM = require('../../components/extension-landing/os-enum.js');
|
||||
const OS_ENUM = require('../../lib/os-enum.js');
|
||||
|
||||
require('./os-chooser.scss');
|
||||
|
||||
|
@ -34,6 +35,28 @@ const OSChooser = props => (
|
|||
<img src="/svgs/extensions/mac.svg" />
|
||||
macOS
|
||||
</Button>
|
||||
{CHROME_APP_RELEASED && (
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className={classNames({active: props.currentOS === OS_ENUM.CHROMEOS})}
|
||||
onClick={() => // eslint-disable-line react/jsx-no-bind
|
||||
props.handleSetOS(OS_ENUM.CHROMEOS)
|
||||
}
|
||||
>
|
||||
<img src="/svgs/extensions/chromeos.svg" />
|
||||
ChromeOS
|
||||
</Button>
|
||||
<Button
|
||||
className={classNames({active: props.currentOS === OS_ENUM.ANDROID})}
|
||||
onClick={() => // eslint-disable-line react/jsx-no-bind
|
||||
props.handleSetOS(OS_ENUM.ANDROID)
|
||||
}
|
||||
>
|
||||
<img src="/svgs/extensions/android.svg" />
|
||||
Android
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</FlexRow>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -8,14 +8,18 @@ const JoinModal = require('../modal/join/modal.jsx');
|
|||
require('./registration.scss');
|
||||
|
||||
const Registration = ({
|
||||
createProjectOnComplete,
|
||||
handleCloseRegistration,
|
||||
handleCompleteRegistration,
|
||||
isOpen
|
||||
isOpen,
|
||||
showCloseButton
|
||||
}) => (
|
||||
<div>
|
||||
<JoinModal
|
||||
createProjectOnComplete={createProjectOnComplete}
|
||||
isOpen={isOpen}
|
||||
key="join-modal"
|
||||
showCloseButton={showCloseButton}
|
||||
onCompleteRegistration={handleCompleteRegistration}
|
||||
onRequestClose={handleCloseRegistration}
|
||||
/>
|
||||
|
@ -23,11 +27,11 @@ const Registration = ({
|
|||
);
|
||||
|
||||
Registration.propTypes = {
|
||||
// used in mapDispatchToProps; eslint doesn't understand that this prop is used
|
||||
createProjectOnComplete: PropTypes.bool, // eslint-disable-line react/no-unused-prop-types
|
||||
createProjectOnComplete: PropTypes.bool,
|
||||
handleCloseRegistration: PropTypes.func,
|
||||
handleCompleteRegistration: PropTypes.func,
|
||||
isOpen: PropTypes.bool
|
||||
isOpen: PropTypes.bool,
|
||||
showCloseButton: PropTypes.bool
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"general.confirmEmail": "Confirm Email",
|
||||
"general.contactUs": "Contact Us",
|
||||
"general.contact": "Contact",
|
||||
"general.done": "Done",
|
||||
"general.downloadPDF": "Download PDF",
|
||||
"general.emailUs": "Email Us",
|
||||
"general.conferences": "Conferences",
|
||||
|
@ -133,10 +134,17 @@
|
|||
|
||||
"oschooser.choose": "Choose your OS:",
|
||||
|
||||
"installScratch.or": "or",
|
||||
"installScratch.directDownload": "Direct download",
|
||||
"installScratch.desktopHeaderTitle": "Install Scratch Desktop",
|
||||
"installScratch.appHeaderTitle": "Install Scratch for {operatingsystem}",
|
||||
"installScratch.downloadScratchDesktop": "Download Scratch Desktop",
|
||||
"installScratch.downloadScratchAppGeneric": "Download Scratch for {operatingsystem}",
|
||||
"installScratch.getScratchAppPlay": "Get Scratch on the Google Play Store",
|
||||
"installScratch.useScratchApp": "Open the Scratch app on your device.",
|
||||
|
||||
"installScratchLink.installHeaderTitle": "Install Scratch Link",
|
||||
"installScratchLink.downloadAndInstall": "Download and install Scratch Link.",
|
||||
"installScratchLink.or": "or",
|
||||
"installScratchLink.directDownload": "Direct download",
|
||||
"installScratchLink.startScratchLink": "Start Scratch Link and make sure it is running. It should appear in your toolbar.",
|
||||
|
||||
"parents.FaqAgeRangeA": "While Scratch is primarily designed for 8 to 16 year olds, it is also used by people of all ages, including younger children with their parents.",
|
||||
|
@ -184,9 +192,10 @@
|
|||
"registration.personalStepDescription": "Your individual responses will not be displayed publicly, and will be kept confidential and secure",
|
||||
"registration.private": "We will keep this information private.",
|
||||
"registration.receiveEmails": "I'd like to receive emails from the Scratch Team about project ideas, events, and more.",
|
||||
"registration.selectCountry": "select country",
|
||||
"registration.selectCountry": "Select country",
|
||||
"registration.studentPersonalStepDescription": "This information will not appear on the Scratch website.",
|
||||
"registration.showPassword": "Show password",
|
||||
"registration.troubleReload": "Scratch is having trouble finishing registration. Try reloading the page or try again in another browser.",
|
||||
"registration.usernameStepDescription": "Fill in the following forms to request an account. The approval process may take up to one day.",
|
||||
"registration.usernameStepDescriptionNonEducator": "Create projects, share ideas, make friends. It’s free!",
|
||||
"registration.usernameStepRealName": "Please do not use any portion of your real name in your username.",
|
||||
|
|
18
src/lib/detect-os.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import bowser from 'bowser';
|
||||
import OS_ENUM from './os-enum.js';
|
||||
import {CHROME_APP_RELEASED} from './feature-flags.js';
|
||||
|
||||
/**
|
||||
* Helper function to the current Operating System.
|
||||
* @returns {OS_ENUM} Returns the OS value, defaults to WINDOWS
|
||||
*/
|
||||
export default function () {
|
||||
// matching OS strings from https://github.com/lancedikson/bowser/blob/master/src/constants.js
|
||||
if (bowser.osname === 'macOS') return OS_ENUM.MACOS;
|
||||
if (CHROME_APP_RELEASED) {
|
||||
if (bowser.osname === 'Chrome OS') return OS_ENUM.CHROMEOS;
|
||||
if (bowser.osname === 'Android') return OS_ENUM.ANDROID;
|
||||
}
|
||||
// if (bowser.osname === 'iOS') return OS_ENUM.IOS; // @todo
|
||||
return OS_ENUM.WINDOWS;
|
||||
}
|
10
src/lib/feature-flags.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const isStaging = () => process.env.SCRATCH_ENV === 'staging';
|
||||
|
||||
const flagInUrl = flag => {
|
||||
const url = (window.location && window.location.search) || '';
|
||||
return url.indexOf(`${flag}=true`) !== -1;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
CHROME_APP_RELEASED: isStaging() && flagInUrl('CHROME_APP_RELEASED')
|
||||
};
|
|
@ -1,6 +1,8 @@
|
|||
const OS_ENUM = {
|
||||
WINDOWS: 'Windows',
|
||||
MACOS: 'macOS'
|
||||
MACOS: 'macOS',
|
||||
CHROMEOS: 'ChromeOS',
|
||||
ANDROID: 'Android'
|
||||
};
|
||||
|
||||
module.exports = OS_ENUM;
|
|
@ -9,12 +9,14 @@ const render = require('../../lib/render.jsx');
|
|||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
|
||||
const OSChooser = require('../../components/os-chooser/os-chooser.jsx');
|
||||
const {isDownloaded, isFromGooglePlay} = require('../../components/install-scratch/install-util.js');
|
||||
|
||||
const ExtensionLanding = require('../../components/extension-landing/extension-landing.jsx');
|
||||
const ExtensionHeader = require('../../components/extension-landing/extension-header.jsx');
|
||||
const ExtensionRequirements = require('../../components/extension-landing/extension-requirements.jsx');
|
||||
const ExtensionSection = require('../../components/extension-landing/extension-section.jsx');
|
||||
const InstallScratchLink = require('../../components/extension-landing/install-scratch-link.jsx');
|
||||
const InstallScratch = require('../../components/install-scratch/install-scratch.jsx');
|
||||
const ProjectCard = require('../../components/extension-landing/project-card.jsx');
|
||||
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
|
@ -56,45 +58,23 @@ class Boost extends ExtensionLanding {
|
|||
src="/images/boost/boost-header.svg"
|
||||
/>}
|
||||
renderRequirements={
|
||||
<ExtensionRequirements>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/windows.svg"
|
||||
/>
|
||||
Windows 10 version 1709+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/mac.svg"
|
||||
/>
|
||||
macOS 10.13+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/bluetooth.svg"
|
||||
/>
|
||||
Bluetooth 4.0
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/scratch-link.svg"
|
||||
/>
|
||||
Scratch Link
|
||||
</span>
|
||||
</ExtensionRequirements>
|
||||
<ExtensionRequirements bluetoothStandard />
|
||||
}
|
||||
/>
|
||||
<OSChooser
|
||||
currentOS={this.state.OS}
|
||||
handleSetOS={this.onSetOS}
|
||||
/>
|
||||
{(isDownloaded(this.state.OS)) && (
|
||||
<InstallScratchLink
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
{(isFromGooglePlay(this.state.OS)) && (
|
||||
<InstallScratch
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
<ExtensionSection className="getting-started">
|
||||
<h2><FormattedMessage id="boost.gettingStarted" /></h2>
|
||||
<FlexRow className="column getting-started-section">
|
||||
|
@ -109,6 +89,7 @@ class Boost extends ExtensionLanding {
|
|||
/>
|
||||
</div>
|
||||
<p>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<FormattedMessage
|
||||
id="boost.useScratch3"
|
||||
values={{
|
||||
|
@ -123,6 +104,10 @@ class Boost extends ExtensionLanding {
|
|||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isFromGooglePlay(this.state.OS) && (
|
||||
<FormattedMessage id="installScratch.useScratchApp" />
|
||||
)}
|
||||
</p>
|
||||
</Step>
|
||||
<Step number={2}>
|
||||
|
@ -208,9 +193,11 @@ class Boost extends ExtensionLanding {
|
|||
</ExtensionSection>
|
||||
<ExtensionSection className="faq">
|
||||
<h2><FormattedMessage id="boost.troubleshootingTitle" /></h2>
|
||||
<h3 className="faq-title"><FormattedMessage id="boost.avoidFirmwareUpdateTitle" /></h3>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-title"><FormattedMessage id="boost.updateScratchLinkTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage id="boost.avoidFirmwareUpdateText" />
|
||||
<FormattedMessage id="boost.updateScratchLinkText" />
|
||||
</p>
|
||||
<h3 className="faq-title"><FormattedMessage id="boost.checkOSVersionTitle" /></h3>
|
||||
<p>
|
||||
|
@ -238,6 +225,8 @@ class Boost extends ExtensionLanding {
|
|||
}}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<h3 className="faq-title"><FormattedMessage id="boost.closeScratchCopiesTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage id="boost.closeScratchCopiesText" />
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"boost.connectALegoBeam": "Connect a LEGO beam with an axle to motor A and click the block again to make it spin.",
|
||||
"boost.starterProjects": "Starter Projects",
|
||||
"boost.troubleshootingTitle": "Troubleshooting",
|
||||
"boost.avoidFirmwareUpdateTitle": "Having trouble connecting or using motor blocks?",
|
||||
"boost.avoidFirmwareUpdateText": "We suggest you avoid updating the firmware on your BOOST for now. We are working on a fix with the team at LEGO for users who have already updated their firmware. Stay tuned! We hope to have a fix released soon.",
|
||||
"boost.updateScratchLinkTitle": "Make sure you have the latest version of Scratch Link",
|
||||
"boost.updateScratchLinkText": "Install Scratch Link using the button above. We recommend using the app store installation process to help keep your version up to date.",
|
||||
"boost.checkOSVersionTitle": "Make sure your operating system is compatible with Scratch Link",
|
||||
"boost.checkOSVersionText": "The minimum operating system versions are listed at the top of this page. See instructions for checking your version of {winOSVersionLink} or {macOSVersionLink}.",
|
||||
"boost.winOSVersionLinkText": "Windows",
|
||||
|
|
|
@ -5,13 +5,14 @@ const React = require('react');
|
|||
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const bindAll = require('lodash.bindall');
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
const Step = require('../../components/steps/step.jsx');
|
||||
|
||||
const Page = require('../../components/page/www/page.jsx');
|
||||
const render = require('../../lib/render.jsx');
|
||||
const OS_ENUM = require('../../components/extension-landing/os-enum.js');
|
||||
const detectOS = require('../../lib/detect-os.js').default;
|
||||
const {CHROME_APP_RELEASED} = require('../../lib/feature-flags.js');
|
||||
const OSChooser = require('../../components/os-chooser/os-chooser.jsx');
|
||||
const InstallScratch = require('../../components/install-scratch/install-scratch.jsx');
|
||||
const {isDownloaded, isFromGooglePlay} = require('../../components/install-scratch/install-util.js');
|
||||
|
||||
require('./download.scss');
|
||||
require('../../components/forms/button.scss');
|
||||
|
@ -22,15 +23,9 @@ class Download extends React.Component {
|
|||
bindAll(this, [
|
||||
'onSetOS'
|
||||
]);
|
||||
let detectedOS = OS_ENUM.WINDOWS;
|
||||
if (window.navigator && window.navigator.platform) {
|
||||
if (window.navigator.platform === 'MacIntel') {
|
||||
detectedOS = OS_ENUM.MACOS;
|
||||
}
|
||||
}
|
||||
|
||||
this.state = {
|
||||
OS: detectedOS
|
||||
OS: detectOS()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -55,10 +50,16 @@ class Download extends React.Component {
|
|||
src="/images/download/icon.png"
|
||||
width="40"
|
||||
/>
|
||||
<FormattedMessage id="download.title" />
|
||||
<FormattedMessage
|
||||
id={CHROME_APP_RELEASED ? 'download.appTitle' :
|
||||
'download.title'}
|
||||
/>
|
||||
</h1>
|
||||
<span className="download-description">
|
||||
<FormattedMessage id="download.intro" />
|
||||
<FormattedMessage
|
||||
id={CHROME_APP_RELEASED ? 'download.appIntro' :
|
||||
'download.intro'}
|
||||
/>
|
||||
</span>
|
||||
</FlexRow>
|
||||
<FlexRow className="column download-requirements-container">
|
||||
|
@ -80,6 +81,24 @@ class Download extends React.Component {
|
|||
/>
|
||||
macOS 10.13+
|
||||
</span>
|
||||
{CHROME_APP_RELEASED && (
|
||||
<React.Fragment>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="svgs/extensions/chromeos.svg"
|
||||
/>
|
||||
ChromeOS
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="svgs/extensions/android.svg"
|
||||
/>
|
||||
Android 5.0+
|
||||
</span>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
|
@ -95,98 +114,9 @@ class Download extends React.Component {
|
|||
currentOS={this.state.OS}
|
||||
handleSetOS={this.onSetOS}
|
||||
/>
|
||||
<div className="blue install-scratch">
|
||||
<FlexRow className="inner column">
|
||||
<h2 className="title">
|
||||
<FormattedMessage id="download.installHeaderTitle" />
|
||||
</h2>
|
||||
<Steps>
|
||||
<div className="step">
|
||||
<Step
|
||||
compact
|
||||
number={1}
|
||||
>
|
||||
<span className="step-description">
|
||||
<FormattedMessage id="download.downloadScratchDesktop" />
|
||||
</span>
|
||||
<div className="downloads-container">
|
||||
<a
|
||||
className="download-button"
|
||||
href={
|
||||
this.state.OS === OS_ENUM.WINDOWS ?
|
||||
'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop%20Setup%203.6.0.exe' :
|
||||
'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop-3.6.0.dmg'
|
||||
}
|
||||
>
|
||||
<FormattedMessage id="download.downloadButton" />
|
||||
</a>
|
||||
</div>
|
||||
</Step>
|
||||
|
||||
</div>
|
||||
<Step
|
||||
compact
|
||||
number={2}
|
||||
>
|
||||
<span className="step-description">
|
||||
{this.state.OS === OS_ENUM.WINDOWS ?
|
||||
<FormattedMessage id="download.winMoveToApplications" /> :
|
||||
<FormattedMessage id="download.macMoveToApplications" />
|
||||
}
|
||||
</span>
|
||||
|
||||
<div className="step-image">
|
||||
<img
|
||||
alt=""
|
||||
className="screenshot"
|
||||
src={`/images/download/${
|
||||
this.state.OS === OS_ENUM.WINDOWS ? 'windows' : 'mac'
|
||||
}-install.png`}
|
||||
/>
|
||||
</div>
|
||||
</Step>
|
||||
</Steps>
|
||||
</FlexRow>
|
||||
</div>
|
||||
<div className="download-section faq">
|
||||
<FlexRow className="inner column">
|
||||
<h2 className="title">
|
||||
<FormattedMessage id="download.troubleshootingTitle" />
|
||||
</h2>
|
||||
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.canIUseScratchLink" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.canIUseScratchLinkAnswer" />
|
||||
</p>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.desktopAndBrowser" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.yesAnswer" />
|
||||
</p>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.canIShare" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.canIShareAnswer" />
|
||||
</p>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.supportChromeOS" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.supportChromeOSAnswer" />
|
||||
</p>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.whenSupportLinux" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.supportLinuxAnswer" />
|
||||
</p>
|
||||
</FlexRow>
|
||||
</div>
|
||||
<div className="download-section blue">
|
||||
<InstallScratch currentOS={this.state.OS} />
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<div className="download-section">
|
||||
<FlexRow className="inner column">
|
||||
<h2 className="title">
|
||||
<FormattedMessage id="download.olderVersionsTitle" />
|
||||
|
@ -244,6 +174,99 @@ class Download extends React.Component {
|
|||
</FlexRow>
|
||||
</FlexRow>
|
||||
</div>
|
||||
)}
|
||||
<div className="download-section faq">
|
||||
<FlexRow className="inner column">
|
||||
<h2 className="title">
|
||||
<FormattedMessage id="download.troubleshootingTitle" />
|
||||
</h2>
|
||||
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.canIUseScratchLink" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.canIUseScratchLinkAnswer" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{isFromGooglePlay(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.canIUseExtensions" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.canIUseExtensionsAnswer" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<h3 className="faq-question">
|
||||
{isFromGooglePlay(this.state.OS) ?
|
||||
<FormattedMessage id="download.appAndBrowser" /> :
|
||||
<FormattedMessage id="download.desktopAndBrowser" />
|
||||
}
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.yesAnswer" />
|
||||
</p>
|
||||
{isDownloaded(this.state.OS) && (CHROME_APP_RELEASED ? (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage
|
||||
id="download.canIShareApp"
|
||||
values={{operatingsystem: this.state.OS}}
|
||||
/>
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="download.canIShareAnswerDownloaded"
|
||||
values={{operatingsystem: this.state.OS}}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.canIShare" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.canIShareAnswer" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
))}
|
||||
{isFromGooglePlay(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage
|
||||
id="download.canIShareApp"
|
||||
values={{operatingsystem: this.state.OS}}
|
||||
/>
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.canIShareAnswerPlayStore" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{!CHROME_APP_RELEASED && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.supportChromeOS" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.supportChromeOSAnswer" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<h3 className="faq-question">
|
||||
<FormattedMessage id="download.whenSupportLinux" />
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage id="download.supportLinuxAnswer" />
|
||||
</p>
|
||||
</FlexRow>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -27,6 +27,18 @@
|
|||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.macos-badge img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.ms-badge img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.play-badge img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.download-header {
|
||||
background-color: $ui-blue;
|
||||
padding: 4rem 0;
|
||||
|
@ -80,6 +92,7 @@
|
|||
|
||||
.download-requirements {
|
||||
justify-content: space-between;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.download-requirements span {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
{
|
||||
"download.title": "Scratch Desktop",
|
||||
"download.intro": "You can install the Scratch Desktop editor to work on projects without an internet connection. This version will work on Windows and MacOS.",
|
||||
"download.appTitle": "Download Scratch",
|
||||
"download.appIntro": "You can install Scratch for free to work on projects without an internet connection.",
|
||||
"download.requirements": "Requirements",
|
||||
"download.imgAltDownloadIllustration" : "Scratch 3.0 Desktop screenshot",
|
||||
"download.installHeaderTitle": "Install Scratch Desktop",
|
||||
"download.downloadScratchDesktop": "Download Scratch Desktop",
|
||||
"download.downloadButton": "Download",
|
||||
"download.troubleshootingTitle": "FAQ",
|
||||
"download.startScratchDesktop": "Start Scratch Desktop",
|
||||
"download.howDoIInstall": "How do I install Scratch Desktop?",
|
||||
|
@ -14,17 +13,23 @@
|
|||
"download.supportChromeOS" : "When will you have Scratch Desktop for Chromebooks?",
|
||||
"download.supportChromeOSAnswer": "Scratch Desktop for Chromebooks is not yet available. We are working on it and expect to release later in 2019.",
|
||||
"download.olderVersionsTitle" : "Older Versions",
|
||||
"download.olderVersions": "Looking for the Scratch 2.0 Offline Editor or Scratch 1.4?",
|
||||
"download.scratch1-4Desktop" : "Scratch 1.4 Desktop",
|
||||
"download.scratch2Desktop" : "Scratch 2.0 Desktop",
|
||||
"download.olderVersions": "Looking for earlier Scratch Offline Editors?",
|
||||
"download.scratch1-4Desktop" : "Scratch 1.4",
|
||||
"download.scratch2Desktop" : "Scratch 2.0 Offline Editor",
|
||||
"download.cannotAccessMacStore" : "What if I can't access the Mac App Store?",
|
||||
"download.cannotAccessWindowsStore" : "What if I can't access the Microsoft Store?",
|
||||
"download.macMoveToApplications" : "Open the .dmg file. Move Scratch Desktop into Applications.",
|
||||
"download.winMoveToApplications" : "Run the .exe file.",
|
||||
"download.canIUseScratchLink" : "Can I use Scratch Link to connect to extensions?",
|
||||
"download.canIUseScratchLinkAnswer" : "Yes. However, you will need an Internet connection to use Scratch Link.",
|
||||
"download.canIUseExtensions" : "Can I connect to hardware extensions?",
|
||||
"download.canIUseExtensionsAnswer" : "Yes. With the Scratch app you can connect to extensions, and you do not need Scratch Link.",
|
||||
"download.desktopAndBrowser": "Can I use Scratch Desktop and also have Scratch open in the browser?",
|
||||
"download.appAndBrowser": "Can I use the Scratch app and also have Scratch open in the browser?",
|
||||
"download.yesAnswer" : "Yes.",
|
||||
"download.canIShare": "Can I share from Scratch Desktop?",
|
||||
"download.canIShareAnswer": "This isn’t supported currently. For now, you can save a project from Scratch Desktop, upload it to your Scratch account, and share it there. In a later version we will add the ability to upload to your Scratch account directly in Scratch Desktop."
|
||||
"download.canIShareAnswer": "This isn’t supported currently. For now, you can save a project from Scratch Desktop, upload it to your Scratch account, and share it there. In a later version we will add the ability to upload to your Scratch account directly in Scratch Desktop.",
|
||||
"download.canIShareApp": "Can I share from Scratch for {operatingsystem}?",
|
||||
"download.canIShareAnswerPlayStore": "Yes. Click the 3-dots menu on a project in the lobby and select Share from the options. In addition to sharing by email you can sign in to your Scratch account and share the project on the Scratch Community.",
|
||||
"download.canIShareAnswerDownloaded": "This isn’t supported currently. For now, you can save a project from Scratch for {operatingsystem}, upload it to your Scratch account, and share it there. In a later version we will add the ability to upload to your Scratch account directly in Scratch for {operatingsystem}."
|
||||
}
|
||||
|
|
|
@ -17,13 +17,15 @@ const ExtensionVideo = require('../../components/extension-landing/extension-vid
|
|||
const ExtensionRequirements = require('../../components/extension-landing/extension-requirements.jsx');
|
||||
const ExtensionSection = require('../../components/extension-landing/extension-section.jsx');
|
||||
const InstallScratchLink = require('../../components/extension-landing/install-scratch-link.jsx');
|
||||
const InstallScratch = require('../../components/install-scratch/install-scratch.jsx');
|
||||
const TipBox = require('../../components/extension-landing/tip-box.jsx');
|
||||
const ProjectCard = require('../../components/extension-landing/project-card.jsx');
|
||||
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
const Step = require('../../components/steps/step.jsx');
|
||||
|
||||
const OS_ENUM = require('../../components/extension-landing/os-enum.js');
|
||||
const OS_ENUM = require('../../lib/os-enum.js');
|
||||
const {isDownloaded, isFromGooglePlay} = require('../../components/install-scratch/install-util.js');
|
||||
|
||||
require('../../components/extension-landing/extension-landing.scss');
|
||||
require('./ev3.scss');
|
||||
|
@ -60,42 +62,23 @@ class EV3 extends ExtensionLanding {
|
|||
videoId="0huu6wfiki"
|
||||
/>}
|
||||
renderRequirements={
|
||||
<ExtensionRequirements>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/windows.svg"
|
||||
/>
|
||||
Windows 10 version 1709+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/mac.svg"
|
||||
/>
|
||||
macOS 10.13+
|
||||
</span>
|
||||
<span>
|
||||
<img src="/svgs/extensions/bluetooth.svg" />
|
||||
Bluetooth
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/scratch-link.svg"
|
||||
/>
|
||||
Scratch Link
|
||||
</span>
|
||||
</ExtensionRequirements>
|
||||
<ExtensionRequirements bluetoothStandard />
|
||||
}
|
||||
/>
|
||||
<OSChooser
|
||||
currentOS={this.state.OS}
|
||||
handleSetOS={this.onSetOS}
|
||||
/>
|
||||
{(isDownloaded(this.state.OS)) && (
|
||||
<InstallScratchLink
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
{(isFromGooglePlay(this.state.OS)) && (
|
||||
<InstallScratch
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
<ExtensionSection className="getting-started">
|
||||
<h2><FormattedMessage id="ev3.gettingStarted" /></h2>
|
||||
<FlexRow className="column getting-started-section">
|
||||
|
@ -119,6 +102,7 @@ class EV3 extends ExtensionLanding {
|
|||
/>
|
||||
</div>
|
||||
<p>
|
||||
{(isDownloaded(this.state.OS)) && (
|
||||
<FormattedMessage
|
||||
id="ev3.useScratch3"
|
||||
values={{
|
||||
|
@ -133,6 +117,10 @@ class EV3 extends ExtensionLanding {
|
|||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{(isFromGooglePlay(this.state.OS)) && (
|
||||
<FormattedMessage id="installScratch.useScratchApp" />
|
||||
)}
|
||||
</p>
|
||||
</Step>
|
||||
<Step number={3}>
|
||||
|
@ -168,27 +156,51 @@ class EV3 extends ExtensionLanding {
|
|||
<p><FormattedMessage id="ev3.acceptPasscode" /></p>
|
||||
</Step>
|
||||
<Step>
|
||||
{this.state.OS === OS_ENUM.WINDOWS && (
|
||||
<React.Fragment>
|
||||
<div className="step-image">
|
||||
<img
|
||||
alt={this.props.intl.formatMessage({id: `ev3.imgAlt${
|
||||
this.state.OS === OS_ENUM.WINDOWS ?
|
||||
'WaitForWindows' :
|
||||
'EnterPasscodeMac'
|
||||
}`})}
|
||||
alt={this.props.intl.formatMessage(
|
||||
{id: 'ev3.imgAltWaitForWindows'})}
|
||||
className="screenshot"
|
||||
src={`/images/ev3/${
|
||||
this.state.OS === OS_ENUM.WINDOWS ?
|
||||
'win-device-ready.png' :
|
||||
'mac-enter-passcode.png'
|
||||
}`}
|
||||
src="/images/ev3/win-device-ready.png"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
{this.state.OS === OS_ENUM.WINDOWS ?
|
||||
<FormattedMessage id="ev3.windowsFinalizePairing" /> :
|
||||
<FormattedMessage id="ev3.macosFinalizePairing" />
|
||||
}
|
||||
<FormattedMessage id="ev3.windowsFinalizePairing" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{this.state.OS === OS_ENUM.MACOS && (
|
||||
<React.Fragment>
|
||||
<div className="step-image">
|
||||
<img
|
||||
alt={this.props.intl.formatMessage(
|
||||
{id: 'ev3.imgAltEnterPasscodeMac'})}
|
||||
className="screenshot"
|
||||
src="/images/ev3/mac-enter-passcode.png"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
<FormattedMessage id="ev3.macosFinalizePairing" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{this.state.OS === OS_ENUM.CHROMEOS && (
|
||||
<React.Fragment>
|
||||
<div className="step-image tall">
|
||||
<img
|
||||
alt={this.props.intl.formatMessage(
|
||||
{id: 'ev3.imgAltEnterPasscodeChrome'})}
|
||||
className="screenshot"
|
||||
src="/images/ev3/chromeos-enter-passcode.png"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
<FormattedMessage id="ev3.chromeosFinalizePairing" />
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Step>
|
||||
</Steps>
|
||||
</TipBox>
|
||||
|
@ -269,6 +281,8 @@ class EV3 extends ExtensionLanding {
|
|||
</ExtensionSection>
|
||||
<ExtensionSection className="faq">
|
||||
<h2><FormattedMessage id="ev3.troubleshootingTitle" /></h2>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-title"><FormattedMessage id="ev3.checkOSVersionTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
|
@ -295,6 +309,8 @@ class EV3 extends ExtensionLanding {
|
|||
}}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<h3 className="faq-title"><FormattedMessage id="ev3.makeSurePairedTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
|
|
|
@ -5,4 +5,7 @@
|
|||
background-color: $ui-orange;
|
||||
background-image: url("/images/ev3/ev3-pattern.svg");
|
||||
}
|
||||
.step-image.tall {
|
||||
height: 16rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"ev3.acceptPasscode": "Accept the passcode.",
|
||||
"ev3.windowsFinalizePairing": "Wait for your device to be ready.",
|
||||
"ev3.macosFinalizePairing": "Enter the passcode on your computer.",
|
||||
"ev3.chromeosFinalizePairing": "Enter the passcode on your Chromebook.",
|
||||
"ev3.thingsToTry": "Things to Try",
|
||||
"ev3.makeMotorMove": "Make a motor move",
|
||||
"ev3.plugMotorIn": "Plug a motor into {portA} on the EV3 hub",
|
||||
|
@ -46,6 +47,7 @@
|
|||
"ev3.imgAltAcceptPasscode": "Use the center button on your EV3 to accept the passcode.",
|
||||
"ev3.imgAltWaitForWindows": "Windows will notify you when the EV3 is ready.",
|
||||
"ev3.imgAltEnterPasscodeMac": "Enter the passcode into the connection request window opening on your Mac.",
|
||||
"ev3.imgAltEnterPasscodeChrome": "Enter the passcode into the connection request window opening on your Chromebook.",
|
||||
"ev3.imgAltPlugInMotor": "To find port A: hold the EV3 with the screen and buttons facing you, with the screen above the buttons. Port A is on top, and it is the left-most one",
|
||||
"ev3.imgAltStarter1Basketball": "A Scratch project with a basketball.",
|
||||
"ev3.imgAltStarter2Music": "A Scratch project with musical instruments.",
|
||||
|
|
|
@ -9,12 +9,14 @@ const render = require('../../lib/render.jsx');
|
|||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
|
||||
const OSChooser = require('../../components/os-chooser/os-chooser.jsx');
|
||||
const {isDownloaded, isFromGooglePlay} = require('../../components/install-scratch/install-util.js');
|
||||
|
||||
const ExtensionLanding = require('../../components/extension-landing/extension-landing.jsx');
|
||||
const ExtensionHeader = require('../../components/extension-landing/extension-header.jsx');
|
||||
const ExtensionRequirements = require('../../components/extension-landing/extension-requirements.jsx');
|
||||
const ExtensionSection = require('../../components/extension-landing/extension-section.jsx');
|
||||
const InstallScratchLink = require('../../components/extension-landing/install-scratch-link.jsx');
|
||||
const InstallScratch = require('../../components/install-scratch/install-scratch.jsx');
|
||||
const ProjectCard = require('../../components/extension-landing/project-card.jsx');
|
||||
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
|
@ -55,45 +57,23 @@ class GdxFor extends ExtensionLanding {
|
|||
src="/images/gdxfor/gdxfor-header.svg"
|
||||
/>}
|
||||
renderRequirements={
|
||||
<ExtensionRequirements>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/windows.svg"
|
||||
/>
|
||||
Windows 10 version 1709+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/mac.svg"
|
||||
/>
|
||||
macOS 10.13+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/bluetooth.svg"
|
||||
/>
|
||||
Bluetooth 4.0
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/scratch-link.svg"
|
||||
/>
|
||||
Scratch Link
|
||||
</span>
|
||||
</ExtensionRequirements>
|
||||
<ExtensionRequirements bluetoothStandard />
|
||||
}
|
||||
/>
|
||||
<OSChooser
|
||||
currentOS={this.state.OS}
|
||||
handleSetOS={this.onSetOS}
|
||||
/>
|
||||
{(isDownloaded(this.state.OS)) && (
|
||||
<InstallScratchLink
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
{(isFromGooglePlay(this.state.OS)) && (
|
||||
<InstallScratch
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
<ExtensionSection className="getting-started">
|
||||
<h2><FormattedMessage id="gdxfor.gettingStarted" /></h2>
|
||||
<FlexRow className="column getting-started-section">
|
||||
|
@ -117,6 +97,7 @@ class GdxFor extends ExtensionLanding {
|
|||
/>
|
||||
</div>
|
||||
<p>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<FormattedMessage
|
||||
id="gdxfor.useScratch3"
|
||||
values={{
|
||||
|
@ -131,6 +112,10 @@ class GdxFor extends ExtensionLanding {
|
|||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isFromGooglePlay(this.state.OS) && (
|
||||
<FormattedMessage id="installScratch.useScratchApp" />
|
||||
)}
|
||||
</p>
|
||||
</Step>
|
||||
<Step number={3}>
|
||||
|
@ -221,6 +206,8 @@ class GdxFor extends ExtensionLanding {
|
|||
</ExtensionSection>
|
||||
<ExtensionSection className="faq">
|
||||
<h2><FormattedMessage id="gdxfor.troubleshootingTitle" /></h2>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-title"><FormattedMessage id="gdxfor.checkOSVersionTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
|
@ -247,6 +234,8 @@ class GdxFor extends ExtensionLanding {
|
|||
}}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<h3 className="faq-title"><FormattedMessage id="gdxfor.closeScratchCopiesTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage id="gdxfor.closeScratchCopiesText" />
|
||||
|
|
|
@ -1,16 +1,30 @@
|
|||
const React = require('react');
|
||||
const render = require('../../lib/render.jsx');
|
||||
const JoinModal = require('../../components/modal/join/modal.jsx');
|
||||
const Scratch3Registration = require('../../components/registration/scratch3-registration.jsx');
|
||||
const ErrorBoundary = require('../../components/errorboundary/errorboundary.jsx');
|
||||
// Require this even though we don't use it because, without it, webpack runs out of memory...
|
||||
const Page = require('../../components/page/www/page.jsx'); // eslint-disable-line no-unused-vars
|
||||
|
||||
const openModal = true;
|
||||
require('./join.scss');
|
||||
const Register = () => (
|
||||
<ErrorBoundary>
|
||||
<JoinModal
|
||||
isOpen={openModal}
|
||||
<div className="join">
|
||||
<a
|
||||
aria-label="Scratch"
|
||||
href="/"
|
||||
>
|
||||
<img
|
||||
className="logo"
|
||||
src="/images/logo_sm.png"
|
||||
/>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<Scratch3Registration
|
||||
createProjectOnComplete
|
||||
isOpen
|
||||
key="scratch3registration"
|
||||
showCloseButton={false}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
|
29
src/views/join/join.scss
Normal file
|
@ -0,0 +1,29 @@
|
|||
@import "../../frameless";
|
||||
|
||||
.join {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
left: calc(25% - 76px);
|
||||
|
||||
.logo {
|
||||
width: 76px;
|
||||
}
|
||||
}
|
||||
|
||||
@media #{$small} {
|
||||
.join {
|
||||
left: calc(50% - 38px);
|
||||
}
|
||||
}
|
||||
@media #{$medium} {
|
||||
.join {
|
||||
left: calc(50% - 38px);
|
||||
}
|
||||
}
|
||||
@media #{$intermediate} {
|
||||
.join {
|
||||
left: calc(50% - 38px);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
"microbit.downloadCardsTitle": "Download micro:bit Cards",
|
||||
"microbit.downloadHex": "Download the Scratch micro:bit HEX file",
|
||||
"microbit.dragDropHex": "Drag and drop the HEX file onto your micro:bit",
|
||||
"microbit.installHexAndroid": "Please follow the instructions to install the HEX file on a computer running Windows, MacOS or ChromeOS.",
|
||||
"microbit.connectingMicrobit": "Connecting micro:bit to Scratch",
|
||||
"microbit.powerMicrobit": "Power your micro:bit with USB or a battery pack.",
|
||||
"microbit.useScratch3": "Use the {scratch3Link} editor.",
|
||||
|
|
|
@ -10,19 +10,21 @@ const render = require('../../lib/render.jsx');
|
|||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
|
||||
const OSChooser = require('../../components/os-chooser/os-chooser.jsx');
|
||||
const {isDownloaded, isFromGooglePlay} = require('../../components/install-scratch/install-util.js');
|
||||
|
||||
const ExtensionLanding = require('../../components/extension-landing/extension-landing.jsx');
|
||||
const ExtensionHeader = require('../../components/extension-landing/extension-header.jsx');
|
||||
const ExtensionRequirements = require('../../components/extension-landing/extension-requirements.jsx');
|
||||
const ExtensionSection = require('../../components/extension-landing/extension-section.jsx');
|
||||
const InstallScratchLink = require('../../components/extension-landing/install-scratch-link.jsx');
|
||||
const InstallScratch = require('../../components/install-scratch/install-scratch.jsx');
|
||||
const ProjectCard = require('../../components/extension-landing/project-card.jsx');
|
||||
const Button = require('../../components/forms/button.jsx');
|
||||
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
const Step = require('../../components/steps/step.jsx');
|
||||
|
||||
const OS_ENUM = require('../../components/extension-landing/os-enum.js');
|
||||
const OS_ENUM = require('../../lib/os-enum.js');
|
||||
|
||||
require('../../components/extension-landing/extension-landing.scss');
|
||||
require('./microbit.scss');
|
||||
|
@ -59,49 +61,28 @@ class MicroBit extends ExtensionLanding {
|
|||
src="/images/microbit/microbit-heart.png"
|
||||
/>}
|
||||
renderRequirements={
|
||||
<ExtensionRequirements>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/windows.svg"
|
||||
/>
|
||||
Windows 10 version 1709+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/mac.svg"
|
||||
/>
|
||||
macOS 10.13+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/bluetooth.svg"
|
||||
/>
|
||||
Bluetooth 4.0
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/scratch-link.svg"
|
||||
/>
|
||||
Scratch Link
|
||||
</span>
|
||||
</ExtensionRequirements>
|
||||
<ExtensionRequirements bluetoothStandard />
|
||||
}
|
||||
/>
|
||||
<OSChooser
|
||||
currentOS={this.state.OS}
|
||||
handleSetOS={this.onSetOS}
|
||||
/>
|
||||
{(isDownloaded(this.state.OS)) && (
|
||||
<InstallScratchLink
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
{(isFromGooglePlay(this.state.OS)) && (
|
||||
<InstallScratch
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
<ExtensionSection className="getting-started">
|
||||
<h2><FormattedMessage id="microbit.gettingStarted" /></h2>
|
||||
<FlexRow className="column getting-started-section">
|
||||
<h3><FormattedMessage id="microbit.installMicrobitHex" /></h3>
|
||||
{this.state.OS !== OS_ENUM.ANDROID && (
|
||||
<Steps>
|
||||
<Step number={1}>
|
||||
<div className="step-image">
|
||||
|
@ -130,19 +111,46 @@ class MicroBit extends ExtensionLanding {
|
|||
</a>
|
||||
</Step>
|
||||
<Step number={3}>
|
||||
{this.state.OS === OS_ENUM.WINDOWS && (
|
||||
<div className="step-image">
|
||||
<img
|
||||
alt={this.props.intl.formatMessage({id: 'microbit.imgAltDragDropHex'})}
|
||||
src={`/images/microbit/${
|
||||
this.state.OS === OS_ENUM.WINDOWS ? 'win' : 'mac'
|
||||
}-copy-hex.png`}
|
||||
src="/images/microbit/win-copy-hex.png"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{this.state.OS === OS_ENUM.MACOS && (
|
||||
<div className="step-image">
|
||||
<img
|
||||
alt={this.props.intl.formatMessage({id: 'microbit.imgAltDragDropHex'})}
|
||||
src="/images/microbit/mac-copy-hex.png"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{this.state.OS === OS_ENUM.CHROMEOS && (
|
||||
<div className="step-image">
|
||||
<img
|
||||
alt={this.props.intl.formatMessage({id: 'microbit.imgAltDragDropHex'})}
|
||||
src="/images/microbit/chromeos-copy-hex.png"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<p>
|
||||
<FormattedMessage id="microbit.dragDropHex" />
|
||||
</p>
|
||||
</Step>
|
||||
</Steps>
|
||||
)}
|
||||
{this.state.OS === OS_ENUM.ANDROID && (
|
||||
<Steps>
|
||||
<Step>
|
||||
<p>
|
||||
<FormattedMessage id="microbit.installHexAndroid" />
|
||||
</p>
|
||||
</Step>
|
||||
</Steps>
|
||||
)}
|
||||
|
||||
</FlexRow>
|
||||
<hr />
|
||||
<FlexRow className="column getting-started-section">
|
||||
|
@ -166,6 +174,7 @@ class MicroBit extends ExtensionLanding {
|
|||
/>
|
||||
</div>
|
||||
<p>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<FormattedMessage
|
||||
id="microbit.useScratch3"
|
||||
values={{
|
||||
|
@ -180,6 +189,10 @@ class MicroBit extends ExtensionLanding {
|
|||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isFromGooglePlay(this.state.OS) && (
|
||||
<FormattedMessage id="installScratch.useScratchApp" />
|
||||
)}
|
||||
</p>
|
||||
</Step>
|
||||
<Step number={3}>
|
||||
|
@ -307,6 +320,8 @@ class MicroBit extends ExtensionLanding {
|
|||
</ExtensionSection>
|
||||
<ExtensionSection className="faq">
|
||||
<h2><FormattedMessage id="microbit.troubleshootingTitle" /></h2>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-title"><FormattedMessage id="microbit.checkOSVersionTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
|
@ -333,6 +348,8 @@ class MicroBit extends ExtensionLanding {
|
|||
}}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<h3 className="faq-title"><FormattedMessage id="microbit.closeScratchCopiesTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage id="microbit.closeScratchCopiesText" />
|
||||
|
|
|
@ -4,7 +4,7 @@ const Helmet = require('react-helmet').default;
|
|||
const projectShape = require('./projectshape.jsx').projectShape;
|
||||
|
||||
const Meta = props => {
|
||||
const {title, instructions, author} = props.projectInfo;
|
||||
const {id, title, instructions, author} = props.projectInfo;
|
||||
|
||||
// Do not want to render any meta tags unless all the info is loaded
|
||||
// Check only author (object) because it is ok to have empty string instructions
|
||||
|
@ -29,6 +29,10 @@ const Meta = props => {
|
|||
content={truncatedInstructions}
|
||||
property="og:description"
|
||||
/>
|
||||
<link
|
||||
href={`https://scratch.mit.edu/projects/${id}`}
|
||||
rel="canonical"
|
||||
/>
|
||||
</Helmet>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -276,7 +276,7 @@ const Landing = props => (
|
|||
id="teacherlanding.codeClub"
|
||||
values={{
|
||||
codeClubLink: (
|
||||
<a href="https://codeclubprojects.org/en-GB/scratch/">
|
||||
<a href="https://projects.raspberrypi.org/en/codeclub/scratch-module-1">
|
||||
<FormattedMessage id="teacherlanding.codeClubLink" />
|
||||
</a>
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ const render = require('../../lib/render.jsx');
|
|||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
|
||||
const OSChooser = require('../../components/os-chooser/os-chooser.jsx');
|
||||
const {isDownloaded, isFromGooglePlay} = require('../../components/install-scratch/install-util.js');
|
||||
|
||||
const ExtensionLanding = require('../../components/extension-landing/extension-landing.jsx');
|
||||
const ExtensionHeader = require('../../components/extension-landing/extension-header.jsx');
|
||||
|
@ -16,6 +17,7 @@ const ExtensionVideo = require('../../components/extension-landing/extension-vid
|
|||
const ExtensionRequirements = require('../../components/extension-landing/extension-requirements.jsx');
|
||||
const ExtensionSection = require('../../components/extension-landing/extension-section.jsx');
|
||||
const InstallScratchLink = require('../../components/extension-landing/install-scratch-link.jsx');
|
||||
const InstallScratch = require('../../components/install-scratch/install-scratch.jsx');
|
||||
const ProjectCard = require('../../components/extension-landing/project-card.jsx');
|
||||
|
||||
const Steps = require('../../components/steps/steps.jsx');
|
||||
|
@ -57,45 +59,23 @@ class Wedo2 extends ExtensionLanding {
|
|||
/>
|
||||
}
|
||||
renderRequirements={
|
||||
<ExtensionRequirements>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/windows.svg"
|
||||
/>
|
||||
Windows 10 version 1709+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/mac.svg"
|
||||
/>
|
||||
macOS 10.13+
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/bluetooth.svg"
|
||||
/>
|
||||
Bluetooth 4.0
|
||||
</span>
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
src="/svgs/extensions/scratch-link.svg"
|
||||
/>
|
||||
Scratch Link
|
||||
</span>
|
||||
</ExtensionRequirements>
|
||||
<ExtensionRequirements bluetoothStandard />
|
||||
}
|
||||
/>
|
||||
<OSChooser
|
||||
currentOS={this.state.OS}
|
||||
handleSetOS={this.onSetOS}
|
||||
/>
|
||||
{(isDownloaded(this.state.OS)) && (
|
||||
<InstallScratchLink
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
{(isFromGooglePlay(this.state.OS)) && (
|
||||
<InstallScratch
|
||||
currentOS={this.state.OS}
|
||||
/>
|
||||
)}
|
||||
<ExtensionSection className="getting-started">
|
||||
<h2><FormattedMessage id="wedo2.gettingStarted" /></h2>
|
||||
<FlexRow className="column getting-started-section">
|
||||
|
@ -110,6 +90,7 @@ class Wedo2 extends ExtensionLanding {
|
|||
/>
|
||||
</div>
|
||||
<p>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<FormattedMessage
|
||||
id="wedo2.useScratch3"
|
||||
values={{
|
||||
|
@ -124,6 +105,10 @@ class Wedo2 extends ExtensionLanding {
|
|||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isFromGooglePlay(this.state.OS) && (
|
||||
<FormattedMessage id="installScratch.useScratchApp" />
|
||||
)}
|
||||
</p>
|
||||
</Step>
|
||||
<Step number={2}>
|
||||
|
@ -207,6 +192,8 @@ class Wedo2 extends ExtensionLanding {
|
|||
</ExtensionSection>
|
||||
<ExtensionSection className="faq">
|
||||
<h2><FormattedMessage id="wedo2.troubleshootingTitle" /></h2>
|
||||
{isDownloaded(this.state.OS) && (
|
||||
<React.Fragment>
|
||||
<h3 className="faq-title"><FormattedMessage id="wedo2.checkOSVersionTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
|
@ -233,6 +220,8 @@ class Wedo2 extends ExtensionLanding {
|
|||
}}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<h3 className="faq-title"><FormattedMessage id="wedo2.closeScratchCopiesTitle" /></h3>
|
||||
<p>
|
||||
<FormattedMessage id="wedo2.closeScratchCopiesText" />
|
||||
|
|
BIN
static/images/badges/google-play-badge.png
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
BIN
static/images/ev3/chromeos-enter-passcode.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
static/images/microbit/chromeos-copy-hex.png
Normal file
After Width: | Height: | Size: 53 KiB |
46
static/svgs/download/mac-badge.svg
Executable file
|
@ -0,0 +1,46 @@
|
|||
<svg id="livetype" xmlns="http://www.w3.org/2000/svg" width="119.66407" height="40" viewBox="0 0 119.66407 40">
|
||||
<title>Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917</title>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M110.13477,0H9.53468c-.3667,0-.729,0-1.09473.002-.30615.002-.60986.00781-.91895.0127A13.21476,13.21476,0,0,0,5.5171.19141a6.66509,6.66509,0,0,0-1.90088.627A6.43779,6.43779,0,0,0,1.99757,1.99707,6.25844,6.25844,0,0,0,.81935,3.61816a6.60119,6.60119,0,0,0-.625,1.90332,12.993,12.993,0,0,0-.1792,2.002C.00587,7.83008.00489,8.1377,0,8.44434V31.5586c.00489.3105.00587.6113.01515.9219a12.99232,12.99232,0,0,0,.1792,2.0019,6.58756,6.58756,0,0,0,.625,1.9043A6.20778,6.20778,0,0,0,1.99757,38.001a6.27445,6.27445,0,0,0,1.61865,1.1787,6.70082,6.70082,0,0,0,1.90088.6308,13.45514,13.45514,0,0,0,2.0039.1768c.30909.0068.6128.0107.91895.0107C8.80567,40,9.168,40,9.53468,40H110.13477c.3594,0,.7246,0,1.084-.002.3047,0,.6172-.0039.9219-.0107a13.279,13.279,0,0,0,2-.1768,6.80432,6.80432,0,0,0,1.9082-.6308,6.27742,6.27742,0,0,0,1.6172-1.1787,6.39482,6.39482,0,0,0,1.1816-1.6143,6.60413,6.60413,0,0,0,.6191-1.9043,13.50643,13.50643,0,0,0,.1856-2.0019c.0039-.3106.0039-.6114.0039-.9219.0078-.3633.0078-.7246.0078-1.0938V9.53613c0-.36621,0-.72949-.0078-1.09179,0-.30664,0-.61426-.0039-.9209a13.5071,13.5071,0,0,0-.1856-2.002,6.6177,6.6177,0,0,0-.6191-1.90332,6.46619,6.46619,0,0,0-2.7988-2.7998,6.76754,6.76754,0,0,0-1.9082-.627,13.04394,13.04394,0,0,0-2-.17676c-.3047-.00488-.6172-.01074-.9219-.01269-.3594-.002-.7246-.002-1.084-.002Z" style="fill: #a6a6a6"/>
|
||||
<path d="M8.44483,39.125c-.30468,0-.602-.0039-.90429-.0107a12.68714,12.68714,0,0,1-1.86914-.1631,5.88381,5.88381,0,0,1-1.65674-.5479,5.40573,5.40573,0,0,1-1.397-1.0166,5.32082,5.32082,0,0,1-1.02051-1.3965,5.72186,5.72186,0,0,1-.543-1.6572,12.41351,12.41351,0,0,1-.1665-1.875c-.00634-.2109-.01464-.9131-.01464-.9131V8.44434S.88185,7.75293.8877,7.5498a12.37039,12.37039,0,0,1,.16553-1.87207,5.7555,5.7555,0,0,1,.54346-1.6621A5.37349,5.37349,0,0,1,2.61183,2.61768,5.56543,5.56543,0,0,1,4.01417,1.59521a5.82309,5.82309,0,0,1,1.65332-.54394A12.58589,12.58589,0,0,1,7.543.88721L8.44532.875H111.21387l.9131.0127a12.38493,12.38493,0,0,1,1.8584.16259,5.93833,5.93833,0,0,1,1.6709.54785,5.59374,5.59374,0,0,1,2.415,2.41993,5.76267,5.76267,0,0,1,.5352,1.64892,12.995,12.995,0,0,1,.1738,1.88721c.0029.2832.0029.5874.0029.89014.0079.375.0079.73193.0079,1.09179V30.4648c0,.3633,0,.7178-.0079,1.0752,0,.3252,0,.6231-.0039.9297a12.73126,12.73126,0,0,1-.1709,1.8535,5.739,5.739,0,0,1-.54,1.67,5.48029,5.48029,0,0,1-1.0156,1.3857,5.4129,5.4129,0,0,1-1.3994,1.0225,5.86168,5.86168,0,0,1-1.668.5498,12.54218,12.54218,0,0,1-1.8692.1631c-.2929.0068-.5996.0107-.8974.0107l-1.084.002Z"/>
|
||||
</g>
|
||||
<g id="_Group_" data-name="<Group>">
|
||||
<g id="_Group_2" data-name="<Group>">
|
||||
<g id="_Group_3" data-name="<Group>">
|
||||
<path id="_Path_" data-name="<Path>" d="M24.76888,20.30068a4.94881,4.94881,0,0,1,2.35656-4.15206,5.06566,5.06566,0,0,0-3.99116-2.15768c-1.67924-.17626-3.30719,1.00483-4.1629,1.00483-.87227,0-2.18977-.98733-3.6085-.95814a5.31529,5.31529,0,0,0-4.47292,2.72787c-1.934,3.34842-.49141,8.26947,1.3612,10.97608.9269,1.32535,2.01018,2.8058,3.42763,2.7533,1.38706-.05753,1.9051-.88448,3.5794-.88448,1.65876,0,2.14479.88448,3.591.8511,1.48838-.02416,2.42613-1.33124,3.32051-2.66914a10.962,10.962,0,0,0,1.51842-3.09251A4.78205,4.78205,0,0,1,24.76888,20.30068Z" style="fill: #fff"/>
|
||||
<path id="_Path_2" data-name="<Path>" d="M22.03725,12.21089a4.87248,4.87248,0,0,0,1.11452-3.49062,4.95746,4.95746,0,0,0-3.20758,1.65961,4.63634,4.63634,0,0,0-1.14371,3.36139A4.09905,4.09905,0,0,0,22.03725,12.21089Z" style="fill: #fff"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M42.30227,27.13965h-4.7334l-1.13672,3.35645H34.42727l4.4834-12.418h2.083l4.4834,12.418H43.438ZM38.0591,25.59082h3.752l-1.84961-5.44727h-.05176Z" style="fill: #fff"/>
|
||||
<path d="M55.15969,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H48.4302v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C53.645,21.34766,55.15969,23.16406,55.15969,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C52.30227,29.01563,53.24953,27.81934,53.24953,25.96973Z" style="fill: #fff"/>
|
||||
<path d="M65.12453,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H58.395v1.50586h.03418A3.21162,3.21162,0,0,1,61.312,21.34766C63.60988,21.34766,65.12453,23.16406,65.12453,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C62.26711,29.01563,63.21438,27.81934,63.21438,25.96973Z" style="fill: #fff"/>
|
||||
<path d="M71.71047,27.03613c.1377,1.23145,1.334,2.04,2.96875,2.04,1.56641,0,2.69336-.80859,2.69336-1.91895,0-.96387-.67969-1.541-2.28906-1.93652l-1.60937-.3877c-2.28027-.55078-3.33887-1.61719-3.33887-3.34766,0-2.14258,1.86719-3.61426,4.51855-3.61426,2.624,0,4.42285,1.47168,4.4834,3.61426h-1.876c-.1123-1.23926-1.13672-1.9873-2.63379-1.9873s-2.52148.75684-2.52148,1.8584c0,.87793.6543,1.39453,2.25488,1.79l1.36816.33594c2.54785.60254,3.60645,1.626,3.60645,3.44238,0,2.32324-1.85059,3.77832-4.79395,3.77832-2.75391,0-4.61328-1.4209-4.7334-3.667Z" style="fill: #fff"/>
|
||||
<path d="M83.34621,19.2998v2.14258h1.72168v1.47168H83.34621v4.99121c0,.77539.34473,1.13672,1.10156,1.13672a5.80752,5.80752,0,0,0,.61133-.043v1.46289a5.10351,5.10351,0,0,1-1.03223.08594c-1.833,0-2.54785-.68848-2.54785-2.44434V22.91406H80.16262V21.44238H81.479V19.2998Z" style="fill: #fff"/>
|
||||
<path d="M86.065,25.96973c0-2.84863,1.67773-4.63867,4.29395-4.63867,2.625,0,4.29492,1.79,4.29492,4.63867,0,2.85645-1.66113,4.63867-4.29492,4.63867C87.72609,30.6084,86.065,28.82617,86.065,25.96973Zm6.69531,0c0-1.9541-.89551-3.10742-2.40137-3.10742s-2.40039,1.16211-2.40039,3.10742c0,1.96191.89453,3.10645,2.40039,3.10645S92.76027,27.93164,92.76027,25.96973Z" style="fill: #fff"/>
|
||||
<path d="M96.18606,21.44238h1.77246v1.541h.043a2.1594,2.1594,0,0,1,2.17773-1.63574,2.86616,2.86616,0,0,1,.63672.06934v1.73828a2.59794,2.59794,0,0,0-.835-.1123,1.87264,1.87264,0,0,0-1.93652,2.083v5.37012h-1.8584Z" style="fill: #fff"/>
|
||||
<path d="M109.3843,27.83691c-.25,1.64355-1.85059,2.77148-3.89844,2.77148-2.63379,0-4.26855-1.76465-4.26855-4.5957,0-2.83984,1.64355-4.68164,4.19043-4.68164,2.50488,0,4.08008,1.7207,4.08008,4.46582v.63672h-6.39453v.1123a2.358,2.358,0,0,0,2.43555,2.56445,2.04834,2.04834,0,0,0,2.09082-1.27344Zm-6.28223-2.70215h4.52637a2.1773,2.1773,0,0,0-2.2207-2.29785A2.292,2.292,0,0,0,103.10207,25.13477Z" style="fill: #fff"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="_Group_4" data-name="<Group>">
|
||||
<g>
|
||||
<path d="M37.82619,8.731a2.63964,2.63964,0,0,1,2.80762,2.96484c0,1.90625-1.03027,3.002-2.80762,3.002H35.67092V8.731Zm-1.22852,5.123h1.125a1.87588,1.87588,0,0,0,1.96777-2.146,1.881,1.881,0,0,0-1.96777-2.13379h-1.125Z" style="fill: #fff"/>
|
||||
<path d="M41.68068,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C44.57522,13.99463,45.01369,13.42432,45.01369,12.44434Z" style="fill: #fff"/>
|
||||
<path d="M51.57326,14.69775h-.92187l-.93066-3.31641h-.07031l-.92676,3.31641h-.91309l-1.24121-4.50293h.90137l.80664,3.436h.06641l.92578-3.436h.85254l.92578,3.436h.07031l.80273-3.436h.88867Z" style="fill: #fff"/>
|
||||
<path d="M53.85354,10.19482H54.709v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915h-.88867V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
|
||||
<path d="M59.09377,8.437h.88867v6.26074h-.88867Z" style="fill: #fff"/>
|
||||
<path d="M61.21779,12.44434a2.13346,2.13346,0,1,1,4.24756,0,2.1338,2.1338,0,1,1-4.24756,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C64.11232,13.99463,64.5508,13.42432,64.5508,12.44434Z" style="fill: #fff"/>
|
||||
<path d="M66.4009,13.42432c0-.81055.60352-1.27783,1.6748-1.34424l1.21973-.07031v-.38867c0-.47559-.31445-.74414-.92187-.74414-.49609,0-.83984.18213-.93848.50049h-.86035c.09082-.77344.81836-1.26953,1.83984-1.26953,1.12891,0,1.76563.562,1.76563,1.51318v3.07666h-.85547v-.63281h-.07031a1.515,1.515,0,0,1-1.35254.707A1.36026,1.36026,0,0,1,66.4009,13.42432Zm2.89453-.38477v-.37646l-1.09961.07031c-.62012.0415-.90137.25244-.90137.64941,0,.40527.35156.64111.835.64111A1.0615,1.0615,0,0,0,69.29543,13.03955Z" style="fill: #fff"/>
|
||||
<path d="M71.34816,12.44434c0-1.42285.73145-2.32422,1.86914-2.32422a1.484,1.484,0,0,1,1.38086.79h.06641V8.437h.88867v6.26074h-.85156v-.71143h-.07031a1.56284,1.56284,0,0,1-1.41406.78564C72.0718,14.772,71.34816,13.87061,71.34816,12.44434Zm.918,0c0,.95508.4502,1.52979,1.20313,1.52979.749,0,1.21191-.583,1.21191-1.52588,0-.93848-.46777-1.52979-1.21191-1.52979C72.72121,10.91846,72.26613,11.49707,72.26613,12.44434Z" style="fill: #fff"/>
|
||||
<path d="M79.23,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C82.12453,13.99463,82.563,13.42432,82.563,12.44434Z" style="fill: #fff"/>
|
||||
<path d="M84.66945,10.19482h.85547v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915H87.605V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
|
||||
<path d="M93.51516,9.07373v1.1416h.97559v.74854h-.97559V13.2793c0,.47168.19434.67822.63672.67822a2.96657,2.96657,0,0,0,.33887-.02051v.74023a2.9155,2.9155,0,0,1-.4834.04541c-.98828,0-1.38184-.34766-1.38184-1.21582v-2.543h-.71484v-.74854h.71484V9.07373Z" style="fill: #fff"/>
|
||||
<path d="M95.70461,8.437h.88086v2.48145h.07031a1.3856,1.3856,0,0,1,1.373-.80664,1.48339,1.48339,0,0,1,1.55078,1.67871v2.90723H98.69v-2.688c0-.71924-.335-1.0835-.96289-1.0835a1.05194,1.05194,0,0,0-1.13379,1.1416v2.62988h-.88867Z" style="fill: #fff"/>
|
||||
<path d="M104.76125,13.48193a1.828,1.828,0,0,1-1.95117,1.30273A2.04531,2.04531,0,0,1,100.73,12.46045a2.07685,2.07685,0,0,1,2.07617-2.35254c1.25293,0,2.00879.856,2.00879,2.27V12.688h-3.17969v.0498a1.1902,1.1902,0,0,0,1.19922,1.29,1.07934,1.07934,0,0,0,1.07129-.5459Zm-3.126-1.45117h2.27441a1.08647,1.08647,0,0,0-1.1084-1.1665A1.15162,1.15162,0,0,0,101.63527,12.03076Z" style="fill: #fff"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
82
static/svgs/download/ms-badge.svg
Executable file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 864 312" enable-background="new 0 0 864 312" xml:space="preserve">
|
||||
<g id="Layer_2">
|
||||
<rect x="2.3" y="2.3" width="859.5" height="307.5"/>
|
||||
<path fill="#D2D2D2" d="M4.5,4.5h855v303H4.5V4.5z M0,312h864V0H0V312z"/>
|
||||
<g>
|
||||
<defs>
|
||||
<rect id="SVGID_1_" y="0" width="864" height="312"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_2_">
|
||||
<use xlink:href="#SVGID_1_" overflow="visible"/>
|
||||
</clipPath>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Layer_1">
|
||||
<rect x="70.5" y="68.6" fill="#F25022" width="83.8" height="83.8"/>
|
||||
<rect x="163" y="68.6" fill="#7FBA00" width="83.8" height="83.8"/>
|
||||
<rect x="70.5" y="161" fill="#00A4EF" width="83.8" height="83.8"/>
|
||||
<rect x="163" y="161" fill="#FFB900" width="83.8" height="83.8"/>
|
||||
<path fill="#FFFFFF" d="M408.3,163c0-2.5,0.9-4.5,2.7-6.2c1.8-1.7,3.9-2.5,6.4-2.5c2.6,0,4.8,0.9,6.5,2.6c1.7,1.7,2.6,3.8,2.6,6.1
|
||||
c0,2.4-0.9,4.5-2.7,6.1c-1.8,1.7-3.9,2.5-6.5,2.5c-2.6,0-4.7-0.8-6.5-2.5C409.2,167.4,408.3,165.4,408.3,163 M424.8,244.8h-14.9
|
||||
v-63.5h14.9V244.8z"/>
|
||||
<path fill="#FFFFFF" d="M470.2,233.9c2.2,0,4.7-0.5,7.4-1.5c2.7-1,5.1-2.4,7.4-4.1v13.9c-2.4,1.4-5.1,2.4-8.1,3.1
|
||||
c-3,0.7-6.4,1.1-10,1.1c-9.3,0-16.9-3-22.8-8.9c-5.9-5.9-8.8-13.5-8.8-22.6c0-10.2,3-18.6,9-25.2c6-6.6,14.4-9.9,25.4-9.9
|
||||
c2.8,0,5.6,0.4,8.5,1.1c2.9,0.7,5.1,1.6,6.8,2.5v14.3c-2.3-1.7-4.7-3-7.1-3.9c-2.4-0.9-4.9-1.4-7.4-1.4c-5.9,0-10.6,1.9-14.3,5.7
|
||||
c-3.6,3.8-5.4,9-5.4,15.5c0,6.4,1.7,11.4,5.2,15C459.5,232.2,464.2,233.9,470.2,233.9"/>
|
||||
<path fill="#FFFFFF" d="M527.5,180.3c1.2,0,2.3,0.1,3.2,0.2c0.9,0.2,1.8,0.4,2.4,0.6v15.1c-0.8-0.6-1.9-1.1-3.4-1.6
|
||||
c-1.5-0.5-3.3-0.8-5.5-0.8c-3.7,0-6.8,1.5-9.3,4.6c-2.5,3.1-3.8,7.8-3.8,14.3v32.1h-14.9v-63.5h14.9v10h0.2
|
||||
c1.4-3.5,3.4-6.2,6.2-8.1C520.3,181.3,523.6,180.3,527.5,180.3"/>
|
||||
<path fill="#FFFFFF" d="M533.9,214c0-10.5,3-18.8,8.9-25c5.9-6.1,14.2-9.2,24.7-9.2c9.9,0,17.7,3,23.3,8.9
|
||||
c5.6,5.9,8.4,13.9,8.4,23.9c0,10.3-3,18.5-8.9,24.6c-5.9,6.1-14,9.1-24.2,9.1c-9.8,0-17.7-2.9-23.4-8.7
|
||||
C536.8,231.9,533.9,224,533.9,214 M549.5,213.5c0,6.6,1.5,11.7,4.5,15.2c3,3.5,7.3,5.2,12.9,5.2c5.4,0,9.6-1.7,12.4-5.2
|
||||
s4.3-8.7,4.3-15.6c0-6.8-1.5-12-4.4-15.5c-2.9-3.5-7.1-5.2-12.4-5.2c-5.5,0-9.7,1.8-12.8,5.5C551,201.6,549.5,206.7,549.5,213.5"/>
|
||||
<path fill="#FFFFFF" d="M621.4,198c0,2.1,0.7,3.8,2,5c1.4,1.2,4.4,2.7,9,4.6c6,2.4,10.2,5.1,12.6,8.1c2.4,3,3.6,6.6,3.6,10.8
|
||||
c0,6-2.3,10.8-6.9,14.4c-4.6,3.6-10.8,5.4-18.6,5.4c-2.6,0-5.5-0.3-8.7-1c-3.2-0.6-5.9-1.5-8.1-2.4v-14.7c2.7,1.9,5.6,3.4,8.8,4.5
|
||||
c3.1,1.1,6,1.7,8.5,1.7c3.4,0,5.9-0.5,7.5-1.4c1.6-0.9,2.4-2.5,2.4-4.8c0-2.1-0.8-3.8-2.5-5.2c-1.7-1.4-4.8-3.1-9.5-4.9
|
||||
c-5.5-2.3-9.4-4.9-11.7-7.8c-2.3-2.9-3.5-6.6-3.5-11c0-5.7,2.3-10.4,6.8-14.1c4.5-3.7,10.4-5.5,17.7-5.5c2.2,0,4.7,0.2,7.5,0.7
|
||||
c2.8,0.5,5.1,1.1,6.9,1.9v14.2c-2-1.3-4.3-2.4-6.9-3.4c-2.6-0.9-5.3-1.4-7.8-1.4c-2.8,0-5.1,0.6-6.6,1.7
|
||||
C622.2,194.5,621.4,196.1,621.4,198"/>
|
||||
<path fill="#FFFFFF" d="M655.2,214c0-10.5,3-18.8,8.9-25c5.9-6.1,14.2-9.2,24.7-9.2c9.9,0,17.7,3,23.3,8.9
|
||||
c5.6,5.9,8.4,13.9,8.4,23.9c0,10.3-3,18.5-8.9,24.6c-5.9,6.1-14,9.1-24.2,9.1c-9.8,0-17.7-2.9-23.4-8.7
|
||||
C658.1,231.9,655.2,224,655.2,214 M670.7,213.5c0,6.6,1.5,11.7,4.5,15.2c3,3.5,7.3,5.2,12.9,5.2c5.4,0,9.6-1.7,12.4-5.2
|
||||
s4.3-8.7,4.3-15.6c0-6.8-1.5-12-4.4-15.5s-7.1-5.2-12.4-5.2c-5.5,0-9.7,1.8-12.8,5.5C672.2,201.6,670.7,206.7,670.7,213.5"/>
|
||||
<path fill="#FFFFFF" d="M769.8,193.6v32.6c0,6.8,1.6,11.8,4.7,15.2c3.1,3.4,7.9,5,14.2,5c2.1,0,4.3-0.2,6.5-0.7
|
||||
c2.2-0.5,3.8-0.9,4.7-1.5v-12.4c-0.9,0.6-2,1.1-3.2,1.5c-1.2,0.4-2.3,0.6-3.1,0.6c-3,0-5.3-0.8-6.7-2.4c-1.4-1.6-2.1-4.4-2.1-8.3
|
||||
v-29.7H800v-12.2h-15.1v-18.8l-15,4.6v14.3h-22.3v-7.7c0-3.8,0.8-6.7,2.5-8.7c1.7-2,4.1-2.9,7.2-2.9c1.6,0,3,0.2,4.3,0.6
|
||||
c1.2,0.4,2.1,0.8,2.6,1.1v-12.9c-1.1-0.4-2.3-0.6-3.7-0.8c-1.4-0.2-3-0.3-4.8-0.3c-6.8,0-12.4,2.1-16.7,6.4
|
||||
c-4.3,4.3-6.5,9.7-6.5,16.4v8.8h-10.6v12.2h10.6v51.3h15.1v-51.3H769.8z"/>
|
||||
<polygon fill="#FFFFFF" points="395.5,156.2 395.5,244.8 380.1,244.8 380.1,175.4 379.9,175.4 352.4,244.8 342.2,244.8 314,175.4
|
||||
313.8,175.4 313.8,244.8 299.6,244.8 299.6,156.2 321.6,156.2 347.1,221.9 347.5,221.9 374.4,156.2 "/>
|
||||
<path fill="#FFFFFF" d="M340,117.9c-5.3,3-11.3,4.5-18,4.5c-5.1,0-9.6-1.1-13.6-3.4c-3.9-2.2-7-5.4-9.1-9.5
|
||||
c-2.1-4.1-3.2-8.7-3.2-13.8c0-5.4,1.2-10.3,3.5-14.5s5.6-7.6,9.9-10c4.3-2.4,9.1-3.6,14.5-3.6c2.7,0,5.4,0.3,8.1,0.8
|
||||
c2.7,0.5,4.9,1.2,6.6,2v8c-4-2.7-9.1-4-15.3-4c-3.7,0-7,0.9-10,2.7c-3,1.8-5.3,4.3-6.9,7.4c-1.6,3.2-2.4,6.8-2.4,10.8
|
||||
c0,6.3,1.7,11.3,5,15c3.3,3.7,7.9,5.5,13.7,5.5c3.7,0,7-0.7,9.8-2.2V99.9h-11.3v-6.6H340V117.9z"/>
|
||||
<path fill="#FFFFFF" d="M383.1,104.6h-26.2c0.1,3.8,1.3,6.7,3.3,8.8c2.1,2,4.8,3.1,8.2,3.1c4.5,0,8.4-1.3,11.8-3.9v6.4
|
||||
c-1.5,1-3.4,1.9-5.7,2.5c-2.3,0.6-4.7,0.9-7.1,0.9c-5.7,0-10.2-1.7-13.3-5.1c-3.1-3.4-4.7-8.2-4.7-14.4c0-3.8,0.8-7.3,2.3-10.3
|
||||
c1.5-3.1,3.7-5.5,6.4-7.2c2.7-1.7,5.8-2.6,9.1-2.6c4.9,0,8.8,1.6,11.6,4.8c2.8,3.2,4.2,7.6,4.2,13.3V104.6z M375.8,98.9
|
||||
c0-3.3-0.8-5.8-2.3-7.5c-1.5-1.7-3.6-2.6-6.4-2.6c-2.5,0-4.7,0.9-6.6,2.7s-3,4.3-3.6,7.4H375.8z"/>
|
||||
<path fill="#FFFFFF" d="M411.5,121.1c-0.7,0.4-1.6,0.7-2.9,0.9c-1.2,0.2-2.3,0.3-3.3,0.3c-7,0-10.5-3.9-10.5-11.6V89.7h-6.4v-6h6.4
|
||||
v-9l7.3-2.3v11.2h9.3v6h-9.3v19.8c0,2.5,0.4,4.3,1.2,5.3c0.8,1,2.2,1.5,4.3,1.5c1.4,0,2.7-0.4,3.8-1.2V121.1z"/>
|
||||
<path fill="#FFFFFF" d="M447.7,70.3c0,1.2-0.4,2.2-1.3,3.1c-0.9,0.9-2,1.3-3.3,1.3c-1.3,0-2.4-0.4-3.3-1.3
|
||||
c-0.9-0.8-1.3-1.9-1.3-3.2c0-1.3,0.5-2.4,1.4-3.2c0.9-0.8,2-1.3,3.2-1.3c1.2,0,2.3,0.4,3.2,1.3C447.3,68,447.7,69,447.7,70.3
|
||||
M446.7,121.5h-7.3V83.7h7.3V121.5z"/>
|
||||
<path fill="#FFFFFF" d="M478.4,121.1c-0.7,0.4-1.6,0.7-2.9,0.9c-1.2,0.2-2.3,0.3-3.3,0.3c-7,0-10.5-3.9-10.5-11.6V89.7h-6.4v-6h6.4
|
||||
v-9l7.3-2.3v11.2h9.3v6h-9.3v19.8c0,2.5,0.4,4.3,1.2,5.3c0.8,1,2.2,1.5,4.3,1.5c1.4,0,2.7-0.4,3.8-1.2V121.1z"/>
|
||||
<path fill="#FFFFFF" d="M526.2,71.7c-1.2-0.6-2.5-1-4-1c-4.1,0-6.1,2.5-6.1,7.5v5.4h8.6v6h-8.6v31.8h-7.3V89.7h-6.4v-6h6.4v-5.8
|
||||
c0-4,1.1-7.2,3.4-9.6c2.3-2.4,5.4-3.6,9.4-3.6c2,0,3.5,0.2,4.7,0.7V71.7z"/>
|
||||
<path fill="#FFFFFF" d="M553.1,91c-0.4-0.3-1.2-0.6-2.2-0.9c-1-0.2-1.9-0.4-2.6-0.4c-2.6,0-4.7,1.2-6.3,3.5c-1.6,2.3-2.4,5.3-2.4,9
|
||||
v19.3h-7.3V83.7h7.3v7.6h0.2c0.8-2.6,2.1-4.6,3.8-6.1c1.7-1.5,3.7-2.2,5.9-2.2c1.5,0,2.7,0.2,3.5,0.5V91z"/>
|
||||
<path fill="#FFFFFF" d="M594.8,102.4c0,6.1-1.8,11-5.3,14.6c-3.5,3.6-8.2,5.4-14,5.4c-5.7,0-10.3-1.8-13.7-5.3
|
||||
c-3.4-3.5-5.1-8.2-5.1-14.1c0-6.3,1.8-11.2,5.3-14.8c3.5-3.6,8.3-5.4,14.4-5.4c5.7,0,10.2,1.7,13.4,5.2
|
||||
C593.2,91.5,594.8,96.3,594.8,102.4 M587.3,102.6c0-4.5-1-7.9-2.9-10.2c-2-2.3-4.7-3.5-8.3-3.5c-3.6,0-6.5,1.2-8.6,3.7
|
||||
c-2.1,2.4-3.1,5.9-3.1,10.3c0,4.3,1,7.6,3.1,10c2.1,2.4,4.9,3.6,8.6,3.6c3.7,0,6.5-1.2,8.4-3.5
|
||||
C586.3,110.5,587.3,107.1,587.3,102.6"/>
|
||||
<path fill="#FFFFFF" d="M660.1,121.5h-7.3V100c0-3.9-0.6-6.7-1.8-8.5c-1.2-1.8-3.3-2.6-6.2-2.6c-2.4,0-4.5,1.1-6.1,3.3
|
||||
c-1.7,2.2-2.5,4.9-2.5,7.9v21.4h-7.3V99.3c0-6.9-2.7-10.4-8-10.4c-2.5,0-4.6,1.1-6.2,3.2s-2.4,4.8-2.4,8.1v21.4h-7.3V83.7h7.3v5.9
|
||||
h0.1c2.7-4.6,6.7-6.8,11.8-6.8c2.4,0,4.6,0.7,6.6,2c1.9,1.3,3.3,3.2,4.2,5.6c1.5-2.6,3.2-4.5,5.3-5.8c2.1-1.2,4.5-1.9,7.3-1.9
|
||||
c8.3,0,12.4,5.1,12.4,15.4V121.5z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.1 KiB |
14
static/svgs/extensions/android.svg
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?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 57.1 (83088) - https://sketch.com -->
|
||||
<title>Android</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Android" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(2.000000, 0.000000)" fill="#FFFFFF" fill-rule="nonzero">
|
||||
<path d="M1.25537906,6.46718412 C0.911371841,6.46718412 0.619494585,6.58714801 0.379566787,6.82707581 C0.139638989,7.06700361 0.0196389892,7.35490975 0.0196389892,7.69093863 L0.0196389892,12.8502888 C0.0196389892,13.1947292 0.139602888,13.4863538 0.379566787,13.7263177 C0.619494585,13.9662455 0.911371841,14.0862455 1.25537906,14.0862455 C1.59913357,14.0862455 1.88924188,13.9662816 2.12545126,13.7263177 C2.36119134,13.4863899 2.47938628,13.1947292 2.47938628,12.8502888 L2.47938628,7.69093863 C2.47938628,7.35487365 2.35942238,7.06700361 2.11945848,6.82707581 C1.87949458,6.58714801 1.59140794,6.46718412 1.25537906,6.46718412 Z" id="Path"></path>
|
||||
<path d="M11.1903249,1.83563177 L12.0422383,0.264079422 C12.0981588,0.160036101 12.0782671,0.0802527076 11.9823827,0.0241516245 C11.8783032,-0.0242238267 11.7983394,0.000288808664 11.7424549,0.0959566787 L10.8786282,1.6800722 C10.1185199,1.34400722 9.31458484,1.17566787 8.4668231,1.17566787 C7.61888087,1.17566787 6.81487365,1.34404332 6.05505415,1.6800722 L5.19119134,0.0959566787 C5.13505415,0.000288808664 5.05509025,-0.0240072202 4.95126354,0.0241516245 C4.85516245,0.0805054152 4.83527076,0.160036101 4.89140794,0.264079422 L5.7433574,1.83563177 C4.87949458,2.27617329 4.19148014,2.88971119 3.67956679,3.67758123 C3.16765343,4.46588448 2.91158845,5.32732852 2.91158845,6.2634296 L14.01,6.2634296 C14.01,5.32754513 13.7538989,4.46606498 13.2420217,3.67758123 C12.7300722,2.88971119 12.0460289,2.27617329 11.1903249,1.83563177 Z M6.26494585,4.12148014 C6.17281588,4.21382671 6.06277978,4.25978339 5.93487365,4.25978339 C5.8067148,4.25978339 5.69891697,4.21382671 5.61097473,4.12148014 C5.52303249,4.02956679 5.47906137,3.9199639 5.47906137,3.79162455 C5.47906137,3.66371841 5.52303249,3.55389892 5.61097473,3.46176895 C5.69891697,3.3698556 5.80696751,3.32389892 5.93487365,3.32389892 C6.06277978,3.32389892 6.17281588,3.3698556 6.26494585,3.46176895 C6.35685921,3.55411552 6.40303249,3.66371841 6.40303249,3.79162455 C6.40277978,3.91974729 6.3566426,4.02956679 6.26494585,4.12148014 Z M11.3222022,4.12148014 C11.2340794,4.21382671 11.1260289,4.25978339 10.9983394,4.25978339 C10.8701444,4.25978339 10.7601444,4.21382671 10.6681949,4.12148014 C10.5761011,4.02956679 10.5301444,3.9199639 10.5301444,3.79162455 C10.5301444,3.66371841 10.5761011,3.55389892 10.6681949,3.46176895 C10.7601444,3.3698556 10.8701444,3.32389892 10.9983394,3.32389892 C11.1262455,3.32389892 11.2340433,3.3698556 11.3222022,3.46176895 C11.4102166,3.55411552 11.4541155,3.66371841 11.4541155,3.79162455 C11.4541155,3.91974729 11.4101805,4.02956679 11.3222022,4.12148014 Z" id="Shape"></path>
|
||||
<path d="M2.95924188,14.686065 C2.95924188,15.0543682 3.08714801,15.3661372 3.34299639,15.6219856 C3.59906137,15.8778339 3.91083032,16.0057401 4.27888087,16.0057401 L5.1668231,16.0057401 L5.17898917,18.7297112 C5.17898917,19.0736823 5.29895307,19.3657762 5.53888087,19.6057401 C5.77880866,19.845704 6.06693141,19.9656679 6.40274368,19.9656679 C6.7465343,19.9656679 7.03859206,19.845704 7.27855596,19.6057401 C7.51851986,19.3657762 7.63848375,19.0737184 7.63848375,18.7297112 L7.63848375,16.0059928 L9.29422383,16.0059928 L9.29422383,18.7297112 C9.29422383,19.0736823 9.41415162,19.3657762 9.65411552,19.6057401 C9.89407942,19.845704 10.1858845,19.9656679 10.5299278,19.9656679 C10.8737184,19.9656679 11.1657762,19.845704 11.4057401,19.6057401 C11.645704,19.3657762 11.7656318,19.0737184 11.7656318,18.7297112 L11.7656318,16.0059928 L12.6655596,16.0059928 C13.0254513,16.0059928 13.333213,15.8780505 13.5895307,15.6222022 C13.845343,15.3663538 13.9733213,15.0545848 13.9733213,14.6863177 L13.9733213,6.69494585 L2.95924188,6.69494585 L2.95924188,14.686065 Z" id="Path"></path>
|
||||
<path d="M15.6777978,6.46718412 C15.3417329,6.46718412 15.0538628,6.58537906 14.8138989,6.82111913 C14.5739711,7.05729242 14.4540072,7.34740072 14.4540072,7.69093863 L14.4540072,12.8502888 C14.4540072,13.1947292 14.573935,13.4863538 14.8138989,13.7263177 C15.0538628,13.9662816 15.3419495,14.0862455 15.6777978,14.0862455 C16.0215884,14.0862455 16.3136462,13.9662816 16.5536101,13.7263177 C16.793574,13.4863538 16.9135018,13.1947292 16.9135018,12.8502888 L16.9135018,7.69093863 C16.9135018,7.34736462 16.793574,7.05729242 16.5536101,6.82111913 C16.3136462,6.58537906 16.0215884,6.46718412 15.6777978,6.46718412 Z" id="Path"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
14
static/svgs/extensions/chromeos.svg
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?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 57.1 (83088) - https://sketch.com -->
|
||||
<title>Chrome</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Chrome" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(2.000000, 2.000000)" fill="#FFFFFF">
|
||||
<path d="M-2.84217094e-14,7.51020408 C0.0433306122,7.19373061 0.0761142857,6.87539592 0.13195102,6.56114286 C0.320685714,5.49874286 0.718008163,4.51797551 1.30847347,3.61521633 C1.32009796,3.59738776 1.33590204,3.58230204 1.35928163,3.5547102 C1.57185306,3.91699592 1.78060408,4.27173878 1.98834286,4.62703673 C2.85528163,6.10958367 3.72205714,7.59222857 4.58811429,9.07529796 C4.62906122,9.14543673 4.66795102,9.21779592 4.69825306,9.29299592 C5.46089796,11.1836735 7.56679184,12.0508408 9.43497143,11.2424816 C9.47294694,11.2260571 9.51203265,11.2122449 9.58279184,11.1846204 C9.54497959,11.2586122 9.52395102,11.3050122 9.49851429,11.3488653 C8.64199184,12.824849 7.78370612,14.2998531 6.93093878,15.7779592 C6.86834286,15.8864327 6.80581224,15.9149061 6.68574694,15.8938776 C3.47578776,15.331951 0.990530612,13.0129306 0.217926531,9.83826939 C0.123297959,9.44943673 0.0910367347,9.04542041 0.029322449,8.64852245 C0.0210938776,8.59536327 0.00986122449,8.54269388 -2.84217094e-14,8.48979592 L-2.84217094e-14,7.51020408 Z" id="Fill-4"></path>
|
||||
<path d="M7.51020408,16 C7.52636735,15.9419429 7.53113469,15.8772245 7.56039184,15.8267102 C8.7072,13.8461714 9.85642449,11.8670041 11.0049959,9.8874449 C11.9937633,8.18337959 11.6030041,6.26808163 10.0272,5.09208163 C10.0116245,5.08045714 9.9979102,5.06638367 9.96133878,5.03399184 C10.0355918,5.03046531 10.0817633,5.02635102 10.127902,5.02635102 C11.8421551,5.02602449 13.5563755,5.02759184 15.2706286,5.02288745 C15.3963429,5.02253061 15.4454857,5.06328163 15.4880327,5.17838367 C15.7498449,5.88659592 15.9166367,6.6144 15.9716898,7.36773878 C15.9751837,7.41564082 15.990302,7.46272653 16,7.51020408 L16,8.48979592 C15.9907918,8.53662041 15.9766857,8.58302041 15.9730286,8.63030204 C15.8665469,10.0016653 15.4397061,11.2664816 14.6717388,12.405649 C13.4046367,14.2852245 11.6505796,15.4418612 9.42226939,15.8699755 C9.12496327,15.9270857 8.82249796,15.9572898 8.52244898,16 L7.51020408,16 Z" id="Fill-6"></path>
|
||||
<path d="M8.48979592,2.84217094e-14 C8.86566531,0.0544653061 9.24662857,0.0857142857 9.61652245,0.167216327 C12.045649,0.702269388 13.8570449,2.06971429 15.0628571,4.24280816 C15.0961306,4.30275918 15.124702,4.36532245 15.168,4.4516898 L14.9320816,4.4516898 C12.6580245,4.4516898 10.3839673,4.4475102 8.10994286,4.45319184 C6.65002449,4.45684898 5.55529796,5.09724082 4.84813061,6.3787102 C4.62618776,6.78089796 4.51265306,7.22106122 4.46409796,7.71451429 C4.41319184,7.63627755 4.38001633,7.58961633 4.35121633,7.54037551 C3.50060408,6.08610612 2.65172245,4.63082449 1.79738776,3.17874286 C1.73381224,3.07072653 1.74220408,3.0069551 1.82164898,2.91320816 C3.19614694,1.29093878 4.92897959,0.327510204 7.04290612,0.0598530612 C7.19869388,0.0401306122 7.35444898,0.0199510204 7.51020408,2.84217094e-14 L8.48979592,2.84217094e-14 Z" id="Fill-8"></path>
|
||||
<path d="M5.02659576,7.98558694 C5.03150694,6.32864 6.36590694,5.02310531 8.05018449,5.02740487 C9.66131918,5.0315298 10.9807967,6.38290939 10.9732861,8.02108082 C10.9655804,9.67394612 9.62566204,10.9782727 7.94122122,10.9726095 C6.34269061,10.9671706 5.02177633,9.61344 5.02659576,7.98558694" id="Fill-12"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
|
@ -50,6 +50,7 @@ describe('EmailStep test', () => {
|
|||
expect(emailInputWrapper.props().onSetRef).toEqual(formikWrapper.instance().handleSetEmailRef);
|
||||
expect(emailInputWrapper.props().validate).toEqual(formikWrapper.instance().validateEmail);
|
||||
});
|
||||
|
||||
test('props sent to FormikCheckbox for subscribe', () => {
|
||||
const wrapper = shallowWithIntl(<EmailStep />);
|
||||
// Dive to get past the intl wrapper
|
||||
|
@ -63,6 +64,7 @@ describe('EmailStep test', () => {
|
|||
expect(checkboxWrapper.first().props().label).toEqual('registration.receiveEmails');
|
||||
expect(checkboxWrapper.first().props().name).toEqual('subscribe');
|
||||
});
|
||||
|
||||
test('handleValidSubmit passes formData to next step', () => {
|
||||
const formikBag = {
|
||||
setSubmitting: jest.fn()
|
||||
|
@ -82,6 +84,7 @@ describe('EmailStep test', () => {
|
|||
expect(formikBag.setSubmitting).toHaveBeenCalledWith(false);
|
||||
expect(global.grecaptcha.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('captchaSolved sets token and goes to next step', () => {
|
||||
const props = {
|
||||
onNextStep: jest.fn()
|
||||
|
@ -116,6 +119,38 @@ describe('EmailStep test', () => {
|
|||
}));
|
||||
expect(formikBag.setSubmitting).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
test('onCaptchaError calls error function with correct message', () => {
|
||||
const props = {
|
||||
onRegistrationError: jest.fn()
|
||||
};
|
||||
|
||||
const wrapper = shallowWithIntl(
|
||||
<EmailStep
|
||||
{...props}
|
||||
/>);
|
||||
|
||||
const formikWrapper = wrapper.dive();
|
||||
formikWrapper.instance().onCaptchaError();
|
||||
expect(props.onRegistrationError).toHaveBeenCalledWith('registation.troubleReload');
|
||||
});
|
||||
|
||||
test('Captcha load error calls error function', () => {
|
||||
const props = {
|
||||
onRegistrationError: jest.fn()
|
||||
};
|
||||
// Set this to null to force an error.
|
||||
global.grecaptcha = null;
|
||||
const wrapper = shallowWithIntl(
|
||||
<EmailStep
|
||||
{...props}
|
||||
/>);
|
||||
|
||||
const formikWrapper = wrapper.dive();
|
||||
formikWrapper.instance().onCaptchaLoad();
|
||||
expect(props.onRegistrationError).toHaveBeenCalledWith('registation.troubleReload');
|
||||
});
|
||||
|
||||
test('validateEmail test email empty', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<EmailStep />);
|
||||
|
@ -123,6 +158,7 @@ describe('EmailStep test', () => {
|
|||
const val = formikWrapper.instance().validateEmail('');
|
||||
expect(val).toBe('general.required');
|
||||
});
|
||||
|
||||
test('validateEmail test email null', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<EmailStep />);
|
||||
|
@ -130,6 +166,7 @@ describe('EmailStep test', () => {
|
|||
const val = formikWrapper.instance().validateEmail(null);
|
||||
expect(val).toBe('general.required');
|
||||
});
|
||||
|
||||
test('validateEmail test email undefined', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<EmailStep />);
|
||||
|
|
|
@ -126,6 +126,19 @@ describe('JoinFlow', () => {
|
|||
expect(joinFlowInstance.props.refreshSession).not.toHaveBeenCalled();
|
||||
expect(joinFlowInstance.state.registrationError).toBe('registration.generalError (400)');
|
||||
});
|
||||
test('handleRegistrationError with no message ', () => {
|
||||
const joinFlowInstance = getJoinFlowWrapper().instance();
|
||||
joinFlowInstance.setState({});
|
||||
joinFlowInstance.handleRegistrationError();
|
||||
expect(joinFlowInstance.state.registrationError).toBe('registration.generalError');
|
||||
});
|
||||
|
||||
test('handleRegistrationError with message ', () => {
|
||||
const joinFlowInstance = getJoinFlowWrapper().instance();
|
||||
joinFlowInstance.setState({});
|
||||
joinFlowInstance.handleRegistrationError('my message');
|
||||
expect(joinFlowInstance.state.registrationError).toBe('my message');
|
||||
});
|
||||
|
||||
test('handleAdvanceStep', () => {
|
||||
const joinFlowInstance = getJoinFlowWrapper().instance();
|
||||
|
|
34
test/unit/components/modal.test.jsx
Normal file
|
@ -0,0 +1,34 @@
|
|||
const React = require('react');
|
||||
const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
|
||||
const Modal = require('../../../src/components/modal/base/modal.jsx');
|
||||
|
||||
describe('Modal', () => {
|
||||
test('Close button not shown when showCloseButton false', () => {
|
||||
const showClose = true;
|
||||
const component = shallowWithIntl(
|
||||
<Modal
|
||||
showCloseButton={showClose}
|
||||
/>
|
||||
);
|
||||
expect(component.find('div.modal-content-close').exists()).toBe(true);
|
||||
expect(component.find('img.modal-content-close-img').exists()).toBe(true);
|
||||
});
|
||||
test('Close button shown by default', () => {
|
||||
const component = shallowWithIntl(
|
||||
<Modal />
|
||||
);
|
||||
expect(component.find('div.modal-content-close').exists()).toBe(true);
|
||||
expect(component.find('img.modal-content-close-img').exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('Close button shown when showCloseButton true', () => {
|
||||
const showClose = false;
|
||||
const component = shallowWithIntl(
|
||||
<Modal
|
||||
showCloseButton={showClose}
|
||||
/>
|
||||
);
|
||||
expect(component.find('div.modal-content-close').exists()).toBe(false);
|
||||
expect(component.find('img.modal-content-close-img').exists()).toBe(false);
|
||||
});
|
||||
});
|