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

View File

@@ -184,6 +184,9 @@ const TopTools = (
const [operationPickerOpened, setOperationPickerOpened] = useState(false)
const [operationKeyword, setOperationKeyword] = useState("")
const labelData = useLabelStore((state) => state.label)
const labelDefaultComments = useLabelStore(
(state) => state.labelDefaultComments
)
const setLabel = useLabelStore((state) => state.setLabel)
const pushStateStack = useLabelStore((state) => state.pushStateStack)
const setLabelTime = useLabelTimeStore((state) => state.setLabelTime)
@@ -1035,10 +1038,41 @@ const TopTools = (
})
return
}
const finalData = adjustAllPoints(
const recoveredData = adjustAllPoints(
backupData,
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()) {
// 赋值用过的id
for (const category of entry[1].values()) {
@@ -1099,6 +1133,8 @@ const TopTools = (
},
[
activeImage,
labelData,
labelDefaultComments,
projectDetail?.label_type,
pushStateStack,
renderPolygons,