bigbuffet-rw/app/soapbox/features/chats/components/chat_list.js

100 lines
2.8 KiB
JavaScript
Raw Normal View History

import { debounce } from 'lodash';
2020-08-24 19:26:42 -07:00
import PropTypes from 'prop-types';
import React from 'react';
2021-07-01 16:01:33 -07:00
import ImmutablePropTypes from 'react-immutable-proptypes';
2020-08-24 19:26:42 -07:00
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
2022-01-10 14:01:24 -08:00
import { createSelector } from 'reselect';
import { expandChats } from 'soapbox/actions/chats';
import ScrollableList from 'soapbox/components/scrollable_list';
import PlaceholderChat from 'soapbox/features/placeholder/components/placeholder_chat';
import Chat from './chat';
2021-07-01 16:14:40 -07:00
const messages = defineMessages({
emptyMessage: { id: 'chat_panels.main_window.empty', defaultMessage: 'No chats found. To start a chat, visit a user\'s profile' },
});
2021-07-01 16:14:40 -07:00
const getSortedChatIds = chats => (
chats
.toList()
.sort(chatDateComparator)
.map(chat => chat.get('id'))
);
2020-08-24 19:26:42 -07:00
2020-08-27 13:07:15 -07:00
const chatDateComparator = (chatA, chatB) => {
// Sort most recently updated chats at the top
const a = new Date(chatA.get('updated_at'));
const b = new Date(chatB.get('updated_at'));
if (a === b) return 0;
if (a > b) return -1;
if (a < b) return 1;
return 0;
};
2021-07-01 16:14:40 -07:00
const makeMapStateToProps = () => {
const sortedChatIdsSelector = createSelector(
[getSortedChatIds],
chats => chats,
);
2020-08-27 13:43:19 -07:00
2021-07-01 16:14:40 -07:00
const mapStateToProps = state => ({
chatIds: sortedChatIdsSelector(state.getIn(['chats', 'items'])),
hasMore: !!state.getIn(['chats', 'next']),
isLoading: state.getIn(['chats', 'loading']),
2021-07-01 16:14:40 -07:00
});
return mapStateToProps;
2020-08-25 10:38:21 -07:00
};
2020-08-24 19:26:42 -07:00
2021-07-01 16:14:40 -07:00
export default @connect(makeMapStateToProps)
2020-08-24 19:26:42 -07:00
@injectIntl
class ChatList extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
2021-07-01 16:01:33 -07:00
chatIds: ImmutablePropTypes.list,
2020-08-25 15:24:47 -07:00
onClickChat: PropTypes.func,
onRefresh: PropTypes.func,
hasMore: PropTypes.func,
isLoading: PropTypes.bool,
2020-08-24 19:26:42 -07:00
};
handleLoadMore = debounce(() => {
this.props.dispatch(expandChats());
}, 300, { leading: true });
2020-08-24 19:26:42 -07:00
render() {
const { intl, chatIds, hasMore, isLoading } = this.props;
2020-08-24 19:26:42 -07:00
return (
<ScrollableList
className='chat-list'
scrollKey='awaiting-approval'
emptyMessage={intl.formatMessage(messages.emptyMessage)}
hasMore={hasMore}
isLoading={isLoading}
showLoading={isLoading && chatIds.size === 0}
onLoadMore={this.handleLoadMore}
onRefresh={this.props.onRefresh}
placeholderComponent={PlaceholderChat}
placeholderCount={20}
>
{chatIds.map(chatId => (
<div key={chatId} className='chat-list-item'>
<Chat
chatId={chatId}
onClick={this.props.onClickChat}
/>
</div>
))}
</ScrollableList>
2020-08-24 19:26:42 -07:00
);
}
}