mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-27 01:25:52 -05:00
commit
96a8775482
48 changed files with 668 additions and 449 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,6 +10,7 @@ npm-*
|
|||
|
||||
# Locales
|
||||
/locales
|
||||
/intl
|
||||
|
||||
# Elastic Beanstalk Files
|
||||
.elasticbeanstalk/*
|
||||
|
|
|
@ -32,7 +32,10 @@ deploy:
|
|||
env: scratch-www-staging
|
||||
on:
|
||||
repo: LLK/scratch-www
|
||||
branch: develop
|
||||
branch:
|
||||
- develop
|
||||
- hotfix/*
|
||||
- release/*
|
||||
- provider: elasticbeanstalk
|
||||
access_key_id: $EB_AWS_ACCESS_KEY_ID
|
||||
secret_access_key: $EB_AWS_SECRET_ACCESS_KEY
|
||||
|
|
35
CONTRIBUTING.md
Normal file
35
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
### Where am I? ###
|
||||
Physically? No idea.
|
||||
|
||||
Digitally? You’re at Scratch’s open source Web Client!
|
||||
|
||||
At Scratch, we’re working to update our UI to use a new codebase, which will be contained in this repository. The transition from existing to new codebase is an ongoing process, and we love to have people in the Scratch and Open Source communities help us along the way, and even afterwards as we develop new features for Scratch here.
|
||||
|
||||
|
||||
### Who and what will I find here? ###
|
||||
We are always excited to have people join us in working to make Scratch a wonderful place for people of all ages to make projects together. If you’re new here, and looking to jump into our wonderful community, we have some wonderful resources for you to take a look at:
|
||||
|
||||
* [README](https://github.com/LLK/scratch-www/blob/develop/README.md) (if you’re to read only one me in this repo, make it this one – it has all of the necessary information for getting a local Scratch UI running on your machine!)
|
||||
* [Community Guidelines](https://github.com/LLK/scratch-www/wiki/Community-Guidelines) (we find it important to maintain a constructive and welcoming community, just like on Scratch)
|
||||
* [Issues](https://github.com/LLK/scratch-www/issues) – where we keep track of all the things that need fixin’ on the website
|
||||
Road map
|
||||
|
||||
Beyond this repo, there are also some other resources that you might want to take a look at:
|
||||
[Scratch](https://scratch.mit.edu/) (the thing we work on)
|
||||
[Open Source forum](https://scratch.mit.edu/discuss/49/) on Scratch (talk about the thing we work on on the thing we work on. so meta.)
|
||||
[Bugs & Glitches forum](https://scratch.mit.edu/discuss/3/) on Scratch (where mosquitoes and dei ex machina congregate)
|
||||
[Advanced Topics forum](https://scratch.mit.edu/discuss/31/) on Scratch (like Topics, but more complex-y)
|
||||
|
||||
|
||||
### I wanna contribute! ###
|
||||
Sweet! Here are some ways you can contribute:
|
||||
* [Report bugs](https://github.com/LLK/scratch-www/wiki/Reporting-Bugs)
|
||||
* [Work on bugs](https://github.com/LLK/scratch-www/wiki/Workflow-for-Repo-Contributions)
|
||||
* Make sure to check out how to [assign yourself bugs](https://github.com/LLK/scratch-www/wiki/Assigning-Yourself-Bugs) too.
|
||||
|
||||
|
||||
We’re currently building Scratch using [React](https://facebook.github.io/react/) and [SCSS](http://sass-lang.com/documentation/file.SASS_REFERENCE.html). Here are some resources to help you get acquainted with how we’re working on the Scratch codebase:
|
||||
* [Style Guide](https://github.com/LLK/scratch-www/wiki/Style-Guide)
|
||||
* [Testing Guide](https://github.com/LLK/scratch-www/wiki/Testing-Guide)
|
||||
* [Localization Guide](https://github.com/LLK/scratch-www/wiki/Localization-Guide)
|
||||
* [Map of the repository](https://github.com/LLK/scratch-www/wiki/Repo-Map)
|
13
LICENSE.md
Normal file
13
LICENSE.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
Copyright 2015 Massachusetts Institute of Technology
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
6
Makefile
6
Makefile
|
@ -18,8 +18,9 @@ build:
|
|||
|
||||
clean:
|
||||
rm -rf ./build
|
||||
rm -rf ./intl
|
||||
mkdir -p build
|
||||
mkdir -p locales
|
||||
mkdir -p intl
|
||||
|
||||
|
||||
deploy:
|
||||
|
@ -38,7 +39,7 @@ tag:
|
|||
echo $(GIT_VERSION) > ./build/version.txt
|
||||
|
||||
translations:
|
||||
./lib/bin/build-locales locales/translations.json
|
||||
./bin/build-locales intl
|
||||
|
||||
webpack:
|
||||
$(WEBPACK) --bail
|
||||
|
@ -63,7 +64,6 @@ lint:
|
|||
$(ESLINT) ./*.js
|
||||
$(ESLINT) ./server/*.js
|
||||
$(ESLINT) ./src/*.js
|
||||
$(ESLINT) ./src/*.jsx
|
||||
$(ESLINT) ./src/mixins/*.jsx
|
||||
$(ESLINT) ./src/views/**/*.jsx
|
||||
$(ESLINT) ./src/components/**/*.jsx
|
||||
|
|
13
README.md
13
README.md
|
@ -3,6 +3,9 @@
|
|||
|
||||
[![Build Status](https://magnum.travis-ci.com/LLK/scratch-www.svg?token=xzzHj4ct3SyBTpeqxnx1)](https://magnum.travis-ci.com/LLK/scratch-www)
|
||||
|
||||
### Before Getting Started
|
||||
* make sure you have node and npm [installed](https://docs.npmjs.com/getting-started/installing-node)
|
||||
|
||||
### To Build
|
||||
```bash
|
||||
npm install
|
||||
|
@ -16,6 +19,10 @@ npm start
|
|||
|
||||
During development, `npm start` watches any update you make to files in either `./static` or `./src` and triggers a rebuild of the project. In development the build is stored in memory, and not served from the `./build` directory.
|
||||
|
||||
When running `npm start`, here are some important log messages to keep an eye out for:
|
||||
* `webpack: bundle is now VALID.` – the bundle has been loaded into memory and is now viewable in the browser. This will show up both once `npm start` has completed its setup, and also once updates you make to files have been re-compiled for viewing in the browser.
|
||||
* `webpack: bundle is now INVALID.` – if you see this, then it means you have made updates to files that are still being compiled for browser viewing. Pages will still be viewable, but they will not see any updates you made yet.
|
||||
|
||||
Once running, open `http://localhost:8333` in your browser. If you wish to have the server reload automatically, you can install either [nodemon](https://github.com/remy/nodemon) or [forever](https://github.com/foreverjs/forever).
|
||||
|
||||
### To stop
|
||||
|
@ -30,7 +37,9 @@ Use `^C` to stop the node process `npm start` starts.
|
|||
| `API_HOST` | `https://api.scratch.mit.edu` | Hostname for API requests |
|
||||
| `NODE_ENV` | `null` | If not `production`, app acts like development |
|
||||
| `PORT` | `8333` | Port for devserver (http://localhost:XXXX) |
|
||||
| `FALLBACK` | `''` | Pass-through location for scratchr2 |
|
||||
| `FALLBACK` | `''` | Pass-through location for old site |
|
||||
|
||||
**NOTE:** Because by default `API_HOST=https://api.scratch.mit.edu`, please be aware that, by default, you will be seeing and interacting with real data on the Scratch website.
|
||||
|
||||
### To Test
|
||||
```bash
|
||||
|
@ -47,3 +56,5 @@ Most of the issues we have currently revolve around the use of `FALLBACK`. This
|
|||
Setting `FALLBACK=https://scratch.mit.edu` allows the web client to retrieve data from the Scratch website in your development environment. However, because of security concerns, trying to send data to Scratch through your development environment won't work. This means the following things will be broken for the time being:
|
||||
* Login on the splash page (*In the process of being fixed*)
|
||||
* Some update attempts to production data made through a development version of the web client
|
||||
|
||||
Additionally, if you set `FALLBACK=https://scratch.mit.edu`, be aware that clicking on links to parts of the website not yet migrated over (currently such as `Explore`, `Discuss`, `Profile`, etc.) will take you to the Scratch website itself.
|
||||
|
|
170
bin/build-locales
Executable file
170
bin/build-locales
Executable file
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
Converts the existing .po translation files in the module to JSON files.
|
||||
Requires po2json in order to work. Takes as input a directory
|
||||
in which to store the resulting json translation files.
|
||||
|
||||
Takes in as an argument an output directory to put translation files.
|
||||
Searches for files named `l10n.json` in the `src/views/` directory to get
|
||||
template english strings (as well as the general template at `src/l10n.json`).
|
||||
|
||||
It compiles the template strings into a flat object that is compared against the
|
||||
translations in the .po files from the `scratchr2_translations` dependency, using
|
||||
an md5 of the template string without whitespace, and an md5 of the .po msgid string
|
||||
without whitespace.
|
||||
|
||||
The output files are javascript files that declare objects by locale. Each locale
|
||||
has a sub-object with FormattedMessage ids as keys, and translated strings as
|
||||
values. If no translation was found for a string, the default english will be the
|
||||
value.
|
||||
|
||||
Output Example:
|
||||
'''
|
||||
var message = {
|
||||
en: {
|
||||
'general.inAWorld': 'In a world, where bears are invisible...',
|
||||
'general.question': 'Are there bears here?',
|
||||
'general.answer': 'I dunno, but there could be...'
|
||||
},
|
||||
es: {
|
||||
'general.inAWorld': 'En un mundo, donde hay osos invisibles',
|
||||
'general.question': 'Are there bears here?',
|
||||
'general.answer': 'No sé, pero es posible...'
|
||||
}
|
||||
}
|
||||
'''
|
||||
*/
|
||||
var fs = require('fs');
|
||||
var glob = require('glob');
|
||||
var merge = require('lodash.merge');
|
||||
var path = require('path');
|
||||
var po2icu = require('po2icu');
|
||||
|
||||
var localeCompare = require('./lib/locale-compare');
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Main script
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
var args = process.argv.slice(2);
|
||||
|
||||
if (!args.length) {
|
||||
process.stdout.write('A destination directory must be specified.');
|
||||
process.exit(1);
|
||||
}
|
||||
var verbose = false;
|
||||
if (args.length > 1) {
|
||||
verbose = (args[1] === '-v') ? true : false;
|
||||
}
|
||||
|
||||
var poUiDir = path.resolve(__dirname, '../node_modules/scratchr2_translations/ui');
|
||||
var outputDir = path.resolve(__dirname, '../', args[0]);
|
||||
try {
|
||||
fs.accessSync(outputDir, fs.F_OK);
|
||||
} catch (err) {
|
||||
// Doesn't exist - create it.
|
||||
fs.mkdirSync(outputDir);
|
||||
}
|
||||
|
||||
// get global locale strings first.
|
||||
var globalTemplateFile = path.resolve(__dirname, '../src/l10n.json');
|
||||
// message key with english string values (i.e. default values)
|
||||
var generalIds = JSON.parse(fs.readFileSync(globalTemplateFile, 'utf8'));
|
||||
var viewLocales = {};
|
||||
var generalLocales = {
|
||||
en: generalIds
|
||||
};
|
||||
|
||||
// FormattedMessage id with english string as value. Use for default values in translations
|
||||
// Sample structure: { 'general-general.blah': 'blah', 'about-about.blah': 'blahblah' }
|
||||
var idsWithICU = {};
|
||||
|
||||
// reverse (i.e. english string with message key as the value) object for searching po files.
|
||||
// Sample structure: { 'blah': 'general-general.blah', 'blahblah': 'about-about.blah' }
|
||||
var icuWithIds = {};
|
||||
|
||||
for (var id in generalIds) {
|
||||
idsWithICU['general-' + id] = generalIds[id];
|
||||
icuWithIds[generalIds[id]] = 'general-' + id;
|
||||
}
|
||||
|
||||
// start with all views, and remove localized ones as they are iterated over
|
||||
var views = glob.sync(path.resolve(__dirname, '../src/views/*'));
|
||||
for (var i = 0; i < views.length; i++) {
|
||||
views[i] = views[i].split('/').pop();
|
||||
}
|
||||
|
||||
// get view-specific locale strings.
|
||||
var files = glob.sync(path.resolve(__dirname, '../src/views/**/l10n.json'));
|
||||
files.forEach(function (file) {
|
||||
var dirPath = file.split('/');
|
||||
dirPath.pop();
|
||||
var view = dirPath.pop();
|
||||
|
||||
var viewIds = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
viewLocales[view] = {
|
||||
en: viewIds
|
||||
};
|
||||
for (var id in viewIds) {
|
||||
idsWithICU[view + '-' + id] = viewIds[id];
|
||||
icuWithIds[viewIds[id]] = view + '-' + id; // add viewName to identifier for later
|
||||
}
|
||||
});
|
||||
|
||||
// md5 of english strings with message key as the value for searching po files.
|
||||
// Sample structure: { 'sdfas43534sdfasdf': 'general-general.blah', 'lkjfasdf4t342asdfa': 'about-about.blah' }
|
||||
var md5WithIds = localeCompare.getMD5Map(icuWithIds);
|
||||
|
||||
// Get ui localization strings first
|
||||
glob(poUiDir + '/*', function (err, files) {
|
||||
if (err) throw new Error(err);
|
||||
|
||||
files.forEach(function (file) {
|
||||
var lang = file.split('/').pop();
|
||||
var jsFile = path.resolve(file, 'LC_MESSAGES/djangojs.po');
|
||||
var pyFile = path.resolve(file, 'LC_MESSAGES/django.po');
|
||||
|
||||
var translations = {};
|
||||
|
||||
try {
|
||||
var jsTranslations = po2icu.poFileToICUSync(lang, jsFile);
|
||||
translations = localeCompare.mergeNewTranslations(translations, jsTranslations, idsWithICU, md5WithIds);
|
||||
} catch (err) {
|
||||
if (verbose) process.stdout.write(lang + ': ' + err + '\n');
|
||||
}
|
||||
|
||||
try {
|
||||
var pyTranslations = po2icu.poFileToICUSync(lang, pyFile);
|
||||
translations = localeCompare.mergeNewTranslations(translations, pyTranslations, idsWithICU, md5WithIds);
|
||||
} catch (err) {
|
||||
if (verbose) process.stdout.write(lang + ': ' + err + '\n');
|
||||
}
|
||||
|
||||
// add new translations to locale object
|
||||
for (var id in translations) {
|
||||
var ids = id.split('-'); // [viewName, stringId]
|
||||
var viewName = ids[0];
|
||||
var stringId = ids[1];
|
||||
if (viewLocales.hasOwnProperty(viewName)) {
|
||||
if (!viewLocales[viewName].hasOwnProperty(lang)) viewLocales[viewName][lang] = {};
|
||||
viewLocales[viewName][lang][stringId] = translations[id];
|
||||
} else {
|
||||
// default to general
|
||||
if (!generalLocales.hasOwnProperty(lang)) generalLocales[lang] = {};
|
||||
generalLocales[lang][stringId] = translations[id];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (var i in views) {
|
||||
var viewTranslations = generalLocales;
|
||||
if (views[i] in viewLocales) {
|
||||
viewTranslations = merge(viewLocales[views[i]], viewTranslations);
|
||||
}
|
||||
var objectString = JSON.stringify(viewTranslations);
|
||||
var fileString = 'window._messages = ' + objectString + ';';
|
||||
fs.writeFileSync(outputDir + '/' + views[i] + '.intl.js', fileString);
|
||||
}
|
||||
});
|
133
en.json
133
en.json
|
@ -1,133 +0,0 @@
|
|||
{
|
||||
"general.accountSettings": "Account settings",
|
||||
"general.about": "About",
|
||||
"general.aboutScratch": "About Scratch",
|
||||
"general.donate": "Donate",
|
||||
"general.collaborators": "Collaborators",
|
||||
"general.community": "Community",
|
||||
"general.contactUs": "Contact Us",
|
||||
"general.copyright": "Scratch is a project of the Lifelong Kindergarten Group at the MIT Media Lab",
|
||||
"general.create": "Create",
|
||||
"general.credits": "Credits",
|
||||
"general.discuss": "Discuss",
|
||||
"general.dmca": "DMCA",
|
||||
"general.explore": "Explore",
|
||||
"general.faq": "FAQ",
|
||||
"general.forParents": "For Parents",
|
||||
"general.forEducators": "For Educators",
|
||||
"general.guidelines": "Community Guidelines",
|
||||
"general.help": "Help",
|
||||
"general.jobs": "Jobs",
|
||||
"general.joinScratch": "Join Scratch",
|
||||
"general.legal": "Legal",
|
||||
"general.learnMore": "Learn More",
|
||||
"general.messages": "Messages",
|
||||
"general.myClasses": "My Classes",
|
||||
"general.myStuff": "My Stuff",
|
||||
"general.offlineEditor": "Offline Editor",
|
||||
"general.profile": "Profile",
|
||||
"general.scratchConference": "Scratch Conference",
|
||||
"general.scratchday": "Scratch Day",
|
||||
"general.scratchEd": "ScratchEd",
|
||||
"general.scratchFoundation": "Scratch Foundation",
|
||||
"general.scratchJr": "ScratchJr",
|
||||
"general.search": "Search",
|
||||
"general.signIn": "Sign in",
|
||||
"general.statistics": "Statistics",
|
||||
"general.support": "Support",
|
||||
"general.tipsWindow": "Tips Window",
|
||||
"general.tipsAnimateYourNameTitle": "Animate Your Name",
|
||||
"general.tipsBearstack": "Bearstack Story",
|
||||
"general.tipsDanceTitle": "Dance, Dance, Dance",
|
||||
"general.tipsGetStarted": "Getting Started",
|
||||
"general.tipsHideAndSeekTitle": "Hide-and-Seek Game",
|
||||
"general.tipsPongGame": "Create a Pong Game",
|
||||
"general.termsOfUse": "Terms of Use",
|
||||
"general.username": "Username",
|
||||
"general.viewAll": "View All",
|
||||
"general.whatsHappening": "What's Happening?",
|
||||
"general.wiki": "Scratch Wiki",
|
||||
|
||||
"about.introOne": "With Scratch, you can program your own interactive stories, games, and animations — and share your creations with others in the online community.",
|
||||
"about.introTwo": "Scratch helps young people learn to think creatively, reason systematically, and work collaboratively — essential skills for life in the 21st century.",
|
||||
"about.introThree": "Scratch is a project of the Lifelong Kindergarten Group at the MIT Media Lab. It is provided free of charge.",
|
||||
"about.introParents": "Info for parents",
|
||||
"about.introEducators": "Info for educators",
|
||||
"about.whoUsesScratch": "Who Uses Scratch?",
|
||||
"about.whoUsesScratchDescription": "Scratch is designed especially for ages 8 to 16, but is used by people of all ages. Millions of people are creating Scratch projects in a wide variety of settings, including homes, schools, museums, libraries, and community centers.",
|
||||
"about.aroundTheWorld": "Around the World",
|
||||
"about.aroundTheWorldDescription": "Scratch is used in more than 150 different countries and available in more than 40 languages. To change languages, click the menu at the bottom of the page. Or, in the Project Editor, click the globe at the top of the page. To add or improve a translation, see the <a href=\"http://wiki.scratch.mit.edu/wiki/How_to_Translate_Scratch\">translation</a> page.",
|
||||
"about.quotes": "Quotes",
|
||||
"about.quotesDescription": "The Scratch Team has received many emails from youth, parents, and educators expressing thanks for Scratch. Want to see what people are saying? You can read a collection of the <a href=\"/info/quotes\">quotes</a> we've received.",
|
||||
"about.learnMore": "Learn More About Scratch",
|
||||
"about.learnMoreHelp": "Scratch Help Page",
|
||||
"about.learnMoreFaq": "Frequently Asked Questions",
|
||||
"about.learnMoreParents": "Information for Parents",
|
||||
"about.learnMoreCredits": "Scratch Credits",
|
||||
"about.literacy": "Learn to Code, Code to Learn",
|
||||
"about.literacyDescription": "The ability to code computer programs is an important part of literacy in today’s society. When people learn to code in Scratch, they learn important strategies for solving problems, designing projects, and communicating ideas.",
|
||||
"about.schools": "Scratch in Schools",
|
||||
"about.schoolsDescription": "Students are learning with Scratch at all levels (from elementary school to college) and across disciplines (such as math, computer science, language arts, social studies). Educators share stories, exchange resources, ask questions, and find people on the <a href=\"http://scratched.gse.harvard.edu/\">ScratchEd website</a>.",
|
||||
"about.research": "Research",
|
||||
"about.researchDescription": "The MIT Scratch Team and collaborators are researching how people use and learn with Scratch (for an introduction, see <a href=\"http://web.media.mit.edu/~mres/papers/Scratch-CACM-final.pdf\">Scratch: Programming for All</a>). Find out more about Scratch <a href=\"/info/research\">research</a> and <a href=\"/statistics\">statistics</a> about Scratch.",
|
||||
"about.support": "Support and Funding",
|
||||
"about.supportDescription": "The Scratch project, initiated in 2003, has received generous support from the National Science Foundation (grants 0325828, 1002713, 1027848, 1019396), Intel Foundation, Microsoft, MacArthur Foundation, LEGO Foundation, Code-to-Learn Foundation, Google, Dell, Fastly, Inversoft, and MIT Media Lab research consortia. If you'd like to support Scratch, please see our <a href=\"https://secure.donationpay.org/scratchfoundation/\">donate page</a>, or contact us at donate@scratch.mit.edu.",
|
||||
|
||||
"footer.about": "About Scratch",
|
||||
"footer.discuss": "Discussion Forums",
|
||||
"footer.help": "Help Page",
|
||||
"footer.scratchFamily": "Scratch Family",
|
||||
|
||||
"hoc.activityCards": "Activity Cards",
|
||||
"hoc.activityCardsHeader": "Activity Cards and Guides",
|
||||
"hoc.activityCardsInfo1": "Want tips and ideas for these Hour of Code™ activities? Use the activity cards to get ideas for creating with Scratch. Facilitator guides can help you plan a group activity.",
|
||||
"hoc.addToStudios": "Add Your Projects to Studios",
|
||||
"hoc.addToStudiosDescription": "These studios include projects created by young people around the world. Take a look at the studios to get inspired - or submit your own projects to the studios!",
|
||||
"hoc.facilitatorGuide": "Facilitator Guide",
|
||||
"hoc.findOutMore": "Find out more",
|
||||
"hoc.helpScratch": "Help with Scratch",
|
||||
"hoc.helpScratchDescription": "You can find tutorials and helpful hints in the <a href=\"/projects/editor/?tip_bar=home\">Tips Window</a>. For more resources, see <a href=\"/help\">Scratch Help</a>",
|
||||
"hoc.moreActivities": "Want More Activities?",
|
||||
"hoc.moreDescription": "Check out these other tutorials. Or remix one of our <a href=\"/starter_projects\">Starter Projects</a>",
|
||||
"hoc.officialNotice": "The \"Hour of Code™\" is a nationwide initiative by <a href=\"http://csedweek.org\">Computer Science Education Week</a> and <a href=\"http://code.org\">Code.org</a> to introduce millions of students to one hour of computer science and computer programming.",
|
||||
"hoc.studioAlice": "Alice in Wonderland Studio",
|
||||
"hoc.studioWeBareBears": "We Bare Bears Studio",
|
||||
"hoc.subTitle": "With Scratch, you can program your own stories, games, and animations — and share them online.",
|
||||
"hoc.tipsDescription": "Need help getting started? Looking for ideas? You can find tutorials and helpful hints in the <a href=\"/projects/editor/?tip_bar=home\">Tips Window</a>",
|
||||
"hoc.title": "Get Creative with Coding",
|
||||
|
||||
"intro.aboutScratch": "ABOUT SCRATCH",
|
||||
"intro.forEducators": "FOR EDUCATORS",
|
||||
"intro.forParents": "FOR PARENTS",
|
||||
"intro.joinScratch": "JOIN SCRATCH",
|
||||
"intro.seeExamples": "SEE EXAMPLES",
|
||||
"intro.tagLine": "Create stories, games, and animations<br /> Share with others around the world",
|
||||
"intro.tryItOut": "TRY IT OUT",
|
||||
"login.forgotPassword": "Forgot Password?",
|
||||
|
||||
"navigation.signOut": "Sign out",
|
||||
|
||||
"news.scratchNews": "Scratch News",
|
||||
|
||||
"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.",
|
||||
"parents.FaqAgeRangeQ": "What is the age range for Scratch?",
|
||||
"parents.FaqResourcesQ": "What resources are available for learning Scratch?",
|
||||
"parents.introDescription": "Scratch is a programming language and an online community where children can program and share interactive media such as stories, games, and animation with people from all over the world. As children create with Scratch, they learn to think creatively, work collaboratively, and reason systematically. Scratch is designed and maintained by the Lifelong Kindergarten group at the MIT Media Lab.",
|
||||
|
||||
"splash.featuredProjects": "Featured Projects",
|
||||
"splash.featuredStudios": "Featured Studios",
|
||||
"splash.projectsCuratedBy": "Projects Curated by",
|
||||
"splash.scratchDesignStudioTitle": "Scratch Design Studio",
|
||||
"splash.visitTheStudio": "Visit the studio",
|
||||
"splash.recentlySharedProjects": "Recently Shared Projects",
|
||||
"splash.projectsByScratchersFollowing": "Projects by Scratchers I'm Following",
|
||||
"splash.projectsLovedByScratchersFollowing": "Projects Loved by Scratchers I'm Following",
|
||||
"splash.projectsInStudiosFollowing": "Projects in Studios I'm Following",
|
||||
"splash.communityRemixing": "What the Community is Remixing",
|
||||
"splash.communityLoving": "What the Community is Loving",
|
||||
|
||||
"welcome.welcomeToScratch": "Welcome to Scratch!",
|
||||
"welcome.learn": "Learn how to make a project in Scratch",
|
||||
"welcome.tryOut": "Try out starter projects",
|
||||
"welcome.connect": "Connect with other Scratchers"
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
Converts the existing .po translation files in the module to JSON files.
|
||||
Requires po2json in order to work. Takes as input a directory
|
||||
in which to store the resulting json translation files.
|
||||
*/
|
||||
var fs = require('fs');
|
||||
var glob = require('glob');
|
||||
var path = require('path');
|
||||
var po2icu = require('po2icu');
|
||||
|
||||
var localeCompare = require('../locale-compare');
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Main script
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
var args = process.argv.slice(2);
|
||||
|
||||
if (!args.length) {
|
||||
process.stdout.write('A destination directory must be specified.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var poUiDir = path.resolve(__dirname, '../../node_modules/scratchr2_translations/ui');
|
||||
var outputFile = path.resolve(__dirname, '../../', args[0]);
|
||||
// Create the directory if it doesn't exist.
|
||||
var fileInfo = path.parse(outputFile);
|
||||
try {
|
||||
fs.accessSync(fileInfo.dir, fs.F_OK);
|
||||
} catch (err) {
|
||||
// Doesn't exist – create it.
|
||||
fs.mkdirSync(fileInfo.dir);
|
||||
}
|
||||
|
||||
var icuTemplateFile = path.resolve(__dirname, '../../en.json');
|
||||
var idsWithICU = JSON.parse(fs.readFileSync(icuTemplateFile, 'utf8'));
|
||||
var locales = {
|
||||
en: idsWithICU
|
||||
};
|
||||
|
||||
var icuWithIds = {};
|
||||
for (var id in idsWithICU) {
|
||||
icuWithIds[idsWithICU[id]] = id;
|
||||
}
|
||||
var md5WithIds = localeCompare.getMD5Map(icuWithIds);
|
||||
|
||||
// Get ui localization strings first
|
||||
glob(poUiDir + '/*', function (err, files) {
|
||||
if (err) throw new Error(err);
|
||||
|
||||
files.forEach(function (file) {
|
||||
var lang = file.split('/').pop();
|
||||
var jsFile = path.resolve(file, 'LC_MESSAGES/djangojs.po');
|
||||
var pyFile = path.resolve(file, 'LC_MESSAGES/django.po');
|
||||
|
||||
var translations = {};
|
||||
|
||||
try {
|
||||
var jsTranslations = po2icu.poFileToICUSync(lang, jsFile);
|
||||
translations = localeCompare.mergeNewTranslations(translations, jsTranslations, idsWithICU, md5WithIds);
|
||||
} catch (err) {
|
||||
process.stdout.write(lang + ': ' + err + '\n');
|
||||
}
|
||||
|
||||
try {
|
||||
var pyTranslations = po2icu.poFileToICUSync(lang, pyFile);
|
||||
translations = localeCompare.mergeNewTranslations(translations, pyTranslations, idsWithICU, md5WithIds);
|
||||
} catch (err) {
|
||||
process.stdout.write(lang + ': ' + err + '\n');
|
||||
}
|
||||
|
||||
locales[lang] = translations;
|
||||
});
|
||||
fs.writeFileSync(outputFile, JSON.stringify(locales, null, 4));
|
||||
});
|
|
@ -46,6 +46,7 @@
|
|||
"jsx-loader": "0.13.2",
|
||||
"lodash.clone": "3.0.3",
|
||||
"lodash.defaultsdeep": "3.10.0",
|
||||
"lodash.merge": "3.3.2",
|
||||
"lodash.omit": "3.1.0",
|
||||
"lodash.range": "3.0.1",
|
||||
"minilog": "2.0.8",
|
||||
|
|
|
@ -23,7 +23,7 @@ function Handler (route) {
|
|||
res.set({
|
||||
'Content-Type': 'text/html',
|
||||
'Cache-Control': 'public, max-age=31536000',
|
||||
'Etag': 'W/"' + checksum + '"'
|
||||
'Etag': '"' + checksum + '"'
|
||||
});
|
||||
res.send(output);
|
||||
};
|
||||
|
|
|
@ -37,7 +37,7 @@ app.use(log());
|
|||
app.use(compression());
|
||||
if (isProduction) {
|
||||
app.use(express.static(path.resolve(__dirname, '../build'), {
|
||||
lastModified: true,
|
||||
etag: 'strong',
|
||||
maxAge: '1y'
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
<script src="/js/lib/react-intl-with-locales{{min}}.js"></script>
|
||||
<script src="/js/lib/raven.min.js"></script>
|
||||
|
||||
<script src="/js/main.bundle.js"></script>
|
||||
<script src="/js/{{view}}.intl.js"></script>
|
||||
<script src="/js/{{view}}.bundle.js"></script>
|
||||
|
||||
<!-- Error logging (Sentry) -->
|
||||
|
|
|
@ -46,7 +46,7 @@ var Activity = React.createClass({
|
|||
return (
|
||||
<li key={item.pk}>
|
||||
<a href={actorProfileUrl}>
|
||||
<img src={item.actor.thumbnail_url} width="34" height="34" />
|
||||
<img src={item.actor.thumbnail_url} width="34" height="34" alt="" />
|
||||
<p dangerouslySetInnerHTML={{__html: activityMessageHTML}}></p>
|
||||
<p>
|
||||
<span className="stamp">
|
||||
|
|
|
@ -3,6 +3,10 @@ var React = require('react');
|
|||
|
||||
require('./banner.scss');
|
||||
|
||||
/**
|
||||
* Container for messages displayed below the nav bar that can be dismissed
|
||||
* (See: email not confirmed banner)
|
||||
*/
|
||||
var Banner = React.createClass({
|
||||
type: 'Banner',
|
||||
propTypes: {
|
||||
|
|
|
@ -9,6 +9,9 @@ require('slick-carousel/slick/slick.scss');
|
|||
require('slick-carousel/slick/slick-theme.scss');
|
||||
require('./carousel.scss');
|
||||
|
||||
/**
|
||||
* Displays content in horizontal scrolling box. Example usage: splash page rows.
|
||||
*/
|
||||
var Carousel = React.createClass({
|
||||
type: 'Carousel',
|
||||
propTypes: {
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
var omit = require('lodash.omit');
|
||||
var React = require('react');
|
||||
var ReactIntl = require('react-intl');
|
||||
var FormattedMessage = ReactIntl.FormattedMessage;
|
||||
var FormattedHTMLMessage = ReactIntl.FormattedHTMLMessage;
|
||||
|
||||
var Modal = require('../modal/modal.jsx');
|
||||
var Registration = require('../registration/registration.jsx');
|
||||
|
@ -18,7 +15,16 @@ var Intro = React.createClass({
|
|||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
projectCount: 10569070
|
||||
projectCount: 10569070,
|
||||
messages: {
|
||||
'intro.aboutScratch': 'ABOUT SCRATCH',
|
||||
'intro.forEducators': 'FOR EDUCATORS',
|
||||
'intro.forParents': 'FOR PARENTS',
|
||||
'intro.joinScratch': 'JOIN SCRATCH',
|
||||
'intro.seeExamples': 'SEE EXAMPLES',
|
||||
'intro.tagLine': 'Create stories, games, and animations<br /> Share with others around the world',
|
||||
'intro.tryItOut': 'TRY IT OUT'
|
||||
}
|
||||
};
|
||||
},
|
||||
getInitialState: function () {
|
||||
|
@ -52,55 +58,49 @@ var Intro = React.createClass({
|
|||
return (
|
||||
<div className="intro">
|
||||
<div className="content">
|
||||
<h1>
|
||||
<FormattedHTMLMessage
|
||||
id='intro.tagLine'
|
||||
defaultMessage={
|
||||
'Create stories, games, and animations<br /> ' +
|
||||
'Share with others around the world'
|
||||
} />
|
||||
<h1 dangerouslySetInnerHTML={{__html: this.props.messages['intro.tagLine']}}>
|
||||
</h1>
|
||||
<div className="sprites">
|
||||
<a className="sprite sprite-1" href="/projects/editor/?tip_bar=getStarted">
|
||||
<img
|
||||
className="costume costume-1"
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/cat-a.png" />
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/cat-a.png"
|
||||
alt="Scratch Cat" />
|
||||
<img
|
||||
className="costume costume-2"
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/cat-b.png" />
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/cat-b.png"
|
||||
alt="Scratch Cat" />
|
||||
<div className="circle"></div>
|
||||
<div className="text">
|
||||
<FormattedMessage
|
||||
id='intro.tryItOut'
|
||||
defaultMessage='TRY IT OUT' />
|
||||
{this.props.messages['intro.tryItOut']}
|
||||
</div>
|
||||
</a>
|
||||
<a className="sprite sprite-2" href="/starter_projects/">
|
||||
<img
|
||||
className="costume costume-1"
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/tera-a.png" />
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/tera-a.png"
|
||||
alt="Tera" />
|
||||
<img
|
||||
className="costume costume-2"
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/tera-b.png" />
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/tera-b.png"
|
||||
alt="Tera" />
|
||||
<div className="circle"></div>
|
||||
<div className="text">
|
||||
<FormattedMessage
|
||||
id='intro.seeExamples'
|
||||
defaultMessage='SEE EXAMPLES' />
|
||||
{this.props.messages['intro.seeExamples']}
|
||||
</div>
|
||||
</a>
|
||||
<a className="sprite sprite-3" href="#" onClick={this.handleJoinClick}>
|
||||
<img
|
||||
className="costume costume-1"
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/gobo-a.png" />
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/gobo-a.png"
|
||||
alt="Gobo" />
|
||||
<img
|
||||
className="costume costume-2"
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/gobo-b.png" />
|
||||
src="//cdn.scratch.mit.edu/scratchr2/static/images/gobo-b.png"
|
||||
alt="Gobo" />
|
||||
<div className="circle"></div>
|
||||
<div className="text">
|
||||
<FormattedMessage
|
||||
id='intro.joinScratch'
|
||||
defaultMessage='JOIN SCRATCH' />
|
||||
{this.props.messages['intro.joinScratch']}
|
||||
</div>
|
||||
<div className="text subtext">( it’s free )</div>
|
||||
</a>
|
||||
|
@ -116,25 +116,20 @@ var Intro = React.createClass({
|
|||
</div>
|
||||
<div className="links">
|
||||
<a href="/about/">
|
||||
<FormattedMessage
|
||||
id='intro.aboutScratch'
|
||||
defaultMessage='ABOUT SCRATCH' />
|
||||
{this.props.messages['intro.aboutScratch']}
|
||||
</a>
|
||||
<a href="/educators/">
|
||||
<FormattedMessage
|
||||
id='intro.forEducators'
|
||||
defaultMessage='FOR EDUCATORS' />
|
||||
{this.props.messages['intro.forEducators']}
|
||||
</a>
|
||||
<a className="last" href="/parents/">
|
||||
<FormattedMessage
|
||||
id='intro.forParents'
|
||||
defaultMessage='FOR PARENTS' />
|
||||
{this.props.messages['intro.forParents']}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="video">
|
||||
<div className="play-button" onClick={this.showVideo}></div>
|
||||
<img src="//cdn.scratch.mit.edu/scratchr2/static/images/hp-video-screenshot.png" />
|
||||
<img src="//cdn.scratch.mit.edu/scratchr2/static/images/hp-video-screenshot.png"
|
||||
alt="Intro Video" />
|
||||
</div>
|
||||
<Modal
|
||||
className="video-modal"
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
var classNames = require('classnames');
|
||||
var React = require('react');
|
||||
var ReactDOM = require('react-dom');
|
||||
|
||||
var Api = require('../../mixins/api.jsx');
|
||||
var jar = require('../../lib/jar.js');
|
||||
var languages = require('../../../languages.json');
|
||||
var Select = require('../forms/select.jsx');
|
||||
|
||||
require('./languagechooser.scss');
|
||||
|
||||
/**
|
||||
* Footer dropdown menu that allows one to change their language.
|
||||
*/
|
||||
var LanguageChooser = React.createClass({
|
||||
type: 'LanguageChooser',
|
||||
mixins: [
|
||||
Api
|
||||
],
|
||||
getInitialState: function () {
|
||||
return {
|
||||
choice: window._locale
|
||||
};
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
languages: languages
|
||||
languages: languages,
|
||||
locale: window._locale
|
||||
};
|
||||
},
|
||||
onSetLanguage: function (e) {
|
||||
e.preventDefault();
|
||||
this.setState({'choice': e.target.value});
|
||||
ReactDOM.findDOMNode(this.refs.languageForm).submit();
|
||||
jar.set('scratchlanguage', e.target.value);
|
||||
window.location.reload();
|
||||
},
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
|
@ -35,15 +34,15 @@ var LanguageChooser = React.createClass({
|
|||
);
|
||||
|
||||
return (
|
||||
<form ref="languageForm" className={classes} action="/i18n/setlang/" method="POST">
|
||||
<Select name="language" defaultValue={this.state.choice} onChange={this.onSetLanguage}>
|
||||
<div className={classes}>
|
||||
<Select name="language" defaultValue={this.props.locale} onChange={this.onSetLanguage}>
|
||||
{Object.keys(this.props.languages).map(function (value) {
|
||||
return <option value={value} key={value}>
|
||||
{this.props.languages[value]}
|
||||
</option>;
|
||||
}.bind(this))}
|
||||
</Select>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -25,6 +25,9 @@ var defaultStyle = {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Container for pop up windows (See: registration window)
|
||||
*/
|
||||
var Modal = React.createClass({
|
||||
type: 'Modal',
|
||||
statics: {
|
||||
|
|
|
@ -4,7 +4,6 @@ var ReactIntl = require('react-intl');
|
|||
var defineMessages = ReactIntl.defineMessages;
|
||||
var FormattedMessage = ReactIntl.FormattedMessage;
|
||||
var injectIntl = ReactIntl.injectIntl;
|
||||
var xhr = require('xhr');
|
||||
|
||||
var Api = require('../../mixins/api.jsx');
|
||||
var Avatar = require('../avatar/avatar.jsx');
|
||||
|
@ -48,14 +47,14 @@ var Navigation = React.createClass({
|
|||
loginOpen: false,
|
||||
loginError: null,
|
||||
registrationOpen: false,
|
||||
unreadMessageCount: 0,
|
||||
messageCountIntervalId: -1
|
||||
unreadMessageCount: 0, // bubble number to display how many notifications someone has.
|
||||
messageCountIntervalId: -1 // javascript method interval id for getting messsage count.
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
if (this.state.session.user) {
|
||||
this.getMessageCount();
|
||||
var intervalId = setInterval(this.getMessageCount, 120000);
|
||||
var intervalId = setInterval(this.getMessageCount, 120000); // check for new messages every 2 mins.
|
||||
this.setState({'messageCountIntervalId': intervalId});
|
||||
}
|
||||
},
|
||||
|
@ -96,11 +95,11 @@ var Navigation = React.createClass({
|
|||
getMessageCount: function () {
|
||||
this.api({
|
||||
method: 'get',
|
||||
uri: '/proxy/users/' + this.state.session.user.username + '/activity/count'
|
||||
uri: '/users/' + this.state.session.user.username + '/messages/count'
|
||||
}, function (err, body) {
|
||||
if (err) return this.setState({'unreadMessageCount': 0});
|
||||
if (body) {
|
||||
var count = parseInt(body.msg_count, this.state.unreadMessageCount);
|
||||
var count = parseInt(body.count, 10);
|
||||
return this.setState({'unreadMessageCount': count});
|
||||
}
|
||||
}.bind(this));
|
||||
|
@ -151,16 +150,15 @@ var Navigation = React.createClass({
|
|||
},
|
||||
handleLogOut: function (e) {
|
||||
e.preventDefault();
|
||||
xhr({
|
||||
this.api({
|
||||
host: '',
|
||||
uri: '/accounts/logout/'
|
||||
method: 'post',
|
||||
uri: '/accounts/logout/',
|
||||
useCsrf: true
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
log.error(err);
|
||||
} else {
|
||||
this.closeLogin();
|
||||
window.refreshSession();
|
||||
}
|
||||
if (err) log.error(err);
|
||||
this.closeLogin();
|
||||
window.refreshSession();
|
||||
}.bind(this));
|
||||
},
|
||||
handleAccountNavClick: function (e) {
|
||||
|
@ -196,8 +194,8 @@ var Navigation = React.createClass({
|
|||
return (
|
||||
<div className={classes}>
|
||||
<ul>
|
||||
<li className="logo"><a href="/"></a></li>
|
||||
|
||||
<li className="logo"><a href="/" aria-label="Scratch"></a></li>
|
||||
|
||||
<li className="link create">
|
||||
<a href="/projects/editor">
|
||||
<FormattedMessage
|
||||
|
@ -237,7 +235,10 @@ var Navigation = React.createClass({
|
|||
<li className="search">
|
||||
<form action="/search/google_results" method="get">
|
||||
<Input type="submit" value="" />
|
||||
<Input type="text" placeholder={formatMessage(defaultMessages.search)} name="q" />
|
||||
<Input type="text"
|
||||
aria-label={formatMessage(defaultMessages.search)}
|
||||
placeholder={formatMessage(defaultMessages.search)}
|
||||
name="q" />
|
||||
<Input type="hidden" name="date" value="anytime" />
|
||||
<Input type="hidden" name="sort_by" value="datetime_shared" />
|
||||
</form>
|
||||
|
@ -262,7 +263,7 @@ var Navigation = React.createClass({
|
|||
</li>,
|
||||
<li className="link right account-nav" key="account-nav">
|
||||
<a className="userInfo" href="#" onClick={this.handleAccountNavClick}>
|
||||
<Avatar src={this.state.session.user.thumbnailUrl} />
|
||||
<Avatar src={this.state.session.user.thumbnailUrl} alt="" />
|
||||
{this.state.session.user.username}
|
||||
</a>
|
||||
<Dropdown
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
var React = require('react');
|
||||
var ReactIntl = require('react-intl');
|
||||
var defineMessages = ReactIntl.defineMessages;
|
||||
var injectIntl = ReactIntl.injectIntl;
|
||||
|
||||
var Box = require('../box/box.jsx');
|
||||
|
||||
require('./news.scss');
|
||||
|
||||
var defaultMessages = defineMessages({
|
||||
scratchNews: {
|
||||
id: 'news.scratchNews',
|
||||
defaultMessage: 'Scratch News'
|
||||
},
|
||||
viewAll: {
|
||||
id: 'general.viewAll',
|
||||
defaultMessage: 'View All'
|
||||
}
|
||||
});
|
||||
|
||||
var News = React.createClass({
|
||||
type: 'News',
|
||||
propTypes: {
|
||||
|
@ -25,16 +11,19 @@ var News = React.createClass({
|
|||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
items: require('./news.json')
|
||||
items: require('./news.json'),
|
||||
messages: {
|
||||
'general.viewAll': 'View All',
|
||||
'news.scratchNews': 'Scratch News'
|
||||
}
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
return (
|
||||
<Box
|
||||
className="news"
|
||||
title={formatMessage(defaultMessages.scratchNews)}
|
||||
moreTitle={formatMessage(defaultMessages.viewAll)}
|
||||
title={this.props.messages['news.scratchNews']}
|
||||
moreTitle={this.props.messages['general.viewAll']}
|
||||
moreHref="/discuss/5/">
|
||||
|
||||
<ul>
|
||||
|
@ -42,7 +31,7 @@ var News = React.createClass({
|
|||
return (
|
||||
<li key={item.id}>
|
||||
<a href={item.url}>
|
||||
<img src={item.image} width="53" height="53" />
|
||||
<img src={item.image} width="53" height="53" alt="" />
|
||||
<h4>{item.headline}</h4>
|
||||
<p>{item.copy}</p>
|
||||
</a>
|
||||
|
@ -55,4 +44,4 @@ var News = React.createClass({
|
|||
}
|
||||
});
|
||||
|
||||
module.exports = injectIntl(News);
|
||||
module.exports = News;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
white-space: normal;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
|
|
|
@ -3,6 +3,10 @@ var React = require('react');
|
|||
|
||||
require('./subnavigation.scss');
|
||||
|
||||
/**
|
||||
* Container for a custom, horizontal list of navigation elements
|
||||
* that can be displayed within a view or component.
|
||||
*/
|
||||
var SubNavigation = React.createClass({
|
||||
type: 'SubNavigation',
|
||||
render: function () {
|
||||
|
|
|
@ -15,7 +15,8 @@ var Thumbnail = React.createClass({
|
|||
src: '',
|
||||
type: 'project',
|
||||
showLoves: false,
|
||||
showRemixes: false
|
||||
showRemixes: false,
|
||||
alt: ''
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
|
@ -57,7 +58,7 @@ var Thumbnail = React.createClass({
|
|||
return (
|
||||
<div className={classes} >
|
||||
<a className="thumbnail-image" href={this.props.href}>
|
||||
<img src={this.props.src} />
|
||||
<img src={this.props.src} alt={this.props.alt} />
|
||||
</a>
|
||||
<div className="thumbnail-title">
|
||||
<a href={this.props.href}>{this.props.title}</a>
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
var React = require('react');
|
||||
var ReactIntl = require('react-intl');
|
||||
|
||||
var injectIntl = ReactIntl.injectIntl;
|
||||
var FormattedMessage = ReactIntl.FormattedMessage;
|
||||
|
||||
var Box = require('../box/box.jsx');
|
||||
|
||||
|
@ -13,10 +9,19 @@ var Welcome = React.createClass({
|
|||
propTypes: {
|
||||
onDismiss: React.PropTypes.func
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
messages: {
|
||||
'welcome.welcomeToScratch': 'Welcome to Scratch!',
|
||||
'welcome.learn': 'Learn how to make a project in Scratch',
|
||||
'welcome.tryOut': 'Try out starter projects',
|
||||
'welcome.connect': 'Connect with other Scratchers'
|
||||
}
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
return (
|
||||
<Box title={formatMessage({id: 'welcome.welcomeToScratch', defaultMessage: 'Welcome to Scratch!'})}
|
||||
<Box title={this.props.messages['welcome.welcomeToScratch']}
|
||||
className="welcome"
|
||||
moreTitle="x"
|
||||
moreHref="#"
|
||||
|
@ -29,37 +34,31 @@ var Welcome = React.createClass({
|
|||
<div className="welcome-col blue">
|
||||
<h4>
|
||||
<a href="/projects/editor/?tip_bar=getStarted">
|
||||
<FormattedMessage
|
||||
id="welcome.learn"
|
||||
defaultMessage="Learn how to make a project in Scratch" />
|
||||
{this.props.messages['welcome.learn']}
|
||||
</a>
|
||||
</h4>
|
||||
<a href="/projects/editor/?tip_bar=getStarted">
|
||||
<img src="/images/welcome-learn.png" />
|
||||
<img src="/images/welcome-learn.png" alt="Get Started" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="welcome-col green">
|
||||
<h4>
|
||||
<a href="/starter_projects/">
|
||||
<FormattedMessage
|
||||
id="welcome.tryOut"
|
||||
defaultMessage="Try out starter projects" />
|
||||
{this.props.messages['welcome.tryOut']}
|
||||
</a>
|
||||
</h4>
|
||||
<a href="/starter_projects/">
|
||||
<img src="/images/welcome-try.png" />
|
||||
<img src="/images/welcome-try.png" alt="Starter Projects" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="welcome-col pink">
|
||||
<h4>
|
||||
<a href="/studios/146521/">
|
||||
<FormattedMessage
|
||||
id="welcome.connect"
|
||||
defaultMessage="Connect with other Scratchers" />
|
||||
{this.props.messages['welcome.connect']}
|
||||
</a>
|
||||
</h4>
|
||||
<a href="/studios/146521/">
|
||||
<img src="/images/welcome-connect.png" />
|
||||
<img src="/images/welcome-connect.png" alt="Connect" />
|
||||
</a>
|
||||
</div>
|
||||
</Box>
|
||||
|
@ -67,4 +66,4 @@ var Welcome = React.createClass({
|
|||
}
|
||||
});
|
||||
|
||||
module.exports = injectIntl(Welcome);
|
||||
module.exports = Welcome;
|
||||
|
|
28
src/init.js
28
src/init.js
|
@ -1,8 +1,6 @@
|
|||
var api = require('./mixins/api.jsx').api;
|
||||
var jar = require('./lib/jar');
|
||||
|
||||
var translations = require('../locales/translations.json');
|
||||
|
||||
/**
|
||||
* -----------------------------------------------------------------------------
|
||||
* Session
|
||||
|
@ -37,10 +35,14 @@ var translations = require('../locales/translations.json');
|
|||
host: '',
|
||||
uri: '/session/'
|
||||
}, function (err, body) {
|
||||
if (body.banned) {
|
||||
return window.location = body.redirectUrl;
|
||||
} else {
|
||||
window.updateSession(body);
|
||||
if (err) return;
|
||||
|
||||
if (typeof body !== 'undefined') {
|
||||
if (body.banned) {
|
||||
return window.location = body.redirectUrl;
|
||||
} else {
|
||||
window.updateSession(body);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -64,18 +66,12 @@ var translations = require('../locales/translations.json');
|
|||
var obj = jar.get('scratchlanguage');
|
||||
if (typeof obj === 'undefined') {
|
||||
obj = window.navigator.userLanguage || window.navigator.language;
|
||||
}
|
||||
if (typeof translations[obj] === 'undefined') {
|
||||
// Fall back on the split
|
||||
obj = obj.split('-')[0];
|
||||
}
|
||||
if (typeof translations[obj] === 'undefined') {
|
||||
// Language appears to not be supported – return `null`
|
||||
obj = null;
|
||||
if (['pt','pt-pt','PT','PT-PT'].indexOf(obj) !== -1) {
|
||||
obj = 'pt-br'; // default Portuguese users to Brazilian Portuguese due to our user base. Added in 2.2.5.
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
window._locale = updateLocale() || 'en';
|
||||
window._translations = translations;
|
||||
window._locale = updateLocale();
|
||||
})();
|
||||
|
|
64
src/l10n.json
Normal file
64
src/l10n.json
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"general.accountSettings": "Account settings",
|
||||
"general.about": "About",
|
||||
"general.aboutScratch": "About Scratch",
|
||||
"general.donate": "Donate",
|
||||
"general.collaborators": "Collaborators",
|
||||
"general.community": "Community",
|
||||
"general.contactUs": "Contact Us",
|
||||
"general.copyright": "Scratch is a project of the Lifelong Kindergarten Group at the MIT Media Lab",
|
||||
"general.create": "Create",
|
||||
"general.credits": "Credits",
|
||||
"general.discuss": "Discuss",
|
||||
"general.dmca": "DMCA",
|
||||
"general.explore": "Explore",
|
||||
"general.faq": "FAQ",
|
||||
"general.forParents": "For Parents",
|
||||
"general.forEducators": "For Educators",
|
||||
"general.guidelines": "Community Guidelines",
|
||||
"general.help": "Help",
|
||||
"general.jobs": "Jobs",
|
||||
"general.joinScratch": "Join Scratch",
|
||||
"general.legal": "Legal",
|
||||
"general.learnMore": "Learn More",
|
||||
"general.messages": "Messages",
|
||||
"general.myClasses": "My Classes",
|
||||
"general.myStuff": "My Stuff",
|
||||
"general.offlineEditor": "Offline Editor",
|
||||
"general.profile": "Profile",
|
||||
"general.scratchConference": "Scratch Conference",
|
||||
"general.scratchday": "Scratch Day",
|
||||
"general.scratchEd": "ScratchEd",
|
||||
"general.scratchFoundation": "Scratch Foundation",
|
||||
"general.scratchJr": "ScratchJr",
|
||||
"general.search": "Search",
|
||||
"general.signIn": "Sign in",
|
||||
"general.statistics": "Statistics",
|
||||
"general.support": "Support",
|
||||
"general.tipsWindow": "Tips Window",
|
||||
"general.tipsAnimateYourNameTitle": "Animate Your Name",
|
||||
"general.tipsBearstack": "Bearstack Story",
|
||||
"general.tipsDanceTitle": "Dance, Dance, Dance",
|
||||
"general.tipsGetStarted": "Getting Started",
|
||||
"general.tipsHideAndSeekTitle": "Hide-and-Seek Game",
|
||||
"general.tipsPongGame": "Create a Pong Game",
|
||||
"general.termsOfUse": "Terms of Use",
|
||||
"general.username": "Username",
|
||||
"general.viewAll": "View All",
|
||||
"general.whatsHappening": "What's Happening?",
|
||||
"general.wiki": "Scratch Wiki",
|
||||
|
||||
"footer.about": "About Scratch",
|
||||
"footer.discuss": "Discussion Forums",
|
||||
"footer.help": "Help Page",
|
||||
"footer.scratchFamily": "Scratch Family",
|
||||
|
||||
"login.forgotPassword": "Forgot Password?",
|
||||
|
||||
"navigation.signOut": "Sign out",
|
||||
|
||||
"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.",
|
||||
"parents.FaqAgeRangeQ": "What is the age range for Scratch?",
|
||||
"parents.FaqResourcesQ": "What resources are available for learning Scratch?",
|
||||
"parents.introDescription": "Scratch is a programming language and an online community where children can program and share interactive media such as stories, games, and animation with people from all over the world. As children create with Scratch, they learn to think creatively, work collaboratively, and reason systematically. Scratch is designed and maintained by the Lifelong Kindergarten group at the MIT Media Lab."
|
||||
}
|
|
@ -2,6 +2,9 @@ var ReactIntl = require('react-intl');
|
|||
|
||||
var customLanguages = require('../../custom-locales.json');
|
||||
|
||||
/**
|
||||
* Add custom locales to react-intl if it doesn't have them.
|
||||
*/
|
||||
for (var locale in customLanguages) {
|
||||
ReactIntl.addLocaleData(customLanguages[locale]);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
var cookie = require('cookie');
|
||||
var xhr = require('xhr');
|
||||
|
||||
/**
|
||||
* Module that handles coookie interactions.
|
||||
* (Cookies?!?! Jar?!?! Get it?!?! WE'RE AMAZING!!!!)
|
||||
*
|
||||
* get(name, callback) – can be sync or async, as callback is optional
|
||||
* set(name, value) – synchronously sets the cookie
|
||||
* use(name, uri, callback) – can by sync or async, gets cookie from the uri if not there.
|
||||
*/
|
||||
var Jar = {};
|
||||
|
||||
Jar.get = function (name, callback) {
|
||||
|
|
|
@ -3,12 +3,47 @@ var ReactDOM = require('react-dom');
|
|||
var ReactIntl = require('./intl.jsx');
|
||||
var IntlProvider = ReactIntl.IntlProvider;
|
||||
|
||||
require('../main.scss');
|
||||
|
||||
var Navigation = require('../components/navigation/navigation.jsx');
|
||||
var Footer = require('../components/footer/footer.jsx');
|
||||
|
||||
var render = function (jsx, element) {
|
||||
// Get locale and messages from global namespace (see "init.js")
|
||||
var locale = window._locale;
|
||||
var messages = window._translations[locale];
|
||||
var locale = window._locale || 'en';
|
||||
if (typeof window._messages[locale] === 'undefined') {
|
||||
// Fall back on the split
|
||||
locale = locale.split('-')[0];
|
||||
}
|
||||
if (typeof window._messages[locale] === 'undefined') {
|
||||
// Language appears to not be supported – fall back to 'en'
|
||||
locale = 'en';
|
||||
}
|
||||
var messages = window._messages[locale];
|
||||
|
||||
// Render component
|
||||
|
||||
// Render nav and footer for page.
|
||||
var nav = ReactDOM.render(
|
||||
<IntlProvider locale={locale} messages={messages}>
|
||||
<Navigation />
|
||||
</IntlProvider>,
|
||||
document.getElementById('navigation')
|
||||
);
|
||||
|
||||
var footer = ReactDOM.render(
|
||||
<IntlProvider locale={locale} messages={messages}>
|
||||
<Footer />
|
||||
</IntlProvider>,
|
||||
document.getElementById('footer')
|
||||
);
|
||||
|
||||
// Provide list of rendered components
|
||||
window._renderedComponents = window._renderedComponents || [];
|
||||
window._renderedComponents.push(nav);
|
||||
window._renderedComponents.push(footer);
|
||||
|
||||
|
||||
// Render view component
|
||||
var component = ReactDOM.render(
|
||||
<IntlProvider locale={locale} messages={messages}>
|
||||
{jsx}
|
||||
|
@ -16,8 +51,6 @@ var render = function (jsx, element) {
|
|||
element
|
||||
);
|
||||
|
||||
// Provide list of rendered components
|
||||
window._renderedComponents = window._renderedComponents || [];
|
||||
window._renderedComponents.push(component);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
var render = require('./lib/render.jsx');
|
||||
|
||||
require('./main.scss');
|
||||
|
||||
var Navigation = require('./components/navigation/navigation.jsx');
|
||||
var Footer = require('./components/footer/footer.jsx');
|
||||
|
||||
render(<Navigation />, document.getElementById('navigation'));
|
||||
render(<Footer />, document.getElementById('footer'));
|
|
@ -40,8 +40,10 @@ p.legal {
|
|||
}
|
||||
|
||||
/* Links */
|
||||
a {
|
||||
white-space: nowrap;
|
||||
p {
|
||||
a {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
a:link,
|
||||
|
|
|
@ -6,6 +6,14 @@ var log = require('../lib/log.js');
|
|||
|
||||
var CookieMixinFactory = require('./cookieMixinFactory.jsx');
|
||||
|
||||
/**
|
||||
* Component mixin that constructs requests to the scratch api.
|
||||
* Custom arguments:
|
||||
* - useCsrf [boolean] – handles unique csrf token retrieval for POST requests. This prevents
|
||||
* CSRF forgeries (see: https://www.squarefree.com/securitytips/web-developers.html#CSRF)
|
||||
*
|
||||
* It also takes in other arguments specified in the xhr library spec.
|
||||
*/
|
||||
var Api = {
|
||||
mixins: [
|
||||
// Provides useScratchcsrftoken
|
||||
|
@ -36,7 +44,11 @@ var Api = {
|
|||
if (err) log.error(err);
|
||||
// Legacy API responses come as lists, and indicate to redirect the client like
|
||||
// [{success: true, redirect: "/location/to/redirect"}]
|
||||
if (body && body[0] && 'redirect' in body[0]) window.location = body[0].redirect;
|
||||
try {
|
||||
if ('redirect' in body[0]) window.location = body[0].redirect;
|
||||
} catch (err) {
|
||||
// do nothing
|
||||
}
|
||||
callback(err, body);
|
||||
});
|
||||
}.bind(this);
|
||||
|
|
|
@ -26,6 +26,7 @@ var About = React.createClass({
|
|||
|
||||
<div>
|
||||
<iframe
|
||||
title="Scratch Overview Video"
|
||||
src="https://player.vimeo.com/video/65583694?title=0&byline=0&portrait=0"
|
||||
frameBorder="0"
|
||||
webkitAllowFullScreen
|
||||
|
@ -38,7 +39,7 @@ var About = React.createClass({
|
|||
<ul>
|
||||
<li>
|
||||
<h2><FormattedMessage id='about.whoUsesScratch' /></h2>
|
||||
<img src="/images/about/who-uses-scratch.jpg" />
|
||||
<img src="/images/about/who-uses-scratch.jpg" alt="" />
|
||||
<p><FormattedHTMLMessage id='about.whoUsesScratchDescription' /></p>
|
||||
</li>
|
||||
|
||||
|
@ -55,25 +56,25 @@ var About = React.createClass({
|
|||
|
||||
<li>
|
||||
<h2><FormattedMessage id='about.aroundTheWorld' /></h2>
|
||||
<img src="/images/about/around-the-world.png" />
|
||||
<img src="/images/about/around-the-world.png" alt="" />
|
||||
<p><FormattedHTMLMessage id='about.aroundTheWorldDescription' /></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h2><FormattedMessage id='about.schools' /></h2>
|
||||
<img src="/images/about/scratch-in-schools.jpg" />
|
||||
<img src="/images/about/scratch-in-schools.jpg" alt="" />
|
||||
<p><FormattedHTMLMessage id='about.schoolsDescription' /></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h2><FormattedMessage id='about.quotes' /></h2>
|
||||
<img src="/images/about/quotes.gif" />
|
||||
<img src="/images/about/quotes.gif" alt="Quotes about Scratch" />
|
||||
<p><FormattedHTMLMessage id='about.quotesDescription' /></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h2><FormattedMessage id='about.research' /></h2>
|
||||
<img src="/images/about/research-remix.png" />
|
||||
<img src="/images/about/research-remix.png" alt="" />
|
||||
<p><FormattedHTMLMessage id='about.researchDescription' /></p>
|
||||
</li>
|
||||
|
||||
|
@ -81,10 +82,18 @@ var About = React.createClass({
|
|||
<h2><FormattedMessage id='about.learnMore' /></h2>
|
||||
<p>
|
||||
<ul className="list">
|
||||
<li><a href="/help"><FormattedMessage id='about.learnMoreHelp' /></a></li>
|
||||
<li><a href="/info/faq"><FormattedMessage id='about.learnMoreFaq' /></a></li>
|
||||
<li><a href="/parents"><FormattedMessage id='about.learnMoreParents' /></a></li>
|
||||
<li><a href="/credits"><FormattedMessage id='about.learnMoreCredits' /></a></li>
|
||||
<li>
|
||||
<a href="/help"><FormattedMessage id='about.learnMoreHelp' /></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/info/faq"><FormattedMessage id='about.learnMoreFaq' /></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/parents"><FormattedMessage id='about.learnMoreParents' /></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/info/credits"><FormattedMessage id='about.learnMoreCredits' /></a>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
</li>
|
||||
|
|
26
src/views/about/l10n.json
Normal file
26
src/views/about/l10n.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"about.introOne": "With Scratch, you can program your own interactive stories, games, and animations — and share your creations with others in the online community.",
|
||||
"about.introTwo": "Scratch helps young people learn to think creatively, reason systematically, and work collaboratively — essential skills for life in the 21st century.",
|
||||
"about.introThree": "Scratch is a project of the Lifelong Kindergarten Group at the MIT Media Lab. It is provided free of charge.",
|
||||
"about.introParents": "Info for parents",
|
||||
"about.introEducators": "Info for educators",
|
||||
"about.whoUsesScratch": "Who Uses Scratch?",
|
||||
"about.whoUsesScratchDescription": "Scratch is designed especially for ages 8 to 16, but is used by people of all ages. Millions of people are creating Scratch projects in a wide variety of settings, including homes, schools, museums, libraries, and community centers.",
|
||||
"about.aroundTheWorld": "Around the World",
|
||||
"about.aroundTheWorldDescription": "Scratch is used in more than 150 different countries and available in more than 40 languages. To change languages, click the menu at the bottom of the page. Or, in the Project Editor, click the globe at the top of the page. To add or improve a translation, see the <a href=\"http://wiki.scratch.mit.edu/wiki/How_to_Translate_Scratch\">translation</a> page.",
|
||||
"about.quotes": "Quotes",
|
||||
"about.quotesDescription": "The Scratch Team has received many emails from youth, parents, and educators expressing thanks for Scratch. Want to see what people are saying? You can read a collection of the <a href=\"/info/quotes\">quotes</a> we've received.",
|
||||
"about.learnMore": "Learn More About Scratch",
|
||||
"about.learnMoreHelp": "Scratch Help Page",
|
||||
"about.learnMoreFaq": "Frequently Asked Questions",
|
||||
"about.learnMoreParents": "Information for Parents",
|
||||
"about.learnMoreCredits": "Scratch Credits",
|
||||
"about.literacy": "Learn to Code, Code to Learn",
|
||||
"about.literacyDescription": "The ability to code computer programs is an important part of literacy in today’s society. When people learn to code in Scratch, they learn important strategies for solving problems, designing projects, and communicating ideas.",
|
||||
"about.schools": "Scratch in Schools",
|
||||
"about.schoolsDescription": "Students are learning with Scratch at all levels (from elementary school to college) and across disciplines (such as math, computer science, language arts, social studies). Educators share stories, exchange resources, ask questions, and find people on the <a href=\"http://scratched.gse.harvard.edu/\">ScratchEd website</a>.",
|
||||
"about.research": "Research",
|
||||
"about.researchDescription": "The MIT Scratch Team and collaborators are researching how people use and learn with Scratch (for an introduction, see <a href=\"http://web.media.mit.edu/~mres/papers/Scratch-CACM-final.pdf\">Scratch: Programming for All</a>). Find out more about Scratch <a href=\"/info/research\">research</a> and <a href=\"/statistics\">statistics</a> about Scratch.",
|
||||
"about.support": "Support and Funding",
|
||||
"about.supportDescription": "The Scratch project, initiated in 2003, has received generous support from the National Science Foundation (grants 0325828, 1002713, 1027848, 1019396), Intel Foundation, Microsoft, MacArthur Foundation, LEGO Foundation, Code-to-Learn Foundation, Google, Dell, Fastly, Inversoft, and MIT Media Lab research consortia. If you'd like to support Scratch, please see our <a href=\"https://secure.donationpay.org/scratchfoundation/\">donate page</a>, or contact us at donate@scratch.mit.edu."
|
||||
}
|
|
@ -8,7 +8,6 @@ var Carousel = require('../../components/carousel/carousel.jsx');
|
|||
var Input = require('../../components/forms/input.jsx');
|
||||
var Spinner = require('../../components/spinner/spinner.jsx');
|
||||
|
||||
|
||||
require('./components.scss');
|
||||
|
||||
var Components = React.createClass({
|
||||
|
|
|
@ -14,112 +14,112 @@ var Credits = React.createClass({
|
|||
|
||||
<ul>
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/167_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/167_170x170.png" alt="Mitchel Avatar" />
|
||||
<span className="name">Mitchel Resnick</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/169_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/169_170x170.png" alt="Natalie Avatar" />
|
||||
<span className="name">Natalie Rusk</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/573207_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/573207_170x170.png" alt="Sayamindu Avatar" />
|
||||
<span className="name">Sayamindu Dasgupta</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/13682_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/13682_170x170.png" alt="Ricarose Avatar" />
|
||||
<span className="name">Ricarose Roque</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2584924_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2584924_170x170.png" alt="Ray Avatar" />
|
||||
<span className="name">Ray Schamp</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3484484_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3484484_170x170.png" alt="Eric Avatar" />
|
||||
<span className="name">Eric Schilling</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3532363_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3532363_170x170.png" alt="Chris Avatar" />
|
||||
<span className="name">Chris Willis-Ford</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3581881_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3581881_170x170.png" alt="Carl Avatar" />
|
||||
<span className="name">Carl Bowman</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4373707_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4373707_170x170.png" alt="Matthew Avatar" />
|
||||
<span className="name">Matthew Taylor</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4598206_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4598206_170x170.png" alt="Kasia Avatar" />
|
||||
<span className="name">Kasia Chmielinski</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/703844_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/703844_170x170.png" alt="Tim Avatar" />
|
||||
<span className="name">Tim Mickel</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2752403_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2752403_170x170.png" alt="Saskia Avatar" />
|
||||
<span className="name">Saskia Leggett</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2755634_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2755634_170x170.png" alt="Christan Avatar" />
|
||||
<span className="name">Christan Balch</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/5721684_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/5721684_170x170.png" alt="Randy Avatar" />
|
||||
<span className="name">Randy Jou</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/10866958_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/10866958_170x170.png" alt="Colby Avatar" />
|
||||
<span className="name">Colby Gutierrez-Kraybill</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/1709047_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/1709047_170x170.png" alt="Andrew Avatar" />
|
||||
<span className="name">Andrew Sliwinski</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/default_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/default_170x170.png" alt="Ben Avatar" />
|
||||
<span className="name">Ben Berg</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2286560_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2286560_170x170.png" alt="Carmelo Avatar" />
|
||||
<span className="name">Carmelo Presicce</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/default_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/default_170x170.png" alt="Moran Avatar" />
|
||||
<span className="name">Moran Tsur</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3661900_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3661900_170x170.png" alt="Juanita Avatar" />
|
||||
<span className="name">Juanita Buitrago</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/default_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/default_170x170.png" alt="Shruti Avatar" />
|
||||
<span className="name">Shruti Mohnot</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/1915915_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/1915915_170x170.png" alt="Hannah Avatar" />
|
||||
<span className="name">Hannah Cole</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -128,47 +128,47 @@ var Credits = React.createClass({
|
|||
|
||||
<ul>
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/49156_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/49156_170x170.png" alt="Mark Avatar" />
|
||||
<span className="name">Mark Goff</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/159139_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/159139_170x170.png" alt="Franchette Avatar" />
|
||||
<span className="name">Franchette Viloria</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/246290_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/246290_170x170.png" alt="Sarah Avatar" />
|
||||
<span className="name">Sarah Otts</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2496866_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/2496866_170x170.png" alt="Jolie Avatar" />
|
||||
<span className="name">Jolie Castellucci</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3087865_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/3087865_170x170.png" alt="Andrea Avatar" />
|
||||
<span className="name">Andrea Saxman</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/373646_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/373646_170x170.png" alt="Dalton Avatar" />
|
||||
<span className="name">Dalton Miner</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/586054_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/586054_170x170.png" alt="Megan Avatar" />
|
||||
<span className="name">Megan Haddadi</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4836354_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4836354_170x170.png" alt="Christina Avatar" />
|
||||
<span className="name">Christina Huang</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4747093_170x170.png" />
|
||||
<img src="//cdn.scratch.mit.edu/get_image/user/4747093_170x170.png" alt="Annie Avatar" />
|
||||
<span className="name">Annie Whitehouse</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -50,7 +50,7 @@ var Hoc = React.createClass({
|
|||
<div className="card">
|
||||
<a href="/projects/editor/?tip_bar=name">
|
||||
<div className="card-info" onMouseEnter={this.onCardEnter.bind(this, 'name-bg')}>
|
||||
<img src="/images/hoc2015/name-tutorial.jpg" />
|
||||
<img src="/images/hoc2015/name-tutorial.jpg" alt="" />
|
||||
<Button>
|
||||
<FormattedMessage
|
||||
id='general.tipsAnimateYourNameTitle'
|
||||
|
@ -63,7 +63,7 @@ var Hoc = React.createClass({
|
|||
<div className="card" onMouseEnter={this.onCardEnter.bind(this, 'wbb-bg')}>
|
||||
<a href="/hide/">
|
||||
<div className="card-info">
|
||||
<img src="/images/hoc2015/hide-seek-tutorial.jpg" />
|
||||
<img src="/images/hoc2015/hide-seek-tutorial.jpg" alt="" />
|
||||
<Button>
|
||||
<FormattedMessage
|
||||
id='general.tipsHideAndSeekTitle'
|
||||
|
@ -76,7 +76,7 @@ var Hoc = React.createClass({
|
|||
<div className="card" onMouseEnter={this.onCardEnter.bind(this, 'dance-bg')}>
|
||||
<a href="/projects/editor/?tip_bar=dance">
|
||||
<div className="card-info">
|
||||
<img src="/images/hoc2015/dance-tutorial.jpg" />
|
||||
<img src="/images/hoc2015/dance-tutorial.jpg" alt="" />
|
||||
<Button>
|
||||
<FormattedMessage
|
||||
id='general.tipsDanceTitle'
|
||||
|
@ -142,7 +142,7 @@ var Hoc = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="resource">
|
||||
<img src="/svgs/tips-card.svg" />
|
||||
<img src="/svgs/tips-card.svg" alt="" />
|
||||
<div className="resource-info">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
|
@ -163,7 +163,7 @@ var Hoc = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="resource">
|
||||
<img src="/svgs/tips-card.svg" />
|
||||
<img src="/svgs/tips-card.svg" alt="" />
|
||||
<div className="resource-info">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
|
@ -184,7 +184,7 @@ var Hoc = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="resource">
|
||||
<img src="/svgs/tips-card.svg" />
|
||||
<img src="/svgs/tips-card.svg" alt="" />
|
||||
<div className="resource-info">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
|
@ -223,7 +223,7 @@ var Hoc = React.createClass({
|
|||
</p>
|
||||
</div>
|
||||
<div className="column">
|
||||
<img src="/images/hoc2015/tips-test-animation.gif" />
|
||||
<img src="/images/hoc2015/tips-test-animation.gif" alt="Tips Window Animation" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -248,7 +248,7 @@ var Hoc = React.createClass({
|
|||
<div className="card">
|
||||
<a href="/projects/editor/?tip_bar=getStarted">
|
||||
<div className="card-info">
|
||||
<img src="/images/hoc2015/getting-started-tutorial.jpg" />
|
||||
<img src="/images/hoc2015/getting-started-tutorial.jpg" alt="" />
|
||||
<Button>
|
||||
<FormattedMessage
|
||||
id='general.tipsGetStarted'
|
||||
|
@ -261,7 +261,7 @@ var Hoc = React.createClass({
|
|||
<div className="card">
|
||||
<a href="/bearstack/">
|
||||
<div className="card-info">
|
||||
<img src="/images/hoc2015/bearstack-tutorial.jpg" />
|
||||
<img src="/images/hoc2015/bearstack-tutorial.jpg" alt="" />
|
||||
<Button>
|
||||
<FormattedMessage
|
||||
id='general.tipsBearstack'
|
||||
|
@ -274,7 +274,7 @@ var Hoc = React.createClass({
|
|||
<div className="card">
|
||||
<a href="/hoops">
|
||||
<div className="card-info">
|
||||
<img src="/images/hoc2015/bball-tutorial.jpg" />
|
||||
<img src="/images/hoc2015/bball-tutorial.jpg" alt="" />
|
||||
<Button>
|
||||
<FormattedMessage
|
||||
id='general.tipsBBallHoops'
|
||||
|
@ -305,7 +305,7 @@ var Hoc = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="studio">
|
||||
<img src="/svgs/studio.svg" />
|
||||
<img src="/svgs/studio.svg" alt="" />
|
||||
<div className="studio-info">
|
||||
<a href="/studios/432299/">
|
||||
<h5>
|
||||
|
@ -318,7 +318,7 @@ var Hoc = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="studio">
|
||||
<img src="/svgs/studio.svg" />
|
||||
<img src="/svgs/studio.svg" alt="" />
|
||||
<div className="studio-info">
|
||||
<a href="/studios/1672166/">
|
||||
<h5>
|
||||
|
@ -331,7 +331,7 @@ var Hoc = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="studio">
|
||||
<img src="/svgs/studio.svg" />
|
||||
<img src="/svgs/studio.svg" alt="" />
|
||||
<div className="studio-info">
|
||||
<a href="/studios/1065372/">
|
||||
<h5>
|
||||
|
@ -344,7 +344,7 @@ var Hoc = React.createClass({
|
|||
</div>
|
||||
|
||||
<div className="studio">
|
||||
<img src="/svgs/studio.svg" />
|
||||
<img src="/svgs/studio.svg" alt="" />
|
||||
<div className="studio-info">
|
||||
<a href="/studios/1672164/">
|
||||
<h5>
|
||||
|
@ -366,22 +366,22 @@ var Hoc = React.createClass({
|
|||
</h3>
|
||||
<div className="logos">
|
||||
<a href="http://scratched.gse.harvard.edu/">
|
||||
<img src="/images/hoc2015/scratchEd-logo.png" />
|
||||
<img src="/images/hoc2015/scratchEd-logo.png" alt="ScratchEd" />
|
||||
</a>
|
||||
<a href="https://code.org/">
|
||||
<img src="/images/hoc2015/code-org-logo.png" />
|
||||
<img src="/images/hoc2015/code-org-logo.png" alt="code.org" />
|
||||
</a>
|
||||
<a href="http://www.cartoonnetwork.com/">
|
||||
<img src="/images/hoc2015/cn-logo.png" />
|
||||
<img src="/images/hoc2015/cn-logo.png" alt="Cartoon Network" />
|
||||
</a>
|
||||
<a href="http://www.madewithcode.com/">
|
||||
<img src="/images/hoc2015/made-with-code-logo.png" />
|
||||
<img src="/images/hoc2015/made-with-code-logo.png" alt="Made with Code" />
|
||||
</a>
|
||||
<a href="http://www.paalive.org/">
|
||||
<img src="/images/hoc2015/paa-logo.png" />
|
||||
<img src="/images/hoc2015/paa-logo.png" alt="Progressive Arts Alliance" />
|
||||
</a>
|
||||
<a href="http://www.catrobat.org/">
|
||||
<img src="/images/hoc2015/pocketcode-logo.png" />
|
||||
<img src="/images/hoc2015/pocketcode-logo.png" alt="Pocket Code" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -77,10 +77,6 @@ $base-bg: $ui-white;
|
|||
min-width: 200px;
|
||||
max-width: 230px;
|
||||
|
||||
a {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.card-info {
|
||||
border-radius: 5px;
|
||||
background-color: $base-bg;
|
||||
|
@ -203,10 +199,6 @@ $base-bg: $ui-white;
|
|||
.studio {
|
||||
width: 50%;
|
||||
|
||||
a {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
h5 {
|
||||
width: 200px;
|
||||
}
|
||||
|
@ -239,10 +231,6 @@ $base-bg: $ui-white;
|
|||
margin: 20px 0;
|
||||
width: 100%;
|
||||
|
||||
a {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
img {
|
||||
margin: 20px;
|
||||
max-width: 150px;
|
||||
|
|
19
src/views/hoc/l10n.json
Normal file
19
src/views/hoc/l10n.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"hoc.activityCards": "Activity Cards",
|
||||
"hoc.activityCardsHeader": "Activity Cards and Guides",
|
||||
"hoc.activityCardsInfo1": "Want tips and ideas for these Hour of Code™ activities? Use the activity cards to get ideas for creating with Scratch. Facilitator guides can help you plan a group activity.",
|
||||
"hoc.addToStudios": "Add Your Projects to Studios",
|
||||
"hoc.addToStudiosDescription": "These studios include projects created by young people around the world. Take a look at the studios to get inspired - or submit your own projects to the studios!",
|
||||
"hoc.facilitatorGuide": "Facilitator Guide",
|
||||
"hoc.findOutMore": "Find out more",
|
||||
"hoc.helpScratch": "Help with Scratch",
|
||||
"hoc.helpScratchDescription": "You can find tutorials and helpful hints in the <a href=\"/projects/editor/?tip_bar=home\">Tips Window</a>. For more resources, see <a href=\"/help\">Scratch Help</a>",
|
||||
"hoc.moreActivities": "Want More Activities?",
|
||||
"hoc.moreDescription": "Check out these other tutorials. Or remix one of our <a href=\"/starter_projects\">Starter Projects</a>",
|
||||
"hoc.officialNotice": "The \"Hour of Code™\" is a nationwide initiative by <a href=\"http://csedweek.org\">Computer Science Education Week</a> and <a href=\"http://code.org\">Code.org</a> to introduce millions of students to one hour of computer science and computer programming.",
|
||||
"hoc.studioAlice": "Alice in Wonderland Studio",
|
||||
"hoc.studioWeBareBears": "We Bare Bears Studio",
|
||||
"hoc.subTitle": "With Scratch, you can program your own stories, games, and animations — and share them online.",
|
||||
"hoc.tipsDescription": "Need help getting started? Looking for ideas? You can find tutorials and helpful hints in the <a href=\"/projects/editor/?tip_bar=home\">Tips Window</a>",
|
||||
"hoc.title": "Get Creative with Coding"
|
||||
}
|
28
src/views/splash/l10n.json
Normal file
28
src/views/splash/l10n.json
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"splash.featuredProjects": "Featured Projects",
|
||||
"splash.featuredStudios": "Featured Studios",
|
||||
"splash.projectsCuratedBy": "Projects Curated by",
|
||||
"splash.scratchDesignStudioTitle": "Scratch Design Studio",
|
||||
"splash.visitTheStudio": "Visit the studio",
|
||||
"splash.recentlySharedProjects": "Recently Shared Projects",
|
||||
"splash.projectsByScratchersFollowing": "Projects by Scratchers I'm Following",
|
||||
"splash.projectsLovedByScratchersFollowing": "Projects Loved by Scratchers I'm Following",
|
||||
"splash.projectsInStudiosFollowing": "Projects in Studios I'm Following",
|
||||
"splash.communityRemixing": "What the Community is Remixing",
|
||||
"splash.communityLoving": "What the Community is Loving",
|
||||
|
||||
"intro.aboutScratch": "ABOUT SCRATCH",
|
||||
"intro.forEducators": "FOR EDUCATORS",
|
||||
"intro.forParents": "FOR PARENTS",
|
||||
"intro.joinScratch": "JOIN SCRATCH",
|
||||
"intro.seeExamples": "SEE EXAMPLES",
|
||||
"intro.tagLine": "Create stories, games, and animations<br /> Share with others around the world",
|
||||
"intro.tryItOut": "TRY IT OUT",
|
||||
|
||||
"news.scratchNews": "Scratch News",
|
||||
|
||||
"welcome.welcomeToScratch": "Welcome to Scratch!",
|
||||
"welcome.learn": "Learn how to make a project in Scratch",
|
||||
"welcome.tryOut": "Try out starter projects",
|
||||
"welcome.connect": "Connect with other Scratchers"
|
||||
}
|
|
@ -28,11 +28,11 @@ var Splash = injectIntl(React.createClass({
|
|||
getInitialState: function () {
|
||||
return {
|
||||
projectCount: 10569070,
|
||||
activity: [],
|
||||
news: [],
|
||||
featuredCustom: {},
|
||||
featuredGlobal: {},
|
||||
showEmailConfirmationModal: false,
|
||||
activity: [], // recent social actions taken by users someone is following
|
||||
news: [], // gets news posts from the scratch Tumblr
|
||||
featuredCustom: {}, // custom homepage rows, such as "Projects by Scratchers I'm Following"
|
||||
featuredGlobal: {}, // global homepage rows, such as "Featured Projects"
|
||||
showEmailConfirmationModal: false, // flag that determines whether to show banner to request email conf.
|
||||
refreshCacheStatus: 'notrequested'
|
||||
};
|
||||
},
|
||||
|
@ -318,6 +318,25 @@ var Splash = injectIntl(React.createClass({
|
|||
var featured = this.renderHomepageRows();
|
||||
var emailConfirmationStyle = {width: 500, height: 330, padding: 1};
|
||||
var homepageCacheState = this.getHomepageRefreshStatus();
|
||||
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
var formatHTMLMessage = this.props.intl.formatHTMLMessage;
|
||||
var messages = {
|
||||
'general.viewAll': formatMessage({id: 'general.viewAll'}),
|
||||
'news.scratchNews': formatMessage({id: 'news.scratchNews'}),
|
||||
'welcome.welcomeToScratch': formatMessage({id: 'welcome.welcomeToScratch'}),
|
||||
'welcome.learn': formatMessage({id: 'welcome.learn'}),
|
||||
'welcome.tryOut': formatMessage({id: 'welcome.tryOut'}),
|
||||
'welcome.connect': formatMessage({id: 'welcome.connect'}),
|
||||
'intro.aboutScratch': formatMessage({id: 'intro.aboutScratch'}),
|
||||
'intro.forEducators': formatMessage({id: 'intro.forEducators'}),
|
||||
'intro.forParents': formatMessage({id: 'intro.forParents'}),
|
||||
'intro.joinScratch': formatMessage({id: 'intro.joinScratch'}),
|
||||
'intro.seeExamples': formatMessage({id: 'intro.seeExamples'}),
|
||||
'intro.tagLine': formatHTMLMessage({id: 'intro.tagLine'}),
|
||||
'intro.tryItOut': formatMessage({id: 'intro.tryItOut'})
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="splash">
|
||||
{this.shouldShowEmailConfirmation() ? [
|
||||
|
@ -341,14 +360,16 @@ var Splash = injectIntl(React.createClass({
|
|||
{this.state.session.user ? [
|
||||
<div key="header" className="splash-header">
|
||||
{this.shouldShowWelcome() ? [
|
||||
<Welcome key="welcome" onDismiss={this.handleDismiss.bind(this, 'welcome')}/>
|
||||
<Welcome key="welcome"
|
||||
onDismiss={this.handleDismiss.bind(this, 'welcome')}
|
||||
messages={messages} />
|
||||
] : [
|
||||
<Activity key="activity" items={this.state.activity} />
|
||||
]}
|
||||
<News items={this.state.news} />
|
||||
<News items={this.state.news} messages={messages} />
|
||||
</div>
|
||||
] : [
|
||||
<Intro projectCount={this.state.projectCount} key="intro"/>
|
||||
<Intro projectCount={this.state.projectCount} messages={messages} key="intro"/>
|
||||
]}
|
||||
|
||||
{featured}
|
||||
|
|
|
@ -3,7 +3,7 @@ var path = require('path');
|
|||
var po2icu = require('po2icu');
|
||||
var tap = require('tap');
|
||||
|
||||
var buildLocales = require('../../lib/locale-compare');
|
||||
var buildLocales = require('../../bin/lib/locale-compare');
|
||||
|
||||
tap.test('buildLocalesFile', function (t) {
|
||||
var md5map = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../fixtures/test_es_md5map.json'), 'utf8'));
|
||||
|
|
|
@ -2,7 +2,7 @@ var fs = require('fs');
|
|||
var path = require('path');
|
||||
var tap = require('tap');
|
||||
|
||||
var buildLocales = require('../../lib/locale-compare');
|
||||
var buildLocales = require('../../bin/lib/locale-compare');
|
||||
|
||||
tap.test('buildLocalesFile', function (t) {
|
||||
var actualMd5map = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../fixtures/test_es_md5map.json'), 'utf8'));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var tap = require('tap');
|
||||
|
||||
var buildLocales = require('../../lib/locale-compare');
|
||||
var buildLocales = require('../../bin/lib/locale-compare');
|
||||
|
||||
tap.test('buildLocalesMergeTranslations', function (t) {
|
||||
var existingTranslations = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var tap = require('tap');
|
||||
|
||||
var buildLocales = require('../../lib/locale-compare');
|
||||
var buildLocales = require('../../bin/lib/locale-compare');
|
||||
|
||||
tap.test('buildLocalesGetMD5', function (t) {
|
||||
var testString1 = 'are there bears here?';
|
||||
|
|
|
@ -6,8 +6,7 @@ var routes = require('./server/routes.json');
|
|||
|
||||
// Prepare all entry points
|
||||
var entry = {
|
||||
init: './src/init.js',
|
||||
main: './src/main.jsx'
|
||||
init: './src/init.js'
|
||||
};
|
||||
routes.forEach(function (route) {
|
||||
entry[route.view] = './src/views/' + route.view + '/' + route.view + '.jsx';
|
||||
|
@ -53,7 +52,8 @@ module.exports = {
|
|||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin([
|
||||
{from: 'static'}
|
||||
{from: 'static'},
|
||||
{from: 'intl', to: 'js'}
|
||||
]),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
|
|
Loading…
Reference in a new issue