From d4107e3f9aea1761b5c7fb01e14b42f4b0bbf142 Mon Sep 17 00:00:00 2001 From: Michael Spalti Date: Wed, 21 Sep 2022 12:13:10 -0700 Subject: [PATCH 1/4] Initial update for multiple bundle check. --- .../mirador-viewer.component.spec.ts | 5 ++ .../mirador-viewer.component.ts | 10 ++- .../mirador-viewer/mirador-viewer.service.ts | 74 +++++++++++++------ 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/app/item-page/mirador-viewer/mirador-viewer.component.spec.ts b/src/app/item-page/mirador-viewer/mirador-viewer.component.spec.ts index 645d2af91d..40ad0fd5d0 100644 --- a/src/app/item-page/mirador-viewer/mirador-viewer.component.spec.ts +++ b/src/app/item-page/mirador-viewer/mirador-viewer.component.spec.ts @@ -12,6 +12,7 @@ import { createPaginatedList } from '../../shared/testing/utils.test'; import { of as observableOf } from 'rxjs'; import { MiradorViewerService } from './mirador-viewer.service'; import { HostWindowService } from '../../shared/host-window.service'; +import { BundleDataService } from '../../core/data/bundle-data.service'; function getItem(metadata: MetadataMap) { @@ -46,6 +47,7 @@ describe('MiradorViewerComponent with search', () => { declarations: [MiradorViewerComponent], providers: [ { provide: BitstreamDataService, useValue: {} }, + { provide: BundleDataService, useValue: {} }, { provide: HostWindowService, useValue: mockHostWindowService } ], schemas: [NO_ERRORS_SCHEMA] @@ -108,6 +110,7 @@ describe('MiradorViewerComponent with multiple images', () => { declarations: [MiradorViewerComponent], providers: [ { provide: BitstreamDataService, useValue: {} }, + { provide: BundleDataService, useValue: {} }, { provide: HostWindowService, useValue: mockHostWindowService } ], schemas: [NO_ERRORS_SCHEMA] @@ -167,6 +170,7 @@ describe('MiradorViewerComponent with a single image', () => { declarations: [MiradorViewerComponent], providers: [ { provide: BitstreamDataService, useValue: {} }, + { provide: BundleDataService, useValue: {} }, { provide: HostWindowService, useValue: mockHostWindowService } ], schemas: [NO_ERRORS_SCHEMA] @@ -225,6 +229,7 @@ describe('MiradorViewerComponent in development mode', () => { set: { providers: [ { provide: MiradorViewerService, useValue: viewerService }, + { provide: BundleDataService, useValue: {} }, { provide: HostWindowService, useValue: mockHostWindowService } ] } diff --git a/src/app/item-page/mirador-viewer/mirador-viewer.component.ts b/src/app/item-page/mirador-viewer/mirador-viewer.component.ts index 8876d2cea0..bcc50c5ed4 100644 --- a/src/app/item-page/mirador-viewer/mirador-viewer.component.ts +++ b/src/app/item-page/mirador-viewer/mirador-viewer.component.ts @@ -8,6 +8,7 @@ import { map, take } from 'rxjs/operators'; import { isPlatformBrowser } from '@angular/common'; import { MiradorViewerService } from './mirador-viewer.service'; import { HostWindowService, WidthCategory } from '../../shared/host-window.service'; +import { BundleDataService } from '../../core/data/bundle-data.service'; @Component({ selector: 'ds-mirador-viewer', @@ -55,6 +56,7 @@ export class MiradorViewerComponent implements OnInit { constructor(private sanitizer: DomSanitizer, private viewerService: MiradorViewerService, private bitstreamDataService: BitstreamDataService, + private bundleDataService: BundleDataService, private hostWindowService: HostWindowService, @Inject(PLATFORM_ID) private platformId: any) { } @@ -120,8 +122,12 @@ export class MiradorViewerComponent implements OnInit { }) ); } else { - // Sets the multi value based on the image count. - this.iframeViewerUrl = this.viewerService.getImageCount(this.object, this.bitstreamDataService).pipe( + // Sets the multi value based on the image count. Any count greater than 1 + // will add the right thumbnail navigation panel to the viewer. + this.iframeViewerUrl = this.viewerService.getImageCount( + this.object, + this.bitstreamDataService, + this.bundleDataService).pipe( map(c => { if (c > 1) { this.multi = true; diff --git a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts index 4bb095b89f..639c8b3d4e 100644 --- a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts +++ b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts @@ -2,13 +2,15 @@ import { Injectable, isDevMode } from '@angular/core'; import { Observable } from 'rxjs'; import { Item } from '../../core/shared/item.model'; import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; -import { last, map, switchMap } from 'rxjs/operators'; +import { filter, last, map, switchMap } from 'rxjs/operators'; import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { Bitstream } from '../../core/shared/bitstream.model'; import { BitstreamFormat } from '../../core/shared/bitstream-format.model'; import { BitstreamDataService } from '../../core/data/bitstream-data.service'; import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { Bundle } from '../../core/shared/bundle.model'; +import { BundleDataService } from '../../core/data/bundle-data.service'; @Injectable() export class MiradorViewerService { @@ -26,32 +28,56 @@ export class MiradorViewerService { } /** - * Returns observable of the number of images in the ORIGINAL bundle + * Returns observable of the number of images found in eligible IIIF bundles. This checks + * only the first 5 bitstreams in each bundle since any count greater than one is + * enough to set the IIIF viewer to use the "multi" image layout. * @param item * @param bitstreamDataService + * @param bundleDataService */ - getImageCount(item: Item, bitstreamDataService: BitstreamDataService): Observable { + getImageCount(item: Item, bitstreamDataService: BitstreamDataService, bundleDataService: BundleDataService): + Observable { let count = 0; - return bitstreamDataService.findAllByItemAndBundleName(item, 'ORIGINAL', { - currentPage: 1, - elementsPerPage: 10 - }, true, true, ...this.LINKS_TO_FOLLOW) - .pipe( - getFirstCompletedRemoteData(), - map((bitstreamsRD: RemoteData>) => bitstreamsRD.payload), - map((paginatedList: PaginatedList) => paginatedList.page), - switchMap((bitstreams: Bitstream[]) => bitstreams), - switchMap((bitstream: Bitstream) => bitstream.format.pipe( - getFirstSucceededRemoteDataPayload(), - map((format: BitstreamFormat) => format) - )), - map((format: BitstreamFormat) => { - if (format.mimetype.includes('image')) { - count++; - } - return count; - }), - last() - ); + return bundleDataService.findAllByItem(item).pipe( + getFirstCompletedRemoteData(), + map((bundlesRD: RemoteData>) => bundlesRD.payload), + map((paginatedList: PaginatedList) => paginatedList.page), + switchMap((bundles: Bundle[]) => bundles), + filter((b: Bundle) => this.isIiifBundle(b.name)), + switchMap((bundle: Bundle) => { + return bitstreamDataService.findAllByItemAndBundleName(item, bundle.name, { + currentPage: 1, + elementsPerPage: 5 + }, true, true, ...this.LINKS_TO_FOLLOW).pipe( + getFirstCompletedRemoteData(), + map((bitstreamsRD: RemoteData>) => bitstreamsRD.payload), + map((paginatedList: PaginatedList) => paginatedList.page), + switchMap((bitstreams: Bitstream[]) => bitstreams), + switchMap((bitstream: Bitstream) => bitstream.format.pipe( + getFirstSucceededRemoteDataPayload(), + map((format: BitstreamFormat) => format) + )), + map((format: BitstreamFormat) => { + if (format.mimetype.includes('image')) { + count++; + } + return count; + }), + last() + ); + })); } + + isIiifBundle(bundleName: string): boolean { + return !( + bundleName === 'OtherContent' || + bundleName === 'LICENSE' || + bundleName === 'THUMBNAIL' || + bundleName === 'TEXT' || + bundleName === 'METADATA' || + bundleName === 'CC-LICENSE' || + bundleName === 'BRANDED_PREVIEW' + ); + } + } From cc3f570da7357c4cb9d5a3484119c9a6fa8aaad1 Mon Sep 17 00:00:00 2001 From: Michael Spalti Date: Wed, 21 Sep 2022 12:16:22 -0700 Subject: [PATCH 2/4] Updated comments. --- .../mirador-viewer/mirador-viewer.component.ts | 12 ++++++------ .../mirador-viewer/mirador-viewer.service.ts | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/app/item-page/mirador-viewer/mirador-viewer.component.ts b/src/app/item-page/mirador-viewer/mirador-viewer.component.ts index bcc50c5ed4..fee8046272 100644 --- a/src/app/item-page/mirador-viewer/mirador-viewer.component.ts +++ b/src/app/item-page/mirador-viewer/mirador-viewer.component.ts @@ -109,10 +109,10 @@ export class MiradorViewerComponent implements OnInit { this.notMobile = !(category === WidthCategory.XS || category === WidthCategory.SM); }); - // We need to set the multi property to true if the - // item is searchable or when the ORIGINAL bundle contains more - // than 1 image. (The multi property determines whether the - // Mirador side thumbnail navigation panel is shown.) + // Set the multi property. The default mirador configuration adds a right + // thumbnail navigation panel to the viewer when multi is 'true'. + + // Set the multi property to 'true' if the item is searchable. if (this.searchable) { this.multi = true; const observable = of(''); @@ -122,8 +122,8 @@ export class MiradorViewerComponent implements OnInit { }) ); } else { - // Sets the multi value based on the image count. Any count greater than 1 - // will add the right thumbnail navigation panel to the viewer. + // Set the multi property based on the image count in IIIF-eligible bundles. + // Any count greater than 1 sets the value to 'true'. this.iframeViewerUrl = this.viewerService.getImageCount( this.object, this.bitstreamDataService, diff --git a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts index 639c8b3d4e..68be928cfa 100644 --- a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts +++ b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts @@ -28,12 +28,12 @@ export class MiradorViewerService { } /** - * Returns observable of the number of images found in eligible IIIF bundles. This checks - * only the first 5 bitstreams in each bundle since any count greater than one is - * enough to set the IIIF viewer to use the "multi" image layout. + * Returns observable of the number of images found in eligible IIIF bundles. Checks + * the mimetype of the first 5 bitstreams in each bundle. * @param item * @param bitstreamDataService * @param bundleDataService + * @returns the total image count */ getImageCount(item: Item, bitstreamDataService: BitstreamDataService, bundleDataService: BundleDataService): Observable { From 60bcfe8cf57f43413336889642813d51a8d0b2b3 Mon Sep 17 00:00:00 2001 From: Michael W Spalti Date: Wed, 28 Sep 2022 09:11:03 -0700 Subject: [PATCH 3/4] Correction in the image count method. --- .../mirador-viewer/mirador-viewer.service.ts | 68 +++++++++++-------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts index 68be928cfa..06e5aa4ced 100644 --- a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts +++ b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts @@ -1,8 +1,10 @@ import { Injectable, isDevMode } from '@angular/core'; import { Observable } from 'rxjs'; import { Item } from '../../core/shared/item.model'; -import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; -import { filter, last, map, switchMap } from 'rxjs/operators'; +import { + getFirstCompletedRemoteData, +} from '../../core/shared/operators'; +import { filter, last, map, mergeMap, switchMap } from 'rxjs/operators'; import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { Bitstream } from '../../core/shared/bitstream.model'; @@ -36,36 +38,44 @@ export class MiradorViewerService { * @returns the total image count */ getImageCount(item: Item, bitstreamDataService: BitstreamDataService, bundleDataService: BundleDataService): - Observable { - let count = 0; - return bundleDataService.findAllByItem(item).pipe( - getFirstCompletedRemoteData(), - map((bundlesRD: RemoteData>) => bundlesRD.payload), - map((paginatedList: PaginatedList) => paginatedList.page), - switchMap((bundles: Bundle[]) => bundles), - filter((b: Bundle) => this.isIiifBundle(b.name)), - switchMap((bundle: Bundle) => { - return bitstreamDataService.findAllByItemAndBundleName(item, bundle.name, { - currentPage: 1, - elementsPerPage: 5 - }, true, true, ...this.LINKS_TO_FOLLOW).pipe( + Observable { + let count = 0; + return bundleDataService.findAllByItem(item).pipe( getFirstCompletedRemoteData(), - map((bitstreamsRD: RemoteData>) => bitstreamsRD.payload), - map((paginatedList: PaginatedList) => paginatedList.page), - switchMap((bitstreams: Bitstream[]) => bitstreams), - switchMap((bitstream: Bitstream) => bitstream.format.pipe( - getFirstSucceededRemoteDataPayload(), - map((format: BitstreamFormat) => format) - )), - map((format: BitstreamFormat) => { - if (format.mimetype.includes('image')) { - count++; - } - return count; + map((bundlesRD: RemoteData>) => { + return bundlesRD.payload + }), + map((paginatedList: PaginatedList) => paginatedList.page), + switchMap((bundles: Bundle[]) => bundles), + filter((b: Bundle) => this.isIiifBundle(b.name)), + mergeMap((bundle: Bundle) => { + return bitstreamDataService.findAllByItemAndBundleName(item, bundle.name, { + currentPage: 1, + elementsPerPage: 5 + }, true, true, ...this.LINKS_TO_FOLLOW).pipe( + getFirstCompletedRemoteData(), + map((bitstreamsRD: RemoteData>) => { + return bitstreamsRD.payload; + }), + map((paginatedList: PaginatedList) => paginatedList.page), + switchMap((bitstreams: Bitstream[]) => bitstreams), + switchMap((bitstream: Bitstream) => bitstream.format.pipe( + getFirstCompletedRemoteData(), + map((formatRD: RemoteData) => { + return formatRD.payload + }), + map((format: BitstreamFormat) => { + if (format.mimetype.includes('image')) { + count++; + } + return count; + }), + ) + ) + ); }), last() - ); - })); + ); } isIiifBundle(bundleName: string): boolean { From 42bb39d097c7a0f4257a304ce7ec9f5c7315f8b8 Mon Sep 17 00:00:00 2001 From: Michael W Spalti Date: Wed, 28 Sep 2022 09:18:03 -0700 Subject: [PATCH 4/4] Missing semicolon. --- src/app/item-page/mirador-viewer/mirador-viewer.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts index 06e5aa4ced..c7a0affd53 100644 --- a/src/app/item-page/mirador-viewer/mirador-viewer.service.ts +++ b/src/app/item-page/mirador-viewer/mirador-viewer.service.ts @@ -43,7 +43,7 @@ export class MiradorViewerService { return bundleDataService.findAllByItem(item).pipe( getFirstCompletedRemoteData(), map((bundlesRD: RemoteData>) => { - return bundlesRD.payload + return bundlesRD.payload; }), map((paginatedList: PaginatedList) => paginatedList.page), switchMap((bundles: Bundle[]) => bundles), @@ -62,7 +62,7 @@ export class MiradorViewerService { switchMap((bitstream: Bitstream) => bitstream.format.pipe( getFirstCompletedRemoteData(), map((formatRD: RemoteData) => { - return formatRD.payload + return formatRD.payload; }), map((format: BitstreamFormat) => { if (format.mimetype.includes('image')) {