Commit 18f82fce authored by Matthew Taylor's avatar Matthew Taylor

Merge branch 'issue/gh-1546' into develop

* issue/gh-1546:
  Make api request on filter change
  render load more even if messages not there

# Conflicts:
#	src/views/messages/container.jsx
#	src/views/messages/presentation.jsx
parents cfa55d98 361afaa9
var defaults = require('lodash.defaults');
var defaultsDeep = require('lodash.defaultsdeep'); var defaultsDeep = require('lodash.defaultsdeep');
var keyMirror = require('keymirror'); var keyMirror = require('keymirror');
...@@ -39,13 +40,11 @@ module.exports.messagesReducer = function (state, action) { ...@@ -39,13 +40,11 @@ module.exports.messagesReducer = function (state, action) {
switch (action.type) { switch (action.type) {
case 'SET_MESSAGES': case 'SET_MESSAGES':
return defaultsDeep({ state.messages.social = action.messages;
messages: {social: action.messages} return state;
}, state);
case 'SET_ADMIN_MESSAGES': case 'SET_ADMIN_MESSAGES':
return defaultsDeep({ state.messages.admin = action.messages;
messages: {admin: action.messages} return state;
}, state);
case 'SET_MESSAGES_OFFSET': case 'SET_MESSAGES_OFFSET':
return defaultsDeep({ return defaultsDeep({
messages: {socialOffset: action.offset} messages: {socialOffset: action.offset}
...@@ -194,17 +193,31 @@ module.exports.clearAdminMessage = function (messageType, messageId, messageCoun ...@@ -194,17 +193,31 @@ module.exports.clearAdminMessage = function (messageType, messageId, messageCoun
/** /**
* Gets a user's messages to be displayed on the /messages page * Gets a user's messages to be displayed on the /messages page
* @param {string} username username of the user for whom the messages should be gotten * @param {string} username username of the user for whom the messages should be gotten
* @param {string} token the user's unique token for auth * @param {string} token the user's unique token for auth
* @param {object[]} messages an array of existing messages on the page, if there are any * @param {object} opts optional args for the method
* @param {number} offset offset of messages to get, based on the number retrieved already * @param {object[]} [opts.messages] an array of existing messages on the page, if there are any
* @return {null} returns nothing * @param {number} [opts.offset] offset of messages to get, based on the number retrieved already
* @param {string} [opts.filter] type of messages to return
* @return {null} returns nothing
*/ */
module.exports.getMessages = function (username, token, messages, offset) { module.exports.getMessages = function (username, token, opts) {
opts = defaults(opts, {
messages: [],
offset: 0,
filter: '',
clearCount: true
});
var filterArg = '';
if (opts.filter.length > 0) {
filterArg = '&filter=' + opts.filter;
}
return function (dispatch) { return function (dispatch) {
dispatch(module.exports.setStatus('MESSAGE_STATUS', module.exports.Status.FETCHING)); dispatch(module.exports.setStatus('MESSAGE_STATUS', module.exports.Status.FETCHING));
api({ api({
uri: '/users/' + username + '/messages?limit=40&offset=' + offset, uri: '/users/' + username + '/messages?limit=40&offset=' + opts.offset + filterArg,
authentication: token authentication: token
}, function (err, body) { }, function (err, body) {
if (err) { if (err) {
...@@ -218,9 +231,11 @@ module.exports.getMessages = function (username, token, messages, offset) { ...@@ -218,9 +231,11 @@ module.exports.getMessages = function (username, token, messages, offset) {
return; return;
} }
dispatch(module.exports.setStatus('MESSAGE_STATUS', module.exports.Status.FETCHED)); dispatch(module.exports.setStatus('MESSAGE_STATUS', module.exports.Status.FETCHED));
dispatch(module.exports.setMessages(messages.concat(body))); dispatch(module.exports.setMessages(opts.messages.concat(body)));
dispatch(module.exports.setMessagesOffset(offset + 40)); dispatch(module.exports.setMessagesOffset(opts.offset + 40));
dispatch(module.exports.clearMessageCount(token)); // clear count once messages loaded if (opts.clearCount) {
dispatch(module.exports.clearMessageCount(token)); // clear count once messages loaded
}
}); });
}; };
}; };
......
...@@ -12,8 +12,7 @@ var Messages = React.createClass({ ...@@ -12,8 +12,7 @@ var Messages = React.createClass({
type: 'ConnectedMessages', type: 'ConnectedMessages',
getInitialState: function () { getInitialState: function () {
return { return {
filterValues: [], filter: ''
displayedMessages: []
}; };
}, },
getDefaultProps: function () { getDefaultProps: function () {
...@@ -26,14 +25,17 @@ var Messages = React.createClass({ ...@@ -26,14 +25,17 @@ var Messages = React.createClass({
}; };
}, },
componentDidUpdate: function (prevProps) { componentDidUpdate: function (prevProps) {
if (this.props.user != prevProps.user) { if (this.props.user.username !== prevProps.user.username) {
if (this.props.user.token) { if (this.props.user.token) {
this.props.dispatch( this.props.dispatch(
messageActions.getMessages( messageActions.getMessages(
this.props.user.username, this.props.user.username,
this.props.user.token, this.props.user.token,
this.props.messages, {
this.props.messageOffset messages: this.props.messages,
offset: this.props.messageOffset,
filter: this.state.filter
}
) )
); );
this.props.dispatch( this.props.dispatch(
...@@ -59,8 +61,11 @@ var Messages = React.createClass({ ...@@ -59,8 +61,11 @@ var Messages = React.createClass({
messageActions.getMessages( messageActions.getMessages(
this.props.user.username, this.props.user.username,
this.props.user.token, this.props.user.token,
this.props.messages, {
this.props.messageOffset messages: this.props.messages,
offset: this.props.messageOffset,
filter: this.state.filter
}
) )
); );
this.props.dispatch( this.props.dispatch(
...@@ -74,26 +79,19 @@ var Messages = React.createClass({ ...@@ -74,26 +79,19 @@ var Messages = React.createClass({
} }
}, },
handleFilterClick: function (field, choice) { handleFilterClick: function (field, choice) {
switch (choice) { if (this.props.user.token) {
case 'comments': this.props.dispatch(
return this.setState({filterValues: ['addcomment']}); messageActions.getMessages(
case 'projects': this.props.user.username,
return this.setState({filterValues: [ this.props.user.token,
'loveproject', {
'favoriteproject', filter: choice,
'remixproject' clearCount: false
]}); }
case 'studios': )
return this.setState({filterValues: [ );
'curatorinvite',
'studioactivity',
'becomeownerstudio'
]});
case 'forums':
return this.setState({filterValues: ['forumpost']});
default:
return this.setState({filterValues: []});
} }
this.setState({filter: choice});
}, },
handleMessageDismiss: function (messageType, messageId) { handleMessageDismiss: function (messageType, messageId) {
var adminMessages = null; var adminMessages = null;
...@@ -111,68 +109,35 @@ var Messages = React.createClass({ ...@@ -111,68 +109,35 @@ var Messages = React.createClass({
messageActions.getMessages( messageActions.getMessages(
this.props.user.username, this.props.user.username,
this.props.user.token, this.props.user.token,
this.props.messages, {
this.props.messageOffset messages: this.props.messages,
offset: this.props.messageOffset,
filter: this.state.filter,
clearCount: false
}
) )
); );
}, },
filterMessages: function (messages, typesAllowed, unreadCount) {
var filteredMessages = [];
if (typesAllowed.length > 0) {
for (var i in messages) {
// check to see if the position of the message in the list is earlier
// than the unread count. If it is, then the message is totally unread.
messages[i].unread = false;
if (i < unreadCount) messages[i].unread = true;
if (typesAllowed.indexOf(messages[i].type) > -1) {
filteredMessages.push(messages[i]);
}
}
} else {
filteredMessages = messages;
for (var j = 0; j < unreadCount; j++) {
if (typeof filteredMessages[j] !== 'undefined') {
filteredMessages[j].unread = true;
}
}
}
return filteredMessages;
},
render: function () { render: function () {
var loadMore = true; var loadMore = true;
if (this.props.messageOffset > this.props.messages.length && this.props.messageOffset > 0) { if (this.props.messageOffset > this.props.messages.length && this.props.messageOffset > 0) {
loadMore = false; loadMore = false;
} }
var adminMessagesLength = this.props.adminMessages.length;
if (Object.keys(this.props.invite).length > 0) {
adminMessagesLength = adminMessagesLength + 1;
}
var numNewSocialMessages = this.props.numNewMessages - adminMessagesLength;
if (numNewSocialMessages < 0) {
numNewSocialMessages = 0;
}
var messages = this.filterMessages(
this.props.messages,
this.state.filterValues,
numNewSocialMessages
);
return( return(
<MessagesPresentation <MessagesPresentation
sessionStatus={this.props.sessionStatus} sessionStatus={this.props.sessionStatus}
user={this.props.user} user={this.props.user}
messages={messages} messages={this.props.messages}
adminMessages={this.props.adminMessages} adminMessages={this.props.adminMessages}
scratcherInvite={this.props.invite} scratcherInvite={this.props.invite}
numNewMessages={numNewSocialMessages} numNewMessages={this.props.numNewSocialMessages}
adminMessagesLength={adminMessagesLength}
handleFilterClick={this.handleFilterClick} handleFilterClick={this.handleFilterClick}
handleAdminDismiss={this.handleMessageDismiss} handleAdminDismiss={this.handleMessageDismiss}
loadMore={loadMore} loadMore={loadMore}
loadMoreMethod={this.handleLoadMoreMessages} loadMoreMethod={this.handleLoadMoreMessages}
requestStatus={this.props.requestStatus} requestStatus={this.props.requestStatus}
filter={this.props.filter}
/> />
); );
} }
......
...@@ -42,8 +42,8 @@ var SocialMessagesList = React.createClass({ ...@@ -42,8 +42,8 @@ var SocialMessagesList = React.createClass({
numNewMessages: 0 numNewMessages: 0
}; };
}, },
getComponentForMessage: function (message) { getComponentForMessage: function (message, unread) {
var className = (message.unread === true) ? 'mod-unread' : ''; var className = (unread) ? 'mod-unread' : '';
var key = message.type + '_' + message.id; var key = message.type + '_' + message.id;
switch (message.type) { switch (message.type) {
...@@ -140,10 +140,14 @@ var SocialMessagesList = React.createClass({ ...@@ -140,10 +140,14 @@ var SocialMessagesList = React.createClass({
/>; />;
} }
}, },
renderSocialMessages: function (messages) { renderSocialMessages: function (messages, unreadCount) {
var messageList = []; var messageList = [];
for (var i in messages) { for (var i in messages) {
messageList.push(this.getComponentForMessage(messages[i])); if (i <= unreadCount) {
messageList.push(this.getComponentForMessage(messages[i], true));
} else {
messageList.push(this.getComponentForMessage(messages[i], false));
}
} }
return messageList; return messageList;
}, },
...@@ -191,10 +195,10 @@ var SocialMessagesList = React.createClass({ ...@@ -191,10 +195,10 @@ var SocialMessagesList = React.createClass({
</h4> </h4>
</div>, </div>,
<ul className="messages-social-list" key="messages-social-list"> <ul className="messages-social-list" key="messages-social-list">
{this.renderSocialMessages(this.props.messages)} {this.renderSocialMessages(this.props.messages, (this.props.numNewMessages - 1))}
</ul>, </ul>
this.renderLoadMore(this.props.loadMore)
] : []} ] : []}
{this.renderLoadMore(this.props.loadMore)}
</section> </section>
); );
} }
...@@ -209,21 +213,30 @@ var MessagesPresentation = injectIntl(React.createClass({ ...@@ -209,21 +213,30 @@ var MessagesPresentation = injectIntl(React.createClass({
adminMessages: React.PropTypes.array.isRequired, adminMessages: React.PropTypes.array.isRequired,
scratcherInvite: React.PropTypes.object.isRequired, scratcherInvite: React.PropTypes.object.isRequired,
numNewMessages: React.PropTypes.number, numNewMessages: React.PropTypes.number,
adminMessagesLength: React.PropTypes.number,
handleFilterClick: React.PropTypes.func.isRequired, handleFilterClick: React.PropTypes.func.isRequired,
handleAdminDismiss: React.PropTypes.func.isRequired, handleAdminDismiss: React.PropTypes.func.isRequired,
loadMore: React.PropTypes.bool.isRequired, loadMore: React.PropTypes.bool.isRequired,
loadMoreMethod: React.PropTypes.func, loadMoreMethod: React.PropTypes.func,
requestStatus: React.PropTypes.object.isRequired requestStatus: React.PropTypes.object.isRequired,
filter: React.PropTypes.string
}, },
getDefaultProps: function () { getDefaultProps: function () {
return { return {
numNewMessages: 0, numNewMessages: 0,
adminMessagesLength: 0, filterOpen: false,
filterOpen: false filter: ''
}; };
}, },
render: function () { render: function () {
var adminMessageLength = this.props.adminMessages.length;
if (Object.keys(this.props.scratcherInvite).length > 0) {
adminMessageLength = adminMessageLength + 1;
}
var numNewSocialMessages = this.props.numNewMessages - adminMessageLength;
if (numNewSocialMessages < 0) {
numNewSocialMessages = 0;
}
return ( return (
<div className="messages"> <div className="messages">
<TitleBanner className="mod-messages"> <TitleBanner className="mod-messages">
...@@ -259,6 +272,7 @@ var MessagesPresentation = injectIntl(React.createClass({ ...@@ -259,6 +272,7 @@ var MessagesPresentation = injectIntl(React.createClass({
value: 'forums' value: 'forums'
} }
]} ]}
value={this.props.filter}
/> />
</Form> </Form>
</div> </div>
...@@ -271,7 +285,7 @@ var MessagesPresentation = injectIntl(React.createClass({ ...@@ -271,7 +285,7 @@ var MessagesPresentation = injectIntl(React.createClass({
<h4 className="messages-header"> <h4 className="messages-header">
<FormattedMessage id='messages.scratchTeamTitle' /> <FormattedMessage id='messages.scratchTeamTitle' />
<div className="messages-header-unread"> <div className="messages-header-unread">
<FormattedNumber value={this.props.adminMessagesLength} /> <FormattedNumber value={adminMessageLength} />
</div> </div>
</h4> </h4>
</div> </div>
...@@ -311,7 +325,7 @@ var MessagesPresentation = injectIntl(React.createClass({ ...@@ -311,7 +325,7 @@ var MessagesPresentation = injectIntl(React.createClass({
<SocialMessagesList <SocialMessagesList
loadStatus={this.props.requestStatus.messages} loadStatus={this.props.requestStatus.messages}
messages={this.props.messages} messages={this.props.messages}
numNewMessages={this.props.numNewMessages} numNewMessages={numNewSocialMessages}
loadMore={this.props.loadMore} loadMore={this.props.loadMore}
loadMoreMethod={this.props.loadMoreMethod} loadMoreMethod={this.props.loadMoreMethod}
/> />
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment