fix(devtool): 元数据对象中的 tip 属性导致 JSON 序列化失败

This commit is contained in:
XcantloadX 2025-02-04 15:33:13 +08:00
parent aaef92dea3
commit 714dafc124
5 changed files with 29 additions and 6 deletions

View File

@ -169,7 +169,7 @@ function DragTool(props: ToolHandlerProps) {
onNativeMouseLeave={handleRectMouseLeave}
onNativeClick={(e) => handleRectClick(anno.id, e)}
onTransform={(points) => handleRectTransform(points, anno.id)}
rectTip={anno.tip}
rectTip={anno._tip}
showRectTip={hoveredRectId === anno.id && selectedRectId === null}
/>
));

View File

@ -297,7 +297,7 @@ const ImageEditor = React.forwardRef<ImageEditorRef, ImageEditorProps>((props, r
<RectBox
key={rect.id}
rect={Convertor.rectImage2Container(rect.data)}
rectTip={rect.tip}
rectTip={rect._tip}
{...props}
/>
));

View File

@ -15,7 +15,7 @@ export interface Annotation {
type: AnnotationType;
data: AnnotationTypeMap[AnnotationType];
/** 提示信息。 */
tip?: React.ReactNode;
_tip?: React.ReactNode;
}
export interface Point {
x: number;

View File

@ -35,8 +35,25 @@ export interface ImageMetaData {
annotations: Annotation[];
}
function fromString(data: string): ImageMetaData {
return JSON.parse(data);
}
function toString(data: ImageMetaData): string {
const replacer = (key: string, value: any) => {
if (key.startsWith('_')) {
return undefined;
}
return value;
};
return JSON.stringify(data, replacer);
}
function useImageMetaData(data?: ImageMetaData) {
const [imageMetaData, updateImageMetaData] = useImmer<ImageMetaData>(data || {
definitions: {},
annotations: [],
});
@ -117,7 +134,12 @@ function useImageMetaData(data?: ImageMetaData) {
load,
/** 检查是否没有任何标注和定义 */
isEmpty: () => imageMetaData.annotations.length === 0 && Object.keys(imageMetaData.definitions).length === 0,
/** 将图像元数据转换为字符串 */
toString,
/** 将字符串转换为图像元数据 */
fromString,
};
}
export default useImageMetaData;

View File

@ -281,7 +281,7 @@ const usePropertyGridData = (
const ImageAnnotation: React.FC = () => {
const [currentTool, setCurrentTool] = useState<EditorTool>(EditorTool.Drag);
const { imageMetaData, Definitions, Annotations, clear, load } = useImageMetaData();
const { imageMetaData, Definitions, Annotations, clear, load, toString, fromString } = useImageMetaData();
const [selectedAnnotation, setSelectedAnnotation] = useState<Annotation | null>(null);
const [isDirty, setIsDirty] = useState(false);
const [image, setImage] = useState<HTMLImageElement | null>(null);
@ -425,10 +425,11 @@ const ImageAnnotation: React.FC = () => {
try {
const handle = await saveFileWFS(
currentFileResult.current?.handle,
JSON.stringify(imageMetaData),
toString(imageMetaData),
imageFileNameRef.current ? `${imageFileNameRef.current}.json` : 'metadata.json'
);
// 更新文件句柄
if (handle !== currentFileResult.current?.handle) {
currentFileResult.current = {
file: await handle.getFile(),
@ -477,7 +478,7 @@ const ImageAnnotation: React.FC = () => {
if (definition) {
Annotations.update({
id,
tip: <Tip>{displayName} ({name})</Tip>
_tip: <Tip>{displayName} ({name})</Tip>
});
}
};