summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/diffs/utils
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/diffs/utils')
-rw-r--r--app/assets/javascripts/diffs/utils/diff_file.js15
-rw-r--r--app/assets/javascripts/diffs/utils/file_reviews.js61
-rw-r--r--app/assets/javascripts/diffs/utils/merge_request.js20
-rw-r--r--app/assets/javascripts/diffs/utils/uuids.js4
4 files changed, 93 insertions, 7 deletions
diff --git a/app/assets/javascripts/diffs/utils/diff_file.js b/app/assets/javascripts/diffs/utils/diff_file.js
index 69d0e49e501..ce0398e75fc 100644
--- a/app/assets/javascripts/diffs/utils/diff_file.js
+++ b/app/assets/javascripts/diffs/utils/diff_file.js
@@ -4,11 +4,12 @@ import {
DIFF_FILE_MANUAL_COLLAPSE,
DIFF_FILE_AUTOMATIC_COLLAPSE,
} from '../constants';
+import { getDerivedMergeRequestInformation } from './merge_request';
import { uuids } from './uuids';
function fileSymlinkInformation(file, fileList) {
- const duplicates = fileList.filter(iteratedFile => iteratedFile.file_hash === file.file_hash);
- const includesSymlink = duplicates.some(iteratedFile => {
+ const duplicates = fileList.filter((iteratedFile) => iteratedFile.file_hash === file.file_hash);
+ const includesSymlink = duplicates.some((iteratedFile) => {
return [iteratedFile.a_mode, iteratedFile.b_mode].includes(DIFF_FILE_SYMLINK_MODE);
});
const brokenSymlinkScenario = duplicates.length > 1 && includesSymlink;
@@ -34,8 +35,12 @@ function collapsed(file) {
}
function identifier(file) {
+ const { userOrGroup, project, id } = getDerivedMergeRequestInformation({
+ endpoint: file.load_collapsed_diff_url,
+ });
+
return uuids({
- seeds: [file.file_identifier_hash, file.blob?.id],
+ seeds: [userOrGroup, project, id, file.file_identifier_hash, file.blob?.id],
})[0];
}
@@ -48,10 +53,10 @@ export function prepareRawDiffFile({ file, allFiles, meta = false }) {
},
};
- // It's possible, but not confirmed, that `content_sha` isn't available sometimes
+ // It's possible, but not confirmed, that `blob.id` isn't available sometimes
// See: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49506#note_464692057
// We don't want duplicate IDs if that's the case, so we just don't assign an ID
- if (!meta && file.blob?.id) {
+ if (!meta && file.blob?.id && file.load_collapsed_diff_url) {
additionalProperties.id = identifier(file);
}
diff --git a/app/assets/javascripts/diffs/utils/file_reviews.js b/app/assets/javascripts/diffs/utils/file_reviews.js
new file mode 100644
index 00000000000..0047955643a
--- /dev/null
+++ b/app/assets/javascripts/diffs/utils/file_reviews.js
@@ -0,0 +1,61 @@
+function getFileReviewsKey(mrPath) {
+ return `${mrPath}-file-reviews`;
+}
+
+export function getReviewsForMergeRequest(mrPath) {
+ const reviewsForMr = localStorage.getItem(getFileReviewsKey(mrPath));
+ let reviews = {};
+
+ if (reviewsForMr) {
+ try {
+ reviews = JSON.parse(reviewsForMr);
+ } catch (err) {
+ reviews = {};
+ }
+ }
+
+ return reviews;
+}
+
+export function setReviewsForMergeRequest(mrPath, reviews) {
+ localStorage.setItem(getFileReviewsKey(mrPath), JSON.stringify(reviews));
+
+ return reviews;
+}
+
+export function isFileReviewed(reviews, file) {
+ const fileReviews = reviews[file.file_identifier_hash];
+
+ return file?.id && fileReviews?.length ? new Set(fileReviews).has(file.id) : false;
+}
+
+export function reviewable(file) {
+ return Boolean(file.id) && Boolean(file.file_identifier_hash);
+}
+
+export function markFileReview(reviews, file, reviewed = true) {
+ const usableReviews = { ...(reviews || {}) };
+ let updatedReviews = usableReviews;
+ let fileReviews;
+
+ if (reviewable(file)) {
+ fileReviews = new Set([...(usableReviews[file.file_identifier_hash] || [])]);
+
+ if (reviewed) {
+ fileReviews.add(file.id);
+ } else {
+ fileReviews.delete(file.id);
+ }
+
+ updatedReviews = {
+ ...usableReviews,
+ [file.file_identifier_hash]: Array.from(fileReviews),
+ };
+
+ if (updatedReviews[file.file_identifier_hash].length === 0) {
+ delete updatedReviews[file.file_identifier_hash];
+ }
+ }
+
+ return updatedReviews;
+}
diff --git a/app/assets/javascripts/diffs/utils/merge_request.js b/app/assets/javascripts/diffs/utils/merge_request.js
new file mode 100644
index 00000000000..edb4304f558
--- /dev/null
+++ b/app/assets/javascripts/diffs/utils/merge_request.js
@@ -0,0 +1,20 @@
+const endpointRE = /^(\/?(.+?)\/(.+?)\/-\/merge_requests\/(\d+)).*$/i;
+
+export function getDerivedMergeRequestInformation({ endpoint } = {}) {
+ let mrPath;
+ let userOrGroup;
+ let project;
+ let id;
+ const matches = endpointRE.exec(endpoint);
+
+ if (matches) {
+ [, mrPath, userOrGroup, project, id] = matches;
+ }
+
+ return {
+ mrPath,
+ userOrGroup,
+ project,
+ id,
+ };
+}
diff --git a/app/assets/javascripts/diffs/utils/uuids.js b/app/assets/javascripts/diffs/utils/uuids.js
index 12448350e62..1fe5f9f6499 100644
--- a/app/assets/javascripts/diffs/utils/uuids.js
+++ b/app/assets/javascripts/diffs/utils/uuids.js
@@ -11,7 +11,7 @@
* @typedef {String} UUIDv4
*/
-import MersenneTwister from 'mersenne-twister';
+import { MersenneTwister } from 'fast-mersenne-twister';
import stringHash from 'string-hash';
import { isString } from 'lodash';
import { v4 } from 'uuid';
@@ -49,7 +49,7 @@ function randomValuesForUuid(prng) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
- view.setUint32(0, prng.random_int());
+ view.setUint32(0, prng.randomNumber());
randomValues.push(view.getUint8(0), view.getUint8(1), view.getUint8(2), view.getUint8(3));
}