mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-03-14 15:09:59 -04:00
Merge pull request #539 from technoboy10/gh395-396-initialstate
Fix GH-395 and GH-396: Add initial state to splash header and navbar
This commit is contained in:
commit
9d6d447fc4
4 changed files with 159 additions and 132 deletions
|
@ -19,8 +19,8 @@ var AdminPanel = React.createClass({
|
|||
render: function () {
|
||||
// make sure user is present before checking if they're an admin. Don't show anything if user not an admin.
|
||||
var showAdmin = false;
|
||||
if (this.props.session.user) {
|
||||
showAdmin = this.props.session.permissions.admin;
|
||||
if (this.props.session.session.user) {
|
||||
showAdmin = this.props.session.session.permissions.admin;
|
||||
}
|
||||
|
||||
if (!showAdmin) return false;
|
||||
|
|
|
@ -44,19 +44,19 @@ var Navigation = React.createClass({
|
|||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
if (this.props.session.user) {
|
||||
if (this.props.session.session.user) {
|
||||
this.getMessageCount();
|
||||
var intervalId = setInterval(this.getMessageCount, 120000); // check for new messages every 2 mins.
|
||||
this.setState({'messageCountIntervalId': intervalId});
|
||||
}
|
||||
},
|
||||
componentDidUpdate: function (prevProps) {
|
||||
if (prevProps.session.user != this.props.session.user) {
|
||||
if (prevProps.session.session.user != this.props.session.session.user) {
|
||||
this.setState({
|
||||
'loginOpen': false,
|
||||
'accountNavOpen': false
|
||||
});
|
||||
if (this.props.session.user) {
|
||||
if (this.props.session.session.user) {
|
||||
this.getMessageCount();
|
||||
var intervalId = setInterval(this.getMessageCount, 120000);
|
||||
this.setState({'messageCountIntervalId': intervalId});
|
||||
|
@ -81,13 +81,13 @@ var Navigation = React.createClass({
|
|||
}
|
||||
},
|
||||
getProfileUrl: function () {
|
||||
if (!this.props.session.user) return;
|
||||
return '/users/' + this.props.session.user.username + '/';
|
||||
if (!this.props.session.session.user) return;
|
||||
return '/users/' + this.props.session.session.user.username + '/';
|
||||
},
|
||||
getMessageCount: function () {
|
||||
this.api({
|
||||
method: 'get',
|
||||
uri: '/users/' + this.props.session.user.username + '/messages/count'
|
||||
uri: '/users/' + this.props.session.session.user.username + '/messages/count'
|
||||
}, function (err, body) {
|
||||
if (err) return this.setState({'unreadMessageCount': 0});
|
||||
if (body) {
|
||||
|
@ -175,14 +175,14 @@ var Navigation = React.createClass({
|
|||
},
|
||||
render: function () {
|
||||
var classes = classNames({
|
||||
'logged-in': this.props.session.user
|
||||
'logged-in': this.props.session.session.user
|
||||
});
|
||||
var messageClasses = classNames({
|
||||
'message-count': true,
|
||||
'show': this.state.unreadMessageCount > 0
|
||||
});
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
var createLink = this.props.session.user ? '/projects/editor/' : '/projects/editor/?tip_bar=home';
|
||||
var createLink = this.props.session.session.user ? '/projects/editor/' : '/projects/editor/?tip_bar=home';
|
||||
return (
|
||||
<NavigationBox className={classes}>
|
||||
<ul>
|
||||
|
@ -225,99 +225,101 @@ var Navigation = React.createClass({
|
|||
<Input type="hidden" name="sort_by" value="datetime_shared" />
|
||||
</form>
|
||||
</li>
|
||||
{this.props.session.user ? [
|
||||
<li className="link right messages" key="messages">
|
||||
<a
|
||||
href="/messages/"
|
||||
title={formatMessage({id: 'general.messages'})}>
|
||||
{this.props.session.status === sessionActions.Status.FETCHED ? (
|
||||
this.props.session.session.user ? [
|
||||
<li className="link right messages" key="messages">
|
||||
<a
|
||||
href="/messages/"
|
||||
title={formatMessage({id: 'general.messages'})}>
|
||||
|
||||
<span className={messageClasses}>{this.state.unreadMessageCount}</span>
|
||||
<FormattedMessage id="general.messages" />
|
||||
</a>
|
||||
</li>,
|
||||
<li className="link right mystuff" key="mystuff">
|
||||
<a
|
||||
href="/mystuff/"
|
||||
title={formatMessage({id: 'general.myStuff'})}>
|
||||
<span className={messageClasses}>{this.state.unreadMessageCount}</span>
|
||||
<FormattedMessage id="general.messages" />
|
||||
</a>
|
||||
</li>,
|
||||
<li className="link right mystuff" key="mystuff">
|
||||
<a
|
||||
href="/mystuff/"
|
||||
title={formatMessage({id: 'general.myStuff'})}>
|
||||
|
||||
<FormattedMessage id="general.myStuff" />
|
||||
</a>
|
||||
</li>,
|
||||
<li className="link right account-nav" key="account-nav">
|
||||
<a className="user-info" href="#" onClick={this.handleAccountNavClick}>
|
||||
<Avatar src={this.props.session.user.thumbnailUrl} alt="" />
|
||||
{this.props.session.user.username}
|
||||
</a>
|
||||
<Dropdown
|
||||
as="ul"
|
||||
isOpen={this.state.accountNavOpen}
|
||||
onRequestClose={this.closeAccountNav}>
|
||||
<li>
|
||||
<a href={this.getProfileUrl()}>
|
||||
<FormattedMessage id="general.profile" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/mystuff/">
|
||||
<FormattedMessage id="general.myStuff" />
|
||||
</a>
|
||||
</li>
|
||||
{this.props.session.permissions.educator ? [
|
||||
<FormattedMessage id="general.myStuff" />
|
||||
</a>
|
||||
</li>,
|
||||
<li className="link right account-nav" key="account-nav">
|
||||
<a className="user-info" href="#" onClick={this.handleAccountNavClick}>
|
||||
<Avatar src={this.props.session.session.user.thumbnailUrl} alt="" />
|
||||
{this.props.session.session.user.username}
|
||||
</a>
|
||||
<Dropdown
|
||||
as="ul"
|
||||
isOpen={this.state.accountNavOpen}
|
||||
onRequestClose={this.closeAccountNav}>
|
||||
<li>
|
||||
<a href="/educators/classes/">
|
||||
<FormattedMessage id="general.myClasses" />
|
||||
<a href={this.getProfileUrl()}>
|
||||
<FormattedMessage id="general.profile" />
|
||||
</a>
|
||||
</li>
|
||||
] : []}
|
||||
{this.props.session.permissions.student ? [
|
||||
<li>
|
||||
<a href={'/classes/' + this.props.session.user.classroomId + '/'}>
|
||||
<FormattedMessage id="general.myClass" />
|
||||
<a href="/mystuff/">
|
||||
<FormattedMessage id="general.myStuff" />
|
||||
</a>
|
||||
</li>
|
||||
] : []}
|
||||
<li>
|
||||
<a href="/accounts/settings/">
|
||||
<FormattedMessage id="general.accountSettings" />
|
||||
</a>
|
||||
</li>
|
||||
<li className="divider">
|
||||
<a href="#" onClick={this.handleLogOut}>
|
||||
<FormattedMessage id="navigation.signOut" />
|
||||
</a>
|
||||
</li>
|
||||
</Dropdown>
|
||||
</li>
|
||||
] : [
|
||||
<li className="link right join" key="join">
|
||||
<a href="#" onClick={this.handleJoinClick}>
|
||||
<FormattedMessage id="general.joinScratch" />
|
||||
</a>
|
||||
</li>,
|
||||
<Registration
|
||||
key="registration"
|
||||
isOpen={this.state.registrationOpen}
|
||||
onRequestClose={this.closeRegistration}
|
||||
onRegistrationDone={this.completeRegistration} />,
|
||||
<li className="link right login-item" key="login">
|
||||
<a
|
||||
href="#"
|
||||
onClick={this.handleLoginClick}
|
||||
className="ignore-react-onclickoutside"
|
||||
key="login-link">
|
||||
<FormattedMessage id="general.signIn" />
|
||||
</a>
|
||||
<Dropdown
|
||||
className="login-dropdown with-arrow"
|
||||
isOpen={this.state.loginOpen}
|
||||
onRequestClose={this.closeLogin}
|
||||
key="login-dropdown">
|
||||
<Login
|
||||
onLogIn={this.handleLogIn}
|
||||
error={this.state.loginError} />
|
||||
</Dropdown>
|
||||
</li>
|
||||
]}
|
||||
{this.props.session.session.permissions.educator ? [
|
||||
<li>
|
||||
<a href="/educators/classes/">
|
||||
<FormattedMessage id="general.myClasses" />
|
||||
</a>
|
||||
</li>
|
||||
] : []}
|
||||
{this.props.session.session.permissions.student ? [
|
||||
<li>
|
||||
<a href={'/classes/' + this.props.session.session.user.classroomId + '/'}>
|
||||
<FormattedMessage id="general.myClass" />
|
||||
</a>
|
||||
</li>
|
||||
] : []}
|
||||
<li>
|
||||
<a href="/accounts/settings/">
|
||||
<FormattedMessage id="general.accountSettings" />
|
||||
</a>
|
||||
</li>
|
||||
<li className="divider">
|
||||
<a href="#" onClick={this.handleLogOut}>
|
||||
<FormattedMessage id="navigation.signOut" />
|
||||
</a>
|
||||
</li>
|
||||
</Dropdown>
|
||||
</li>
|
||||
] : [
|
||||
<li className="link right join" key="join">
|
||||
<a href="#" onClick={this.handleJoinClick}>
|
||||
<FormattedMessage id="general.joinScratch" />
|
||||
</a>
|
||||
</li>,
|
||||
<Registration
|
||||
key="registration"
|
||||
isOpen={this.state.registrationOpen}
|
||||
onRequestClose={this.closeRegistration}
|
||||
onRegistrationDone={this.completeRegistration} />,
|
||||
<li className="link right login-item" key="login">
|
||||
<a
|
||||
href="#"
|
||||
onClick={this.handleLoginClick}
|
||||
className="ignore-react-onclickoutside"
|
||||
key="login-link">
|
||||
<FormattedMessage id="general.signIn" />
|
||||
</a>
|
||||
<Dropdown
|
||||
className="login-dropdown with-arrow"
|
||||
isOpen={this.state.loginOpen}
|
||||
onRequestClose={this.closeLogin}
|
||||
key="login-dropdown">
|
||||
<Login
|
||||
onLogIn={this.handleLogIn}
|
||||
error={this.state.loginError} />
|
||||
</Dropdown>
|
||||
</li>
|
||||
]) : [
|
||||
]}
|
||||
</ul>
|
||||
<Modal isOpen={this.state.canceledDeletionOpen}
|
||||
onRequestClose={this.closeCanceledDeletion}
|
||||
|
|
|
@ -1,21 +1,35 @@
|
|||
var keyMirror = require('keymirror');
|
||||
var defaultsDeep = require('lodash.defaultsdeep');
|
||||
|
||||
var api = require('../mixins/api.jsx').api;
|
||||
var tokenActions = require('./token.js');
|
||||
|
||||
var Types = keyMirror({
|
||||
SET_SESSION: null,
|
||||
SET_SESSION_ERROR: null
|
||||
SET_SESSION_ERROR: null,
|
||||
SET_STATUS: null
|
||||
});
|
||||
|
||||
module.exports.Status = keyMirror({
|
||||
FETCHED: null,
|
||||
NOT_FETCHED: null,
|
||||
FETCHING: null
|
||||
});
|
||||
|
||||
module.exports.getInitialState = function (){
|
||||
return {status: module.exports.Status.NOT_FETCHED, session:{}};
|
||||
};
|
||||
|
||||
module.exports.sessionReducer = function (state, action) {
|
||||
// Reducer for handling changes to session state
|
||||
if (typeof state === 'undefined') {
|
||||
state = {};
|
||||
state = module.exports.getInitialState();
|
||||
}
|
||||
switch (action.type) {
|
||||
case Types.SET_SESSION:
|
||||
return action.session;
|
||||
return defaultsDeep({session: action.session}, state);
|
||||
case Types.SET_STATUS:
|
||||
return defaultsDeep({status: action.status}, state);
|
||||
case Types.SET_SESSION_ERROR:
|
||||
// TODO: do something with action.error
|
||||
return state;
|
||||
|
@ -38,8 +52,16 @@ module.exports.setSession = function (session) {
|
|||
};
|
||||
};
|
||||
|
||||
module.exports.setStatus = function (status){
|
||||
return {
|
||||
type: Types.SET_STATUS,
|
||||
status: status
|
||||
};
|
||||
};
|
||||
|
||||
module.exports.refreshSession = function () {
|
||||
return function (dispatch) {
|
||||
dispatch(module.exports.setStatus(module.exports.Status.FETCHING));
|
||||
api({
|
||||
host: '',
|
||||
uri: '/session/'
|
||||
|
@ -52,6 +74,7 @@ module.exports.refreshSession = function () {
|
|||
} else {
|
||||
dispatch(tokenActions.getToken());
|
||||
dispatch(module.exports.setSession(body));
|
||||
dispatch(module.exports.setStatus(module.exports.Status.FETCHED));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ var Splash = injectIntl(React.createClass({
|
|||
};
|
||||
},
|
||||
componentDidUpdate: function (prevProps) {
|
||||
if (this.props.session.user != prevProps.session.user) {
|
||||
if (this.props.session.user) {
|
||||
if (this.props.session.session.user != prevProps.session.session.user) {
|
||||
if (this.props.session.session.user) {
|
||||
this.getActivity();
|
||||
this.getFeaturedCustom();
|
||||
this.getNews();
|
||||
|
@ -65,7 +65,7 @@ var Splash = injectIntl(React.createClass({
|
|||
},
|
||||
componentDidMount: function () {
|
||||
this.getFeaturedGlobal();
|
||||
if (this.props.session.user) {
|
||||
if (this.props.session.session.user) {
|
||||
this.getActivity();
|
||||
this.getFeaturedCustom();
|
||||
this.getNews();
|
||||
|
@ -91,7 +91,7 @@ var Splash = injectIntl(React.createClass({
|
|||
},
|
||||
getActivity: function () {
|
||||
this.api({
|
||||
uri: '/proxy/users/' + this.props.session.user.username + '/activity?limit=5'
|
||||
uri: '/proxy/users/' + this.props.session.session.user.username + '/activity?limit=5'
|
||||
}, function (err, body) {
|
||||
if (!err) this.setState({activity: body});
|
||||
}.bind(this));
|
||||
|
@ -105,7 +105,7 @@ var Splash = injectIntl(React.createClass({
|
|||
},
|
||||
getFeaturedCustom: function () {
|
||||
this.api({
|
||||
uri: '/proxy/users/' + this.props.session.user.id + '/featured'
|
||||
uri: '/proxy/users/' + this.props.session.session.user.id + '/featured'
|
||||
}, function (err, body) {
|
||||
if (!err) this.setState({featuredCustom: body});
|
||||
}.bind(this));
|
||||
|
@ -172,16 +172,16 @@ var Splash = injectIntl(React.createClass({
|
|||
});
|
||||
},
|
||||
shouldShowWelcome: function () {
|
||||
if (!this.props.session.user || !this.props.session.flags.show_welcome) return false;
|
||||
if (!this.props.session.session.user || !this.props.session.session.flags.show_welcome) return false;
|
||||
return (
|
||||
new Date(this.props.session.user.dateJoined) >
|
||||
new Date(this.props.session.session.user.dateJoined) >
|
||||
new Date(new Date - 2*7*24*60*60*1000) // Two weeks ago
|
||||
);
|
||||
},
|
||||
shouldShowEmailConfirmation: function () {
|
||||
return (
|
||||
this.props.session.user && this.props.session.flags.has_outstanding_email_confirmation &&
|
||||
this.props.session.flags.confirm_email_banner);
|
||||
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;
|
||||
|
@ -206,7 +206,7 @@ var Splash = injectIntl(React.createClass({
|
|||
|
||||
if (this.state.featuredGlobal.curator_top_projects &&
|
||||
this.state.featuredGlobal.curator_top_projects.length > 4) {
|
||||
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
key="curator_top_projects"
|
||||
|
@ -223,7 +223,7 @@ var Splash = injectIntl(React.createClass({
|
|||
|
||||
if (this.state.featuredGlobal.scratch_design_studio &&
|
||||
this.state.featuredGlobal.scratch_design_studio.length > 4) {
|
||||
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
key="scratch_design_studio"
|
||||
|
@ -240,10 +240,10 @@ var Splash = injectIntl(React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
if (this.props.session.user &&
|
||||
if (this.props.session.session.user &&
|
||||
this.state.featuredGlobal.community_newest_projects &&
|
||||
this.state.featuredGlobal.community_newest_projects.length > 0) {
|
||||
|
||||
|
||||
rows.push(
|
||||
<Box
|
||||
title={
|
||||
|
@ -259,14 +259,14 @@ var Splash = injectIntl(React.createClass({
|
|||
|
||||
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',
|
||||
defaultMessage: 'Projects by Scratchers I\'m Following'})}
|
||||
key="custom_projects_by_following">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_by_following} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -280,7 +280,7 @@ var Splash = injectIntl(React.createClass({
|
|||
id: 'splash.projectsLovedByScratchersFollowing',
|
||||
defaultMessage: 'Projects Loved by Scratchers I\'m Following'})}
|
||||
key="custom_projects_loved_by_following">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_loved_by_following} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -288,14 +288,14 @@ var Splash = injectIntl(React.createClass({
|
|||
|
||||
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',
|
||||
defaultMessage: 'Projects in Studios I\'m Following'})}
|
||||
key="custom_projects_in_studios_following">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_in_studios_following} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -307,7 +307,7 @@ var Splash = injectIntl(React.createClass({
|
|||
id: 'splash.communityRemixing',
|
||||
defaultMessage: 'What the Community is Remixing' })}
|
||||
key="community_most_remixed_projects">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredGlobal.community_most_remixed_projects} showRemixes={true} />
|
||||
</Box>,
|
||||
<Box title={
|
||||
|
@ -315,7 +315,7 @@ var Splash = injectIntl(React.createClass({
|
|||
id: 'splash.communityLoving',
|
||||
defaultMessage: 'What the Community is Loving' })}
|
||||
key="community_most_loved_projects">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredGlobal.community_most_loved_projects} showLoves={true} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -373,20 +373,22 @@ var Splash = injectIntl(React.createClass({
|
|||
] : []}
|
||||
<CNBanner />
|
||||
<div key="inner" className="inner">
|
||||
{this.props.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>
|
||||
] : [
|
||||
<Intro projectCount={this.state.projectCount} messages={messages} key="intro"/>
|
||||
]}
|
||||
{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>
|
||||
] : [
|
||||
<Intro projectCount={this.state.projectCount} messages={messages} key="intro"/>
|
||||
]) : []
|
||||
}
|
||||
|
||||
{featured}
|
||||
|
||||
|
|
Loading…
Reference in a new issue