Optimize getting Commented Code To calculate diff for user suggested edit we need to get code that is inside comment range. - request only if comment has user suggestion - reuse commented code for apply fix dialog Release-Notes: skip Google-Bug-Id: b/298011591 Change-Id: I935e338ac6adfc287e8ff4904d7c0b1ad558f641
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-model/gr-comment-model.ts b/polygerrit-ui/app/elements/shared/gr-comment-model/gr-comment-model.ts index 974329a..46b43c9 100644 --- a/polygerrit-ui/app/elements/shared/gr-comment-model/gr-comment-model.ts +++ b/polygerrit-ui/app/elements/shared/gr-comment-model/gr-comment-model.ts
@@ -10,16 +10,26 @@ import {isDefined} from '../../../types/types'; import {select} from '../../../utils/observable-util'; import {Comment} from '../../../types/common'; +import {RestApiService} from '../../../services/gr-rest-api/gr-rest-api'; +import {NumericChangeId, isBase64FileContent} from '../../../api/rest-api'; +import {assert, assertIsDefined} from '../../../utils/common-util'; +import {getContentInCommentRange} from '../../../utils/comment-util'; +import {SpecialFilePath} from '../../../constants/constants'; export interface CommentState { - comment: Comment; + comment?: Comment; commentedText?: string; } +const initialState: CommentState = { + comment: undefined, + commentedText: undefined, +}; + export const commentModelToken = define<CommentModel>('diff-model'); export class CommentModel extends Model<CommentState | undefined> { - readonly comment$: Observable<Comment> = select( + readonly comment$: Observable<Comment | undefined> = select( this.state$.pipe(filter(isDefined)), commentState => commentState.comment ); @@ -28,4 +38,32 @@ this.state$.pipe(filter(isDefined)), commentState => commentState.commentedText ); + + constructor(private readonly restApiService: RestApiService) { + super(initialState); + } + + async getCommentedCode( + comment?: Comment, + changeNum?: NumericChangeId + ): Promise<string | undefined> { + assertIsDefined(comment, 'comment'); + assertIsDefined(changeNum, 'changeNum'); + if (comment.path === SpecialFilePath.PATCHSET_LEVEL_COMMENTS) return; + const file = await this.restApiService.getFileContent( + changeNum, + comment.path!, + comment.patch_set! + ); + assert( + !!file && isBase64FileContent(file) && !!file.content, + 'file content for comment not found' + ); + const commentedText = getContentInCommentRange(file.content, comment); + assert(!!commentedText, 'file content for comment not found'); + this.updateState({ + commentedText, + }); + return commentedText; + } }
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts index 6ca4702..0a5005a 100644 --- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts +++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
@@ -214,6 +214,9 @@ @state() isOwner = false; + @state() + commentedText?: string; + private readonly restApiService = getAppContext().restApiService; private readonly reporting = getAppContext().reportingService; @@ -230,7 +233,7 @@ private readonly shortcuts = new ShortcutController(this); - private commentModel = new CommentModel(undefined); + private commentModel = new CommentModel(this.restApiService); /** * This is triggered when the user types into the editing textarea. We then @@ -995,14 +998,15 @@ KnownExperimentId.DIFF_FOR_USER_SUGGESTED_EDIT ) || !this.changeNum || - !this.comment + !this.comment || + !hasUserSuggestion(this.comment) ) return; (async () => { - const commentedText = await this.getCommentedCode(); - this.commentModel.updateState({ - commentedText, - }); + this.commentedText = await this.commentModel.getCommentedCode( + this.comment, + this.changeNum + ); })(); } } @@ -1072,12 +1076,15 @@ if (hasUserSuggestion(this.comment) || replacement) { replacement = replacement ?? getUserSuggestion(this.comment); assert(!!replacement, 'malformed user suggestion'); - const line = await this.getCommentedCode(); + let commentedCode = this.commentedText; + if (!commentedCode) { + commentedCode = await this.getCommentedCode(); + } return { fixSuggestions: createUserFixSuggestion( this.comment, - line, + commentedCode, replacement ), patchNum: this.comment.patch_set, @@ -1196,11 +1203,10 @@ }${USER_SUGGESTION_START_PATTERN}${line}${'\n```'}`; } + // TODO(milutin): Remove once feature flag is rollout and use only model async getCommentedCode() { assertIsDefined(this.comment, 'comment'); assertIsDefined(this.changeNum, 'changeNum'); - // TODO(milutin): Show a toast while the file is being loaded. - // TODO(milutin): This should be moved into a service/model. const file = await this.restApiService.getFileContent( this.changeNum, this.comment.path!,
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts index 88866d4..a287659 100644 --- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts +++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
@@ -41,7 +41,10 @@ testResolver(changeModelToken), getAppContext().restApiService ); - const commentModel = new CommentModel({comment: createComment()}); + const commentModel = new CommentModel(getAppContext().restApiService); + commentModel.updateState({ + comment: createComment(), + }); await setCommentLinks({ customLinkRewrite: { match: '(LinkRewriteMe)',
diff --git a/polygerrit-ui/app/elements/shared/gr-user-suggestion-fix/gr-user-suggestion-fix_test.ts b/polygerrit-ui/app/elements/shared/gr-user-suggestion-fix/gr-user-suggestion-fix_test.ts index 423fe62..35b2d90 100644 --- a/polygerrit-ui/app/elements/shared/gr-user-suggestion-fix/gr-user-suggestion-fix_test.ts +++ b/polygerrit-ui/app/elements/shared/gr-user-suggestion-fix/gr-user-suggestion-fix_test.ts
@@ -13,12 +13,16 @@ } from '../gr-comment-model/gr-comment-model'; import {wrapInProvider} from '../../../models/di-provider-element'; import {createComment} from '../../../test/test-data-generators'; +import {getAppContext} from '../../../services/app-context'; suite('gr-user-suggestion-fix tests', () => { let element: GrUserSuggestionsFix; setup(async () => { - const commentModel = new CommentModel({comment: createComment()}); + const commentModel = new CommentModel(getAppContext().restApiService); + commentModel.updateState({ + comment: createComment(), + }); element = ( await fixture<GrUserSuggestionsFix>( wrapInProvider(