From 9247f37e75abd41c1338ef5cbc73fa54203d03e2 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 7 Sep 2020 16:07:05 -0500 Subject: [PATCH 1/5] 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; From 54a772190d1402482bd1aac37ea6db387cd2a759 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 7 Sep 2020 16:10:45 -0500 Subject: [PATCH 2/5] Chats: fix send icon on light theme --- app/styles/chats.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/styles/chats.scss b/app/styles/chats.scss index c11f122f9..e524de2ab 100644 --- a/app/styles/chats.scss +++ b/app/styles/chats.scss @@ -219,6 +219,7 @@ position: relative; .icon-button { + color: var(--primary-text-color--faint); position: absolute; right: 10px; top: 8px; From fb35417fe226cd82edeb6d09809aa433bf808089 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 7 Sep 2020 18:42:59 -0500 Subject: [PATCH 3/5] Chats: prevent repeat API calls --- .../chats/components/chat_message_list.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/soapbox/features/chats/components/chat_message_list.js b/app/soapbox/features/chats/components/chat_message_list.js index 826f23b6b..48937518d 100644 --- a/app/soapbox/features/chats/components/chat_message_list.js +++ b/app/soapbox/features/chats/components/chat_message_list.js @@ -102,6 +102,11 @@ class ChatMessageList extends ImmutablePureComponent { return scrollHeight - scrollTop; } + restoreScrollPosition = (scrollBottom) => { + this.lastComputedScroll = this.node.scrollHeight - scrollBottom; + this.node.scrollTop = this.lastComputedScroll; + } + componentDidUpdate(prevProps, prevState, scrollBottom) { const { initialLoad } = this.state; const oldCount = prevProps.chatMessages.count(); @@ -110,7 +115,7 @@ class ChatMessageList extends ImmutablePureComponent { 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; + this.restoreScrollPosition(scrollBottom); if (oldCount !== newCount) { if (isNearBottom || initialLoad) this.scrollToBottom(); @@ -130,7 +135,13 @@ class ChatMessageList extends ImmutablePureComponent { } handleScroll = throttle(() => { - if (this.node.scrollTop < this.node.offsetHeight * 2 && !this.state.isLoading) + const { lastComputedScroll } = this; + const { isLoading, initialLoad } = this.state; + const { scrollTop, offsetHeight } = this.node; + const computedScroll = lastComputedScroll === scrollTop; + const nearTop = scrollTop < offsetHeight * 2; + + if (nearTop && !isLoading && !initialLoad && !computedScroll) this.handleLoadMore(); }, 150, { trailing: true, From fdaa9f24ce7f2a5898e80f8a4df24ba2d21ded1a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 7 Sep 2020 18:51:57 -0500 Subject: [PATCH 4/5] Chats: fix position of action icons --- app/styles/chats.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/styles/chats.scss b/app/styles/chats.scss index e524de2ab..d5cb4b361 100644 --- a/app/styles/chats.scss +++ b/app/styles/chats.scss @@ -222,7 +222,7 @@ color: var(--primary-text-color--faint); position: absolute; right: 10px; - top: 8px; + top: calc(50% - 13px); width: auto; height: auto; background: transparent !important; @@ -232,7 +232,7 @@ } .chat-box__send .icon-button { - top: 12px; + top: calc(50% - 9px); } textarea { From 255419a6e99eee42472e627658b08b7b6d0f0bda Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 7 Sep 2020 19:13:59 -0500 Subject: [PATCH 5/5] Chats: display attachments in a shitty letterbox to support FireFox --- .../chats/components/chat_message_list.js | 20 ++++++++++--------- app/styles/chats.scss | 8 ++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/app/soapbox/features/chats/components/chat_message_list.js b/app/soapbox/features/chats/components/chat_message_list.js index 48937518d..1cfc41442 100644 --- a/app/soapbox/features/chats/components/chat_message_list.js +++ b/app/soapbox/features/chats/components/chat_message_list.js @@ -155,15 +155,17 @@ class ChatMessageList extends ImmutablePureComponent { const attachment = chatMessage.get('attachment'); if (!attachment) return null; return ( - - {Component => ( - - )} - +
+ + {Component => ( + + )} + +
); } diff --git a/app/styles/chats.scss b/app/styles/chats.scss index d5cb4b361..29c2f0c4f 100644 --- a/app/styles/chats.scss +++ b/app/styles/chats.scss @@ -342,8 +342,12 @@ } } +.chat-message__media { + height: 120px; +} + .chat-message .media-gallery { - height: auto !important; + height: 100% !important; margin: 4px 0 8px; .spoiler-button { @@ -353,7 +357,7 @@ .media-gallery__item:not(.media-gallery__item--image) { max-width: 100%; width: 120px !important; - height: 70px !important; + height: 100% !important; } &__preview {