From 8dc26d8d307ff0fd71d142f2dfde649368edd5f2 Mon Sep 17 00:00:00 2001 From: Matthew Taylor <mewtaylor@gmail.com> Date: Wed, 20 Dec 2017 14:49:27 -0500 Subject: [PATCH] Partially Implement GH-830: Add coming soon tooltips (#1069) * Implement GH-830: Add coming soon tooltips This implements coming soon tooltips for: * the small stage size * save, load and language It also creates the component that can be copied over into the paint editor for use there as well. Lastly, this does a small refactor on the full screen implementation to include multiple small screen sizes too. --- package.json | 1 + src/components/button/button.jsx | 34 +-- src/components/coming-soon/aww-cat.png | Bin 0 -> 4467 bytes src/components/coming-soon/coming-soon.css | 68 ++++++ src/components/coming-soon/coming-soon.jsx | 143 ++++++++++++ src/components/coming-soon/cool-cat.png | Bin 0 -> 3829 bytes src/components/gui/gui.css | 8 - src/components/gui/gui.jsx | 8 +- .../language-selector/language-icon.svg | Bin 3693 -> 1898 bytes .../language-selector/language-selector.css | 5 +- .../language-selector/language-selector.jsx | 49 +++-- src/components/load-button/load-button.jsx | 26 ++- src/components/menu-bar/menu-bar.css | 10 +- .../prompt/icon--dropdown-caret.svg | Bin 0 -> 950 bytes src/components/prompt/prompt.css | 26 +++ src/components/prompt/prompt.jsx | 32 ++- .../stage-header/icon--fullscreen.svg | Bin 0 -> 2620 bytes .../stage-header/icon--large-stage.svg | Bin 0 -> 1167 bytes .../stage-header/icon--small-stage.svg | Bin 0 -> 1173 bytes .../stage-header/icon--unfullscreen.svg | Bin 0 -> 3006 bytes src/components/stage-header/icon--unzoom.svg | Bin 2906 -> 0 bytes src/components/stage-header/icon--zoom.svg | Bin 2902 -> 0 bytes src/components/stage-header/stage-header.css | 45 +++- src/components/stage-header/stage-header.jsx | 204 ++++++++++++------ src/components/stage/stage.jsx | 14 +- src/containers/save-button.jsx | 18 +- src/containers/stage-header.jsx | 17 +- src/containers/stage.jsx | 6 +- src/css/colors.css | 2 + src/reducers/gui.js | 4 +- src/reducers/stage-size.js | 55 +++++ src/reducers/zoom.js | 23 -- test/integration/test.js | 6 +- 33 files changed, 615 insertions(+), 189 deletions(-) create mode 100644 src/components/coming-soon/aww-cat.png create mode 100644 src/components/coming-soon/coming-soon.css create mode 100644 src/components/coming-soon/coming-soon.jsx create mode 100644 src/components/coming-soon/cool-cat.png create mode 100644 src/components/prompt/icon--dropdown-caret.svg create mode 100644 src/components/stage-header/icon--fullscreen.svg create mode 100644 src/components/stage-header/icon--large-stage.svg create mode 100644 src/components/stage-header/icon--small-stage.svg create mode 100644 src/components/stage-header/icon--unfullscreen.svg delete mode 100644 src/components/stage-header/icon--unzoom.svg delete mode 100644 src/components/stage-header/icon--zoom.svg create mode 100644 src/reducers/stage-size.js delete mode 100644 src/reducers/zoom.js diff --git a/package.json b/package.json index 778cc2eea..50369a1f7 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "react-style-proptype": "3.1.0", "react-tabs": "2.1.1", "react-test-renderer": "16.2.0", + "react-tooltip": "3.4.0", "redux": "3.7.0", "redux-mock-store": "^1.2.3", "redux-throttle": "0.1.1", diff --git a/src/components/button/button.jsx b/src/components/button/button.jsx index ae322d10f..59b39668f 100644 --- a/src/components/button/button.jsx +++ b/src/components/button/button.jsx @@ -9,23 +9,31 @@ const ButtonComponent = ({ onClick, children, ...props -}) => ( - <span - className={classNames( - styles.button, - className - )} - role="button" - onClick={onClick} - {...props} - > - {children} - </span> -); +}) => { + if (props.disabled === true) { + onClick = function () {}; + } + + return ( + <span + className={classNames( + styles.button, + className + )} + role="button" + onClick={onClick} + {...props} + > + {children} + </span> + ); +}; ButtonComponent.propTypes = { children: PropTypes.node, className: PropTypes.string, + disabled: PropTypes.bool, onClick: PropTypes.func.isRequired }; + export default ButtonComponent; diff --git a/src/components/coming-soon/aww-cat.png b/src/components/coming-soon/aww-cat.png new file mode 100644 index 0000000000000000000000000000000000000000..bddfb8de9ee95ccef600bcb6a67ce5ed3c5ed4d5 GIT binary patch literal 4467 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 FV1kgta$x`f literal 0 HcmV?d00001 diff --git a/src/components/coming-soon/coming-soon.css b/src/components/coming-soon/coming-soon.css new file mode 100644 index 000000000..7c3bdeb14 --- /dev/null +++ b/src/components/coming-soon/coming-soon.css @@ -0,0 +1,68 @@ +/* + * NOTE: the copious use of `important` is needed to overwrite + * the default tooltip styling, and is required by the 3rd party + * library being used, `react-tooltip` + */ + +@import "../../css/colors.css"; + +.coming-soon { + background-color: $data-primary !important; + border: 1px solid hsla(0, 0%, 0%, .1) !important; + border-radius: .25rem !important; + box-shadow: 0 0 .5rem hsla(0, 0%, 0%, .25) !important; + padding: .75rem 1rem !important; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important; + font-size: 1rem !important; + line-height: 1.25rem !important; + z-index: 100 !important; +} + +.coming-soon:after { + content: ""; + border-top: 1px solid hsla(0, 0%, 0%, .1) !important; + border-left: 0 !important; + border-bottom: 0 !important; + border-right: 1px solid hsla(0, 0%, 0%, .1) !important; + border-radius: .25rem; + background-color: $data-primary !important; + height: 1rem !important; + width: 1rem !important; +} + +.show, +.show:before, +.show:after { + opacity: 1 !important; +} + +.left:after { + margin-top: -.5rem !important; + right: -.5rem !important; + transform: rotate(45deg) !important; +} + +.right:after { + margin-top: -.5rem !important; + left: -.5rem !important; + transform: rotate(-135deg) !important; +} + +.top:after { + margin-right: -.5rem !important; + bottom: -.5rem !important; + transform: rotate(135deg) !important; +} + +.bottom:after { + margin-left: -.5rem !important; + top: -.5rem !important; + transform: rotate(-45deg) !important; +} + +.coming-soon-image { + margin-left: .125rem; + width: 1.25rem; + height: 1.25rem; + vertical-align: middle; +} diff --git a/src/components/coming-soon/coming-soon.jsx b/src/components/coming-soon/coming-soon.jsx new file mode 100644 index 000000000..e16ae80be --- /dev/null +++ b/src/components/coming-soon/coming-soon.jsx @@ -0,0 +1,143 @@ +import bindAll from 'lodash.bindall'; +import classNames from 'classnames'; +import {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-intl'; +import PropTypes from 'prop-types'; +import React from 'react'; +import ReactTooltip from 'react-tooltip'; + +import styles from './coming-soon.css'; + +import awwCatIcon from './aww-cat.png'; +import coolCatIcon from './cool-cat.png'; + +const messages = defineMessages({ + message1: { + defaultMessage: 'Don\'t worry, we\'re on it {emoji}', + description: 'One of the "coming soon" random messages for yet-to-be-done features', + id: 'gui.comingSoon.message1' + }, + message2: { + defaultMessage: 'Coming Soon...', + description: 'One of the "coming soon" random messages for yet-to-be-done features', + id: 'gui.comingSoon.message2' + }, + message3: { + defaultMessage: 'We\'re working on it {emoji}', + description: 'One of the "coming soon" random messages for yet-to-be-done features', + id: 'gui.comingSoon.message3' + } +}); + +class ComingSoonContent extends React.Component { + constructor (props) { + super(props); + bindAll(this, [ + 'setHide', + 'setShow', + 'getRandomMessage' + ]); + this.state = { + isShowing: false + }; + } + setShow () { + // needed to set the opacity to 1, since the default is .9 on show + this.setState({isShowing: true}); + } + setHide () { + this.setState({isShowing: false}); + } + getRandomMessage () { + // randomly chooses a messages from `messages` to display in the tooltip. + const images = [awwCatIcon, coolCatIcon]; + const messageNumber = Math.floor(Math.random() * Object.keys(messages).length) + 1; + const imageNumber = Math.floor(Math.random() * Object.keys(images).length); + return ( + <FormattedMessage + {...messages[`message${messageNumber}`]} + values={{ + emoji: ( + <img + className={styles.comingSoonImage} + src={images[imageNumber]} + /> + ) + }} + /> + ); + } + render () { + return ( + <ReactTooltip + afterHide={this.setHide} + afterShow={this.setShow} + className={classNames( + styles.comingSoon, + this.props.className, + { + [styles.show]: (this.state.isShowing), + [styles.left]: (this.props.place === 'left'), + [styles.right]: (this.props.place === 'right'), + [styles.top]: (this.props.place === 'top'), + [styles.bottom]: (this.props.place === 'bottom') + } + )} + getContent={this.getRandomMessage} + id={this.props.tooltipId} + /> + ); + } +} + +ComingSoonContent.propTypes = { + className: PropTypes.string, + intl: intlShape, + place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), + tooltipId: PropTypes.string.isRequired +}; + +ComingSoonContent.defaultProps = { + place: 'bottom' +}; + +const ComingSoon = injectIntl(ComingSoonContent); + +const ComingSoonTooltip = props => ( + <div className={props.className}> + <div + data-delay-hide={props.delayHide} + data-delay-show={props.delayShow} + data-effect="solid" + data-for={props.tooltipId} + data-place={props.place} + data-tip="tooltip" + > + {props.children} + </div> + <ComingSoon + className={props.tooltipClassName} + place={props.place} + tooltipId={props.tooltipId} + /> + </div> +); + +ComingSoonTooltip.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, + delayHide: PropTypes.number, + delayShow: PropTypes.number, + place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), + tooltipClassName: PropTypes.string, + tooltipId: PropTypes.string.isRequired +}; + +ComingSoonTooltip.defaultProps = { + delayHide: 0, + delayShow: 0 +}; + +export { + ComingSoon as ComingSoonComponent, + ComingSoonTooltip +}; diff --git a/src/components/coming-soon/cool-cat.png b/src/components/coming-soon/cool-cat.png new file mode 100644 index 0000000000000000000000000000000000000000..15b2151e35bd84cfa154e6af8fd20607ca4d5e9e GIT binary patch literal 3829 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 literal 0 HcmV?d00001 diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css index 3d08cadf6..2c0533e98 100644 --- a/src/components/gui/gui.css +++ b/src/components/gui/gui.css @@ -143,14 +143,6 @@ overflow: hidden; } -.stage-menu-wrapper { - display: flex; - flex-shrink: 0; - align-items: center; - height: $stage-menu-height; - padding: $space; -} - .extension-button-container { width: 3.25rem; height: 3.25rem; diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index 349e20d5e..639c8cbd3 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -112,13 +112,7 @@ const GUIComponent = props => { <Box className={styles.stageAndTargetWrapper}> <Box className={styles.stageMenuWrapper}> - <MediaQuery minWidth={layout.fullSizeMinWidth}>{isFullSize => ( - <StageHeader - height={isFullSize ? layout.fullStageHeight : layout.smallerStageHeight} - vm={vm} - width={isFullSize ? layout.fullStageWidth : layout.smallerStageWidth} - /> - )}</MediaQuery> + <StageHeader vm={vm} /> </Box> <Box className={styles.stageWrapper}> <MediaQuery minWidth={layout.fullSizeMinWidth}>{isFullSize => ( diff --git a/src/components/language-selector/language-icon.svg b/src/components/language-selector/language-icon.svg index 3644ab6fde2247b0cd949231071e98bc95638a10..42bd409ab18e8ed0e737e6547c7ecc89ea57df0d 100644 GIT binary patch literal 1898 zcma)7QE!_t5Pt8k@Vu8+3dS}D>?)+vB5g05G^yLm-dJ!6D}e}TlKuOg4J4PU(i%mI z`F#HF^LKY-`Ec6R<Y2qLYMYD-#woGQrY)+b%;?V_p94)vKjcl3*KK1n+O+gxb+hab zB{^2bu+6CC`x7NwTb0{kemYe4_^CZ*loL**`%;`lPy%V2KBL=V*x!fY@pxp%h_ziA zO3rx*^i#<Fsjiymw*rMRCiJ^>bwl8@{161>i*0O|4{di(9-r;7*%Fm9L2gy7q`V^m zK^cFyTf3|B>AGyw?!taN69g0GPz|+Rea)NlB`@tV9G}N@h3z-1b!YRz7GTD(oiegz z=(pymr+(!S_!*IsR7FO=1783}^h4J^dt)0rKLwMuu>DlkwR7EVx^>XK)DUeCwrPvv zd;m<cn|z<qu6=0$Zuj}78va57n2fKY{<IYodJG!{dGAJ1^F`+q8T|<5fX@t^l{wnW z@rh#S@}_@kyIn^8vIc8zB^xOgWM199I_XdEb1)Em`6gnPM6q0GCWJIf2u;>ACM1)I zmQfrLzf4kySd6=AqEg}yMQ(}Fb;L}Za(58JoW)uvLZk`67iJ7&5g7M`kcB4%ak~fu zbSf2C35M55H^%21BH|fB8h%mVJCD9+pnIUPoNw2Kcx9(xMsw}$O#EfR&IvOtRVI$X zLjq7L;z(<`fTc{hP(nIX!r(v+oI%P+kFEtMk7Et)Ereo`i6Xc(F--9^am5);R<1bS z2kvWz(RISKh*DQw3`6M?BU2t5OstqmK%6f%QlVHZX6B1z#iUXZ#EJ#F9zva+vk?eR zn9|ZI76cJP>NN6=1L#>r1ipz8U1P~i%gIi3Jy&H7zB!9r?nyF+*T_1IW1lbFs3=$n zsvuGgs4qXd-V7lluKOx_PhW8ushCg018*7ar<Ht#u7wd*e$>wJRolXg<Ns}o>0@S8 z;@%17iv9v$(WmdB_cJA++tmULH=KiBM~`qneyN*|D|+)b{W2^sQ+R&xi>3QJTm1uf CZO0@4 literal 3693 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 V&ra539k2RB<p1!ZztLVD{sq2uFpvNM diff --git a/src/components/language-selector/language-selector.css b/src/components/language-selector/language-selector.css index a060131a8..0ae9e0a10 100644 --- a/src/components/language-selector/language-selector.css +++ b/src/components/language-selector/language-selector.css @@ -1,3 +1,4 @@ +@import "../../css/colors.css"; @import "../../css/units.css"; .group { @@ -9,7 +10,7 @@ .language-icon { height: 2rem; - display:none; + display: none; } .language-select { @@ -19,7 +20,7 @@ user-select: none; outline: none; background: rgba(255, 255, 255, 0.5); - color: #3373cc; + color: $motion-tertiary; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } diff --git a/src/components/language-selector/language-selector.jsx b/src/components/language-selector/language-selector.jsx index d3d3bb48d..db846fef5 100644 --- a/src/components/language-selector/language-selector.jsx +++ b/src/components/language-selector/language-selector.jsx @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import Box from '../box/box.jsx'; +import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx'; import locales from 'scratch-l10n'; import languageIcon from './language-icon.svg'; import styles from './language-selector.css'; @@ -12,27 +13,33 @@ const LanguageSelector = ({ ...props }) => ( <Box {...props}> - <div className={styles.group}> - <img - className={styles.languageIcon} - src={languageIcon} - /> - <select - aria-label="language selector" - className={styles.languageSelect} - value={currentLocale} - onChange={onChange} - > - {Object.keys(locales).map(locale => ( - <option - key={locale} - value={locale} - > - {locales[locale].name} - </option> - ))} - </select> - </div> + <ComingSoonTooltip + place="bottom" + tooltipId="language-selector" + > + <div className={styles.group}> + <img + className={styles.languageIcon} + src={languageIcon} + /> + <select + disabled + aria-label="language selector" + className={styles.languageSelect} + value={currentLocale} + onChange={onChange} + > + {Object.keys(locales).map(locale => ( + <option + key={locale} + value={locale} + > + {locales[locale].name} + </option> + ))} + </select> + </div> + </ComingSoonTooltip> </Box> ); diff --git a/src/components/load-button/load-button.jsx b/src/components/load-button/load-button.jsx index dd94a2a11..0f580278c 100644 --- a/src/components/load-button/load-button.jsx +++ b/src/components/load-button/load-button.jsx @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import ButtonComponent from '../button/button.jsx'; +import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx'; import styles from './load-button.css'; @@ -13,13 +14,24 @@ const LoadButtonComponent = ({ ...props }) => ( <span {...props}> - <ButtonComponent onClick={onClick}>{title}</ButtonComponent> - <input - className={styles.fileInput} - ref={inputRef} - type="file" - onChange={onChange} - /> + <ComingSoonTooltip + place="bottom" + tooltipId="load-button" + > + <ButtonComponent + disabled + onClick={onClick} + > + {title} + </ButtonComponent> + <input + disabled + className={styles.fileInput} + ref={inputRef} + type="file" + onChange={onChange} + /> + </ComingSoonTooltip> </span> ); diff --git a/src/components/menu-bar/menu-bar.css b/src/components/menu-bar/menu-bar.css index a9d3b37fa..a85926d39 100644 --- a/src/components/menu-bar/menu-bar.css +++ b/src/components/menu-bar/menu-bar.css @@ -1,3 +1,4 @@ +@import "../../css/colors.css"; @import "../../css/units.css"; .menu-bar { @@ -23,7 +24,7 @@ width: 100%; */ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - background-color: #4c97ff; + background-color: $motion-primary; color: white; } @@ -56,11 +57,6 @@ line-height: $menu-bar-height; cursor: pointer; text-decoration: none; - color: white; + color: $motion-tertiary; user-select: none; } - -.menu-item:hover { - opacity: 0.8; - background: rgba(255, 255, 255, 0.2) -} diff --git a/src/components/prompt/icon--dropdown-caret.svg b/src/components/prompt/icon--dropdown-caret.svg new file mode 100644 index 0000000000000000000000000000000000000000..8e08eda35e5cb30d80ec7d97a21352dbe6098f7a GIT binary patch literal 950 zcmZuw+m4$s5PjdTaNU<y3dVPv2w166+m~IbQri!p!3!uXj=&A+-*>n~CDrC7_L-S; zW{!vS@%q}Li|dERcNu1cV&uA`FPpB)@XsG#B8$-wimohL-?<ET9zW&}>2Rsg*p#8p zusvTfs$EmnA;W6ATpBli^4APgM3F@bkbeRUBarNd4A&u?_i;RqBN+wpeHC*`X$;hB z%Kq9m-RZ4FmLy3$M{)ju;FrFOBJ|aDt}lY`_vrh{g=3ARB@BI#hAa9JMQEe=%h&F; zDb`WR(Z9ySQWHfhWoSa{^0N2m(vMwqEP5BBsxSVe@e*2;OE(<zL+^^<O7JAqt2jyH zIdsc<8S)8%zXhpKQ)c*EQMm{_8A9(*v%j6Y-J;cD2){IKJDEQPr*qW*ZXw%UT<6Pj zHDNYlp?#z48_9cR)MukMHFMp$fX<<zXSq}8AP9KIsi78bf=I=*pj7W9v58I;l@rP( z<0dfzPz|sWjG-q=1e2NxW%!N}OSRUV8+3>$VN_bfSi&G662Y~y0^Q*hWTlpza)Gu) z)0t9fgkb0ZNrGF;rLeoXS_qkdv>{vry;1r<SX(8mmST5D1FNz21GwQrN?{B~8+g;D zfeBZV%}`I07?mVKGqd&JAc>NRvM}D(FiE)4ltSm=DY%U11-O4H3_CKt#Ihsv!^G9P LFw-HOK9Bq_1LgV` literal 0 HcmV?d00001 diff --git a/src/components/prompt/prompt.css b/src/components/prompt/prompt.css index 94b907c04..527901233 100644 --- a/src/components/prompt/prompt.css +++ b/src/components/prompt/prompt.css @@ -49,3 +49,29 @@ .button-row button + button { margin-left: 0.5rem; } + +.more-options { + border-top: 1px dashed hsla(0, 0%, 0%, .25); + overflow: visible; + padding: 1rem; + text-align: center; + margin: 0 0 1rem; +} + +.more-options-accordion { + width: 60%; + margin: 0 auto; +} + +.more-options-text { + opacity: .5; +} + +.more-options-icon { + width: .75rem; + height: .75rem; + margin-left: .5rem; + vertical-align: middle; + padding-bottom: .2rem; + opacity: .5; +} diff --git a/src/components/prompt/prompt.jsx b/src/components/prompt/prompt.jsx index 4fca4cb4a..b99580b79 100644 --- a/src/components/prompt/prompt.jsx +++ b/src/components/prompt/prompt.jsx @@ -1,10 +1,23 @@ +import {defineMessages, FormattedMessage} from 'react-intl'; import PropTypes from 'prop-types'; import React from 'react'; -import Modal from '../modal/modal.jsx'; + import Box from '../box/box.jsx'; +import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx'; +import Modal from '../modal/modal.jsx'; import styles from './prompt.css'; +import dropdownIcon from './icon--dropdown-caret.svg'; + +const messages = defineMessages({ + moreOptionsMessage: { + defaultMessage: 'More Options', + description: 'Dropdown message for variable/list options', + id: 'gui.gui.variablePrompt' + } +}); + const PromptComponent = props => ( <Modal className={styles.modalContent} @@ -24,6 +37,23 @@ const PromptComponent = props => ( onKeyPress={props.onKeyPress} /> </Box> + <Box className={styles.moreOptions}> + <ComingSoonTooltip + className={styles.moreOptionsAccordion} + place="right" + tooltipId="variable-options-accordion" + > + <div className={styles.moreOptionsText}> + <FormattedMessage + {...messages.moreOptionsMessage} + /> + <img + className={styles.moreOptionsIcon} + src={dropdownIcon} + /> + </div> + </ComingSoonTooltip> + </Box> <Box className={styles.buttonRow}> <button className={styles.cancelButton} diff --git a/src/components/stage-header/icon--fullscreen.svg b/src/components/stage-header/icon--fullscreen.svg new file mode 100644 index 0000000000000000000000000000000000000000..9d26e43918902d57eaa8c1719ee4c133877d85f9 GIT binary patch literal 2620 zcmb7G+ioI95PjdT=uBRAC20Cm)fWp`DJaehks>Ae0Aj{~j0X#5ZGV1F4-8Z6T8c8V z<gU}z)m?S!ls*0W{=8SO_3^YjG_%TTQ>nUnIIMTgW>)?E*ZnwE>eQ~9^=f};>RHts zs;~1;)6?rlz3tZRc2+s_@?NQJz1wWt-g@2DZ@(PgXO&S#x$;xVOKhcZZF8Dc+qQkV zn@rx`-t?Q-hvR1Aj4>00zqs7J?|049M~*h<Jn43;`6q>M`qOx<eyf}MxM~l_JN4&N z-9Bs;MQzn*Vsh?_8Y^+*KZkAoyjxw;)enc~$?1G%Jidf%ckRBO-+$ZhPY=hsZl;qn za=vg~pC0CmW4&tYHOkR$FL&zcq}%Gf9#8Xv;MW=1sNH&2{ju8AW0d059uH4lX`8yY z#+Tw^`*FA5m%5kDvK}A5?crU&*3DtPzU1EJe-1l5wm<tbNB%Xka24*4*W4=A9#_rj z@o;>eRo!xr#6EisM(~YPzxwiBq%PXa3h5)O->ui)CzJh%v}fbl1yW1vG*L={Xyi3< zN*?^FW!BzO@@(CRb@HBEB&!xlXO7m#Y)3&`lN?8rRMO;Aj)?#oA8bw?Xagl?j{qS= zc4WO;M4iboB^v<yXtK#Rse(ohE?B%R2WM<>jIezK(jhs^+2OrLv&VZlj;v-fhHc>T z-ViuZAUiTxA|FF3szughL(I$soNU59A(G0Pv(M3m2pBPpi#|HMI_vBS?k0S<u|)ZT zb<X0AMlE0^N0d>v+W@uz7G+NCGpo+@DaGUo1zf@=ZIZzao)D&(5CB=Est}Zsr^^N9 z%m#5%L4V+_>KgUFbe*lx!-eE?4;Rk+Z+hjv)Wl{Ja>^r=in0UIg?-Izt>;or6qZa% zE~sUxH|mPM7!?u%NCHa>)`naHJ$V#$%GMz<r&x2a2898b5jy4wtn?01#Ch*AI+A6z zKzDE?wrG^310sR+qzdZDM_-<1e1r?gA0m`i#3{ma(V@5?xil(m%UGeO@LKePWzTuk z)yjH9Xf>2D;cB8#U{2Q9m=wxwLZRCiG-tfmIiMymTv2&}E{*mng1Q9JSkMJ#BbejT zX2Q=DBcZu6QtymlQ7}SZ8swBM%I7kU!{CVfyw9q%V@$DB1TfmQyb9<?L<ze6|E2pz z>;v6W?1FA7c0sog`#`r4`@ohIyWm@hUGOc$K12{=7kmq?3%+l(E(n)e7mVLZRgiwW zal<>rE@{8@G&f=|me9I^iU+9|>#B4~zL2_Pf8b59kG~cFEp{~HWnkP$eHipo>SEAK zsf$4`q&^J#LF&VlmQojUUPxWcc_H;7f{?nL^Fr%l&Ua~Ev@XUx;9l!u$^-4SE=IgS zmst1ny+|EqKj4KI=5^V)Nd0VGwGLB=y|b=r$Ekj_4`K)S15twP_%Yej$z~Y!SEE}@ J%RgxIe*s>oO49%U literal 0 HcmV?d00001 diff --git a/src/components/stage-header/icon--large-stage.svg b/src/components/stage-header/icon--large-stage.svg new file mode 100644 index 0000000000000000000000000000000000000000..ed4361ca3ac88804e87a1531ea79c7fc53201721 GIT binary patch literal 1167 zcma)*O^=%}5QgvjE2i!xkuYFB!X|>ORHXEhm8x!g>5YN|ZipR$H%b3}#|Dz^Hiueh z{5|u|GdO*^99lT>t`|yXgt<NeE=yGjS!d+?w+($H(Cb20MXMywh*ach{gC#j8qT89 zO-2I$cp=bmQ8#*;odiFBQkRVQ;6q?O@-_$~fMI2ykw)v|%Ja_WvwIF*)zx0$`@V<n z$0MstE9Cy(LAG2jJ-bWR4}dNGKq-9Yl6Qqx-3ngzT$c?*iOXOX#ZeH<fx?@JKUKpI zq8QV4OLg%2;SQyvOD%NE*W042IlSls?W`!ZIPrPv4SPfAiudI@?|7kkg<y0uMt4)s zZcV3l{o1TxH>}hks*HR=#}uLTx>I`#S@LN{N6fgr6K!iMU^dN|cCRg-<|i&yRb4M2 zFkTkNjCAT%{=NK539Rz4J}9u@1{F3-YO|zMmXp(re2nsCve}HR%{9}~;c9CDQT$KP z&V(Eh5zt*B`<?0z8L`6_`OHEWON`BdXdKPod9|L81yV#f&&=^*n+%2puw~BG=Dr(6 zNy6eFHj4{4S%h(z#0+sJ4r6W{2f<^MfR7W{q8&_5-yOaAf!ol*=fI*k^cNxeTYwSr zgV>6F<t09fy5$7xX_Ve*S}q37H36%gg(d@Qa~4j*9Qr;+<lF=Ri;QBlu^Yq&!qndp zGX5UdI{l9>^l6-1YXF&e4078|65)+nWQ-XY{7Bc@_#YxPSI6J?v7}yo<8+<aL2BOo F`VZpxIBfs` literal 0 HcmV?d00001 diff --git a/src/components/stage-header/icon--small-stage.svg b/src/components/stage-header/icon--small-stage.svg new file mode 100644 index 0000000000000000000000000000000000000000..f73f5b242583675de267ad84dde99a7173a7e032 GIT binary patch literal 1173 zcma)*O^=%}5QgvjE2i#cSHfWP5jHExN{!lHwo=t?FTGK4z+GZT;7!th-?2?X8ttJL z8vHr)&NFuLc-;1|7sDvEDhUr60ikN$NY$3)$M;Y4p1^1-)l|J!q9jU_$JI?S?prv> z#&ji#+3rZ76SD2hX|$K(@IfC-!hk_+KXMs_6Tq-)EJ<g~?jec}heLQsLOrxm%ovN% z{j}xb*h}^D)<(WuE+e-}RyTmHct<IG7D^12(Zd5gzX(%zkmezW+cZn#_zoysMEs>Y zv6a=7ZdmJWH2O1?PA-i!y;wbOtG<V4Q?&warK)Np_u{UI{HhP$h_PO+2T>W(AR5z6 z@xvl=OQ&6%ab;)l=Vw}wO-a6@Yl>J#Gw2tGS&7q#PM~plBm3Ugz%JT89bS9fE%rj` zra2!#WTLKiB^mUq`gi)bmRM&$?-e+7UWLn(x;*Ke=gDnJ-e-CCG0!I6_MmNrKRjAU z6z>XVa(UPcl^QpC*p|d~dn9z5gji;50i;v!?#iq4ysMBS;`zb@22Y$#md7{<&UVeh zG|h9K#hIO4g!v-Ll04&xG!Hlrvn-D9(;OHM;0diaYkIYH_5*V_z(>K;EMbcT{Vl*s z`AJ;WzKI&2M%xR5HMLr2qK=G(GpFFyCoTtT*E~5X3+Q!_G?*0tPpxFMiG$$n8!D#z zaW2z;iL&0jXN=;*;BReX&g3qnB4M6*_(;-Lf}yT!B6O{Hf8NGYMD5J!JaC=DzWmi+ D4$?Xw literal 0 HcmV?d00001 diff --git a/src/components/stage-header/icon--unfullscreen.svg b/src/components/stage-header/icon--unfullscreen.svg new file mode 100644 index 0000000000000000000000000000000000000000..bf4a3e450de8aa70b034203d69824860d568f1c0 GIT binary patch literal 3006 zcmb7G+iv4F5PjdTVAYomAkiG&8Q5N+Mz=36P@wGxxUpgzaiqXj;(UG&WznM3EYcVY zEa#9j9L^k_$@JUn<DR|LhvTkoW(9Fku)4Wx*SlsjEB^lLd*usu>{iWswQrkxRy1w# zZT@9?eA%$mZryEXg%nS(1>4rU&9+O{%dS5C(!S0L!32}>Uy)xz1;e$?aaL@*?&)?i zIh{`Yq<DMSOr#KEg7CwU+t>ZBd3f(2g%BqFZZZGD@SFZrRqVIAsSm5JJ>0TCAL{OI z%e3djzG^3pxM3B`Zv3a+){nc@@LYb^K2DBjpQ;){cDrt0&!3y>{&~MY-W}??nNH5& z`ObBHyqhl$^{T7as7SXRuI1B7zm-niALkLle`jRFcI#R3$7)kosK&87v=4oCn>tz5 zP+x4{@Amsx`nVa_)!})M)AdW;wCnZo{JsR|uvhse_n(b3zdDnh9z43ksyW`bhsRmb zFZX!MSIN-_{7RNqH*Y+9@23@BjEDSAhAZVoP^IR|2xX+zY)P7H?Y-5yR9qYH6}kqP zxFYS9q0(@#l$K5tTae(vI8rW@mXq+(IN=#kt$c7^0~N|r@Mn~)_QoiLu+|x=NwG!X zK}(}OS-{GPAOd+7QD>~QgzSQqf~+(#a0;Qh^^#1G$W3yikdkpFaifJWWKEy4wZ?0! zOM(0FB%!@S&croY7mNX}$>SpHGy`mc3Qjt}h#{m?PR6{62c>bG-fS#UK}%8+k`#!G z!bq(HD)%OU1wg2@H!9!}(Nx|$uQY17gsr*o!k`BlVWO!eii4*z1T}c43>v5jMj#GS zdZ%?oPtWg>YvA9z3?X%)NLt;nL)%66Anvevb9U}IRb?*K=u_a!h&(!f8Ie}$H@(m+ z)|`T{!G{thv^q$T3D4!IBq<ZSg~n;&y|io@`-#4RdS%~b3mQnaFkEQq(f?2e?g622 zlA$P;1PTu@AhHV%SY)Tx2#fM6h>{0E!9U})Ay5&pMJRNeMO13#RG*qq4rf#zA+jBA z8Xp9{0^Hyw@<Lw>R$wjC1>wjjg9x!1qy!=?&?AqlwYCv9o&-71;3sV4lZt2vNLWgs z!WtY!Ycq5ix#7SKj}Mb9TYx$a)G$_4eojQggS`Q7?+r_YXM*^!Kv@a|+Q2_r#^FY= zD-zy$7i$t>d=W7(!0+`cW0d*<qY@=bb|K0~j2c}=a^0}cGU`gQMn>h5l`$%ptc+2a zWQ~l<6l<hZE?60*GQr9yl?m1uA=9gjQJGw2jJlGmj8eH=Wt_TJn~YZ18&}MNUggBP zJ}IvBDq5Lb2?)`sR?)hMRnD$Vt#WpaeaqNoK4e!S%_qn;y8It*;bR(x;gwe5al<go zwF*blFwC_I>og2Atpb{c;V4$U+j$mZc~Pru76MLcmCZujoYX20k;zp)43T}(tN5y6 z81_#c^a^mAg@BV@0ZpS2Xwoa7X%1%S66-Vsqg=sEQ!qOPrH&heT%E0pUPUt#th1RE t3vOuu#$*S<0{WkJWrT7+Ak;;qKA~5c&&Pr_oovRLcrp6LH2#S^{}-kdt)Kt^ literal 0 HcmV?d00001 diff --git a/src/components/stage-header/icon--unzoom.svg b/src/components/stage-header/icon--unzoom.svg deleted file mode 100644 index c929966dc735c3c1aeaadc4c10fdfa82306596f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2906 zcmd5;%Wm8@6y5tPSb38mCPh(iMRI`F2$DrNZQ26e(Gq7ywL}gm&W!D^@1-P4;}?)F zidL`z@jl3V?m4`g^3#3ap`*}4t7PQ`gnCHGS~acQR^D&lKI6<ogW<B_osy#Rr1Cyp zUz9&!jDFIB8_}RsYj)_Xyc=r17wFy2n0?{<r_+hFvymvh_1`0muP-jj;kdm(2*J5> zD4M$R=7jx0cVl2v`=S%QkY?}$68PR4Ua#S`J-t1OTJ^n>!<Z?D%d=qJY?jS!HK%Y4 z3i3SnDf1b_5P^pWY4|;UnhG_(mdYrlKKRx{zAvg6prL#CU&5V%4C<h3v4I8&B8Bm9 zzTNoFi79DJvmREselFX*XtLzJ81}ptgYSaJ{4<7w(a<)P2T0hsIJJ%0RbDu)cB0+x z%(6VT;`F1suRMw<3K{&3Ij+c}QMEm_^4eNSj1Tfrsh+qlxhjgK0!niBp%F*Xp@Y1W z>Lk5uV7Tms;SD$3vW<|f&snlD078JT;+LDxHrzgCT^D~SeK#+`VgvZCIzaVv&KTF! z1$4OQ=DO|qR#*x@fc{E<bu4?7U^5SUu^8rUwV0?{dVj9hrtVvt<o{~guKQ{a@sRK8 zgi7tEt?9&SEd9CqDXR3(z?Hs(K6a)Nn_())cEzredG~T*!BWszs;0m_R8Xr<>B_s@ zjL%3KLbpmcLOWM7KC^3~3K%`u>xZ>6aL4Rmpij~jC=BqzyqL}E_AgNzqdK9vtU(Kb zOW11A)@$}d+lbd3OBEKva**5ZiFerXMx82e5+rD59yi6QmEgd$tb?4rNS`B|)bq?C zu^nD|8O`v9ojO?{mAB#DAfETD7koHqfniQ+P+k;}B+0U?AR#PVH+IFjXdz)gdiA0- zdwl>CB`l4fpH#y&w4ON4((r}T5)zYuhAeuKIRm!W_<7#!f^3$(;p_Q*+qaJbDqb4p z@YDybtynt#AV6+gpng($InMbrTDDpp_PuIAA7k+I!#aK|y2_ib&nkGk<FqoMuEE~q z${Sxh`2M`3R{?v!ObC$S6pP@q_0Yjl8@Q3hWmM<sX7kZ5@T{sL_&6A??!+XN0tQo* z(lE`Oo~9|JVatf64mX1D-8e0w)nSz9(Hia46flxTVVtii(Dsb5B+gmrm_Y~{ju{DQ zo+Zp(Xc!fHZg&3|LLuSn{1i?AG6|C;J*yn(>k$h{7SNc6S2zHrQkn(<I--=ochNp* zhcZ}0X^c_m2dr^SKyU%gtsUOeoaIT59%ow4`V_{=YFreeq=Y6ajX^6%Zs4w18M;~c zFC+dL*{hVWG>@Yz9NN1XXGwy-AfRNlk8m>rA9r{ni+90(L=Jic3F}7a&lM(gb<_x8 z$1A(bFoLh*e~7+EVL;LZ*aouW928;kS;QH<EI5Bh0my=8EDiwYobndP{~g7>rIIBy twNp1IF-xP&Y8r6PU>Bgfg;4O%QcmAcGEP^Lze~%dzlGn%_UFa*#ot~xI<x=) diff --git a/src/components/stage-header/icon--zoom.svg b/src/components/stage-header/icon--zoom.svg deleted file mode 100644 index 62e008983d41b35d568610d17287c2854e2b7ca7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2902 zcmd5;O^@3)5WVlOV6~S7SyCkRtw;{g20?S^rA<+wH?2h5>Pn;`(f02C`V1*i@_wX9 zFKvZg!{p3x=FNLUx%hD3cjzRBu~oA47@-~#vQ|wiccu6HmrpqL(5NffRGpHd^rZ4W zY_5tQFh)NOqSB&4=T`60XL&c))j^;)d#w+-@1M_S($1Si4LkoW!gzCaRg9<I6+#H| z$}w;1(whSg$Dy;1P3?<L^g`;<XN39Q>RzwzwaMO|M6LQ>$<ap2@%qAfXtvAYrkZnL zomiG-KIJ~=7(DR!Aa!+*pN2w>uZ40-sSma_$@h8XBQ*2?|BJiZAfq}Cwb(*~1d&4f zAHRI`oe@*g=w?lpyM8XmylAqldNCfVT8zGPw(%DXGrQ3?r3Xm3U7XuS?@KS3R(sLz z_Ig>KT5<kS-IpFk6a^gqY>X>1Z&YovmR?&ciSeUSJ#js9HRMZvN;3Yg5hu~1qr8*q zEWHizTl7L#O{FWtHA1F3x06~2Z~?aRUq5~_?&c}#I{!lrck>c<j6-#+j!^p?WBr;s zhyM1J-n4zS6NbQdpuWOi4a*q??CFPtST^Qk2Qd+~bpBGUP2IO9$p1~ZUH91}@sRK8 zgi6h!t?tCe=A6Dd6#fijaxeS~l!fnlU|ZCP?Knl5_Lx;XrzsXP3=@rEY;rt6DYfd< zP<q!}`&jM}x>Z9X24{-xGn*F9fY_s%LOdu9qh{_0`XpR|&;U4G8}qih{Y%tZt4<7+ ztU(gY1?&cp*lYX8wh^xxmMRQ{C6PPsiFMppjXIa!q)QObeCy=rR)PV~>Sh^#5k7l3 z#b>EQVmiF^GMwR!dv!KIN^e_rqj=u0UR2|85E!n@0VEhQ631zJ!(zgN^<Y<=^A-}$ zqc<-~Gjjx(DB(%;JW~zRXe?2ZCcz7%AtWM<20VNbIRiG+{5)<pK{QXlVe6~=wr?K= zRJ=6G;i-?qV8qf@4+7-21L~(4DC~8ALCbDX$3w3g(1&$?o~)~GMOS*$9Ib*kCr&F3 z>Ke^Rm!AFF!E5LZy<z<Aa#er~Ctn0_uZIp&ZDBO?>#)v}?e@J{;8|5Udq3(y-HAyk zIU`|^MvQUSyy-d`;K-0C4mX0=p1m}AKmrzJ+=&DsrzVz>Ad0heJqOwz0-tHj;%vr( z5HuV|B<7TbkkZ{7#i7#se+(g)@REKGhetsiCl{3ieLV^oNg0i3aDxL9Q<^Y_P6(%H zZ$3_l6V7Qu16W4{bjD}~yYMy1c$T2YrG7IHwmATH-CSg$q=e3?0fRtJm4*Q^+WVJa z{(@5Icg&M4y}`^5WRxc8XJp38Y)2u0N(sEz;R(UONtgj=JT}d6z@w=N7CHY0biC5M zTtM(b{13tR2(+2Rz%VE=%0LAG!%#bsybx?zod^c}QwaKVrSgJb{J&$kH&pVNCg!GP pB;rY!8X+4UTdWIA(6!@p=JxNDjFYti-=*ck-@)%<^W$Q3^%W9DJ5T@s diff --git a/src/components/stage-header/stage-header.css b/src/components/stage-header/stage-header.css index c491b82e9..2c2c30bed 100644 --- a/src/components/stage-header/stage-header.css +++ b/src/components/stage-header/stage-header.css @@ -23,21 +23,48 @@ padding: $space; } -.stage-zoom-icon { - text-align: right; +.stage-size-row { + display: flex; +} + +.stage-size-toggle-group { + display: flex; + margin-right: .2rem; +} + +.stage-button { + display: block; + border: 1px solid $ui-pane-border; + border-radius: .25rem; box-sizing: content-box; width: 1.25rem; height: 1.25rem; padding: 0.375rem; - border-radius: 0.25rem; user-select: none; cursor: pointer; - transition: 0.2s ease-out; } -.stage-zoom-icon:hover { - /* Scale icon image by 1.2, but keep background static */ - width: 1.5rem; - height: 1.5rem; - padding: 0.25rem; +.stage-button-icon { + width: 100%; + height: 100%; +} + +.stage-button-right { + border-left: none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.stage-button-left { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.stage-button-active { + background: #FFF; +} + +.stage-button-disabled { + opacity: .5; + cursor: auto; } diff --git a/src/components/stage-header/stage-header.jsx b/src/components/stage-header/stage-header.jsx index 635d161ba..19f46e220 100644 --- a/src/components/stage-header/stage-header.jsx +++ b/src/components/stage-header/stage-header.jsx @@ -1,81 +1,157 @@ import classNames from 'classnames'; +import {defineMessages, injectIntl, intlShape} from 'react-intl'; import PropTypes from 'prop-types'; import React from 'react'; import VM from 'scratch-vm'; + import Box from '../box/box.jsx'; +import Button from '../button/button.jsx'; +import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx'; import Controls from '../../containers/controls.jsx'; -import zoomIcon from './icon--zoom.svg'; -import unzoomIcon from './icon--unzoom.svg'; +import {STAGE_SIZES} from '../../reducers/stage-size'; + +import fullScreenIcon from './icon--fullscreen.svg'; +import largeStageIcon from './icon--large-stage.svg'; +import smallStageIcon from './icon--small-stage.svg'; +import unFullScreenIcon from './icon--unfullscreen.svg'; + import styles from './stage-header.css'; +const messages = defineMessages({ + largeStageSizeMessage: { + defaultMessage: 'Stage Size Toggle - Large', + description: 'Button to change stage size to large', + id: 'gui.gui.stageSizeLarge' + }, + smallStageSizeMessage: { + defaultMessage: 'Stage Size Toggle - Small', + description: 'Button to change stage size to small', + id: 'gui.gui.stageSizeSmall' + }, + fullStageSizeMessage: { + defaultMessage: 'Stage Size Toggle - Full Screen', + description: 'Button to change stage size to full screen', + id: 'gui.gui.stageSizeFull' + }, + unFullStageSizeMessage: { + defaultMessage: 'Stage Size Toggle - Un-full screen', + description: 'Button to get out of full screen mode', + id: 'gui.gui.stageSizeUnFull' + } +}); + const StageHeaderComponent = function (props) { const { - className, - height, - isZoomed, - onUnzoom, - onZoom, - titleZoomIcon, - vm, - width, - ...componentProps + stageSize, + isFullScreen, + onSetStageLarge, + onSetStageFull, + onSetStageUnFull, + vm } = props; - return isZoomed === false ? ( - <Box className={styles.stageHeaderWrapper}> - <Box - className={styles.stageMenuWrapper} - height={height} - width={width} - > - <Controls vm={vm} /> - <img - className={classNames( - className, - styles.stageZoomIcon - )} - src={zoomIcon} - title={titleZoomIcon} - onClick={onZoom} - {...componentProps} - /> + + let header = null; + + if (isFullScreen) { + header = ( + <Box className={styles.stageHeaderWrapperOverlay}> + <Box className={styles.stageMenuWrapper}> + <Controls vm={vm} /> + <Button + className={classNames( + styles.stageButton, + styles.stageButtonActive + )} + onClick={onSetStageUnFull} + > + <img + alt={props.intl.formatMessage(messages.unFullStageSizeMessage)} + className={styles.stageButtonIcon} + src={unFullScreenIcon} + title="Full Screen Control" + /> + </Button> + </Box> </Box> - </Box> - ) : ( - <Box className={styles.stageHeaderWrapperOverlay}> - <Box - className={styles.stageMenuWrapper} - height={'100%'} - width={'100%'} - > - <Controls vm={vm} /> - <img - className={classNames( - className, - styles.stageZoomIcon - )} - src={unzoomIcon} - title={titleZoomIcon} - onClick={onUnzoom} - {...componentProps} - /> + ); + } else { + header = ( + <Box className={styles.stageHeaderWrapper}> + <Box className={styles.stageMenuWrapper}> + <Controls vm={vm} /> + <div className={styles.stageSizeRow}> + <div className={styles.stageSizeToggleGroup}> + <ComingSoonTooltip + place="left" + tooltipId="small-stage-button" + > + <div + disabled + className={classNames( + styles.stageButton, + styles.stageButtonLeft, + styles.stageButtonDisabled + )} + role="button" + > + <img + disabled + alt={props.intl.formatMessage(messages.smallStageSizeMessage)} + className={styles.stageButtonIcon} + src={smallStageIcon} + /> + </div> + </ComingSoonTooltip> + <div> + <Button + className={classNames( + styles.stageButton, + styles.stageButtonRight, + { + [styles.stageButtonActive]: stageSize === STAGE_SIZES.large + } + )} + onClick={onSetStageLarge} + > + <img + alt={props.intl.formatMessage(messages.largeStageSizeMessage)} + className={styles.stageButtonIcon} + src={largeStageIcon} + /> + </Button> + </div> + </div> + <div> + <Button + className={styles.stageButton} + onClick={onSetStageFull} + > + <img + alt={props.intl.formatMessage(messages.fullStageSizeMessage)} + className={styles.stageButtonIcon} + src={fullScreenIcon} + title="Full Screen Control" + /> + </Button> + </div> + </div> + </Box> </Box> - </Box> - ); + ); + } + + return header; }; + StageHeaderComponent.propTypes = { - className: PropTypes.string, - height: PropTypes.number, - isZoomed: PropTypes.bool.isRequired, - onUnzoom: PropTypes.func.isRequired, - onZoom: PropTypes.func.isRequired, - titleZoomIcon: PropTypes.string, - vm: PropTypes.instanceOf(VM).isRequired, - width: PropTypes.number + intl: intlShape, + isFullScreen: PropTypes.bool.isRequired, + onSetStageFull: PropTypes.func.isRequired, + onSetStageLarge: PropTypes.func.isRequired, + onSetStageUnFull: PropTypes.func.isRequired, + stageSize: PropTypes.oneOf(Object.keys(STAGE_SIZES)).isRequired, + vm: PropTypes.instanceOf(VM).isRequired }; -StageHeaderComponent.defaultProps = { - width: 480, - height: 360, - titleZoomIcon: 'Zoom Control' -}; -export default StageHeaderComponent; + +export default injectIntl(StageHeaderComponent); diff --git a/src/components/stage/stage.jsx b/src/components/stage/stage.jsx index 47981e04a..c8777a263 100644 --- a/src/components/stage/stage.jsx +++ b/src/components/stage/stage.jsx @@ -13,7 +13,7 @@ const StageComponent = props => { canvasRef, height, isColorPicking, - isZoomed, + isFullScreen, width, colorInfo, onDeactivateColorPicker, @@ -26,7 +26,7 @@ const StageComponent = props => { let widthCorrectedAspect = width; const spacingBorderAdjustment = 9; const stageMenuHeightAdjustment = 40; - if (isZoomed) { + if (isFullScreen) { heightCorrectedAspect = window.innerHeight - stageMenuHeightAdjustment - spacingBorderAdjustment; widthCorrectedAspect = heightCorrectedAspect + (heightCorrectedAspect / 3); if (widthCorrectedAspect > window.innerWidth) { @@ -38,15 +38,15 @@ const StageComponent = props => { <div> <Box className={classNames({ - [styles.stageWrapper]: !isZoomed, - [styles.stageWrapperOverlay]: isZoomed, - [styles.withColorPicker]: !isZoomed && isColorPicking + [styles.stageWrapper]: !isFullScreen, + [styles.stageWrapperOverlay]: isFullScreen, + [styles.withColorPicker]: !isFullScreen && isColorPicking })} > <Box className={classNames( styles.stage, - {[styles.stageOverlayContent]: isZoomed} + {[styles.stageOverlayContent]: isFullScreen} )} componentRef={canvasRef} element="canvas" @@ -95,7 +95,7 @@ StageComponent.propTypes = { colorInfo: Loupe.propTypes.colorInfo, height: PropTypes.number, isColorPicking: PropTypes.bool, - isZoomed: PropTypes.bool.isRequired, + isFullScreen: PropTypes.bool.isRequired, onDeactivateColorPicker: PropTypes.func, onQuestionAnswered: PropTypes.func, question: PropTypes.string, diff --git a/src/containers/save-button.jsx b/src/containers/save-button.jsx index 12585ab70..f2ae497de 100644 --- a/src/containers/save-button.jsx +++ b/src/containers/save-button.jsx @@ -4,6 +4,8 @@ import React from 'react'; import {connect} from 'react-redux'; import ButtonComponent from '../components/button/button.jsx'; +import {ComingSoonTooltip} from '../components/coming-soon/coming-soon.jsx'; + class SaveButton extends React.Component { constructor (props) { @@ -38,12 +40,18 @@ class SaveButton extends React.Component { ...props } = this.props; return ( - <ButtonComponent - onClick={this.handleClick} - {...props} + <ComingSoonTooltip + place="bottom" + tooltipId="save-button" > - Save - </ButtonComponent> + <ButtonComponent + disabled + onClick={this.handleClick} + {...props} + > + Save + </ButtonComponent> + </ComingSoonTooltip> ); } } diff --git a/src/containers/stage-header.jsx b/src/containers/stage-header.jsx index d3acba94e..593851a41 100644 --- a/src/containers/stage-header.jsx +++ b/src/containers/stage-header.jsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import VM from 'scratch-vm'; -import {setZoomed} from '../reducers/zoom'; +import {setStageSize, setFullScreen, STAGE_SIZES} from '../reducers/stage-size'; import {connect} from 'react-redux'; @@ -22,19 +22,20 @@ class StageHeader extends React.Component { } StageHeader.propTypes = { - height: PropTypes.number, - isZoomed: PropTypes.bool, - vm: PropTypes.instanceOf(VM).isRequired, - width: PropTypes.number + stageSize: PropTypes.oneOf(Object.keys(STAGE_SIZES)), + vm: PropTypes.instanceOf(VM).isRequired }; const mapStateToProps = state => ({ - isZoomed: state.isZoomed + stageSize: state.stageSize.stageSize, + isFullScreen: state.stageSize.isFullScreen }); const mapDispatchToProps = dispatch => ({ - onZoom: () => dispatch(setZoomed(true)), - onUnzoom: () => dispatch(setZoomed(false)) + onSetStageLarge: () => dispatch(setStageSize(STAGE_SIZES.large)), + onSetStageSmall: () => dispatch(setStageSize(STAGE_SIZES.small)), + onSetStageFull: () => dispatch(setFullScreen(true)), + onSetStageUnFull: () => dispatch(setFullScreen(false)) }); export default connect( diff --git a/src/containers/stage.jsx b/src/containers/stage.jsx index 9f76aa7ab..cb2a38963 100644 --- a/src/containers/stage.jsx +++ b/src/containers/stage.jsx @@ -57,7 +57,7 @@ class Stage extends React.Component { this.props.height !== nextProps.height || this.props.isColorPicking !== nextProps.isColorPicking || this.state.colorInfo !== nextState.colorInfo || - this.props.isZoomed !== nextProps.isZoomed || + this.props.isFullScreen !== nextProps.isFullScreen || this.state.question !== nextState.question; } componentDidUpdate (prevProps) { @@ -279,7 +279,7 @@ class Stage extends React.Component { Stage.propTypes = { height: PropTypes.number, isColorPicking: PropTypes.bool, - isZoomed: PropTypes.bool, + isFullScreen: PropTypes.bool.isRequired, onActivateColorPicker: PropTypes.func, onDeactivateColorPicker: PropTypes.func, vm: PropTypes.instanceOf(VM).isRequired, @@ -288,7 +288,7 @@ Stage.propTypes = { const mapStateToProps = state => ({ isColorPicking: state.colorPicker.active, - isZoomed: state.isZoomed + isFullScreen: state.stageSize.isFullScreen }); const mapDispatchToProps = dispatch => ({ diff --git a/src/css/colors.css b/src/css/colors.css index d524795cd..e270217f9 100644 --- a/src/css/colors.css +++ b/src/css/colors.css @@ -16,4 +16,6 @@ $sound-tertiary: #A63FA6; $control-primary: #FFAB19; +$data-primary: #FF8C1A; + $form-border: #E9EEF2; diff --git a/src/reducers/gui.js b/src/reducers/gui.js index 83ede0203..d49144b4f 100644 --- a/src/reducers/gui.js +++ b/src/reducers/gui.js @@ -8,14 +8,14 @@ import monitorLayoutReducer from './monitor-layout'; import targetReducer from './targets'; import toolboxReducer from './toolbox'; import vmReducer from './vm'; -import zoomReducer from './zoom'; +import stageSizeReducer from './stage-size'; import {ScratchPaintReducer} from 'scratch-paint'; export default combineReducers({ colorPicker: colorPickerReducer, customProcedures: customProceduresReducer, intl: intlReducer, - isZoomed: zoomReducer, + stageSize: stageSizeReducer, modals: modalReducer, monitors: monitorReducer, monitorLayout: monitorLayoutReducer, diff --git a/src/reducers/stage-size.js b/src/reducers/stage-size.js new file mode 100644 index 000000000..ea2750e34 --- /dev/null +++ b/src/reducers/stage-size.js @@ -0,0 +1,55 @@ +const SET_STAGE_SIZE = 'scratch-gui/StageSize/SET_STAGE_SIZE'; +const SET_FULL_SCREEN = 'scratch-gui/StageSize/SET_FULL_SCREEN'; + +const initialState = { + isFullScreen: false, + stageSize: 'large' +}; + +// stage size constants +const STAGE_SIZES = { + small: 'small', + large: 'large' +}; + +const reducer = function (state, action) { + if (typeof state === 'undefined') state = initialState; + switch (action.type) { + case SET_STAGE_SIZE: + return { + isFullScreen: state.isFullScreen, + stageSize: action.stageSize + }; + case SET_FULL_SCREEN: + return { + isFullScreen: action.isFullScreen, + stageSize: state.stageSize + }; + default: + return state; + } +}; + +const setStageSize = function (stageSize) { + return { + type: SET_STAGE_SIZE, + stageSize: stageSize + }; +}; + +// `isFullScreen` is a separate value because "stage size" does not +// actually apply to full screen mode, so they are treated as separate +// values to be assessed. +const setFullScreen = function (isFullScreen) { + return { + type: SET_FULL_SCREEN, + isFullScreen: isFullScreen + }; +}; + +export { + reducer as default, + setStageSize, + setFullScreen, + STAGE_SIZES +}; diff --git a/src/reducers/zoom.js b/src/reducers/zoom.js deleted file mode 100644 index 3cd0f5f7f..000000000 --- a/src/reducers/zoom.js +++ /dev/null @@ -1,23 +0,0 @@ -const SET_ZOOMED = 'scratch-gui/Zoomed/SET_ZOOMED'; -const defaultZoomed = false; -const initialState = defaultZoomed; - -const reducer = function (state, action) { - if (typeof state === 'undefined') state = initialState; - switch (action.type) { - case SET_ZOOMED: - return action.isZoomed; - default: - return state; - } -}; -const setZoomed = function (isZoomed) { - return { - type: SET_ZOOMED, - isZoomed: isZoomed - }; -}; -export { - reducer as default, - setZoomed -}; diff --git a/test/integration/test.js b/test/integration/test.js index 58b488ecd..8668fce2a 100644 --- a/test/integration/test.js +++ b/test/integration/test.js @@ -143,7 +143,7 @@ describe('costumes, sounds and variables', () => { const projectId = '96708228'; await loadUri(`${uri}#${projectId}`); await new Promise(resolve => setTimeout(resolve, 2000)); - await clickXpath('//img[@title="Zoom Control"]'); + await clickXpath('//img[@title="Full Screen Control"]'); await clickXpath('//img[@title="Go"]'); await new Promise(resolve => setTimeout(resolve, 2000)); await clickXpath('//img[@title="Stop"]'); @@ -235,7 +235,9 @@ describe('costumes, sounds and variables', () => { await expect(logs).toEqual([]); }); - test('Localization', async () => { + // Skipped temporarily while the language selector is marked as + // "Coming Soon" + test.skip('Localization', async () => { await loadUri(uri); await clickText('Blocks'); await clickText('Extensions'); -- GitLab