From 9247f37e75abd41c1338ef5cbc73fa54203d03e2 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 7 Sep 2020 16:07:05 -0500 Subject: [PATCH] Chats: fix #399 scrolling in FireFox --- .../chats/components/chat_message_list.js | 40 ++++++++++++++----- app/soapbox/reducers/chat_message_lists.js | 4 +- app/styles/chats.scss | 8 +--- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/app/soapbox/features/chats/components/chat_message_list.js b/app/soapbox/features/chats/components/chat_message_list.js index 2ff423143..826f23b6b 100644 --- a/app/soapbox/features/chats/components/chat_message_list.js +++ b/app/soapbox/features/chats/components/chat_message_list.js @@ -13,8 +13,6 @@ import { escape, throttle } from 'lodash'; import { MediaGallery } from 'soapbox/features/ui/util/async-components'; import Bundle from 'soapbox/features/ui/components/bundle'; -const scrollBottom = (elem) => elem.scrollHeight - elem.offsetHeight - elem.scrollTop; - const makeEmojiMap = record => record.get('emojis', ImmutableList()).reduce((map, emoji) => { return map.set(`:${emoji.get('shortcode')}:`, emoji); }, ImmutableMap()); @@ -45,12 +43,13 @@ class ChatMessageList extends ImmutablePureComponent { } state = { + initialLoad: true, isLoading: false, } scrollToBottom = () => { if (!this.messagesEnd) return; - this.messagesEnd.scrollIntoView(); + this.messagesEnd.scrollIntoView(false); } setMessageEndRef = (el) => { @@ -82,22 +81,40 @@ class ChatMessageList extends ImmutablePureComponent { }); } + isNearBottom = () => { + const elem = this.node; + if (!elem) return false; + + const scrollBottom = elem.scrollHeight - elem.offsetHeight - elem.scrollTop; + return scrollBottom < elem.offsetHeight * 1.5; + } + componentDidMount() { const { dispatch, chatId } = this.props; dispatch(fetchChatMessages(chatId)); this.node.addEventListener('scroll', this.handleScroll); + this.scrollToBottom(); } - componentDidUpdate(prevProps) { + getSnapshotBeforeUpdate(prevProps, prevState) { + const { scrollHeight, scrollTop } = this.node; + return scrollHeight - scrollTop; + } + + componentDidUpdate(prevProps, prevState, scrollBottom) { + const { initialLoad } = this.state; const oldCount = prevProps.chatMessages.count(); 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']); + const isNearBottom = this.isNearBottom(); + const historyAdded = prevProps.chatMessages.getIn([0, 'id']) !== this.props.chatMessages.getIn([0, 'id']); + + // Retain scroll bar position when loading old messages + this.node.scrollTop = this.node.scrollHeight - scrollBottom; if (oldCount !== newCount) { - if (isNearBottom) this.scrollToBottom(); - if (historyAdded) this.setState({ isLoading: false }); + if (isNearBottom || initialLoad) this.scrollToBottom(); + if (historyAdded) this.setState({ isLoading: false, initialLoad: false }); } } @@ -107,13 +124,14 @@ class ChatMessageList extends ImmutablePureComponent { handleLoadMore = () => { const { dispatch, chatId, chatMessages } = this.props; - const maxId = chatMessages.getIn([-1, 'id']); + const maxId = chatMessages.getIn([0, 'id']); dispatch(fetchChatMessages(chatId, maxId)); this.setState({ isLoading: true }); } handleScroll = throttle(() => { - if (this.node.scrollTop < 150 && !this.state.isLoading) this.handleLoadMore(); + if (this.node.scrollTop < this.node.offsetHeight * 2 && !this.state.isLoading) + this.handleLoadMore(); }, 150, { trailing: true, }); @@ -159,7 +177,6 @@ class ChatMessageList extends ImmutablePureComponent { return (
-
{chatMessages.map(chatMessage => (
))} +
); } diff --git a/app/soapbox/reducers/chat_message_lists.js b/app/soapbox/reducers/chat_message_lists.js index b584dca72..3e2d1dbae 100644 --- a/app/soapbox/reducers/chat_message_lists.js +++ b/app/soapbox/reducers/chat_message_lists.js @@ -10,8 +10,8 @@ import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutabl const initialState = ImmutableMap(); const idComparator = (a, b) => { - if (a < b) return 1; - if (a > b) return -1; + if (a < b) return -1; + if (a > b) return 1; return 0; }; diff --git a/app/styles/chats.scss b/app/styles/chats.scss index 49719a638..c11f122f9 100644 --- a/app/styles/chats.scss +++ b/app/styles/chats.scss @@ -99,18 +99,12 @@ .chat-messages { overflow-y: scroll; flex: 1; - display: flex; - flex-direction: column-reverse; } .chat-message { - padding: 7px 10px; + margin: 14px 10px; display: flex; - &:last-child { - padding-top: 14px; - } - &__bubble { font-size: 15px; padding: 4px 10px;