Skip to content

Commit 39af7ac

Browse files
committed
chore: resolve cover images urls using CORS proxy on loading failures
1 parent 63ab88a commit 39af7ac

6 files changed

Lines changed: 58 additions & 4 deletions

File tree

src/app/modules/episode/card/card.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
mdcCardMedia
1010
size="square"
1111
[style.background-image]="
12-
episode.anime.cover | url: 'encodeAndFormat' | safe: 'style'
12+
episode.anime.cover
13+
| proxy: 'resolveUrl':'image'
14+
| async
15+
| url: 'encodeAndFormat'
16+
| safe: 'style'
1317
"
1418
[attr.data-cover]="episode.anime.cover"
1519
>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Pipe, PipeTransform } from '@angular/core';
2+
import { ScraperService } from 'src/app/services/scraper.service';
3+
4+
export type ProxyPipeAction = 'resolveUrl';
5+
export type ProxyPipeValueType = 'image';
6+
7+
@Pipe({
8+
name: 'proxy',
9+
pure: true,
10+
})
11+
export class ProxyPipe implements PipeTransform {
12+
constructor(protected scraper: ScraperService) {}
13+
14+
private getImageOrFallback = (
15+
path: string,
16+
fallback: string
17+
): Promise<string> => {
18+
return new Promise((resolve) => {
19+
const img = new Image();
20+
img.src = path;
21+
img.onload = () => resolve(path);
22+
img.onerror = () => resolve(fallback);
23+
});
24+
};
25+
26+
async transform(
27+
value: string,
28+
action: ProxyPipeAction,
29+
type?: ProxyPipeValueType
30+
): Promise<string> {
31+
switch (action) {
32+
case 'resolveUrl': {
33+
const url = this.scraper.resolveUrl(value);
34+
switch (type) {
35+
case 'image':
36+
return await this.getImageOrFallback(value, url);
37+
default:
38+
return url;
39+
}
40+
}
41+
default:
42+
throw new Error(
43+
`ProxyPipe unable to transform value for invalid action: ${action}`
44+
);
45+
}
46+
}
47+
}

src/app/modules/shared/pipes/safe.pipe.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type SafePipeType = 'html' | 'style' | 'script' | 'url' | 'resourceUrl';
2020
export class SafePipe implements PipeTransform {
2121
constructor(protected sanitizer: DomSanitizer) {}
2222

23-
public transform(
23+
transform(
2424
value: string,
2525
type: SafePipeType
2626
): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {

src/app/modules/shared/pipes/url.pipe.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export type UrlPipeAction =
1414
export class UrlPipe implements PipeTransform {
1515
constructor() {}
1616

17-
public transform(value: string, action: UrlPipeAction): string {
17+
transform(value: string, action: UrlPipeAction): string {
1818
switch (action) {
1919
case 'format':
2020
return `url("${value}")`;

src/app/modules/shared/shared.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { ShortDatePipe } from './pipes/shortdate.pipe';
1010
import { DateTimePipe } from './pipes/datetime.pipe';
1111
import { UrlPipe } from './pipes/url.pipe';
1212
import { SafePipe } from './pipes/safe.pipe';
13+
import { ProxyPipe } from './pipes/proxy.pipe';
1314

1415
@NgModule({
1516
declarations: [
@@ -20,6 +21,7 @@ import { SafePipe } from './pipes/safe.pipe';
2021
DateTimePipe,
2122
UrlPipe,
2223
SafePipe,
24+
ProxyPipe,
2325
],
2426
imports: [CommonModule, FormsModule, MaterialModule],
2527
exports: [
@@ -33,6 +35,7 @@ import { SafePipe } from './pipes/safe.pipe';
3335
DateTimePipe,
3436
UrlPipe,
3537
SafePipe,
38+
ProxyPipe,
3639
],
3740
})
3841
export class SharedModule {}

src/app/services/scraper.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export class ScraperService {
5656
);
5757
}
5858

59-
private resolveUrl(url: string): string {
59+
resolveUrl(url: string): string {
6060
return this.settings.proxy.enabled ? `${this.proxy.url}${url}` : url;
6161
}
6262

0 commit comments

Comments
 (0)