Load images with cors allowed

Without allowing cors it is e.g. not possible to extract colors from an image
This commit is contained in:
schroda
2025-01-26 03:51:43 +01:00
parent 2579ba92a3
commit 25e3fc7808
4 changed files with 30 additions and 10 deletions

View File

@@ -860,7 +860,7 @@ export class RequestManager {
abort();
}
private async optionallyDecodeImage(url: string, shouldDecode?: boolean): Promise<string> {
private async optionallyDecodeImage(url: string, shouldDecode?: boolean, allowCors?: boolean): Promise<string> {
if (!shouldDecode) {
return url;
}
@@ -868,6 +868,10 @@ export class RequestManager {
const decodePromise = new ControlledPromise();
const img = new Image();
if (allowCors) {
img.crossOrigin = 'anonymous';
}
img.src = url;
img.onload = async () => {
@@ -890,7 +894,11 @@ export class RequestManager {
private fetchImageViaTag(
url: string,
{ priority, shouldDecode }: { priority?: QueuePriority; shouldDecode?: boolean } = {},
{
priority,
shouldDecode,
allowCors,
}: { priority?: QueuePriority; shouldDecode?: boolean; allowCors?: boolean } = {},
): ImageRequest {
const imgRequest = new ControlledPromise<string>();
imgRequest.promise.catch(() => {});
@@ -910,6 +918,9 @@ export class RequestManager {
// throws error in case request was already aborted
await Promise.race([imgRequest.promise, Promise.resolve()]);
if (allowCors) {
img.crossOrigin = 'anonymous';
}
img.src = url;
img.onload = async () => {
@@ -993,21 +1004,25 @@ export class RequestManager {
*/
public requestImage(
url: string,
options: { priority?: QueuePriority; useFetchApi?: boolean; shouldDecode?: boolean } = {
options: { priority?: QueuePriority; useFetchApi?: boolean; shouldDecode?: boolean; allowCors?: boolean } = {},
): ImageRequest {
const finalOptions = {
useFetchApi: false,
shouldDecode: false,
},
): ImageRequest {
allowCors: true,
...Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined)),
};
// on firefox images are decoded async which causes a "flicker/blinking" when they're getting visible for the first time
// this is an issue especially in the reader because pages that should not be shown are rendered but
// not displayed, which then causes this issue once they get displayed
const shouldDecode = !!options.shouldDecode && navigator.userAgent.toLowerCase().includes('firefox');
const shouldDecode = finalOptions.shouldDecode && navigator.userAgent.toLowerCase().includes('firefox');
if (options.useFetchApi) {
return this.fetchImageViaFetchApi(url, { ...options, shouldDecode });
if (finalOptions.useFetchApi) {
return this.fetchImageViaFetchApi(url, { ...finalOptions, shouldDecode });
}
return this.fetchImageViaTag(url, { ...options, shouldDecode });
return this.fetchImageViaTag(url, { ...finalOptions, shouldDecode });
}
private doRequest<Data, Variables extends OperationVariables = OperationVariables>(

View File

@@ -35,6 +35,7 @@ interface IProps {
shouldDecode?: boolean;
useFetchApi?: boolean;
allowCors?: boolean;
priority?: Priority;
@@ -46,6 +47,7 @@ export const SpinnerImage = forwardRef((props: IProps, imgRef: ForwardedRef<HTML
shouldLoad = true,
shouldDecode,
useFetchApi,
allowCors,
src,
alt,
onLoad,
@@ -84,7 +86,7 @@ export const SpinnerImage = forwardRef((props: IProps, imgRef: ForwardedRef<HTML
return () => {};
}
const imageRequest = requestManager.requestImage(src, { priority, shouldDecode, useFetchApi });
const imageRequest = requestManager.requestImage(src, { priority, shouldDecode, useFetchApi, allowCors });
let cacheTimeout: NodeJS.Timeout;
const fetchImage = async () => {
@@ -156,6 +158,7 @@ export const SpinnerImage = forwardRef((props: IProps, imgRef: ForwardedRef<HTML
}),
]}
ref={imgRef}
crossOrigin={allowCors ? 'anonymous' : undefined}
src={imageSourceUrl}
alt={alt}
draggable={false}

View File

@@ -147,6 +147,7 @@ export const createUpdateReaderPageLoadState =
return prevState.toSpliced(index, 1, { url, isSpread: isSpreadPageFlag });
});
};
img.crossOrigin = 'anonymous';
img.src = url;
}

View File

@@ -152,6 +152,7 @@ export const TrackerMangaCard = ({
<TrackerMangaCardLink url={manga.trackingUrl}>
<SpinnerImage
useFetchApi={false}
allowCors={false}
alt={manga.title}
src={manga.coverUrl}
spinnerStyle={{ width: '100%', height: '100%' }}