{{ placeholder | translate }}
diff --git a/src/app/thumbnail/thumbnail.component.spec.ts b/src/app/thumbnail/thumbnail.component.spec.ts
index f81089e57c..38eceb8427 100644
--- a/src/app/thumbnail/thumbnail.component.spec.ts
+++ b/src/app/thumbnail/thumbnail.component.spec.ts
@@ -100,31 +100,31 @@ describe('ThumbnailComponent', () => {
describe('loading', () => {
it('should start out with isLoading$ true', () => {
- expect(comp.isLoading).toBeTrue();
+ expect(comp.isLoading$.getValue()).toBeTrue();
});
it('should set isLoading$ to false once an image is successfully loaded', () => {
comp.setSrc('http://bit.stream');
fixture.debugElement.query(By.css('img.thumbnail-content')).triggerEventHandler('load', new Event('load'));
- expect(comp.isLoading).toBeFalse();
+ expect(comp.isLoading$.getValue()).toBeFalse();
});
it('should set isLoading$ to false once the src is set to null', () => {
comp.setSrc(null);
- expect(comp.isLoading).toBeFalse();
+ expect(comp.isLoading$.getValue()).toBeFalse();
});
it('should show a loading animation while isLoading$ is true', () => {
expect(de.query(By.css('ds-loading'))).toBeTruthy();
- comp.isLoading = false;
+ comp.isLoading$.next(false);
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('ds-loading'))).toBeFalsy();
});
describe('with a thumbnail image', () => {
beforeEach(() => {
- comp.src = 'https://bit.stream';
+ comp.src$.next('https://bit.stream');
fixture.detectChanges();
});
@@ -133,7 +133,7 @@ describe('ThumbnailComponent', () => {
expect(img).toBeTruthy();
expect(img.classes['d-none']).toBeTrue();
- comp.isLoading = false;
+ comp.isLoading$.next(false);
fixture.detectChanges();
img = fixture.debugElement.query(By.css('img.thumbnail-content'));
expect(img).toBeTruthy();
@@ -144,14 +144,14 @@ describe('ThumbnailComponent', () => {
describe('without a thumbnail image', () => {
beforeEach(() => {
- comp.src = null;
+ comp.src$.next(null);
fixture.detectChanges();
});
it('should only show the HTML placeholder once done loading', () => {
expect(fixture.debugElement.query(By.css('div.thumbnail-placeholder'))).toBeFalsy();
- comp.isLoading = false;
+ comp.isLoading$.next(false);
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('div.thumbnail-placeholder'))).toBeTruthy();
});
@@ -247,14 +247,14 @@ describe('ThumbnailComponent', () => {
describe('fallback', () => {
describe('if there is a default image', () => {
it('should display the default image', () => {
- comp.src = 'http://bit.stream';
+ comp.src$.next('http://bit.stream');
comp.defaultImage = 'http://default.img';
comp.errorHandler();
- expect(comp.src).toBe(comp.defaultImage);
+ expect(comp.src$.getValue()).toBe(comp.defaultImage);
});
it('should include the alt text', () => {
- comp.src = 'http://bit.stream';
+ comp.src$.next('http://bit.stream');
comp.defaultImage = 'http://default.img';
comp.errorHandler();
@@ -266,10 +266,10 @@ describe('ThumbnailComponent', () => {
describe('if there is no default image', () => {
it('should display the HTML placeholder', () => {
- comp.src = 'http://default.img';
+ comp.src$.next('http://default.img');
comp.defaultImage = null;
comp.errorHandler();
- expect(comp.src).toBe(null);
+ expect(comp.src$.getValue()).toBe(null);
fixture.detectChanges();
const placeholder = fixture.debugElement.query(By.css('div.thumbnail-placeholder')).nativeElement;
@@ -361,7 +361,7 @@ describe('ThumbnailComponent', () => {
it('should show the default image', () => {
comp.defaultImage = 'default/image.jpg';
comp.ngOnChanges({});
- expect(comp.src).toBe('default/image.jpg');
+ expect(comp.src$.getValue()).toBe('default/image.jpg');
});
});
});
@@ -417,7 +417,7 @@ describe('ThumbnailComponent', () => {
});
it('should start out with isLoading$ true', () => {
- expect(comp.isLoading).toBeTrue();
+ expect(comp.isLoading$.getValue()).toBeTrue();
expect(de.query(By.css('ds-loading'))).toBeTruthy();
});
diff --git a/src/app/thumbnail/thumbnail.component.ts b/src/app/thumbnail/thumbnail.component.ts
index 7b22dde4cd..179af1dac0 100644
--- a/src/app/thumbnail/thumbnail.component.ts
+++ b/src/app/thumbnail/thumbnail.component.ts
@@ -11,7 +11,10 @@ import {
SimpleChanges,
} from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
-import { of as observableOf } from 'rxjs';
+import {
+ BehaviorSubject,
+ of as observableOf,
+} from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { AuthService } from '../core/auth/auth.service';
@@ -55,7 +58,7 @@ export class ThumbnailComponent implements OnChanges {
/**
* The src attribute used in the template to render the image.
*/
- src: string = undefined;
+ src$: BehaviorSubject = new BehaviorSubject(undefined);
retriedWithToken = false;
@@ -78,7 +81,7 @@ export class ThumbnailComponent implements OnChanges {
* Whether the thumbnail is currently loading
* Start out as true to avoid flashing the alt text while a thumbnail is being loaded.
*/
- isLoading = true;
+ isLoading$: BehaviorSubject = new BehaviorSubject(true);
constructor(
@Inject(PLATFORM_ID) private platformID: any,
@@ -134,7 +137,7 @@ export class ThumbnailComponent implements OnChanges {
* Otherwise, fall back to the default image or a HTML placeholder
*/
errorHandler() {
- const src = this.src;
+ const src = this.src$.getValue();
const thumbnail = this.bitstream;
const thumbnailSrc = thumbnail?._links?.content?.href;
@@ -186,9 +189,22 @@ export class ThumbnailComponent implements OnChanges {
* @param src
*/
setSrc(src: string): void {
- this.src = src;
- if (src === null) {
- this.isLoading = false;
+ // only update the src if it has changed (the parent component may fire the same one multiple times
+ if (this.src$.getValue() !== src) {
+ // every time the src changes we need to start the loading animation again, as it's possible
+ // that it is first set to null when the parent component initializes and then set to
+ // the actual value
+ //
+ // isLoading$ will be set to false by the error or success handler afterwards, except in the
+ // case where src is null, then we have to set it manually here (because those handlers won't
+ // trigger)
+ if (src !== null && this.isLoading$.getValue() === false) {
+ this.isLoading$.next(true);
+ }
+ this.src$.next(src);
+ if (src === null && this.isLoading$.getValue() === true) {
+ this.isLoading$.next(false);
+ }
}
}
@@ -196,6 +212,6 @@ export class ThumbnailComponent implements OnChanges {
* Stop the loading animation once the thumbnail is successfully loaded
*/
successHandler() {
- this.isLoading = false;
+ this.isLoading$.next(false);
}
}