feat: [UEPR-88] added modal for written guides

This commit is contained in:
MiroslavDionisiev 2024-11-22 11:12:01 +02:00
parent c27046698a
commit 1b76b929b4
16 changed files with 455 additions and 57 deletions

View file

@ -0,0 +1,143 @@
import React, {useCallback, useState} from 'react';
import ReactModal from 'react-modal';
import PropTypes from 'prop-types';
import Button from '../forms/button.jsx';
import {FormattedMessage, useIntl} from 'react-intl';
import ModalNavigation from '../modal-navigation/modal-navigation.jsx';
import './cards-modal.scss';
const GUIDES_SECTIONS = [
{
titleId: 'ideas.modalSectionTitleSpritesAndSounds',
imgSrc: '/images/ideas/sprites-sounds.svg',
cards: [
{
cardId: 'ideas.modalCardNameCreateSprite',
hrefId: 'guides.ScratchLearningResource_CreateOriginalSpriteLink'
},
{
cardId: 'ideas.modalCardNameRemix',
hrefId: 'guides.ScratchLearningResource_RemixRe-imagineSpritesLink'
},
{
cardId: 'ideas.modalCardNameBringDrawingsIntoScratch',
hrefId: 'guides.ScratchLearningResource_BringYourDrawingsIntoScratchLink'
},
{
cardId: 'ideas.modalCardNameSound',
hrefId: 'guides.ScratchLearningResource_SoundsAddRecordText-to-SpeechLink'
},
{
cardId: 'ideas.modalCardNameCreateAsset',
hrefId: 'guides.ScratchLearningResource_CreateanAssetPackLink'
}
]
},
{
titleId: 'ideas.modalSectionTitleAdvancedTopics',
imgSrc: '/images/ideas/advanced-topics.svg',
cards: [
{
cardId: 'ideas.modalCardNameConditionalStatements',
hrefId: 'guides.ScratchLearningResource_ConditionalStatementsLink'
},
{
cardId: 'ideas.modalCardNameVariablesLists',
hrefId: 'guides.ScratchLearningResource_VariablesandListsLink'
},
{
cardId: 'ideas.modalCardNameCustomBlocks',
hrefId: 'guides.ScratchLearningResource_MyBlocksLink'
},
{
cardId: 'ideas.modalCardNameFaceSensing',
hrefId: 'cards.paperplanes-turtlegraphics-cardsLink'
},
{
cardId: 'ideas.modalCardNameComputationalConcepts',
hrefId: 'cards.facesensing-cardsLink'
}
]
}
];
export const CardsModal = ({isOpen, onClose = () => {}}) => {
const [currentPage, setCurrentPage] = useState(0);
const intl = useIntl();
const onNextPage = useCallback(() => {
if (currentPage < GUIDES_SECTIONS.length - 1) {
setCurrentPage(currentPage + 1);
}
}, [currentPage]);
const onBackPage = useCallback(() => {
if (currentPage > 0) {
setCurrentPage(currentPage - 1);
}
}, [currentPage]);
if (!isOpen) return null;
return (
<ReactModal
isOpen={isOpen}
onRequestClose={onClose}
className="cards-modal-container"
overlayClassName="cards-modal-overlay"
>
<div className="cards-modal-header">
<div className="cards-title">
<FormattedMessage id={'ideas.modalTitle'} />
</div>
<Button
className="close-button"
isCloseType
onClick={onClose}
/>
</div>
<div className="cards-modal-section-title">
<FormattedMessage id={GUIDES_SECTIONS[currentPage].titleId} />
</div>
<div className="cards-modal-section-content">
<img
className="section-img"
src={GUIDES_SECTIONS[currentPage].imgSrc}
/>
<div className="cards-modal-cards-list">
{GUIDES_SECTIONS[currentPage].cards.map(card => (
<div
key={card.cardId}
className="card"
>
<FormattedMessage id={card.cardId} />
<a
href={intl.formatMessage({
id: card.hrefId
})}
target="_blank"
rel="noopener noreferrer"
>
<Button>
<img src="/images/ideas/download-icon.svg" />
</Button>
</a>
</div>
))}
</div>
</div>
<ModalNavigation
currentPage={currentPage}
totalDots={GUIDES_SECTIONS.length}
nextButtonImageSrc="/images/ideas/right-arrow.svg"
prevButtonImageSrc="/images/ideas/left-arrow.svg"
onNextPage={onNextPage}
onBackPage={onBackPage}
className="cards-modal-navigation"
/>
</ReactModal>
);
};
CardsModal.propTypes = {
isOpen: PropTypes.bool,
onClose: PropTypes.func
};

View file

@ -0,0 +1,150 @@
@import "../../colors";
@import "../../frameless";
.cards-modal-overlay {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 510;
background-color: $box-shadow-light-gray;
border-color: unset;
}
.cards-modal-container {
display: flex;
flex-direction: column;
background: white;
border-radius: 8px;
width: 640px;
box-shadow: 0 0 0 4px $ui-blue-25percent;
&:focus {
outline: none;
border: none;
}
.cards-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background-color: $ui-blue;
border-radius: 8px 8px 0 0;
.cards-title {
font-size: 1rem;
font-weight: 700;
line-height: 1.25rem;
color: $ui-white;
margin-left: auto;
margin-right: auto;
}
.close-button {
position: unset;
margin: 0;
}
}
.cards-modal-section-title {
text-align: center;
vertical-align: middle;
color: $header-gray;
font-size: 1.5rem;
font-weight: 700;
line-height: 2rem;
padding: 0.5rem 0;
margin: 0.75rem 0
}
.cards-modal-section-content {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin: 0 1.25rem;
gap: 1.25rem;
.section-img {
width: 200px;
}
.cards-modal-cards-list {
flex: 1;
.card {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.875rem;
font-weight: 500;
.button {
display: flex;
justify-content: center;
align-items: center;
width: 2rem;
height: 2rem;
}
}
.card + .card {
border-top: 1px solid $box-shadow-light-gray;
}
}
}
.cards-modal-navigation {
justify-content: center;
align-items: center;
margin: 1.75rem 0;
.navigation-button {
padding: 0;
margin: 0 1rem;
}
.dotRow{
width: 32px;
height: 16px;
gap: 0.5rem;
}
.dot{
width: 8px;
height: 8px;
background-color: transparent;
border: 2px solid $ui-blue;
}
.active{
background-color: $ui-blue;
box-shadow: 0 0 0 4px $ui-blue-25percent;
}
}
}
.cards-modal-container:focus {
outline: none;
border: none;
}
@media only screen and (max-width: $mobileIntermediate) {
.cards-modal-container {
width: 100%;
}
}

View file

@ -36,13 +36,25 @@ export const CommunityGuidelinesModal = props => {
<CommunityGuidelines <CommunityGuidelines
userId={props.userId} userId={props.userId}
currentPage={currentPage} currentPage={currentPage}
onNextPage={currentPage < communityGuidelines.length - 1 ? onNextPage : onComplete} onNextPage={
nextButtonText={currentPage === communityGuidelines.length - 1 ? currentPage < communityGuidelines.length - 1 ?
<FormattedMessage id={'communityGuidelines.buttons.finish'} /> : onNextPage :
null} onComplete
}
nextButtonText={
currentPage === communityGuidelines.length - 1 ? (
<FormattedMessage id={'communityGuidelines.buttons.finish'} />
) : (
<FormattedMessage id={'communityGuidelines.buttons.next'} />
)
}
prevButtonText={
<FormattedMessage id={'communityGuidelines.buttons.back'} />
}
onBackPage={currentPage > 0 ? onBackPage : null} onBackPage={currentPage > 0 ? onBackPage : null}
/> />
</ReactModal>); </ReactModal>
);
}; };
CommunityGuidelinesModal.propTypes = { CommunityGuidelinesModal.propTypes = {

View file

@ -1,7 +1,7 @@
import React, {useEffect} from 'react'; import React, {useEffect} from 'react';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import thumbnailUrl from '../../lib/user-thumbnail.js'; import thumbnailUrl from '../../lib/user-thumbnail.js';
import OnboardingNavigation from '../onboarding-navigation/onboarding-navigation.jsx'; import ModalNavigation from '../modal-navigation/modal-navigation.jsx';
import './community-guidelines.scss'; import './community-guidelines.scss';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
@ -65,6 +65,7 @@ export const CommunityGuidelines = ({
userId, userId,
currentPage, currentPage,
nextButtonText, nextButtonText,
prevButtonText,
onNextPage, onNextPage,
onBackPage onBackPage
}) => { }) => {
@ -108,10 +109,11 @@ export const CommunityGuidelines = ({
</div> </div>
)} )}
</div> </div>
<OnboardingNavigation <ModalNavigation
currentPage={currentPage} currentPage={currentPage}
totalDots={communityGuidelines.length} totalDots={communityGuidelines.length}
nextButtonText={nextButtonText} nextButtonText={nextButtonText}
prevButtonText={prevButtonText}
onNextPage={onNextPage} onNextPage={onNextPage}
onBackPage={onBackPage} onBackPage={onBackPage}
/> />
@ -123,7 +125,8 @@ CommunityGuidelines.propTypes = {
currentPage: PropTypes.number, currentPage: PropTypes.number,
userId: PropTypes.string, userId: PropTypes.string,
constructHeader: PropTypes.func, constructHeader: PropTypes.func,
nextButtonText: PropTypes.string, nextButtonText: PropTypes.node,
prevButtonText: PropTypes.node,
onNextPage: PropTypes.func, onNextPage: PropTypes.func,
onBackPage: PropTypes.func onBackPage: PropTypes.func
}; };

View file

@ -39,6 +39,10 @@ $pass-bg: $ui-aqua;
box-shadow: none; box-shadow: none;
} }
&.transparent {
background-color: transparent;
}
&.large { &.large {
border-radius: .25rem; border-radius: .25rem;
font-size: 1rem; font-size: 1rem;

View file

@ -1,21 +1,24 @@
import React, {useEffect, useMemo} from 'react'; import React, {useEffect, useMemo} from 'react';
import Button from '../forms/button.jsx'; import Button from '../forms/button.jsx';
import {FormattedMessage} from 'react-intl';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import './onboarding-navigation.scss'; import './modal-navigation.scss';
import classNames from 'classnames'; import classNames from 'classnames';
const OnboardingNavigation = ({ const ModalNavigation = ({
currentPage, currentPage,
totalDots, totalDots,
onNextPage, onNextPage,
onBackPage, onBackPage,
nextButtonText nextButtonText,
prevButtonText,
nextButtonImageSrc,
prevButtonImageSrc,
className
}) => { }) => {
useEffect(() => { useEffect(() => {
new Image().src = '/images/onboarding/right-arrow.svg'; new Image().src = nextButtonImageSrc;
new Image().src = '/images/onboarding/left-arrow.svg'; new Image().src = prevButtonImageSrc;
}, []); }, []);
const dots = useMemo(() => { const dots = useMemo(() => {
@ -32,49 +35,62 @@ const OnboardingNavigation = ({
}, [currentPage, totalDots]); }, [currentPage, totalDots]);
return ( return (
<div className="navigation"> <div className={classNames('navigation', className)}>
{ {
<Button <Button
onClick={onBackPage} onClick={onBackPage}
className={classNames({ className={classNames('navigation-button', {
hidden: !onBackPage hidden: !onBackPage,
transparent: !prevButtonText
})} })}
> >
<img <img
className="left-arrow" className="left-arrow"
alt="" alt=""
src="/images/onboarding/left-arrow.svg" src={prevButtonImageSrc}
/> />
<span className="navText"> <span className="navText">
{<FormattedMessage {prevButtonText}
id={'communityGuidelines.buttons.back'}
/>}
</span> </span>
</Button> } </Button> }
{(currentPage >= 0 && totalDots) && {(currentPage >= 0 && totalDots) &&
<div className="dotRow"> <div className="dotRow">
{dots} {dots}
</div>} </div>}
<Button onClick={onNextPage}> <Button
onClick={onNextPage}
className={classNames('navigation-button', {
transparent: !nextButtonText
})}
>
<span className="navText"> <span className="navText">
{nextButtonText || <FormattedMessage id={'communityGuidelines.buttons.next'} />} {nextButtonText}
</span> </span>
<img <img
className="right-arrow" className="right-arrow"
alt="" alt=""
src="/images/onboarding/right-arrow.svg" src={nextButtonImageSrc}
/> />
</Button> </Button>
</div> </div>
); );
}; };
OnboardingNavigation.propTypes = { ModalNavigation.propTypes = {
currentPage: PropTypes.number, currentPage: PropTypes.number,
totalDots: PropTypes.number, totalDots: PropTypes.number,
onNextPage: PropTypes.func, onNextPage: PropTypes.func,
onBackPage: PropTypes.func, onBackPage: PropTypes.func,
nextButtonText: PropTypes.node nextButtonText: PropTypes.node,
prevButtonText: PropTypes.node,
nextButtonImageSrc: PropTypes.string,
prevButtonImageSrc: PropTypes.string,
className: PropTypes.string
}; };
export default OnboardingNavigation; ModalNavigation.defaultProps = {
nextButtonImageSrc: '/images/onboarding/right-arrow.svg',
prevButtonImageSrc: '/images/onboarding/left-arrow.svg'
};
export default ModalNavigation;

View file

@ -1,7 +1,7 @@
@import "../../colors"; @import "../../colors";
@import "../../frameless"; @import "../../frameless";
.button{ .navigation-button{
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -35,6 +35,7 @@
.dotRow{ .dotRow{
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
width: 244px; width: 244px;
min-width: 0px; min-width: 0px;
padding: 0px 5px; padding: 0px 5px;

View file

@ -14,7 +14,7 @@ import Button from '../../components/forms/button.jsx';
import Modal from '../../components/modal/base/modal.jsx'; import Modal from '../../components/modal/base/modal.jsx';
import NotAvailable from '../../components/not-available/not-available.jsx'; import NotAvailable from '../../components/not-available/not-available.jsx';
import WarningBanner from '../../components/title-banner/warning-banner.jsx'; import WarningBanner from '../../components/title-banner/warning-banner.jsx';
import OnboardingNavigation from '../../components/onboarding-navigation/onboarding-navigation.jsx'; import ModalNavigation from '../../components/modal-navigation/modal-navigation.jsx';
import { import {
CommunityGuidelines, CommunityGuidelines,
communityGuidelines communityGuidelines
@ -285,10 +285,11 @@ const BecomeAScratcher = ({user, invitedScratcher, scratcher, sessionStatus}) =>
<FormattedMessage id={'becomeAScratcher.toBeAScratcher.communityGuidelines'} /> <FormattedMessage id={'becomeAScratcher.toBeAScratcher.communityGuidelines'} />
</div> </div>
</div> </div>
<OnboardingNavigation <ModalNavigation
onNextPage={nextPage} onNextPage={nextPage}
onBackPage={backPage} onBackPage={backPage}
nextButtonText={<FormattedMessage id={'becomeAScratcher.buttons.communityGuidelines'} />} nextButtonText={<FormattedMessage id={'becomeAScratcher.buttons.communityGuidelines'} />}
prevButtonText={<FormattedMessage id={'communityGuidelines.buttons.back'} />}
/> />
</div> </div>
); );

View file

@ -1,5 +1,6 @@
const FormattedMessage = require('react-intl').FormattedMessage; const FormattedMessage = require('react-intl').FormattedMessage;
const React = require('react'); const React = require('react');
const {useState, useCallback} = require('react');
const Button = require('../../components/forms/button.jsx'); const Button = require('../../components/forms/button.jsx');
const FlexRow = require('../../components/flex-row/flex-row.jsx'); const FlexRow = require('../../components/flex-row/flex-row.jsx');
@ -9,6 +10,7 @@ const Page = require('../../components/page/www/page.jsx');
const render = require('../../lib/render.jsx'); const render = require('../../lib/render.jsx');
const {useIntl} = require('react-intl'); const {useIntl} = require('react-intl');
const {CardsModal} = require('../../components/cards-modal/cards-modal.jsx');
require('./ideas.scss'); require('./ideas.scss');
@ -87,6 +89,10 @@ const physicalIdeasData = [
const Ideas = () => { const Ideas = () => {
const intl = useIntl(); const intl = useIntl();
const [isOpen, setIsOpen] = useState(false);
const onOpen = useCallback(() => setIsOpen(true), [setIsOpen]);
const onClose = useCallback(() => setIsOpen(false), [setIsOpen]);
return ( return (
<div> <div>
@ -154,6 +160,31 @@ const Ideas = () => {
</FlexRow> </FlexRow>
</div> </div>
</div> </div>
<div className="youtube-videos">
<div className="inner">
<div
className="download-cards"
>
<Button
className="pass"
onClick={onOpen}
>
<img src="/images/ideas/download-icon.svg" />
</Button>
<FormattedMessage
id="ideas.downloadGuides"
values={{
strong: chunks => <strong>{chunks}</strong>,
a: chunks => <a onClick={onOpen}>{chunks}</a>
}}
/>
<CardsModal
isOpen={isOpen}
onClose={onClose}
/>
</div>
</div>
</div>
<div className="physical-ideas"> <div className="physical-ideas">
<div className="inner"> <div className="inner">
<div className="section-header"> <div className="section-header">

View file

@ -40,6 +40,36 @@ $base-bg: $ui-white;
} }
} }
.youtube-videos {
.inner {
.download-cards {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 3.5rem;
.button {
display: flex;
justify-content: center;
align-items: center;
width: 2rem;
height: 2rem;
}
span {
font-size: 1rem;
line-height: 1.5rem;
text-align: start;
a {
text-decoration: underline;
}
}
}
}
}
.physical-ideas { .physical-ideas {
.inner { .inner {
display: flex; display: flex;

View file

@ -11,6 +11,8 @@
"cards.pong-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/pong-cards.pdf", "cards.pong-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/pong-cards.pdf",
"cards.fly-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/fly-cards.pdf", "cards.fly-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/fly-cards.pdf",
"cards.imagine-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/imagine-cards.pdf", "cards.imagine-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/imagine-cards.pdf",
"cards.paperplanes-turtlegraphics-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/paperplanes-turtlegraphics-cards.pdf",
"cards.facesensing-cardsLink": "https://resources.scratch.mit.edu/www/cards/en/facesensing-cards.pdf",
"guides.NameGuideLink": "https://resources.scratch.mit.edu/www/guides/en/NameGuide.pdf", "guides.NameGuideLink": "https://resources.scratch.mit.edu/www/guides/en/NameGuide.pdf",
"guides.AnimateGuideLink": "https://resources.scratch.mit.edu/www/guides/en/AnimateGuide.pdf", "guides.AnimateGuideLink": "https://resources.scratch.mit.edu/www/guides/en/AnimateGuide.pdf",
"guides.MusicGuideLink": "https://resources.scratch.mit.edu/www/guides/en/MusicGuide.pdf", "guides.MusicGuideLink": "https://resources.scratch.mit.edu/www/guides/en/MusicGuide.pdf",
@ -19,5 +21,13 @@
"guides.VideoGuideLink": "https://resources.scratch.mit.edu/www/guides/en/VideoGuide.pdf", "guides.VideoGuideLink": "https://resources.scratch.mit.edu/www/guides/en/VideoGuide.pdf",
"guides.PongGuideLink": "https://resources.scratch.mit.edu/www/guides/en/PongGuide.pdf", "guides.PongGuideLink": "https://resources.scratch.mit.edu/www/guides/en/PongGuide.pdf",
"guides.FlyGuideLink": "https://resources.scratch.mit.edu/www/guides/en/FlyGuide.pdf", "guides.FlyGuideLink": "https://resources.scratch.mit.edu/www/guides/en/FlyGuide.pdf",
"guides.ImagineGuideLink": "https://resources.scratch.mit.edu/www/guides/en/ImagineGuide.pdf" "guides.ImagineGuideLink": "https://resources.scratch.mit.edu/www/guides/en/ImagineGuide.pdf",
"guides.ScratchLearningResource_CreateOriginalSpriteLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_CreateOriginalSprite.pdf",
"guides.ScratchLearningResource_RemixRe-imagineSpritesLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_RemixRe-imagineSprites.pdf",
"guides.ScratchLearningResource_BringYourDrawingsIntoScratchLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_BringYourDrawingsIntoScratch.pdf",
"guides.ScratchLearningResource_SoundsAddRecordText-to-SpeechLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_SoundsAddRecordText-to-Speech.pdf",
"guides.ScratchLearningResource_CreateanAssetPackLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_CreateanAssetPack.pdf",
"guides.ScratchLearningResource_ConditionalStatementsLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_ConditionalStatements.pdf",
"guides.ScratchLearningResource_VariablesandListsLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_VariablesandLists.pdf",
"guides.ScratchLearningResource_MyBlocksLink": "https://resources.scratch.mit.edu/www/guides/en/ScratchLearningResource_MyBlocks.pdf"
} }

View file

@ -2,16 +2,11 @@
"ideas.headerMessage": "What will you create?", "ideas.headerMessage": "What will you create?",
"ideas.headerImageDescription": "Outlandish creations from pixelated unicorns to drumbeat waveforms to levitating tacos to buckets of rainbows.", "ideas.headerImageDescription": "Outlandish creations from pixelated unicorns to drumbeat waveforms to levitating tacos to buckets of rainbows.",
"ideas.headerButtonMessage": "Choose a tutorial", "ideas.headerButtonMessage": "Choose a tutorial",
"ideas.gettingStartedTitle": "Getting Started", "ideas.startHereText": "New to Scratch? Start here!",
"ideas.gettingStartedText": "New to Scratch? Try the Getting Started tutorial.",
"ideas.startHereText": "New to Scratch? Stay here!",
"ideas.gettingStartedButtonText": "Try Getting Started Tutorial", "ideas.gettingStartedButtonText": "Try Getting Started Tutorial",
"ideas.seeTutorialsLibraryButtonText": "See Tutorials Library", "ideas.seeTutorialsLibraryButtonText": "See Tutorials Library",
"ideas.gettingStartedImageDescription": "An illustrated boy plants his flag on top of a freshly painted mountaintop.", "ideas.gettingStartedImageDescription": "An illustrated boy plants his flag on top of a freshly painted mountaintop.",
"ideas.seeTutorialsLibraryImageDescription": "An illustration of three tutorial thumbnails.", "ideas.seeTutorialsLibraryImageDescription": "An illustration of three tutorial thumbnails.",
"ideas.tryIt": "Try it!",
"ideas.activityGuidesTitle": "Activity Guides",
"ideas.activityGuidesText": "What do you want to make with Scratch? For each activity, you can try the Tutorial, download a set of Coding Cards, or view the Educator Guide.",
"ideas.animateANameTitle": "Animate a Name", "ideas.animateANameTitle": "Animate a Name",
"ideas.animateANameDescription": "Animate the letters of your name, initials, or favorite word.", "ideas.animateANameDescription": "Animate the letters of your name, initials, or favorite word.",
"ideas.animateANameImageDescription": "The name ANYA in all caps and blocked letters is poised to wiggle", "ideas.animateANameImageDescription": "The name ANYA in all caps and blocked letters is poised to wiggle",
@ -30,12 +25,7 @@
"ideas.videoSensingTitle": "Video Sensing", "ideas.videoSensingTitle": "Video Sensing",
"ideas.videoSensingDescription": "Interact with a project using the Video Sensing extension.", "ideas.videoSensingDescription": "Interact with a project using the Video Sensing extension.",
"ideas.videoSensingImageDescription": "A virtual hand dodges a spurt of flame in an attempt to pet a dragon.", "ideas.videoSensingImageDescription": "A virtual hand dodges a spurt of flame in an attempt to pet a dragon.",
"ideas.seeAllTutorials": "See All Tutorials",
"ideas.cardsTitle": "Get the Entire Collection of Coding Cards",
"ideas.cardsText": "With the Scratch Coding Cards, you can learn to create interactive games, stories, music, animations, and more!",
"ideas.cardsIllustrationDescription": "An assortment of fun, animated characters and objects leap out of a stack of cards.", "ideas.cardsIllustrationDescription": "An assortment of fun, animated characters and objects leap out of a stack of cards.",
"ideas.starterProjectsTitle": "Starter Projects",
"ideas.starterProjectsText": "You can play with Starter Projects and remix them to make your own creations.",
"ideas.starterProjectsImageDescription": "An illustration of the Scratch Code Editor.", "ideas.starterProjectsImageDescription": "An illustration of the Scratch Code Editor.",
"ideas.starterProjectsButton": "Explore Starter Projects", "ideas.starterProjectsButton": "Explore Starter Projects",
"ideas.tryTheTutorial": "Try the tutorial", "ideas.tryTheTutorial": "Try the tutorial",
@ -47,31 +37,30 @@
"ideas.makeyMakeyHeader": "Have a MakeyMakey?", "ideas.makeyMakeyHeader": "Have a MakeyMakey?",
"ideas.makeyMakeyBody": "Turn anything into a key that connects with your Scratch project!", "ideas.makeyMakeyBody": "Turn anything into a key that connects with your Scratch project!",
"ideas.desktopEditorHeader": "Scratch App Download", "ideas.desktopEditorHeader": "Scratch App Download",
"ideas.desktopEditorBody": "To create projects without an Internet connection, you can <a href=\"/download\">download the Scratch app</a>.",
"ideas.desktopEditorBodyHTML": "To create projects without an Internet connection, you can <a>download the Scratch app</a>.", "ideas.desktopEditorBodyHTML": "To create projects without an Internet connection, you can <a>download the Scratch app</a>.",
"ideas.questionsHeader": "Questions", "ideas.questionsHeader": "Questions",
"ideas.questionsBody": "Have more questions? See the <a href=\"/info/faq\">Frequently Asked Questions</a> or visit the <a href=\"/discuss/7/\">Help with Scripts Forum</a>.",
"ideas.questionsBodyHTML": "Have more questions? See the <faq>Frequently Asked Questions</faq> or visit the <forum>Help with Scripts Forum</forum>.", "ideas.questionsBodyHTML": "Have more questions? See the <faq>Frequently Asked Questions</faq> or visit the <forum>Help with Scripts Forum</forum>.",
"ideas.cardsPurchase": "Purchase Printed Set",
"ideas.MakeItFlyTitle": "Make It Fly", "ideas.MakeItFlyTitle": "Make It Fly",
"ideas.MakeItFlyDescription": "Choose any character and make it fly!", "ideas.MakeItFlyDescription": "Choose any character and make it fly!",
"ideas.MakeItFlyImageDescription": "The scratch cat flies over the skyline. Alongside a flying taco.", "ideas.MakeItFlyImageDescription": "The scratch cat flies over the skyline. Alongside a flying taco.",
"ideas.RaceTitle": "Race to the Finish",
"ideas.RaceDescription": "Make a game where two characters race each other.",
"ideas.HideAndSeekTitle": "Hide and Seek",
"ideas.HideAndSeekDescription": "Make a hide-and-seek game with characters that appear and disappear.",
"ideas.FashionTitle": "Fashion Game",
"ideas.FashionDescription": "Make a game where you dress a character with different clothes and styles.",
"ideas.PongTitle": "Pong Game", "ideas.PongTitle": "Pong Game",
"ideas.PongDescription": "Make a bouncing ball game with sounds, points, and other effects.", "ideas.PongDescription": "Make a bouncing ball game with sounds, points, and other effects.",
"ideas.PongImageDescription": "A ball bounces off a digital paddle.", "ideas.PongImageDescription": "A ball bounces off a digital paddle.",
"ideas.ImagineTitle": "Imagine a World", "ideas.ImagineTitle": "Imagine a World",
"ideas.ImagineDescription": "Imagine a world where anything is possible.", "ideas.ImagineDescription": "Imagine a world where anything is possible.",
"ideas.ImagineImageDescription": "A girl stands proudly in front of a thought bubble as big as the Earth and as intricate as butterfly wings.", "ideas.ImagineImageDescription": "A girl stands proudly in front of a thought bubble as big as the Earth and as intricate as butterfly wings.",
"ideas.DanceTitle": "Let's Dance", "ideas.modalTitle": "Written Guides",
"ideas.DanceDescription": "Design an animated dance scene with music and dance moves.", "ideas.modalSectionTitleSpritesAndSounds": "Sprites and Sounds",
"ideas.CatchTitle": "Catch Game", "ideas.modalSectionTitleAdvancedTopics": "Advanced Topics",
"ideas.CatchDescription": "Make a game where you catch things falling from the sky.", "ideas.modalCardNameCreateSprite": "Create a Sprite with the Paint Editor",
"ideas.VirtualPetTitle": "Virtual Pet", "ideas.modalCardNameRemix": "Remix and Re-Imagine Sprites",
"ideas.VirtualPetDescription": "Create an interactive pet that can eat, drink, and play." "ideas.modalCardNameBringDrawingsIntoScratch": "Bring Your Drawings Into Scratch",
"ideas.modalCardNameSound": "Sound: Add, Record, and Use Text to Speech Blocks",
"ideas.modalCardNameCreateAsset": "Create Your Own Asset Pack",
"ideas.modalCardNameConditionalStatements": "Conditional Statements",
"ideas.modalCardNameVariablesLists": "Variables and Lists",
"ideas.modalCardNameCustomBlocks": "Make Your Custom My Blocks",
"ideas.modalCardNameFaceSensing": "Scratch Lab Face Sensing Coding Cards",
"ideas.modalCardNameComputationalConcepts": "Turtle Graphics Coding Cards",
"ideas.downloadGuides": "<strong>Computer doesnt allow Youtube?</strong> Download <a>written guides</a> for these topics."
} }

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,3 @@
<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.558139 10.7977L7.83016 18.2108C8.42768 18.7845 9.26604 18.9379 9.9863 18.6192C10.7066 18.3028 11.1512 17.604 11.1512 16.7943L11.1512 13.9825L21.2718 12.5494C22.8212 12.344 24 10.97 24 9.35284C24 9.21355 23.9907 9.0719 23.9745 8.93261C23.7499 7.4736 22.6336 6.34747 21.2603 6.17041L11.1512 4.6996L11.1512 2.01058C11.1512 1.19137 10.6788 0.461858 9.94924 0.152587C9.21509 -0.156686 8.4022 0.0109341 7.83016 0.594066L0.558139 8.00716C0.199169 8.37545 -8.6648e-07 8.87123 -8.20042e-07 9.40242C-7.73604e-07 9.93361 0.199169 10.4294 0.558139 10.7977Z" fill="#4C97FF"/>
</svg>

After

Width:  |  Height:  |  Size: 718 B

View file

@ -0,0 +1,3 @@
<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.4419 10.7977L16.1698 18.2108C15.5723 18.7845 14.734 18.9379 14.0137 18.6192C13.2934 18.3028 12.8488 17.604 12.8488 16.7943L12.8488 13.9825L2.72817 12.5494C1.17881 12.344 6.82997e-07 10.97 8.24376e-07 9.35284C8.36553e-07 9.21355 0.00926484 9.0719 0.0254754 8.93261C0.250121 7.4736 1.3664 6.34747 2.73975 6.17041L12.8488 4.6996L12.8488 2.01058C12.8488 1.19137 13.3212 0.461858 14.0508 0.152587C14.7849 -0.156686 15.5978 0.0109341 16.1698 0.594066L23.4419 8.00716C23.8008 8.37545 24 8.87123 24 9.40242C24 9.93361 23.8008 10.4294 23.4419 10.7977Z" fill="#4C97FF"/>
</svg>

After

Width:  |  Height:  |  Size: 717 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.6 KiB