]}
{this.state.swfVersion === -1 ? [
From 32fc959ed28e5a9d0ddcd24cac6d080d145275b4 Mon Sep 17 00:00:00 2001
From: Andrew Sliwinski
Date: Wed, 16 May 2018 09:44:11 -0400
Subject: [PATCH 09/32] Remove references to Linux in download l10n strings
---
src/views/download/l10n.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/views/download/l10n.json b/src/views/download/l10n.json
index 48ecdd50c..3c5144115 100644
--- a/src/views/download/l10n.json
+++ b/src/views/download/l10n.json
@@ -1,6 +1,6 @@
{
"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 Mac, Windows, and some versions of Linux (32 bit).",
+ "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",
@@ -8,7 +8,6 @@
"download.macOSX": "Mac OS X",
"download.macOlder": "Mac OS 10.5 & Older",
"download.windows": "Windows",
- "download.linux": "Linux",
"download.download": "Download",
"download.offlineEditorTitle": "Scratch Offline Editor",
"download.offlineEditorBody": "Next download and install the Scratch 2.0 Offline Editor",
From e7f57122c220e8422196006f09fda5ed5f710ba5 Mon Sep 17 00:00:00 2001
From: BryceLTaylor
Date: Thu, 17 May 2018 11:33:21 -0400
Subject: [PATCH 10/32] Make Selenium Helper function to click element by CSS
---
test/integration/selenium-helpers.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/test/integration/selenium-helpers.js b/test/integration/selenium-helpers.js
index 82a3abe58..faf658ec9 100644
--- a/test/integration/selenium-helpers.js
+++ b/test/integration/selenium-helpers.js
@@ -30,6 +30,10 @@ const findByCss = (css) => {
return driver.wait(until.elementLocated(By.css(css), 1000 * 5));
};
+const clickCss = (css) => {
+ return findByCss(css).then(el => el.click());
+};
+
const getLogs = (whitelist) => {
return driver.manage()
.logs()
@@ -65,5 +69,6 @@ module.exports = {
findText,
clickButton,
findByCss,
+ clickCss,
getLogs
};
From 86e9549ceea51f9842515ec4283260b3c03e7669 Mon Sep 17 00:00:00 2001
From: BryceLTaylor
Date: Thu, 17 May 2018 11:52:05 -0400
Subject: [PATCH 11/32] Make all Selenium tests of login-failures work and use
css to select elements.
---
.../smoke-testing/test-login-failures.js | 62 +++++++++----------
1 file changed, 30 insertions(+), 32 deletions(-)
diff --git a/test/integration/smoke-testing/test-login-failures.js b/test/integration/smoke-testing/test-login-failures.js
index ea7b9a78d..fca6c9c01 100644
--- a/test/integration/smoke-testing/test-login-failures.js
+++ b/test/integration/smoke-testing/test-login-failures.js
@@ -1,10 +1,8 @@
const {
- clickText,
- findByXpath,
- clickButton,
driver,
- until,
- By
+ findByCss,
+ clickCss,
+ until
} = require('../selenium-helpers.js');
var username = process.env.SMOKE_USERNAME;
@@ -31,17 +29,17 @@ test('Trying to sign in with no password using scratchr2 navbar', t => {
var nonsenseusername = Math.random().toString(36)
.replace(/[^a-z]+/g, '')
.substr(0, 5);
- clickText('Sign in')
- .then(() => findByXpath('//input[@id="login_dropdown_username"]'))
+ clickCss('.dropdown-toggle')
+ .then(() => findByCss('form#login input#login_dropdown_username'))
.then((element) => element.sendKeys(nonsenseusername))
- .then(() => clickButton('Sign in'))
- .then(() => driver.wait(until
- .elementLocated(By.xpath('//form[@id="login"]/button[@type="submit"]'))))
- .then(() => driver.wait(until
- .elementLocated(By.xpath('//form[@id="login"]/div[@class="error"]'))))
- .then(() => findByXpath('//form/div[@class="error"]'))
+ .then(() => clickCss('form#login button'))
+ .then(() => findByCss('form#login .error'))
+ .then((element) => {
+ driver.wait(until.elementIsVisible(element));
+ return element;
+ })
.then((element) => element.getText())
- .then((text) => t.match(text, 'This field is required.',
+ .then((text) => t.match(text, 'This field is required',
'"This field is required" error should be displayed'))
.then(() => t.end());
});
@@ -50,17 +48,17 @@ test('Trying to sign in with the wrong username using scratchr2 navbar', t => {
var nonsenseusername = Math.random().toString(36)
.replace(/[^a-z]+/g, '')
.substr(0, 5);
- clickText('Sign in')
- .then(() => findByXpath('//input[@id="login_dropdown_username"]'))
+ clickCss('.dropdown-toggle')
+ .then(() => findByCss('form#login input#login_dropdown_username'))
.then((element) => element.sendKeys(nonsenseusername))
- .then(() => findByXpath('//input[@name="password"]'))
+ .then(() => findByCss('form#login input.wide.password'))
.then((element) => element.sendKeys(password))
- .then(() => clickButton('Sign in'))
- .then(() => driver.wait(until
- .elementLocated(By.xpath('//form[@id="login"]/button[@type="submit"]'))))
- .then(() => driver.wait(until
- .elementLocated(By.xpath('//form[@id="login"]/div[@class="error"]'))))
- .then(() => findByXpath('//form/div[@class="error"]'))
+ .then(() => clickCss('form#login button'))
+ .then(() => findByCss('form#login .error'))
+ .then((element) => {
+ driver.wait(until.elementIsVisible(element));
+ return element;
+ })
.then((element) => element.getText())
.then((text) => t.match(text, 'Incorrect username or password.',
'"Incorrect username or password" error should be displayed'))
@@ -68,17 +66,17 @@ test('Trying to sign in with the wrong username using scratchr2 navbar', t => {
});
test('Trying to sign in with the wrong password using scratchr2 navbar', t => {
- clickText('Sign in')
- .then(() => findByXpath('//input[@id="login_dropdown_username"]'))
+ clickCss('.dropdown-toggle')
+ .then(() => findByCss('form#login input#login_dropdown_username'))
.then((element) => element.sendKeys(username))
- .then(() => findByXpath('//input[@name="password"]'))
+ .then(() => findByCss('form#login input.wide.password'))
.then((element) => element.sendKeys('nonsensepassword'))
- .then(() => clickButton('Sign in'))
- .then(() => driver.wait(until
- .elementLocated(By.xpath('//form[@id="login"]/button[@type="submit"]'))))
- .then(() => driver.wait(until
- .elementLocated(By.xpath('//form[@id="login"]/div[@class="error"]'))))
- .then(() => findByXpath('//form/div[@class="error"]'))
+ .then(() => clickCss('form#login button'))
+ .then(() => findByCss('form#login .error'))
+ .then((element) => {
+ driver.wait(until.elementIsVisible(element));
+ return element;
+ })
.then((element) => element.getText())
.then((text) => t.match(text, 'Incorrect username or password.',
'"Incorrect username or password" error should be displayed'))
From 881c2affa462cad3c66bb238ccbcce579a8e4c4d Mon Sep 17 00:00:00 2001
From: Andrew Sliwinski
Date: Mon, 21 May 2018 15:55:21 -0400
Subject: [PATCH 12/32] Update privacy policy
---
src/views/privacypolicy/privacypolicy.jsx | 561 ++++++++++++++++------
1 file changed, 406 insertions(+), 155 deletions(-)
diff --git a/src/views/privacypolicy/privacypolicy.jsx b/src/views/privacypolicy/privacypolicy.jsx
index ea988dda7..0db9ca512 100644
--- a/src/views/privacypolicy/privacypolicy.jsx
+++ b/src/views/privacypolicy/privacypolicy.jsx
@@ -9,213 +9,464 @@ const Privacypolicy = () => (
+
+
+ The Scratch Privacy Policy was last updated: May 23, 2018
+
+
- We made Scratch so people like you could create projects,
- share ideas, and build a community. To make this happen,
- we collect some information for our users. The Scratch Team
- understands how important privacy is to our community,
- especially kids and parents. We wrote this privacy policy
- to explain what information we collect, how we use it,
- and what we're doing to keep it safe. If you have any
- questions regarding this privacy policy, you can{' '}
- contact us.
+ Scratch understands how important privacy is to our
+ community, especially kids and parents. We wrote this
+ Privacy Policy to explain what information we collect
+ through our website (scratch.mit.edu) (the “Site”), how we
+ use, process, and share it, and what we're doing to keep it
+ safe. It also tells you about your rights and choices with
+ respect to your information, and how you can{' '}
+ contact us if you have any
+ questions or concerns.
- Please do not share personal contact information, such as
- your name, physical address, email address, phone number,
- or anything else that can be used to make contact outside
- of the Scratch website. Please report projects, comments,
- or forum posts that contain this kind of information so
- the Scratch team can remove it, and please remind the
- author of our policy.
+ If you would like to build projects with Scratch without
+ submitting any Personal Information to us, you can download
+ the Scratch Offline Editor. Projects
+ created in the Scratch Offline Editor
+ {' '}are not accessible by the Scratch Team, and using the
+ offline editor does not disclose any personally identifying
+ information to Scratch unless you upload these projects to
+ the Scratch online community.
-
What information does the Scratch Team collect about me?
-
Account Information:
+
What personal information does the Scratch Team collect about me?
+
+ For the purpose of this Privacy Policy, “Personal
+ Information” means any information relating to an
+ identified or identifiable individual. We obtain
+ Personal Information relating to you from various
+ sources described below.
+
+
+ Where applicable, we indicate whether and why you must
+ provide us with your Personal Information, as well as
+ the consequences of failing to do so. If you do not
+ provide Personal Information when requested, you may not
+ be able to benefit from our Site if that information is
+ necessary to provide you with the service or if we are
+ legally required to collect the information.
+
+
Account Information
- In order to build projects or comment on other users' projects,
- you need to make an account. During account creation, we ask you
- for a username, your country, birth month and year, gender, and
- your email address (or your parent or guardian's email address if
- you are under 13 years old). We ask that you select a user name
- that does not disclose your real name or other information that
- could identify you. Other users can see your username and country,
- but not your age, gender, or email address.
+ In order to share projects, create studios, or post
+ comments, you need to make an account. During account
+ creation, we ask you for a username, your country, birth
+ month and year, gender, and your email address (or your
+ parent or guardian's email address if you are under 16
+ years old). We ask that you select a username that does
+ not disclose your real name or other information that
+ could identify you. Other users can see your username
+ and country, but not your age, gender, or email address.
-
User-generated Content:
+
User-generated Content
- All of your Scratch projects, comments, and forum posts are stored
- on the Scratch servers. Other users can see your shared projects,
- comments, and forum posts, along with your username. Because the
- Scratch Team is responsible for moderation, we have access to all
- content stored on the Scratch website, including unshared projects.
- If you prefer to work on projects in complete privacy, you can use
- either the Scratch 2{' '}
- or Scratch 1.4 offline editor.
+ We collect any information that you provide to us when
+ you create Scratch projects (including unshared
+ projects), write comments, or post on our forums.
-
Usage Information:
+
Communications
- When you use Scratch, our servers will automatically store a limited
- amount of information about how you use the website. This information
- includes a number that identifies your computer (the IP address), which
- pages you visited, and what browser you are using.
+ If you contact us directly, we may receive additional
+ information about you. For example, when you contact our
+ Customer Support Team, we may receive your name, email
+ address, phone number, the contents of a message or
+ attachments that you may send to us, and other
+ information you choose to provide.
-
Google Analytics:
+
+ Personal Information We Collect Automatically From Your
+ Use of the Site
+
- We also collect some data on where you click and which parts of the
- site you visit using Google Analytics. This "click data" helps us figure
- out ways to improve the website. Information collected and processed by
- Google Analytics includes the user's IP address, network location, and
- geographic location. Google Analytics acquires all its information
- directly from the user, by installing a cookie (see below) on your
- computer, if you have enabled JavaScript. Scratch does not share any
- information it collects with Google, and Google does not collect any
- personal identifying information about you.
+ When you use Scratch, we and our third-party service
+ providers collect information about you and your device
+ through automated means, such as cookies and web server
+ logs. By using Scratch, you consent to the placement of
+ cookies and similar technologies in your browser in
+ accordance with this Privacy Policy. The information
+ collected in this manner includes your IP address,
+ network location, what browser you are using, device IDs
+ and characteristics, operating system version, language
+ preferences, referring URLs, and information about the
+ usage of our site.
-
Cookies:
- When you log in, the Scratch website asks your browser to put an http
- "cookie" on your computer. The cookie is actually a small text file
- that our site can send to your browser for storage on your computer.
- This allows the website to remember that you are logged in when you
- go to a different page.
+ We use this information, for example, to ensure that the
+ site functions properly, to determine how many users
+ have visited certain pages, or to prevent fraud. We use
+ IP address information to derive your approximate
+ location. We also work with analytics providers, such
+ as Google Analytics, which use cookies and similar
+ technologies to collect and analyze information about
+ use of the site and report on activities and trends.
+ These services may also collect information about the
+ use of other websites, apps, and online resources. You
+ can learn more about Google’s practices by going to{' '}
+
+ https://www.google.com/policies/privacy/partners/.
+
+
+ If you do not want information collected through the use
+ of cookies, most browsers allow you to automatically
+ decline cookies or be given the choice of declining or
+ accepting the transfer to your computer of a particular
+ cookie (or cookies) from a particular site. You may also
+ wish to refer to{' '}
+
+ http://www.allaboutcookies.org/manage-cookies/index.html.
+ If, however, you do not accept cookies, you may
+ experience some inconvenience in your use of Scratch.
+
+
+
How does the Scratch Team use my personal information?
+
+
Internal and Service-Related Usage
+
+ We use Personal Information for internal and Site-related
+ purposes, including to operate, provide, and maintain the
+ Site.
+
+
Analytics and Improving the Site
+
+ We and our service providers use Personal Information
+ that we collect on the Site, such as your location and
+ your activities on the Site, to monitor and analyze
+ usage of the Site and to improve and enhance the Site.
+
+
Communications
+
+ We may send emails to an email address you provide to us
+ for customer-service or technical-support purposes, to
+ send you information about topics or content that we
+ think may interest you, or updates about the latest
+ developments or features on the Site. We may also send a
+ newsletter to the email address you provide to us if you
+ subscribe to receive the newsletter. Parents and
+ guardians who register their under-16 year olds for
+ Scratch may also receive additional updates from the
+ Scratch Foundation, a non-profit that supports Scratch
+ educational initiatives.
+
+
Aggregate Data
+
+ We may de-identify and aggregate information collected
+ through the Site for statistical analysis and other
+ lawful purpose, including in research studies intended
+ to improve our understanding of how people learn with
+ Scratch. The results of this research are shared with
+ educators and researchers through conferences, journals,
+ and other publications. You can find out more on our{' '}
+ Research page.
+
+
Legal
+
+ We may use your Personal Information to enforce our{' '}
+ Terms of Use, to defend our
+ legal rights, and to comply with our legal obligations
+ and internal policies. We moderate all content posted to
+ Scratch, including unshared projects, comments, and
+ forum posts.
+
+
+ If you are located in the European Economic Area, we
+ only process your Personal Information based on a valid
+ legal ground, including when:
+
+
+
+ You have consented to the use of your Personal
+ Information, for example, to receive electronic
+ marketing communications;
+
+
+ We need your Personal Information to provide our
+ services, including for account registration, to
+ respond to your inquiries, or for customer support;
+
+
+ We have a legal obligation to use your Personal
+ Information; or
+
+
+ We or a third party have a legitimate interest in
+ using your Personal Information. In particular, we
+ have a legitimate interest in using your Personal
+ Information to personalize our services and provide
+ you with tailored content, conduct business
+ analytics, and otherwise improve the safety,
+ security, and performance of our Site. We only rely
+ on our or a third party’s legitimate interests to
+ process your Personal Information when these
+ interests are not overridden by your rights and
+ interests.
+
+
+
+
+
-
How does the Scratch Team use my information?
+
How Does Scratch Share my Personal Information?
+
+ We disclose information that we collect through the Site to
+ third parties in the following circumstances:
+
- We collect age and gender data so that we know who is using our
- website.
+ To third-party service providers who provide services
+ such as website hosting, data analysis, information
+ technology and related infrastructure provisions,
+ customer service, email delivery, and other services.
- If you forget your password, we will ask you to disclose to us
- your birth month and year so that we can verify your account, and
- your email address so that we can send you a new password.
+ We may also disclose your Personal Information with your
+ permission. We may seek your permission in various ways.
+ For example, we may present you with an “opt-in” prompt
+ when you register to use the Site or access certain
+ content.
- We will use your email address to respond to messages you send us
- or to communicate with you about the Scratch service or your account.
+ To a potential or actual acquirer, successor, or
+ assignee as part of any reorganization, merger, sale,
+ joint venture, assignment, transfer, or other
+ disposition of all or any portion of our organization or
+ assets. You will have the opportunity to opt out of any
+ such transfer if the new entity’s planned processing of
+ your information differs materially from that set forth
+ in this Privacy Policy.
- We send out occasional email updates about Scratch to the confirmed
- email address on your account. Scratch will never sell or share your
- email address without your permission. You can unsubscribe from these
- updates by clicking the unsubscribe link found at the bottom of the
- email.
-
-
- Parents and guardians who register their under-13 year olds for
- Scratch may also receive additional updates from the{' '}
- Scratch Foundation,
- a non-profit that supports Scratch educational initiatives.
- The Scratch Foundation will never sell or share your email
- address without your permission. You can unsubscribe from these
- updates by clicking the unsubscribe link found at the bottom of
- the email.
-
-
- If we detect repeated abusive behavior from your account, IP address,
- or email address, we may share your account name, IP address, and the
- time and content of the abusive behavior with the IP address owner
- (such as a school or internet service provider).
-
-
- We may use de-identified location, age, gender, and usage data
- in research studies intended to improve our understanding of
- how people learn with Scratch. The results of this research are
- shared with educators and researchers through conferences,
- journals, and other publications. You can find out more on our{' '}
- Research page.
-
-
- We may disclose some of the information we collect to third-party
- service providers that help us manage communications to and from
- the Scratch website and improve website performance. We are
- satisfied that these service providers have privacy policies that
- restrict them from further disclosing any of your information.
-
-
- Other than as described above, we will never share personally
- identifiable information about you with any other person,
- company, or organization, except:
-
-
- As required to comply with our obligations under the law.
-
-
- For technical reasons, if we are required to transfer the
- data on our servers to another location or organization.
-
-
-
-
- Scratch reserves the right to share user information with the
- appropriate authorities (including schools, school districts,
- and law enforcement, when necessary) for the purposes of protecting
- the safety of users, other individuals, or the security of the site.
+ If required to do so by law or in the good faith belief
+ that such action is appropriate: (a) under applicable
+ law, including laws outside your country of residence;
+ (b) to comply with legal process; (c) to respond to
+ requests from public and government authorities, such
+ as school, school districts, and law enforcement,
+ including public and government authorities outside your
+ country of residence; (d) to enforce our terms and
+ conditions; (e) to protect our operations or those of
+ any of our affiliates; (f) to protect our rights,
+ privacy, safety, or property, and/or that of our
+ affiliates, you, or others; and (g) to allow us to
+ pursue available remedies or limit the damages that we
+ may sustain.
-
+
-
How can I update my personal information?
+
Third Party Services
- You can update your password, email address, and country through
- the Account Settings page.
- You can also reset your password through the{' '}
- Account Reset{' '}
- page. You cannot change your username, but you can make a new
- account and manually copy your projects to the new account.
+ This Privacy Policy applies only to the processing of your
+ Personal Information by Scratch. It does not address, and we
+ are not responsible for, the privacy, information, or other
+ practices of any third parties, including any third party
+ operating any site or service to which the Site links. The
+ inclusion of a link on the Site does not imply endorsement
+ of the linked site or service by us or by our affiliates.
+
+
+
+
Your Rights and Choices
+
+
+
Updating Your Information
+
+ You can update your password, email address, and country
+ through the Account
+ Settings page. You can also reset your password
+ through the Account
+ Reset page. You cannot change your username, but you
+ can make a new account and manually copy your projects
+ to the new account.
+
+
+ If you want to delete your account, login to Scratch,
+ and then click your username in the top right-hand
+ corner. Select "Account Settings," then click the "I
+ want to delete my account" link at the bottom of the
+ page. Deleting your account hides all information from
+ public view, but does not remove all of your information
+ from our servers. If you want to have all of your
+ information removed from our servers, please contact
+ help@scratch.mit.edu for assistance.
+
+
Marketing Communications
+
+ If you decide at any time that you no longer wish to
+ receive marketing communications from us, please follow
+ the unsubscribe instructions provided in any of the
+ communications. You may also opt out from receiving
+ email from us by sending your request to us by email at
+ help@scratch.mit.edu. Please be aware that, even after
+ you opt out from receiving marketing communications from
+ us, you may continue to receive administrative messages
+ from us regarding the Site.
+
+
Your Data Protection Rights (EEA)
+
+ In certain jurisdictions, you have the right to request
+ access and receive information about the Personal
+ Information we maintain about you, to update and correct
+ inaccuracies in your Personal Information, to restrict
+ or object to the processing of your Personal
+ Information, to have the information blocked,
+ anonymized, or deleted, as appropriate, or to exercise
+ your right to data portability to easily transfer your
+ Personal Information to another company. Those rights
+ may be limited in some circumstances by local law
+ requirements. In addition to the above-mentioned rights,
+ you also have the right to lodge a complaint with a
+ competent supervisory authority subject to applicable
+ law.
+
+
+ Where required by law, we obtain your consent for the
+ processing of certain Personal Information collected by
+ cookies or similar technologies, or used to send you
+ direct marketing communications, or when we carry out
+ other processing activities for which consent may be
+ required. If we rely on consent for the processing of
+ your Personal Information, you have the right to
+ withdraw it at any time and free of charge. When you do
+ so, this will not affect the lawfulness of the
+ processing before your consent withdrawal.
+
+
+ To update your preferences, ask us to remove your
+ information from our mailing lists, or submit a request
+ to exercise your rights under applicable law, please
+ contact us as specified in the “How to Contact Us”
+ section below.
+
+
+
+
+
+
Data Retention
- If you want to delete your account entirely, log in to Scratch,
- and then click your username in the top right-hand corner. Select
- "Account Settings," then click the "I want to delete my account"
- link at the bottom of the page.
+ We take measures to delete your Personal Information or keep
+ it in a form that does not allow you to be identified when
+ this information is no longer necessary for the purposes for
+ which we process it, unless we are required by law to keep
+ this information for a longer period. When determining the
+ retention period, we take into account various criteria,
+ such as the type of services requested by or provided to
+ you, the nature and length of our relationship with you,
+ possible re-enrolment with our services, the impact on the
+ services we provide to you if we delete some information
+ from or about you, mandatory retention periods provided by
+ law and the statute of limitations.
-
How does the Scratch Team protect my information?
+
How does the Scratch Team protect my personal information?
- The Scratch Team has in place physical and electronic procedures
- to protect the information we collect on the Scratch website. We
- strictly limit individual access to the Scratch servers and the
- data we store on them. However, as effective as these measures
- are, no security system is impenetrable. We cannot completely
- guarantee the security of our database, nor can we guarantee that
- the information you supply will not be intercepted while being
- transmitted to us over the Internet.
+ The Scratch Team has in place administrative, physical, and
+ technical procedures that are intended to protect the
+ information we collect on the Scratch website against
+ accidental or unlawful destruction, accidental loss,
+ unauthorized alteration, unauthorized disclosure or access,
+ misuse, and any other unlawful form of processing of the
+ Personal Information in our possession. For example, we
+ strictly limit access to the Scratch servers and the data we
+ store on them. However, as effective as these measures are,
+ no security system is impenetrable. We cannot completely
+ guarantee the security of our databases, nor can we
+ guarantee that the information you supply will not be
+ intercepted while being transmitted to us over the Internet.
-
Notifications of Changes to the Privacy Policy
+
Notifications of changes to the Privacy Policy
- We review our security measures and Privacy Policy on a periodic
- basis, and we may modify our policies as appropriate. We may also
- change or update our Privacy Policy if we add new services or
- features. If we make any changes to our privacy practices, we will
- amend this Privacy Policy accordingly and post the amended policy
- on the Scratch website. We encourage you to review our Privacy
- Policy on a regular basis.
+ We review our security measures and Privacy Policy on a
+ periodic basis, and we may modify our policies as
+ appropriate. If we make material changes, we will notify you
+ through the Site or by sending you an email or other
+ communication. We encourage you to review our Privacy Policy
+ on a regular basis. The “Last Updated” date at the top of
+ this page indicates when this Privacy Policy was last
+ revised. Your continued use of the Site following these
+ changes means that you accept the revised Privacy Policy.
+
+
+
+
+
International Cross-Border Data Transfer
+
+ Scratch is based in the United States. Personal Information
+ that we collect may be transferred to, and stored at, any of
+ our affiliates, partners, or service providers which may be
+ inside or outside the European Economic Area, including the
+ United States. By submitting your personal data, you agree
+ to such transfers.
+
+
+
+
+
What can I do to help protect privacy on Scratch?
+
+ Please do not share personal contact information (such as
+ your name, physical address, email address, or phone number)
+ in projects, comments, profiles, studios, or forum posts.
+ Please let us know if you see this kind of information by
+ using the “Report” link which appears on the page. It is
+ also important that you maintain the security and control
+ of your account credentials, and not share your password
+ with anyone.
+
+
+
+
+
Contact Us
+
+ The Code-to-Learn Foundation d/b/a The Scratch Foundation is
+ the entity responsible for the processing of your Personal
+ Information. If you have any questions about this Privacy
+ Policy, or if you would like to exercise your rights to your
+ Personal Information, you may contact us at{' '}
+ help@scratch.mit.edu or
+ via mail at:
+
+
+ Scratch Foundation
+ ATTN: Privacy Policy
+ 7315 Wisconsin Ave.
+ 4th Floor West
+ Bethesda, MD 20814
-
The Scratch Privacy Policy was last updated: November 2016
From d78d78e1fa9660b892b060cafb610c4be306df5e Mon Sep 17 00:00:00 2001
From: Andrew Sliwinski
Date: Mon, 21 May 2018 15:55:42 -0400
Subject: [PATCH 13/32] Update default 'opt-in' state for teacher registration
---
src/components/registration/steps.jsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/registration/steps.jsx b/src/components/registration/steps.jsx
index b97960df6..4f090a8e0 100644
--- a/src/components/registration/steps.jsx
+++ b/src/components/registration/steps.jsx
@@ -1246,6 +1246,7 @@ class EmailStep extends React.Component {
value
help={null}
name="subscribe"
+ value={false}
valueLabel={
this.props.intl.formatMessage({id: 'registration.optIn'})
}
From 88e99e655bb0bc0a0b503420601f8f4cf77e19d7 Mon Sep 17 00:00:00 2001
From: Andrew Sliwinski
Date: Mon, 21 May 2018 17:04:50 -0400
Subject: [PATCH 14/32] Resolve lint issues
---
src/components/registration/steps.jsx | 1 -
src/views/privacypolicy/privacypolicy.jsx | 38 +++++++++++------------
2 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/src/components/registration/steps.jsx b/src/components/registration/steps.jsx
index 4f090a8e0..a1d752f99 100644
--- a/src/components/registration/steps.jsx
+++ b/src/components/registration/steps.jsx
@@ -1243,7 +1243,6 @@ class EmailStep extends React.Component {
validations="equalsField:user.email"
/>
(
Scratch understands how important privacy is to our
community, especially kids and parents. We wrote this
Privacy Policy to explain what information we collect
- through our website (scratch.mit.edu) (the “Site”), how we
- use, process, and share it, and what we're doing to keep it
- safe. It also tells you about your rights and choices with
- respect to your information, and how you can{' '}
+ through our website (scratch.mit.edu) (the "Site"),
+ how we use, process, and share it, and what we're doing
+ to keep it safe. It also tells you about your rights and
+ choices with respect to your information, and how you can{' '}
contact us if you have any
questions or concerns.
@@ -62,8 +62,8 @@ const Privacypolicy = () => (
comments, you need to make an account. During account
creation, we ask you for a username, your country, birth
month and year, gender, and your email address (or your
- parent or guardian's email address if you are under 16
- years old). We ask that you select a username that does
+ parent or guardian's email address if you are under
+ 16 years old). We ask that you select a username that does
not disclose your real name or other information that
could identify you. Other users can see your username
and country, but not your age, gender, or email address.
@@ -133,7 +133,7 @@ const Privacypolicy = () => (
How does the Scratch Team use my personal information?
-
+
Internal and Service-Related Usage
We use Personal Information for internal and Site-related
@@ -282,7 +282,7 @@ const Privacypolicy = () => (
If you want to delete your account, login to Scratch,
and then click your username in the top right-hand
- corner. Select "Account Settings," then click the "I
- want to delete my account" link at the bottom of the
- page. Deleting your account hides all information from
- public view, but does not remove all of your information
- from our servers. If you want to have all of your
- information removed from our servers, please contact
- help@scratch.mit.edu for assistance.
+ corner. Select "Account Settings," then click
+ the "I want to delete my account" link at the
+ bottom of the page. Deleting your account hides all
+ information from public view, but does not remove all of
+ your information from our servers. If you want to have
+ all of your information removed from our servers, please
+ contact help@scratch.mit.edu for assistance.
Marketing Communications
@@ -446,10 +446,10 @@ const Privacypolicy = () => (
via mail at:
- Scratch Foundation
- ATTN: Privacy Policy
- 7315 Wisconsin Ave.
- 4th Floor West
+ Scratch Foundation
+ ATTN: Privacy Policy
+ 7315 Wisconsin Ave.
+ 4th Floor West
Bethesda, MD 20814
Scratch Foundation
From f19a6c6196f12574ae340c529751b9de2b91547f Mon Sep 17 00:00:00 2001
From: Andrew Sliwinski
Date: Tue, 22 May 2018 16:15:26 -0400
Subject: [PATCH 18/32] Remove link from email address
---
src/views/privacypolicy/privacypolicy.jsx | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/views/privacypolicy/privacypolicy.jsx b/src/views/privacypolicy/privacypolicy.jsx
index c5b527005..a7f82e44d 100644
--- a/src/views/privacypolicy/privacypolicy.jsx
+++ b/src/views/privacypolicy/privacypolicy.jsx
@@ -441,9 +441,8 @@ const Privacypolicy = () => (
the entity responsible for the processing of your Personal
Information. If you have any questions about this Privacy
Policy, or if you would like to exercise your rights to your
- Personal Information, you may contact us at{' '}
- help@scratch.mit.edu
- {' '}or via mail at:
+ Personal Information, you may contact us at
+ help@scratch.mit.edu or via mail at:
Scratch Foundation
From 80de164d0201de74334c40d78df00ae4e0f3fbeb Mon Sep 17 00:00:00 2001
From: chrisgarrity
Date: Thu, 24 May 2018 16:23:07 -0400
Subject: [PATCH 19/32] Handle See inside button (#1890)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Handle See inside button
Import GUI reducers, initial state and middleware (throttle).
Update render to handle state and middleware.
Remove preview mode state and use scratchGui.mode from redux instead.
URL is getting updated, and mode will be updated based on URL. However, the history needs work - it doesn’t work with the modal back.
* Update to latest GUI
This is the minimum version of GUI that is needed for see-inside
* Really remove cruft.
---
package.json | 2 +-
src/lib/render.jsx | 23 ++++--
src/views/preview/presentation.jsx | 2 +-
src/views/preview/preview.jsx | 116 ++++++++++++++++++++++++-----
4 files changed, 118 insertions(+), 25 deletions(-)
diff --git a/package.json b/package.json
index 61b2d4a12..143b05f6e 100644
--- a/package.json
+++ b/package.json
@@ -95,7 +95,7 @@
"redux-thunk": "2.0.1",
"sass-lint": "1.5.1",
"sass-loader": "6.0.6",
- "scratch-gui": "0.1.0-prerelease.20180427201459",
+ "scratch-gui": "0.1.0-prerelease.20180522203439",
"scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master",
"slick-carousel": "1.6.0",
"source-map-support": "0.3.2",
diff --git a/src/lib/render.jsx b/src/lib/render.jsx
index 394eee801..3bbc66743 100644
--- a/src/lib/render.jsx
+++ b/src/lib/render.jsx
@@ -14,11 +14,13 @@ require('../main.scss');
/**
* Function to render views into a full page
- * @param {object} jsx jsx component of the view
- * @param {object} element html element to render to on the template
- * @param {array} reducers list of view-specific reducers
+ * @param {object} jsx jsx component of the view
+ * @param {object} element html element to render to on the template
+ * @param {array} reducers list of view-specific reducers
+ * @param {object} initialState optional initialState for store
+ * @param {bool} enhancer whether or not to apply redux-throttle middleware
*/
-const render = (jsx, element, reducers) => {
+const render = (jsx, element, reducers, initialState, enhancer) => {
// Get locale and messages from global namespace (see "init.js")
let locale = window._locale || 'en';
let messages = {};
@@ -35,9 +37,20 @@ const render = (jsx, element, reducers) => {
}
const allReducers = reducer(reducers);
+
+ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose;
+ const enhancers = enhancer ?
+ composeEnhancers(
+ redux.applyMiddleware(thunk),
+ enhancer
+ ) :
+ composeEnhancers(
+ redux.applyMiddleware(thunk)
+ );
const store = redux.createStore(
allReducers,
- redux.applyMiddleware(thunk)
+ initialState || {},
+ enhancers
);
// Render view component
diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx
index 79df3f93b..d72170592 100644
--- a/src/views/preview/presentation.jsx
+++ b/src/views/preview/presentation.jsx
@@ -306,7 +306,7 @@ PreviewPresentation.propTypes = {
onLoveClicked: PropTypes.func,
onSeeInside: PropTypes.func,
onUpdate: PropTypes.func,
- projectId: PropTypes.number,
+ projectId: PropTypes.string,
projectInfo: PropTypes.shape({
id: PropTypes.number,
title: PropTypes.string,
diff --git a/src/views/preview/preview.jsx b/src/views/preview/preview.jsx
index fb40c2cff..3c040377d 100644
--- a/src/views/preview/preview.jsx
+++ b/src/views/preview/preview.jsx
@@ -10,21 +10,26 @@ const PreviewPresentation = require('./presentation.jsx');
const sessionActions = require('../../redux/session.js');
const previewActions = require('../../redux/preview.js');
-const GUI = require('scratch-gui').default;
-const IntlGUI = injectIntl(GUI);
+
+const GUI = require('scratch-gui');
+const IntlGUI = injectIntl(GUI.default);
class Preview extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
+ 'addEventListeners',
'handleFavoriteToggle',
'handleLoveToggle',
'handlePermissions',
+ 'handlePopState',
'handleSeeInside',
'handleUpdate',
- 'initCounts'
+ 'initCounts',
+ 'pushHistory'
]);
this.state = this.initState();
+ this.addEventListeners();
}
componentDidUpdate (prevProps) {
if (this.props.sessionStatus !== prevProps.sessionStatus &&
@@ -52,6 +57,51 @@ class Preview extends React.Component {
this.props.getCreditInfo(this.props.projectInfo.remix.root);
}
}
+ if (this.props.playerMode !== prevProps.playerMode || this.props.fullScreen !== prevProps.fullScreen) {
+ this.pushHistory(history.state === null);
+ }
+ }
+ componentWillUnmount () {
+ this.removeEventListeners();
+ }
+ addEventListeners () {
+ window.addEventListener('popstate', this.handlePopState);
+ }
+ removeEventListeners () {
+ window.removeEventListener('popstate', this.handlePopState);
+ }
+ handlePopState () {
+ const path = window.location.pathname.toLowerCase();
+ const playerMode = path.indexOf('editor') === -1;
+ const fullScreen = path.indexOf('fullscreen') !== -1;
+ if (this.props.playerMode !== playerMode) {
+ this.props.setPlayer(playerMode);
+ }
+ if (this.props.fullScreen !== fullScreen) {
+ this.props.setFullScreen(fullScreen);
+ }
+ }
+ pushHistory (push) {
+ // update URI to match mode
+ const idPath = this.state.projectId ? `${this.state.projectId}/` : '';
+ let modePath = '';
+ if (!this.props.playerMode) modePath = 'editor/';
+ // fullscreen overrides editor
+ if (this.props.fullScreen) modePath = 'fullscreen/';
+ const newPath = `/preview/${idPath}${modePath}`;
+ if (push) {
+ history.pushState(
+ {},
+ document.title,
+ newPath
+ );
+ } else {
+ history.replaceState(
+ {},
+ document.title,
+ newPath
+ );
+ }
}
initState () {
const pathname = window.location.pathname.toLowerCase();
@@ -62,10 +112,8 @@ class Preview extends React.Component {
return {
editable: false,
favoriteCount: 0,
- inEditor: parts.indexOf('editor') !== -1,
- isFullScreen: parts.indexOf('fullscreen') !== -1,
loveCount: 0,
- projectId: parts[1] === 'editor' ? null : parts[1]
+ projectId: parts[1] === 'editor' ? 0 : parts[1]
};
}
handleFavoriteToggle () {
@@ -109,8 +157,7 @@ class Preview extends React.Component {
}
}
handleSeeInside () {
- this.setState({inEditor: true});
- history.pushState({}, document.title, `/preview/${this.state.projectId}/editor`);
+ this.props.setPlayer(false);
}
handleUpdate (jsonData) {
this.props.updateProject(
@@ -128,13 +175,7 @@ class Preview extends React.Component {
}
render () {
return (
- this.state.inEditor ?
- :
+ this.props.playerMode ?
-
+ :
+
);
}
}
@@ -186,6 +233,7 @@ Preview.propTypes = {
})
}),
faved: PropTypes.bool,
+ fullScreen: PropTypes.bool,
getCreditInfo: PropTypes.func.isRequired,
getFavedStatus: PropTypes.func.isRequired,
getLovedStatus: PropTypes.func.isRequired,
@@ -193,6 +241,7 @@ Preview.propTypes = {
getRemixes: PropTypes.func.isRequired,
getStudios: PropTypes.func.isRequired,
loved: PropTypes.bool,
+ playerMode: PropTypes.bool,
projectInfo: PropTypes.shape({
author: PropTypes.shape({
id: PropTypes.number,
@@ -219,7 +268,9 @@ Preview.propTypes = {
remixes: PropTypes.arrayOf(PropTypes.object),
sessionStatus: PropTypes.string,
setFavedStatus: PropTypes.func.isRequired,
+ setFullScreen: PropTypes.func.isRequired,
setLovedStatus: PropTypes.func.isRequired,
+ setPlayer: PropTypes.func.isRequired,
studios: PropTypes.arrayOf(PropTypes.object),
updateProject: PropTypes.func.isRequired,
user: PropTypes.shape({
@@ -248,7 +299,9 @@ const mapStateToProps = state => ({
remixes: state.preview.remixes,
sessionStatus: state.session.status,
studios: state.preview.studios,
- user: state.session.session.user
+ user: state.session.session.user,
+ playerMode: state.scratchGui.mode.isPlayerOnly,
+ fullScreen: state.scratchGui.mode.isFullScreen
});
@@ -285,6 +338,12 @@ const mapDispatchToProps = dispatch => ({
},
updateProject: (id, formData, username, token) => {
dispatch(previewActions.updateProject(id, formData, username, token));
+ },
+ setPlayer: player => {
+ dispatch(GUI.setPlayer(player));
+ },
+ setFullScreen: fullscreen => {
+ dispatch(GUI.setFullScreen(fullscreen));
}
});
@@ -293,8 +352,29 @@ const ConnectedPreview = connect(
mapDispatchToProps
)(Preview);
+GUI.setAppElement(document.getElementById('app'));
+const initGuiState = guiInitialState => {
+ const pathname = window.location.pathname.toLowerCase();
+ const parts = pathname.split('/').filter(Boolean);
+ // parts[0]: 'preview'
+ // parts[1]: either :id or 'editor'
+ // parts[2]: undefined if no :id, otherwise either 'editor' or 'fullscreen'
+ if (parts.indexOf('editor') === -1) {
+ guiInitialState = GUI.initPlayer(guiInitialState);
+ }
+ if (parts.indexOf('fullscreen') !== -1) {
+ guiInitialState = GUI.initFullScreen(guiInitialState);
+ }
+ return guiInitialState;
+};
+
render(
,
document.getElementById('app'),
- {preview: previewActions.previewReducer}
+ {
+ preview: previewActions.previewReducer,
+ ...GUI.guiReducers
+ },
+ {scratchGui: initGuiState(GUI.guiInitialState)},
+ GUI.guiMiddleware
);
From d58599a22f4971d3a4179f966599ecf5839096fa Mon Sep 17 00:00:00 2001
From: BryceLTaylor
Date: Wed, 30 May 2018 10:40:44 -0400
Subject: [PATCH 20/32] Update travis.yml to run smoke tests
---
.travis.yml | 51 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 17 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index a88817457..ee24ed756 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,6 +18,11 @@ env:
- API_HOST_VAR=API_HOST_$TRAVIS_BRANCH
- API_HOST=${!API_HOST_VAR}
- API_HOST=${API_HOST:-$API_HOST_STAGING}
+ - ROOT_URL_master=https://scratch.mit.edu
+ - ROOT_URL_STAGING=https://scratch.ly
+ - ROOT_URL_VAR=ROOT_URL_$TRAVIS_BRANCH
+ - ROOT_URL=${!ROOT_URL_VAR}
+ - ROOT_URL=${ROOT_URL:-$ROOT_URL_STAGING}
# EB_AWS_ACCESS_KEY_ID
- secure: A138rYuXDsOmpEwYxZ31WyXEeq5fgr9qyqsQh1nTFsjBKpFtNM+CN9e0QJQFT3PLs4wH/lWTRSyHxakxKQS1sxq828f9gHed+f15REKk/fRUplcCYIexT9xKVtU3D8CRNn/KBFWk75fZyZt20eyOVIv4h3pInKQz7y84J6PWzB1BCrAFvADrzS1X68Z3NJJLyxnz0YEurzz8mC2v4D0s/XifKTWvRtefD4QM6pE0C2iYyk+ThrLwg7i9FDHVfo0MrkgcdX7mz37SnTr7p7mHWnGXrGngi/NiDRQ+Uwwq/sr2UIww0rCwS1xsOcS//dC4NNqrrt1kUTsoC1Yt87Ny+gI0nUplsfEpdKajAkOYdANC5bJUGqPdSlOds1v9aJs9Hx48uGamWkm/3cFmoJ5uA2ZzUwbSGjTkWbnhwzT0YRvcLGhP1WE/EswaIyK5qMp522E79mP1yH6M750iUvi4N39+QW1BNX3ADkOwyAI67ArX5on5gWP83RXcJ15im7XsBpsmVn/KXi6AouWPb8jmSmKCj0QZCzfLY7ivM42IugYpK2NV7kFB38DpXQamJ5eskgwYa3elRmednIFUuwb1QDnONvJogVjk4CLmoSxssC2mJnnrUItM7l8G6As81GMI+6lTtl86hAuXBjUk60FMbgTAQDX9ll26LgpBy8jHSx8=
# EB_AWS_SECRET_ACCESS_KEY
@@ -66,20 +71,32 @@ addons:
install:
- sudo -H pip install -r requirements.txt
- npm --production=false install
-deploy:
-- provider: script
- skip_cleanup: $SKIP_CLEANUP
- script: env make sync
- on:
- repo: LLK/scratch-www
- branch:
- - develop
- - hotfix/*
- - release/*
-- provider: script
- skip_cleanup: $SKIP_CLEANUP
- script: env make sync
- on:
- repo: LLK/scratch-www
- branch:
- - master
+jobs:
+ include:
+ - stage: test
+ deploy:
+ - provider: script
+ skip_cleanup: $SKIP_CLEANUP
+ script: env make sync
+ on:
+ repo: LLK/scratch-www
+ branch:
+ - develop
+ - hotfix/*
+ - release/*
+ - provider: script
+ skip_cleanup: $SKIP_CLEANUP
+ script: env make sync
+ on:
+ repo: LLK/scratch-www
+ branch:
+ - master
+ - stage: smoke
+ install:
+ - cd test/intergration
+ - npm install
+ script: npm run smoke
+stages:
+- test
+- name: smoke
+ if: branch IN (master, develop, travis) and type != pull_request
From 99ed30e2c89d7b9235a925d47a67ef0d31a0fc80 Mon Sep 17 00:00:00 2001
From: chrisgarrity
Date: Wed, 30 May 2018 14:39:25 -0400
Subject: [PATCH 21/32] Fix up favorites
Found a couple of typos now that API can process favorites.
---
src/views/preview/presentation.jsx | 2 +-
src/views/preview/preview.jsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx
index d72170592..b4f5f0165 100644
--- a/src/views/preview/presentation.jsx
+++ b/src/views/preview/presentation.jsx
@@ -184,7 +184,7 @@ const PreviewPresentation = props => {
{loveCount}
-
-
-
- This project is not shared — so only you can see it. Click share to let everyone see it!
-
-
-
-
+ {projectInfo.history && shareDate === '' &&
+
+
+
+ This project is not shared — so only you can see it. Click share to let everyone see it!
+
+
+
+
+ }
+
{ projectInfo && projectInfo.author && projectInfo.author.id && (
- {projectInfo.history && shareDate === '' &&
-
-
-
- This project is not shared — so only you can see it. Click share to let everyone see it!
-
-
- Share
-
-
-
- }
-
- { projectInfo && projectInfo.author && projectInfo.author.id && (
-
-
+class PreviewPresentation extends React.Component {
+ constructor (props) {
+ super(props);
+ bindAll(this, [
+ 'handleReportClick',
+ 'handleReportClose',
+ 'handleReportReasonSelect',
+ 'handleReportSubmit'
+ ]);
+ this.state = {
+ reportOpen: false,
+ reportPrompt: 'Select a reason why above.',
+ reportReason: ''
+ };
+ }
+ handleReportClick (e) {
+ e.preventDefault();
+ this.setState({reportOpen: true});
+ }
+ handleReportClose () {
+ this.setState({reportOpen: false});
+ }
+ handleReportReasonSelect (name, value) {
+ const prompts = [
+ 'Please provide a link to the original project',
+ 'Please provide links to the uncredited content',
+ 'Please say why the project is too violent or scary',
+ 'Please say where the inappropriate language occurs in the project (For example: Notes & Credits, sprite name, project text, etc.)',
+ 'Please say the name of the audio file with the inappropriate music',
+ 'Please say where the personal contact information is shared (For example: Notes & Credits, sprite name, project text, etc.)',
+ 'Please be specific about why this project does not follow our Community Guidelines',
+ 'not used',
+ 'Please say the name of the sprite or the backdrop with the inappropriate image'
+ ];
+ this.setState({reportPrompt: prompts[value]});
+ }
+ handleReportSubmit (formData) {
+ console.log('submit report data', formData);
+ this.setState({reportOpen: false});
+ }
+ render () {
+ const {
+ editable,
+ faved,
+ favoriteCount,
+ intl,
+ isFullScreen,
+ loved,
+ loveCount,
+ originalInfo,
+ parentInfo,
+ projectId,
+ projectInfo,
+ remixes,
+ sessionStatus,
+ studios,
+ user,
+ onFavoriteClicked,
+ onLoveClicked,
+ onSeeInside,
+ onUpdate
+ // ...otherProps TBD
+ } = this.props;
+ const shareDate = (projectInfo.history && projectInfo.history.shared) ? projectInfo.history.shared : '';
+ return (
+
+
+ This project is not shared — so only you can see it. Click share to let everyone see it!
+
+
+ Share
+
+
+
+ }
+
+ { projectInfo && projectInfo.author && projectInfo.author.id && (
+
+
+
+ );
+ }
+}
ReportModal.propTypes = {
- children: PropTypes.node,
- contentLabel: PropTypes.string,
- onRequestClose: PropTypes.func
+ intl: intlShape,
+ onReport: PropTypes.func,
+ onRequestClose: PropTypes.func,
+ type: PropTypes.string
};
-module.exports = ReportModal;
+module.exports = injectIntl(ReportModal);
diff --git a/src/l10n.json b/src/l10n.json
index fe4b152ce..31e108a76 100644
--- a/src/l10n.json
+++ b/src/l10n.json
@@ -159,5 +159,29 @@
"registration.welcomeStepPrompt": "To get started, click on the button below.",
"registration.welcomeStepTitle": "Hurray! Welcome to Scratch!",
- "thumbnail.by": "by"
+ "thumbnail.by": "by",
+ "report.project": "Report Project",
+ "report.projectInstructions": "From the dropdown below, please select the reason why you feel this project is disrespectful or inappropriate or otherwise breaks the {CommunityGuidelinesLink}.",
+ "report.CommunityGuidelinesLinkText": "Scratch Community Guidelines",
+ "report.reasonPlaceHolder": "Select a reason",
+ "report.reasonCopy": "Exact Copy of Project",
+ "report.reasonUncredited": "Uses Image/Music Without Credit",
+ "report.reasonScary": "Too Violent or Scary",
+ "report.reasonLanguage": "Inappropriate Language",
+ "report.reasonMusic": "Inappropriate Music",
+ "report.reasonImage": "Inappropriate Images",
+ "report.reasonPersonal": "Sharing Personal Contact Information",
+ "report.reasonOther": "Other",
+ "report.promptPlaceholder": "Select a reason why above.",
+ "report.promptCopy": "Please provide a link to the original project",
+ "report.promptUncredited": "Please provide links to the uncredited content",
+ "report.promptScary": "Please say why the project is too violent or scary",
+ "report.promptLanguage": "Please say where the inappropriate language occurs in the project (For example: Notes & Credits, sprite name, project text, etc.)",
+ "report.promptMusic": "Please say the name of the audio file with the inappropriate music",
+ "report.promptPersonal": "Please say where the personal contact information is shared (For example: Notes & Credits, sprite name, project text, etc.)",
+ "report.promptGuidelines": "Please be specific about why this project does not follow our Community Guidelines",
+ "report.promptImage": "Please say the name of the sprite or the backdrop with the inappropriate image",
+ "report.tooLongError": "That's too long! Please find a way to shorten your text.",
+ "report.tooShortError": "That's too short. Please describe in detail what's inappropriate or disrespectful about the project.",
+ "report.send": "Send"
}
\ No newline at end of file
diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx
index a468d228f..a105ed4a3 100644
--- a/src/views/preview/presentation.jsx
+++ b/src/views/preview/presentation.jsx
@@ -14,11 +14,6 @@ const sessionActions = require('../../redux/session.js');
const decorateText = require('../../lib/decorate-text.jsx');
const FlexRow = require('../../components/flex-row/flex-row.jsx');
const Button = require('../../components/forms/button.jsx');
-const Form = require('../../components/forms/form.jsx');
-const Input = require('../../components/forms/input.jsx');
-const Select = require('../../components/forms/select.jsx');
-const Spinner = require('../../components/spinner/spinner.jsx');
-const TextArea = require('../../components/forms/textarea.jsx');
const Avatar = require('../../components/avatar/avatar.jsx');
const CappedNumber = require('../../components/cappednumber/cappednumber.jsx');
const ShareBanner = require('../../components/share-banner/share-banner.jsx');
@@ -26,7 +21,6 @@ const ThumbnailColumn = require('../../components/thumbnailcolumn/thumbnailcolum
const InplaceInput = require('../../components/forms/inplace-input.jsx');
const ReportModal = require('../../components/modal/report/modal.jsx');
-
require('./preview.scss');
class PreviewPresentation extends React.Component {
@@ -35,13 +29,10 @@ class PreviewPresentation extends React.Component {
bindAll(this, [
'handleReportClick',
'handleReportClose',
- 'handleReportReasonSelect',
'handleReportSubmit'
]);
this.state = {
- reportOpen: false,
- reportPrompt: 'Select a reason why above.',
- reportReason: ''
+ reportOpen: false
};
}
handleReportClick (e) {
@@ -51,22 +42,16 @@ class PreviewPresentation extends React.Component {
handleReportClose () {
this.setState({reportOpen: false});
}
- handleReportReasonSelect (name, value) {
- const prompts = [
- 'Please provide a link to the original project',
- 'Please provide links to the uncredited content',
- 'Please say why the project is too violent or scary',
- 'Please say where the inappropriate language occurs in the project (For example: Notes & Credits, sprite name, project text, etc.)',
- 'Please say the name of the audio file with the inappropriate music',
- 'Please say where the personal contact information is shared (For example: Notes & Credits, sprite name, project text, etc.)',
- 'Please be specific about why this project does not follow our Community Guidelines',
- 'not used',
- 'Please say the name of the sprite or the backdrop with the inappropriate image'
- ];
- this.setState({reportPrompt: prompts[value]});
- }
- handleReportSubmit (formData) {
- console.log('submit report data', formData);
+
+ handleReportSubmit (formData, callback) {
+ const data = {
+ ...formData,
+ id: this.props.projectId,
+ username: this.props.user.username
+ };
+ console.log('submit report data', data);
+ // TODO: pass error to modal via callback.
+ callback();
this.setState({reportOpen: false});
}
render () {
@@ -99,7 +84,7 @@ class PreviewPresentation extends React.Component {
- This project is not shared — so only you can see it. Click share to let everyone see it!
+ This project is not shared — so only you can see it. Click share to let everyone see it!
Share
@@ -130,8 +115,7 @@ class PreviewPresentation extends React.Component {
// })
}}
validations={{
- // TODO: actual 100
- maxLength: 40
+ maxLength: 100
}}
value={projectInfo.title}
/> :
@@ -337,114 +321,16 @@ class PreviewPresentation extends React.Component {
Report
,
- From the dropdown below, please select the reason why you feel this project is disrespectful or inappropriate or otherwise breaks the Scratch Community Guidelines.
-
-
-
+ />
]
}
-
-
-
Instructions
@@ -206,6 +206,7 @@ class PreviewPresentation extends React.Component {
)}
handleUpdate={onUpdate}
name="instructions"
+ placeholder="Tell people how to use your project (such as which keys to press)."
type="textarea"
validationErrors={{
maxLength: 'Sorry description is too long'
@@ -236,6 +237,7 @@ class PreviewPresentation extends React.Component {
)}
handleUpdate={onUpdate}
name="description"
+ placeholder="How did you make this project? Did you use ideas scripts or artwork from other people? Thank them here."
type="textarea"
validationErrors={{
maxLength: 'Sorry description is too long'
@@ -254,6 +256,7 @@ class PreviewPresentation extends React.Component {
@@ -235,6 +232,7 @@ class PreviewPresentation extends React.Component {
Date: Thu, 31 May 2018 15:05:40 -0400
Subject: [PATCH 32/32] Make travis only run selenium tests on Travis Branch
Until we can get the tests to run reliably
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 3da12ffa2..b4f98bb41 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -102,4 +102,4 @@ jobs:
stages:
- test
- name: smoke
- if: branch IN (master, develop, travis) and type != pull_request
+ if: branch IN (travis) and type != pull_request