Show 3D hall loading overlay during canvas and texture boot.

Display Loading gallery and Loading paintings in the canvas area while the WebGL scene initializes and wall textures resolve, and document the behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila KhodjaefandCursor committed 2026-07-08 15:18:16 +03:00
1 parent 21e3e41e48
commit aa6635803d
3 files changed
+21 -11

No files matched your search

+16 -10
View File
@@ -1711,6 +1711,7 @@ export default function VirtualGallery(props: Props) {
const [nearPassage, setNearPassage] = useState(false);
const [isLooking, setIsLooking] = useState(false);
const [texturesPending, setTexturesPending] = useState(0);
const [canvasReady, setCanvasReady] = useState(false);
const [glEpoch, setGlEpoch] = useState(0);
const [glLost, setGlLost] = useState(false);
@@ -1722,15 +1723,12 @@ export default function VirtualGallery(props: Props) {
[]
);
useEffect(() => {
setTexturesPending(0);
}, [hallKey, glEpoch]);
const handleCanvasCreated = useCallback((state: { gl: THREE.WebGLRenderer }) => {
const canvas = state.gl.domElement;
// A freshly created canvas has a healthy context, so clear any lingering
// "restoring" state from a previous loss/remount.
setGlLost(false);
setCanvasReady(true);
const onLost = (event: Event) => {
// Prevent the default so the browser can restore the context, and
// force a clean remount to obtain a fresh WebGL context if it does not.
@@ -1798,6 +1796,14 @@ export default function VirtualGallery(props: Props) {
return buildHallLayout(paintings, periods);
}, [isMovement, movementHalls, hallIndex, paintings, periods]);
const gallerySceneLoading = active && !glLost && (!canvasReady || texturesPending > 0);
const galleryLoadingMessage = !canvasReady
? 'Loading gallery…'
: texturesPending > 0
? 'Loading paintings…'
: 'Loading gallery…';
const computedWindows = useMemo(() => {
if (!isMovement || !interiorStyle || !('hallIndex' in layout)) return undefined;
return computeSideWallWindows(layout as MovementHallLayout, interiorStyle);
@@ -2069,10 +2075,13 @@ export default function VirtualGallery(props: Props) {
onPointerLeave={endCanvasDrag}
onPointerCancel={endCanvasDrag}
>
{active && texturesPending > 0 && (
<GalleryLoadingMarker overlay message="Loading paintings…" />
{active && (gallerySceneLoading || glLost) && (
<GalleryLoadingMarker
overlay
message={glLost ? 'Restoring gallery…' : galleryLoadingMessage}
/>
)}
{syncStatus && texturesPending === 0 && (
{syncStatus && !gallerySceneLoading && !glLost && (
<div className="gallery-loading-overlay gallery-sync-badge">
<p>{syncStatus}</p>
</div>
@@ -2080,9 +2089,6 @@ export default function VirtualGallery(props: Props) {
{!showExitNav && (
<div className="gallery-exit-hint">{exitHint}</div>
)}
{glLost && (
<GalleryLoadingMarker overlay message="Restoring gallery…" />
)}
<Canvas
key={`${hallKey}-${glEpoch}`}
shadows