diff --git a/src/routes.json b/src/routes.json index 491674e4f..1a7b35022 100644 --- a/src/routes.json +++ b/src/routes.json @@ -238,6 +238,13 @@ "view": "scratch_1.4/scratch_1.4", "title": "Scratch 1.4" }, + { + "name": "scratch2", + "pattern": "^/download/scratch2/?$", + "routeAlias": "/download/scratch2", + "view": "download/scratch2/download", + "title": "Scratch 2.0" + }, { "name": "search", "pattern": "^/search/:projects/?$", diff --git a/src/views/download/download.jsx b/src/views/download/download.jsx index e4a6bef7c..39cbeec53 100644 --- a/src/views/download/download.jsx +++ b/src/views/download/download.jsx @@ -1,16 +1,17 @@ -const FormattedHTMLMessage = require('react-intl').FormattedHTMLMessage; const FormattedMessage = require('react-intl').FormattedMessage; const injectIntl = require('react-intl').injectIntl; const intlShape = require('react-intl').intlShape; const React = require('react'); -const api = require('../../lib/api'); const FlexRow = require('../../components/flex-row/flex-row.jsx'); -const SubNavigation = require('../../components/subnavigation/subnavigation.jsx'); -const TitleBanner = require('../../components/title-banner/title-banner.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 OSChooser = require('../../components/os-chooser/os-chooser.jsx'); require('./download.scss'); require('../../components/forms/button.scss'); @@ -18,246 +19,219 @@ require('../../components/forms/button.scss'); class Download extends React.Component { constructor (props) { super(props); + 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 = { - swfVersion: '' + OS: detectedOS }; } - componentDidMount () { - let uri = '/scratchr2/static/sa/version.xml'; - if (this.props.intl.locale === 'pt-br') { - uri = '/scratchr2/static/sa/pt-br/version.xml'; - } - api({ - host: '', - uri: uri, - responseType: 'string' - }, (err, body, res) => { - if (err || res.statusCode >= 400) { - return this.setState({ - swfVersion: -1 - }); - } - - const doc = new DOMParser().parseFromString(body, 'text/xml'); - return this.setState({ - swfVersion: doc.getElementsByTagName('versionNumber')[0].childNodes[0].nodeValue - }); + onSetOS (os) { + this.setState({ + OS: os }); } - render () { - let downloadPath = '/scratchr2/static/sa/Scratch-'; - let downloadUrls = null; - if (this.props.intl.locale === 'pt-br') { - downloadPath = '/scratchr2/static/sa/pt-br/Scratch-'; - } - if (this.state.swfVersion.length > 0 && this.state.swfVersion !== -1) { - downloadUrls = { - mac: `${downloadPath}${this.state.swfVersion}.dmg`, - mac105: `${downloadPath}${this.state.swfVersion}.air`, - windows: `${downloadPath}${this.state.swfVersion}.exe` - }; - } + render () { return (
- -
-

- -

-

- -

-
-
- - -
  • - -
  • -
    - -
  • - -
  • -
    - -
  • - -
  • -
    - -
  • - -
  • -
    -
    -
    -
    -
    -
    -
    -

    - -

    - -
    -
    -

    {'1'}

    -
    -

    -

    - -
    -
    -
    -

    {'2'}

    -
    -

    -

    - {downloadUrls === null ? [] : [ - - ]} - {this.state.swfVersion === -1 ? [ -

    - -

    - ] : []} -
    -
    -
    -

    {'3'}

    -
    -

    -

    - -
    -
    -
    -
    -
    -
    - -

    -

    - {this.state.swfVersion === -1 ? [] : [ -

    - + + + +

    + {this.props.intl.formatMessage({id: -

    - ]} -

    + + + + + + + + + + + + + + Windows 10+ + + + + macOS 10.13+ + + + + +
    + {this.props.intl.formatMessage({id: +
    + +
    + +
    + +

    + +

    + +
    + + + + + + -
    - -

    -

    -

    -
    - -
    - -

    -

    -

    -

    -

    - + - - -
    -
    + + {this.state.OS === OS_ENUM.WINDOWS ? + : + + } + + +
    + +
    + +
    +
    +
    +
    + +

    + +

    + +

    + +

    +

    + +

    + +

    + +

    +

    + +

    + +
    +
    +
    + +

    + +

    +

    + +

    + +
    + + + +

    + + + + +

    +
    +
    + + + +

    + + + + +

    +
    +
    +
    ); + } } - Download.propTypes = { intl: intlShape + }; const WrappedDownload = injectIntl(Download); diff --git a/src/views/download/download.scss b/src/views/download/download.scss index 146508a6f..f21af4a52 100644 --- a/src/views/download/download.scss +++ b/src/views/download/download.scss @@ -6,123 +6,168 @@ } .download { - .title-banner { - &.masthead { - margin-bottom: 0; - background-color: $ui-blue-dark; - padding-bottom: 0; + .title { + margin-bottom: 1rem; + font-size: 2rem; + } - h1 { - margin: 0 0 2rem 0; - text-align: left; - color: $ui-white; - } + .legacy-link { + display: flex; + } - p { - margin: 0; - text-align: left; - color: $ui-white; + .download-button { + display: inline-block; + margin: .5em 0; + border: 0; + border-radius: 8px; + background-color: $ui-blue; + cursor: pointer; + padding: 1rem; + color: $ui-white; + font-size: 1rem; + } - a { - border-bottom: 1px solid $ui-white; + .download-header { + background-color: $ui-blue; + padding: 4rem 0; + color: $ui-white; + + + .title { + color: $ui-white; + } + + .inner { + justify-content: space-between; + flex-wrap: nowrap; + } + + .download-info { + padding-right: $cols1; + max-width: $cols6 + ($gutter / $em); + align-items: flex-start; + + .download-copy { + margin-bottom: 5rem; + align-items: flex-start; + + .download-title { + display: flex; + margin-bottom: 2rem; color: $ui-white; + font-size: 2rem; + } + + .icon { + padding-right: .5rem; + max-height: 100%; + align-self: center; + } + + .download-description { + line-height: 1.7rem; + font-size: 1.2rem; } } - .band { - margin-top: 2rem; - background-color: $ui-white-15percent; - padding: 1rem 0; - } + .download-requirements-container { + font-weight: 500; + align-items: flex-start; - .sub-nav { - text-align: left; - justify-content: flex-start; - - li { - margin: 0 .5rem 0 0; + .requirements-header { + margin-bottom: 1.5rem; } + + .download-requirements { + justify-content: space-between; + } + + .download-requirements span { + display: flex; + margin-right: 1rem; + font-size: 15px; + align-items: center; + } + + .download-requirements span img { + padding-right: .5rem; + } + } + } + + .download-image { + width: 100%; + max-width: $cols6; + + img { + max-width: 100%; + max-height: 100%; } } } - .sub-nav-item { - margin: .5rem; - } - - .callout { - text-align: center; - } - - .download-content { - padding-bottom: 2rem; + .install-scratch { + padding: 2rem 0; + + .inner { + align-items: flex-start; + } + + .downloads-container { + text-align: center; + } + + .store-badge { + display: block; + width: 150px; + height: 80px; + } } - .three-col-row { - align-items: flex-start; + .download-section { + padding: 4rem 0; + + .inner { + align-items: flex-start; + } } - .installation { - background-color: $ui-gray; - padding: 2rem; + .blue { + background-color: $ui-blue-10percent; } - .installation-column { - max-width: $cols4; - text-align: center; + .faq { + p { + margin-bottom: 1.25rem; + margin-left: 0; + max-width: $cols8; + text-align: left; + } + + .faq-question { + margin-bottom: 0; + font-size: 1.4rem; + } + } + + .older-version { + padding-right: 24px; p { - margin-right: .5rem; - margin-left: .5rem; + line-height: normal; + color: $link-blue; + font-weight: 600; } - } - .installation-column-number { - margin: 2rem auto; - border: 2px solid $active-gray; - border-radius: 2rem; - background-color: $ui-blue; - width: 3.75rem; - height: 3.75rem; - } - - .installation-column-number-text { - text-align: center; - line-height: 1.8em; - color: $type-white; - } - - .installation-downloads { - padding-left: 0; - list-style: none; - } - - .installation-downloads-item { - margin: .25rem; - padding: 0; - text-align: center; - } - - section { - margin-bottom: 2rem; - } - - .mod-link { - color: $ui-white; - } - - @media #{$small} { - .inner { - .installation-column { - max-width: 100%; - } + .little-arrow { + padding-left: 2px; } - } - @media #{$intermediate-and-smaller} { - .three-col-row { - flex-direction: column; - align-items: center; + .screenshot { + margin-top: 1rem; + $img-border: rgba(0, 0, 0, .05); + border: 2px solid $img-border; + border-radius: 8px; } } } diff --git a/src/views/download/l10n.json b/src/views/download/l10n.json index 3c5144115..a1db7fb93 100644 --- a/src/views/download/l10n.json +++ b/src/views/download/l10n.json @@ -1,32 +1,25 @@ { - "download.title": "Scratch 2.0 Offline Editor", - "download.intro": "You can install the Scratch 2.0 editor to work on projects without an internet connection. This version will work on Windows and MacOS.", - "download.introMac": "Note for Mac Users: the latest version of Scratch 2.0 Offline requires Adobe AIR 20. To upgrade to Adobe AIR 20 manually, go here.", - "download.installation": "Installation", - "download.airTitle": "Adobe AIR", - "download.airBody": "If you don't already have it, download and install the latest Adobe AIR", - "download.macOSX": "Mac OS X", - "download.macOlder": "Mac OS 10.5 & Older", - "download.windows": "Windows", - "download.download": "Download", - "download.offlineEditorTitle": "Scratch Offline Editor", - "download.offlineEditorBody": "Next download and install the Scratch 2.0 Offline Editor", - "download.supportMaterialsTitle": "Support Materials", - "download.supportMaterialsBody": "Need some help getting started? Here are some helpful resources.", - "download.starterProjects": "Starter Projects", - "download.gettingStarted": "Getting Started Guide", - "download.scratchCards": "Scratch Cards", - "download.updatesTitle": "Updates", - "download.updatesBody": "The Offline Editor can update itself (with user permission). It will check for updates at startup or you can use the \"Check for updates\" command in the file menu.", - "download.currentVersion": "The current version is {version}.", - "download.otherVersionsTitle": "Other Versions of Scratch", - "download.otherVersionsOlder": "If you have an older computer, or cannot install the Scratch 2.0 offline editor, you can try installing Scratch 1.4.", - "download.otherVersionsAdmin": "If you are a network administrator: a Scratch 2.0 MSI has been created and maintained by a member of the community and hosted for public download here.", - "download.knownIssuesTitle": "Known issues", - "download.knownIssuesOne": "If your offline editor is crashing directly after Scratch is opened, install the Scratch 2 offline editor again (see step 2 above). This issue is due to a bug introduced in Adobe AIR version 14 (released April 2014).", - "download.knownIssuesTwo": "Graphic effects blocks (in \"Looks\") may slow down projects due to a known Flash bug.", - "download.knownIssuesThree": "The backpack is not yet available.", - "download.knownIssuesFour": "On Mac OS you may see a prompt indicating that \"Scratch 2 is trying to install a new helper tool\" and asking for your user name and password. We are currently investigating a solution to this problem.", - "download.reportBugs": "Report Bugs and Glitches", - "download.notAvailable": "Hmm, editor downloads are not available right now - please refresh the page to try again." + "download.title": "Scratch 3.0 Desktop", + "download.intro": "You can install the Scratch 3.0 editor to work on projects without an internet connection. This version will work on Windows and MacOS.", + "download.requirements": "Requirements", + "download.imgAltDownloadIllustration" : "Scratch 3.0 Desktop screenshot", + "download.installHeaderTitle": "Install Scratch Desktop", + "download.downloadAndInstall": "Download and install Scratch Desktop", + "download.troubleshootingTitle": "FAQ", + "download.startScratchDesktop": "Start Scratch Desktop", + "download.howDoIInstall": "How do I install Scratch Desktop?", + "download.whenSupportLinux": "When will you have Scratch Desktop for Linux?", + "download.supportLinuxAnswer" : "Scratch Desktop on Linux is currently not supported. We are working with partners and the open-source community to determine if there is a way we can support Linux in the future. Stay tuned!", + "download.supportChromeOS" : "When will you have Scratch Desktop for ChromeOS?", + "download.supportChromeOSAnswer": "Scratch Desktop for ChromeOS is not yet available. We are working on it and expect to release later in 2019.", + "download.olderVersionsTitle" : "Older Versions", + "download.olderVersions": "Looking for an older version of Scratch Desktop?", + "download.scratch1-4Desktop" : "Scratch 1.4 Desktop", + "download.scratch2Desktop" : "Scratch 2.0 Desktop", + "download.cannotAccessMacStore" : "What if I can't access the Mac App Store?", + "download.cannotAccessWindowsStore" : "What if I can't access the Microsoft Store?", + "download.appstoreAccessAnswer" : "You can download Scratch Desktop directly to your computer by {directDownloadLink}.", + "download.directDownloadText" : "clicking here", + "download.macMoveToApplications" : "Move Scratch Desktop to your Applications folder and start Scratch Desktop.", + "download.winMoveToApplications" : "Run it." } diff --git a/src/views/download/scratch2/download.jsx b/src/views/download/scratch2/download.jsx new file mode 100644 index 000000000..edbf5afe2 --- /dev/null +++ b/src/views/download/scratch2/download.jsx @@ -0,0 +1,265 @@ +const FormattedHTMLMessage = require('react-intl').FormattedHTMLMessage; +const FormattedMessage = require('react-intl').FormattedMessage; +const injectIntl = require('react-intl').injectIntl; +const intlShape = require('react-intl').intlShape; +const React = require('react'); + +const api = require('../../../lib/api'); +const FlexRow = require('../../../components/flex-row/flex-row.jsx'); +const SubNavigation = require('../../../components/subnavigation/subnavigation.jsx'); +const TitleBanner = require('../../../components/title-banner/title-banner.jsx'); + +const Page = require('../../../components/page/www/page.jsx'); +const render = require('../../../lib/render.jsx'); + +require('./download.scss'); +require('../../../components/forms/button.scss'); + +class Download extends React.Component { + constructor (props) { + super(props); + this.state = { + swfVersion: '' + }; + } + componentDidMount () { + let uri = '/scratchr2/static/sa/version.xml'; + if (this.props.intl.locale === 'pt-br') { + uri = '/scratchr2/static/sa/pt-br/version.xml'; + } + + api({ + host: '', + uri: uri, + responseType: 'string' + }, (err, body, res) => { + if (err || res.statusCode >= 400) { + return this.setState({ + swfVersion: -1 + }); + } + + const doc = new DOMParser().parseFromString(body, 'text/xml'); + return this.setState({ + swfVersion: doc.getElementsByTagName('versionNumber')[0].childNodes[0].nodeValue + }); + }); + } + render () { + let downloadPath = '/scratchr2/static/sa/Scratch-'; + let downloadUrls = null; + if (this.props.intl.locale === 'pt-br') { + downloadPath = '/scratchr2/static/sa/pt-br/Scratch-'; + } + if (this.state.swfVersion.length > 0 && this.state.swfVersion !== -1) { + downloadUrls = { + mac: `${downloadPath}${this.state.swfVersion}.dmg`, + mac105: `${downloadPath}${this.state.swfVersion}.air`, + windows: `${downloadPath}${this.state.swfVersion}.exe` + }; + } + + return ( +
    + +
    +

    + +

    +

    + +

    +
    +
    + + +
  • + +
  • +
    + +
  • + +
  • +
    + +
  • + +
  • +
    + +
  • + +
  • +
    +
    +
    +
    +
    +
    +
    +

    + +

    + +
    +
    +

    {'1'}

    +
    +

    +

    + +
    +
    +
    +

    {'2'}

    +
    +

    +

    + {downloadUrls === null ? [] : [ + + ]} + {this.state.swfVersion === -1 ? [ +

    + +

    + ] : []} +
    +
    +
    +

    {'3'}

    +
    +

    +

    + +
    +
    +
    +
    +
    +
    + +

    +

    + {this.state.swfVersion === -1 ? [] : [ +

    + +

    + ]} +
    + +
    + +

    +

    +

    +
    + +
    + +

    +

    +

    +

    +

    + + + +
    +
    +
    +
    + ); + } +} + +Download.propTypes = { + intl: intlShape +}; + +const WrappedDownload = injectIntl(Download); + +render(, document.getElementById('app')); diff --git a/src/views/download/scratch2/download.scss b/src/views/download/scratch2/download.scss new file mode 100644 index 000000000..66ee5b070 --- /dev/null +++ b/src/views/download/scratch2/download.scss @@ -0,0 +1,128 @@ +@import "../../../colors"; +@import "../../../frameless"; + +#view { + padding: 0; +} + +.download { + .title-banner { + &.masthead { + margin-bottom: 0; + background-color: $ui-blue-dark; + padding-bottom: 0; + + h1 { + margin: 0 0 2rem 0; + text-align: left; + color: $ui-white; + } + + p { + margin: 0; + text-align: left; + color: $ui-white; + + a { + border-bottom: 1px solid $ui-white; + color: $ui-white; + } + } + + .band { + margin-top: 2rem; + background-color: $ui-white-15percent; + padding: 1rem 0; + } + + .sub-nav { + text-align: left; + justify-content: flex-start; + + li { + margin: 0 .5rem 0 0; + } + } + } + } + + .sub-nav-item { + margin: .5rem; + } + + .callout { + text-align: center; + } + + .download-content { + padding-bottom: 2rem; + } + + .three-col-row { + align-items: flex-start; + } + + .installation { + background-color: $ui-gray; + padding: 2rem; + } + + .installation-column { + max-width: $cols4; + text-align: center; + + p { + margin-right: .5rem; + margin-left: .5rem; + } + } + + .installation-column-number { + margin: 2rem auto; + border: 2px solid $active-gray; + border-radius: 2rem; + background-color: $ui-blue; + width: 3.75rem; + height: 3.75rem; + } + + .installation-column-number-text { + text-align: center; + line-height: 1.8em; + color: $type-white; + } + + .installation-downloads { + padding-left: 0; + list-style: none; + } + + .installation-downloads-item { + margin: .25rem; + padding: 0; + text-align: center; + } + + section { + margin-bottom: 2rem; + } + + .mod-link { + color: $ui-white; + } + + @media #{$small} { + .inner { + .installation-column { + max-width: 100%; + } + } + } + + @media #{$intermediate-and-smaller} { + .three-col-row { + flex-direction: column; + align-items: center; + } + } +} diff --git a/src/views/download/scratch2/l10n.json b/src/views/download/scratch2/l10n.json new file mode 100644 index 000000000..3c5144115 --- /dev/null +++ b/src/views/download/scratch2/l10n.json @@ -0,0 +1,32 @@ +{ + "download.title": "Scratch 2.0 Offline Editor", + "download.intro": "You can install the Scratch 2.0 editor to work on projects without an internet connection. This version will work on Windows and MacOS.", + "download.introMac": "Note for Mac Users: the latest version of Scratch 2.0 Offline requires Adobe AIR 20. To upgrade to Adobe AIR 20 manually, go here.", + "download.installation": "Installation", + "download.airTitle": "Adobe AIR", + "download.airBody": "If you don't already have it, download and install the latest Adobe AIR", + "download.macOSX": "Mac OS X", + "download.macOlder": "Mac OS 10.5 & Older", + "download.windows": "Windows", + "download.download": "Download", + "download.offlineEditorTitle": "Scratch Offline Editor", + "download.offlineEditorBody": "Next download and install the Scratch 2.0 Offline Editor", + "download.supportMaterialsTitle": "Support Materials", + "download.supportMaterialsBody": "Need some help getting started? Here are some helpful resources.", + "download.starterProjects": "Starter Projects", + "download.gettingStarted": "Getting Started Guide", + "download.scratchCards": "Scratch Cards", + "download.updatesTitle": "Updates", + "download.updatesBody": "The Offline Editor can update itself (with user permission). It will check for updates at startup or you can use the \"Check for updates\" command in the file menu.", + "download.currentVersion": "The current version is {version}.", + "download.otherVersionsTitle": "Other Versions of Scratch", + "download.otherVersionsOlder": "If you have an older computer, or cannot install the Scratch 2.0 offline editor, you can try installing Scratch 1.4.", + "download.otherVersionsAdmin": "If you are a network administrator: a Scratch 2.0 MSI has been created and maintained by a member of the community and hosted for public download here.", + "download.knownIssuesTitle": "Known issues", + "download.knownIssuesOne": "If your offline editor is crashing directly after Scratch is opened, install the Scratch 2 offline editor again (see step 2 above). This issue is due to a bug introduced in Adobe AIR version 14 (released April 2014).", + "download.knownIssuesTwo": "Graphic effects blocks (in \"Looks\") may slow down projects due to a known Flash bug.", + "download.knownIssuesThree": "The backpack is not yet available.", + "download.knownIssuesFour": "On Mac OS you may see a prompt indicating that \"Scratch 2 is trying to install a new helper tool\" and asking for your user name and password. We are currently investigating a solution to this problem.", + "download.reportBugs": "Report Bugs and Glitches", + "download.notAvailable": "Hmm, editor downloads are not available right now - please refresh the page to try again." +} diff --git a/static/images/download/download.png b/static/images/download/download.png new file mode 100644 index 000000000..bcf66a45b Binary files /dev/null and b/static/images/download/download.png differ diff --git a/static/images/download/placeholder.png b/static/images/download/placeholder.png new file mode 100644 index 000000000..2d54b4d08 Binary files /dev/null and b/static/images/download/placeholder.png differ diff --git a/static/images/download/scratch1-4.png b/static/images/download/scratch1-4.png new file mode 100644 index 000000000..58d07f8bb Binary files /dev/null and b/static/images/download/scratch1-4.png differ diff --git a/static/images/download/scratch2.png b/static/images/download/scratch2.png new file mode 100644 index 000000000..f23d17f39 Binary files /dev/null and b/static/images/download/scratch2.png differ diff --git a/static/svgs/download/r-arrow.svg b/static/svgs/download/r-arrow.svg new file mode 100644 index 000000000..142288cb3 --- /dev/null +++ b/static/svgs/download/r-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file