diff options
Diffstat (limited to 'app/assets/javascripts/notes/mixins/discussion_navigation.js')
-rw-r--r-- | app/assets/javascripts/notes/mixins/discussion_navigation.js | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/app/assets/javascripts/notes/mixins/discussion_navigation.js b/app/assets/javascripts/notes/mixins/discussion_navigation.js index 96974c4fa2d..ad529eb99b6 100644 --- a/app/assets/javascripts/notes/mixins/discussion_navigation.js +++ b/app/assets/javascripts/notes/mixins/discussion_navigation.js @@ -1,7 +1,10 @@ import { mapGetters, mapActions, mapState } from 'vuex'; import { scrollToElementWithContext, scrollToElement } from '~/lib/utils/common_utils'; +import { updateHistory } from '../../lib/utils/url_utility'; import eventHub from '../event_hub'; +const isDiffsVirtualScrollingEnabled = () => window.gon?.features?.diffsVirtualScrolling; + /** * @param {string} selector * @returns {boolean} @@ -11,20 +14,52 @@ function scrollTo(selector, { withoutContext = false } = {}) { const scrollFunction = withoutContext ? scrollToElement : scrollToElementWithContext; if (el) { - scrollFunction(el); + scrollFunction(el, { + behavior: isDiffsVirtualScrollingEnabled() ? 'auto' : 'smooth', + }); return true; } return false; } +function updateUrlWithNoteId(noteId) { + const newHistoryEntry = { + state: null, + title: window.title, + url: `#note_${noteId}`, + replace: true, + }; + + if (noteId && isDiffsVirtualScrollingEnabled()) { + // Temporarily mask the ID to avoid the browser default + // scrolling taking over which is broken with virtual + // scrolling enabled. + const note = document.querySelector(`#note_${noteId}`); + note?.setAttribute('id', `masked::${note.id}`); + + // Update the hash now that the ID "doesn't exist" in the page + updateHistory(newHistoryEntry); + + // Unmask the note's ID + note?.setAttribute('id', `note_${noteId}`); + } else if (noteId) { + updateHistory(newHistoryEntry); + } +} + /** * @param {object} self Component instance with mixin applied * @param {string} id Discussion id we are jumping to */ -function diffsJump({ expandDiscussion }, id) { +function diffsJump({ expandDiscussion }, id, firstNoteId) { const selector = `ul.notes[data-discussion-id="${id}"]`; - eventHub.$once('scrollToDiscussion', () => scrollTo(selector)); + + eventHub.$once('scrollToDiscussion', () => { + scrollTo(selector); + // Wait for the discussion scroll before updating to the more specific ID + setTimeout(() => updateUrlWithNoteId(firstNoteId), 0); + }); expandDiscussion({ discussionId: id }); } @@ -56,12 +91,13 @@ function switchToDiscussionsTabAndJumpTo(self, id) { * @param {object} discussion Discussion we are jumping to */ function jumpToDiscussion(self, discussion) { - const { id, diff_discussion: isDiffDiscussion } = discussion; + const { id, diff_discussion: isDiffDiscussion, notes } = discussion; + const firstNoteId = notes?.[0]?.id; if (id) { const activeTab = window.mrTabs.currentAction; if (activeTab === 'diffs' && isDiffDiscussion) { - diffsJump(self, id); + diffsJump(self, id, firstNoteId); } else if (activeTab === 'show') { discussionJump(self, id); } else { @@ -79,10 +115,18 @@ function handleDiscussionJump(self, fn, discussionId = self.currentDiscussionId) const isDiffView = window.mrTabs.currentAction === 'diffs'; const targetId = fn(discussionId, isDiffView); const discussion = self.getDiscussion(targetId); + const setHash = !isDiffView && !isDiffsVirtualScrollingEnabled(); const discussionFilePath = discussion?.diff_file?.file_path; + if (isDiffsVirtualScrollingEnabled()) { + window.location.hash = ''; + } + if (discussionFilePath) { - self.scrollToFile(discussionFilePath); + self.scrollToFile({ + path: discussionFilePath, + setHash, + }); } self.$nextTick(() => { |