mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 00:21:20 -05:00
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
This commit is contained in:
commit
18f82fce3f
3 changed files with 91 additions and 97 deletions
|
@ -1,3 +1,4 @@
|
|||
var defaults = require('lodash.defaults');
|
||||
var defaultsDeep = require('lodash.defaultsdeep');
|
||||
var keyMirror = require('keymirror');
|
||||
|
||||
|
@ -39,13 +40,11 @@ module.exports.messagesReducer = function (state, action) {
|
|||
|
||||
switch (action.type) {
|
||||
case 'SET_MESSAGES':
|
||||
return defaultsDeep({
|
||||
messages: {social: action.messages}
|
||||
}, state);
|
||||
state.messages.social = action.messages;
|
||||
return state;
|
||||
case 'SET_ADMIN_MESSAGES':
|
||||
return defaultsDeep({
|
||||
messages: {admin: action.messages}
|
||||
}, state);
|
||||
state.messages.admin = action.messages;
|
||||
return state;
|
||||
case 'SET_MESSAGES_OFFSET':
|
||||
return defaultsDeep({
|
||||
messages: {socialOffset: action.offset}
|
||||
|
@ -194,17 +193,31 @@ module.exports.clearAdminMessage = function (messageType, messageId, messageCoun
|
|||
|
||||
/**
|
||||
* 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} token the user's unique token for auth
|
||||
* @param {object[]} messages an array of existing messages on the page, if there are any
|
||||
* @param {number} offset offset of messages to get, based on the number retrieved already
|
||||
* @return {null} returns nothing
|
||||
* @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 {object} opts optional args for the method
|
||||
* @param {object[]} [opts.messages] an array of existing messages on the page, if there are any
|
||||
* @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) {
|
||||
dispatch(module.exports.setStatus('MESSAGE_STATUS', module.exports.Status.FETCHING));
|
||||
api({
|
||||
uri: '/users/' + username + '/messages?limit=40&offset=' + offset,
|
||||
uri: '/users/' + username + '/messages?limit=40&offset=' + opts.offset + filterArg,
|
||||
authentication: token
|
||||
}, function (err, body) {
|
||||
if (err) {
|
||||
|
@ -218,9 +231,11 @@ module.exports.getMessages = function (username, token, messages, offset) {
|
|||
return;
|
||||
}
|
||||
dispatch(module.exports.setStatus('MESSAGE_STATUS', module.exports.Status.FETCHED));
|
||||
dispatch(module.exports.setMessages(messages.concat(body)));
|
||||
dispatch(module.exports.setMessagesOffset(offset + 40));
|
||||
dispatch(module.exports.clearMessageCount(token)); // clear count once messages loaded
|
||||
dispatch(module.exports.setMessages(opts.messages.concat(body)));
|
||||
dispatch(module.exports.setMessagesOffset(opts.offset + 40));
|
||||
if (opts.clearCount) {
|
||||
dispatch(module.exports.clearMessageCount(token)); // clear count once messages loaded
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,8 +12,7 @@ var Messages = React.createClass({
|
|||
type: 'ConnectedMessages',
|
||||
getInitialState: function () {
|
||||
return {
|
||||
filterValues: [],
|
||||
displayedMessages: []
|
||||
filter: ''
|
||||
};
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
|
@ -26,14 +25,17 @@ var Messages = React.createClass({
|
|||
};
|
||||
},
|
||||
componentDidUpdate: function (prevProps) {
|
||||
if (this.props.user != prevProps.user) {
|
||||
if (this.props.user.username !== prevProps.user.username) {
|
||||
if (this.props.user.token) {
|
||||
this.props.dispatch(
|
||||
messageActions.getMessages(
|
||||
this.props.user.username,
|
||||
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(
|
||||
|
@ -59,8 +61,11 @@ var Messages = React.createClass({
|
|||
messageActions.getMessages(
|
||||
this.props.user.username,
|
||||
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(
|
||||
|
@ -74,26 +79,19 @@ var Messages = React.createClass({
|
|||
}
|
||||
},
|
||||
handleFilterClick: function (field, choice) {
|
||||
switch (choice) {
|
||||
case 'comments':
|
||||
return this.setState({filterValues: ['addcomment']});
|
||||
case 'projects':
|
||||
return this.setState({filterValues: [
|
||||
'loveproject',
|
||||
'favoriteproject',
|
||||
'remixproject'
|
||||
]});
|
||||
case 'studios':
|
||||
return this.setState({filterValues: [
|
||||
'curatorinvite',
|
||||
'studioactivity',
|
||||
'becomeownerstudio'
|
||||
]});
|
||||
case 'forums':
|
||||
return this.setState({filterValues: ['forumpost']});
|
||||
default:
|
||||
return this.setState({filterValues: []});
|
||||
if (this.props.user.token) {
|
||||
this.props.dispatch(
|
||||
messageActions.getMessages(
|
||||
this.props.user.username,
|
||||
this.props.user.token,
|
||||
{
|
||||
filter: choice,
|
||||
clearCount: false
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
this.setState({filter: choice});
|
||||
},
|
||||
handleMessageDismiss: function (messageType, messageId) {
|
||||
var adminMessages = null;
|
||||
|
@ -111,68 +109,35 @@ var Messages = React.createClass({
|
|||
messageActions.getMessages(
|
||||
this.props.user.username,
|
||||
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 () {
|
||||
var loadMore = true;
|
||||
if (this.props.messageOffset > this.props.messages.length && this.props.messageOffset > 0) {
|
||||
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(
|
||||
<MessagesPresentation
|
||||
sessionStatus={this.props.sessionStatus}
|
||||
user={this.props.user}
|
||||
messages={messages}
|
||||
messages={this.props.messages}
|
||||
adminMessages={this.props.adminMessages}
|
||||
scratcherInvite={this.props.invite}
|
||||
numNewMessages={numNewSocialMessages}
|
||||
adminMessagesLength={adminMessagesLength}
|
||||
numNewMessages={this.props.numNewSocialMessages}
|
||||
handleFilterClick={this.handleFilterClick}
|
||||
handleAdminDismiss={this.handleMessageDismiss}
|
||||
loadMore={loadMore}
|
||||
loadMoreMethod={this.handleLoadMoreMessages}
|
||||
requestStatus={this.props.requestStatus}
|
||||
filter={this.props.filter}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ var SocialMessagesList = React.createClass({
|
|||
numNewMessages: 0
|
||||
};
|
||||
},
|
||||
getComponentForMessage: function (message) {
|
||||
var className = (message.unread === true) ? 'mod-unread' : '';
|
||||
getComponentForMessage: function (message, unread) {
|
||||
var className = (unread) ? 'mod-unread' : '';
|
||||
var key = message.type + '_' + message.id;
|
||||
|
||||
switch (message.type) {
|
||||
|
@ -140,10 +140,14 @@ var SocialMessagesList = React.createClass({
|
|||
/>;
|
||||
}
|
||||
},
|
||||
renderSocialMessages: function (messages) {
|
||||
renderSocialMessages: function (messages, unreadCount) {
|
||||
var messageList = [];
|
||||
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;
|
||||
},
|
||||
|
@ -191,10 +195,10 @@ var SocialMessagesList = React.createClass({
|
|||
</h4>
|
||||
</div>,
|
||||
<ul className="messages-social-list" key="messages-social-list">
|
||||
{this.renderSocialMessages(this.props.messages)}
|
||||
</ul>,
|
||||
this.renderLoadMore(this.props.loadMore)
|
||||
{this.renderSocialMessages(this.props.messages, (this.props.numNewMessages - 1))}
|
||||
</ul>
|
||||
] : []}
|
||||
{this.renderLoadMore(this.props.loadMore)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
@ -209,21 +213,30 @@ var MessagesPresentation = injectIntl(React.createClass({
|
|||
adminMessages: React.PropTypes.array.isRequired,
|
||||
scratcherInvite: React.PropTypes.object.isRequired,
|
||||
numNewMessages: React.PropTypes.number,
|
||||
adminMessagesLength: React.PropTypes.number,
|
||||
handleFilterClick: React.PropTypes.func.isRequired,
|
||||
handleAdminDismiss: React.PropTypes.func.isRequired,
|
||||
loadMore: React.PropTypes.bool.isRequired,
|
||||
loadMoreMethod: React.PropTypes.func,
|
||||
requestStatus: React.PropTypes.object.isRequired
|
||||
requestStatus: React.PropTypes.object.isRequired,
|
||||
filter: React.PropTypes.string
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
numNewMessages: 0,
|
||||
adminMessagesLength: 0,
|
||||
filterOpen: false
|
||||
filterOpen: false,
|
||||
filter: ''
|
||||
};
|
||||
},
|
||||
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 (
|
||||
<div className="messages">
|
||||
<TitleBanner className="mod-messages">
|
||||
|
@ -259,6 +272,7 @@ var MessagesPresentation = injectIntl(React.createClass({
|
|||
value: 'forums'
|
||||
}
|
||||
]}
|
||||
value={this.props.filter}
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
|
@ -271,7 +285,7 @@ var MessagesPresentation = injectIntl(React.createClass({
|
|||
<h4 className="messages-header">
|
||||
<FormattedMessage id='messages.scratchTeamTitle' />
|
||||
<div className="messages-header-unread">
|
||||
<FormattedNumber value={this.props.adminMessagesLength} />
|
||||
<FormattedNumber value={adminMessageLength} />
|
||||
</div>
|
||||
</h4>
|
||||
</div>
|
||||
|
@ -311,7 +325,7 @@ var MessagesPresentation = injectIntl(React.createClass({
|
|||
<SocialMessagesList
|
||||
loadStatus={this.props.requestStatus.messages}
|
||||
messages={this.props.messages}
|
||||
numNewMessages={this.props.numNewMessages}
|
||||
numNewMessages={numNewSocialMessages}
|
||||
loadMore={this.props.loadMore}
|
||||
loadMoreMethod={this.props.loadMoreMethod}
|
||||
/>
|
||||
|
|
Loading…
Reference in a new issue