Merge changes from topic "comment-context"
* changes:
Show the lines of code around a comment as context
Request comment context along with the comments from server
diff --git a/polygerrit-ui/app/api/diff.ts b/polygerrit-ui/app/api/diff.ts
index 5d7125c..7ee68b7 100644
--- a/polygerrit-ui/app/api/diff.ts
+++ b/polygerrit-ui/app/api/diff.ts
@@ -178,6 +178,11 @@
theme?: string;
}
+export declare interface RenderPreferences {
+ hide_left_side?: boolean;
+ disable_context_control_buttons?: boolean;
+}
+
/**
* Whether whitespace changes should be ignored and if yes, which whitespace
* changes should be ignored
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts
index a0a8253..85bfed2 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts
@@ -682,6 +682,7 @@
logged-in="[[_loggedIn]]"
only-show-robot-comments-with-human-reply=""
unresolved-only
+ show-comment-context
></gr-thread-list>
</template>
<template
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_html.ts b/polygerrit-ui/app/elements/change/gr-message/gr-message_html.ts
index 6515af0..0409a42 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_html.ts
@@ -259,6 +259,7 @@
change-num="[[changeNum]]"
logged-in="[[_loggedIn]]"
hide-toggle-buttons
+ show-comment-context
>
</gr-thread-list>
</template>
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.ts b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.ts
index 22b2e43..28bccc6 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.ts
@@ -77,6 +77,9 @@
@property({type: Array})
_sortedThreads: CommentThread[] = [];
+ @property({type: Boolean})
+ showCommentContext = false;
+
@property({
computed:
'_computeDisplayedThreads(_sortedThreads.*, unresolvedOnly, ' +
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_html.ts b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_html.ts
index 8a52555..1be2da1 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_html.ts
@@ -25,7 +25,6 @@
gr-comment-thread {
display: block;
margin-bottom: var(--spacing-m);
- max-width: 80ch;
}
.header {
align-items: center;
@@ -172,6 +171,7 @@
<gr-comment-thread
show-file-path=""
show-ported-comment="[[thread.ported]]"
+ show-comment-context="[[showCommentContext]]"
change-num="[[changeNum]]"
comments="[[thread.comments]]"
diff-side="[[thread.diffSide]]"
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.ts b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.ts
index 7946061..7c32bf7 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.ts
@@ -66,7 +66,10 @@
// @ts-ignore
import * as shadow from 'shadow-selection-polyfill/shadow.js';
-import {CreateCommentEventDetail as CreateCommentEventDetailApi} from '../../../api/diff';
+import {
+ CreateCommentEventDetail as CreateCommentEventDetailApi,
+ RenderPreferences,
+} from '../../../api/diff';
import {isSafari} from '../../../utils/dom-util';
const NO_NEWLINE_BASE = 'No newline at end of base file.';
@@ -158,6 +161,9 @@
@property({type: Object, observer: '_prefsObserver'})
prefs?: DiffPreferencesInfo;
+ @property({type: Object, observer: '_renderPrefsChanged'})
+ renderPrefs?: RenderPreferences;
+
@property({type: Boolean})
displayLine = false;
@@ -727,6 +733,16 @@
}
}
+ _renderPrefsChanged(renderPrefs?: RenderPreferences) {
+ if (!renderPrefs) return;
+ if (renderPrefs.hide_left_side) {
+ this.classList.add('no-left');
+ }
+ if (renderPrefs.disable_context_control_buttons) {
+ this.updateStyles({'--context-control-display': 'none'});
+ }
+ }
+
_diffChanged(newValue?: DiffInfo) {
this._setLoading(true);
this._cleanup();
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts
index b0f48ce..4b477cd 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts
@@ -272,6 +272,7 @@
/* Context controls */
.contextControl {
+ display: var(--context-control-display, table-row-group);
background-color: transparent;
border: none;
--divider-height: var(--spacing-s);
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
index 6ee82c9..1af2adf 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
@@ -17,6 +17,7 @@
import '../../../styles/shared-styles';
import '../gr-storage/gr-storage';
import '../gr-comment/gr-comment';
+import '../../diff/gr-diff/gr-diff';
import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
@@ -24,6 +25,7 @@
import {htmlTemplate} from './gr-comment-thread_html';
import {KeyboardShortcutMixin} from '../../../mixins/keyboard-shortcut-mixin/keyboard-shortcut-mixin';
import {
+ computeDiffFromContext,
isDraft,
isRobot,
sortComments,
@@ -33,9 +35,14 @@
} from '../../../utils/comment-util';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {appContext} from '../../../services/app-context';
-import {CommentSide, Side, SpecialFilePath} from '../../../constants/constants';
+import {
+ CommentSide,
+ createDefaultDiffPrefs,
+ Side,
+ SpecialFilePath,
+} from '../../../constants/constants';
import {computeDisplayPath} from '../../../utils/path-list-util';
-import {customElement, observe, property} from '@polymer/decorators';
+import {computed, customElement, observe, property} from '@polymer/decorators';
import {
CommentRange,
ConfigInfo,
@@ -50,6 +57,9 @@
import {CustomKeyboardEvent} from '../../../types/events';
import {LineNumber, FILE} from '../../diff/gr-diff/gr-diff-line';
import {GrButton} from '../gr-button/gr-button';
+import {KnownExperimentId} from '../../../services/flags/flags';
+import {DiffInfo, DiffPreferencesInfo} from '../../../types/diff';
+import {RenderPreferences} from '../../../api/diff';
const UNRESOLVED_EXPAND_COUNT = 5;
const NEWLINE_PATTERN = /\n/g;
@@ -122,7 +132,7 @@
patchNum?: PatchSetNum;
@property({type: String})
- path?: string;
+ path: string | undefined;
@property({type: String, observer: '_projectNameChanged'})
projectName?: RepoName;
@@ -164,6 +174,15 @@
@property({type: Object})
_projectConfig?: ConfigInfo;
+ @property({type: Object})
+ _prefs: DiffPreferencesInfo = createDefaultDiffPrefs();
+
+ @property({type: Object})
+ _renderPrefs: RenderPreferences = {
+ hide_left_side: true,
+ disable_context_control_buttons: true,
+ };
+
@property({type: Boolean, reflectToAttribute: true})
isRobotComment = false;
@@ -176,6 +195,9 @@
@property({type: Boolean})
showPatchset = true;
+ @property({type: Boolean})
+ showCommentContext = false;
+
get keyBindings() {
return {
'e shift+e': '_handleEKey',
@@ -188,6 +210,10 @@
readonly storage = new GrStorage();
+ private isCommentContextExperimentEnabled = this.flagsService.isEnabled(
+ KnownExperimentId.COMMENT_CONTEXT
+ );
+
readonly restApiService = appContext.restApiService;
/** @override */
@@ -204,9 +230,34 @@
this._getLoggedIn().then(loggedIn => {
this._showActions = loggedIn;
});
+ this.restApiService.getDiffPreferences().then(prefs => {
+ if (!prefs) return;
+ this._prefs = {
+ ...prefs,
+ show_file_comment_button: false,
+ // override explicitly so that diff doesn't take too much width
+ // compared to the context
+ line_wrapping: false,
+ };
+ });
this._setInitialExpandedState();
}
+ @computed('comments', 'path')
+ get _diff() {
+ if (this.comments === undefined || this.path === undefined) return;
+ if (!this.comments[0]?.context_lines?.length) return;
+ return computeDiffFromContext(this.comments[0].context_lines, this.path);
+ }
+
+ _shouldShowCommentContext(diff?: DiffInfo) {
+ return (
+ this.isCommentContextExperimentEnabled &&
+ this.showCommentContext &&
+ !!diff
+ );
+ }
+
addOrEditDraft(lineNum?: LineNumber, rangeParam?: CommentRange) {
const lastComment = this.comments[this.comments.length - 1] || {};
if (isDraft(lastComment)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
index 1a89a79..7d5ba11 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_html.ts
@@ -23,6 +23,15 @@
font-size: var(--font-size-normal);
font-weight: var(--font-weight-normal);
line-height: var(--line-height-normal);
+ /* Explicitly set the background color of the diff to be white. We
+ * cannot use the diff content type ab because of the skip chunk preceding
+ * it, diff processor assumes the chunk of type skip/ab can be collapsed
+ * and hides our diff behind context control buttons.
+ * */
+ --dark-add-highlight-color: white;
+ --diff-container-styles: {
+ border: 1px solid var(--border-color);
+ }
}
gr-button {
margin-left: var(--spacing-m);
@@ -34,24 +43,29 @@
margin-left: auto;
padding: var(--spacing-s) var(--spacing-m);
}
- #container {
+ .comment-box {
+ width: 80ch;
+ max-width: 100%;
background-color: var(--comment-background-color);
color: var(--comment-text-color);
- display: var(--gr-comment-thread-display, block);
- margin: 0 var(--spacing-s) var(--spacing-s);
- white-space: normal;
box-shadow: var(--elevation-level-2);
border-radius: var(--border-radius);
+ }
+ #container {
+ display: var(--gr-comment-thread-display, flex);
+ align-items: flex-start;
+ margin: 0 var(--spacing-s) var(--spacing-s);
+ white-space: normal;
/** This is required for firefox to continue the inheritance */
-webkit-user-select: inherit;
-moz-user-select: inherit;
-ms-user-select: inherit;
user-select: inherit;
}
- #container.unresolved {
+ .comment-box.unresolved {
background-color: var(--unresolved-comment-background-color);
}
- #container.robotComment {
+ .comment-box.robotComment {
background-color: var(--robot-comment-background-color);
}
#commentInfoContainer {
@@ -75,7 +89,11 @@
.fileName {
padding: var(--spacing-m) var(--spacing-s) var(--spacing-m);
}
+ gr-diff {
+ margin-left: var(--spacing-l);
+ }
</style>
+
<template is="dom-if" if="[[showFilePath]]">
<template is="dom-if" if="[[showFileName]]">
<div class="fileName">
@@ -100,71 +118,81 @@
</template>
</div>
</template>
- <div
- id="container"
- class$="[[_computeHostClass(unresolved, isRobotComment)]]"
- >
- <template
- id="commentList"
- is="dom-repeat"
- items="[[_orderedComments]]"
- as="comment"
- >
- <gr-comment
- comment="{{comment}}"
- comments="{{comments}}"
- robot-button-disabled="[[_shouldDisableAction(_showActions, _lastComment)]]"
- change-num="[[changeNum]]"
- project-name="[[projectName]]"
- patch-num="[[patchNum]]"
- draft="[[_isDraft(comment)]]"
- show-actions="[[_showActions]]"
- show-patchset="[[showPatchset]]"
- show-ported-comment="[[_computeShowPortedComment(comment)]]"
- side="[[comment.side]]"
- project-config="[[_projectConfig]]"
- on-create-fix-comment="_handleCommentFix"
- on-comment-discard="_handleCommentDiscard"
- on-comment-save="_handleCommentSavedOrDiscarded"
- ></gr-comment>
- </template>
- <div
- id="commentInfoContainer"
- hidden$="[[_hideActions(_showActions, _lastComment)]]"
- >
- <span id="unresolvedLabel">[[_getUnresolvedLabel(unresolved)]]</span>
- <div id="actions">
- <gr-button
- id="replyBtn"
- link=""
- class="action reply"
- on-click="_handleCommentReply"
- >Reply</gr-button
- >
- <gr-button
- id="quoteBtn"
- link=""
- class="action quote"
- on-click="_handleCommentQuote"
- >Quote</gr-button
- >
- <template is="dom-if" if="[[unresolved]]">
+ <div id="container">
+ <div class$="[[_computeHostClass(unresolved, isRobotComment)]] comment-box">
+ <template
+ id="commentList"
+ is="dom-repeat"
+ items="[[_orderedComments]]"
+ as="comment"
+ >
+ <gr-comment
+ comment="{{comment}}"
+ comments="{{comments}}"
+ robot-button-disabled="[[_shouldDisableAction(_showActions, _lastComment)]]"
+ change-num="[[changeNum]]"
+ project-name="[[projectName]]"
+ patch-num="[[patchNum]]"
+ draft="[[_isDraft(comment)]]"
+ show-actions="[[_showActions]]"
+ show-patchset="[[showPatchset]]"
+ show-ported-comment="[[_computeShowPortedComment(comment)]]"
+ side="[[comment.side]]"
+ project-config="[[_projectConfig]]"
+ on-create-fix-comment="_handleCommentFix"
+ on-comment-discard="_handleCommentDiscard"
+ on-comment-save="_handleCommentSavedOrDiscarded"
+ ></gr-comment>
+ </template>
+ <div
+ id="commentInfoContainer"
+ hidden$="[[_hideActions(_showActions, _lastComment)]]"
+ >
+ <span id="unresolvedLabel">[[_getUnresolvedLabel(unresolved)]]</span>
+ <div id="actions">
<gr-button
- id="ackBtn"
+ id="replyBtn"
link=""
- class="action ack"
- on-click="_handleCommentAck"
- >Ack</gr-button
+ class="action reply"
+ on-click="_handleCommentReply"
+ >Reply</gr-button
>
<gr-button
- id="doneBtn"
+ id="quoteBtn"
link=""
- class="action done"
- on-click="_handleCommentDone"
- >Done</gr-button
+ class="action quote"
+ on-click="_handleCommentQuote"
+ >Quote</gr-button
>
- </template>
+ <template is="dom-if" if="[[unresolved]]">
+ <gr-button
+ id="ackBtn"
+ link=""
+ class="action ack"
+ on-click="_handleCommentAck"
+ >Ack</gr-button
+ >
+ <gr-button
+ id="doneBtn"
+ link=""
+ class="action done"
+ on-click="_handleCommentDone"
+ >Done</gr-button
+ >
+ </template>
+ </div>
</div>
</div>
+ <template is="dom-if" if="[[_shouldShowCommentContext(_diff)]]">
+ <gr-diff
+ id="diff"
+ change-num="[[changeNum]]"
+ diff="[[_diff]]"
+ path="[[path]]"
+ prefs="[[_prefs]]"
+ render-prefs="[[_renderPrefs]]"
+ >
+ </gr-diff>
+ </template>
</div>
`;
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
index 6e17c75..20d2d1d 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
@@ -2232,11 +2232,14 @@
path?: string
) {
if (!basePatchNum && !patchNum && !path) {
- return this._getDiffComments(changeNum, '/comments');
+ return this._getDiffComments(changeNum, '/comments', {
+ 'enable-context': true,
+ });
}
return this._getDiffComments(
changeNum,
'/comments',
+ {'enable-context': true},
basePatchNum,
patchNum,
path
@@ -2267,6 +2270,7 @@
return this._getDiffComments(
changeNum,
'/robotcomments',
+ undefined,
basePatchNum,
patchNum,
path
@@ -2305,6 +2309,7 @@
return this._getDiffComments(
changeNum,
'/drafts',
+ undefined,
basePatchNum,
patchNum,
path
@@ -2337,7 +2342,8 @@
_getDiffComments(
changeNum: NumericChangeId,
- endpoint: '/comments' | '/drafts'
+ endpoint: '/comments' | '/drafts',
+ params?: FetchParams
): Promise<PathToCommentsInfoMap | undefined>;
_getDiffComments(
@@ -2348,6 +2354,7 @@
_getDiffComments(
changeNum: NumericChangeId,
endpoint: '/comments' | '/drafts',
+ params?: FetchParams,
basePatchNum?: PatchSetNum,
patchNum?: PatchSetNum,
path?: string
@@ -2356,6 +2363,7 @@
_getDiffComments(
changeNum: NumericChangeId,
endpoint: '/robotcomments',
+ params?: FetchParams,
basePatchNum?: PatchSetNum,
patchNum?: PatchSetNum,
path?: string
@@ -2364,6 +2372,7 @@
_getDiffComments(
changeNum: NumericChangeId,
endpoint: string,
+ params?: FetchParams,
basePatchNum?: PatchSetNum,
patchNum?: PatchSetNum,
path?: string
@@ -2388,6 +2397,7 @@
endpoint,
revision: patchNum,
reportEndpointAsIs: true,
+ params,
},
noAcceptHeader
) as Promise<
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js
index 6db2bff..fbd675f 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js
@@ -75,7 +75,8 @@
},
],
}));
- return element._getDiffComments('42', '', 'PARENT', 1, 'sieve.go').then(
+ return element._getDiffComments('42', '', undefined, 'PARENT', 1,
+ 'sieve.go').then(
obj => {
assert.equal(obj.baseComments.length, 1);
assert.deepEqual(obj.baseComments[0], {
@@ -239,7 +240,7 @@
});
}
});
- return element._getDiffComments('42', '', 1, 2, 'sieve.go').then(
+ return element._getDiffComments('42', '', undefined, 1, 2, 'sieve.go').then(
obj => {
assert.equal(obj.baseComments.length, 1);
assert.deepEqual(obj.baseComments[0], {
diff --git a/polygerrit-ui/app/services/flags/flags.ts b/polygerrit-ui/app/services/flags/flags.ts
index f96afaa..878b8f7 100644
--- a/polygerrit-ui/app/services/flags/flags.ts
+++ b/polygerrit-ui/app/services/flags/flags.ts
@@ -31,4 +31,5 @@
NEW_CHANGE_SUMMARY_UI = 'UiFeature__new_change_summary_ui',
PORTING_COMMENTS = 'UiFeature__porting_comments',
NEW_IMAGE_DIFF_UI = 'UiFeature__new_image_diff_ui',
+ COMMENT_CONTEXT = 'UiFeature__comment_context',
}
diff --git a/polygerrit-ui/app/types/common.ts b/polygerrit-ui/app/types/common.ts
index 8f5518a..aeacd9a 100644
--- a/polygerrit-ui/app/types/common.ts
+++ b/polygerrit-ui/app/types/common.ts
@@ -1173,11 +1173,21 @@
unresolved?: boolean;
change_message_id?: string;
commit_id?: string;
+ context_lines?: ContextLine[];
}
export type PathToCommentsInfoMap = {[path: string]: CommentInfo[]};
/**
+ * The ContextLine entity contains the line number and line text of a single line of the source file content..
+ * https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#context-line
+ */
+export interface ContextLine {
+ line_number: number;
+ context_line: string;
+}
+
+/**
* The ProjectInfo entity contains information about a project
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#project-info
*/
diff --git a/polygerrit-ui/app/utils/comment-util.ts b/polygerrit-ui/app/utils/comment-util.ts
index 0c4a3c6..61456a2 100644
--- a/polygerrit-ui/app/utils/comment-util.ts
+++ b/polygerrit-ui/app/utils/comment-util.ts
@@ -24,12 +24,14 @@
CommentRange,
PatchRange,
ParentPatchSetNum,
+ ContextLine,
} from '../types/common';
import {CommentSide, Side} from '../constants/constants';
import {parseDate} from './date-util';
import {LineNumber} from '../elements/diff/gr-diff/gr-diff-line';
import {CommentIdToCommentThreadMap} from '../elements/diff/gr-comment-api/gr-comment-api';
import {isMergeParent, getParentIndex} from './patch-set-util';
+import {DiffInfo} from '../types/diff';
export interface DraftCommentProps {
__draft?: boolean;
@@ -285,3 +287,32 @@
};
}
}
+
+export function computeDiffFromContext(context: ContextLine[], path: string) {
+ const diff: DiffInfo = {
+ meta_a: {
+ name: '',
+ content_type: '',
+ lines: 0,
+ web_links: [],
+ },
+ meta_b: {
+ name: path,
+ content_type: '',
+ lines: context.length + context?.[0].line_number,
+ web_links: [],
+ },
+ change_type: 'MODIFIED',
+ intraline_status: 'OK',
+ diff_header: [],
+ content: [
+ {
+ skip: context[0].line_number - 1,
+ },
+ {
+ b: context.map(line => line.context_line),
+ },
+ ],
+ };
+ return diff;
+}