mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-27 01:25:52 -05:00
explore redesign
This commit is contained in:
parent
017df9da20
commit
4d0efd1268
2 changed files with 203 additions and 87 deletions
|
@ -9,6 +9,9 @@ var api = require('../../lib/api');
|
||||||
var Page = require('../../components/page/www/page.jsx');
|
var Page = require('../../components/page/www/page.jsx');
|
||||||
var Tabs = require('../../components/tabs/tabs.jsx');
|
var Tabs = require('../../components/tabs/tabs.jsx');
|
||||||
var TitleBanner = require('../../components/title-banner/title-banner.jsx');
|
var TitleBanner = require('../../components/title-banner/title-banner.jsx');
|
||||||
|
var Button = require('../../components/forms/button.jsx');
|
||||||
|
var Form = require('../../components/forms/form.jsx');
|
||||||
|
var Select = require('../../components/forms/select.jsx');
|
||||||
var SubNavigation = require('../../components/subnavigation/subnavigation.jsx');
|
var SubNavigation = require('../../components/subnavigation/subnavigation.jsx');
|
||||||
var Grid = require('../../components/grid/grid.jsx');
|
var Grid = require('../../components/grid/grid.jsx');
|
||||||
|
|
||||||
|
@ -27,16 +30,19 @@ var Explore = injectIntl(React.createClass({
|
||||||
stories: 'stories'
|
stories: 'stories'
|
||||||
};
|
};
|
||||||
var typeOptions = ['projects','studios'];
|
var typeOptions = ['projects','studios'];
|
||||||
|
var modeOptions = ['trending', 'popular', 'recent', ''];
|
||||||
|
|
||||||
var pathname = window.location.pathname.toLowerCase();
|
var pathname = window.location.pathname.toLowerCase();
|
||||||
if (pathname[pathname.length - 1] === '/') {
|
if (pathname[pathname.length - 1] === '/') {
|
||||||
pathname = pathname.substring(0, pathname.length - 1);
|
pathname = pathname.substring(0, pathname.length - 1);
|
||||||
}
|
}
|
||||||
var slash = pathname.lastIndexOf('/');
|
var options = pathname.split('/');
|
||||||
var currentCategory = pathname.substring(slash + 1,pathname.length);
|
var type = options[2];
|
||||||
var typeStart = pathname.indexOf('explore/');
|
var currentCategory = options[3];
|
||||||
var type = pathname.substring(typeStart + 8,slash);
|
var currentMode = options.length > 4 ? options[4] : '';
|
||||||
if (Object.keys(categoryOptions).indexOf(currentCategory) === -1 || typeOptions.indexOf(type) === -1) {
|
if (Object.keys(categoryOptions).indexOf(currentCategory) === -1 ||
|
||||||
|
typeOptions.indexOf(type) === -1 ||
|
||||||
|
modeOptions.indexOf(currentMode) === -1){
|
||||||
window.location = window.location.origin + '/explore/projects/all/';
|
window.location = window.location.origin + '/explore/projects/all/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +50,9 @@ var Explore = injectIntl(React.createClass({
|
||||||
category: currentCategory,
|
category: currentCategory,
|
||||||
acceptableTabs: categoryOptions,
|
acceptableTabs: categoryOptions,
|
||||||
acceptableTypes: typeOptions,
|
acceptableTypes: typeOptions,
|
||||||
|
acceptableModes: modeOptions,
|
||||||
itemType: type,
|
itemType: type,
|
||||||
|
mode: currentMode,
|
||||||
loadNumber: 16
|
loadNumber: 16
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -65,6 +73,7 @@ var Explore = injectIntl(React.createClass({
|
||||||
'?limit=' + this.props.loadNumber +
|
'?limit=' + this.props.loadNumber +
|
||||||
'&offset=' + this.state.offset +
|
'&offset=' + this.state.offset +
|
||||||
'&language=' + this.props.intl.locale +
|
'&language=' + this.props.intl.locale +
|
||||||
|
'&mode=' + (this.props.mode ? this.props.mode : 'trending') +
|
||||||
qText
|
qText
|
||||||
}, function (err, body) {
|
}, function (err, body) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
@ -84,14 +93,20 @@ var Explore = injectIntl(React.createClass({
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.location = window.location.origin + '/explore/' + newType + '/' + this.props.tab;
|
window.location = window.location.origin + '/explore/' + newType + '/' + this.props.tab + '/' + this.props.mode;
|
||||||
|
},
|
||||||
|
changeSortMode: function (name, value) {
|
||||||
|
if (this.props.acceptableModes.indexOf(value) !== -1) {
|
||||||
|
window.location = window.location.origin + '/explore/' +
|
||||||
|
this.props.itemType + '/' + this.props.category + '/' + value;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getBubble: function (type) {
|
getBubble: function (type) {
|
||||||
var classes = classNames({
|
var classes = classNames({
|
||||||
active: (this.props.category === type)
|
active: (this.props.category === type)
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<a href={'/explore/' + this.props.itemType + '/' + type + '/'}>
|
<a href={'/explore/' + this.props.itemType + '/' + type + '/' + this.props.mode}>
|
||||||
<li className={classes}>
|
<li className={classes}>
|
||||||
<FormattedMessage id={'general.' + type} />
|
<FormattedMessage id={'general.' + type} />
|
||||||
</li>
|
</li>
|
||||||
|
@ -100,15 +115,16 @@ var Explore = injectIntl(React.createClass({
|
||||||
},
|
},
|
||||||
getTab: function (type) {
|
getTab: function (type) {
|
||||||
var classes = classNames({
|
var classes = classNames({
|
||||||
active: (this.props.itemType === type)
|
active: (this.props.itemType === type),
|
||||||
|
inactive: (this.props.itemType !== type)
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<a href={'/explore/' + type + '/' + this.props.category + '/'}>
|
<a href={'/explore/' + type + '/' + this.props.category + '/' + this.props.mode}>
|
||||||
<li className={classes}>
|
<li className={classes}>
|
||||||
{this.props.itemType === type ? [
|
{this.props.itemType === type ? [
|
||||||
<img src={'/svgs/explore/' + type + '-active.svg'} className={'tab-icon ' + type} />
|
<img src={'/svgs/tabs/' + type + '-active.svg'} className={'tab-icon ' + type} />
|
||||||
] : [
|
] : [
|
||||||
<img src={'/svgs/explore/' + type + '-inactive.svg'} className={'tab-icon ' + type} />
|
<img src={'/svgs/tabs/' + type + '-inactive.svg'} className={'tab-icon ' + type} />
|
||||||
]}
|
]}
|
||||||
<FormattedMessage id={'general.' + type} />
|
<FormattedMessage id={'general.' + type} />
|
||||||
</li>
|
</li>
|
||||||
|
@ -130,29 +146,37 @@ var Explore = injectIntl(React.createClass({
|
||||||
{this.getTab('projects')}
|
{this.getTab('projects')}
|
||||||
{this.getTab('studios')}
|
{this.getTab('studios')}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<SubNavigation className='categories'>
|
<div className="sort-controls">
|
||||||
{this.getBubble('all')}
|
<SubNavigation className='categories'>
|
||||||
{this.getBubble('animations')}
|
{this.getBubble('all')}
|
||||||
{this.getBubble('art')}
|
{this.getBubble('animations')}
|
||||||
{this.getBubble('games')}
|
{this.getBubble('art')}
|
||||||
{this.getBubble('music')}
|
{this.getBubble('games')}
|
||||||
{this.getBubble('stories')}
|
{this.getBubble('music')}
|
||||||
</SubNavigation>
|
{this.getBubble('stories')}
|
||||||
|
</SubNavigation>
|
||||||
|
<Form className='sort-mode'>
|
||||||
|
<Select name="sort"
|
||||||
|
options={[
|
||||||
|
{value: 'trending', label: 'Trending'},
|
||||||
|
{value: 'popular', label: 'Popular'},
|
||||||
|
{value: 'recent', label: 'Recent'}
|
||||||
|
]}
|
||||||
|
value={this.props.mode}
|
||||||
|
onChange={this.changeSortMode}/>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
<div id='projectBox' key='projectBox'>
|
<div id='projectBox' key='projectBox'>
|
||||||
<Grid items={this.state.loaded}
|
<Grid items={this.state.loaded}
|
||||||
itemType={this.props.itemType}
|
itemType={this.props.itemType}
|
||||||
explore={true}
|
cards={true}
|
||||||
showLoves={false}
|
showLoves={false}
|
||||||
showFavorites={false}
|
showFavorites={false}
|
||||||
showViews={false}
|
showViews={false}
|
||||||
showAvatar={true}/>
|
showAvatar={true}/>
|
||||||
<SubNavigation className='load'>
|
<Button onClick={this.getExploreMore} className="white">
|
||||||
<button onClick={this.getExploreMore}>
|
<FormattedMessage id='general.loadMore' />
|
||||||
<li>
|
</Button>
|
||||||
<FormattedMessage id='general.loadMore' />
|
|
||||||
</li>
|
|
||||||
</button>
|
|
||||||
</SubNavigation>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -35,111 +35,103 @@ $base-bg: $ui-white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.box {
|
.left-pusher {
|
||||||
display: block;
|
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-bottom: 20px;
|
width: 8.75rem;
|
||||||
margin-left: auto;
|
|
||||||
|
|
||||||
.box-content {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-background {
|
.tab-background {
|
||||||
box-shadow: 1px 0 1px $box-shadow-gray;
|
box-shadow: 0 0 1px $box-shadow-gray;
|
||||||
background-color: $ui-white;
|
background-color: $ui-white;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
background-color: $ui-white;
|
width: 58.75rem;
|
||||||
padding: 0;
|
}
|
||||||
width: 100%;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
li {
|
/* HACK: sort controls are terrible. There's some sort of magic formula for height of formsy components that I can't control. */
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
width: $cols2;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&.active {
|
.sort-controls {
|
||||||
border-bottom: 3px solid $ui-aqua;
|
display: flex;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-bottom: 1px solid $ui-border;
|
||||||
|
padding: 8px 0;
|
||||||
|
width: 58.75rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-mode {
|
||||||
|
margin-top: -4px;
|
||||||
|
width: 13.75rem;
|
||||||
|
|
||||||
|
.select {
|
||||||
|
|
||||||
|
select {
|
||||||
|
margin-bottom: 0;
|
||||||
|
border: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
height: 32px;
|
||||||
|
color: $header-gray;
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:active {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
.help-block {
|
||||||
box-shadow: none;
|
display: none;
|
||||||
padding: .75em 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-icon {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
|
|
||||||
&.projects {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.studios {
|
|
||||||
width: 24px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.categories {
|
.categories {
|
||||||
border-bottom: 1px solid $ui-border;
|
justify-content: flex-start;
|
||||||
padding: 8px 0;
|
|
||||||
width: 58.75rem;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
li {
|
li {
|
||||||
border: 0;
|
border: 0;
|
||||||
background-color: $ui-dark-gray;
|
background-color: $active-gray;
|
||||||
color: $ui-light-gray;
|
color: $ui-white;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
background-color: $ui-aqua;
|
background-color: $ui-aqua;
|
||||||
color: $ui-white;
|
color: $ui-white;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
padding: .75em 1.5em;
|
padding: .75em 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $active-dark-gray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#projectBox {
|
#projectBox {
|
||||||
background-color: $ui-gray;
|
background-color: $ui-gray;
|
||||||
padding-top: 8px;
|
padding-top: 16px;
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.grid .flex-row {
|
.grid .flex-row {
|
||||||
width: $cols12;
|
width: $cols12;
|
||||||
justify-content: space-around;
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.load button {
|
|
||||||
outline: None;
|
|
||||||
border: None;
|
|
||||||
background-color: $ui-gray;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: $header-gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.thumbnail {
|
.thumbnail {
|
||||||
$project-width: 220px;
|
$project-width: 220px;
|
||||||
$project-height: 208px;
|
$project-height: 208px;
|
||||||
margin-left: 8px;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
&.project {
|
&.project {
|
||||||
|
@ -158,11 +150,111 @@ $base-bg: $ui-white;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.thumbnail-title,
|
&.gallery {
|
||||||
.thumbnail-creator {
|
margin-bottom: 16px;
|
||||||
margin: 0 auto;
|
border-radius: 4px;
|
||||||
|
width: $project-width;
|
||||||
|
height: $project-height;
|
||||||
|
|
||||||
|
.thumbnail-image {
|
||||||
|
margin: 8px auto;
|
||||||
width: 204px;
|
width: 204px;
|
||||||
|
height: 120px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail-info {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 204px;
|
||||||
|
|
||||||
|
.creator-image {
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-right: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail-title {
|
||||||
|
float: left;
|
||||||
|
max-width: 164px;
|
||||||
|
|
||||||
|
.thumbnail-creator a {
|
||||||
|
color: $type-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//4 columns
|
||||||
|
@media only screen and (max-width: $mobile - 1) {
|
||||||
|
.outer {
|
||||||
|
.tabs {
|
||||||
|
width: $cols4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-controls {
|
||||||
|
width: $cols4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectBox {
|
||||||
|
.grid {
|
||||||
|
.flex-row {
|
||||||
|
width: $cols4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//6 columns
|
||||||
|
@media only screen and (min-width: $mobile) and (max-width: $tablet - 1) {
|
||||||
|
.outer {
|
||||||
|
.tabs {
|
||||||
|
width: $cols6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-controls {
|
||||||
|
width: $cols6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectBox {
|
||||||
|
.grid {
|
||||||
|
.flex-row {
|
||||||
|
width: $cols6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8 columns
|
||||||
|
@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
|
||||||
|
.outer {
|
||||||
|
.tabs {
|
||||||
|
width: $cols8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-controls {
|
||||||
|
width: $cols8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectBox {
|
||||||
|
.grid {
|
||||||
|
.flex-row {
|
||||||
|
width: $cols9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue