关闭 3D 预览面板时清掉查看器状态

- src/components/image-editor/model3d-preview/Model3dViewerModal.tsx:layer 变 null(面板关闭)时把 viewerStatus 复位,下一次打开从禁用的「重置视角」开始,不再继承上一轮实例的 ready;只处理关闭不处理换模型,避免 effect 晚于查看器上报而盖掉 loading
- src/components/image-editor/model3d-preview/Model3dViewerModal.test.tsx:新增「关闭后重开不沿用 ready」的回归用例

验证:npx vitest run src/components/image-editor/model3d-preview(18 用例全绿)
This commit is contained in:
2026-09-22 13:29:10 +08:00
parent c96d7fe847
commit 0ec0a13cbc
2 changed files with 25 additions and 1 deletions
@@ -195,4 +195,20 @@ describe('Model3dViewerModal', () => {
expect(screen.queryByRole('dialog', { name: '3D模型预览' })).toBeNull();
});
it('关闭面板后重开不沿用上一轮的 ready 状态', () => {
const layer = createLayer();
const { rerender } = renderModal(layer);
const resetButton = () =>
screen.getByRole('button', { name: '重置视角' }) as HTMLButtonElement;
expect(resetButton().disabled).toBe(false);
rerender(<Model3dViewerModal layer={null} onClose={vi.fn()} />);
// 重开后的新查看器本轮不上报状态,按钮必须保持禁用,不能继承上一轮的 ready。
reportedStatus.status = 'idle';
rerender(<Model3dViewerModal layer={layer} onClose={vi.fn()} />);
expect(resetButton().disabled).toBe(true);
});
});
@@ -5,7 +5,7 @@ import {
type Model3dViewerStatus,
type Model3dViewerStatusDetail,
} from '@genarrative/model3d-viewer';
import { useRef, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useResolvedAssetReadUrl } from '../../../hooks/useResolvedAssetReadUrl';
import { PlatformActionButton } from '../../common/PlatformActionButton';
@@ -111,6 +111,14 @@ export function Model3dViewerModal({
MODEL3D_VIEWER_FAILURE_FALLBACK_TEXT,
);
// 面板关闭(layer 变 null)时清掉状态,让下一次打开从禁用的「重置视角」重新开始。
// 只处理关闭、不处理换模型:换模型时查看器会立刻上报,effect 晚一步会把 loading 盖掉。
useEffect(() => {
if (viewerIdentity === null) {
setViewerStatus(null);
}
}, [viewerIdentity]);
return (
<UnifiedModal
open={Boolean(layer)}