-
-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#2548, #2430 - Fix chat scroll related bugs #2590
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -166,10 +166,13 @@ const onChatScroll = function () { | |||||
|
||||||
for (let i = this.messages.length - 1; i >= 0; i--) { | ||||||
const msg = this.messages[i] | ||||||
const msgEl = this.$refs[msg.hash][0].$el | ||||||
|
||||||
if (msg.pending || msg.hasFailed) continue | ||||||
const offsetTop = this.$refs[msg.hash][0].$el.offsetTop | ||||||
const offsetTop = msgEl.offsetTop | ||||||
// const parentOffsetTop = this.$refs[msg.hash][0].$el.offsetParent.offsetTop | ||||||
const height = this.$refs[msg.hash][0].$el.clientHeight | ||||||
const height = msgEl.clientHeight | ||||||
|
||||||
if (offsetTop + height <= curScrollBottom) { | ||||||
const bottomMessageCreatedHeight = msg.height | ||||||
const latestMessageCreatedHeight = this.currentChatRoomReadUntil?.createdHeight | ||||||
|
@@ -188,14 +191,14 @@ const onChatScroll = function () { | |||||
return | ||||||
} | ||||||
|
||||||
if (this.ephemeral.scrolledDistance > ignorableScrollDistanceInPixel) { | ||||||
if (curScrollTop > ignorableScrollDistanceInPixel) { | ||||||
Comment on lines
-191
to
+194
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is part of the fix for #2548 too. group-income/frontend/views/containers/chatroom/ChatMain.vue Lines 164 to 165 in 5b89d70
if (curScrollTop > ignorableScrollDistanceInPixel) { ... } ends up not getting executed for a couple of most recent messages, in some cases. I didn't go ahead and update |
||||||
// Save the current scroll position per each chatroom | ||||||
for (let i = 0; i < this.messages.length - 1; i++) { | ||||||
for (let i = 0; i <= this.messages.length - 1; i++) { | ||||||
const msg = this.messages[i] | ||||||
if (msg.pending || msg.hasFailed) continue | ||||||
const offsetTop = this.$refs[msg.hash][0].$el.offsetTop | ||||||
const scrollMarginTop = parseFloat(window.getComputedStyle(this.$refs[msg.hash][0].$el).scrollMarginTop || 0) | ||||||
if (offsetTop - scrollMarginTop > curScrollTop) { | ||||||
|
||||||
if (offsetTop > curScrollTop) { | ||||||
sbp('okTurtles.events/emit', NEW_CHATROOM_UNREAD_POSITION, { | ||||||
chatRoomID: this.nonReactive.renderingChatRoomId, | ||||||
messageHash: msg.hash | ||||||
|
@@ -257,6 +260,7 @@ export default ({ | |||||
// NOTE: messagesInitiated describes if the messages are fully re-rendered | ||||||
// according to this, we could display loading/skeleton component | ||||||
messagesInitiated: undefined, | ||||||
scrollHashOnInitialLoad: null, // Message hash to scroll to on chatroom's initial load | ||||||
replyingMessage: null, | ||||||
replyingTo: null, | ||||||
unprocessedEvents: [] | ||||||
|
@@ -544,25 +548,27 @@ export default ({ | |||||
|
||||||
const scrollAndHighlight = (index) => { | ||||||
const eleMessage = document.querySelectorAll('.c-body-conversation > .c-message')[index] | ||||||
const eleTarget = document.querySelectorAll('.c-body-conversation > .c-message')[Math.max(0, index - 1)] | ||||||
|
||||||
if (!eleTarget) { return } | ||||||
if (!eleMessage) { return } | ||||||
|
||||||
if (effect) { | ||||||
eleTarget.scrollIntoView({ behavior: this.isReducedMotionMode ? 'instant' : 'smooth' }) | ||||||
eleMessage.scrollIntoView({ behavior: this.isReducedMotionMode ? 'instant' : 'smooth' }) | ||||||
eleMessage.classList.add('c-focused') | ||||||
setTimeout(() => { | ||||||
eleMessage.classList.remove('c-focused') | ||||||
}, 1500) | ||||||
} else { | ||||||
eleTarget.scrollIntoView() | ||||||
eleMessage.scrollIntoView() | ||||||
Comment on lines
-552
to
+561
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part is the fix for #2548. (It's unclear what the original intention here was but) |
||||||
} | ||||||
} | ||||||
|
||||||
const msgIndex = findMessageIdx(messageHash, this.messages) | ||||||
if (msgIndex >= 0) { | ||||||
// if the message has already been loaded in the DOM, scroll to it. | ||||||
scrollAndHighlight(msgIndex) | ||||||
} else { | ||||||
// If the target message cannot be found in the current messages state, fetch more events | ||||||
// and render the older messages. | ||||||
const contractID = this.summary.chatRoomID | ||||||
const limit = this.chatRoomSettings?.actionsPerPage || CHATROOM_ACTIONS_PER_PAGE | ||||||
const events = | ||||||
|
@@ -858,23 +864,7 @@ export default ({ | |||||
|
||||||
if (!this.ephemeral.messagesInitiated) { | ||||||
this.setStartNewMessageIndex() | ||||||
|
||||||
// NOTE: we do want the 'c-focused' animation if there is a message-scroll query. | ||||||
if (events.length) { | ||||||
// NOTE: if 'messageHashToScroll' was not there in the messages of the contract state | ||||||
// we need to retrieve more events, and render to scroll to that message | ||||||
this.updateScroll(messageHashToScroll, Boolean(mhash)) | ||||||
} else { | ||||||
// NOTE: we need to scroll to the message first in order to no more infiniteHandler is called | ||||||
await this.updateScroll(messageHashToScroll, Boolean(mhash)) | ||||||
|
||||||
if (mhash) { | ||||||
// NOTE: delete mhash in the query after scroll and highlight the message with mhash | ||||||
const newQuery = { ...this.$route.query } | ||||||
delete newQuery.mhash | ||||||
this.$router.replace({ query: newQuery }) | ||||||
} | ||||||
} | ||||||
Comment on lines
-861
to
-877
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic here handles scrolling to a particular message after message states are initialized. And moving this logic to below |
||||||
this.ephemeral.scrollHashOnInitialLoad = messageHashToScroll | ||||||
} | ||||||
|
||||||
return events.length > 0 && GIMessage.deserializeHEAD(events[0]).head.height === 0 | ||||||
|
@@ -1090,6 +1080,7 @@ export default ({ | |||||
}, 40), | ||||||
infiniteHandler ($state) { | ||||||
this.ephemeral.infiniteLoading = $state | ||||||
|
||||||
if (this.ephemeral.messagesInitiated === undefined) { | ||||||
// NOTE: this infinite handler is being called once which should be ignored | ||||||
// before calling the setInitMessages function | ||||||
|
@@ -1105,6 +1096,7 @@ export default ({ | |||||
|
||||||
try { | ||||||
const completed = await this.renderMoreMessages() | ||||||
|
||||||
if (!this.checkEventSourceConsistency(chatRoomID)) return | ||||||
|
||||||
if (completed === true) { | ||||||
|
@@ -1129,9 +1121,30 @@ export default ({ | |||||
} else if (completed === false) { | ||||||
$state.loaded() | ||||||
} | ||||||
|
||||||
if (completed !== undefined && !this.ephemeral.messagesInitiated) { | ||||||
// NOTE: 'this.ephemeral.messagesInitiated' can be set true only when renderMoreMessages are successfully proceeded | ||||||
this.ephemeral.messagesInitiated = true | ||||||
|
||||||
if (this.ephemeral.scrollHashOnInitialLoad) { | ||||||
const scrollingToSpecificMessage = this.$route.query?.mhash === this.ephemeral.scrollHashOnInitialLoad | ||||||
|
||||||
this.$nextTick(() => { | ||||||
this.updateScroll( | ||||||
this.ephemeral.scrollHashOnInitialLoad, | ||||||
scrollingToSpecificMessage // NOTE: we do want the 'c-focused' animation if there is a scroll-to-message query. | ||||||
) | ||||||
|
||||||
// NOTE: delete mhash in the query after scroll and highlight the message with mhash | ||||||
if (scrollingToSpecificMessage) { | ||||||
const newQuery = { ...this.$route.query } | ||||||
delete newQuery.mhash | ||||||
this.$router.replace({ query: newQuery }) | ||||||
} | ||||||
|
||||||
this.ephemeral.scrollHashOnInitialLoad = null | ||||||
}) | ||||||
} | ||||||
} | ||||||
} catch (e) { | ||||||
console.error('ChatMain infiniteHandler() error:', e) | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DRYing reference to a particular message DOM element here.