);
}
- var imgElement,titleElement;
+ var imgElement,titleElement,avatarElement;
if (this.props.linkTitle) {
imgElement =
{imgElement}
-
- {titleElement}
+
+ {avatarElement}
+
+ {info}
+
{extra}
diff --git a/src/components/thumbnail/thumbnail.scss b/src/components/thumbnail/thumbnail.scss
index f119b78ec..f731449ab 100644
--- a/src/components/thumbnail/thumbnail.scss
+++ b/src/components/thumbnail/thumbnail.scss
@@ -90,9 +90,11 @@
$project-height: 108px;
width: $project-width;
- img {
- width: $project-width;
- height: $project-height;
+ .thumbnail-image {
+ img {
+ width: $project-width;
+ height: $project-height;
+ }
}
}
diff --git a/src/routes.json b/src/routes.json
index 0520c20cd..478b94c9e 100644
--- a/src/routes.json
+++ b/src/routes.json
@@ -4,8 +4,7 @@
"pattern": "^/?$",
"routeAlias": "/?$",
"view": "splash/splash",
- "title": "Imagine, Program, Share",
- "viewportWidth": "device-width"
+ "title": "Imagine, Program, Share"
},
{
"name": "about",
@@ -48,32 +47,28 @@
"pattern": "^/conference/plan/?$",
"routeAlias": "/conference(?!/201[4-5])",
"view": "conference/plan/plan",
- "title": "Plan Your Visit",
- "viewportWidth": "device-width"
+ "title": "Plan Your Visit"
},
{
"name": "conference-expectations",
"pattern": "^/conference/expect/?$",
"routeAlias": "/conference(?!/201[4-5])",
"view": "conference/expect/expect",
- "title": "What to Expect",
- "viewportWidth": "device-width"
+ "title": "What to Expect"
},
{
"name": "conference-schedule",
"pattern": "^/conference/schedule/?$",
"routeAlias": "/conference(?!/201[4-5])",
"view": "conference/schedule/schedule",
- "title": "Conference Schedule",
- "viewportWidth": "device-width"
+ "title": "Conference Schedule"
},
{
"name": "conference-details",
"pattern": "^/conference/:id/details/?$",
"routeAlias": "/conference(?!/201[4-5])",
"view": "conference/details/details",
- "title": "Event Details",
- "viewportWidth": "device-width"
+ "title": "Event Details"
},
{
"name": "developers",
@@ -108,8 +103,7 @@
"pattern": "^/educators/register/?$",
"routeAlias": "/educators(?:/(faq|register|waiting))?/?$",
"view": "teacherregistration/teacherregistration",
- "title": "Teacher Registration",
- "viewportWidth": "device-width"
+ "title": "Teacher Registration"
},
{
"name": "teacherwaitingroom",
diff --git a/src/template-config.js b/src/template-config.js
index 297328d74..33cd26ca7 100644
--- a/src/template-config.js
+++ b/src/template-config.js
@@ -7,7 +7,7 @@ module.exports = {
'and animations.',
// override if mobile-friendly
- viewportWidth: 942,
+ viewportWidth: 'device-width',
// Open graph
og_image: 'https://scratch.mit.edu/images/scratch-og.png',
diff --git a/src/views/explore/explore.jsx b/src/views/explore/explore.jsx
index 2149be580..c1c0e00df 100644
--- a/src/views/explore/explore.jsx
+++ b/src/views/explore/explore.jsx
@@ -7,8 +7,11 @@ var render = require('../../lib/render.jsx');
var api = require('../../lib/api');
var Page = require('../../components/page/www/page.jsx');
-var Box = require('../../components/box/box.jsx');
var Tabs = require('../../components/tabs/tabs.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 Grid = require('../../components/grid/grid.jsx');
@@ -27,16 +30,19 @@ var Explore = injectIntl(React.createClass({
stories: 'stories'
};
var typeOptions = ['projects','studios'];
+ var modeOptions = ['trending', 'popular', 'recent', ''];
var pathname = window.location.pathname.toLowerCase();
if (pathname[pathname.length - 1] === '/') {
pathname = pathname.substring(0, pathname.length - 1);
}
- var slash = pathname.lastIndexOf('/');
- var currentCategory = pathname.substring(slash + 1,pathname.length);
- var typeStart = pathname.indexOf('explore/');
- var type = pathname.substring(typeStart + 8,slash);
- if (Object.keys(categoryOptions).indexOf(currentCategory) === -1 || typeOptions.indexOf(type) === -1) {
+ var options = pathname.split('/');
+ var type = options[2];
+ var currentCategory = options[3];
+ var currentMode = options.length > 4 ? options[4] : '';
+ if (Object.keys(categoryOptions).indexOf(currentCategory) === -1 ||
+ typeOptions.indexOf(type) === -1 ||
+ modeOptions.indexOf(currentMode) === -1){
window.location = window.location.origin + '/explore/projects/all/';
}
@@ -44,7 +50,9 @@ var Explore = injectIntl(React.createClass({
category: currentCategory,
acceptableTabs: categoryOptions,
acceptableTypes: typeOptions,
+ acceptableModes: modeOptions,
itemType: type,
+ mode: currentMode,
loadNumber: 16
};
},
@@ -59,12 +67,13 @@ var Explore = injectIntl(React.createClass({
},
getExploreMore: function () {
var qText = '&q=' + this.props.acceptableTabs[this.props.category] || '*';
-
+
api({
uri: '/search/' + this.props.itemType +
'?limit=' + this.props.loadNumber +
'&offset=' + this.state.offset +
'&language=' + this.props.intl.locale +
+ '&mode=' + (this.props.mode ? this.props.mode : 'trending') +
qText
}, function (err, body) {
if (!err) {
@@ -84,14 +93,20 @@ var Explore = injectIntl(React.createClass({
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) {
var classes = classNames({
active: (this.props.category === type)
});
return (
-
+
@@ -103,20 +118,33 @@ var Explore = injectIntl(React.createClass({
active: (this.props.itemType === type)
});
return (
-
+
+ {this.props.itemType === type ? [
+
+ ] : [
+
+ ]}
);
},
render: function () {
- var formatMessage = this.props.intl.formatMessage;
return (
-
+
+
+
Explore
+
+
+
+ {this.getTab('projects')}
+ {this.getTab('studios')}
+
+
{this.getBubble('all')}
{this.getBubble('animations')}
@@ -125,25 +153,29 @@ var Explore = injectIntl(React.createClass({
{this.getBubble('music')}
{this.getBubble('stories')}
-
- {this.getTab('projects')}
- {this.getTab('studios')}
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/views/explore/explore.scss b/src/views/explore/explore.scss
index 3e8406771..fcc3e5944 100644
--- a/src/views/explore/explore.scss
+++ b/src/views/explore/explore.scss
@@ -4,62 +4,163 @@
$base-bg: $ui-white;
#view {
- .box {
- display: block;
- margin-right: auto;
- margin-bottom: 20px;
- margin-left: auto;
+ background-color: $ui-gray;
+ padding: 0;
+}
- .box-content {
+.outer {
+ .title-banner {
+ &.masthead {
+ margin-bottom: 0;
+ background-color: $ui-yellow;
padding: 0;
- }
- }
- .categories {
- display: inline-block;
- background-color: $ui-gray;
- padding-left: 10px;
- width: calc(100% - 10px);
- justify-content: left;
+ h1 {
+ text-align: center;
+ color: $ui-white;
+ font-size: 3rem;
+ }
- li {
- opacity: .75;
- background-color: $ui-white;
- color: $header-gray;
-
- &:hover {
- opacity: 1;
- border-color: $active-dark-gray;
+ p {
+ margin: 0;
+ width: $cols6;
+ text-align: left;
+ color: $ui-white;
+
+ a {
+ border-bottom: 1px solid $ui-white;
+ color: $ui-white;
+ }
}
}
+ }
- li.active {
- opacity: 1;
- border-color: $active-dark-gray;
+ .left-pusher {
+ margin-right: auto;
+ width: 8.75rem;
+ }
+
+ .tabs {
+ width: 58.75rem;
+ }
+
+ /* HACK: sort controls are terrible. There's some sort of magic formula for height of formsy components that I can't control. */
+
+ .sort-controls {
+ 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;
+ }
+ }
+
+ .help-block {
+ display: none;
+ }
+ }
+ }
+
+ .categories {
+ justify-content: flex-start;
+
+ li {
+ border: 0;
+ background-color: $active-gray;
+ color: $ui-white;
+
+ &.active {
+ opacity: 1;
+ background-color: $ui-aqua;
+ color: $ui-white;
+
+ }
+
+ &:active {
+ padding: .75em 1.5em;
+ }
&:hover {
- opacity: 1;
- border-color: $active-dark-gray;
+ background-color: $active-dark-gray;
}
}
}
#projectBox {
- border-top: 2px solid;
- border-color: $active-gray;
- background-color: $ui-white;
- padding-bottom: 30px;
+ background-color: $ui-gray;
+ padding-top: 16px;
+ padding-bottom: 32px;
width: 100%;
- }
- .load button {
- outline: None;
- border: None;
- background-color: $ui-white;
- padding: 0;
-
- li {
- color: $header-gray;
+ .button {
+ display: block;
+ margin: 0 auto;
+ }
+ }
+}
+
+//4 columns
+@media only screen and (max-width: $mobile - 1) {
+ .outer {
+ .tabs {
+ width: $cols4;
+ }
+
+ .sort-controls {
+ width: $cols4;
+ }
+ }
+}
+
+//6 columns
+@media only screen and (min-width: $mobile) and (max-width: $tablet - 1) {
+ .outer {
+ .tabs {
+ width: $cols6;
+ }
+
+ .sort-controls {
+ 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;
+ }
+ }
}
}
}
diff --git a/src/views/faq/l10n.json b/src/views/faq/l10n.json
index bdb848a5b..a81f73c91 100644
--- a/src/views/faq/l10n.json
+++ b/src/views/faq/l10n.json
@@ -13,7 +13,7 @@
"faq.makeGameTitle":"How do I make a game or animation with Scratch?",
"faq.makeGameBody":"Check out the
help page to see lots of ways to get started with Scratch. Or just
dive in to the project editor.",
"faq.requirementsTitle":"What are the system requirements for Scratch?",
- "faq.requirementsBody":"To run Scratch 2, you need to be using (1) a Mac, Linux or Windows computer; (2) a version of
Adobe Flash Player released on or after June 15, 2016; (3) a relatively recent web browser: one of the latest two versions of
Chrome,
Firefox,
Safari (Mac or Windows only),
Edge (Windows only), or
Internet Explorer 10+ (Windows only). If your computer doesn’t meet these requirements, you can try downloading and installing
Scratch 1.4, which you can still use to share projects to the Scratch 2 website.",
+ "faq.requirementsBody":"To run Scratch 2, you need to be using (1) a Mac, Linux, or Windows computer; (2) a version of
Adobe Flash Player released on or after June 15, 2016; (3) a relatively recent web browser: one of the latest two versions of
Chrome,
Firefox,
Safari (Mac or Windows only),
Edge (Windows only), or
Internet Explorer 10+ (Windows only). If your computer doesn’t meet these requirements, you can try downloading and installing
Scratch 1.4, which you can still use to share projects to the Scratch 2 website.",
"faq.offlineTitle":"Do you have a downloadable version so I can create and view projects offline?",
"faq.offlineBody":"The Scratch 2 offline editor allows you to create Scratch projects without an internet connection. You can download Scratch 2 from the
website. You can also still use
Scratch 1.4. Note: You can have both Scratch 1.4 and 2 on your computer.",
"faq.uploadOldTitle":"Can I still upload projects created with older versions of Scratch to the website?",
diff --git a/src/views/search/search.jsx b/src/views/search/search.jsx
index c517b739f..87e2b9ae0 100644
--- a/src/views/search/search.jsx
+++ b/src/views/search/search.jsx
@@ -6,8 +6,10 @@ var render = require('../../lib/render.jsx');
var api = require('../../lib/api');
var Page = require('../../components/page/www/page.jsx');
-var Box = require('../../components/box/box.jsx');
-var SubNavigation = require('../../components/subnavigation/subnavigation.jsx');
+var TitleBanner = require('../../components/title-banner/title-banner.jsx');
+var Form = require('../../components/forms/form.jsx');
+var Input = require('../../components/forms/input.jsx');
+var Button = require('../../components/forms/button.jsx');
var Tabs = require('../../components/tabs/tabs.jsx');
var Grid = require('../../components/grid/grid.jsx');
@@ -62,6 +64,7 @@ var Search = injectIntl(React.createClass({
'?limit=' + this.props.loadNumber +
'&offset=' + this.state.offset +
'&language=' + this.props.intl.locale +
+ '&mode=popular' +
termText
}, function (err, body) {
var loadedSoFar = this.state.loaded;
@@ -71,16 +74,21 @@ var Search = injectIntl(React.createClass({
this.setState({offset: currentOffset});
}.bind(this));
},
+ onSearchSubmit: function (formData) {
+ window.location.href = '/search/projects?q=' + formData.q;
+ },
getTab: function (type) {
var term = this.props.searchTerm.split(' ').join('+');
var allTab =
+
;
if (this.props.tab == type) {
allTab =
+
;
@@ -89,32 +97,41 @@ var Search = injectIntl(React.createClass({
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
-
+
return (
-
+
+
+
{this.getTab('projects')}
{this.getTab('studios')}
-
-
-
-
+
+
-
);
diff --git a/src/views/search/search.scss b/src/views/search/search.scss
index 49752fb82..0a9d4f583 100644
--- a/src/views/search/search.scss
+++ b/src/views/search/search.scss
@@ -4,33 +4,181 @@
$base-bg: $ui-white;
#view {
- .box {
- display: block;
- margin-right: auto;
- margin-bottom: 20px;
- margin-left: auto;
+ background-color: $ui-gray;
+ padding: 0;
+}
- .box-content {
+.outer {
+ .title-banner {
+ &.masthead {
+ margin-bottom: 0;
+ background-color: darken($ui-blue, 10%);
padding: 0;
- }
- }
- #projectBox {
- border-top: 2px solid;
- border-color: $active-gray;
+ h1 {
+ text-align: center;
+ color: $ui-white;
+ font-size: 3rem;
+ }
+
+ p {
+ margin: 0;
+ width: $cols6;
+ text-align: left;
+ color: $ui-white;
+
+ a {
+ border-bottom: 1px solid $ui-white;
+ color: $ui-white;
+ }
+ }
+ }
+ }
+
+ .search {
+ margin: 0 auto;
+ border-right: 0;
+ width: $cols6;
+ color: $type-white;
+
+ .form {
+ margin: 0;
+ }
+
+ .row {
+ .help-block {
+ display: none;
+ }
+ }
+
+ .input,
+ .button {
+ display: inline-block;
+ margin-top: 5px;
+ outline: none;
+ border: 0;
+ background-color: $active-gray;
+ height: 14px;
+
+ &[type=text] {
+ transition: .15s ease background-color;
+ padding: 0;
+ padding-right: 10px;
+ padding-left: 40px;
+ width: calc(100% - 50px);
+ height: 40px;
+ color: $type-white;
+ font-size: .85em;
+
+ &::placeholder {
+ $placeholder-transparent: rgba(255, 255, 255, .75);
+ color: $placeholder-transparent;
+ }
+
+ &:focus {
+ transition: .15s ease background-color;
+ background-color: $active-dark-gray;
+ }
+
+ .ie9 & {
+ width: 70px;
+ }
+ }
+ }
+
+ .btn-search {
+ position: absolute;
+
+ box-shadow: none;
+ background-color: transparent;
+ background-image: url("/images/nav-search-glass.png");
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: 14px 14px;
+
+ width: 40px;
+ height: 40px;
+
+ &:hover {
+ box-shadow: none;
+ }
+ }
+ }
+
+ .select {
+ select {
+ margin-bottom: 0;
+ color: $header-gray;
+ }
+
+ .help-block {
+ display: none;
+ }
+ }
+
+ .tab-background {
+ box-shadow: 0 0 1px $box-shadow-gray;
background-color: $ui-white;
- padding-bottom: 30px;
width: 100%;
}
- .load button {
- outline: None;
- border: None;
- background-color: $ui-white;
- padding: 0;
+ #projectBox {
+ margin-top: 16px;
+ background-color: $ui-gray;
+ padding-bottom: 32px;
+ width: 100%;
- li {
- color: $header-gray;
+ .button {
+ display: block;
+ margin: 0 auto;
+ }
+ }
+}
+
+//4 columns
+@media only screen and (max-width: $mobile - 1) {
+ .outer {
+ .search {
+ width: $cols4;
+
+ .btn-search {
+ left: 40px;
+ }
+ }
+
+ .tabs {
+ width: $cols4;
+ }
+
+ .sort-controls {
+ width: $cols4;
+ }
+ }
+}
+
+
+//6 columns
+@media only screen and (min-width: $mobile) and (max-width: $tablet - 1) {
+ .outer {
+ .tabs {
+ width: $cols6;
+ }
+
+ .sort-controls {
+ width: $cols6;
+ }
+ }
+}
+
+// 8 columns
+@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
+ .outer {
+ .tabs {
+ width: $cols8;
+ }
+
+ .sort-controls {
+ width: $cols8;
}
}
}
diff --git a/static/svgs/tabs/projects-active.svg b/static/svgs/tabs/projects-active.svg
new file mode 100644
index 000000000..3738946b1
--- /dev/null
+++ b/static/svgs/tabs/projects-active.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/svgs/tabs/projects-inactive.svg b/static/svgs/tabs/projects-inactive.svg
new file mode 100644
index 000000000..c86555b0c
--- /dev/null
+++ b/static/svgs/tabs/projects-inactive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/svgs/tabs/studios-active.svg b/static/svgs/tabs/studios-active.svg
new file mode 100644
index 000000000..71e9fac64
--- /dev/null
+++ b/static/svgs/tabs/studios-active.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/svgs/tabs/studios-inactive.svg b/static/svgs/tabs/studios-inactive.svg
new file mode 100644
index 000000000..241faf900
--- /dev/null
+++ b/static/svgs/tabs/studios-inactive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file