fix(tool): right object

This commit is contained in:
zhangheng
2026-04-20 20:10:05 +08:00
parent dbdf834caa
commit 853801b947
2 changed files with 137 additions and 68 deletions

View File

@@ -8,8 +8,8 @@ import {
Collapse, Collapse,
Flex, Flex,
Group, Group,
HoverCard,
Paper, Paper,
Popover,
ScrollArea, ScrollArea,
Stack, Stack,
Text, Text,
@@ -31,6 +31,7 @@ import {
} from "lucide-react" } from "lucide-react"
import paper from "paper" import paper from "paper"
import { useCallback, useMemo, useState } from "react" import { useCallback, useMemo, useState } from "react"
import { Comment } from "../api/label/typing"
import { Project } from "../api/project/typing" import { Project } from "../api/project/typing"
import { Task } from "../api/task/typing" import { Task } from "../api/task/typing"
import { LabelState } from "../LabelNossr" import { LabelState } from "../LabelNossr"
@@ -141,6 +142,65 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
} }
}, []) }, [])
const getCommentTextColor = useCallback((type: number) => {
switch (type) {
case 3:
return "yellow.9"
case 2:
return "red.7"
case 1:
return "green.7"
case 0:
return "gray.7"
default:
return "blue.7"
}
}, [])
const getUserLabel = useCallback(
(uid?: number) => {
if (uid === undefined || uid === null) return "-"
return (
userOpts.find((item) => item.value === uid)?.label || uid.toString()
)
},
[userOpts]
)
const getCommentCount = useCallback((commentItem: Comment) => {
const checkBoxComments = (commentItem.check_box_comments || []).filter(
(item) => item?.trim()
)
const textComments = (commentItem.text_comments || []).filter((item) =>
item?.trim()
)
return checkBoxComments.length + textComments.length
}, [])
const getCommentContent = useCallback((commentItem: Comment) => {
const mergedComments = [
...(commentItem.check_box_comments || []),
...(commentItem.text_comments || []),
].filter((item) => item?.trim())
return mergedComments.length ? mergedComments.join(",") : "无批注"
}, [])
const getCommentDisplayType = useCallback(
(commentItem: Comment, lastModifiedTimestamp?: number) => {
const type = Math.max(0, Math.min(3, commentItem.comment_type ?? 0))
if (
type === 2 &&
lastModifiedTimestamp &&
lastModifiedTimestamp > commentItem.date &&
getCommentCount(commentItem) > 0
) {
return 3
}
return type
},
[getCommentCount]
)
const { shift: pressShift } = useKeyEventStore() const { shift: pressShift } = useKeyEventStore()
const continuePolygonTarget = usePaperStore( const continuePolygonTarget = usePaperStore(
@@ -696,15 +756,10 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
comment.length === 1 comment.length === 1
? comment[comment.length - 1] ? comment[comment.length - 1]
: comment[comment.length - 2] : comment[comment.length - 2]
let type = latest_comment.comment_type const type = getCommentDisplayType(
if (type === 2) { latest_comment,
const { last_modified_timestamp } = child[2] child[2].last_modified_timestamp
if ( )
last_modified_timestamp &&
last_modified_timestamp > latest_comment.date
)
type = 3
}
visibleFlag = checkBoxsChecked[3 - type] visibleFlag = checkBoxsChecked[3 - type]
} }
if (checkBoxsChecked.every((value) => !value)) if (checkBoxsChecked.every((value) => !value))
@@ -954,12 +1009,7 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
<Group gap={4}> <Group gap={4}>
<Text size="xs"></Text> <Text size="xs"></Text>
<Text size="xs"> <Text size="xs">
{ {getUserLabel(child[2]?.uid)}
userOpts.find(
(item) =>
item.value === child[2]?.uid
)?.label
}
</Text> </Text>
<Text size="xs"> <Text size="xs">
{dayjs( {dayjs(
@@ -972,14 +1022,9 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
<Group gap={4}> <Group gap={4}>
<Text size="xs"></Text> <Text size="xs"></Text>
<Text size="xs"> <Text size="xs">
{ {getUserLabel(
userOpts.find( child[2]?.first_modified_uid
(item) => )}
item.value ===
child[2]
?.first_modified_uid
)?.label
}
</Text> </Text>
<Text size="xs"> <Text size="xs">
{dayjs( {dayjs(
@@ -994,14 +1039,9 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
<Group gap={4}> <Group gap={4}>
<Text size="xs"></Text> <Text size="xs"></Text>
<Text size="xs"> <Text size="xs">
{ {getUserLabel(
userOpts.find( child[2]?.last_modified_uid
(item) => )}
item.value ===
child[2]
?.last_modified_uid
)?.label
}
</Text> </Text>
<Text size="xs"> <Text size="xs">
{dayjs( {dayjs(
@@ -1027,33 +1067,28 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
</Group> </Group>
{comment ? ( {comment ? (
<Group gap={4}> <Group gap={4}>
{comment.map((c: any) => { {comment.map((c: Comment) => {
const count = const count = getCommentCount(c)
c.check_box_comments.length + const commentType =
c.text_comments.length getCommentDisplayType(
const { last_modified_timestamp } = c,
child[2] child[2]?.last_modified_timestamp
let flag = false )
if ( const badgeColor =
count > 0 && getCheckBoxColor(commentType)
last_modified_timestamp && const commentTextColor =
last_modified_timestamp > c.date getCommentTextColor(commentType)
)
flag = true
let badgeColor = "gray"
if (c.comment_type === 1)
badgeColor = "green"
if (c.comment_type === 2)
badgeColor = "red"
if (flag) badgeColor = "yellow"
return ( return (
<Popover <HoverCard
key={`${child[0]}${c.turn}${c.times}`} key={`${child[0]}${c.turn}${c.times}`}
position="left" position="left"
withArrow> withArrow
<Popover.Target> shadow="md"
openDelay={100}
closeDelay={100}
withinPortal>
<HoverCard.Target>
<Badge <Badge
size="xs" size="xs"
circle circle
@@ -1063,16 +1098,14 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
}}> }}>
{count} {count}
</Badge> </Badge>
</Popover.Target> </HoverCard.Target>
<Popover.Dropdown> <HoverCard.Dropdown>
<Text size="xs" c={badgeColor}> <Text
{`P${child[2].image_id}${ size="xs"
child[2].uid c={commentTextColor}>
}${c.check_box_comments.join( {`P${child[2].image_id}${getUserLabel(
"," c.uid
)},${c.text_comments.join( )}${getCommentContent(c)} ${
","
)} ${
c.date c.date
? dayjs( ? dayjs(
c.date * 1000 c.date * 1000
@@ -1082,8 +1115,8 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
: "" : ""
}`} }`}
</Text> </Text>
</Popover.Dropdown> </HoverCard.Dropdown>
</Popover> </HoverCard>
) )
})} })}
</Group> </Group>

View File

@@ -184,6 +184,9 @@ const TopTools = (
const [operationPickerOpened, setOperationPickerOpened] = useState(false) const [operationPickerOpened, setOperationPickerOpened] = useState(false)
const [operationKeyword, setOperationKeyword] = useState("") const [operationKeyword, setOperationKeyword] = useState("")
const labelData = useLabelStore((state) => state.label) const labelData = useLabelStore((state) => state.label)
const labelDefaultComments = useLabelStore(
(state) => state.labelDefaultComments
)
const setLabel = useLabelStore((state) => state.setLabel) const setLabel = useLabelStore((state) => state.setLabel)
const pushStateStack = useLabelStore((state) => state.pushStateStack) const pushStateStack = useLabelStore((state) => state.pushStateStack)
const setLabelTime = useLabelTimeStore((state) => state.setLabelTime) const setLabelTime = useLabelTimeStore((state) => state.setLabelTime)
@@ -1035,10 +1038,41 @@ const TopTools = (
}) })
return return
} }
const finalData = adjustAllPoints( const recoveredData = adjustAllPoints(
backupData, backupData,
usePaperStore.getState().rasterScale usePaperStore.getState().rasterScale
) )
const finalData = safeClone(recoveredData)
for (const [imageId, categoryMap] of finalData.entries()) {
const currentDetailById = new Map<number, any>()
labelData.get(imageId)?.forEach((objects) => {
objects.forEach(([id, _points, detail]) => {
currentDetailById.set(id, detail)
})
})
for (const [operationId, objects] of categoryMap.entries()) {
categoryMap.set(
operationId,
objects.map(([id, points, detail, hollowPoints]) => {
const currentDetail = currentDetailById.get(id)
return [
id,
points,
{
...detail,
comment: currentDetail?.comment
? safeClone(currentDetail.comment)
: safeClone(labelDefaultComments),
last_modified_timestamp:
currentDetail?.last_modified_timestamp ??
detail.last_modified_timestamp,
},
hollowPoints,
]
}) as any
)
}
}
for (const entry of finalData.entries()) { for (const entry of finalData.entries()) {
// 赋值用过的id // 赋值用过的id
for (const category of entry[1].values()) { for (const category of entry[1].values()) {
@@ -1099,6 +1133,8 @@ const TopTools = (
}, },
[ [
activeImage, activeImage,
labelData,
labelDefaultComments,
projectDetail?.label_type, projectDetail?.label_type,
pushStateStack, pushStateStack,
renderPolygons, renderPolygons,