Procházet zdrojové kódy

fixed a bug that added multiple instances of tooltips to names on reselting the same entry

Warafear před 6 měsíci
rodič
revize
39aa234d6f

+ 1 - 12
src/app/journal/journal-notes/journal-notes.component.html

@@ -1,17 +1,6 @@
 <div class="entries-list">
   <div class="title t-0">{{ "notes.sessions" | translate }}</div>
   <divider appearance="gold-2" style="padding: 0 1rem"></divider>
-
-  <button
-    type="button"
-    class="btn btn-outline-secondary"
-    (click)="addHighlightsToText('Edeltraut')"
-  >
-    I've got markup and bindings in my tooltip!
-  </button>
-
-  <!-- TODO: Delete or make display: none -->
-  <div #test>Hallo, ich hoffe hier wird gleich was rein geschrieben...</div>
   <!-- Add Button or temporary unsaved new entry -->
   @if (isNewEntry) {
     <div class="entry active">
@@ -110,7 +99,6 @@
           </div>
         </div>
         <divider appearance="gold-2"></divider>
-        <!-- <div class="content-read" [innerHTML]="currentEntry.content"></div> -->
         <div class="content-read" [innerHTML]="tooltipifiedEntry.content"></div>
       </div>
     }
@@ -139,3 +127,4 @@
   </div>
 }
 <ng-template #tooltip><div [innerHTML]="tooltipText"></div></ng-template>
+<div #creationAnchor></div>

+ 69 - 79
src/app/journal/journal-notes/journal-notes.component.ts

@@ -3,7 +3,6 @@ import {
   OnInit,
   OnDestroy,
   inject,
-  ComponentFactoryResolver,
   TemplateRef,
   ViewChild,
   ViewContainerRef,
@@ -18,7 +17,6 @@ import { registerLocaleData } from '@angular/common';
 import { DataService } from 'src/services/data/data.service';
 import { TooltipService } from 'src/services/tooltip/tooltip.service';
 import { HighlightComponent } from 'src/app/shared-components/highlight/highlight.component';
-import { DomSanitizer } from '@angular/platform-browser';
 
 @Component({
   selector: 'app-journal-notes',
@@ -26,12 +24,12 @@ import { DomSanitizer } from '@angular/platform-browser';
   styleUrl: './journal-notes.component.scss',
 })
 export class JournalNotesComponent implements OnInit, OnDestroy {
+  /** Reference to the tooltip */
   @ViewChild('tooltip', { read: TemplateRef }) tooltip!: TemplateRef<any>;
-  @ViewChild('test', { read: ViewContainerRef }) test!: ViewContainerRef;
 
-  tooltipText = 'Initial';
-
-  public npcDescriptions: any = {};
+  /** Reference to the creation anchor */
+  @ViewChild('creationAnchor', { read: ViewContainerRef })
+  creationAnchor!: ViewContainerRef;
 
   editor: Editor = new Editor();
   toolbar: any = [
@@ -41,20 +39,21 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     [{ heading: ['h3', 'h4', 'h5', 'h6'] }],
   ];
 
-  /** Used to show the interactale form or the display version of an entry. */
-  public isInEditMode = false;
+  public entries: JournalEntry[] = [];
+  public currentEntry: JournalEntry = {
+    title: '',
+    content: '',
+    created: new Date(),
+  };
 
-  /** The index of the currently active entry */
+  public isInEditMode = false;
   public currentEntryIndex: number = 0;
-
   private backupIndex: number = -1;
-  /** Indicates, if the currentEntry is a newly generated one that is still not saved. */
   public isNewEntry = false;
 
-  /**The array of JournalEntries, synched to the   */
-  public entries: JournalEntry[] = [];
+  public tooltipText: string = '';
 
-  public tooltipifiedEntries: JournalEntry[] = [];
+  public npcDescriptions: any = {};
 
   tooltipifiedEntry: JournalEntry = {
     title: 'Title',
@@ -62,17 +61,9 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     created: new Date(),
   };
 
-  /** Holds the data for the current entry */
-  public currentEntry: JournalEntry = {
-    title: '',
-    content: '',
-    created: new Date(),
-  };
-
   private _adapter: DateAdapter<any> = inject(DateAdapter);
   private dataService: DataService = inject(DataService);
   private tooltipService: TooltipService = inject(TooltipService);
-  private sanitizer: DomSanitizer = inject(DomSanitizer);
   private renderer: Renderer2 = inject(Renderer2);
   private el: ElementRef = inject(ElementRef);
 
@@ -80,7 +71,6 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     registerLocaleData(localeDe);
     this._adapter.setLocale('de');
     this.entries = this.dataService.notesData;
-    this.tooltipifiedEntries = this.entries;
 
     // if the list is empty, set the currentEntryIndex to -1 to hide the entry-container
     if (this.entries.length === 0) {
@@ -92,23 +82,28 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     this.tooltipify();
   }
 
+  // ACTIONS FROM THE TEMPLATE
+
   /**
    * Sets the currentEntry variable when being clicked on in the entries list on the left.
+   * It also modifies the content of the entry by highlighting names and adding tooltips.
+   * Is only called when the entry is not in edit mode or a different entry is selected.
    * @param index The index of the selected entry.
    */
   public selectEntry(index: number): void {
-    this.currentEntryIndex = index;
-    this.currentEntry = this.getEntryAt(index);
-    this.isNewEntry = false;
-    this.isInEditMode = false;
-    // this.tooltipify();
-    this.collectNamesFromEntry().forEach((name) => {
-      this.addHighlightsToText(name);
-    });
+    if (this.isInEditMode || index !== this.currentEntryIndex) {
+      this.currentEntryIndex = index;
+      this.currentEntry = this.getEntryAt(index);
+      this.isNewEntry = false;
+      this.isInEditMode = false;
+      this.tooltipify();
+    }
   }
 
-  // DONE
-  addEntry(): void {
+  /**
+   * Adds an new empty entry, switches to edit mode and removes the highlighting of the selected entry.
+   */
+  public addEntry(): void {
     this.currentEntry = {
       title: '',
       content: '',
@@ -121,11 +116,18 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     this.currentEntryIndex = -1;
   }
 
+  /**
+   * Switches to edit mode.
+   */
   public editEntry(): void {
     this.isInEditMode = true;
   }
 
-  // DONE
+  /**
+   * If the current entry is a new entry, it will be prepended to the entries list.
+   * Else it is saved at the current index.
+   * The content is the tooltipified and saved in the database.
+   */
   public saveEntry(): void {
     if (this.isNewEntry) {
       // Prepend the new JournalEntry
@@ -139,6 +141,11 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     this.uploadNotes();
   }
 
+  /**
+   * Discards the current entry and resets the currentEntry to the last saved version.
+   * If the entry was a new entry, the currentEntryIndex is reset to the last selected entry.
+   * The content is also tooltipified again.
+   */
   public discardEntry(): void {
     if (this.isNewEntry) {
       this.currentEntryIndex = this.backupIndex;
@@ -149,8 +156,14 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
       this.currentEntry = this.getEntryAt(this.currentEntryIndex);
     }
     this.isInEditMode = false;
+    this.tooltipify();
   }
 
+  /**
+   * Deletes the current entry and removes it from the entries list.
+   * If the last entry was deleted, the currentEntryIndex is reset to -1.
+   * The content is saved in the database.
+   */
   public deleteEntry(): void {
     this.entries.splice(this.currentEntryIndex, 1);
     if (this.entries.length === 0) {
@@ -158,93 +171,70 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     } else {
       this.currentEntryIndex = Math.max(this.currentEntryIndex - 1, 0);
       this.currentEntry = this.getEntryAt(this.currentEntryIndex);
+      // Update the tooltipified entry
+      this.tooltipify();
     }
     this.uploadNotes();
   }
 
+  /**
+   * Returns a deep copy of the entry at the given index.
+   * @param index Defines the index of the entry that should be returned.
+   * @returns A deep copy of the entry at the given index.
+   */
   private getEntryAt(index: number): JournalEntry {
     return JSON.parse(JSON.stringify(this.entries[index]));
   }
 
+  /**
+   * Saves the current entries in the data service.
+   */
   private uploadNotes(): void {
     this.dataService.notesData = this.entries;
   }
 
-  ////////////////////////////////////////////////////
-
   /**
    * Converts the content of the current entry to a tooltipified version.
-   * Is called on everyx refresh of an entry
+   * It then adds the highlights to the names and sets the tooltip text.
+   * Is called on every refresh of an entry (selecting, saving, discarding, deleting, adding, etc.)
    */
-  tooltipify() {
+  public tooltipify(): void {
     let result: any = this.tooltipService.tooltipifyEntry(
-      JSON.parse(JSON.stringify(this.currentEntry.content)),
+      this.getEntryAt(this.currentEntryIndex).content,
     );
-    console.log(result.npcDescriptions);
+
     this.tooltipifiedEntry.content = result.content;
     this.npcDescriptions = result.npcDescriptions;
-
-    console.log(this.npcDescriptions);
-
-    // console.log(result.content);
-    // console.log(this.tooltipifiedEntry);
-
     setTimeout(() => {
       result.npcs.forEach((name: string) => {
         this.addHighlightsToText(name);
       });
-    }, 10);
-
-    // result.forEach((entry: any) => {
-    //   entry.content = this.sanitizer.bypassSecurityTrustHtml(entry.content);
-    // });
-    // this.tooltipifiedEntries = result;
-  }
-
-  /**
-   * Searches the current entry for names that are mentioned in the text.
-   * @returns An array of all the names that are mentioned in the current entry.
-   */
-  private collectNamesFromEntry(): string[] {
-    const matches = this.currentEntry.content.match(/(?<=@)\w+/g);
-    const uniqueMatches = [...new Set(matches)];
-    return uniqueMatches;
+    });
   }
 
   /**
+   * Adds a highlight component to the names that are mentioned in the current entry.
    * Highlights and adds tooltips to the names that are mentioned in the current entry.
    * @param name The name of the person which is currently highlighted.
    */
-  addHighlightsToText(name: string) {
-    console.log('Highlighting: ' + name);
-
-    // Target the correct containers
+  private addHighlightsToText(name: string) {
+    // get all elements where a highlight component should be added to
     const parent = this.el.nativeElement.querySelectorAll('.' + name);
-    console.log(parent);
-
     parent.forEach((element: any) => {
-      const componentRef = this.test.createComponent(HighlightComponent);
-      // The name
+      const componentRef =
+        this.creationAnchor.createComponent(HighlightComponent);
       componentRef.instance.text = name;
-      // A reference to the tooltip template
       componentRef.instance.tooltip = this.tooltip;
-      // Appends it at the right spot
       this.renderer.appendChild(element, componentRef.location.nativeElement);
-      // add a mouseover event listener to the highlight component
+      // add a mouseover event listener to the highlight component, when it is hovered over, the tooltip-text is set
       this.renderer.listen(
         componentRef.location.nativeElement,
         'mouseover',
         () => {
-          console.log('Mouseover on: ' + name);
-          console.log(this.npcDescriptions);
-
           this.tooltipText = this.npcDescriptions[name];
         },
       );
     });
-    // Modufies the text inside the tooltip template
-    // Muss auf mouseover erfolgen
-    // this.tooltipText = 'Neuer Tooltip <b>text</b>';
   }
 
   ngOnDestroy(): void {

+ 3 - 2
src/services/tooltip/tooltip.service.ts

@@ -17,7 +17,6 @@ export class TooltipService {
     const npcArray = Object.keys(npcs)
       .map((key) => npcs[key])
       .flat();
-    console.log(npcArray);
     let npcsDescription: any = {};
 
     uniqueMatches.forEach((name) => {
@@ -25,9 +24,11 @@ export class TooltipService {
         (npc: Npc) => npc.name === name || npc.identifier === name,
       );
       if (npc) {
-        console.log('NPC data found: ', npc);
         // Add it to the npcDescription object
         npcsDescription[name] = npc.shortDescription;
+      } else {
+        // Add a placeholder to the npcDescription object
+        npcsDescription[name] = 'Keine Person mit diesem Name gefunden.';
       }
     });