Refactor: 코멘트 api 리팩토링 - S11P21S002-258
This commit is contained in:
parent
4eed4889b3
commit
3fa8abfb34
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useRef, useState } from 'react';
|
||||
import { Group, Rect, Text, Image } from 'react-konva';
|
||||
import { CommentResponse } from '@/types';
|
||||
import useImage from 'use-image';
|
||||
@ -9,13 +9,22 @@ import toggleDownIconSrc from '@/assets/icons/chevron-down.svg';
|
||||
import Konva from 'konva';
|
||||
|
||||
interface CommentLabelProps {
|
||||
stage: Konva.Stage;
|
||||
comment: CommentResponse & { isOpen?: boolean };
|
||||
updateComment: (comment: CommentResponse) => void;
|
||||
deleteComment: (commentId: number) => void;
|
||||
toggleComment: (commentId: number) => void;
|
||||
}
|
||||
|
||||
export default function CommentLabel({ comment, updateComment, deleteComment, toggleComment }: CommentLabelProps) {
|
||||
export default function CommentLabel({
|
||||
stage,
|
||||
comment,
|
||||
updateComment,
|
||||
deleteComment,
|
||||
toggleComment,
|
||||
}: CommentLabelProps) {
|
||||
const groupRef = useRef<Konva.Group>(null);
|
||||
// const stage = groupRef.current?.getStage();
|
||||
const [content, setContent] = useState(comment.content);
|
||||
const [deleteIcon] = useImage(deleteIconSrc);
|
||||
const [toggleUpIcon] = useImage(toggleUpIconSrc);
|
||||
@ -31,7 +40,7 @@ export default function CommentLabel({ comment, updateComment, deleteComment, to
|
||||
|
||||
const handleDelete = (e: Konva.KonvaEventObject<MouseEvent>) => {
|
||||
e.cancelBubble = true;
|
||||
deleteComment(comment.id);
|
||||
confirm('정말 삭제하시겠습니까?') && deleteComment(comment.id);
|
||||
};
|
||||
|
||||
const handleToggle = (e: Konva.KonvaEventObject<MouseEvent>) => {
|
||||
@ -40,7 +49,9 @@ export default function CommentLabel({ comment, updateComment, deleteComment, to
|
||||
};
|
||||
|
||||
return (
|
||||
stage && (
|
||||
<Group
|
||||
ref={groupRef}
|
||||
x={comment.positionX}
|
||||
y={comment.positionY}
|
||||
draggable
|
||||
@ -49,57 +60,47 @@ export default function CommentLabel({ comment, updateComment, deleteComment, to
|
||||
const newY = e.target.y();
|
||||
updateComment({ ...comment, positionX: newX, positionY: newY });
|
||||
}}
|
||||
strokeScaleEnabled={false}
|
||||
scale={{ x: 1 / stage.getAbsoluteScale().x, y: 1 / stage.getAbsoluteScale().y }}
|
||||
perfectDrawEnabled={false}
|
||||
shadowForStrokeEnabled={false}
|
||||
>
|
||||
<Rect
|
||||
width={comment.isOpen ? 200 : 50}
|
||||
width={comment.isOpen ? 200 : 60}
|
||||
height={comment.isOpen ? 100 : 30}
|
||||
fill="white"
|
||||
stroke="black"
|
||||
onClick={handleEdit}
|
||||
stroke="#080808"
|
||||
strokeWidth={1}
|
||||
cornerRadius={5}
|
||||
/>
|
||||
{comment.isOpen && (
|
||||
<Text
|
||||
x={5}
|
||||
y={5}
|
||||
x={10}
|
||||
y={35}
|
||||
width={190}
|
||||
text={content || '내용 없음'}
|
||||
fontSize={16}
|
||||
fill="black"
|
||||
fill="#080808"
|
||||
onClick={handleEdit}
|
||||
/>
|
||||
)}
|
||||
{deleteIcon && (
|
||||
<Image
|
||||
image={comment.isOpen ? toggleUpIcon : toggleDownIcon}
|
||||
x={5}
|
||||
y={5}
|
||||
width={20}
|
||||
height={20}
|
||||
onClick={handleToggle}
|
||||
/>
|
||||
<Image
|
||||
image={deleteIcon}
|
||||
x={comment.isOpen ? 175 : 25}
|
||||
x={35}
|
||||
y={5}
|
||||
width={20}
|
||||
height={20}
|
||||
onClick={handleDelete}
|
||||
/>
|
||||
)}
|
||||
|
||||
{comment.isOpen
|
||||
? toggleUpIcon && (
|
||||
<Image
|
||||
image={toggleUpIcon}
|
||||
x={comment.isOpen ? 150 : 0}
|
||||
y={5}
|
||||
width={20}
|
||||
height={20}
|
||||
onClick={handleToggle}
|
||||
/>
|
||||
)
|
||||
: toggleDownIcon && (
|
||||
<Image
|
||||
image={toggleDownIcon}
|
||||
x={comment.isOpen ? 150 : 0}
|
||||
y={5}
|
||||
width={20}
|
||||
height={20}
|
||||
onClick={handleToggle}
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { TRANSFORM_CHANGE_STR } from '@/constants';
|
||||
import Konva from 'konva';
|
||||
import { Vector2d } from 'konva/lib/types';
|
||||
import { useEffect, useRef } from 'react';
|
||||
@ -10,19 +11,6 @@ interface PolygonTransformerProps {
|
||||
dragLayer: Konva.Layer;
|
||||
}
|
||||
|
||||
const TRANSFORM_CHANGE_STR = [
|
||||
'widthChange',
|
||||
'heightChange',
|
||||
'scaleXChange',
|
||||
'skewXChange',
|
||||
'skewYChange',
|
||||
'rotationChange',
|
||||
'offsetXChange',
|
||||
'offsetYChange',
|
||||
'transformsEnabledChange',
|
||||
'strokeWidthChange',
|
||||
];
|
||||
|
||||
export default function PolygonTransformer({ coordinates, setCoordinates, stage, dragLayer }: PolygonTransformerProps) {
|
||||
const anchorsRef = useRef<Konva.Group>(null);
|
||||
const scale: Vector2d = { x: 1 / stage.getAbsoluteScale().x, y: 1 / stage.getAbsoluteScale().y };
|
||||
@ -99,7 +87,10 @@ export default function PolygonTransformer({ coordinates, setCoordinates, stage,
|
||||
shadowForStrokeEnabled={false}
|
||||
listening={false}
|
||||
/>
|
||||
<Group ref={anchorsRef}>
|
||||
<Group
|
||||
ref={anchorsRef}
|
||||
// scale={scale}
|
||||
>
|
||||
{coordinates.map((point, index) => {
|
||||
return (
|
||||
<Circle
|
||||
|
@ -19,7 +19,6 @@ import { useQueryClient } from '@tanstack/react-query';
|
||||
import useSaveImageLabelsQuery from '@/queries/projects/useSaveImageLabelsQuery';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import CommentLabel from './CommentLabel';
|
||||
import useAuthStore from '@/stores/useAuthStore';
|
||||
|
||||
export default function ImageCanvas() {
|
||||
const { project, folderId, categories } = useProjectStore();
|
||||
@ -40,7 +39,6 @@ export default function ImageCanvas() {
|
||||
const queryClient = useQueryClient();
|
||||
const { toast } = useToast();
|
||||
|
||||
const { profile } = useAuthStore();
|
||||
const { comments, setComments } = useCommentStore();
|
||||
const { data: commentList } = useCommentListQuery(project!.id, imageId);
|
||||
const createCommentMutation = useCreateCommentQuery(project!.id, imageId);
|
||||
@ -208,6 +206,16 @@ export default function ImageCanvas() {
|
||||
setDrawState('pointer');
|
||||
setSelectedLabelId(id);
|
||||
};
|
||||
const addComment = () => {
|
||||
const { x, y } = stageRef.current!.getRelativePointerPosition()!;
|
||||
|
||||
createCommentMutation.mutate({
|
||||
content: '',
|
||||
positionX: x,
|
||||
positionY: y,
|
||||
});
|
||||
setDrawState('pointer');
|
||||
};
|
||||
|
||||
const handleClick = (e: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {
|
||||
e.evt.preventDefault();
|
||||
@ -216,37 +224,7 @@ export default function ImageCanvas() {
|
||||
const isRightClicked = e.evt.type === 'mousedown' && (e.evt as MouseEvent).button === 2;
|
||||
|
||||
if (drawState === 'comment' && isLeftClicked) {
|
||||
const stage = stageRef.current;
|
||||
if (!stage) return;
|
||||
|
||||
const pointerPosition = stage.getRelativePointerPosition();
|
||||
if (!pointerPosition) return;
|
||||
|
||||
if (!profile) {
|
||||
console.error('User profile is not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const x = pointerPosition.x;
|
||||
const y = pointerPosition.y;
|
||||
|
||||
createCommentMutation.mutate({
|
||||
id: 0,
|
||||
content: '',
|
||||
positionX: x,
|
||||
positionY: y,
|
||||
memberId: profile.id,
|
||||
memberNickname: profile.nickname,
|
||||
memberProfileImage: profile.profileImage,
|
||||
createTime: new Date().toISOString(),
|
||||
author: {
|
||||
id: profile.id,
|
||||
nickname: profile.nickname,
|
||||
profileImage: profile.profileImage,
|
||||
email: profile.email,
|
||||
},
|
||||
});
|
||||
return;
|
||||
addComment();
|
||||
}
|
||||
|
||||
if (drawState !== 'pointer' && (isLeftClicked || isRightClicked)) {
|
||||
@ -436,6 +414,7 @@ export default function ImageCanvas() {
|
||||
{comments.map((comment) => (
|
||||
<CommentLabel
|
||||
key={comment.id}
|
||||
stage={stageRef.current as Konva.Stage}
|
||||
comment={comment}
|
||||
updateComment={(updatedComment) => {
|
||||
updateCommentMutation.mutate({
|
||||
|
@ -80,3 +80,16 @@ export const LABEL_CATEGORY = [
|
||||
'hair drier',
|
||||
'toothbrush',
|
||||
];
|
||||
|
||||
export const TRANSFORM_CHANGE_STR = [
|
||||
'widthChange',
|
||||
'heightChange',
|
||||
'scaleXChange',
|
||||
'skewXChange',
|
||||
'skewYChange',
|
||||
'rotationChange',
|
||||
'offsetXChange',
|
||||
'offsetYChange',
|
||||
'transformsEnabledChange',
|
||||
'strokeWidthChange',
|
||||
];
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { createComment } from '@/api/commentAPi';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { CommentResponse } from '@/types';
|
||||
import { CommentRequest } from '@/types';
|
||||
|
||||
export default function useCreateCommentQuery(projectId: number, imageId: number) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (commentData: CommentResponse) => createComment(projectId, imageId, commentData),
|
||||
mutationFn: (commentData: CommentRequest) => createComment(projectId, imageId, commentData),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['commentList', projectId, imageId] });
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { updateComment } from '@/api/commentAPi';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { CommentRequest } from '@/types';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
export default function useUpdateCommentQuery(projectId: number) {
|
||||
const queryClient = useQueryClient();
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { MemberResponse } from './memberTypes';
|
||||
|
||||
// 댓글 관련 DTO
|
||||
export interface CommentRequest {
|
||||
content: string;
|
||||
positionX: number;
|
||||
@ -9,16 +8,9 @@ export interface CommentRequest {
|
||||
|
||||
export interface CommentResponse {
|
||||
id: number;
|
||||
memberId: number;
|
||||
memberNickname: string;
|
||||
memberProfileImage: string;
|
||||
positionX: number;
|
||||
positionY: number;
|
||||
content: string;
|
||||
createTime: string; // 작성 일자 (ISO 8601 형식)
|
||||
author: MemberResponse; // 추가됨
|
||||
}
|
||||
|
||||
export interface CommentListResponse {
|
||||
commentResponses: CommentResponse[];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user