Prevent unauthenticated image request on manga refresh

This commit is contained in:
schroda
2026-02-05 02:23:02 +01:00
parent d99d950585
commit 59d887eaea

View File

@@ -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' }}
/> />