Browse Source

added restoring of unsaved notes and added tooltips for locations

Warafear 6 months ago
parent
commit
ca0c16f130

+ 38 - 16
src/app/journal/journal-notes/journal-notes.component.ts

@@ -17,6 +17,7 @@ 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 { NotesService } from 'src/services/notes/notes.service';
 
 @Component({
   selector: 'app-journal-notes',
@@ -53,7 +54,7 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
 
   public tooltipText: string = '';
 
-  public npcDescriptions: any = {};
+  public descriptions: any = {};
 
   tooltipifiedEntry: JournalEntry = {
     title: 'Title',
@@ -61,9 +62,10 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     created: new Date(),
   };
 
-  private _adapter: DateAdapter<any> = inject(DateAdapter);
   private dataService: DataService = inject(DataService);
   private tooltipService: TooltipService = inject(TooltipService);
+  private notesService: NotesService = inject(NotesService);
+  private _adapter: DateAdapter<any> = inject(DateAdapter);
   private renderer: Renderer2 = inject(Renderer2);
   private el: ElementRef = inject(ElementRef);
 
@@ -72,8 +74,13 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     this._adapter.setLocale('de');
     this.entries = this.dataService.notesData;
 
-    // if the list is empty, set the currentIndex to -1 to hide the entry-container
-    if (this.entries.length === 0) {
+    if (this.notesService.isUnsaved) {
+      const { entry, index, isNewEntry } = this.notesService.getEntry();
+      this.currentEntry = entry;
+      this.currentIndex = index;
+      this.isNewEntry = isNewEntry;
+      this.isInEditMode = true;
+    } else if (this.entries.length === 0) {
       this.currentIndex = -1;
     } else {
       this.selectEntry(0);
@@ -89,7 +96,6 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
    * @param index The index of the selected entry.
    */
   public selectEntry(index: number): void {
-    // hier
     if (this.isInEditMode || index !== this.currentIndex) {
       this.currentIndex = index;
       this.currentEntry = this.getEntryAt(index);
@@ -138,6 +144,7 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     this.entries[this.currentIndex] = this.currentEntry;
     this.tooltipify();
     this.uploadNotes();
+    this.notesService.markAsSaved();
   }
 
   /**
@@ -156,6 +163,7 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
     }
     this.isInEditMode = false;
     this.tooltipify();
+    this.notesService.markAsSaved();
   }
 
   /**
@@ -202,27 +210,32 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
       this.getEntryAt(this.currentIndex).content,
     );
 
+    console.log(result.content);
+
     this.tooltipifiedEntry.content = result.content;
-    this.npcDescriptions = result.npcDescriptions;
+    console.log(result.descriptions);
+
+    this.descriptions = result.descriptions;
+    console.log(result.identifiers);
+
     setTimeout(() => {
-      result.npcs.forEach((name: string) => {
+      result.identifiers.forEach((name: string) => {
         this.addHighlightsToText(name);
       });
     });
   }
 
   /**
-   * 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.
+   * Adds a highlight component to the persons and locations that are mentioned in the current entry.
+   * @param identifier The name of the person or location which is currently highlighted.
    */
-  private addHighlightsToText(name: string) {
+  private addHighlightsToText(identifier: string) {
     // get all elements where a highlight component should be added to
-    const parent = this.el.nativeElement.querySelectorAll('.' + name);
+    const parent = this.el.nativeElement.querySelectorAll('.' + identifier);
     parent.forEach((element: any) => {
       const componentRef =
         this.creationAnchor.createComponent(HighlightComponent);
-      componentRef.instance.text = name;
+      componentRef.instance.text = identifier;
       componentRef.instance.tooltip = this.tooltip;
       this.renderer.appendChild(element, componentRef.location.nativeElement);
       // add a mouseover event listener to the highlight component, when it is hovered over, the tooltip-text is set
@@ -230,13 +243,22 @@ export class JournalNotesComponent implements OnInit, OnDestroy {
         componentRef.location.nativeElement,
         'mouseover',
         () => {
-          this.tooltipText = this.npcDescriptions[name];
+          this.tooltipText = this.descriptions[identifier];
         },
       );
     });
   }
 
-  ngOnDestroy(): void {
-    this.editor.destroy();
+  /**
+   * Saves unsaved changes to restore them when visiting the page the next time.
+   */
+  ngOnDestroy() {
+    if (this.isInEditMode) {
+      this.notesService.setEntry(
+        this.currentEntry,
+        this.currentIndex,
+        this.isNewEntry,
+      );
+    }
   }
 }

+ 0 - 2
src/app/journal/journal.module.ts

@@ -101,7 +101,6 @@ import { CustomSpellsModalComponent } from './journal-spellbook/custom-spells-mo
 import { DurationPipe } from '../../pipes/duration/duration.pipe';
 import { CombinedComponent } from './journal-character/combined/combined.component';
 import { DividerComponent } from '../shared-components/divider/divider.component';
-import { TooltipDirective } from 'src/directives/tooltip/tooltip.directive';
 
 @NgModule({
   declarations: [
@@ -207,7 +206,6 @@ import { TooltipDirective } from 'src/directives/tooltip/tooltip.directive';
     NgbCollapseModule,
     MatButtonToggleModule,
     MatIconModule,
-    TooltipDirective,
     NgbTooltipModule,
   ],
 })

+ 1 - 1
src/app/shared-components/highlight/highlight.component.html

@@ -1 +1 @@
-<span [ngbTooltip]="tooltip!" tooltipClass="my-custom-class">{{ text }}</span>
+<span [ngbTooltip]="tooltip!" tooltipClass="tooltip-styles">{{ text }}</span>

+ 2 - 1
src/assets/i18n/de.json

@@ -73,7 +73,8 @@
     "deleteSelected": "Ausgewählte löschen",
     "addToFavorites": "Zu Favoriten hinzufügen",
     "alradyInFavorites": "Bereits in Favoriten",
-    "finalDelete": "Endgültig löschen?"
+    "finalDelete": "Endgültig löschen?",
+    "consume": "Verbrauchen"
   },
   "time": {
     "none": "Keine Kosten",

+ 3 - 2
src/assets/i18n/en.json

@@ -70,7 +70,8 @@
     "close": "Close",
     "discard": "Discard",
     "export": "Export",
-    "deleteSelected": "Delete Selected"
+    "deleteSelected": "Delete Selected",
+    "consume": "Consume"
   },
   "time": {
     "none": "No cost",
@@ -707,7 +708,7 @@
     "weight": "Weight",
     "value": "Value",
     "quantity": "Quanitty",
-    "ready": "Ready to eat",
+    "ready": "Ready",
     "total": "Total Weight",
     "description": "Description",
     "modal": {

+ 16 - 0
src/services/notes/notes.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { NotesService } from './notes.service';
+
+describe('NotesService', () => {
+  let service: NotesService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(NotesService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 53 - 0
src/services/notes/notes.service.ts

@@ -0,0 +1,53 @@
+import { Injectable } from '@angular/core';
+import { JournalEntry } from 'src/interfaces/interfaces';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class NotesService {
+  public isUnsaved: boolean = false;
+
+  private isNewEntry: boolean = false;
+
+  private unsavedEntry: JournalEntry | null = null;
+
+  private unsavedIndex: number = -1;
+
+  /**
+   * Stores the unsaved entry and the index where it can be found.
+   * @param entry The entry that was edited but not yet saved.
+   * @param index The index of the entry in the entries list.
+   */
+  public setEntry(
+    entry: JournalEntry,
+    index: number,
+    isNewEntry: boolean,
+  ): void {
+    this.unsavedEntry = entry;
+    this.unsavedIndex = index;
+    this.isNewEntry = isNewEntry;
+    this.isUnsaved = true;
+  }
+
+  /**
+   * Returns the entry that was edited but not yet saved when leaving the notes view.
+   * @returns The unsaved entry and its index.
+   */
+  public getEntry(): { [key: string]: any } {
+    return {
+      entry: this.unsavedEntry,
+      index: this.unsavedIndex,
+      isNewEntry: this.isNewEntry,
+    };
+  }
+
+  /**
+   * Marks the entry as saved and resets the unsaved entry and index.
+   */
+  public markAsSaved(): void {
+    this.isUnsaved = false;
+    this.unsavedEntry = null;
+    this.isNewEntry = false;
+    this.unsavedIndex = -1;
+  }
+}

+ 43 - 11
src/services/tooltip/tooltip.service.ts

@@ -9,9 +9,9 @@ export class TooltipService {
   private dataService: DataService = inject(DataService);
 
   public tooltipifyEntry(entry: string): any {
-    const content = this.replaceNpcs(entry);
-    const matches = entry.match(/(?<=@)\w+/g);
-    const uniqueMatches = [...new Set(matches)];
+    const content = this.replaceIdentifiers(entry);
+    const personMatches = entry.match(/(?<=@)\w+/g);
+    const uniquePersons = [...new Set(personMatches)];
     // get the descriptions from the data service
     const npcs = this.dataService.npcs;
     const npcArray = Object.keys(npcs)
@@ -19,27 +19,59 @@ export class TooltipService {
       .flat();
     let npcsDescription: any = {};
 
-    uniqueMatches.forEach((name) => {
+    uniquePersons.forEach((person) => {
       const npc = npcArray.find(
-        (npc: Npc) => npc.name === name || npc.identifier === name,
+        (npc: Npc) => npc.name === person || npc.identifier === person,
       );
       if (npc) {
         // Add it to the npcDescription object
-        npcsDescription[name] = npc.shortDescription;
+        npcsDescription[person] = npc.shortDescription;
       } else {
         // Add a placeholder to the npcDescription object
-        npcsDescription[name] = 'Keine Person mit diesem Name gefunden.';
+        npcsDescription[person] = 'Keine Person mit diesem Name gefunden.';
+      }
+    });
+
+    const locationsMatches = entry.match(/(?<=#)\w+/g);
+    const uniqueLocations = [...new Set(locationsMatches)];
+    // get the descriptions from the data service
+    const locationArray = this.dataService.places;
+    // const locationArray = Object.keys(locations)
+    //   .map((key) => locations[key])
+    //   .flat();
+    let locationsDescription: any = {};
+
+    uniqueLocations.forEach((location) => {
+      const loc = locationArray.find(
+        (loc) => loc.name === location || loc.identifier === location,
+      );
+      if (loc) {
+        // Add it to the npcDescription object
+        locationsDescription[location] = loc.shortDescription;
+      } else {
+        // Add a placeholder to the npcDescription object
+        locationsDescription[location] = 'Kein Ort mit diesem Name gefunden.';
       }
     });
 
     return {
       content: content,
-      npcs: uniqueMatches,
-      npcDescriptions: npcsDescription,
+      identifiers: [...uniquePersons, ...uniqueLocations],
+      descriptions: { ...npcsDescription, ...locationsDescription },
     };
   }
 
-  private replaceNpcs(content: string): string {
-    return content.replace(/@(\w+)/g, "<span class='$1'></span>");
+  private replaceIdentifiers(content: string): string {
+    content = content.replace(/@(\w+)/g, "<span class='$1'></span>");
+    content = content.replace(/#(\w+)/g, "<span class='$1'></span>");
+    return content;
   }
+
+  // private replaceNpcs(content: string): string {
+  //   return content.replace(/@(\w+)/g, "<span class='$1'></span>");
+  // }
+
+  // private replaceLocations(content: string): string {
+  //   return content.replace(/#(\w+)/g, "<span class='$1'></span>");
+  // }
 }