Skip to content

Commit fbbf16f

Browse files
authored
Merge pull request #4250 from atmire/fix-embargoed-thumbnails_contribute-7.6
[Port dspace-7_x] Show restricted thumbnails to users with access rights
2 parents aaa4b91 + 283b345 commit fbbf16f

File tree

5 files changed

+45
-37
lines changed

5 files changed

+45
-37
lines changed

src/app/item-page/media-viewer/media-viewer.component.html

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,7 @@
1616
</ng-container>
1717
</div>
1818
<ng-template #showThumbnail>
19-
<ds-themed-media-viewer-image *ngIf="mediaOptions.image && mediaOptions.video"
20-
[image]="(thumbnailsRD$ | async)?.payload?.page[0]?._links.content.href || thumbnailPlaceholder"
21-
[preview]="false"
22-
></ds-themed-media-viewer-image>
23-
<ds-thumbnail *ngIf="!(mediaOptions.image && mediaOptions.video)"
24-
[thumbnail]="(thumbnailsRD$ | async)?.payload?.page[0]">
25-
</ds-thumbnail>
19+
<ds-themed-thumbnail [thumbnail]="(thumbnailsRD$ | async)?.payload?.page[0]">
20+
</ds-themed-thumbnail>
2621
</ng-template>
2722
</ng-container>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ describe('MediaViewerComponent', () => {
139139
expect(mediaItem.thumbnail).toBe(null);
140140
});
141141

142-
it('should display a default, thumbnail', () => {
142+
it('should display a default thumbnail', () => {
143143
const defaultThumbnail = fixture.debugElement.query(
144-
By.css('ds-themed-media-viewer-image')
144+
By.css('ds-themed-thumbnail')
145145
);
146146
expect(defaultThumbnail.nativeElement).toBeDefined();
147147
});

src/app/thumbnail/thumbnail.component.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<div class="thumbnail" [class.limit-width]="limitWidth">
2-
<div *ngIf="isLoading" class="thumbnail-content outer">
2+
<div *ngIf="(isLoading$ | async)" class="thumbnail-content outer">
33
<div class="inner">
44
<div class="centered">
55
<ds-themed-loading [spinner]="true"></ds-themed-loading>
66
</div>
77
</div>
88
</div>
9-
<!-- don't use *ngIf="!isLoading" so the thumbnail can load in while the animation is playing -->
10-
<img *ngIf="src !== null" class="thumbnail-content img-fluid" [ngClass]="{'d-none': isLoading}"
11-
[src]="src | dsSafeUrl" [alt]="alt | translate" (error)="errorHandler()" (load)="successHandler()">
12-
<div *ngIf="src === null && !isLoading" class="thumbnail-content outer">
9+
<!-- don't use *ngIf="!(isLoading$ | async)" so the thumbnail can load in while the animation is playing -->
10+
<img *ngIf="(src$ | async) !== null" class="thumbnail-content img-fluid" [ngClass]="{'d-none': (isLoading$ | async)}"
11+
[src]="(src$ | async) | dsSafeUrl" [alt]="alt | translate" (error)="errorHandler()" (load)="successHandler()">
12+
<div *ngIf="(src$ | async) === null && !(isLoading$ | async)" class="thumbnail-content outer">
1313
<div class="inner">
1414
<div class="thumbnail-placeholder centered lead">
1515
{{ placeholder | translate }}

src/app/thumbnail/thumbnail.component.spec.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,31 +73,31 @@ describe('ThumbnailComponent', () => {
7373

7474
describe('loading', () => {
7575
it('should start out with isLoading$ true', () => {
76-
expect(comp.isLoading).toBeTrue();
76+
expect(comp.isLoading$.getValue()).toBeTrue();
7777
});
7878

7979
it('should set isLoading$ to false once an image is successfully loaded', () => {
8080
comp.setSrc('http://bit.stream');
8181
fixture.debugElement.query(By.css('img.thumbnail-content')).triggerEventHandler('load', new Event('load'));
82-
expect(comp.isLoading).toBeFalse();
82+
expect(comp.isLoading$.getValue()).toBeFalse();
8383
});
8484

8585
it('should set isLoading$ to false once the src is set to null', () => {
8686
comp.setSrc(null);
87-
expect(comp.isLoading).toBeFalse();
87+
expect(comp.isLoading$.getValue()).toBeFalse();
8888
});
8989

9090
it('should show a loading animation while isLoading$ is true', () => {
9191
expect(de.query(By.css('ds-themed-loading'))).toBeTruthy();
9292

93-
comp.isLoading = false;
93+
comp.isLoading$.next(false);
9494
fixture.detectChanges();
9595
expect(fixture.debugElement.query(By.css('ds-themed-loading'))).toBeFalsy();
9696
});
9797

9898
describe('with a thumbnail image', () => {
9999
beforeEach(() => {
100-
comp.src = 'https://bit.stream';
100+
comp.src$.next('https://bit.stream');
101101
fixture.detectChanges();
102102
});
103103

@@ -106,7 +106,7 @@ describe('ThumbnailComponent', () => {
106106
expect(img).toBeTruthy();
107107
expect(img.classes['d-none']).toBeTrue();
108108

109-
comp.isLoading = false;
109+
comp.isLoading$.next(false);
110110
fixture.detectChanges();
111111
img = fixture.debugElement.query(By.css('img.thumbnail-content'));
112112
expect(img).toBeTruthy();
@@ -117,14 +117,14 @@ describe('ThumbnailComponent', () => {
117117

118118
describe('without a thumbnail image', () => {
119119
beforeEach(() => {
120-
comp.src = null;
120+
comp.src$.next(null);
121121
fixture.detectChanges();
122122
});
123123

124124
it('should only show the HTML placeholder once done loading', () => {
125125
expect(fixture.debugElement.query(By.css('div.thumbnail-placeholder'))).toBeFalsy();
126126

127-
comp.isLoading = false;
127+
comp.isLoading$.next(false);
128128
fixture.detectChanges();
129129
expect(fixture.debugElement.query(By.css('div.thumbnail-placeholder'))).toBeTruthy();
130130
});
@@ -220,14 +220,14 @@ describe('ThumbnailComponent', () => {
220220
describe('fallback', () => {
221221
describe('if there is a default image', () => {
222222
it('should display the default image', () => {
223-
comp.src = 'http://bit.stream';
223+
comp.src$.next('http://bit.stream');
224224
comp.defaultImage = 'http://default.img';
225225
comp.errorHandler();
226-
expect(comp.src).toBe(comp.defaultImage);
226+
expect(comp.src$.getValue()).toBe(comp.defaultImage);
227227
});
228228

229229
it('should include the alt text', () => {
230-
comp.src = 'http://bit.stream';
230+
comp.src$.next('http://bit.stream');
231231
comp.defaultImage = 'http://default.img';
232232
comp.errorHandler();
233233

@@ -239,10 +239,10 @@ describe('ThumbnailComponent', () => {
239239

240240
describe('if there is no default image', () => {
241241
it('should display the HTML placeholder', () => {
242-
comp.src = 'http://default.img';
242+
comp.src$.next('http://default.img');
243243
comp.defaultImage = null;
244244
comp.errorHandler();
245-
expect(comp.src).toBe(null);
245+
expect(comp.src$.getValue()).toBe(null);
246246

247247
fixture.detectChanges();
248248
const placeholder = fixture.debugElement.query(By.css('div.thumbnail-placeholder')).nativeElement;
@@ -334,7 +334,7 @@ describe('ThumbnailComponent', () => {
334334
it('should show the default image', () => {
335335
comp.defaultImage = 'default/image.jpg';
336336
comp.ngOnChanges({});
337-
expect(comp.src).toBe('default/image.jpg');
337+
expect(comp.src$.getValue()).toBe('default/image.jpg');
338338
});
339339
});
340340
});
@@ -382,7 +382,7 @@ describe('ThumbnailComponent', () => {
382382
});
383383

384384
it('should start out with isLoading$ true', () => {
385-
expect(comp.isLoading).toBeTrue();
385+
expect(comp.isLoading$.getValue()).toBeTrue();
386386
expect(de.query(By.css('ds-themed-loading'))).toBeTruthy();
387387
});
388388

src/app/thumbnail/thumbnail.component.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Component, Inject, Input, OnChanges, PLATFORM_ID, SimpleChanges } from
22
import { Bitstream } from '../core/shared/bitstream.model';
33
import { hasNoValue, hasValue } from '../shared/empty.util';
44
import { RemoteData } from '../core/data/remote-data';
5-
import { of as observableOf } from 'rxjs';
5+
import { of as observableOf, BehaviorSubject } from 'rxjs';
66
import { switchMap } from 'rxjs/operators';
77
import { FeatureID } from '../core/data/feature-authorization/feature-id';
88
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
@@ -35,7 +35,7 @@ export class ThumbnailComponent implements OnChanges {
3535
/**
3636
* The src attribute used in the template to render the image.
3737
*/
38-
src: string = undefined;
38+
src$: BehaviorSubject<string> = new BehaviorSubject<string>(undefined);
3939

4040
retriedWithToken = false;
4141

@@ -58,7 +58,7 @@ export class ThumbnailComponent implements OnChanges {
5858
* Whether the thumbnail is currently loading
5959
* Start out as true to avoid flashing the alt text while a thumbnail is being loaded.
6060
*/
61-
isLoading = true;
61+
isLoading$: BehaviorSubject<boolean> = new BehaviorSubject(true);
6262

6363
constructor(
6464
@Inject(PLATFORM_ID) private platformID: any,
@@ -114,7 +114,7 @@ export class ThumbnailComponent implements OnChanges {
114114
* Otherwise, fall back to the default image or a HTML placeholder
115115
*/
116116
errorHandler() {
117-
const src = this.src;
117+
const src = this.src$.getValue();
118118
const thumbnail = this.bitstream;
119119
const thumbnailSrc = thumbnail?._links?.content?.href;
120120

@@ -166,16 +166,29 @@ export class ThumbnailComponent implements OnChanges {
166166
* @param src
167167
*/
168168
setSrc(src: string): void {
169-
this.src = src;
170-
if (src === null) {
171-
this.isLoading = false;
169+
// only update the src if it has changed (the parent component may fire the same one multiple times
170+
if (this.src$.getValue() !== src) {
171+
// every time the src changes we need to start the loading animation again, as it's possible
172+
// that it is first set to null when the parent component initializes and then set to
173+
// the actual value
174+
//
175+
// isLoading$ will be set to false by the error or success handler afterwards, except in the
176+
// case where src is null, then we have to set it manually here (because those handlers won't
177+
// trigger)
178+
if (src !== null && this.isLoading$.getValue() === false) {
179+
this.isLoading$.next(true);
180+
}
181+
this.src$.next(src);
182+
if (src === null && this.isLoading$.getValue() === true) {
183+
this.isLoading$.next(false);
184+
}
172185
}
173186
}
174187

175188
/**
176189
* Stop the loading animation once the thumbnail is successfully loaded
177190
*/
178191
successHandler() {
179-
this.isLoading = false;
192+
this.isLoading$.next(false);
180193
}
181194
}

0 commit comments

Comments
 (0)