Prevent unauthenticated image request on manga refresh
This commit is contained in:
@@ -20,6 +20,8 @@ import { MANGA_COVER_ASPECT_RATIO } from '@/features/manga/Manga.constants.ts';
|
|||||||
import { MangaThumbnailInfo } from '@/features/manga/Manga.types.ts';
|
import { MangaThumbnailInfo } from '@/features/manga/Manga.types.ts';
|
||||||
import { useAppThemeContext } from '@/features/theme/AppThemeContext.tsx';
|
import { useAppThemeContext } from '@/features/theme/AppThemeContext.tsx';
|
||||||
import { TAppThemeContext } from '@/features/theme/AppTheme.types.ts';
|
import { TAppThemeContext } from '@/features/theme/AppTheme.types.ts';
|
||||||
|
import { ImageRequest, requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
|
import { noOp } from '@/lib/HelperFunctions.ts';
|
||||||
|
|
||||||
export const Thumbnail = ({
|
export const Thumbnail = ({
|
||||||
manga,
|
manga,
|
||||||
@@ -35,51 +37,67 @@ export const Thumbnail = ({
|
|||||||
|
|
||||||
const [isImageReady, setIsImageReady] = useState(false);
|
const [isImageReady, setIsImageReady] = useState(false);
|
||||||
|
|
||||||
|
const url = Mangas.getThumbnailUrl(manga);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!mangaDynamicColorSchemes) {
|
if (!mangaDynamicColorSchemes) {
|
||||||
return () => {};
|
return () => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const img = new Image();
|
let imageRequest: ImageRequest = {
|
||||||
img.crossOrigin = 'anonymous';
|
response: Promise.resolve(''),
|
||||||
img.src = Mangas.getThumbnailUrl(manga);
|
cleanup: noOp,
|
||||||
|
abortRequest: noOp,
|
||||||
img.onload = () => {
|
fromCache: false,
|
||||||
const isLargeImage = img.width > 600 && img.height > 900;
|
|
||||||
|
|
||||||
Promise.all([
|
|
||||||
Vibrant.from(img).getPalette(),
|
|
||||||
new FastAverageColor().getColor(img, {
|
|
||||||
algorithm: 'dominant',
|
|
||||||
mode: isLargeImage ? 'speed' : 'precision',
|
|
||||||
ignoredColor: [
|
|
||||||
[255, 255, 255, 255, 75],
|
|
||||||
[0, 0, 0, 255, 75],
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
]).then(([palette, averageColor]) => {
|
|
||||||
if (
|
|
||||||
!palette.Vibrant ||
|
|
||||||
!palette.DarkVibrant ||
|
|
||||||
!palette.LightVibrant ||
|
|
||||||
!palette.LightMuted ||
|
|
||||||
!palette.Muted ||
|
|
||||||
!palette.DarkMuted
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDynamicColor({
|
|
||||||
...palette,
|
|
||||||
average: averageColor,
|
|
||||||
} as TAppThemeContext['dynamicColor']);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
const fetchImage = async () => {
|
||||||
|
imageRequest = await requestManager.requestImage(url);
|
||||||
|
const image = await imageRequest.response;
|
||||||
|
|
||||||
|
const img = new Image();
|
||||||
|
img.crossOrigin = 'anonymous';
|
||||||
|
img.src = image;
|
||||||
|
|
||||||
|
img.onload = () => {
|
||||||
|
const isLargeImage = img.width > 600 && img.height > 900;
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
Vibrant.from(img).getPalette(),
|
||||||
|
new FastAverageColor().getColor(img, {
|
||||||
|
algorithm: 'dominant',
|
||||||
|
mode: isLargeImage ? 'speed' : 'precision',
|
||||||
|
ignoredColor: [
|
||||||
|
[255, 255, 255, 255, 75],
|
||||||
|
[0, 0, 0, 255, 75],
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
]).then(([palette, averageColor]) => {
|
||||||
|
if (
|
||||||
|
!palette.Vibrant ||
|
||||||
|
!palette.DarkVibrant ||
|
||||||
|
!palette.LightVibrant ||
|
||||||
|
!palette.LightMuted ||
|
||||||
|
!palette.Muted ||
|
||||||
|
!palette.DarkMuted
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDynamicColor({
|
||||||
|
...palette,
|
||||||
|
average: averageColor,
|
||||||
|
} as TAppThemeContext['dynamicColor']);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchImage().catch(() => {});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
imageRequest.cleanup();
|
||||||
setDynamicColor(null);
|
setDynamicColor(null);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [url, mangaDynamicColorSchemes]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -105,7 +123,7 @@ export const Thumbnail = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SpinnerImage
|
<SpinnerImage
|
||||||
src={Mangas.getThumbnailUrl(manga)}
|
src={url}
|
||||||
alt="Manga Thumbnail"
|
alt="Manga Thumbnail"
|
||||||
onLoad={() => setIsImageReady(true)}
|
onLoad={() => setIsImageReady(true)}
|
||||||
imgStyle={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
imgStyle={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||||
@@ -138,7 +156,7 @@ export const Thumbnail = ({
|
|||||||
sx={{ height: '100vh', p: 2, outline: 0, justifyContent: 'center', alignItems: 'center' }}
|
sx={{ height: '100vh', p: 2, outline: 0, justifyContent: 'center', alignItems: 'center' }}
|
||||||
>
|
>
|
||||||
<SpinnerImage
|
<SpinnerImage
|
||||||
src={Mangas.getThumbnailUrl(manga)}
|
src={url}
|
||||||
alt="Manga Thumbnail"
|
alt="Manga Thumbnail"
|
||||||
imgStyle={{ height: '100%', width: '100%', objectFit: 'contain' }}
|
imgStyle={{ height: '100%', width: '100%', objectFit: 'contain' }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user