Skip to content

Commit c7029ed

Browse files
authored
Merge pull request DSpace#1847 from mspalti/iiif-multi-fix
Bug fix for multiple IIIF image property
2 parents fbe35e1 + 42bb39d commit c7029ed

3 files changed

Lines changed: 78 additions & 31 deletions

File tree

src/app/item-page/mirador-viewer/mirador-viewer.component.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { createPaginatedList } from '../../shared/testing/utils.test';
1212
import { of as observableOf } from 'rxjs';
1313
import { MiradorViewerService } from './mirador-viewer.service';
1414
import { HostWindowService } from '../../shared/host-window.service';
15+
import { BundleDataService } from '../../core/data/bundle-data.service';
1516

1617

1718
function getItem(metadata: MetadataMap) {
@@ -46,6 +47,7 @@ describe('MiradorViewerComponent with search', () => {
4647
declarations: [MiradorViewerComponent],
4748
providers: [
4849
{ provide: BitstreamDataService, useValue: {} },
50+
{ provide: BundleDataService, useValue: {} },
4951
{ provide: HostWindowService, useValue: mockHostWindowService }
5052
],
5153
schemas: [NO_ERRORS_SCHEMA]
@@ -108,6 +110,7 @@ describe('MiradorViewerComponent with multiple images', () => {
108110
declarations: [MiradorViewerComponent],
109111
providers: [
110112
{ provide: BitstreamDataService, useValue: {} },
113+
{ provide: BundleDataService, useValue: {} },
111114
{ provide: HostWindowService, useValue: mockHostWindowService }
112115
],
113116
schemas: [NO_ERRORS_SCHEMA]
@@ -167,6 +170,7 @@ describe('MiradorViewerComponent with a single image', () => {
167170
declarations: [MiradorViewerComponent],
168171
providers: [
169172
{ provide: BitstreamDataService, useValue: {} },
173+
{ provide: BundleDataService, useValue: {} },
170174
{ provide: HostWindowService, useValue: mockHostWindowService }
171175
],
172176
schemas: [NO_ERRORS_SCHEMA]
@@ -225,6 +229,7 @@ describe('MiradorViewerComponent in development mode', () => {
225229
set: {
226230
providers: [
227231
{ provide: MiradorViewerService, useValue: viewerService },
232+
{ provide: BundleDataService, useValue: {} },
228233
{ provide: HostWindowService, useValue: mockHostWindowService }
229234
]
230235
}

src/app/item-page/mirador-viewer/mirador-viewer.component.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { map, take } from 'rxjs/operators';
88
import { isPlatformBrowser } from '@angular/common';
99
import { MiradorViewerService } from './mirador-viewer.service';
1010
import { HostWindowService, WidthCategory } from '../../shared/host-window.service';
11+
import { BundleDataService } from '../../core/data/bundle-data.service';
1112

1213
@Component({
1314
selector: 'ds-mirador-viewer',
@@ -55,6 +56,7 @@ export class MiradorViewerComponent implements OnInit {
5556
constructor(private sanitizer: DomSanitizer,
5657
private viewerService: MiradorViewerService,
5758
private bitstreamDataService: BitstreamDataService,
59+
private bundleDataService: BundleDataService,
5860
private hostWindowService: HostWindowService,
5961
@Inject(PLATFORM_ID) private platformId: any) {
6062
}
@@ -107,10 +109,10 @@ export class MiradorViewerComponent implements OnInit {
107109
this.notMobile = !(category === WidthCategory.XS || category === WidthCategory.SM);
108110
});
109111

110-
// We need to set the multi property to true if the
111-
// item is searchable or when the ORIGINAL bundle contains more
112-
// than 1 image. (The multi property determines whether the
113-
// Mirador side thumbnail navigation panel is shown.)
112+
// Set the multi property. The default mirador configuration adds a right
113+
// thumbnail navigation panel to the viewer when multi is 'true'.
114+
115+
// Set the multi property to 'true' if the item is searchable.
114116
if (this.searchable) {
115117
this.multi = true;
116118
const observable = of('');
@@ -120,8 +122,12 @@ export class MiradorViewerComponent implements OnInit {
120122
})
121123
);
122124
} else {
123-
// Sets the multi value based on the image count.
124-
this.iframeViewerUrl = this.viewerService.getImageCount(this.object, this.bitstreamDataService).pipe(
125+
// Set the multi property based on the image count in IIIF-eligible bundles.
126+
// Any count greater than 1 sets the value to 'true'.
127+
this.iframeViewerUrl = this.viewerService.getImageCount(
128+
this.object,
129+
this.bitstreamDataService,
130+
this.bundleDataService).pipe(
125131
map(c => {
126132
if (c > 1) {
127133
this.multi = true;
Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import { Injectable, isDevMode } from '@angular/core';
22
import { Observable } from 'rxjs';
33
import { Item } from '../../core/shared/item.model';
4-
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
5-
import { last, map, switchMap } from 'rxjs/operators';
4+
import {
5+
getFirstCompletedRemoteData,
6+
} from '../../core/shared/operators';
7+
import { filter, last, map, mergeMap, switchMap } from 'rxjs/operators';
68
import { RemoteData } from '../../core/data/remote-data';
79
import { PaginatedList } from '../../core/data/paginated-list.model';
810
import { Bitstream } from '../../core/shared/bitstream.model';
911
import { BitstreamFormat } from '../../core/shared/bitstream-format.model';
1012
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
1113
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
14+
import { Bundle } from '../../core/shared/bundle.model';
15+
import { BundleDataService } from '../../core/data/bundle-data.service';
1216

1317
@Injectable()
1418
export class MiradorViewerService {
@@ -26,32 +30,64 @@ export class MiradorViewerService {
2630
}
2731

2832
/**
29-
* Returns observable of the number of images in the ORIGINAL bundle
33+
* Returns observable of the number of images found in eligible IIIF bundles. Checks
34+
* the mimetype of the first 5 bitstreams in each bundle.
3035
* @param item
3136
* @param bitstreamDataService
37+
* @param bundleDataService
38+
* @returns the total image count
3239
*/
33-
getImageCount(item: Item, bitstreamDataService: BitstreamDataService): Observable<number> {
34-
let count = 0;
35-
return bitstreamDataService.findAllByItemAndBundleName(item, 'ORIGINAL', {
36-
currentPage: 1,
37-
elementsPerPage: 10
38-
}, true, true, ...this.LINKS_TO_FOLLOW)
39-
.pipe(
40-
getFirstCompletedRemoteData(),
41-
map((bitstreamsRD: RemoteData<PaginatedList<Bitstream>>) => bitstreamsRD.payload),
42-
map((paginatedList: PaginatedList<Bitstream>) => paginatedList.page),
43-
switchMap((bitstreams: Bitstream[]) => bitstreams),
44-
switchMap((bitstream: Bitstream) => bitstream.format.pipe(
45-
getFirstSucceededRemoteDataPayload(),
46-
map((format: BitstreamFormat) => format)
47-
)),
48-
map((format: BitstreamFormat) => {
49-
if (format.mimetype.includes('image')) {
50-
count++;
51-
}
52-
return count;
53-
}),
54-
last()
40+
getImageCount(item: Item, bitstreamDataService: BitstreamDataService, bundleDataService: BundleDataService):
41+
Observable<number> {
42+
let count = 0;
43+
return bundleDataService.findAllByItem(item).pipe(
44+
getFirstCompletedRemoteData(),
45+
map((bundlesRD: RemoteData<PaginatedList<Bundle>>) => {
46+
return bundlesRD.payload;
47+
}),
48+
map((paginatedList: PaginatedList<Bundle>) => paginatedList.page),
49+
switchMap((bundles: Bundle[]) => bundles),
50+
filter((b: Bundle) => this.isIiifBundle(b.name)),
51+
mergeMap((bundle: Bundle) => {
52+
return bitstreamDataService.findAllByItemAndBundleName(item, bundle.name, {
53+
currentPage: 1,
54+
elementsPerPage: 5
55+
}, true, true, ...this.LINKS_TO_FOLLOW).pipe(
56+
getFirstCompletedRemoteData(),
57+
map((bitstreamsRD: RemoteData<PaginatedList<Bitstream>>) => {
58+
return bitstreamsRD.payload;
59+
}),
60+
map((paginatedList: PaginatedList<Bitstream>) => paginatedList.page),
61+
switchMap((bitstreams: Bitstream[]) => bitstreams),
62+
switchMap((bitstream: Bitstream) => bitstream.format.pipe(
63+
getFirstCompletedRemoteData(),
64+
map((formatRD: RemoteData<BitstreamFormat>) => {
65+
return formatRD.payload;
66+
}),
67+
map((format: BitstreamFormat) => {
68+
if (format.mimetype.includes('image')) {
69+
count++;
70+
}
71+
return count;
72+
}),
73+
)
74+
)
75+
);
76+
}),
77+
last()
5578
);
5679
}
80+
81+
isIiifBundle(bundleName: string): boolean {
82+
return !(
83+
bundleName === 'OtherContent' ||
84+
bundleName === 'LICENSE' ||
85+
bundleName === 'THUMBNAIL' ||
86+
bundleName === 'TEXT' ||
87+
bundleName === 'METADATA' ||
88+
bundleName === 'CC-LICENSE' ||
89+
bundleName === 'BRANDED_PREVIEW'
90+
);
91+
}
92+
5793
}

0 commit comments

Comments
 (0)