diff options
Diffstat (limited to 'app/assets/javascripts/notes/mixins/discussion_navigation.js')
-rw-r--r-- | app/assets/javascripts/notes/mixins/discussion_navigation.js | 156 |
1 files changed, 16 insertions, 140 deletions
diff --git a/app/assets/javascripts/notes/mixins/discussion_navigation.js b/app/assets/javascripts/notes/mixins/discussion_navigation.js index db5f9ebf3f0..d75a4158440 100644 --- a/app/assets/javascripts/notes/mixins/discussion_navigation.js +++ b/app/assets/javascripts/notes/mixins/discussion_navigation.js @@ -1,136 +1,12 @@ import { mapGetters, mapActions, mapState } from 'vuex'; -import { scrollToElementWithContext, scrollToElement, contentTop } from '~/lib/utils/common_utils'; -import { updateHistory } from '~/lib/utils/url_utility'; -import eventHub from '../event_hub'; - -/** - * @param {string} selector - * @returns {boolean} - */ -function scrollTo(selector, { withoutContext = false, offset = 0 } = {}) { - const el = document.querySelector(selector); - const scrollFunction = withoutContext ? scrollToElement : scrollToElementWithContext; - - if (el) { - scrollFunction(el, { - behavior: 'auto', - offset, - }); - return true; - } - - return false; -} - -function updateUrlWithNoteId(noteId) { - const newHistoryEntry = { - state: null, - title: window.title, - url: `#note_${noteId}`, - replace: true, - }; - - if (noteId) { - // 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}`); - } -} - -/** - * @param {object} self Component instance with mixin applied - * @param {string} id Discussion id we are jumping to - */ -function diffsJump({ expandDiscussion }, id, firstNoteId) { - const selector = `ul.notes[data-discussion-id="${id}"]`; - - eventHub.$once('scrollToDiscussion', () => { - scrollTo(selector); - // Wait for the discussion scroll before updating to the more specific ID - setTimeout(() => updateUrlWithNoteId(firstNoteId), 0); - }); - expandDiscussion({ discussionId: id }); -} - -/** - * @param {object} self Component instance with mixin applied - * @param {string} id Discussion id we are jumping to - * @returns {boolean} - */ -function discussionJump({ expandDiscussion }, id) { - const selector = `div.discussion[data-discussion-id="${id}"]`; - expandDiscussion({ discussionId: id }); - return scrollTo(selector, { - withoutContext: true, - offset: window.gon?.features?.movedMrSidebar ? -28 : 0, - }); -} - -/** - * @param {object} self Component instance with mixin applied - * @param {string} id Discussion id we are jumping to - */ -function switchToDiscussionsTabAndJumpTo(self, id) { - window.mrTabs.eventHub.$once('MergeRequestTabChange', () => { - setTimeout(() => discussionJump(self, id), 0); - }); - - window.mrTabs.tabShown('show'); -} - -/** - * @param {object} self Component instance with mixin applied - * @param {object} discussion Discussion we are jumping to - */ -function jumpToDiscussion(self, 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, firstNoteId); - } else { - switchToDiscussionsTabAndJumpTo(self, id); - } - } -} - -/** - * @param {object} self Component instance with mixin applied - * @param {function} fn Which function used to get the target discussion's id - */ -function handleDiscussionJump(self, fn) { - const isDiffView = window.mrTabs.currentAction === 'diffs'; - const targetId = fn(self.currentDiscussionId, isDiffView); - const discussion = self.getDiscussion(targetId); - const discussionFilePath = discussion?.diff_file?.file_path; - - window.location.hash = ''; - - if (discussionFilePath) { - self.scrollToFile({ - path: discussionFilePath, - }); - } - - self.$nextTick(() => { - jumpToDiscussion(self, discussion); - self.setCurrentDiscussionId(targetId); - }); -} +import { scrollToElement, contentTop } from '~/lib/utils/common_utils'; function getAllDiscussionElements() { + const containerEl = window.mrTabs?.currentAction === 'diffs' ? '.diffs' : '.notes'; return Array.from( - document.querySelectorAll('[data-discussion-id]:not([data-discussion-resolved])'), + document.querySelectorAll( + `${containerEl} div[data-discussion-id]:not([data-discussion-resolved])`, + ), ); } @@ -182,14 +58,10 @@ function getPreviousDiscussion() { } function handleJumpForBothPages(getDiscussion, ctx, fn, scrollOptions) { - if (window.mrTabs.currentAction !== 'show') { - handleDiscussionJump(ctx, fn); - } else { - const discussion = getDiscussion(); - const id = discussion.dataset.discussionId; - ctx.expandDiscussion({ discussionId: id }); - scrollToElement(discussion, scrollOptions); - } + const discussion = getDiscussion(); + const id = discussion.dataset.discussionId; + ctx.expandDiscussion({ discussionId: id }); + scrollToElement(discussion, scrollOptions); } export default { @@ -205,9 +77,11 @@ export default { }, methods: { ...mapActions(['expandDiscussion', 'setCurrentDiscussionId']), - ...mapActions('diffs', ['scrollToFile']), + ...mapActions('diffs', ['scrollToFile', 'disableVirtualScroller']), + + async jumpToNextDiscussion(scrollOptions) { + await this.disableVirtualScroller(); - jumpToNextDiscussion(scrollOptions) { handleJumpForBothPages( getNextDiscussion, this, @@ -216,7 +90,9 @@ export default { ); }, - jumpToPreviousDiscussion(scrollOptions) { + async jumpToPreviousDiscussion(scrollOptions) { + await this.disableVirtualScroller(); + handleJumpForBothPages( getPreviousDiscussion, this, |