mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-30 10:58:23 -05:00
fixed height of studio buttons scrolling container to fill all modal
This commit is contained in:
commit
7c8fdbfcc3
15 changed files with 184 additions and 97 deletions
|
@ -100,7 +100,7 @@
|
||||||
"redux-thunk": "2.0.1",
|
"redux-thunk": "2.0.1",
|
||||||
"sass-lint": "1.5.1",
|
"sass-lint": "1.5.1",
|
||||||
"sass-loader": "6.0.6",
|
"sass-loader": "6.0.6",
|
||||||
"scratch-gui": "latest",
|
"scratch-gui": "develop",
|
||||||
"scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master",
|
"scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master",
|
||||||
"slick-carousel": "1.6.0",
|
"slick-carousel": "1.6.0",
|
||||||
"source-map-support": "0.3.2",
|
"source-map-support": "0.3.2",
|
||||||
|
|
|
@ -28,6 +28,7 @@ $ui-coral-dark: hsla(350, 100, 60, 1); // #FF3355 More Blocks tertiary
|
||||||
$ui-white: hsla(0, 100%, 100%, 1); //#FFF
|
$ui-white: hsla(0, 100%, 100%, 1); //#FFF
|
||||||
$ui-white-15percent: hsla(0, 100%, 100%, .15); //#FFF
|
$ui-white-15percent: hsla(0, 100%, 100%, .15); //#FFF
|
||||||
$ui-light-primary: hsl(215, 100, 95);
|
$ui-light-primary: hsl(215, 100, 95);
|
||||||
|
$ui-light-primary-transparent: hsla(215, 100, 95, 0);
|
||||||
|
|
||||||
$ui-border: hsla(0, 0, 85, 1); //#D9D9D9
|
$ui-border: hsla(0, 0, 85, 1); //#D9D9D9
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,19 @@ $medium-height: "only screen and (min-height : #{$mobile} + 1) and (max-height :
|
||||||
.studio-list-outer-scrollbox {
|
.studio-list-outer-scrollbox {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: $ui-blue-10percent;
|
background-color: $ui-blue-10percent;
|
||||||
|
flex: 1;
|
||||||
|
max-height: calc(100% - 8rem);
|
||||||
|
min-height: 15rem;
|
||||||
|
|
||||||
|
@media #{$small-height} {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.studio-list-inner-scrollbox {
|
.studio-list-inner-scrollbox {
|
||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
padding-right: .5rem;
|
padding-right: .5rem;
|
||||||
height: 16.9375rem;
|
height: 100%;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
|
|
@ -37,13 +37,12 @@ const AddToStudioModalPresentation = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
standardSizes
|
useStandardSizes
|
||||||
className="mod-addToStudio"
|
className="mod-addToStudio"
|
||||||
contentLabel={contentLabel}
|
contentLabel={contentLabel}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onRequestClose={onRequestClose}
|
onRequestClose={onRequestClose}
|
||||||
>
|
>
|
||||||
<div>
|
|
||||||
<div className="addToStudio-modal-header modal-header">
|
<div className="addToStudio-modal-header modal-header">
|
||||||
<div className="addToStudio-content-label content-label">
|
<div className="addToStudio-content-label content-label">
|
||||||
{contentLabel}
|
{contentLabel}
|
||||||
|
@ -102,7 +101,6 @@ const AddToStudioModalPresentation = ({
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Modal extends React.Component {
|
||||||
appElement={document.getElementById('app')}
|
appElement={document.getElementById('app')}
|
||||||
className={{
|
className={{
|
||||||
base: classNames('modal-content', this.props.className, {
|
base: classNames('modal-content', this.props.className, {
|
||||||
'modal-sizes': this.props.standardSizes
|
'modal-sizes': this.props.useStandardSizes
|
||||||
}),
|
}),
|
||||||
afterOpen: classNames('modal-content', this.props.className),
|
afterOpen: classNames('modal-content', this.props.className),
|
||||||
beforeClose: classNames('modal-content', this.props.className)
|
beforeClose: classNames('modal-content', this.props.className)
|
||||||
|
@ -63,7 +63,7 @@ Modal.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
overlayClassName: PropTypes.string,
|
overlayClassName: PropTypes.string,
|
||||||
standardSizes: PropTypes.bool
|
useStandardSizes: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Modal;
|
module.exports = Modal;
|
||||||
|
|
|
@ -111,7 +111,7 @@ class ReportModal extends React.Component {
|
||||||
const contentLabel = intl.formatMessage({id: `report.${type}`});
|
const contentLabel = intl.formatMessage({id: `report.${type}`});
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
standardSizes
|
useStandardSizes
|
||||||
className="mod-report"
|
className="mod-report"
|
||||||
contentLabel={contentLabel}
|
contentLabel={contentLabel}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
|
|
|
@ -444,18 +444,20 @@ class DemographicsStep extends React.Component {
|
||||||
handleChooseGender (name, gender) {
|
handleChooseGender (name, gender) {
|
||||||
this.setState({otherDisabled: gender !== 'other'});
|
this.setState({otherDisabled: gender !== 'other'});
|
||||||
}
|
}
|
||||||
handleValidSubmit (formData, reset, invalidate) {
|
handleValidSubmit (formData) {
|
||||||
|
return this.props.onNextStep(formData);
|
||||||
|
}
|
||||||
|
isValidBirthdate (year, month) {
|
||||||
const birthdate = new Date(
|
const birthdate = new Date(
|
||||||
formData.user.birth.year,
|
year,
|
||||||
formData.user.birth.month - 1,
|
month - 1,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
if (((Date.now() - birthdate) / (24 * 3600 * 1000 * 365.25)) < this.props.birthOffset) {
|
return (((Date.now() - birthdate) / (24 * 3600 * 1000 * 365.25)) >= this.props.birthOffset);
|
||||||
return invalidate({
|
|
||||||
'user.birth.year': this.props.intl.formatMessage({id: 'teacherRegistration.validationAge'})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return this.props.onNextStep(formData);
|
birthDateValidator (values) {
|
||||||
|
const isValid = this.isValidBirthdate(values['user.birth.year'], values['user.birth.month']);
|
||||||
|
return isValid ? true : this.props.intl.formatMessage({id: 'teacherRegistration.validationAge'});
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
const countryOptions = getCountryOptions(this.props.intl, DEFAULT_COUNTRY);
|
const countryOptions = getCountryOptions(this.props.intl, DEFAULT_COUNTRY);
|
||||||
|
@ -485,6 +487,9 @@ class DemographicsStep extends React.Component {
|
||||||
}
|
}
|
||||||
name="user.birth.month"
|
name="user.birth.month"
|
||||||
options={this.getMonthOptions()}
|
options={this.getMonthOptions()}
|
||||||
|
validations={{
|
||||||
|
birthDateVal: values => this.birthDateValidator(values)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
required
|
required
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
float: left;
|
float: left;
|
||||||
max-width: 164px;
|
max-width: 164px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
.thumbnail-creator a {
|
.thumbnail-creator a {
|
||||||
color: $type-gray;
|
color: $type-gray;
|
||||||
|
|
|
@ -35,14 +35,6 @@ const Jobs = () => (
|
||||||
MIT Media Lab, Cambridge, MA
|
MIT Media Lab, Cambridge, MA
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href="https://scratch.mit.edu/jobs/moderator">
|
|
||||||
Community Moderator
|
|
||||||
</a>
|
|
||||||
<span>
|
|
||||||
Remote
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -172,7 +172,7 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
transparent,
|
$ui-light-primary-transparent,
|
||||||
$ui-light-primary
|
$ui-light-primary
|
||||||
);
|
);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -211,4 +211,3 @@
|
||||||
margin-right: -50%;
|
margin-right: -50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
font-size: .875rem;
|
font-size: .875rem;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extension-status {
|
.extension-status {
|
||||||
|
|
|
@ -2,6 +2,7 @@ const FormattedDate = require('react-intl').FormattedDate;
|
||||||
const injectIntl = require('react-intl').injectIntl;
|
const injectIntl = require('react-intl').injectIntl;
|
||||||
const PropTypes = require('prop-types');
|
const PropTypes = require('prop-types');
|
||||||
const intlShape = require('react-intl').intlShape;
|
const intlShape = require('react-intl').intlShape;
|
||||||
|
const MediaQuery = require('react-responsive').default;
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const Formsy = require('formsy-react').default;
|
const Formsy = require('formsy-react').default;
|
||||||
const classNames = require('classnames');
|
const classNames = require('classnames');
|
||||||
|
@ -28,6 +29,8 @@ const ExtensionChip = require('./extension-chip.jsx');
|
||||||
const projectShape = require('./projectshape.jsx').projectShape;
|
const projectShape = require('./projectshape.jsx').projectShape;
|
||||||
require('./preview.scss');
|
require('./preview.scss');
|
||||||
|
|
||||||
|
const frameless = require('../../lib/frameless');
|
||||||
|
|
||||||
// disable enter key submission on formsy input fields; otherwise formsy thinks
|
// disable enter key submission on formsy input fields; otherwise formsy thinks
|
||||||
// we meant to trigger the "See inside" button. Instead, treat these keypresses
|
// we meant to trigger the "See inside" button. Instead, treat these keypresses
|
||||||
// as a blur, which will trigger a save.
|
// as a blur, which will trigger a save.
|
||||||
|
@ -155,6 +158,21 @@ const PreviewPresentation = ({
|
||||||
<RemixCredit projectInfo={parentInfo} />
|
<RemixCredit projectInfo={parentInfo} />
|
||||||
<RemixCredit projectInfo={originalInfo} />
|
<RemixCredit projectInfo={originalInfo} />
|
||||||
{/* eslint-disable max-len */}
|
{/* eslint-disable max-len */}
|
||||||
|
<MediaQuery maxWidth={frameless.tablet - 1}>
|
||||||
|
<FlexRow className="preview-row">
|
||||||
|
<FlexRow className="extension-list">
|
||||||
|
{extensions && extensions.map(extension => (
|
||||||
|
<ExtensionChip
|
||||||
|
extensionL10n={extension.l10nId}
|
||||||
|
extensionName={extension.name}
|
||||||
|
hasStatus={extension.hasStatus}
|
||||||
|
iconURI={extension.icon && `/svgs/project/${extension.icon}`}
|
||||||
|
key={extension.name || extension.l10nId}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</FlexRow>
|
||||||
|
</FlexRow>
|
||||||
|
</MediaQuery>
|
||||||
<FlexRow className="description-block">
|
<FlexRow className="description-block">
|
||||||
<div className="project-textlabel">
|
<div className="project-textlabel">
|
||||||
Instructions
|
Instructions
|
||||||
|
@ -309,6 +327,7 @@ const PreviewPresentation = ({
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
|
<MediaQuery minWidth={frameless.tablet}>
|
||||||
<FlexRow className="preview-row">
|
<FlexRow className="preview-row">
|
||||||
<FlexRow className="extension-list">
|
<FlexRow className="extension-list">
|
||||||
{extensions && extensions.map(extension => (
|
{extensions && extensions.map(extension => (
|
||||||
|
@ -322,6 +341,7 @@ const PreviewPresentation = ({
|
||||||
))}
|
))}
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
|
</MediaQuery>
|
||||||
</div>
|
</div>
|
||||||
<div className="project-lower-container">
|
<div className="project-lower-container">
|
||||||
<div className="inner">
|
<div className="inner">
|
||||||
|
|
|
@ -246,6 +246,9 @@ class Preview extends React.Component {
|
||||||
handleSeeInside () {
|
handleSeeInside () {
|
||||||
this.props.setPlayer(false);
|
this.props.setPlayer(false);
|
||||||
}
|
}
|
||||||
|
handleShare () {
|
||||||
|
// This is just a placeholder, but enables the button in the editor
|
||||||
|
}
|
||||||
handleUpdate (jsonData) {
|
handleUpdate (jsonData) {
|
||||||
this.props.updateProject(
|
this.props.updateProject(
|
||||||
this.props.projectInfo.id,
|
this.props.projectInfo.id,
|
||||||
|
@ -338,6 +341,7 @@ class Preview extends React.Component {
|
||||||
renderLogin={this.renderLogin}
|
renderLogin={this.renderLogin}
|
||||||
onLogOut={this.props.handleLogOut}
|
onLogOut={this.props.handleLogOut}
|
||||||
onOpenRegistration={this.props.handleOpenRegistration}
|
onOpenRegistration={this.props.handleOpenRegistration}
|
||||||
|
onShare={this.handleShare}
|
||||||
onToggleLoginOpen={this.props.handleToggleLoginOpen}
|
onToggleLoginOpen={this.props.handleToggleLoginOpen}
|
||||||
onUpdateProjectTitle={this.handleUpdateProjectTitle}
|
onUpdateProjectTitle={this.handleUpdateProjectTitle}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -11,7 +11,6 @@ $small: "screen and (max-width : #{$mobile}-1)";
|
||||||
$medium: "screen and (min-width : #{$mobile}) and (max-width : #{$tablet}-1)";
|
$medium: "screen and (min-width : #{$mobile}) and (max-width : #{$tablet}-1)";
|
||||||
$big: "screen and (min-width : #{$tablet})";
|
$big: "screen and (min-width : #{$tablet})";
|
||||||
$medium-and-small: "screen and (max-width : #{$tablet}-1)";
|
$medium-and-small: "screen and (max-width : #{$tablet}-1)";
|
||||||
$little-height: "screen and (max-height : 460px)";
|
|
||||||
|
|
||||||
/* override view padding for share banner */
|
/* override view padding for share banner */
|
||||||
#view {
|
#view {
|
||||||
|
@ -154,7 +153,23 @@ $little-height: "screen and (max-height : 460px)";
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments-container {
|
.comments-container {
|
||||||
width: 65%;
|
padding-right: 1.5rem;
|
||||||
|
min-width: 65%;
|
||||||
|
max-width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
@media #{$medium-and-small} {
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment, .comment-top-row, .comment-bottom-row {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-bubble {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.remix-button,
|
.remix-button,
|
||||||
|
@ -201,6 +216,14 @@ $little-height: "screen and (max-height : 460px)";
|
||||||
.guiPlayer {
|
.guiPlayer {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: $player-width;
|
width: $player-width;
|
||||||
|
|
||||||
|
@media #{$small} {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.stage-wrapper {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-notes {
|
.project-notes {
|
||||||
|
@ -210,6 +233,12 @@ $little-height: "screen and (max-height : 460px)";
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
|
|
||||||
|
@media #{$medium-and-small} {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
> .description-block:first-child {
|
> .description-block:first-child {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -516,6 +545,12 @@ $little-height: "screen and (max-height : 460px)";
|
||||||
|
|
||||||
.extension-list {
|
.extension-list {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
@media #{$medium-and-small} {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.remix-list,
|
.remix-list,
|
||||||
|
@ -537,6 +572,21 @@ $little-height: "screen and (max-height : 460px)";
|
||||||
.thumbnail-column {
|
.thumbnail-column {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
/* TODO: the following can be transferred to
|
||||||
|
src/components/thumbnailcolumn/thumbnailcolumn.scss
|
||||||
|
after testing */
|
||||||
|
@media #{$medium-and-small} {
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media #{$medium-and-small} {
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,12 +57,21 @@ class Search extends React.Component {
|
||||||
|
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const query = window.location.search;
|
const query = decodeURIComponent(window.location.search);
|
||||||
const q = query.lastIndexOf('q=');
|
let term = query;
|
||||||
let term = '';
|
|
||||||
if (q !== -1) {
|
const stripQueryValue = function (queryTerm) {
|
||||||
term = query.substring(q + 2, query.length).toLowerCase();
|
const queryIndex = query.indexOf('q=');
|
||||||
|
if (queryIndex !== -1) {
|
||||||
|
queryTerm = query.substring(queryIndex + 2, query.length).toLowerCase();
|
||||||
}
|
}
|
||||||
|
return queryTerm;
|
||||||
|
};
|
||||||
|
// Strip off the initial "?q="
|
||||||
|
term = stripQueryValue(term);
|
||||||
|
// Strip off user entered "?q="
|
||||||
|
term = stripQueryValue(term);
|
||||||
|
|
||||||
while (term.indexOf('/') > -1) {
|
while (term.indexOf('/') > -1) {
|
||||||
term = term.substring(0, term.indexOf('/'));
|
term = term.substring(0, term.indexOf('/'));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue