import {Component, Host, OnInit, ViewChild, ViewChildren} from '@angular/core'; import HostRecord from '../../structures/HostRecord'; import PageRecord from '../../structures/PageRecord'; import {PageService} from '../../service/page.service'; import {ActivatedRoute, Router} from '@angular/router'; import {LoadingController, PopoverController} from '@ionic/angular'; import {NodePickerComponent} from '../../components/editor/node-picker/node-picker.component'; import {HostOptionsComponent} from '../../components/editor/host-options/host-options.component'; @Component({ selector: 'app-editor', templateUrl: './editor.page.html', styleUrls: ['./editor.page.scss'], }) export class EditorPage implements OnInit { public hostRecords: Array = [new HostRecord('Click to edit page...')]; public pageRecord: PageRecord = new PageRecord(); public pageId: string; public visibleButtons: Array = []; @ViewChildren('editorHosts') editorHosts; @ViewChild('titleBar') titleBar; constructor( protected pages: PageService, protected route: ActivatedRoute, protected router: Router, protected popover: PopoverController, protected loader: LoadingController, ) { this.route.params.subscribe(params => { this.pageId = params.id; }); } ngOnInit() {} buttonIsVisible(index) { return this.visibleButtons.includes(index); } makeVisible(index) { if ( !this.buttonIsVisible(index) ) { this.visibleButtons.push(index); } } makeInvisible(index) { this.visibleButtons = this.visibleButtons.filter(x => x !== index); } ionViewDidEnter() { if ( this.pageId ) { this.pages.load(this.pageId).subscribe(pageRecord => { this.pageRecord = pageRecord; this.pages.get_nodes(pageRecord).subscribe((hosts: Array) => { this.hostRecords = hosts; if ( !pageRecord.isViewOnly() ) { this.onSaveClick(); } }); }); } else { this.router.navigate(['/home']); } } onHostRecordChange($event, i) { if ( !this.pageRecord.isViewOnly() ) { this.hostRecords[i] = $event; } } async onAddClick($event) { if ( this.pageRecord.isViewOnly() ) { return; } const popover = await this.popover.create({ component: NodePickerComponent, event: $event, }); popover.onDidDismiss().then(arg => { const defValue = this.getDefaultValue(arg.data); const hostRec = new HostRecord(defValue); hostRec.type = arg.data; hostRec.PageId = this.pageRecord.UUID; if ( hostRec.type === 'ul' ) { hostRec.value = JSON.stringify([{value: '', indentationLevel: 0}]); } this.hostRecords.push(hostRec); if ( hostRec.isNorm() ) { setTimeout(() => { this.editorHosts.toArray().reverse()[0].takeFocus(); }, 0); } else { this.onSaveClick(); } }); await popover.present(); } getDefaultValue(type: string) { if ( type === 'paragraph' ) { return ''; } else if ( type === 'header1' ) { return '# '; } else if ( type === 'header2' ) { return '## '; } else if ( type === 'header3' ) { return '### '; } else if ( type === 'header4' ) { return '#### '; } else if ( type === 'block_code' ) { return '```'; } else if ( type === 'click_link' ) { return 'https://'; } else if ( type === 'page_sep' ) { return '==='; } else { return ''; } } onNewHostRequested($event) { if ( this.pageRecord.isViewOnly() ) { return; } const insertAfter = this.getIndexFromRecord($event.record); const record = new HostRecord(''); const newHosts = [] this.hostRecords.forEach((rec, i) => { newHosts.push(rec); if ( i === insertAfter ) { newHosts.push(record); } }) this.hostRecords = newHosts; setTimeout(() => { this.editorHosts.toArray()[insertAfter + 1].takeFocus(); }, 0); } onDestroyHostRequested($event) { if ( this.pageRecord.isViewOnly() ) { return; } let removedIndex = 0; const newHostRecords = this.editorHosts.filter((host, i) => { if ( $event.record === host.record ) { removedIndex = i; } return host.record !== $event.record; }); const removedHost = this.editorHosts[removedIndex]; const hostRecords = newHostRecords.map(host => host.record); this.hostRecords = hostRecords; setTimeout(() => { let focusIndex; if ( removedIndex === 0 && this.editorHosts.toArray().length ) { focusIndex = 0; } else if ( removedIndex !== 0 ) { focusIndex = removedIndex - 1; } if ( focusIndex >= 0 ) { this.editorHosts.toArray()[focusIndex].takeFocus(false); } }, 0); } protected getIndexFromRecord(record) { let index; this.editorHosts.toArray().forEach((host, i) => { if ( host.record === record ) { index = i; } }); return index; } onSaveClick() { if ( this.pageRecord.isViewOnly() ) { return; } this.loader.create({message: 'Saving changes...'}).then(loader => { loader.present().then(() => { this.pageRecord.Name = this.titleBar.el.innerText.trim(); // First, save the page record itself this.pages.save(this.pageRecord).subscribe(pageRecord => { this.pageRecord = pageRecord; // Now, save the nodes this.pages.save_nodes(pageRecord, this.hostRecords).subscribe(result => { this.hostRecords = result; loader.dismiss(); }); }); }); }); } async onOptionsClick($event, i) { if ( this.pageRecord.isViewOnly() ) { return; } const popover = await this.popover.create({ component: HostOptionsComponent, event: $event, componentProps: { editor: this, index: i, event: $event, hostRecord: this.hostRecords[i], } }); popover.onDidDismiss().then((result) => { if ( result.data === 'delete_node' ) { $event.record = this.hostRecords[i]; this.onDestroyHostRequested($event); } }) await popover.present(); } onEditorKeydown($event) { if ( $event.key === 's' && $event.ctrlKey ) { $event.preventDefault(); this.onSaveClick(); } } }