fix(tool): right object
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user