Skip to content

Commit fa96c8c

Browse files
committed
Merge branch 'fix-embargoed-thumbnails_contribute-8.1'
2 parents 9b5d008 + 54ed550 commit fa96c8c

File tree

3 files changed

+35
-29
lines changed

3 files changed

+35
-29
lines changed

src/app/thumbnail/thumbnail.component.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="thumbnail" [class.limit-width]="limitWidth">
2-
@if (isLoading) {
2+
@if (isLoading$ | async) {
33
<div class="thumbnail-content outer">
44
<div class="inner">
55
<div class="centered">
@@ -9,11 +9,11 @@
99
</div>
1010
}
1111
<!-- don't use *ngIf="!isLoading" so the thumbnail can load in while the animation is playing -->
12-
@if (src !== null) {
13-
<img class="thumbnail-content img-fluid" [ngClass]="{'d-none': isLoading}"
14-
[src]="src | dsSafeUrl" [alt]="alt | translate" (error)="errorHandler()" (load)="successHandler()">
12+
@if ((src$ | async) !== null) {
13+
<img class="thumbnail-content img-fluid" [ngClass]="{'d-none': (isLoading$ | async)}"
14+
[src]="(src$ | async) | dsSafeUrl" [alt]="alt | translate" (error)="errorHandler()" (load)="successHandler()">
1515
}
16-
@if (src === null && !isLoading) {
16+
@if ((src$ | async) === null && (isLoading$ | async) === false) {
1717
<div class="thumbnail-content outer">
1818
<div class="inner">
1919
<div class="thumbnail-placeholder centered lead">

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

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

101101
describe('loading', () => {
102102
it('should start out with isLoading$ true', () => {
103-
expect(comp.isLoading).toBeTrue();
103+
expect(comp.isLoading$.getValue()).toBeTrue();
104104
});
105105

106106
it('should set isLoading$ to false once an image is successfully loaded', () => {
107107
comp.setSrc('http://bit.stream');
108108
fixture.debugElement.query(By.css('img.thumbnail-content')).triggerEventHandler('load', new Event('load'));
109-
expect(comp.isLoading).toBeFalse();
109+
expect(comp.isLoading$.getValue()).toBeFalse();
110110
});
111111

112112
it('should set isLoading$ to false once the src is set to null', () => {
113113
comp.setSrc(null);
114-
expect(comp.isLoading).toBeFalse();
114+
expect(comp.isLoading$.getValue()).toBeFalse();
115115
});
116116

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

120-
comp.isLoading = false;
120+
comp.isLoading$.next(false);
121121
fixture.detectChanges();
122122
expect(fixture.debugElement.query(By.css('ds-loading'))).toBeFalsy();
123123
});
124124

125125
describe('with a thumbnail image', () => {
126126
beforeEach(() => {
127-
comp.src = 'https://bit.stream';
127+
comp.src$.next('https://bit.stream');
128128
fixture.detectChanges();
129129
});
130130

@@ -133,7 +133,7 @@ describe('ThumbnailComponent', () => {
133133
expect(img).toBeTruthy();
134134
expect(img.classes['d-none']).toBeTrue();
135135

136-
comp.isLoading = false;
136+
comp.isLoading$.next(false);
137137
fixture.detectChanges();
138138
img = fixture.debugElement.query(By.css('img.thumbnail-content'));
139139
expect(img).toBeTruthy();
@@ -144,14 +144,14 @@ describe('ThumbnailComponent', () => {
144144

145145
describe('without a thumbnail image', () => {
146146
beforeEach(() => {
147-
comp.src = null;
147+
comp.src$.next(null);
148148
fixture.detectChanges();
149149
});
150150

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

154-
comp.isLoading = false;
154+
comp.isLoading$.next(false);
155155
fixture.detectChanges();
156156
expect(fixture.debugElement.query(By.css('div.thumbnail-placeholder'))).toBeTruthy();
157157
});
@@ -247,14 +247,14 @@ describe('ThumbnailComponent', () => {
247247
describe('fallback', () => {
248248
describe('if there is a default image', () => {
249249
it('should display the default image', () => {
250-
comp.src = 'http://bit.stream';
250+
comp.src$.next('http://bit.stream');
251251
comp.defaultImage = 'http://default.img';
252252
comp.errorHandler();
253-
expect(comp.src).toBe(comp.defaultImage);
253+
expect(comp.src$.getValue()).toBe(comp.defaultImage);
254254
});
255255

256256
it('should include the alt text', () => {
257-
comp.src = 'http://bit.stream';
257+
comp.src$.next('http://bit.stream');
258258
comp.defaultImage = 'http://default.img';
259259
comp.errorHandler();
260260

@@ -266,10 +266,10 @@ describe('ThumbnailComponent', () => {
266266

267267
describe('if there is no default image', () => {
268268
it('should display the HTML placeholder', () => {
269-
comp.src = 'http://default.img';
269+
comp.src$.next('http://default.img');
270270
comp.defaultImage = null;
271271
comp.errorHandler();
272-
expect(comp.src).toBe(null);
272+
expect(comp.src$.getValue()).toBe(null);
273273

274274
fixture.detectChanges();
275275
const placeholder = fixture.debugElement.query(By.css('div.thumbnail-placeholder')).nativeElement;
@@ -363,7 +363,7 @@ describe('ThumbnailComponent', () => {
363363
it('should show the default image', () => {
364364
comp.defaultImage = 'default/image.jpg';
365365
comp.ngOnChanges({});
366-
expect(comp.src).toBe('default/image.jpg');
366+
expect(comp.src$.getValue()).toBe('default/image.jpg');
367367
});
368368
});
369369
});
@@ -419,7 +419,7 @@ describe('ThumbnailComponent', () => {
419419
});
420420

421421
it('should start out with isLoading$ true', () => {
422-
expect(comp.isLoading).toBeTrue();
422+
expect(comp.isLoading$.getValue()).toBeTrue();
423423
expect(de.query(By.css('ds-loading'))).toBeTruthy();
424424
});
425425

src/app/thumbnail/thumbnail.component.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
SimpleChanges,
1212
} from '@angular/core';
1313
import { TranslateModule } from '@ngx-translate/core';
14-
import { of as observableOf } from 'rxjs';
14+
import { of as observableOf, BehaviorSubject } from 'rxjs';
1515
import { switchMap } from 'rxjs/operators';
1616

1717
import { AuthService } from '../core/auth/auth.service';
@@ -26,7 +26,6 @@ import {
2626
} from '../shared/empty.util';
2727
import { ThemedLoadingComponent } from '../shared/loading/themed-loading.component';
2828
import { SafeUrlPipe } from '../shared/utils/safe-url-pipe';
29-
import { VarDirective } from '../shared/utils/var.directive';
3029

3130
/**
3231
* This component renders a given Bitstream as a thumbnail.
@@ -38,7 +37,7 @@ import { VarDirective } from '../shared/utils/var.directive';
3837
styleUrls: ['./thumbnail.component.scss'],
3938
templateUrl: './thumbnail.component.html',
4039
standalone: true,
41-
imports: [VarDirective, CommonModule, ThemedLoadingComponent, TranslateModule, SafeUrlPipe],
40+
imports: [CommonModule, ThemedLoadingComponent, TranslateModule, SafeUrlPipe],
4241
})
4342
export class ThumbnailComponent implements OnChanges {
4443
/**
@@ -55,7 +54,7 @@ export class ThumbnailComponent implements OnChanges {
5554
/**
5655
* The src attribute used in the template to render the image.
5756
*/
58-
src: string = undefined;
57+
src$: BehaviorSubject<string> = new BehaviorSubject<string>(undefined);
5958

6059
retriedWithToken = false;
6160

@@ -78,7 +77,7 @@ export class ThumbnailComponent implements OnChanges {
7877
* Whether the thumbnail is currently loading
7978
* Start out as true to avoid flashing the alt text while a thumbnail is being loaded.
8079
*/
81-
isLoading = true;
80+
isLoading$: BehaviorSubject<boolean> = new BehaviorSubject(true);
8281

8382
constructor(
8483
@Inject(PLATFORM_ID) private platformID: any,
@@ -94,6 +93,13 @@ export class ThumbnailComponent implements OnChanges {
9493
*/
9594
ngOnChanges(changes: SimpleChanges): void {
9695
if (isPlatformBrowser(this.platformID)) {
96+
// every time the inputs change we need to start the loading animation again, as it's possible
97+
// that thumbnail is first set to null when the parent component initializes and then set to
98+
// the actual value
99+
if (this.isLoading$.getValue() === false) {
100+
this.isLoading$.next(true);
101+
}
102+
97103
if (hasNoValue(this.thumbnail)) {
98104
this.setSrc(this.defaultImage);
99105
return;
@@ -134,7 +140,7 @@ export class ThumbnailComponent implements OnChanges {
134140
* Otherwise, fall back to the default image or a HTML placeholder
135141
*/
136142
errorHandler() {
137-
const src = this.src;
143+
const src = this.src$.getValue();
138144
const thumbnail = this.bitstream;
139145
const thumbnailSrc = thumbnail?._links?.content?.href;
140146

@@ -186,16 +192,16 @@ export class ThumbnailComponent implements OnChanges {
186192
* @param src
187193
*/
188194
setSrc(src: string): void {
189-
this.src = src;
195+
this.src$.next(src);
190196
if (src === null) {
191-
this.isLoading = false;
197+
this.isLoading$.next(false);
192198
}
193199
}
194200

195201
/**
196202
* Stop the loading animation once the thumbnail is successfully loaded
197203
*/
198204
successHandler() {
199-
this.isLoading = false;
205+
this.isLoading$.next(false);
200206
}
201207
}

0 commit comments

Comments
 (0)