Add image fallback debug logging
This commit is contained in:
parent
6d7c5d6903
commit
e1cd7d23f1
@ -11,6 +11,7 @@ import {
|
|||||||
HTML_LANG,
|
HTML_LANG,
|
||||||
NAV_CAPTION,
|
NAV_CAPTION,
|
||||||
SITE_FEEDS_ENABLED,
|
SITE_FEEDS_ENABLED,
|
||||||
|
ADMIN_DEBUG_TOOLS_ENABLED,
|
||||||
} from '@/app/config';
|
} from '@/app/config';
|
||||||
import AppStateProvider from '@/state/AppStateProvider';
|
import AppStateProvider from '@/state/AppStateProvider';
|
||||||
import ToasterWithThemes from '@/toast/ToasterWithThemes';
|
import ToasterWithThemes from '@/toast/ToasterWithThemes';
|
||||||
@ -91,7 +92,7 @@ export default function RootLayout({
|
|||||||
// Center on large screens
|
// Center on large screens
|
||||||
'3xl:flex flex-col items-center',
|
'3xl:flex flex-col items-center',
|
||||||
)}>
|
)}>
|
||||||
<AppStateProvider>
|
<AppStateProvider areAdminDebugToolsEnabled={ADMIN_DEBUG_TOOLS_ENABLED}>
|
||||||
<AppTextProvider>
|
<AppTextProvider>
|
||||||
<ThemeColors />
|
<ThemeColors />
|
||||||
<ThemeProvider attribute="class" defaultTheme={DEFAULT_THEME}>
|
<ThemeProvider attribute="class" defaultTheme={DEFAULT_THEME}>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import CommandKClient from './CommandKClient';
|
import CommandKClient from './CommandKClient';
|
||||||
import { getPhotosMetaCached } from '@/photo/cache';
|
import { getPhotosMetaCached } from '@/photo/cache';
|
||||||
import { photoQuantityText } from '@/photo';
|
import { photoQuantityText } from '@/photo';
|
||||||
import { ADMIN_DEBUG_TOOLS_ENABLED } from '../app/config';
|
|
||||||
import { getDataForCategoriesCached } from '@/category/cache';
|
import { getDataForCategoriesCached } from '@/category/cache';
|
||||||
import { getAppText } from '@/i18n/state/server';
|
import { getAppText } from '@/i18n/state/server';
|
||||||
|
|
||||||
@ -21,7 +20,6 @@ export default async function CommandK() {
|
|||||||
return (
|
return (
|
||||||
<CommandKClient
|
<CommandKClient
|
||||||
{...categories}
|
{...categories}
|
||||||
showDebugTools={ADMIN_DEBUG_TOOLS_ENABLED}
|
|
||||||
footer={photoQuantityText(count, appText, false)}
|
footer={photoQuantityText(count, appText, false)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -122,10 +122,8 @@ export default function CommandKClient({
|
|||||||
recipes,
|
recipes,
|
||||||
films,
|
films,
|
||||||
focalLengths,
|
focalLengths,
|
||||||
showDebugTools,
|
|
||||||
footer,
|
footer,
|
||||||
}: {
|
}: {
|
||||||
showDebugTools?: boolean
|
|
||||||
footer?: string
|
footer?: string
|
||||||
} & PhotoSetCategories) {
|
} & PhotoSetCategories) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
@ -146,6 +144,7 @@ export default function CommandKClient({
|
|||||||
isGridHighDensity,
|
isGridHighDensity,
|
||||||
areZoomControlsShown,
|
areZoomControlsShown,
|
||||||
arePhotosMatted,
|
arePhotosMatted,
|
||||||
|
areAdminDebugToolsEnabled,
|
||||||
shouldShowBaselineGrid,
|
shouldShowBaselineGrid,
|
||||||
shouldDebugImageFallbacks,
|
shouldDebugImageFallbacks,
|
||||||
shouldDebugInsights,
|
shouldDebugInsights,
|
||||||
@ -406,7 +405,7 @@ export default function CommandKClient({
|
|||||||
}],
|
}],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (isUserSignedIn && showDebugTools) {
|
if (isUserSignedIn && areAdminDebugToolsEnabled) {
|
||||||
clientSections.push({
|
clientSections.push({
|
||||||
heading: 'Debug Tools',
|
heading: 'Debug Tools',
|
||||||
accessory: <RiToolsFill size={16} className="translate-x-[-1px]" />,
|
accessory: <RiToolsFill size={16} className="translate-x-[-1px]" />,
|
||||||
@ -537,7 +536,7 @@ export default function CommandKClient({
|
|||||||
annotation: <IconLock narrow />,
|
annotation: <IconLock narrow />,
|
||||||
path: PATH_ADMIN_CONFIGURATION,
|
path: PATH_ADMIN_CONFIGURATION,
|
||||||
});
|
});
|
||||||
if (showDebugTools) {
|
if (areAdminDebugToolsEnabled) {
|
||||||
adminSection.items.push({
|
adminSection.items.push({
|
||||||
label: 'Baseline Overview',
|
label: 'Baseline Overview',
|
||||||
annotation: <BiLockAlt />,
|
annotation: <BiLockAlt />,
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|||||||
export default function ImageWithFallback({
|
export default function ImageWithFallback({
|
||||||
className,
|
className,
|
||||||
classNameImage = 'object-cover h-full',
|
classNameImage = 'object-cover h-full',
|
||||||
|
debug,
|
||||||
priority,
|
priority,
|
||||||
blurDataURL,
|
blurDataURL,
|
||||||
blurCompatibilityLevel = 'low',
|
blurCompatibilityLevel = 'low',
|
||||||
@ -17,8 +18,12 @@ export default function ImageWithFallback({
|
|||||||
}: ImageProps & {
|
}: ImageProps & {
|
||||||
blurCompatibilityLevel?: 'none' | 'low' | 'high'
|
blurCompatibilityLevel?: 'none' | 'low' | 'high'
|
||||||
classNameImage?: string
|
classNameImage?: string
|
||||||
|
debug?: boolean
|
||||||
}) {
|
}) {
|
||||||
const { shouldDebugImageFallbacks } = useAppState();
|
const {
|
||||||
|
shouldDebugImageFallbacks,
|
||||||
|
areAdminDebugToolsEnabled,
|
||||||
|
} = useAppState();
|
||||||
|
|
||||||
const [wasCached, setWasCached] = useState(true);
|
const [wasCached, setWasCached] = useState(true);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
@ -39,10 +44,28 @@ export default function ImageWithFallback({
|
|||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const shouldDebugFallback = areAdminDebugToolsEnabled && debug;
|
||||||
|
|
||||||
|
const debugFallbackStyles = useCallback(() => {
|
||||||
|
const stylesMap = refFallback.current?.computedStyleMap();
|
||||||
|
const styles = stylesMap
|
||||||
|
? Array.from(stylesMap.entries()).reduce((acc, [key, value]) => {
|
||||||
|
acc[key] = value.toString();
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<string, string>) : {};
|
||||||
|
const opacity = (stylesMap?.get('opacity') as CSSUnitValue)?.value;
|
||||||
|
return {
|
||||||
|
styles,
|
||||||
|
opacity,
|
||||||
|
classList: refFallback.current?.classList,
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const outerTimeout = useRef<NodeJS.Timeout>(undefined);
|
||||||
|
const innerTimeout = useRef<NodeJS.Timeout>(undefined);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoading && !didError) {
|
if (!isLoading && !didError) {
|
||||||
let innerTimeout: NodeJS.Timeout;
|
outerTimeout.current = setTimeout(() => {
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
if (refFallback.current) {
|
if (refFallback.current) {
|
||||||
const fallbackOpacity = (refFallback
|
const fallbackOpacity = (refFallback
|
||||||
.current
|
.current
|
||||||
@ -54,22 +77,32 @@ export default function ImageWithFallback({
|
|||||||
if (fallbackOpacity === 0) {
|
if (fallbackOpacity === 0) {
|
||||||
// Image has loaded and fallback is already hidden
|
// Image has loaded and fallback is already hidden
|
||||||
setHideFallback(true);
|
setHideFallback(true);
|
||||||
|
if (shouldDebugFallback) {
|
||||||
|
console.log('Hide fallback: 01', debugFallbackStyles());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Image has loaded but fallback is still visible
|
// Image has loaded but fallback is still visible
|
||||||
// Delay hiding fallback to avoid abrupt transition
|
// Delay hiding fallback to avoid abrupt transition
|
||||||
innerTimeout = setTimeout(() =>{
|
innerTimeout.current = setTimeout(() =>{
|
||||||
console.log('Delayed hide fallback');
|
|
||||||
setHideFallback(true);
|
setHideFallback(true);
|
||||||
|
if (shouldDebugFallback) {
|
||||||
|
console.log('Hide fallback: 02', debugFallbackStyles());
|
||||||
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(outerTimeout.current);
|
||||||
clearTimeout(innerTimeout);
|
clearTimeout(innerTimeout.current);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [isLoading, didError]);
|
}, [
|
||||||
|
isLoading,
|
||||||
|
didError,
|
||||||
|
shouldDebugFallback,
|
||||||
|
debugFallbackStyles,
|
||||||
|
]);
|
||||||
|
|
||||||
const showFallback =
|
const showFallback =
|
||||||
!wasCached &&
|
!wasCached &&
|
||||||
|
|||||||
@ -78,6 +78,7 @@ export default function PhotoLarge({
|
|||||||
includeFavoriteInAdminMenu,
|
includeFavoriteInAdminMenu,
|
||||||
onVisible,
|
onVisible,
|
||||||
showAdminKeyCommands,
|
showAdminKeyCommands,
|
||||||
|
debugImageFallback,
|
||||||
}: {
|
}: {
|
||||||
photo: Photo
|
photo: Photo
|
||||||
className?: string
|
className?: string
|
||||||
@ -104,6 +105,7 @@ export default function PhotoLarge({
|
|||||||
includeFavoriteInAdminMenu?: boolean
|
includeFavoriteInAdminMenu?: boolean
|
||||||
onVisible?: () => void
|
onVisible?: () => void
|
||||||
showAdminKeyCommands?: boolean
|
showAdminKeyCommands?: boolean
|
||||||
|
debugImageFallback?: boolean
|
||||||
}) {
|
}) {
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const refZoomControls = useRef<ZoomControlsRef>(null);
|
const refZoomControls = useRef<ZoomControlsRef>(null);
|
||||||
@ -224,6 +226,7 @@ export default function PhotoLarge({
|
|||||||
blurDataURL={photo.blurData}
|
blurDataURL={photo.blurData}
|
||||||
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
||||||
priority={priority}
|
priority={priority}
|
||||||
|
debug={debugImageFallback}
|
||||||
/>
|
/>
|
||||||
</ZoomControls>
|
</ZoomControls>
|
||||||
<div className={clsx(
|
<div className={clsx(
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export default function PhotosLarge({
|
|||||||
onVisible={index === photos.length - 1
|
onVisible={index === photos.length - 1
|
||||||
? onLastPhotoVisible
|
? onLastPhotoVisible
|
||||||
: undefined}
|
: undefined}
|
||||||
|
debugImageFallback={index === 0}
|
||||||
/>)}
|
/>)}
|
||||||
itemKeys={photos.map(photo => photo.id)}
|
itemKeys={photos.map(photo => photo.id)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -64,6 +64,7 @@ export type AppStateContextType = {
|
|||||||
setUploadState?: (uploadState: Partial<UploadState>) => void
|
setUploadState?: (uploadState: Partial<UploadState>) => void
|
||||||
resetUploadState?: () => void
|
resetUploadState?: () => void
|
||||||
// DEBUG
|
// DEBUG
|
||||||
|
areAdminDebugToolsEnabled?: boolean
|
||||||
isGridHighDensity?: boolean
|
isGridHighDensity?: boolean
|
||||||
setIsGridHighDensity?: Dispatch<SetStateAction<boolean>>
|
setIsGridHighDensity?: Dispatch<SetStateAction<boolean>>
|
||||||
areZoomControlsShown?: boolean
|
areZoomControlsShown?: boolean
|
||||||
|
|||||||
@ -30,8 +30,10 @@ import { toastSuccess } from '@/toast';
|
|||||||
|
|
||||||
export default function AppStateProvider({
|
export default function AppStateProvider({
|
||||||
children,
|
children,
|
||||||
|
areAdminDebugToolsEnabled,
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
|
areAdminDebugToolsEnabled?: boolean
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@ -243,6 +245,7 @@ export default function AppStateProvider({
|
|||||||
setUploadState,
|
setUploadState,
|
||||||
resetUploadState,
|
resetUploadState,
|
||||||
// DEBUG
|
// DEBUG
|
||||||
|
areAdminDebugToolsEnabled,
|
||||||
isGridHighDensity,
|
isGridHighDensity,
|
||||||
setIsGridHighDensity,
|
setIsGridHighDensity,
|
||||||
areZoomControlsShown,
|
areZoomControlsShown,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user