diff --git a/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.html b/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.html index 0c5fdca..d5121fe 100644 --- a/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.html +++ b/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.html @@ -1,22 +1,22 @@
- +
diff --git a/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.ts b/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.ts index 084b3a1..30de933 100644 --- a/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.ts +++ b/nietzsche-beta-app/src/app/content-view-tab-component/content-view-tab-component.component.ts @@ -1,82 +1,83 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute, Params, Router} from '@angular/router'; import {Subscription} from "rxjs/index"; import {NavigationServiceService} from "../services/navigation-service.service"; import { TLN_CROSSREF_ROUTE, TLN_MANUSCRIPT_ROUTE, TLN_VIEWER_ROUTE } from '../tln-edition/constants'; @Component({ selector: 'app-content-view-tab-component', templateUrl: './content-view-tab-component.component.html', styleUrls: ['./content-view-tab-component.component.scss'], providers: [ NavigationServiceService ] }) export class ContentViewTabComponentComponent implements OnInit { // navigation tabs for the content view (manuscript view, page view, rhizome view) navTabLinks: any[]; // navbar on th left for navigating navBarOpenState: boolean; - fullscreen: boolean; + fullscreen: boolean = false; navBarOpenMode: string; - queryParams: Params; + queryParams: Params = {}; queryParamSubscription: Subscription; constructor(private router: Router, private activatedRoute: ActivatedRoute, private naviService: NavigationServiceService) { - - - // this.mesurePerformance(); - this.setParamsOnInit(); - - this.navBarOpenMode = 'push'; // side || over || push - // If url pasted or page refreshed --> resetting this.queryparams to the query params of the url; - // needed for active routing in the nav tabs & for general use in the template - this.queryParamSubscription = this.activatedRoute.queryParams.subscribe( (queryParams: Params ) => { - this.queryParams = queryParams; - this.navBarOpenState = JSON.parse(queryParams.navBarOpenState.toLowerCase()); - console.log('new navBaropenstate in content-view ', this.navBarOpenState); - this.fullscreen = JSON.parse(queryParams.fullscreen.toLowerCase()); - }); - - // The links/tabs for routing the correct view-component this.navTabLinks = [ { label: 'Manuskriptansicht', link: TLN_MANUSCRIPT_ROUTE, index: 0 }, { label: 'Seitenansicht', link: TLN_VIEWER_ROUTE, index: 1 }, { label: 'Querverweise', link: TLN_CROSSREF_ROUTE, index: 2 }, ]; + + } ngOnInit() { + // this.mesurePerformance(); + this.setParamsOnInit(); + // The links/tabs for routing the correct view-component + + + this.navBarOpenMode = 'push'; // side || over || push + // If url pasted or page refreshed --> resetting this.queryparams to the query params of the url; + // needed for active routing in the nav tabs & for general use in the template + this.queryParamSubscription = this.activatedRoute.queryParams.subscribe( (queryParams: Params ) => { + this.queryParams = queryParams; + this.navBarOpenState = JSON.parse(queryParams.navBarOpenState.toLowerCase()); + console.log('new navBaropenstate in content-view ', this.navBarOpenState); + this.fullscreen = JSON.parse(queryParams.fullscreen.toLowerCase()); + }); + } mesurePerformance() { const perfData = window.performance.timing; const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart; console.log('content load performance is: ', pageLoadTime); } setParamsOnInit() { const qParams: Params = {}; // Set the NavBarOpenstate to true if it is not defined explicitely as false in the url query param onInit. if (this.activatedRoute.snapshot.queryParamMap.get('navBarOpenState') !== 'false') { console.log('setQParamsOnInit', this.activatedRoute.snapshot.queryParamMap.get('navBarOpenState')) this.navBarOpenState = true; qParams.navBarOpenState = 'true'; } // viewMode if (!this.activatedRoute.snapshot.queryParamMap.get('viewMode')) { qParams.viewMode = 'Transkription/Faksimile'; } this.naviService.updateRoute(qParams); } } diff --git a/nietzsche-beta-app/src/app/page-view/page-view.component.ts b/nietzsche-beta-app/src/app/page-view/page-view.component.ts index 43952f9..1b02618 100644 --- a/nietzsche-beta-app/src/app/page-view/page-view.component.ts +++ b/nietzsche-beta-app/src/app/page-view/page-view.component.ts @@ -1,173 +1,174 @@ import { Component, Input, OnInit, OnChanges} from '@angular/core'; import { externalAssignClass, externalAssignStyle, Configuration, Identifier, Image, Line, TextField, TextByForeignHand, Word} from './models'; /** * This component displays one or two {@link /components/TextFieldComponent.html|TextFieldComponent(s)} * and its or their {@link /components/MarginFieldComponent.html|MarginFieldComponent(s)}. **/ @Component({ selector: 'page-view', templateUrl: './page-view.component.html', styleUrls: ['./page-view.component.css'] }) export class PageViewComponent implements OnInit, OnChanges { @Input() configuration: Configuration; /** * the search text of words that should be highlighted as {@link /miscellaneous/enumerations.html#HIGHTLIGHT_CASES|HIGHTLIGHT_CASES.SEARCHED_WORD}. **/ @Input() findText: string; /** * first texts written by foreign hand **/ @Input() first_foreign_texts: TextByForeignHand[] = []; /** * the first image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() first_image: Image; /** * the Array of lines of the first image that will be displayed by {@link /components/MarginFieldComponent.html|MarginFieldComponent}. **/ @Input() first_lines: Line[]; /** * Identification of first textfield. **/ first_textfield_id: string = 'first textfield' /** * the Array of words of the first image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() first_words: Word[]; /** * the (initial) maximum height of the image(s). **/ @Input() max_height: number = -1; /** * the (initial) maximum width of the image(s). **/ @Input() max_width: number = -1; /** * should primary Url be used for image. Use secondary Url if false. **/ @Input() preferPrimaryUrl: boolean = true; /** * second texts written by foreign hand **/ @Input() second_foreign_texts: TextByForeignHand[] = []; /** * the second image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() second_image: Image; /** * the Array of lines of the second image that will be displayed by {@link /components/MarginFieldComponent.html|MarginFieldComponent}. **/ @Input() second_lines: Line[]; /** * Identification of second textfield. **/ second_textfield_id: string = 'second textfield' /** * the Array of words of the second image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() second_words: Word[]; /** * An optional function that will be passed to {@link /components/TextFieldComponent.html|TextFieldComponent} * in order to return a further highlight class * to the word rects when the internal function would return 'textfield unhighlighted'. **/ @Input('assignClass') assignClass?: externalAssignClass; /** * An optional function that will be passed to {@link /components/TextFieldComponent.html|TextFieldComponent} * and {@link /components/MarginFieldComponent.html|MarginFieldComponent} * in order to return a (svg-)style object * to the word and line rects. This function allows the user to extend the style of this component. * E.g. by returning { fill: blue } the function overwrites the default behaviour and sets * the default highlight color to blue. **/ @Input('assignStyle') assignStyle?: externalAssignStyle; /** * global zoom factor. **/ @Input() zoomFactor: number = 1; /** * identifiers of selected words that should be highlighted. **/ @Input() selectedWords: Identifier[] = []; /** * identifiers of selected lines that should be highlighted. **/ @Input() selectedLines: Identifier[] = []; @Input('startLine') startLineId: Identifier; @Input('endLine') endLineId: Identifier; @Input() dontShowReference: boolean; showReferenceLeft: string = 'from'; showReferenceRight: string = 'to'; constructor() {} /** * sets {@link /components/PageViewComponent.html#max_height|max_height} if it is unset. **/ ngOnInit() { if (this.max_height == -1 && this.max_width == -1){ - this.max_height = screen.availHeight; + this.max_height = screen.availHeight - 40; + console.log(this.max_height); } this.checkImages(); } ngOnChanges(){ if (this.dontShowReference != undefined && this.dontShowReference != null && this.dontShowReference){ this.showReferenceLeft = ''; this.showReferenceRight = ''; } else { this.showReferenceLeft = 'from'; this.showReferenceRight = 'to'; } this.checkImages(); if (this.first_image != null && this.first_image != undefined && this.first_image.transform != null){ this.updateLines(this.first_words, this.first_lines) } if (this.second_image != null && this.second_image != undefined && this.second_image.transform != null){ this.updateLines(this.second_words, this.second_lines) } } private checkImages(){ if (this.first_image != null && this.first_image != undefined && this.startLineId != null && this.startLineId != undefined){ if(this.first_lines != null && this.first_lines != undefined && this.first_lines.length > 0){ this.first_image = this.updateTextField(this.first_image, this.first_lines); } if(this.second_lines != null && this.second_lines != undefined && this.second_lines.length > 0){ this.second_image = this.updateTextField(this.second_image, this.second_lines); } } } private updateLines(words: Word[], lines: Line[]) { for (var i = 0; i < lines.length; i++){ if (words.filter(word =>word.line == lines[i].id).length > 0){ lines[i].top = words.filter(word =>word.line == lines[i].id).map(word =>Number(word.top)).sort(function(a,b){ return a-b; })[0] lines[i].bottom = words.filter(word =>word.line == lines[i].id).map(word =>Number(word.top)+Number(word.height)).sort(function(a,b){ return b-a; })[0] } } } private updateTextField(image: Image, lines: Line[]): Image { let endLineId = (this.endLineId != null && this.endLineId != undefined) ? this.endLineId : this.startLineId; let startLines = lines.filter(line =>line.id == this.startLineId) let endLines = lines.filter(line =>line.id == endLineId) if (startLines.length > 0 && endLines.length > 0){ let top = (startLines[0].top > 10) ? startLines[0].top-10 : startLines[0].top; let height = (endLines[0].bottom-top)+10; let text_field: TextField = { top: top, left: image.text_field.left, width: image.text_field.width, height: height } return { x: image.x, y: image.y, width: image.width, height: image.height, filename: image.filename, URL: image.URL, secondaryURL: image.secondaryURL, text_field: text_field, transform: image.transform, copyright: image.copyright } } return image; } /** * Returns whether the two images can be displayed as columns. **/ private hasColumnStyle(): boolean { if (this.zoomFactor <= 1 || this.first_image == null || this.second_image == null){ return true } let newLeftWidth = this.max_height/this.first_image.text_field.height*this.zoomFactor*this.first_image.text_field.width; let newRightWidth = this.max_height/this.second_image.text_field.height*this.zoomFactor*this.second_image.text_field.width; return newLeftWidth + newRightWidth < screen.availWidth; } } diff --git a/nietzsche-beta-app/src/app/tln-edition/constants.ts b/nietzsche-beta-app/src/app/tln-edition/constants.ts index 92435aa..fdc95ae 100644 --- a/nietzsche-beta-app/src/app/tln-edition/constants.ts +++ b/nietzsche-beta-app/src/app/tln-edition/constants.ts @@ -1,62 +1,66 @@ export {HIGHTLIGHT_CASES} from '../page-view/highlight_status'; export enum VIEW_OPTIONS { TRANSKRIPTION = 'Transkription', FAKSIMILE = 'Faksimile', SYNOPSIS = 'Transkription/Faksimile', SYNOPSIS_B = 'Faksimile/Transkription' } export const DEFAULT_VIEW_OPTION: string = VIEW_OPTIONS.SYNOPSIS_B; export const ONTOLOTY_PREFIX: string = 'http://www.nie.org/ontology/nietzsche#' /** * Route for TlnCrossrefComponent **/ export const TLN_CROSSREF_ROUTE: string = 'tln-crossref'; /** * Route for TlnManuscriptViewComponent **/ export const TLN_MANUSCRIPT_ROUTE: string = 'tln-manuscript'; /** * Route for TlnViewerComponent **/ export const TLN_VIEWER_ROUTE: string = 'tln-viewer'; /** * Param that refers to the context that should be shown, i.e. 'page' or 'manuscript'. **/ export const TLN_CONTEXT_VIEW_PARAM: string = 'contextView'; /** * Param that toggles fullscreen, value type: boolean. **/ export const TLN_FULLSCREEN_PARAM: string = 'fullscreen'; /** * Param for find text in page. **/ export const TLN_FIND_PARAM: string = 'find'; /** * Param for page iri. **/ export const TLN_PAGE_PARAM: string = 'page'; /** * Param for manuscript iri. **/ export const TLN_MANUSCRIPT_PARAM: string = 'manuscript'; +/** + * Param for navigation bar open state. + **/ +export const TLN_NAV_BAR_OPEN_STATE_PARAM: string = 'navBarOpenState'; /** * Param for selected lines. **/ export const TLN_SELECTED_LINES_PARAM: string = 'selectedLines'; /** * Param for selected lines. **/ export const TLN_SELECTED_WORDS_PARAM: string = 'selectedWords'; /** * Param for iri of a genetic order of text versions. **/ export const TLN_TEXT_GENETIC_ORDER_PARAM: string = 'geneticOrder'; /** * Param for selected view option, e.g. 'Transkription', 'Faksimile', etc. **/ export const TLN_VIEW_OPTION_PARAM: string = 'viewMode'; /** * Param for zoom. **/ export const TLN_ZOOM_PARAM: string = 'zoom'; diff --git a/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.html b/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.html index 8239608..aa21eee 100644 --- a/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.html +++ b/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.html @@ -1,51 +1,55 @@ diff --git a/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts b/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts index b3a3b4a..495de00 100644 --- a/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts +++ b/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts @@ -1,162 +1,168 @@ import { Component, OnInit, Input } from '@angular/core'; import { Router, ActivatedRoute, Params } from '@angular/router'; import {MatBottomSheet, MatBottomSheetRef} from '@angular/material/bottom-sheet'; import { TlnQueryServiceInterface, Reference, ManuscriptUnity, NavigationPage } from '../models'; import { TlnManuscriptUnity, TlnNavigationPage} from '../datatypes/navigation'; -import { DEFAULT_VIEW_OPTION, TLN_VIEWER_ROUTE, TLN_FULLSCREEN_PARAM, TLN_FIND_PARAM, TLN_PAGE_PARAM, TLN_MANUSCRIPT_PARAM, +import { DEFAULT_VIEW_OPTION, TLN_VIEWER_ROUTE, TLN_FULLSCREEN_PARAM, TLN_FIND_PARAM, TLN_NAV_BAR_OPEN_STATE_PARAM, TLN_PAGE_PARAM, TLN_MANUSCRIPT_PARAM, TLN_SELECTED_LINES_PARAM, TLN_VIEW_OPTION_PARAM, TLN_ZOOM_PARAM, VIEW_OPTIONS, ONTOLOTY_PREFIX } from '../constants'; import { IsReconstructedKonvolut } from '../datatypes/basic_datatype'; import { TlnLine} from '../datatypes/line'; import { TlnTextGeneticOrder} from '../datatypes/text_version'; import { Mapping } from '../route-reader'; import { RouteUpdater } from '../route-updater'; import { ComplexKeyIriMapping, DataHandler, KeyIriMapping } from '../data_handler'; import { PageViewService, TlnQueryService } from '../services'; import { TlnInformationComponent, ParentInformation } from '../tln-information/tln-information.component'; import { PageInformation } from '../tln-information/page-information'; @Component({ selector: 'tln-viewer-navigation', templateUrl: './tln-viewer-navigation.component.html', styleUrls: ['./tln-viewer-navigation.component.css'] }) export class TlnViewerNavigation extends RouteUpdater { /** * OPTIONAL pass a queryService with method * {@link /interfaces/TlnQueryServiceInterface.html#getData|getData} * to TlnPageViewComponent. **/ @Input() queryService: TlnQueryServiceInterface; /** * whether or not to show page view in fullscreen mode. **/ fullscreen: boolean = false; zoomFactor: number = 1; findText: string; current_iri: string; current_manuscript_iri: string; manuscript_unity: ManuscriptUnity; current_page: NavigationPage; pageInformation: PageInformation; previous_page: NavigationPage; next_page: NavigationPage; + navBarOpenState: boolean; showArchivalManuscriptUnity: boolean = false; dataHandler: DataHandler = new DataHandler(this); geneticOrders: TlnTextGeneticOrder[] = []; selectedLines: string[] = []; private readonly increment: number = 0.333; private readonly decrement: number = this.increment*-1; protected currentRoute: string = TLN_VIEWER_ROUTE; protected mapping: Mapping = { findText: { param: TLN_FIND_PARAM, type: "string" }, current_iri: { param: TLN_PAGE_PARAM, type: "string" }, + navBarOpenState: { param: TLN_NAV_BAR_OPEN_STATE_PARAM, type: "boolean" }, current_manuscript_iri: { param: TLN_MANUSCRIPT_PARAM, type: "string" }, fullscreen: { param: TLN_FULLSCREEN_PARAM, type: "boolean" }, selectedViewOption: { param: TLN_VIEW_OPTION_PARAM, type: "string" }, selectedLines: { param: TLN_SELECTED_LINES_PARAM, type: "string" }, zoomFactor: { param: TLN_ZOOM_PARAM, type: "number" } } routerParams: Params; selectedViewOption: string = DEFAULT_VIEW_OPTION updating: boolean = false; viewOptions: string[] = [ VIEW_OPTIONS.TRANSKRIPTION, VIEW_OPTIONS.FAKSIMILE, VIEW_OPTIONS.SYNOPSIS, VIEW_OPTIONS.SYNOPSIS_B ]; constructor(private bottomSheet: MatBottomSheet, private pageViewService: PageViewService, private localQueryService: TlnQueryService, protected router: Router, protected activatedRoute: ActivatedRoute ) { super(router, activatedRoute); } ngOnInit() { let tlnQueryService = (this.queryService != null) ? this.queryService : this.localQueryService; this.dataHandler.addHandler('manuscript_unity', { 'handler': TlnManuscriptUnity, 'next_key': 'navigation_page'}); this.dataHandler.addHandler('navigation_page', ['current_page', 'geneticOrders'] ); this.dataHandler.addHandler('current_page', { 'handler': TlnNavigationPage }); this.dataHandler.addHandler('geneticOrders', { 'handler': TlnTextGeneticOrder}); this.dataHandler.setQueryService(tlnQueryService); this.dataHandler.start_processing.subscribe( (started: boolean) =>{ this.updating = true; }); this.dataHandler.processing_finished.subscribe( (finished: boolean) =>{ this.updating = false; }); super.ngOnInit(); this.pageViewService.reference.subscribe( (newReference: Reference) => { this.updatePageToReference(newReference) }) this.pageViewService.onClickedLine.subscribe( (clickedLine: TlnLine) => { let index = this.selectedLines.indexOf(clickedLine.id) if (index > -1){ this.selectedLines.splice(index, 1); } else { this.selectedLines.push(clickedLine.id); } this.updateParams(); }); } private clearFindText() { this.findText = ''; this.updateParams(); } private getPageTitle(page?: NavigationPage, numPages?: number): string { if (page == null){ return ''; } let indexPrefix = (numPages != null) ? page.index + '/' + numPages : page.index; return indexPrefix + ': ' + page.title + ' ' + page.number; } private getZoomTitle(changeValue: number): string { if (this.zoomFactor+changeValue < 0){ return Math.round(this.zoomFactor*50) + '%'; } return Math.round((this.zoomFactor+changeValue)*100) + '%'; } protected readParams(params: Params){ super.readParams(params); if (this.dataHandler.ready && (this.current_page == null || this.current_page.id != this.current_iri)){ this.dataHandler.resetData('navigation_page') if(this.current_manuscript_iri != null){ //this.dataHandler.debug = true; this.dataHandler.conditionalAddHandler(IsReconstructedKonvolut.getQuery(this.current_manuscript_iri), 'current_page',{ handler: TlnNavigationPage}, { handler: TlnNavigationPage}); this.dataHandler.getData('manuscript_unity', this.current_manuscript_iri, this.current_iri); } else { this.dataHandler.getData('current_page', this.current_iri); } } } private setZoomFactor(newZoomFactor: number){ if (newZoomFactor > 0){ this.zoomFactor = Math.round(newZoomFactor*100)/100; } else { this.zoomFactor = this.zoomFactor/2 } this.updateParams(); } private setCurrentIri(pageIri: string, manuscriptIir?: string){ this.dataHandler.stop_processing.emit(true); this.current_iri = pageIri; this.updateParams(); } private showInformation() { let parentData: ParentInformation = { geneticOrders: this.geneticOrders, page: this.current_page, manuscript_iri: this.current_manuscript_iri, parentActivatedRoute: this.activatedRoute.parent } this.bottomSheet.open(TlnInformationComponent, { data: parentData }); } private updatePageToReference(reference: Reference){ this.current_iri = reference.page.id; this.selectedLines = [ reference.line.id ] this.updateParams(); } private toggleFullscreen(){ this.fullscreen = !this.fullscreen; this.updateParams(); } public test(iri?: string){ this.bottomSheet.open(TlnInformationComponent); //this.dataHandler.isOfType('showArchivalManuscriptUnity', 'http://rdfh.ch/projects/0068#_Mp_XIV', 'http://www.nie.org/ontology/nietzsche#ArchivalManuscriptUnity') } + toggleNavDrawer(){ + this.navBarOpenState = !this.navBarOpenState; + this.updateParams(); + } }