123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- import {
- Component,
- OnInit,
- OnDestroy,
- inject,
- TemplateRef,
- ViewChild,
- ViewContainerRef,
- Renderer2,
- ElementRef,
- } from '@angular/core';
- import { Editor } from 'ngx-editor';
- import { DateAdapter } from '@angular/material/core';
- import { JournalEntry } from 'src/interfaces/interfaces';
- import localeDe from '@angular/common/locales/de';
- 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';
- @Component({
- selector: 'app-journal-notes',
- templateUrl: './journal-notes.component.html',
- styleUrl: './journal-notes.component.scss',
- })
- export class JournalNotesComponent implements OnInit, OnDestroy {
- /** Reference to the tooltip */
- @ViewChild('tooltip', { read: TemplateRef }) tooltip!: TemplateRef<any>;
- /** Reference to the creation anchor */
- @ViewChild('creationAnchor', { read: ViewContainerRef })
- creationAnchor!: ViewContainerRef;
- editor: Editor = new Editor();
- toolbar: any = [
- // default value
- ['bold', 'italic'],
- ['bullet_list'],
- [{ heading: ['h3', 'h4', 'h5', 'h6'] }],
- ];
- public entries: JournalEntry[] = [];
- public currentEntry: JournalEntry = {
- title: '',
- content: '',
- created: new Date(),
- };
- public isInEditMode = false;
- public currentIndex: number = -1;
- private backupIndex: number = -1;
- public isNewEntry = false;
- public tooltipText: string = '';
- public npcDescriptions: any = {};
- tooltipifiedEntry: JournalEntry = {
- title: 'Title',
- content: 'Content',
- created: new Date(),
- };
- private _adapter: DateAdapter<any> = inject(DateAdapter);
- private dataService: DataService = inject(DataService);
- private tooltipService: TooltipService = inject(TooltipService);
- private renderer: Renderer2 = inject(Renderer2);
- private el: ElementRef = inject(ElementRef);
- ngOnInit(): void {
- registerLocaleData(localeDe);
- 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) {
- this.currentIndex = -1;
- } else {
- this.selectEntry(0);
- }
- }
- // 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 {
- // hier
- if (this.isInEditMode || index !== this.currentIndex) {
- this.currentIndex = index;
- this.currentEntry = this.getEntryAt(index);
- this.isNewEntry = false;
- this.isInEditMode = false;
- this.tooltipify();
- }
- }
- /**
- * Adds an new empty entry, switches to edit mode and removes the highlighting of the selected entry.
- */
- public addEntry(): void {
- this.currentEntry = {
- title: '',
- content: '',
- created: new Date(),
- };
- this.isNewEntry = true;
- this.isInEditMode = true;
- this.backupIndex = this.currentIndex;
- // Hightlight no entry because the placeholder is shown as active
- this.currentIndex = -1;
- }
- /**
- * Switches to edit mode.
- */
- public editEntry(): void {
- this.isInEditMode = true;
- }
- /**
- * 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
- this.entries.unshift(this.currentEntry);
- this.isNewEntry = false;
- this.currentIndex = 0;
- }
- this.isInEditMode = false;
- this.entries[this.currentIndex] = this.currentEntry;
- this.tooltipify();
- this.uploadNotes();
- }
- /**
- * Discards the current entry and resets the currentEntry to the last saved version.
- * If the entry was a new entry, the currentIndex is reset to the last selected entry.
- * The content is also tooltipified again.
- */
- public discardEntry(): void {
- if (this.isNewEntry) {
- this.currentIndex = this.backupIndex;
- this.isNewEntry = false;
- }
- if (this.entries.length > 0) {
- // Reset the currentEntry to the last saved version
- this.currentEntry = this.getEntryAt(this.currentIndex);
- }
- this.isInEditMode = false;
- this.tooltipify();
- }
- /**
- * Deletes the current entry and removes it from the entries list.
- * If the last entry was deleted, the currentIndex is reset to -1.
- * The content is saved in the database.
- */
- public deleteEntry(): void {
- this.entries.splice(this.currentIndex, 1);
- if (this.entries.length === 0) {
- this.currentIndex = -1;
- } else {
- this.currentIndex = Math.max(this.currentIndex - 1, 0);
- this.currentEntry = this.getEntryAt(this.currentIndex);
- // 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.
- * 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.)
- */
- public tooltipify(): void {
- let result: any = this.tooltipService.tooltipifyEntry(
- this.getEntryAt(this.currentIndex).content,
- );
- this.tooltipifiedEntry.content = result.content;
- this.npcDescriptions = result.npcDescriptions;
- setTimeout(() => {
- result.npcs.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.
- */
- private addHighlightsToText(name: string) {
- // get all elements where a highlight component should be added to
- const parent = this.el.nativeElement.querySelectorAll('.' + name);
- parent.forEach((element: any) => {
- const componentRef =
- this.creationAnchor.createComponent(HighlightComponent);
- componentRef.instance.text = name;
- 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
- this.renderer.listen(
- componentRef.location.nativeElement,
- 'mouseover',
- () => {
- this.tooltipText = this.npcDescriptions[name];
- },
- );
- });
- }
- ngOnDestroy(): void {
- this.editor.destroy();
- }
- }
|