multi color comment support

This commit is contained in:
Hlars 2025-05-06 21:54:46 +02:00
parent 2190cc06e4
commit ca90d1c422
3 changed files with 37 additions and 11 deletions

View File

@ -29,10 +29,16 @@
]" (overlayOutsideClick)="clickOutsideMenu($event)">
<div class="mat-mdc-menu-panel" #menuContent>
<div class="mat-mdc-menu-content">
@if (filteredSelectionList.length > 0) {
@for (item of filteredSelectionList; track item; let index_ = $index) {
<div class="mat-mdc-menu-item mat-focus-indicator"
[class.mat-mdc-menu-item-highlighted]="index_ === selectedDropdownItemIndex"
[class.active]="index_ === selectedDropdownItemIndex" (click)="clickMention(index_)">{{item}}
[class.active]="index_ === selectedDropdownItemIndex" (click)="clickMention(index_)">{{item.title}}
</div>
}
} @else {
<div class="mat-mdc-menu-item mat-focus-indicator">
Keine Übereinstimmung...
</div>
}
</div>

View File

@ -8,11 +8,13 @@
}
.mention {
--mention-color: blue;
display: inline-block;
position: relative;
&:not(.ignore) {
color: blue;
color: var(--mention-color);
background-color: transparent;
font-style: italic;
font-size: 0.8rem;

View File

@ -9,6 +9,11 @@ import { OverlayModule } from '@angular/cdk/overlay';
import { DOWN_ARROW, ENTER, ESCAPE, TAB, UP_ARROW } from '@angular/cdk/keycodes';
import { Cursor, MentionHandleResult } from './cursor';
export interface MentionItem {
title: string,
color?: string,
}
@Component({
selector: 'app-comment-box',
imports: [MatMenuModule, OverlayModule],
@ -155,7 +160,7 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
@ViewChild('commentInput') _commentInputRef!: ElementRef;
@ViewChild('menuContent') _menuContent!: ElementRef;
@Input() mentionListItems: string[] = [];
@Input() mentionListItems: MentionItem[] = [];
selectedDropdownItemIndex = 0;
menuOffsetX = 0;
@ -163,7 +168,7 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
menuOpenAboveYShift = 0;
isOpen = false;
filteredSelectionList: string[] = [];
filteredSelectionList: MentionItem[] = [];
handleKeyEvent(event: KeyboardEvent) {
if (this.isOpen) {
@ -180,9 +185,16 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
this.removeFocusedMention(event.target as HTMLInputElement);
event.preventDefault();
break;
case ENTER || TAB:
case ENTER:
case TAB:
if (this.filteredSelectionList[this.selectedDropdownItemIndex]) {
this.addMention(event.target as HTMLInputElement);
this.handleTextChanged(true, 1);
} else {
this.removeFocusedMention(event.target as HTMLInputElement);
this.isOpen = false;
}
event.preventDefault();
break;
}
@ -230,7 +242,7 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
// filter menu entries
let searchQuery = focusedMentionElement.textContent?.substring(1);
this.filteredSelectionList = this.mentionListItems.filter((element) => element.toLocaleLowerCase().includes(searchQuery?.toLocaleLowerCase() ?? ""))
this.filteredSelectionList = this.mentionListItems.filter((element) => element.title.toLocaleLowerCase().includes(searchQuery?.toLocaleLowerCase() ?? ""))
if (this.selectedDropdownItemIndex > this.filteredSelectionList.length - 1)
this.selectedDropdownItemIndex = this.filteredSelectionList.length - 1;
@ -245,11 +257,12 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
handleMentionElements(innerHtml: string): MentionHandleResult {
let newOffset = null;
innerHtml = innerHtml.replace(/(?<!(<div class[ \t]*=[ \t]*"[^"]*mention[^"]*">|\w))@\w*/g, (match) => {
// innerHtml = innerHtml.replace(/(?<!(<div class[ \t]*=[ \t]*"[^"]*mention[^"]*">|\w))@\w*/g, (match) => {
innerHtml = innerHtml.replace(/(?<!(<div class[ \t]*=[ \t]*"[^"]*mention[^"]*"[ \t]*(style[ \t]*=[ \t]*".*[ \t]*")?>|\w))@\w*/g, (match) => {
newOffset = match.length;
return `<div class="${Cursor.focusedClassName} ignore mention">${match}</div>`;
});
console.log(innerHtml)
// remove old focus classes if match was found
if (newOffset) {
innerHtml = innerHtml.replaceAll(/class="focused"/g, "");
@ -303,14 +316,19 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
}
addMention(element: HTMLElement) {
const mentionItem = this.filteredSelectionList[this.selectedDropdownItemIndex];
let focusedMention = element.querySelector(`.mention.${Cursor.focusedClassName}`);
let focusedElements = element.querySelectorAll(Cursor.focusedClassName);
if (focusedMention) {
// set text and remove ignore to style mention
focusedMention.textContent = `@${this.filteredSelectionList[this.selectedDropdownItemIndex]}`;
focusedMention.textContent = `@${mentionItem.title}`;
focusedMention.classList.remove(Cursor.focusedClassName);
focusedMention.classList.remove("ignore")
if (mentionItem.color)
focusedMention.setAttribute('style', `--mention-color:${mentionItem.color}`)
// remove all old focused classes
for (let node of focusedElements) {
node.classList.remove(Cursor.focusedClassName);