diff --git a/CHANGELOG.md b/CHANGELOG.md index 77bf53a1a..35b684186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Sampling declaration visualization - Project description visualization - Encoding description visualization +- Image-image visualization - Critical edition navigation - Project Info modal - Notes statement visualization diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 7a2ed2473..738e9f405 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CollationComponent } from './view-modes/collation/collation.component'; +import { ImageImageComponent } from './view-modes/image-image/image-image.component'; import { ImageTextComponent } from './view-modes/image-text/image-text.component'; import { ReadingTextComponent } from './view-modes/reading-text/reading-text.component'; import { TextSourcesComponent } from './view-modes/text-sources/text-sources.component'; @@ -11,6 +12,7 @@ const appRoutes: Routes = [ { path: 'imageText', component: ImageTextComponent }, { path: 'readingText', component: ReadingTextComponent }, { path: 'textText', component: TextTextComponent }, + { path: 'imageImage', component: ImageImageComponent }, { path: 'collation', component: CollationComponent }, { path: 'textSources', component: TextSourcesComponent }, { path: 'textVersions', component: TextVersionsComponent }, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9959dcaf8..d974eb318 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -114,6 +114,7 @@ import { XMLParsers } from './services/xml-parsers/xml-parsers'; import { ShortcutsComponent } from './shortcuts/shortcuts.component'; import { MsDescSectionComponent } from './ui-components/ms-desc-section/ms-desc-section.component'; import { CollationComponent } from './view-modes/collation/collation.component'; +import { ImageImageComponent } from './view-modes/image-image/image-image.component'; import { ImageTextComponent } from './view-modes/image-text/image-text.component'; import { ReadingTextComponent } from './view-modes/reading-text/reading-text.component'; import { TextSourcesComponent } from './view-modes/text-sources/text-sources.component'; @@ -161,6 +162,7 @@ export function initializeApp(appConfig: AppConfig) { HtmlAttributesDirective, HumanizePipe, IdentifierComponent, + ImageImageComponent, ImagePanelComponent, ImageTextComponent, LbComponent, diff --git a/src/app/components/osd/osd.component.ts b/src/app/components/osd/osd.component.ts index f8c0d82ce..970a69aca 100644 --- a/src/app/components/osd/osd.component.ts +++ b/src/app/components/osd/osd.component.ts @@ -100,7 +100,7 @@ export class OsdComponent implements AfterViewInit, OnDestroy { @Input() set page(v: number) { if (v !== this._page) { this._page = v; - this.pageChange.next(this._page); + this.pageChange.next(this._page + 1); } } @@ -174,4 +174,5 @@ export class OsdComponent implements AfterViewInit, OnDestroy { ngOnDestroy(): void { this.subscriptions.forEach((s) => s.unsubscribe()); } + } diff --git a/src/app/panels/image-panel/image-panel.component.html b/src/app/panels/image-panel/image-panel.component.html index 6b192a5f7..482538e18 100644 --- a/src/app/panels/image-panel/image-panel.component.html +++ b/src/app/panels/image-panel/image-panel.component.html @@ -1,21 +1,33 @@ - +
- - + + + {{ item.label || item.url.split('/').pop().split('.')[0] }} + + +
+ [viewerData]="viewerData" + [page]="imageIndex" + (pageChange)="eventPageImg($event)">

Found no source file

-
-
- +
+
+ +
diff --git a/src/app/panels/image-panel/image-panel.component.spec.ts b/src/app/panels/image-panel/image-panel.component.spec.ts index 4499d7d2c..a6e99b9ca 100644 --- a/src/app/panels/image-panel/image-panel.component.spec.ts +++ b/src/app/panels/image-panel/image-panel.component.spec.ts @@ -8,7 +8,7 @@ describe('ImagePanelComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [ ImagePanelComponent ] + declarations: [ ImagePanelComponent ], }) .compileComponents(); })); diff --git a/src/app/panels/image-panel/image-panel.component.ts b/src/app/panels/image-panel/image-panel.component.ts index 7e4b84b88..ae03369b9 100644 --- a/src/app/panels/image-panel/image-panel.component.ts +++ b/src/app/panels/image-panel/image-panel.component.ts @@ -1,6 +1,5 @@ -import { Component, Input } from '@angular/core'; -import { BehaviorSubject, combineLatest } from 'rxjs'; -import { filter, map } from 'rxjs/operators'; +import { HttpClient } from '@angular/common/http'; +import { ChangeDetectorRef, Component, Input } from '@angular/core'; import { ViewerDataType } from '../../models/evt-models'; import { EVTModelService } from '../../services/evt-model.service'; @@ -12,24 +11,74 @@ import { EVTModelService } from '../../services/evt-model.service'; export class ImagePanelComponent { @Input() viewerData: ViewerDataType; - currentMsDescId$ = new BehaviorSubject(undefined); - currentMsDesc$ = combineLatest([this.evtModelService.msDesc$, this.currentMsDescId$]).pipe( - filter(([msDesc, currentId]) => !!msDesc && !!currentId), - map(([msDesc, currentId]) => msDesc.find(m => m.id === currentId)), - ); - - msDescOpen = false; + get imageIndex() { return this._imageIndex; } constructor( - private evtModelService: EVTModelService, + public evtModelService: EVTModelService, + public http: HttpClient, + private cdref: ChangeDetectorRef, ) { } + public msDesc$ = this.evtModelService.msDesc$; + public showSecondaryContent = false; + public selectedPage; + public msDescID = ''; + public value: number; + public images = []; + public currentImg: string; + // tslint:disable-next-line: variable-name + private _imageIndex: number; + public manifest; + public imagePath; + public filename; + + toggleImg(event){ + this._imageIndex = this.images.indexOf(event); + } + + eventPageImg(pageImg: number){ + if (this.viewerData?.type === 'manifest'){ + this.currentImg = this.images[pageImg - 1].label; + } + if (this.viewerData?.type === 'default' || this.viewerData?.type === 'graphics'){ + this.currentImg = this.images[pageImg - 1].url.split('/').pop().split('.')[0]; + } + this.cdref.detectChanges(); + } - setMsDescOpen(isOpen: boolean) { - this.msDescOpen = isOpen; + // tslint:disable-next-line: use-lifecycle-interface + ngOnChanges() { + if (this.viewerData?.type === 'manifest'){ + this.manifest = this.viewerData.value?.manifestURL; + // tslint:disable-next-line: no-any + this.http.get(`${this.manifest}`).subscribe((item: any) => { + item.sequences.forEach((value) => { + this.images.push(...value.canvases); + }); + this.currentImg = this.images[0].label; + }); + } + if (this.viewerData?.type === 'default' || this.viewerData?.type === 'graphics'){ + this.images = this.viewerData?.value?.xmlImages; + this.imagePath = this.viewerData?.value?.xmlImages[0]?.url; + this.filename = this.imagePath.split('/').pop().split('.')[0]; + this.currentImg = this.filename; + } + else { + this.currentImg = 'Error loading'; + } } - setMsDescID(msDescId: string) { - this.currentMsDescId$.next(msDescId); + isSecondaryContentOpened(): boolean { + return this.showSecondaryContent; } + + isMsDescOpen(event: boolean){ + this.showSecondaryContent = event; + } + + setMsDescID(idMsDesc: string){ + this.msDescID = idMsDesc; + } + } diff --git a/src/app/ui-components/icon/icon.component.scss b/src/app/ui-components/icon/icon.component.scss index 26ecc8583..a7e0b6bbc 100644 --- a/src/app/ui-components/icon/icon.component.scss +++ b/src/app/ui-components/icon/icon.component.scss @@ -78,6 +78,10 @@ content: "\e91c"; } +.evt-icon-imgImg:before { + content: "\e92b"; +} + .evt-icon-txt:before { content: "\e92e"; } diff --git a/src/app/view-modes/image-image/image-image.component.html b/src/app/view-modes/image-image/image-image.component.html new file mode 100644 index 000000000..847541257 --- /dev/null +++ b/src/app/view-modes/image-image/image-image.component.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/app/view-modes/image-image/image-image.component.scss b/src/app/view-modes/image-image/image-image.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/view-modes/image-image/image-image.component.spec.ts b/src/app/view-modes/image-image/image-image.component.spec.ts new file mode 100644 index 000000000..e32a9e02b --- /dev/null +++ b/src/app/view-modes/image-image/image-image.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImageImageComponent } from './image-image.component'; + +describe('ImageImageComponent', () => { + let component: ImageImageComponent; + let fixture: ComponentFixture; + + beforeEach(async() => { + await TestBed.configureTestingModule({ + declarations: [ ImageImageComponent ], + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ImageImageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/view-modes/image-image/image-image.component.ts b/src/app/view-modes/image-image/image-image.component.ts new file mode 100644 index 000000000..2d7946aa2 --- /dev/null +++ b/src/app/view-modes/image-image/image-image.component.ts @@ -0,0 +1,64 @@ +import { Component, OnInit } from '@angular/core'; +import { DisplayGrid, GridsterConfig, GridsterItem, GridType } from 'angular-gridster2'; +import { map } from 'rxjs/operators'; +import { AppConfig } from '../../app.config'; +import { Surface, ViewerDataType, XMLImagesValues } from '../../models/evt-models'; +import { ViewerSource } from '../../models/evt-polymorphic-models'; +import { EVTModelService } from '../../services/evt-model.service'; + +@Component({ + selector: 'evt-image-image', + templateUrl: './image-image.component.html', + styleUrls: ['./image-image.component.scss'], +}) +export class ImageImageComponent implements OnInit { + public layoutOptions: GridsterConfig = {}; + public imagePanel1Item: GridsterItem = { cols: 1, rows: 1, y: 0, x: 0 }; + public imagePanel2Item: GridsterItem = { cols: 1, rows: 1, y: 0, x: 1 }; + + public imageViewer$ = this.evtModelService.surfaces$.pipe( + map((surface) => this.getImageViewerType(AppConfig.evtSettings.files.editionImagesSource, surface)), + ); + + constructor( + private evtModelService: EVTModelService, + ) { + } + + getImageViewerType(editionImages, surface: Surface[]): ViewerDataType { + for (const key of Object.keys(editionImages)) { + if (editionImages[key].enabled) { + return ViewerSource.getDataType(key, surface); + } + } + const xmlImages: XMLImagesValues[] = []; + this.evtModelService.pages$.pipe().subscribe( + (pages) => pages.map(page => xmlImages.push({ url: page.facsUrl }), + )); + + return { type: 'default', value: { xmlImages } }; + } + + ngOnInit() { + this.initGridster(); + } + + private initGridster() { + this.layoutOptions = { + gridType: GridType.Fit, + displayGrid: DisplayGrid.None, + margin: 0, + maxCols: 2, + maxRows: 1, + draggable: { + enabled: true, + ignoreContent: true, + dragHandleClass: 'panel-header', + }, + resizable: { + enabled: false, + }, + }; + } + +} diff --git a/src/app/view-modes/image-text/image-text.component.spec.ts b/src/app/view-modes/image-text/image-text.component.spec.ts index 71c1c937d..e8de44b27 100644 --- a/src/app/view-modes/image-text/image-text.component.spec.ts +++ b/src/app/view-modes/image-text/image-text.component.spec.ts @@ -8,7 +8,7 @@ describe('ImageTextComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [ ImageTextComponent ] + declarations: [ ImageTextComponent ], }) .compileComponents(); })); diff --git a/src/assets/config/edition_config.json b/src/assets/config/edition_config.json index a2c863fcf..baa762ff0 100644 --- a/src/assets/config/edition_config.json +++ b/src/assets/config/edition_config.json @@ -108,6 +108,12 @@ "id": "textText", "label": "Text Text" }, + { + "icon": "imgImg", + "iconSet": "evt", + "id": "imageImage", + "label": "Image Image" + }, { "icon": "collation", "iconSet": "evt", diff --git a/src/assets/fonts/evt-icons.eot b/src/assets/fonts/evt-icons.eot index 60a39e2f5..ce50c997c 100755 Binary files a/src/assets/fonts/evt-icons.eot and b/src/assets/fonts/evt-icons.eot differ diff --git a/src/assets/fonts/evt-icons.svg b/src/assets/fonts/evt-icons.svg index 040331ad8..3311fa4a0 100755 --- a/src/assets/fonts/evt-icons.svg +++ b/src/assets/fonts/evt-icons.svg @@ -61,7 +61,12 @@ + + + + + diff --git a/src/assets/fonts/evt-icons.ttf b/src/assets/fonts/evt-icons.ttf index 04361acb1..c90314d75 100755 Binary files a/src/assets/fonts/evt-icons.ttf and b/src/assets/fonts/evt-icons.ttf differ diff --git a/src/assets/fonts/evt-icons.woff b/src/assets/fonts/evt-icons.woff index 7520004c7..c3db50ba8 100755 Binary files a/src/assets/fonts/evt-icons.woff and b/src/assets/fonts/evt-icons.woff differ diff --git a/src/styles.scss b/src/styles.scss index 02b317f3e..bc16a76f4 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -152,6 +152,10 @@ body { } } +.imgSelect { + width: 10rem; +} + .overflow-y-auto { overflow-y: auto; }