Skip to content

Commit d02dab4

Browse files
Improve Component Communication Logic
1 parent 6ecd9b2 commit d02dab4

7 files changed

Lines changed: 52 additions & 63 deletions

File tree

src/dotnet/APIView/ClientSPA/src/app/_components/code-panel/code-panel.component.ts

Lines changed: 16 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class CodePanelComponent implements OnChanges{
3838
@Input() showLineNumbers: boolean = true;
3939
@Input() loadFailed : boolean = false;
4040
@Input() codeLineSearchText: string | undefined;
41-
@Input() codeLineNavigationDirection: number | undefined;
41+
@Input() codeLineSearchInfo: CodeLineSearchInfo | undefined = undefined;
4242

4343
@Output() hasActiveConversationEmitter : EventEmitter<boolean> = new EventEmitter<boolean>();
4444
@Output() codeLineSearchInfoEmitter : EventEmitter<CodeLineSearchInfo> = new EventEmitter<CodeLineSearchInfo>();
@@ -56,8 +56,6 @@ export class CodePanelComponent implements OnChanges{
5656

5757
searchMatchedRowInfo: Map<string, RegExpMatchArray[]> = new Map<string, RegExpMatchArray[]>();
5858
codeLineSearchMatchInfo : DoublyLinkedList<CodeLineSearchMatch> | undefined = undefined;
59-
currentCodeLineSearchMatch: DoublyLinkedListNode<CodeLineSearchMatch> | undefined = undefined;
60-
codeLineSearchInfo: CodeLineSearchInfo | undefined = undefined;
6159

6260
destroy$ = new Subject<void>();
6361

@@ -103,11 +101,8 @@ export class CodePanelComponent implements OnChanges{
103101
await this.searchCodePanelRowData(this.codeLineSearchText!);
104102
}
105103

106-
if (changes['codeLineNavigationDirection']) {
107-
this.navigateToCodeLineWithSearchMatch(
108-
changes['codeLineNavigationDirection'].previousValue,
109-
changes['codeLineNavigationDirection'].currentValue
110-
);
104+
if (changes['codeLineSearchInfo'] && changes['codeLineSearchInfo'].currentValue != changes['codeLineSearchInfo'].previousValue) {
105+
this.navigateToCodeLineWithSearchMatch();
111106
}
112107
}
113108

@@ -702,7 +697,6 @@ export class CodePanelComponent implements OnChanges{
702697
if (!searchText || searchText.length === 0) {
703698
this.clearSearchMatchHighlights();
704699
this.codeLineSearchMatchInfo = undefined;
705-
this.currentCodeLineSearchMatch = undefined;
706700
this.codeLineSearchInfo = undefined;
707701
this.codeLineSearchInfoEmitter.emit(this.codeLineSearchInfo);
708702
return;
@@ -726,34 +720,24 @@ export class CodePanelComponent implements OnChanges{
726720
}
727721
}
728722
});
729-
730-
let currentMatch = 0;
731-
let totalMatchCount = 0;
732723

733724
if (hasMatch) {
734-
this.currentCodeLineSearchMatch = this.codeLineSearchMatchInfo.head;
725+
this.codeLineSearchInfo = new CodeLineSearchInfo(this.codeLineSearchMatchInfo.head, this.codeLineSearchMatchInfo.length);
735726

736-
if (this.currentCodeLineSearchMatch?.value.rowIndex! < this.codePanelRowSource?.adapter?.firstVisible.$index! ||
737-
this.currentCodeLineSearchMatch?.value.rowIndex! > this.codePanelRowSource?.adapter?.lastVisible.$index!) {
727+
if (this.codeLineSearchInfo.currentMatch?.value.rowIndex! < this.codePanelRowSource?.adapter?.firstVisible.$index! ||
728+
this.codeLineSearchInfo.currentMatch?.value.rowIndex! > this.codePanelRowSource?.adapter?.lastVisible.$index!) {
738729
// Scroll first match into view
739-
await this.scrollToNode(this.currentCodeLineSearchMatch!.value.nodeIdHashed, undefined, false, false);
730+
await this.scrollToNode(this.codeLineSearchInfo.currentMatch!.value.nodeIdHashed, undefined, false, false);
740731
await this.codePanelRowSource?.adapter?.relax();
741732
}
742733

743-
currentMatch = this.currentCodeLineSearchMatch!.index + 1;
744-
totalMatchCount = this.codeLineSearchMatchInfo.length;
745734
this.highlightSearchMatches();
746735
this.highlightActiveSearchMatch();
747736
} else {
748737
this.clearSearchMatchHighlights();
749738
this.codeLineSearchMatchInfo = undefined;
750-
this.currentCodeLineSearchMatch = undefined;
739+
this.codeLineSearchInfo = undefined;
751740
}
752-
753-
this.codeLineSearchInfo = {
754-
currentMatch: currentMatch,
755-
totalMatchCount: totalMatchCount
756-
};
757741
this.codeLineSearchInfoEmitter.emit(this.codeLineSearchInfo);
758742
}
759743

@@ -833,9 +817,9 @@ export class CodePanelComponent implements OnChanges{
833817
}
834818

835819
private highlightActiveSearchMatch(scrollIntoView: boolean = true) {
836-
if (this.currentCodeLineSearchMatch) {
837-
const nodeIdHashed = this.currentCodeLineSearchMatch.value.nodeIdHashed;
838-
const matchId = this.currentCodeLineSearchMatch.value.matchId;
820+
if (this.codeLineSearchInfo?.currentMatch) {
821+
const nodeIdHashed = this.codeLineSearchInfo?.currentMatch.value.nodeIdHashed;
822+
const matchId = this.codeLineSearchInfo?.currentMatch.value.matchId;
839823

840824
const activeMatch = this.elementRef.nativeElement.querySelector('.codeline-search-match-highlight.active');
841825
if (activeMatch) {
@@ -860,31 +844,16 @@ export class CodePanelComponent implements OnChanges{
860844
/**
861845
* Navigates to the next or previous code line that contains a search match but is outside the viewport
862846
*/
863-
private navigateToCodeLineWithSearchMatch(previousPosition: number, newPosition: number) {
864-
if (this.currentCodeLineSearchMatch) {
847+
private navigateToCodeLineWithSearchMatch() {
848+
if (this.codeLineSearchInfo?.currentMatch) {
865849
const firstVisibleIndex = this.codePanelRowSource?.adapter?.firstVisible.$index!;
866850
const lastVisibleIndex = this.codePanelRowSource?.adapter?.lastVisible.$index!;
867-
let currentMatch = this.codeLineSearchInfo?.currentMatch!;
868-
869-
if (!previousPosition || newPosition > previousPosition) {
870-
this.currentCodeLineSearchMatch = this.currentCodeLineSearchMatch?.next!;
871-
currentMatch++;
872-
} else if (newPosition < previousPosition) {
873-
this.currentCodeLineSearchMatch = this.currentCodeLineSearchMatch?.prev!;
874-
currentMatch--;
875-
}
876851

877-
if (this.currentCodeLineSearchMatch && (this.currentCodeLineSearchMatch.value.rowIndex < firstVisibleIndex || this.currentCodeLineSearchMatch.value.rowIndex > lastVisibleIndex)) {
878-
this.scrollToNode(this.currentCodeLineSearchMatch.value.nodeIdHashed, undefined, false, false);
852+
if (this.codeLineSearchInfo?.currentMatch && (this.codeLineSearchInfo?.currentMatch.value.rowIndex < firstVisibleIndex || this.codeLineSearchInfo?.currentMatch.value.rowIndex > lastVisibleIndex)) {
853+
this.scrollToNode(this.codeLineSearchInfo?.currentMatch.value.nodeIdHashed, undefined, false, false);
879854
this.codePanelRowSource?.adapter?.relax();
880855
}
881-
882856
this.highlightActiveSearchMatch();
883-
this.codeLineSearchInfo = {
884-
currentMatch: currentMatch,
885-
totalMatchCount: this.codeLineSearchInfo?.totalMatchCount
886-
};
887-
this.codeLineSearchInfoEmitter.emit(this.codeLineSearchInfo);
888857
}
889858
}
890859

@@ -963,7 +932,7 @@ export class CodePanelComponent implements OnChanges{
963932
const viewport = this.elementRef.nativeElement.ownerDocument.getElementById('viewport');
964933
if (viewport) {
965934
viewport.addEventListener('scroll', (event) => {
966-
if (this.currentCodeLineSearchMatch) {
935+
if (this.codeLineSearchInfo?.currentMatch) {
967936
this.highlightSearchMatches();
968937
this.highlightActiveSearchMatch(false);
969938
}

src/dotnet/APIView/ClientSPA/src/app/_components/review-page-options/review-page-options.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
<input type="text" [formControl]="codeLineSearchText" pInputText placeholder="Search Review" style="width: 100%; box-sizing: border-box;"/>
7676
</p-iconField>
7777
<div *ngIf="codeLineSearchInfo" class="d-flex justify-content-between">
78-
<small class="review-search-info">{{ codeLineSearchInfo.currentMatch }} of {{ codeLineSearchInfo.totalMatchCount }}</small>
78+
<small class="review-search-info">{{ (codeLineSearchInfo.currentMatch?.index ?? 0) + 1 }} of {{ codeLineSearchInfo.totalMatchCount }}</small>
7979
<span class="mt-2">
8080
<i class="bi bi-arrow-up-short border rounded-start review-search-icon" (click)="navigateSearch(-1)"></i>
8181
<i class="bi bi-arrow-down-short border review-search-icon" (click)="navigateSearch(1)"></i>

src/dotnet/APIView/ClientSPA/src/app/_components/review-page-options/review-page-options.component.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class ReviewPageOptionsComponent implements OnInit, OnChanges {
5050
@Output() diffNavaigationEmitter : EventEmitter<CodeLineRowNavigationDirection> = new EventEmitter<CodeLineRowNavigationDirection>();
5151
@Output() copyReviewTextEmitter : EventEmitter<boolean> = new EventEmitter<boolean>();
5252
@Output() codeLineSearchTextEmitter : EventEmitter<string> = new EventEmitter<string>();
53-
@Output() codeLineSearchNaviationEmmiter : EventEmitter<number> = new EventEmitter<number>();
53+
@Output() codeLineSearchInfoEmmiter : EventEmitter<CodeLineSearchInfo> = new EventEmitter<CodeLineSearchInfo>();
5454

5555
private destroy$ = new Subject<void>();
5656

@@ -374,9 +374,17 @@ export class ReviewPageOptionsComponent implements OnInit, OnChanges {
374374
* @param number
375375
*/
376376
navigateSearch(number: 1 | -1) {
377-
const navigationPosition = this.codeLineSearchInfo?.currentMatch! + number;
378-
if (navigationPosition >= 1 && navigationPosition <= this.codeLineSearchInfo?.totalMatchCount!) {
379-
this.codeLineSearchNaviationEmmiter.emit(navigationPosition!);
377+
if (number == 1) {
378+
if (!this.codeLineSearchInfo?.currentMatch?.isTail()) {
379+
this.codeLineSearchInfo!.currentMatch = this.codeLineSearchInfo?.currentMatch?.next;
380+
this.codeLineSearchInfoEmmiter.emit(this.codeLineSearchInfo!);
381+
}
382+
}
383+
else {
384+
if (!this.codeLineSearchInfo?.currentMatch?.isHead()) {
385+
this.codeLineSearchInfo!.currentMatch = this.codeLineSearchInfo?.currentMatch?.prev;
386+
this.codeLineSearchInfoEmmiter.emit(this.codeLineSearchInfo!);
387+
}
380388
}
381389
}
382390

src/dotnet/APIView/ClientSPA/src/app/_components/review-page/review-page.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
[showLineNumbers]="showLineNumbers" [scrollToNodeIdHashed]="scrollToNodeIdHashed"
3131
[scrollToNodeId]="scrollToNodeId"
3232
[codeLineSearchText]="codeLineSearchText"
33-
[codeLineNavigationDirection]="codeLineNavigationDirection"
33+
[codeLineSearchInfo]="codeLineSearchInfo"
3434
(hasActiveConversationEmitter)="handleHasActiveConversationEmitter($event)"
3535
(codeLineSearchInfoEmitter)="handleCodeLineSearchInfoEmitter($event)"></app-code-panel>
3636
</div>
@@ -66,7 +66,7 @@
6666
(diffNavaigationEmitter)="handleDiffNavaigationEmitter($event)"
6767
(copyReviewTextEmitter)="handleCopyReviewTextEmitter($event)"
6868
(codeLineSearchTextEmitter)="handleCodeLineSearchTextEmitter($event)"
69-
(codeLineSearchNaviationEmmiter)="handleCodeLineSearchNavigationEmitter($event)"></app-review-page-options>
69+
(codeLineSearchInfoEmmiter)="handleCodeLineSearchInfoEmitter($event)"></app-review-page-options>
7070
</div>
7171
</ng-template>
7272
</p-splitter>

src/dotnet/APIView/ClientSPA/src/app/_components/review-page/review-page.component.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class ReviewPageComponent implements OnInit {
5353
preferredApprovers : string[] = [];
5454
hasFatalDiagnostics : boolean = false;
5555
hasActiveConversation : boolean = false;
56-
codeLineSearchInfo : CodeLineSearchInfo | undefined = new CodeLineSearchInfo();
56+
codeLineSearchInfo : CodeLineSearchInfo | undefined;
5757
numberOfActiveConversation : number = 0;
5858
hasHiddenAPIs : boolean = false;
5959
hasHiddenAPIThatIsDiff : boolean = false;
@@ -72,7 +72,6 @@ export class ReviewPageComponent implements OnInit {
7272
lastNodeIdUnhashedDiscarded = '';
7373

7474
codeLineSearchText: string | undefined = undefined;
75-
codeLineNavigationDirection: number | undefined = undefined;
7675

7776
private destroy$ = new Subject<void>();
7877
private destroyLoadAPIRevision$ : Subject<void> | null = null;
@@ -491,16 +490,14 @@ export class ReviewPageComponent implements OnInit {
491490
this.codeLineSearchText = searchText;
492491
}
493492

494-
handleCodeLineSearchNavigationEmitter(direction: number) {
495-
this.codeLineNavigationDirection = direction;
496-
}
497-
498493
handleHasActiveConversationEmitter(value: boolean) {
499494
this.hasActiveConversation = value;
500495
}
501496

502497
handleCodeLineSearchInfoEmitter(value: CodeLineSearchInfo) {
503-
this.codeLineSearchInfo = value;
498+
setTimeout(() => {
499+
this.codeLineSearchInfo = (value) ? new CodeLineSearchInfo(value.currentMatch, value.totalMatchCount) : undefined;
500+
}, 0);
504501
}
505502

506503
handleNumberOfActiveThreadsEmitter(value: number) {

src/dotnet/APIView/ClientSPA/src/app/_helpers/doubly-linkedlist.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,12 @@ export class DoublyLinkedListNode<T> {
2929
this.value = value;
3030
this.index = index;
3131
}
32+
33+
isHead(): boolean {
34+
return this.prev === undefined;
35+
}
36+
37+
isTail(): boolean {
38+
return this.next === undefined;
39+
}
3240
}

src/dotnet/APIView/ClientSPA/src/app/_models/codeLineSearchInfo.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
import { DoublyLinkedListNode } from "../_helpers/doubly-linkedlist";
2+
13
export class CodeLineSearchInfo {
2-
currentMatch?: number;
3-
totalMatchCount?: number
4+
currentMatch?: DoublyLinkedListNode<CodeLineSearchMatch> | undefined;
5+
totalMatchCount?: number;
6+
7+
constructor(currentMatch: DoublyLinkedListNode<CodeLineSearchMatch> | undefined, totalMatchCount: number | undefined) {
8+
this.currentMatch = currentMatch;
9+
this.totalMatchCount = totalMatchCount;
10+
}
411
}
512

613
export class CodeLineSearchMatch {

0 commit comments

Comments
 (0)