Merge pull request #6256 from LLK/release/2021-11-03

[Master] release/2021-11-03
This commit is contained in:
Karishma Chadha 2021-11-04 10:24:57 -04:00 committed by GitHub
commit a34b7477fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 484 additions and 394 deletions

646
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -131,8 +131,8 @@
"redux-mock-store": "1.5.4",
"redux-thunk": "2.0.1",
"sass-loader": "6.0.6",
"scratch-gui": "0.1.0-prerelease.20211027094435",
"scratch-l10n": "3.14.20211027031612",
"scratch-gui": "0.1.0-prerelease.20211103150403",
"scratch-l10n": "3.14.20211103031555",
"selenium-webdriver": "3.6.0",
"slick-carousel": "1.6.0",
"style-loader": "0.12.3",

View file

@ -2,6 +2,8 @@ const classNames = require('classnames');
const PropTypes = require('prop-types');
const React = require('react');
const VideoPreview = require('../video-preview/video-preview.jsx');
const MediaQuery = require('react-responsive').default;
const frameless = require('../../lib/frameless');
require('./text-and-media-snippet.scss');
@ -10,16 +12,34 @@ const TextAndMediaSnippet = props => (
{props.className === 'regular' &&
<div className="half">
{props.type === 'video' &&
<div>
<MediaQuery
minWidth={frameless.mobile}
>
<VideoPreview
buttonMessage=""
thumbnail={props.largeImage}
thumbnailWidth="320"
videoHeight="230"
thumbnailWidth="430"
videoHeight={430 * .568}
videoId={props.videoId}
videoWidth="380"
videoWidth="430"
alt={props.alt}
spinnerColor={props.spinnerColor}
/>
</MediaQuery>
<MediaQuery maxWidth={frameless.mobile - 1}>
<VideoPreview
buttonMessage=""
thumbnail={props.largeImage}
thumbnailWidth="300"
videoHeight={300 * .568}
videoId={props.videoId}
videoWidth="300"
alt={props.alt}
spinnerColor={props.spinnerColor}
/>
</MediaQuery>
</div>
}
{props.type !== 'video' &&
<img

View file

@ -1,5 +1,6 @@
@import "../../colors";
@import "../../frameless";
$timeline-breakpoint: "only screen and (max-width : 1030px)";
.timeline-card{
max-width: 450px;
@ -24,13 +25,13 @@
}
&.left{
margin-left: calc((100% - 980px)/2);
@media #{$intermediate-and-smaller} {
@media #{$timeline-breakpoint} {
margin: 0 auto 30px;
}
}
&.right{
margin-left: calc(100% - ((100% - 980px)/2) - 470px);
@media #{$intermediate-and-smaller} {
@media #{$timeline-breakpoint} {
margin: 0 auto 30px;
}
}

View file

@ -35,7 +35,12 @@ class VideoPreview extends React.Component {
render () {
return (
<div className="video-preview">
// Adding a width to this div allows the videoFoam property on the embedded video
// to fill the size of the div once fullscreen has been entered and exited
<div
className="video-preview"
style={{width: `${this.props.videoWidth}px`}}
>
{this.state.videoOpen ?
(
<div className="spinner-video-container">

View file

@ -1074,8 +1074,8 @@ class AnnualReport extends React.Component {
thumbnail="/images/annual-report/2020/connectivity/aroundtheworld_videothumb.png"
videoId="rlsjbx0st4"
thumbnailWidth="580"
videoHeight="320"
videoWidth="568"
videoHeight={580 * .568}
videoWidth="580"
alt={
this.props.intl.formatMessage(
{id: 'annualReport.2020.altConnectivityVideoPreview'}
@ -1094,8 +1094,8 @@ class AnnualReport extends React.Component {
thumbnail="/images/annual-report/2020/connectivity/aroundtheworld_videothumb.png"
videoId="rlsjbx0st4"
thumbnailWidth="400"
videoHeight="320"
videoWidth="568"
videoHeight={400 * .568}
videoWidth="400"
alt={
this.props.intl.formatMessage(
{id: 'annualReport.2020.altConnectivityVideoPreview'}
@ -1111,8 +1111,8 @@ class AnnualReport extends React.Component {
thumbnail="/images/annual-report/2020/connectivity/aroundtheworld_videothumb.png"
videoId="rlsjbx0st4"
thumbnailWidth="300"
videoHeight="216"
videoWidth="380"
videoHeight={300 * .568}
videoWidth="300"
alt={
this.props.intl.formatMessage(
{id: 'annualReport.2020.altConnectivityVideoPreview'}
@ -1143,7 +1143,7 @@ class AnnualReport extends React.Component {
largeImage="/images/annual-report/2020/connectivity/Scratch Around the World/Scratch Al Sur graphic.svg"
>
<FormattedMessage
id="annualReport.2020.connectivityCountryBrazilParagraph"
id="annualReport.2020.connectivityCountryChileParagraph"
/>
</CountryBlurb>
<CountryBlurb
@ -1448,8 +1448,8 @@ class AnnualReport extends React.Component {
thumbnail="/images/annual-report/2020/adaptation/createalongs_videothumb.png"
videoId="uzfapi7t03"
thumbnailWidth="580"
videoHeight="320"
videoWidth="568"
videoHeight={580 * .568}
videoWidth="580"
alt={
this.props.intl.formatMessage(
{id: 'annualReport.2020.altAdaptationVideoPreview'}
@ -1468,8 +1468,8 @@ class AnnualReport extends React.Component {
thumbnail="/images/annual-report/2020/adaptation/createalongs_videothumb.png"
videoId="uzfapi7t03"
thumbnailWidth="400"
videoHeight="320"
videoWidth="568"
videoHeight={400 * .568}
videoWidth="400"
alt={
this.props.intl.formatMessage(
{id: 'annualReport.2020.altAdaptationVideoPreview'}
@ -1485,8 +1485,8 @@ class AnnualReport extends React.Component {
thumbnail="/images/annual-report/2020/adaptation/createalongs_videothumb.png"
videoId="uzfapi7t03"
thumbnailWidth="300"
videoHeight="216"
videoWidth="380"
videoHeight={300 * .568}
videoWidth="300"
alt={
this.props.intl.formatMessage(
{id: 'annualReport.2020.altAdaptationVideoPreview'}
@ -1627,7 +1627,7 @@ class AnnualReport extends React.Component {
minWidth={frameless.mobile}
>
<iframe
src="https://scratch.mit.edu/projects/412126066/embed"
src="https://scratch.mit.edu/projects/411647484/embed"
allowTransparency="true"
width="480"
height={((480 * .76) + 45)}
@ -1638,7 +1638,7 @@ class AnnualReport extends React.Component {
</MediaQuery>
<MediaQuery maxWidth={frameless.mobile - 1}>
<iframe
src="https://scratch.mit.edu/projects/412126066/embed"
src="https://scratch.mit.edu/projects/411647484/embed"
allowTransparency="true"
width="300"
height={((300 * .76) + 45)}

View file

@ -6,6 +6,7 @@ $annual-report-aqua: #088763;
$annual-report-teal: #297EA4;
$masthead-breakpoint: "only screen and (max-width : 960px)";
$masthead-breakpoint-wave: "only screen and (max-width : 1060px)";
$timeline-breakpoint: "only screen and (max-width : 1030px)";
$ui-purple-dark: hsla(260, 55, 55, 1);
// $motion-blue-3 #3373CC
@ -1115,7 +1116,7 @@ img.comment-viz{
flex-direction: column;
}
.text{
width: 390px;
width: 360px;
.larger{
font-size: 1.25rem;
line-height: 2.5rem;
@ -1168,9 +1169,12 @@ img.comment-viz{
margin: auto;
}
&.india{
margin: 0 0 20px;
@media #{$intermediate-and-smaller}{
margin: 0 auto 20px;
}
}
}
&.inverted{
border: 2.5px solid $ui-purple-dark;
background-color: $ui-white;
@ -1238,7 +1242,7 @@ img.comment-viz{
}
.two-wide{
margin: 50px auto;
margin: 50px auto 0px;
.text{
max-width: 480px;
width: 100%;
@ -1248,6 +1252,9 @@ img.comment-viz{
width: 100%;
img{
width: 100%;
@media #{$intermediate-and-smaller}{
margin-bottom: -40px;
}
}
}
}
@ -1283,7 +1290,7 @@ img.comment-viz{
&.content{
justify-content: space-between;
.text{
max-width: 370px;
max-width: 360px;
width: 100%;
}
.images{
@ -1352,7 +1359,7 @@ img.comment-viz{
&.right{
margin-left: 50%
}
@media #{$intermediate-and-smaller} {
@media #{$timeline-breakpoint} {
display: none;
}
}
@ -1362,7 +1369,7 @@ img.comment-viz{
width: 100%;
margin-left: calc((100% - 980px)/2);
top: 1150px;
@media #{$intermediate-and-smaller} {
@media #{$timeline-breakpoint} {
display: none;
}
img{
@ -1781,6 +1788,10 @@ img.comment-viz{
flex-direction: column;
justify-content: center;
align-items: center;
div{
width: 250px;
margin: auto;
}
}
.twitter-tweet{
width: 100%;
@ -1791,7 +1802,7 @@ img.comment-viz{
.directors-message {
.inner {
max-width: 940px;
max-width: 900px;
padding: 80px 0;
@media #{$intermediate}{
max-width: 700px;
@ -1917,7 +1928,7 @@ img.comment-viz{
}
.supporters-section {
padding: 104px 0 52px 0;
padding: 0px 0 52px 0;
.inner {
max-width: 840px;
@ -1949,7 +1960,7 @@ img.comment-viz{
}
.supporters-heading {
margin-bottom: 68px;
margin-bottom: 0px;
h2 {
padding-bottom: 24px;
@ -2064,12 +2075,7 @@ img.comment-viz{
.supporters-subsection {
text-align: left;
width: 460px;
&.supporters-lists {
width: 100%;
}
width: 440px;
}
.david-siegel {

View file

@ -215,7 +215,7 @@
"annualReport.2020.yearInReviewCard9Title": "Scratchtober",
"annualReport.2020.yearInReviewCard9Text": "Scratchers made hundreds of creative stories, games, and animations based on daily themed prompts.",
"annualReport.2020.communityQuote2Name": "Anna Lytical, Scratch Alumni",
"annualReport.2020.communityQuote2Name": "Anna Lytical, Scratch Alum",
"annualReport.2020.communityQuote2Title": "Google Cloud Platform Developer Relations Engineer, and the Coding Drag Queen",
"annualReport.2020.communityQuote2Text": "Seeing the power you have when youre creating something and can represent yourself and your problems and express them or solve them with code is a really magical experience and has real world impact.",
@ -253,7 +253,7 @@
"annualReport.2020.supportersIntro": "Thank you to our generous supporters. Your contribution helps us expand creative learning opportunities for children of all ages, from all backgrounds, around the globe.",
"annualReport.2020.ourSupporters": "Our Supporters",
"annualReport.2020.ourSupportersText": "We want to thank all Scratch supporters who, throughout the years, have helped us create amazing learning experiences for millions of young people around the world. The following list is based on cumulative giving to Scratch (at both MIT and Scratch Foundation) through December 31, 2020.",
"annualReport.2020.ourSupportersText": "We want to thank all Scratch supporters who, throughout the years, have helped us create amazing learning experiences for millions of young people around the world. The following list is based on giving to Scratch Foundation from January 1, 2020 to December 31, 2020.",
"annualReport.2020.supportersFoundingTitle": "Founding Partners — $10,000,000+",
"annualReport.2020.supportersFoundingText": "We are especially grateful to our Founding Partners who have each provided at least $10,000,000 in cumulative support, since the start of Scratch in 2003.",

View file

@ -5,8 +5,7 @@
"parents.faq": "FAQ",
"parents.overviewTitle": "How does Scratch work for children?",
"parents.overviewLearningTitle": "Learning",
"parents.overviewLearningBody": "For a one-page overview of what young people learn with Scratch, see {learningWithScratch}.\nRead an article on the {creativeLearningApproach}.",
"parents.learningWithScratchLinkText": "Learning with Scratch",
"parents.overviewLearningBody": "Scratch is a safe and playful learning environment that engages all children in thinking creatively, reasoning systematically, and working collaboratively—essential skills for everyone in today's society.\nRead an article on the {creativeLearningApproach}.",
"parents.creativeLearningApproachLinkText": "Creative Learning Approach",
"parents.overviewCommunityTitle": "Community",
"parents.overviewCommunityBody": "We ask all participants on the site to follow the {communityGuidelines}.\nWe do not make private account information available to anyone. For more information, please see the {privacyPolicy}.",

View file

@ -59,13 +59,6 @@ const Landing = () => (
<FormattedMessage
id="parents.overviewLearningBody"
values={{
learningWithScratch: (
<a href="http://llk.media.mit.edu/scratch/Learning-with-Scratch.pdf">
<FormattedMessage
id="parents.learningWithScratchLinkText"
/>
</a>
),
creativeLearningApproach: (
<a href="http://www.edutopia.org/kindergarten-creativity-collaboration-lifelong-learning">
<FormattedMessage

View file

@ -1,9 +1,9 @@
{
"research.title":"Research on Scratch",
"research.conductors":"Research on Scratch is being conducted by members of the MIT Scratch Team and researchers at other universities, including Yasmin Kafai at the University of Pennsylvania Graduate School of Education, Karen Brennan at the Harvard Graduate School of Education, Benjamin Mako Hill at the University of Washington, Andrés Monroy Hernandez at Microsoft Research, Mimi Ito and Crystle Martin at the University of California, Irvine, Quinn Burke at College of Charleston, Deborah Fields at Utah State University, and Kylie Peppler at Indiana University.",
"research.privacy":"By sharing projects and participating in the Scratch online community, you are helping us better understand how people can use and learn with Scratch. Any publicly shared projects, comments, or other material on the Scratch site may be included in the research analysis, presentations, papers, and reports. No personally identifiable information is shared. (If you have any questions, please use the {contactLink} form.)",
"research.conductors":"Research on Scratch is being conducted by the Scratch Foundation team. By sharing projects and participating in the Scratch online community, you are helping us better understand how people use and learn with Scratch. Any publicly shared projects, comments, or other material on the Scratch site may be included in research analyses, presentations, and reports. We never share personally identifiable information. To learn more, please read the {ethicsCodeLink}. (If you have any questions, please use the {contactLink} form.)",
"research.collaborators":"Previous research collaborators have included the Lifelong Kindergarten group at MIT, Yasmin Kafai at the University of Pennsylvania Graduate School of Education, Karen Brennan at the Harvard Graduate School of Education, Benjamin Mako Hill at the University of Washington, Andrés Monroy Hernandez at Microsoft Research, Mimi Ito and Crystle Martin at the University of California, Irvine, Quinn Burke at College of Charleston, Deborah Fields at Utah State University, and Kylie Peppler at Indiana University. Below are selected research papers, presentations, and theses on Scratch and the Scratch online community, followed by a list of National Science Foundation grants awarded to support Scratch.",
"research.ethicsCodeLinkText": "Scratch Foundations Research Code of Ethics",
"research.contactLinkText":"Contact Us",
"research.intro":"Below are selected research papers, presentations, and theses on Scratch and the Scratch online community, followed by a list of National Science Foundation grants awarded to support Scratch.",
"research.papers":"Research Papers & Presentations",
"research.grants":"National Science Foundation Grants"
}

View file

@ -11,20 +11,26 @@ const Page = require('../../components/page/www/page.jsx');
const Research = props => (
<InformationPage title={props.intl.formatMessage({id: 'research.title'})}>
<div className="inner info-inner">
<p><FormattedMessage id="research.conductors" /></p>
<p>
<FormattedMessage
id="research.privacy"
<p><FormattedMessage
id="research.conductors"
values={{
ethicsCodeLink: (
<a href="/code-of-ethics/">
<FormattedMessage id="research.ethicsCodeLinkText" />
</a>
),
contactLink: (
<a href="/contact-us/">
<FormattedMessage id="research.contactLinkText" />
</a>
)
}}
/></p>
<p>
<FormattedMessage
id="research.collaborators"
/>
</p>
<p><FormattedMessage id="research.intro" /></p>
<h3><FormattedMessage id="research.papers" /></h3>
<ul>
<li>
@ -84,8 +90,8 @@ const Research = props => (
Hill, B.M. &amp; Monroy-Hernández, A. (2013).{' '}
<a href="https://dl.acm.org/citation.cfm?id=2441776.2441893">
The cost of collaboration for code and art: Evidence from a remixing community.
</a> Forthcoming in &lt;i&gt;Proceedings of the ACM Conference{' '}
on Computer Supported Cooperative Work (CSCW &apos;13)&lt;/i&gt;.{' '}
</a> Forthcoming in <i>Proceedings of the ACM Conference{' '}
on Computer Supported Cooperative Work (CSCW &apos;13)</i>.{' '}
San Antonio, Texas, USA: ACM. Best Paper Award [
<a href="https://dl.acm.org/citation.cfm?id=2441776.2441893">
Official Link

View file

@ -39,6 +39,9 @@ let projectComment = buildNumber + ' project';
let profileComment = buildNumber + ' profile';
let studioComment = buildNumber + ' studio';
let projectReply = projectComment + ' reply';
let studioReply = studioComment + ' reply';
if (remote) {
jest.setTimeout(60000);
} else {
@ -81,7 +84,8 @@ describe('comment tests', async () => {
await driver.get(projectUrl);
// find the comment
let commentXpath = await `//div[@class="comment-bubble"]/span/span[contains(text(), "${buildNumber}")]`;
let commentXpath = await `//div[@class="comment-bubble"]/span/span[contains(text(),` +
` "${projectComment}")]`;
let postedComment = await findByXpath(commentXpath);
let commentVisible = await postedComment.isDisplayed();
await expect(commentVisible).toBe(true);
@ -100,7 +104,8 @@ describe('comment tests', async () => {
await driver.get(profileUrl);
// find the comment
let newComment = await findByXpath(`//div[@class="comment "]/div/div[contains(text(), "${buildNumber}")]`);
let newComment = await findByXpath(`//div[@class="comment "]/div/div[contains(text(),` +
` "${profileComment}")]`);
let commentVisible = await newComment.isDisplayed();
await expect(commentVisible).toBe(true);
@ -122,7 +127,7 @@ describe('comment tests', async () => {
await driver.get(studioUrl);
// find the comment
let commentXpath = `//div[@class="comment-bubble"]/span/span[contains(text(), "${buildNumber}")]`;
let commentXpath = `//div[@class="comment-bubble"]/span/span[contains(text(), "${studioComment}")]`;
let postedComment = await findByXpath(commentXpath);
let commentVisible = await postedComment.isDisplayed();
await expect(commentVisible).toBe(true);
@ -254,5 +259,54 @@ describe('comment tests', async () => {
let isHighlighted = await containsClass(commentContainer, 'highlighted');
await expect(isHighlighted).toBe(true);
});
test('project: reply to comment', async () => {
await driver.get(projectUrl);
let commentXpath = `//span[contains(text(), "${projectComment}")]/../..`;
let replyXpath = commentXpath + '//span[@class = "comment-reply"]';
await clickXpath(replyXpath);
// type reply
let replyRow = '//div[contains(@class, "comment-reply-row")]';
let replyComposeXpath = replyRow + '//textArea[@class = "inplace-textarea"]';
let composeBox = await findByXpath(replyComposeXpath);
await composeBox.sendKeys(projectReply);
// click post
let postButton = await findByXpath(replyRow + '//button[@class = "button compose-post"]');
await postButton.click();
// find reply
await driver.sleep(500);
await driver.get(projectUrl);
let postedReply = await findByXpath(`//span[contains(text(), "${projectReply}")]`);
let commentVisible = await postedReply.isDisplayed();
await expect(commentVisible).toBe(true);
});
test('studio: reply to comment', async () => {
await driver.get(studioUrl);
// find the comment and click reply
let commentXpath = `//span[contains(text(), "${studioComment}")]/../..`;
await clickXpath(commentXpath + '//span[@class = "comment-reply"]');
// type reply
let replyRow = '//div[contains(@class, "comment-reply-row")]';
let replyComposeXpath = replyRow + '//textArea[@class = "inplace-textarea"]';
let composeBox = await findByXpath(replyComposeXpath);
await composeBox.sendKeys(studioReply);
// click post
let postButton = await findByXpath(replyRow + '//button[@class = "button compose-post"]');
await postButton.click();
// find reply
await driver.sleep(500);
await driver.get(studioUrl);
let postedReply = await findByXpath(`//span[contains(text(), "${studioReply}")]`);
let commentVisible = await postedReply.isDisplayed();
await expect(commentVisible).toBe(true);
});
});
});