复用画布尺寸状态生成项目封面
由 ResizeObserver 维护的 canvasSize 传入项目持久化 hook 移除持久化层对 canvasViewportRef 和 clientWidth/clientHeight 的直接读取 更新持久化测试夹具并保持封面尺寸断言
This commit is contained in:
@@ -1116,7 +1116,6 @@ export function ImageCanvasEditorView({
|
||||
() => ({
|
||||
layersRef,
|
||||
viewportRef,
|
||||
canvasViewportRef,
|
||||
canvasGenerationDialogsRef,
|
||||
canvasBackgroundColorRef,
|
||||
}),
|
||||
@@ -1156,6 +1155,7 @@ export function ImageCanvasEditorView({
|
||||
layers,
|
||||
canvasGenerationDialogs,
|
||||
viewport,
|
||||
canvasSize,
|
||||
canvasBackgroundColor,
|
||||
isViewportInteracting,
|
||||
canAccessProtectedData: authUi ? authUi.canAccessProtectedData : true,
|
||||
|
||||
@@ -113,12 +113,12 @@ function ProjectPersistenceHarness({
|
||||
y: 0,
|
||||
scale: 1,
|
||||
});
|
||||
const canvasSize = { width: 900, height: 640 };
|
||||
const [isViewportInteracting, setIsViewportInteracting] = useState(false);
|
||||
const [projectTitle, setProjectTitle] = useState('');
|
||||
const [projectRenameValue, setProjectRenameValue] = useState('');
|
||||
const layersRef = useRef(layers);
|
||||
const viewportRef = useRef(viewport);
|
||||
const canvasViewportRef = useRef<HTMLDivElement | null>(null);
|
||||
const canvasGenerationDialogsRef = useRef(generationDialogs);
|
||||
const canvasBackgroundColorRef = useRef(canvasBackgroundColor);
|
||||
const selectedLayerRef = useRef<string | null>(null);
|
||||
@@ -147,7 +147,6 @@ function ProjectPersistenceHarness({
|
||||
() => ({
|
||||
layersRef,
|
||||
viewportRef,
|
||||
canvasViewportRef,
|
||||
canvasGenerationDialogsRef,
|
||||
canvasBackgroundColorRef,
|
||||
}),
|
||||
@@ -173,6 +172,7 @@ function ProjectPersistenceHarness({
|
||||
layers,
|
||||
canvasGenerationDialogs: generationDialogs,
|
||||
viewport,
|
||||
canvasSize,
|
||||
canvasBackgroundColor,
|
||||
isViewportInteracting,
|
||||
canAccessProtectedData,
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
canvasDisplayViewportToViewport,
|
||||
type CanvasLayerResourceMetadata,
|
||||
DEFAULT_CANVAS_BACKGROUND_COLOR,
|
||||
DEFAULT_CANVAS_SIZE,
|
||||
hydrateLayer,
|
||||
isInlineEditorMediaSource,
|
||||
serializeCanvasLayout,
|
||||
@@ -40,6 +39,7 @@ import {
|
||||
PROJECT_COVER_SNAPSHOT_ASSET_KIND,
|
||||
PROJECT_COVER_SNAPSHOT_OBJECT_ASSET_KIND,
|
||||
PROJECT_COVER_SNAPSHOT_SIZE,
|
||||
type ProjectCoverSnapshotViewportSize,
|
||||
} from './ImageCanvasProjectCoverSnapshotModel';
|
||||
|
||||
type ProjectResourceOptions = {
|
||||
@@ -66,7 +66,6 @@ type CachedEditorProjectSnapshot = {
|
||||
type ImageCanvasProjectPersistenceRefs = {
|
||||
layersRef: RefObject<CanvasLayer[]>;
|
||||
viewportRef: RefObject<CanvasViewport>;
|
||||
canvasViewportRef: RefObject<HTMLDivElement | null>;
|
||||
canvasGenerationDialogsRef: RefObject<CanvasGenerationDialogState[]>;
|
||||
canvasBackgroundColorRef: RefObject<string>;
|
||||
};
|
||||
@@ -90,6 +89,7 @@ type ImageCanvasProjectPersistenceOptions = {
|
||||
layers: CanvasLayer[];
|
||||
canvasGenerationDialogs: CanvasGenerationDialogState[];
|
||||
viewport: CanvasViewport;
|
||||
canvasSize: ProjectCoverSnapshotViewportSize;
|
||||
canvasBackgroundColor: string;
|
||||
isViewportInteracting: boolean;
|
||||
canAccessProtectedData: boolean;
|
||||
@@ -116,21 +116,6 @@ function isEditorProjectRevisionConflict(error: unknown) {
|
||||
return error instanceof ApiClientError && error.status === 409;
|
||||
}
|
||||
|
||||
function resolveProjectCoverViewportSize(
|
||||
viewportElement: HTMLDivElement | null,
|
||||
) {
|
||||
const width = viewportElement?.clientWidth ?? 0;
|
||||
const height = viewportElement?.clientHeight ?? 0;
|
||||
return {
|
||||
width:
|
||||
width > 0 && Number.isFinite(width) ? width : DEFAULT_CANVAS_SIZE.width,
|
||||
height:
|
||||
height > 0 && Number.isFinite(height)
|
||||
? height
|
||||
: DEFAULT_CANVAS_SIZE.height,
|
||||
};
|
||||
}
|
||||
|
||||
const EDITOR_PROJECT_LAYOUT_RETRYABLE_STATUS_CODES = new Set([
|
||||
408, 425, 429, 502, 503, 504,
|
||||
]);
|
||||
@@ -330,6 +315,7 @@ export function useImageCanvasProjectPersistence({
|
||||
layers,
|
||||
canvasGenerationDialogs,
|
||||
viewport,
|
||||
canvasSize,
|
||||
canvasBackgroundColor,
|
||||
isViewportInteracting,
|
||||
canAccessProtectedData,
|
||||
@@ -354,6 +340,7 @@ export function useImageCanvasProjectPersistence({
|
||||
const projectTitleRef = useRef('未命名画布');
|
||||
const coverSnapshotSignatureRef = useRef<string | null>(null);
|
||||
const coverSnapshotUploadRequestRef = useRef(0);
|
||||
const coverSnapshotViewportSizeRef = useRef(canvasSize);
|
||||
const [projectId, setProjectId] = useState<string | null>(null);
|
||||
const [isProjectReady, setIsProjectReady] = useState(false);
|
||||
const {
|
||||
@@ -366,6 +353,7 @@ export function useImageCanvasProjectPersistence({
|
||||
restoreCanvasGenerationDialogs,
|
||||
applyCanvasBackgroundColor,
|
||||
} = setters;
|
||||
coverSnapshotViewportSizeRef.current = canvasSize;
|
||||
|
||||
const clearPendingProjectLayoutSave = useCallback(() => {
|
||||
pendingProjectLayoutSaveRef.current = null;
|
||||
@@ -478,9 +466,7 @@ export function useImageCanvasProjectPersistence({
|
||||
}
|
||||
const coverViewport =
|
||||
canvasDisplayViewportToViewport(coverDisplayViewport);
|
||||
const viewportSize = resolveProjectCoverViewportSize(
|
||||
refs.canvasViewportRef.current,
|
||||
);
|
||||
const viewportSize = coverSnapshotViewportSizeRef.current;
|
||||
const backgroundColor = refs.canvasBackgroundColorRef.current;
|
||||
const signature = buildProjectCoverSnapshotSignature({
|
||||
layers: coverLayers,
|
||||
|
||||
Reference in New Issue
Block a user