summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/notes/mixins
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-23 15:09:40 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-23 15:09:40 +0000
commite01e71a98f4c2d3492d99993d67e7277a2ead698 (patch)
treed43754b3eebf6b32feb442ad29c967f088e51536 /app/assets/javascripts/notes/mixins
parentdb90a0f7e36108df2c57f28bf84b733faceb6ee2 (diff)
downloadgitlab-ce-e01e71a98f4c2d3492d99993d67e7277a2ead698.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/notes/mixins')
-rw-r--r--app/assets/javascripts/notes/mixins/discussion_navigation.js99
1 files changed, 81 insertions, 18 deletions
diff --git a/app/assets/javascripts/notes/mixins/discussion_navigation.js b/app/assets/javascripts/notes/mixins/discussion_navigation.js
index 45df91796fc..10c897d2d2a 100644
--- a/app/assets/javascripts/notes/mixins/discussion_navigation.js
+++ b/app/assets/javascripts/notes/mixins/discussion_navigation.js
@@ -1,5 +1,5 @@
import { mapGetters, mapActions, mapState } from 'vuex';
-import { scrollToElementWithContext, scrollToElement } from '~/lib/utils/common_utils';
+import { scrollToElementWithContext, scrollToElement, contentTop } from '~/lib/utils/common_utils';
import { updateHistory } from '~/lib/utils/url_utility';
import eventHub from '../event_hub';
@@ -94,8 +94,6 @@ function jumpToDiscussion(self, discussion) {
if (activeTab === 'diffs' && isDiffDiscussion) {
diffsJump(self, id, firstNoteId);
- } else if (activeTab === 'show') {
- discussionJump(self, id);
} else {
switchToDiscussionsTabAndJumpTo(self, id);
}
@@ -105,11 +103,10 @@ function jumpToDiscussion(self, discussion) {
/**
* @param {object} self Component instance with mixin applied
* @param {function} fn Which function used to get the target discussion's id
- * @param {string} [discussionId=this.currentDiscussionId] Current discussion id, will be null if discussions have not been traversed yet
*/
-function handleDiscussionJump(self, fn, discussionId = self.currentDiscussionId) {
+function handleDiscussionJump(self, fn) {
const isDiffView = window.mrTabs.currentAction === 'diffs';
- const targetId = fn(discussionId, isDiffView);
+ const targetId = fn(self.currentDiscussionId, isDiffView);
const discussion = self.getDiscussion(targetId);
const discussionFilePath = discussion?.diff_file?.file_path;
@@ -127,6 +124,70 @@ function handleDiscussionJump(self, fn, discussionId = self.currentDiscussionId)
});
}
+function getAllDiscussionElements() {
+ return Array.from(
+ document.querySelectorAll('[data-discussion-id]:not([data-discussion-resolved])'),
+ );
+}
+
+function hasReachedPageEnd() {
+ return document.body.scrollHeight <= Math.ceil(window.scrollY + window.innerHeight);
+}
+
+function findNextClosestVisibleDiscussion(discussionElements) {
+ const offsetHeight = contentTop();
+ let isActive;
+ const index = discussionElements.findIndex((element) => {
+ const { y } = element.getBoundingClientRect();
+ const visibleHorizontalOffset = Math.ceil(y) - offsetHeight;
+ // handle rect rounding errors
+ isActive = visibleHorizontalOffset < 2;
+ return visibleHorizontalOffset >= 0;
+ });
+ return [discussionElements[index], index, isActive];
+}
+
+function getNextDiscussion() {
+ const discussionElements = getAllDiscussionElements();
+ const firstDiscussion = discussionElements[0];
+ if (hasReachedPageEnd()) {
+ return firstDiscussion;
+ }
+ const [nextClosestDiscussion, index, isActive] = findNextClosestVisibleDiscussion(
+ discussionElements,
+ );
+ if (nextClosestDiscussion && !isActive) {
+ return nextClosestDiscussion;
+ }
+ const nextDiscussion = discussionElements[index + 1];
+ if (!nextClosestDiscussion || !nextDiscussion) {
+ return firstDiscussion;
+ }
+ return nextDiscussion;
+}
+
+function getPreviousDiscussion() {
+ const discussionElements = getAllDiscussionElements();
+ const lastDiscussion = discussionElements[discussionElements.length - 1];
+ const [, index] = findNextClosestVisibleDiscussion(discussionElements);
+ const previousDiscussion = discussionElements[index - 1];
+ if (previousDiscussion) {
+ return previousDiscussion;
+ }
+ return lastDiscussion;
+}
+
+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);
+ }
+}
+
export default {
computed: {
...mapGetters([
@@ -142,12 +203,22 @@ export default {
...mapActions(['expandDiscussion', 'setCurrentDiscussionId']),
...mapActions('diffs', ['scrollToFile']),
- jumpToNextDiscussion() {
- handleDiscussionJump(this, this.nextUnresolvedDiscussionId);
+ jumpToNextDiscussion(scrollOptions) {
+ handleJumpForBothPages(
+ getNextDiscussion,
+ this,
+ this.nextUnresolvedDiscussionId,
+ scrollOptions,
+ );
},
- jumpToPreviousDiscussion() {
- handleDiscussionJump(this, this.previousUnresolvedDiscussionId);
+ jumpToPreviousDiscussion(scrollOptions) {
+ handleJumpForBothPages(
+ getPreviousDiscussion,
+ this,
+ this.previousUnresolvedDiscussionId,
+ scrollOptions,
+ );
},
jumpToFirstUnresolvedDiscussion() {
@@ -157,13 +228,5 @@ export default {
})
.catch(() => {});
},
-
- /**
- * Go to the next discussion from the given discussionId
- * @param {String} discussionId The id we are jumping from
- */
- jumpToNextRelativeDiscussion(discussionId) {
- handleDiscussionJump(this, this.nextUnresolvedDiscussionId, discussionId);
- },
},
};