mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 00:21:20 -05:00
Merge pull request #1416 from mewtaylor/issue/custom-rows-api
Move custom homepage row to new api endpoints
This commit is contained in:
commit
36583f0d04
3 changed files with 398 additions and 286 deletions
|
@ -19,7 +19,7 @@
|
|||
"intro.tagLine": "Create stories, games, and animations<br /> Share with others around the world",
|
||||
"intro.tryItOut": "TRY IT OUT",
|
||||
"intro.description": "A creative learning community with <span class=\"project-count\"> {value} </span>projects shared",
|
||||
"intro.defaultDescription": "A creative learning community with <span class=\"project-count\"> over 14 million </span>projects shared",
|
||||
"intro.defaultDescription": "A creative learning community with <span class=\"project-count\"> over 20 million </span>projects shared",
|
||||
|
||||
"news.scratchNews": "Scratch News",
|
||||
|
||||
|
|
315
src/views/splash/presentation.jsx
Normal file
315
src/views/splash/presentation.jsx
Normal file
|
@ -0,0 +1,315 @@
|
|||
var injectIntl = require('react-intl').injectIntl;
|
||||
var React = require('react');
|
||||
|
||||
var sessionActions = require('../../redux/session.js');
|
||||
var shuffle = require('../../lib/shuffle.js').shuffle;
|
||||
|
||||
var Activity = require('../../components/activity/activity.jsx');
|
||||
var AdminPanel = require('../../components/adminpanel/adminpanel.jsx');
|
||||
var DropdownBanner = require('../../components/dropdown-banner/banner.jsx');
|
||||
var Box = require('../../components/box/box.jsx');
|
||||
var Button = require('../../components/forms/button.jsx');
|
||||
var Carousel = require('../../components/carousel/carousel.jsx');
|
||||
var Intro = require('../../components/intro/intro.jsx');
|
||||
var IframeModal = require('../../components/modal/iframe/modal.jsx');
|
||||
var News = require('../../components/news/news.jsx');
|
||||
var TeacherBanner = require('../../components/teacher-banner/teacher-banner.jsx');
|
||||
var Welcome = require('../../components/welcome/welcome.jsx');
|
||||
|
||||
var MediaQuery = require('react-responsive');
|
||||
var frameless = require('../../lib/frameless');
|
||||
|
||||
require('./splash.scss');
|
||||
|
||||
var SplashPresentation = injectIntl(React.createClass({
|
||||
type: 'Splash',
|
||||
propTypes: {
|
||||
sessionStatus: React.PropTypes.string.isRequired,
|
||||
user: React.PropTypes.object.isRequired,
|
||||
isEducator: React.PropTypes.bool.isRequired,
|
||||
isAdmin: React.PropTypes.bool.isRequired,
|
||||
handleDismiss: React.PropTypes.func.isRequired,
|
||||
refreshHomepageCache: React.PropTypes.func.isRequired,
|
||||
shouldShowEmailConfirmation: React.PropTypes.bool.isRequired,
|
||||
emailConfirmationModalOpen: React.PropTypes.bool.isRequired,
|
||||
showEmailConfirmationModal: React.PropTypes.func.isRequired,
|
||||
hideEmailConfirmationModal: React.PropTypes.func.isRequired,
|
||||
shouldShowWelcome: React.PropTypes.bool.isRequired,
|
||||
refreshCacheStatus: React.PropTypes.object.isRequired
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
projectCount: 20000000, // gets the shared project count
|
||||
activity: [], // recent social actions taken by users someone is following
|
||||
news: [], // gets news posts from the scratch Tumblr
|
||||
sharedByFollowing: [], // "Projects by Scratchers I'm Following"
|
||||
lovedByFollowing: [], // "Projects Loved by Scratchers I'm Following"
|
||||
inStudiosFollowing: [], // "Projects in Studios I'm Following"
|
||||
featuredGlobal: {} // global homepage rows, such as "Featured Projects"
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
if (this.props.shouldShowEmailConfirmation) window.addEventListener('message', this.onMessage);
|
||||
},
|
||||
componentWillUnmount: function () {
|
||||
window.removeEventListener('message', this.onMessage);
|
||||
},
|
||||
onMessage: function (e) {
|
||||
if (e.origin != window.location.origin) return;
|
||||
if (e.source != this.emailConfirmationiFrame.contentWindow) return;
|
||||
if (e.data == 'resend-done') {
|
||||
this.hideEmailConfirmationModal();
|
||||
} else {
|
||||
var data = JSON.parse(e.data);
|
||||
if (data['action'] === 'leave-page') {
|
||||
window.location.href = data['uri'];
|
||||
}
|
||||
}
|
||||
},
|
||||
renderHomepageRows: function () {
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
|
||||
var rows = [
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.featuredProjects'})}
|
||||
key="community_featured_projects"
|
||||
>
|
||||
<Carousel items={this.props.featuredGlobal.community_featured_projects} />
|
||||
</Box>,
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.featuredStudios'})}
|
||||
key="community_featured_studios"
|
||||
>
|
||||
<Carousel
|
||||
items={this.props.featuredGlobal.community_featured_studios}
|
||||
settings={{slidesToShow: 4, slidesToScroll: 4, lazyLoad: false}}
|
||||
/>
|
||||
</Box>
|
||||
];
|
||||
|
||||
if (this.props.featuredGlobal.curator_top_projects &&
|
||||
this.props.featuredGlobal.curator_top_projects.length > 4) {
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
key="curator_top_projects"
|
||||
title={
|
||||
formatMessage({id: 'splash.projectsCuratedBy'}) + ' ' +
|
||||
this.props.featuredGlobal.curator_top_projects[0].curator_name}
|
||||
moreTitle={formatMessage({id: 'general.learnMore'})}
|
||||
moreHref="/studios/386359/"
|
||||
>
|
||||
<Carousel items={this.props.featuredGlobal.curator_top_projects} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.featuredGlobal.scratch_design_studio &&
|
||||
this.props.featuredGlobal.scratch_design_studio.length > 4) {
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
key="scratch_design_studio"
|
||||
title={
|
||||
formatMessage({id: 'splash.scratchDesignStudioTitle'})
|
||||
+ ' - ' + this.props.featuredGlobal.scratch_design_studio[0].gallery_title}
|
||||
moreTitle={formatMessage({id: 'splash.visitTheStudio'})}
|
||||
moreHref={'/studios/' + this.props.featuredGlobal.scratch_design_studio[0].gallery_id + '/'}
|
||||
>
|
||||
<Carousel items={this.props.featuredGlobal.scratch_design_studio} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.user &&
|
||||
this.props.featuredGlobal.community_newest_projects &&
|
||||
this.props.featuredGlobal.community_newest_projects.length > 0) {
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.recentlySharedProjects'})}
|
||||
key="community_newest_projects"
|
||||
>
|
||||
<Carousel items={this.props.featuredGlobal.community_newest_projects} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.sharedByFollowing && this.props.sharedByFollowing.length > 0) {
|
||||
rows.push(
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.projectsByScratchersFollowing'})}
|
||||
key="custom_projects_by_following"
|
||||
>
|
||||
<Carousel items={this.props.sharedByFollowing} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.lovedByFollowing && this.props.lovedByFollowing.length > 0) {
|
||||
rows.push(
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.projectsLovedByScratchersFollowing'})}
|
||||
key="custom_projects_loved_by_following"
|
||||
>
|
||||
<Carousel items={this.props.lovedByFollowing} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.inStudiosFollowing && this.props.inStudiosFollowing.length > 0) {
|
||||
rows.push(
|
||||
<Box
|
||||
title={formatMessage({id:'splash.projectsInStudiosFollowing'})}
|
||||
key="custom_projects_in_studios_following"
|
||||
>
|
||||
<Carousel items={this.props.inStudiosFollowing} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.communityRemixing'})}
|
||||
key="community_most_remixed_projects"
|
||||
>
|
||||
<Carousel
|
||||
items={shuffle(this.props.featuredGlobal.community_most_remixed_projects)}
|
||||
showRemixes={true}
|
||||
/>
|
||||
</Box>,
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.communityLoving'})}
|
||||
key="community_most_loved_projects"
|
||||
>
|
||||
<Carousel
|
||||
items={shuffle(this.props.featuredGlobal.community_most_loved_projects)}
|
||||
showLoves={true}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
||||
return rows;
|
||||
},
|
||||
render: function () {
|
||||
var featured = this.renderHomepageRows();
|
||||
|
||||
var formatHTMLMessage = this.props.intl.formatHTMLMessage;
|
||||
var formatNumber = this.props.intl.formatNumber;
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
var messages = {
|
||||
'general.viewAll': formatMessage({id: 'general.viewAll'}),
|
||||
'news.scratchNews': formatMessage({id: 'news.scratchNews'}),
|
||||
'welcome.welcomeToScratch': formatMessage({id: 'welcome.welcomeToScratch'}),
|
||||
'welcome.learn': formatMessage({id: 'welcome.learn'}),
|
||||
'welcome.tryOut': formatMessage({id: 'welcome.tryOut'}),
|
||||
'welcome.connect': formatMessage({id: 'welcome.connect'}),
|
||||
'intro.aboutScratch': formatMessage({id: 'intro.aboutScratch'}),
|
||||
'intro.forEducators': formatMessage({id: 'intro.forEducators'}),
|
||||
'intro.forParents': formatMessage({id: 'intro.forParents'}),
|
||||
'intro.joinScratch': formatMessage({id: 'intro.joinScratch'}),
|
||||
'intro.seeExamples': formatMessage({id: 'intro.seeExamples'}),
|
||||
'intro.tagLine': formatHTMLMessage({id: 'intro.tagLine'}),
|
||||
'intro.tryItOut': formatMessage({id: 'intro.tryItOut'}),
|
||||
'teacherbanner.greeting': formatMessage({id: 'teacherbanner.greeting'}),
|
||||
'teacherbanner.subgreeting': formatMessage({id: 'teacherbanner.subgreeting'}),
|
||||
'teacherbanner.classesButton': formatMessage({id: 'teacherbanner.classesButton'}),
|
||||
'teacherbanner.resourcesButton': formatMessage({id: 'general.resourcesTitle'}),
|
||||
'teacherbanner.faqButton': formatMessage({id: 'teacherbanner.faqButton'})
|
||||
};
|
||||
if (this.props.projectCount === 20000000) {
|
||||
messages['intro.description'] = formatHTMLMessage({id: 'intro.defaultDescription'});
|
||||
} else {
|
||||
var count = formatNumber(this.props.projectCount);
|
||||
messages['intro.description'] = formatHTMLMessage({id: 'intro.description'}, {value: count});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="splash">
|
||||
{this.props.shouldShowEmailConfirmation ? [
|
||||
<DropdownBanner
|
||||
key="confirmedEmail"
|
||||
className="warning"
|
||||
onRequestDismiss={this.props.handleDismiss.bind(this, 'confirmed_email')}
|
||||
>
|
||||
<a href="#" onClick={this.props.showEmailConfirmationModal}>Confirm your email</a>
|
||||
{' '}to enable sharing.{' '}
|
||||
<a href="/info/faq/#accounts">Having trouble?</a>
|
||||
</DropdownBanner>,
|
||||
<IframeModal
|
||||
isOpen={this.props.emailConfirmationModalOpen}
|
||||
onRequestClose={this.props.hideEmailConfirmationModal}
|
||||
className="mod-confirmation"
|
||||
componentRef={
|
||||
function (iframe) {
|
||||
this.emailConfirmationiFrame = iframe;
|
||||
}.bind(this)
|
||||
}
|
||||
src="/accounts/email_resend_standalone/"
|
||||
/>
|
||||
] : []}
|
||||
{this.props.isEducator ? [
|
||||
<TeacherBanner key="teacherbanner" messages={messages} />
|
||||
] : []}
|
||||
<div key="inner" className="inner mod-splash">
|
||||
{this.props.sessionStatus === sessionActions.Status.FETCHED ? (
|
||||
Object.keys(this.props.user).length !== 0 ? [
|
||||
<div key="header" className="splash-header">
|
||||
{this.props.shouldShowWelcome ? [
|
||||
<Welcome key="welcome"
|
||||
onDismiss={this.props.handleDismiss.bind(this, 'welcome')}
|
||||
messages={messages} />
|
||||
] : [
|
||||
<Activity key="activity" items={this.props.activity} />
|
||||
]}
|
||||
<News items={this.props.news} messages={messages} />
|
||||
</div>
|
||||
] : [
|
||||
<MediaQuery minWidth={frameless.desktop}>
|
||||
<Intro projectCount={this.props.projectCount} messages={messages} key="intro"/>
|
||||
</MediaQuery>
|
||||
]) : []
|
||||
}
|
||||
|
||||
{featured}
|
||||
|
||||
{this.props.isAdmin ? [
|
||||
<AdminPanel>
|
||||
<dt>Tools</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/scratch_admin/tickets">Ticket Queue</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/scratch_admin/ip-search/">IP Search</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/scratch_admin/email-search/">Email Search</a>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt>Homepage Cache</dt>
|
||||
<dd>
|
||||
<ul className="cache-list">
|
||||
<li>
|
||||
<div className="button-row">
|
||||
<span>Refresh row data:</span>
|
||||
<Button onClick={this.props.refreshHomepageCache}
|
||||
className={this.props.refreshCacheStatus.status}
|
||||
disabled={this.props.refreshCacheStatus.disabled}>
|
||||
<span>{this.props.refreshCacheStatus.content}</span>
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</AdminPanel>
|
||||
] : []}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
module.exports = SplashPresentation;
|
|
@ -6,53 +6,46 @@ var api = require('../../lib/api');
|
|||
var log = require('../../lib/log');
|
||||
var render = require('../../lib/render.jsx');
|
||||
var sessionActions = require('../../redux/session.js');
|
||||
var shuffle = require('../../lib/shuffle.js').shuffle;
|
||||
|
||||
var Activity = require('../../components/activity/activity.jsx');
|
||||
var AdminPanel = require('../../components/adminpanel/adminpanel.jsx');
|
||||
var DropdownBanner = require('../../components/dropdown-banner/banner.jsx');
|
||||
var Box = require('../../components/box/box.jsx');
|
||||
var Button = require('../../components/forms/button.jsx');
|
||||
var Carousel = require('../../components/carousel/carousel.jsx');
|
||||
var Intro = require('../../components/intro/intro.jsx');
|
||||
var IframeModal = require('../../components/modal/iframe/modal.jsx');
|
||||
var News = require('../../components/news/news.jsx');
|
||||
var Page = require('../../components/page/www/page.jsx');
|
||||
var TeacherBanner = require('../../components/teacher-banner/teacher-banner.jsx');
|
||||
var Welcome = require('../../components/welcome/welcome.jsx');
|
||||
|
||||
var MediaQuery = require('react-responsive');
|
||||
var frameless = require('../../lib/frameless');
|
||||
|
||||
require('./splash.scss');
|
||||
var SplashPresentation = require('./presentation.jsx');
|
||||
|
||||
var Splash = injectIntl(React.createClass({
|
||||
type: 'Splash',
|
||||
getInitialState: function () {
|
||||
return {
|
||||
projectCount: 14000000, // gets the shared project count
|
||||
projectCount: 20000000, // gets the shared project count
|
||||
activity: [], // recent social actions taken by users someone is following
|
||||
news: [], // gets news posts from the scratch Tumblr
|
||||
featuredCustom: {}, // custom homepage rows, such as "Projects by Scratchers I'm Following"
|
||||
sharedByFollowing: [], // "Projects by Scratchers I'm Following"
|
||||
lovedByFollowing: [], // "Projects Loved by Scratchers I'm Following"
|
||||
inStudiosFollowing: [], // "Projects in Studios I'm Following"
|
||||
featuredGlobal: {}, // global homepage rows, such as "Featured Projects"
|
||||
showEmailConfirmationModal: true, // flag that determines whether to show banner to request email conf.
|
||||
emailConfirmationModalOpen: false, // flag that determines whether to show banner to request email conf.
|
||||
refreshCacheStatus: 'notrequested'
|
||||
};
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
session: {},
|
||||
permissions: {}
|
||||
sessionStatus: sessionActions.Status.NOT_FETCHED,
|
||||
user: {},
|
||||
flags: {},
|
||||
isEducator: false,
|
||||
isAdmin: false
|
||||
};
|
||||
},
|
||||
componentDidUpdate: function (prevProps) {
|
||||
if (this.props.session.session.user != prevProps.session.session.user) {
|
||||
if (this.props.session.session.user) {
|
||||
this.getActivity();
|
||||
this.getFeaturedCustom();
|
||||
if (this.props.user != prevProps.user) {
|
||||
if (this.props.user) {
|
||||
this.getActivity(this.props.user.username);
|
||||
this.getSharedByFollowing(this.props.user.token);
|
||||
this.getInStudiosFollowing(this.props.user.token);
|
||||
this.getLovedByFollowing(this.props.user.token);
|
||||
this.getNews();
|
||||
} else {
|
||||
this.setState({featuredCustom: []});
|
||||
this.setState({sharedByFollowing: []});
|
||||
this.setState({lovedByFollowing: []});
|
||||
this.setState({inStudiosFollowing: []});
|
||||
this.setState({activity: []});
|
||||
this.setState({news: []});
|
||||
this.getProjectCount();
|
||||
|
@ -66,33 +59,19 @@ var Splash = injectIntl(React.createClass({
|
|||
},
|
||||
componentDidMount: function () {
|
||||
this.getFeaturedGlobal();
|
||||
if (this.props.session.session.user) {
|
||||
this.getActivity();
|
||||
this.getFeaturedCustom();
|
||||
if (this.props.user) {
|
||||
this.getActivity(this.props.user.username);
|
||||
this.getSharedByFollowing(this.props.user.token);
|
||||
this.getInStudiosFollowing(this.props.user.token);
|
||||
this.getLovedByFollowing(this.props.user.token);
|
||||
this.getNews();
|
||||
} else {
|
||||
this.getProjectCount();
|
||||
}
|
||||
if (this.shouldShowEmailConfirmation()) window.addEventListener('message', this.onMessage);
|
||||
},
|
||||
componentWillUnmount: function () {
|
||||
window.removeEventListener('message', this.onMessage);
|
||||
},
|
||||
onMessage: function (e) {
|
||||
if (e.origin != window.location.origin) return;
|
||||
if (e.source != this.emailConfirmationiFrame.contentWindow) return;
|
||||
if (e.data == 'resend-done') {
|
||||
this.hideEmailConfirmationModal();
|
||||
} else {
|
||||
var data = JSON.parse(e.data);
|
||||
if (data['action'] === 'leave-page') {
|
||||
window.location.href = data['uri'];
|
||||
}
|
||||
}
|
||||
},
|
||||
getActivity: function () {
|
||||
getActivity: function (username) {
|
||||
api({
|
||||
uri: '/proxy/users/' + this.props.session.session.user.username + '/activity?limit=5'
|
||||
uri: '/proxy/users/' + username + '/activity?limit=5'
|
||||
}, function (err, body) {
|
||||
if (!body) return log.error('No response body');
|
||||
if (!err) return this.setState({activity: body});
|
||||
|
@ -106,12 +85,31 @@ var Splash = injectIntl(React.createClass({
|
|||
if (!err) return this.setState({featuredGlobal: body});
|
||||
}.bind(this));
|
||||
},
|
||||
getFeaturedCustom: function () {
|
||||
getSharedByFollowing: function (token) {
|
||||
api({
|
||||
uri: '/proxy/users/' + this.props.session.session.user.id + '/featured'
|
||||
uri: '/projects/following/users',
|
||||
authentication: token
|
||||
}, function (err, body) {
|
||||
if (!body) return log.error('No response body');
|
||||
if (!err) return this.setState({featuredCustom: body});
|
||||
if (!err) return this.setState({sharedByFollowing: body});
|
||||
}.bind(this));
|
||||
},
|
||||
getInStudiosFollowing: function (token) {
|
||||
api({
|
||||
uri: '/projects/following/studios',
|
||||
authentication: token
|
||||
}, function (err, body) {
|
||||
if (!body) return log.error('No response body');
|
||||
if (!err) return this.setState({inStudiosFollowing: body});
|
||||
}.bind(this));
|
||||
},
|
||||
getLovedByFollowing: function (token) {
|
||||
api({
|
||||
uri: '/projects/following/loves',
|
||||
authentication: token
|
||||
}, function (err, body) {
|
||||
if (!body) return log.error('No response body');
|
||||
if (!err) return this.setState({lovedByFollowing: body});
|
||||
}.bind(this));
|
||||
},
|
||||
getNews: function () {
|
||||
|
@ -179,256 +177,55 @@ var Splash = injectIntl(React.createClass({
|
|||
}.bind(this));
|
||||
},
|
||||
shouldShowWelcome: function () {
|
||||
if (!this.props.session.session.user || !this.props.session.session.flags.show_welcome) return false;
|
||||
if (!this.props.user || !this.props.flags.show_welcome) return false;
|
||||
return (
|
||||
new Date(this.props.session.session.user.dateJoined) >
|
||||
new Date(this.props.user.dateJoined) >
|
||||
new Date(new Date - 2*7*24*60*60*1000) // Two weeks ago
|
||||
);
|
||||
},
|
||||
shouldShowEmailConfirmation: function () {
|
||||
return (
|
||||
this.props.session.session.user && this.props.session.session.flags.has_outstanding_email_confirmation &&
|
||||
this.props.session.session.flags.confirm_email_banner);
|
||||
},
|
||||
renderHomepageRows: function () {
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
|
||||
var rows = [
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.featuredProjects'})}
|
||||
key="community_featured_projects">
|
||||
<Carousel items={this.state.featuredGlobal.community_featured_projects} />
|
||||
</Box>,
|
||||
<Box
|
||||
title={formatMessage({id: 'splash.featuredStudios'})}
|
||||
key="community_featured_studios">
|
||||
<Carousel items={this.state.featuredGlobal.community_featured_studios}
|
||||
settings={{slidesToShow: 4, slidesToScroll: 4, lazyLoad: false}} />
|
||||
</Box>
|
||||
];
|
||||
|
||||
if (this.state.featuredGlobal.curator_top_projects &&
|
||||
this.state.featuredGlobal.curator_top_projects.length > 4) {
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
key="curator_top_projects"
|
||||
title={
|
||||
formatMessage({id: 'splash.projectsCuratedBy'}) + ' ' +
|
||||
this.state.featuredGlobal.curator_top_projects[0].curator_name}
|
||||
moreTitle={formatMessage({id: 'general.learnMore'})}
|
||||
moreHref="/studios/386359/">
|
||||
|
||||
<Carousel items={this.state.featuredGlobal.curator_top_projects} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.featuredGlobal.scratch_design_studio &&
|
||||
this.state.featuredGlobal.scratch_design_studio.length > 4) {
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
key="scratch_design_studio"
|
||||
title={
|
||||
formatMessage({id: 'splash.scratchDesignStudioTitle'})
|
||||
+ ' - ' + this.state.featuredGlobal.scratch_design_studio[0].gallery_title}
|
||||
moreTitle={formatMessage({id: 'splash.visitTheStudio'})}
|
||||
moreHref={'/studios/' + this.state.featuredGlobal.scratch_design_studio[0].gallery_id + '/'}>
|
||||
|
||||
<Carousel items={this.state.featuredGlobal.scratch_design_studio} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.session.session.user &&
|
||||
this.state.featuredGlobal.community_newest_projects &&
|
||||
this.state.featuredGlobal.community_newest_projects.length > 0) {
|
||||
|
||||
rows.push(
|
||||
<Box title={formatMessage({id: 'splash.recentlySharedProjects'})}
|
||||
key="community_newest_projects">
|
||||
<Carousel items={this.state.featuredGlobal.community_newest_projects} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.featuredCustom.custom_projects_by_following &&
|
||||
this.state.featuredCustom.custom_projects_by_following.length > 0) {
|
||||
|
||||
rows.push(
|
||||
<Box title={formatMessage({id: 'splash.projectsByScratchersFollowing'})}
|
||||
key="custom_projects_by_following">
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_by_following} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
if (this.state.featuredCustom.custom_projects_loved_by_following &&
|
||||
this.state.featuredCustom.custom_projects_loved_by_following.length > 0) {
|
||||
|
||||
rows.push(
|
||||
<Box title={formatMessage({id: 'splash.projectsLovedByScratchersFollowing'})}
|
||||
key="custom_projects_loved_by_following">
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_loved_by_following} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.featuredCustom.custom_projects_in_studios_following &&
|
||||
this.state.featuredCustom.custom_projects_in_studios_following.length > 0) {
|
||||
|
||||
rows.push(
|
||||
<Box title={formatMessage({id:'splash.projectsInStudiosFollowing'})}
|
||||
key="custom_projects_in_studios_following">
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_in_studios_following} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
rows.push(
|
||||
<Box title={formatMessage({id: 'splash.communityRemixing'})}
|
||||
key="community_most_remixed_projects">
|
||||
|
||||
<Carousel items={shuffle(this.state.featuredGlobal.community_most_remixed_projects)}
|
||||
showRemixes={true} />
|
||||
</Box>,
|
||||
<Box title={formatMessage({id: 'splash.communityLoving'})}
|
||||
key="community_most_loved_projects">
|
||||
|
||||
<Carousel items={shuffle(this.state.featuredGlobal.community_most_loved_projects)}
|
||||
showLoves={true} />
|
||||
</Box>
|
||||
);
|
||||
|
||||
return rows;
|
||||
this.props.user && this.props.flags.has_outstanding_email_confirmation &&
|
||||
this.props.flags.confirm_email_banner);
|
||||
},
|
||||
render: function () {
|
||||
var featured = this.renderHomepageRows();
|
||||
var homepageCacheState = this.getHomepageRefreshStatus();
|
||||
|
||||
var formatHTMLMessage = this.props.intl.formatHTMLMessage;
|
||||
var formatNumber = this.props.intl.formatNumber;
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
var messages = {
|
||||
'general.viewAll': formatMessage({id: 'general.viewAll'}),
|
||||
'news.scratchNews': formatMessage({id: 'news.scratchNews'}),
|
||||
'welcome.welcomeToScratch': formatMessage({id: 'welcome.welcomeToScratch'}),
|
||||
'welcome.learn': formatMessage({id: 'welcome.learn'}),
|
||||
'welcome.tryOut': formatMessage({id: 'welcome.tryOut'}),
|
||||
'welcome.connect': formatMessage({id: 'welcome.connect'}),
|
||||
'intro.aboutScratch': formatMessage({id: 'intro.aboutScratch'}),
|
||||
'intro.forEducators': formatMessage({id: 'intro.forEducators'}),
|
||||
'intro.forParents': formatMessage({id: 'intro.forParents'}),
|
||||
'intro.joinScratch': formatMessage({id: 'intro.joinScratch'}),
|
||||
'intro.seeExamples': formatMessage({id: 'intro.seeExamples'}),
|
||||
'intro.tagLine': formatHTMLMessage({id: 'intro.tagLine'}),
|
||||
'intro.tryItOut': formatMessage({id: 'intro.tryItOut'}),
|
||||
'teacherbanner.greeting': formatMessage({id: 'teacherbanner.greeting'}),
|
||||
'teacherbanner.subgreeting': formatMessage({id: 'teacherbanner.subgreeting'}),
|
||||
'teacherbanner.classesButton': formatMessage({id: 'teacherbanner.classesButton'}),
|
||||
'teacherbanner.resourcesButton': formatMessage({id: 'general.resourcesTitle'}),
|
||||
'teacherbanner.faqButton': formatMessage({id: 'teacherbanner.faqButton'})
|
||||
};
|
||||
if (this.state.projectCount === this.getInitialState().projectCount) {
|
||||
messages['intro.description'] = formatHTMLMessage({id: 'intro.defaultDescription'});
|
||||
} else {
|
||||
var count = formatNumber(this.state.projectCount);
|
||||
messages['intro.description'] = formatHTMLMessage({id: 'intro.description'}, {value: count});
|
||||
}
|
||||
var showEmailConfirmation = this.shouldShowEmailConfirmation() || false;
|
||||
var showWelcome = this.shouldShowWelcome();
|
||||
var homepageRefreshStatus = this.getHomepageRefreshStatus();
|
||||
|
||||
return (
|
||||
<div className="splash">
|
||||
{this.shouldShowEmailConfirmation() ? [
|
||||
<DropdownBanner
|
||||
key="confirmedEmail"
|
||||
className="warning"
|
||||
onRequestDismiss={this.handleDismiss.bind(this, 'confirmed_email')}
|
||||
>
|
||||
<a href="#" onClick={this.showEmailConfirmationModal}>Confirm your email</a>
|
||||
{' '}to enable sharing.{' '}
|
||||
<a href="/info/faq/#accounts">Having trouble?</a>
|
||||
</DropdownBanner>,
|
||||
<IframeModal
|
||||
isOpen={this.state.emailConfirmationModalOpen}
|
||||
onRequestClose={this.hideEmailConfirmationModal}
|
||||
className="mod-confirmation"
|
||||
componentRef={
|
||||
function (iframe) {
|
||||
this.emailConfirmationiFrame = iframe;
|
||||
}.bind(this)
|
||||
}
|
||||
src="/accounts/email_resend_standalone/"
|
||||
/>
|
||||
] : []}
|
||||
{this.props.permissions.educator ? [
|
||||
<TeacherBanner key="teacherbanner" messages={messages} />
|
||||
] : []}
|
||||
<div key="inner" className="inner mod-splash">
|
||||
{this.props.session.status === sessionActions.Status.FETCHED ? (
|
||||
this.props.session.session.user ? [
|
||||
<div key="header" className="splash-header">
|
||||
{this.shouldShowWelcome() ? [
|
||||
<Welcome key="welcome"
|
||||
onDismiss={this.handleDismiss.bind(this, 'welcome')}
|
||||
messages={messages} />
|
||||
] : [
|
||||
<Activity key="activity" items={this.state.activity} />
|
||||
]}
|
||||
<News items={this.state.news} messages={messages} />
|
||||
</div>
|
||||
] : [
|
||||
<MediaQuery minWidth={frameless.desktop}>
|
||||
<Intro projectCount={this.state.projectCount} messages={messages} key="intro"/>
|
||||
</MediaQuery>
|
||||
]) : []
|
||||
}
|
||||
|
||||
{featured}
|
||||
|
||||
<AdminPanel>
|
||||
<dt>Tools</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/scratch_admin/tickets">Ticket Queue</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/scratch_admin/ip-search/">IP Search</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/scratch_admin/email-search/">Email Search</a>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt>Homepage Cache</dt>
|
||||
<dd>
|
||||
<ul className="cache-list">
|
||||
<li>
|
||||
<div className="button-row">
|
||||
<span>Refresh row data:</span>
|
||||
<Button onClick={this.refreshHomepageCache}
|
||||
className={homepageCacheState.status}
|
||||
disabled={homepageCacheState.disabled}>
|
||||
<span>{homepageCacheState.content}</span>
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</AdminPanel>
|
||||
</div>
|
||||
</div>
|
||||
<SplashPresentation
|
||||
sessionStatus={this.props.sessionStatus}
|
||||
user={this.props.user}
|
||||
isEducator={this.props.isEducator}
|
||||
isAdmin={this.props.isAdmin}
|
||||
handleDismiss={this.handleDismiss}
|
||||
refreshHomepageCache={this.refreshHomepageCache}
|
||||
shouldShowEmailConfirmation={showEmailConfirmation}
|
||||
emailConfirmationModalOpen={this.state.emailConfirmationModalOpen}
|
||||
showEmailConfirmationModal={this.showEmailConfirmationModal}
|
||||
hideEmailConfirmationModal={this.hideEmailConfirmationModal}
|
||||
shouldShowWelcome={showWelcome}
|
||||
projectCount={this.state.projectCount}
|
||||
activity={this.state.activity}
|
||||
news={this.state.news}
|
||||
sharedByFollowing={this.state.sharedByFollowing}
|
||||
lovedByFollowing={this.state.lovedByFollowing}
|
||||
inStudiosFollowing={this.state.inStudiosFollowing}
|
||||
featuredGlobal={this.state.featuredGlobal}
|
||||
refreshCacheStatus={homepageRefreshStatus}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
var mapStateToProps = function (state) {
|
||||
return {
|
||||
session: state.session,
|
||||
permissions: state.permissions
|
||||
sessionStatus: state.session.status,
|
||||
user: state.session.session.user,
|
||||
flags: state.session.session.flags,
|
||||
isEducator: state.permissions.educator,
|
||||
isAdmin: state.permissions.admin
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue