diff --git a/src/app/services/navigation-service.service.ts b/src/app/services/navigation-service.service.ts index 2da1e25..1be0dd7 100644 --- a/src/app/services/navigation-service.service.ts +++ b/src/app/services/navigation-service.service.ts @@ -1,418 +1,418 @@ import {EventEmitter, Injectable, OnDestroy} from '@angular/core'; import { TlnManuscript, NavigationEntity, TlnPage, TlnEntity, TlnWord, TlnQueryParams, NavTree, Svg, TlnRow } from '../models/models'; import {NietzscheSourceSeviceService} from "./nietzsche-source-sevice.service"; import {Subscription} from "rxjs/index"; import {ActivatedRoute, Params, Router, NavigationEnd, ChildActivationEnd} from '@angular/router'; import {QueryService} from "./query.service"; import {DomSanitizer} from '@angular/platform-browser'; @Injectable({ providedIn: 'root' }) export class NavigationServiceService implements OnDestroy { selectedManuscript: TlnManuscript; selectedPage: TlnPage; queryParams: TlnQueryParams; // Listening to the queries entered actively (so also if page is refreshed or a url loaded) queryParamSubscription: Subscription; viewTabSubscription: Subscription; activeViewTab = ''; constructor(private nietzscheSourceService: NietzscheSourceSeviceService, private router: Router, private sanitizer: DomSanitizer, private activatedRoute: ActivatedRoute, private queryService: QueryService ) { this.queryParams = new TlnQueryParams('', '', '', '', false, 0); // Listening to the queries entered actively (so also if page is refreshed or a url loaded) this.queryParamSubscription = this.activatedRoute.queryParams.subscribe( (queryparams: Params ) => { // set new query params this.queryParams = new TlnQueryParams(queryparams.man, queryparams.page, queryparams.row, queryparams.word, queryparams.navBarOpenState, queryparams.navTreeIndex ); } ); // also listening to changes in viewtab and impose navTreeChange this.viewTabSubscription = this.router.events.subscribe(event => { if (event instanceof ChildActivationEnd) { const regex = new RegExp('\\W'); // for splitting at every non alphanumeric char const newTab = this.router.url.split(regex)[2]; if (this.activeViewTab !== newTab) { this.changeNavTreeOnViewChange(newTab); } } }); this.navTreeIndex = [ { idx: 0, isActive: true, label: 'Manuskripte', treeClass: 'Tln:Manuscript' }, { idx: 1, isActive: false, label: 'Seiten', treeClass: 'TlnPage' }/*, { idx: 2, isActive: false, label: 'Worte', treeClass: 'TlnWord' }*/ ]; } resourceOfInterest: string; // simple iri for Databrowser and rdf stuff to come resourceOfInterestChange = new EventEmitter(); selectedManuscriptChange = new EventEmitter(); selectedPageChange = new EventEmitter(); activeTreeData: Array; activeTreeDataChange = new EventEmitter>(); // if the active tree data changes navTreeIndex: Array; navTreeIndexChange = new EventEmitter>(); // Weather only the index changes manuscriptNavTree: Array = []; manuscriptNavTreeChange = new EventEmitter>(); // internally used pageNavTree: Array = []; pageNavTreeChange = new EventEmitter>(); // internally used /** * setActiveTreeData * Set the active tree data and emits it back to navigation list component, * param: idx:number : the index of the tree data to be displayed. */ setActiveTreeData(idx: number) { switch (idx) { case 0: // Manuscript this.activeTreeData = this.manuscriptNavTree; break; case 1: // Page this.activeTreeData = this.pageNavTree; break; } this.activeTreeDataChange.emit(this.activeTreeData); } /** * updateRoute * Gets the active url without query parameters and routes to the updated query params of this class. */ updateRoute() { const activeUrl = this.router.url.split('?')[0]; // seems workaroundish, but actually safe & secure; no other suitable solution at hand this.router.navigate([activeUrl], { queryParams: this.queryParams }); } /** * changeActiveTreeIndex * Simply changing the active tree index for the navBar in * param: idx:number : the index of the tree which should be displayed. */ changeActiveTreeIndex(idx: number) { // setting all to false first for (const tree of this.navTreeIndex ) { tree.isActive = false; } this.navTreeIndex[idx].isActive = true; this.navTreeIndexChange.emit(this.navTreeIndex); this.setQueryParam('navTreeIndex', idx.toString() ); // also routing according to the chosen thing this.updateRoute(); } /** * changeNavTreeOnViewChange: Changes the active Navigation tree * e.g. if a user changes to page view, the navigation bar should also switch to pages. If Manuscript view is clicked, the navigation bar * should show manuscript items * param: oldView: The view before view changes * param: chengedView: The newly active view * */ changeNavTreeOnViewChange(changedView) { let treeIndex; if ( changedView === 'manuscript' ) { treeIndex = 0; } else { treeIndex = 1; } this.changeActiveTreeIndex(treeIndex); this.setActiveTreeData(treeIndex); this.activeViewTab = changedView; } /** * createNavTreesOnInit creates the first trees if no query params are available in the url: * It ceates the manuscripNavTree and the pageNavTree of the first manuscript per default. * */ createNavTreesOnInit() { this.getManuscriptsToNavTree(); // create the pageNavTree with the first item of manuscriptNavTree AFTER the first TlnManuscript is in the manuscriptNavTree this.manuscriptNavTreeChange.subscribe(tree => { this.getPagesToNavTree(tree[0].tlnEntity.id); this.activeTreeData = tree; this.setActiveTreeData(0); this.changeActiveTreeIndex(0); }); if (!this.selectedManuscript) { // if no manuscript is selected the first entry will be set as selected manuscript; this.manuscriptNavTreeChange.subscribe(manTree => this.setSelectedManuscript(manTree[0].tlnEntity)); } } createManuscriptNavTreeFromRdf() { // TODO: implement this further for switch to RDF data only this.queryService.getQueryfromFilename('getConvolutes.rq').subscribe(qString => { this.queryService.getData(qString, 'SELECT').subscribe(data => { console.log('convolute data: ', data); }); }); } /** * getManuscriptsToNavTree * Gets the convolutes/manuscripts from nietzscheSource and pushes them as NavigationEntitiy objects to the manuscriptNavTree array */ getManuscriptsToNavTree() { this.nietzscheSourceService.getConvolutes().subscribe( res => { const manuscripts = res.result.children; manuscripts.forEach(( man, index ) => { const entity = new TlnEntity(man.id, man.api_retrieve_content, 'man', index, man.id); const manEntity = new NavigationEntity(index, entity, ''); this.manuscriptNavTree.push(manEntity); if (index + 1 === manuscripts.length) { // if everything is pushed to the manuscriptNavTree we emit the new tree to the navigation-list-component this.manuscriptNavTreeChange.emit(this.manuscriptNavTree); } }); } ); } /** * createManuscriptNavTreeFromUrl * Gets the convolutes/manuscripts from nietzscheSource and pushes them as NavigationEntitiy objects to the manuscriptNavTree array * param: params: the query parameters */ createManuscriptNavTreeFromUrl(params) { this.getManuscriptsToNavTree(); this.manuscriptNavTreeChange.subscribe(tree => { tree.forEach(navEntity => { if (navEntity.tlnEntity.id === params.man) { this.setSelectedManuscript(navEntity.tlnEntity); // setting the active tree to the manuscriptNavTree if (params.navTreeIndex === '0') { this.setActiveTreeData(Number(params.navTreeIndex)); } } }); }); } /** * getPagesToNavTree * Gets the pages from a given manuscript to the pageNavTree. Sets the selectedPage to the passed pageId. If no pageId is passed, * the selectedPage will be set to the first page of the given manuscript. * param: manId: the manuscript id for ehich the pages are loaded * param: pageId: the page id which should be set as the selected page */ getPagesToNavTree(manId: string, pageId?: string) { this.pageNavTree = []; this.nietzscheSourceService.getPages(manId).subscribe( res => { const pages = res.result.children; let intIndex = 0; // internal index pages.forEach((p, index) => { // only if the last id part of the id can be converted to a number, it is a single page for which we have use. // (we only transcribe single pages for now if (isNaN( p.id.split(',').pop() ) === false) { const entity = new TlnEntity(p.id, p.api_retrieve_content, 'page', intIndex, p.id ); const pageEntity = new NavigationEntity(intIndex, entity, ''); this.pageNavTree.push(pageEntity); if (!pageId && intIndex === 0) { // if there is no page param passed set the first entry as selected page this.setSelectedPage(this.pageNavTree[0]); } intIndex += 1; if (pageId && p.id === pageId ) { // if the p.id matches the pageId we set that page as selectedPage this.setSelectedPage(pageEntity); } } // else {console.log('skipped double page', p.id); } // if last page has been loaded to pageNavTree we emit to navlist for display and add the additional data from other sources if (index + 1 === pages.length) { this.pageNavTreeChange.emit(this.pageNavTree); console.log('pageNavTree', this.pageNavTree); this.addDataToPageTree(); } }); }); } /** * createNavTreesFromUrlParams * Loads the navigation view & trees accoring to the given query parameters. * param: params: the query parameters */ createNavTreesFromUrlParams(params) { // change active this.changeActiveTreeIndex(Number(params.navTreeIndex)); this.createManuscriptNavTreeFromUrl(params); this.createPageNavTreeFromUrl(params); } setSelectedManuscript(man: TlnEntity) { this.selectedManuscript = new TlnManuscript(man); this.selectedManuscriptChange.emit(this.selectedManuscript); } setSelectedPage(pageData: NavigationEntity ) { this.selectedPage = new TlnPage(pageData.tlnEntity, pageData.tlnEntity.label, pageData.img, pageData.svg); - // this.addPageData(pageData.iri); + this.selectedPageChange.emit(this.selectedPage); } // sets the first page as selected if no selectedPage setSelectedPageIfNone() { if (!this.selectedPage) { this.pageNavTreeChange.subscribe(pageTree => this.setSelectedPage(pageTree[0])); this.pageNavTreeChange.unsubscribe(); } } turnPage(modifier: number) { const newPageIndex = this.selectedPage.entity.navIndex + modifier; this.setSelectedPage(this.pageNavTree[newPageIndex]); } /** * createPageNavTreeFromUrl: Loads all navigation navigation trees according to the given queryParams passed * param: params: the query parameters * */ createPageNavTreeFromUrl(params) { this.getPagesToNavTree(params.man, params.page); // if the active tree === '1' we have to set pageNavTree as active tree if (params.navTreeIndex === '1' ) { // update active tree data each time the pageNavTree changes this.pageNavTreeChange.subscribe(tree => this.setActiveTreeData(Number(params.navTreeIndex))); } } switchTreeIfPageView(activeTab: string) { if ( activeTab === 'page') { // console.log('switching tree hence acivetab ===', activeTab); this.setActiveTreeData(1); this.changeActiveTreeIndex(1); this.setSelectedPageIfNone(); } } onSelectedItem(item: NavigationEntity) { console.log('clicked item: ', item); const activeTab = this.activatedRoute.snapshot['_urlSegment'].children.primary.segments[1].path; switch (item.tlnEntity.type) { case 'man': { // set the new url with the chose man parameter this.getPagesToNavTree(item.tlnEntity.id); // If the active tab is the page view we switch automatically to page tree in navigation this.switchTreeIfPageView(activeTab); this.setSelectedManuscript(item.tlnEntity); this.setQueryParam('man', this.selectedManuscript.entity.id ); // also routing according to the chosen thing break; } case 'page': { this.setSelectedPage(item); this.selectedPageChange.emit(this.selectedPage); this.setQueryParam('page', this.selectedPage.entity.id ); // also routing according to the chosen thing break; } default: { console.log('unknown item.tlnEntity.type: ', item.tlnEntity.type); } } this.updateRoute(); } getSelectedPage() { return this.selectedPage; } setResourceOfInterest(res: string) { this.resourceOfInterest = res; this.resourceOfInterestChange.emit(res); } // adds all file data such as thumbnails as well as imageUrls or svgUrls to the pageNavTree addDataToPageTree() { for (let i = 0; i < this.pageNavTree.length; i++) { this.addFileDataToPageTree(this.pageNavTree[i].tlnEntity.iri, i); } } addFileDataToPageTree(pageIri, index) { this.nietzscheSourceService.getFileUrl(pageIri).subscribe(data => { this.getFileToEntity(data.result.metadata.download_version.thumb, index, 'thumb'); // get thumbnail this.pageNavTree[index].img = data.result.metadata.download_version.medium; // setting the image url // console.log(data.result.metadata); this.setSvgUrl(data.result.metadata.siglum, index); // setting the svg url }); } private setSvgUrl(pageName: string, index) { const baseUrl = 'http://130.60.24.65:8081/exist/rest/db/ProjectData/Nietzsche/svg/'; const pNamepre = pageName.split('-').join('_'); // exchanging '-' with underscore const pName = pNamepre.split(',')[0]; const pNumber = pNamepre.split(',')[1]; const pageZerofilled = ('000' + pNumber).slice(-3); this.pageNavTree[index].svg = baseUrl + pName + '_page' + pageZerofilled + '_web.svg'; } /** * getFileToEntity: Gets a file from a url and adds it to the desired property of a navigation entity * param: url: the query parameters * param: index: the index of the navTree entity to update * param: prop: The property which will be set, e.g. 'thumb' for navEntity.thumb */ getFileToEntity(url: string, index: number, prop: string) { this.nietzscheSourceService.getFileFromUrl(url).subscribe(file => { const reader = new FileReader(); reader.addEventListener('load', () => { if ( this.pageNavTree[index] ) { this.pageNavTree[index][prop] = reader.result; } }, false); if (file) { reader.readAsDataURL(file); } this.pageNavTreeChange.emit(this.pageNavTree); }); } getFullImage(pageIri: string) { this.nietzscheSourceService.getFileUrl(pageIri).subscribe(data => { this.nietzscheSourceService.getFileFromUrl(data.result.metadata.download_version.medium).subscribe(img => { const reader = new FileReader(); reader.addEventListener('load', () => { if ( this.selectedPage ) { this.selectedPage.image = reader.result; } }, false); if (img) { reader.readAsDataURL(img); } this.selectedPageChange.emit(this.selectedPage); }); }); } // sets queryParams: to the queryParam object setQueryParam(type: string, value: string) { this.queryParams[type] = value; // this.queryParamsChange.emit(this.queryParams); } ngOnDestroy() { // unsubscribe to subscriptions if component change so there is no memory leak this.queryParamSubscription.unsubscribe(); } }