Chats: fix pagination bugs, use flex column-reverse

better-thread-display
Alex Gleason 2020-09-04 17:19:26 -05:00
rodzic 8e6a662fbb
commit c595e393da
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
2 zmienionych plików z 29 dodań i 10 usunięć

Wyświetl plik

@ -10,6 +10,8 @@ import emojify from 'soapbox/features/emoji/emoji';
import classNames from 'classnames'; import classNames from 'classnames';
import { escape, throttle } from 'lodash'; import { escape, throttle } from 'lodash';
const scrollBottom = (elem) => elem.scrollHeight - elem.offsetHeight - elem.scrollTop;
const makeEmojiMap = record => record.get('emojis', ImmutableList()).reduce((map, emoji) => { const makeEmojiMap = record => record.get('emojis', ImmutableList()).reduce((map, emoji) => {
return map.set(`:${emoji.get('shortcode')}:`, emoji); return map.set(`:${emoji.get('shortcode')}:`, emoji);
}, ImmutableMap()); }, ImmutableMap());
@ -19,7 +21,7 @@ const mapStateToProps = (state, { chatMessageIds }) => ({
chatMessages: chatMessageIds.reduce((acc, curr) => { chatMessages: chatMessageIds.reduce((acc, curr) => {
const chatMessage = state.getIn(['chat_messages', curr]); const chatMessage = state.getIn(['chat_messages', curr]);
return chatMessage ? acc.push(chatMessage) : acc; return chatMessage ? acc.push(chatMessage) : acc;
}, ImmutableList()).sort(), }, ImmutableList()).sort().reverse(),
}); });
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@ -39,6 +41,10 @@ class ChatMessageList extends ImmutablePureComponent {
chatMessages: ImmutableList(), chatMessages: ImmutableList(),
} }
state = {
isLoading: false,
}
scrollToBottom = () => { scrollToBottom = () => {
if (!this.messagesEnd) return; if (!this.messagesEnd) return;
this.messagesEnd.scrollIntoView(); this.messagesEnd.scrollIntoView();
@ -46,7 +52,6 @@ class ChatMessageList extends ImmutablePureComponent {
setMessageEndRef = (el) => { setMessageEndRef = (el) => {
this.messagesEnd = el; this.messagesEnd = el;
this.scrollToBottom();
}; };
getFormattedTimestamp = (chatMessage) => { getFormattedTimestamp = (chatMessage) => {
@ -75,11 +80,19 @@ class ChatMessageList extends ImmutablePureComponent {
} }
componentDidMount() { componentDidMount() {
this.node.addEventListener('scroll', this.handleScroll);
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if (prevProps.chatMessages !== this.props.chatMessages) const oldCount = prevProps.chatMessages.count();
this.scrollToBottom(); const newCount = this.props.chatMessages.count();
const isNearBottom = scrollBottom(this.node) < 150;
const historyAdded = prevProps.chatMessages.getIn([-1, 'id']) !== this.props.chatMessages.getIn([-1, 'id']);
if (oldCount !== newCount) {
if (isNearBottom) this.scrollToBottom();
if (historyAdded) this.setState({ isLoading: false });
}
} }
componentWillUnmount() { componentWillUnmount() {
@ -87,13 +100,14 @@ class ChatMessageList extends ImmutablePureComponent {
} }
handleLoadMore = () => { handleLoadMore = () => {
const { dispatch, chatId, chatMessageIds } = this.props; const { dispatch, chatId, chatMessages } = this.props;
const maxId = chatMessageIds.last(); const maxId = chatMessages.getIn([-1, 'id']);
dispatch(fetchChatMessages(chatId, maxId)); dispatch(fetchChatMessages(chatId, maxId));
this.setState({ isLoading: true });
} }
handleScroll = throttle(() => { handleScroll = throttle(() => {
if (this.node.scrollTop < 100) this.handleLoadMore(); if (this.node.scrollTop < 150 && !this.state.isLoading) this.handleLoadMore();
}, 150, { }, 150, {
trailing: true, trailing: true,
}); });
@ -112,7 +126,6 @@ class ChatMessageList extends ImmutablePureComponent {
setRef = (c) => { setRef = (c) => {
this.node = c; this.node = c;
this.node.addEventListener('scroll', this.handleScroll);
} }
render() { render() {
@ -120,6 +133,7 @@ class ChatMessageList extends ImmutablePureComponent {
return ( return (
<div className='chat-messages' ref={this.setRef}> <div className='chat-messages' ref={this.setRef}>
<div style={{ float: 'left', clear: 'both' }} ref={this.setMessageEndRef} />
{chatMessages.map(chatMessage => ( {chatMessages.map(chatMessage => (
<div <div
className={classNames('chat-message', { className={classNames('chat-message', {
@ -136,7 +150,6 @@ class ChatMessageList extends ImmutablePureComponent {
/> />
</div> </div>
))} ))}
<div style={{ float: 'left', clear: 'both' }} ref={this.setMessageEndRef} />
</div> </div>
); );
} }

Wyświetl plik

@ -99,12 +99,18 @@
.chat-messages { .chat-messages {
overflow-y: scroll; overflow-y: scroll;
flex: 1; flex: 1;
display: flex;
flex-direction: column-reverse;
} }
.chat-message { .chat-message {
margin: 14px 10px; padding: 7px 10px;
display: flex; display: flex;
&:last-child {
padding-top: 14px;
}
&__bubble { &__bubble {
font-size: 15px; font-size: 15px;
padding: 4px 10px; padding: 4px 10px;