Skip to content

Commit f9f7aab

Browse files
committed
feat: message creation effects
1 parent dd9e643 commit f9f7aab

File tree

10 files changed

+267
-95
lines changed

10 files changed

+267
-95
lines changed

src/components/DiagramFrame/SeqDiagram/LifeLineLayer/LifeLine.tsx

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,15 @@
1-
import {
2-
codeAtom,
3-
diagramElementAtom,
4-
dragAnchorAtom,
5-
onContentChangeAtom,
6-
scaleAtom,
7-
} from "@/store/Store";
8-
import { useAtom, useAtomValue } from "jotai";
1+
import { diagramElementAtom, dragAnchorAtom, scaleAtom } from "@/store/Store";
2+
import { useAtomValue } from "jotai";
93
import { useCallback, useEffect, useRef, useState } from "react";
104
import parentLogger from "@/logger/logger";
115
import { EventBus } from "@/EventBus";
126
import { cn } from "@/utils";
137
import { Participant } from "./Participant";
148
import { centerOf } from "../MessageLayer/Block/Statement/utils";
15-
import {
16-
getCurrentLine,
17-
getLeadingSpaces,
18-
getLineTail,
19-
getPrevLine,
20-
getPrevNotCommentLineTail,
21-
} from "@/utils/StringUtil";
9+
import { useAnchorDrop } from "./useAnchorDrop";
2210

2311
const logger = parentLogger.child({ name: "LifeLine" });
2412

25-
const INDENT = " ";
26-
2713
export const LifeLine = (props: {
2814
entity: any;
2915
groupLeft?: any;
@@ -32,8 +18,6 @@ export const LifeLine = (props: {
3218
className?: string;
3319
}) => {
3420
const elRef = useRef<HTMLDivElement>(null);
35-
const [code, setCode] = useAtom(codeAtom);
36-
const onContentChange = useAtomValue(onContentChangeAtom);
3721
const scale = useAtomValue(scaleAtom);
3822
const diagramElement = useAtomValue(diagramElementAtom);
3923
const PARTICIPANT_TOP_SPACE_FOR_GROUP = 20;
@@ -79,36 +63,7 @@ export const LifeLine = (props: {
7963
}, [props.entity, updateTop]);
8064

8165
const dragAnchor = useAtomValue(dragAnchorAtom);
82-
const handleDrop = () => {
83-
if (!dragAnchor) return;
84-
let newCode = code;
85-
const messageContent = `${props.entity.name}.method`;
86-
if (typeof dragAnchor.index !== "number") {
87-
const start = dragAnchor.context.children[0]?.start?.start;
88-
const insertPosition = getLineTail(code, start);
89-
const prev = code.slice(0, insertPosition);
90-
const next = code.slice(insertPosition);
91-
const leadingSpaces = getLeadingSpaces(
92-
getPrevLine(code, insertPosition + 1),
93-
);
94-
newCode = `${prev} {\n${leadingSpaces}${INDENT}${messageContent}\n${leadingSpaces}}${next}`;
95-
} else if (dragAnchor.index < dragAnchor.context.children.length) {
96-
const start = dragAnchor.context.children[dragAnchor.index]?.start?.start;
97-
const insertPosition = getPrevNotCommentLineTail(code, start) + 1;
98-
const prev = code.slice(0, insertPosition);
99-
const next = code.slice(insertPosition);
100-
newCode = `${prev}${getLeadingSpaces(next)}${messageContent}\n${next}`;
101-
} else {
102-
const start =
103-
dragAnchor.context.children.at(-1)?.stop?.stop || code.length;
104-
const insertPosition = getLineTail(code, start);
105-
const prev = code.slice(0, insertPosition);
106-
const next = code.slice(insertPosition);
107-
newCode = `${prev}\n${getLeadingSpaces(getCurrentLine(code, insertPosition))}${messageContent}\n${next}`;
108-
}
109-
setCode(newCode);
110-
onContentChange(newCode);
111-
};
66+
const { handleDrop } = useAnchorDrop(props.entity.name);
11267

11368
return (
11469
<div
@@ -136,7 +91,7 @@ export const LifeLine = (props: {
13691
)}
13792
onMouseUp={handleDrop}
13893
/>
139-
<div className="relative line w0 mx-auto flex-grow w-px bg-[linear-gradient(to_bottom,transparent_50%,var(--color-border-base)_50%)] bg-[length:1px_10px]" />
94+
<div className="relative line mx-auto flex-grow w-px bg-[linear-gradient(to_bottom,transparent_50%,var(--color-border-base)_50%)] bg-[length:1px_10px] pointer-events-none" />
14095
</>
14196
)}
14297
</div>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { codeAtom, dragAnchorAtom, onContentChangeAtom } from "@/store/Store";
2+
import {
3+
getCurrentLine,
4+
getLeadingSpaces,
5+
getLineTail,
6+
getPrevLine,
7+
getPrevNotCommentLineTail,
8+
} from "@/utils/StringUtil";
9+
import { useAtom, useAtomValue } from "jotai";
10+
11+
const DEFAULT_INDENT = " ";
12+
13+
export const useAnchorDrop = (entity: string) => {
14+
const [code, setCode] = useAtom(codeAtom);
15+
const dragAnchor = useAtomValue(dragAnchorAtom);
16+
const onContentChange = useAtomValue(onContentChangeAtom);
17+
const handleDrop = () => {
18+
if (!dragAnchor) return;
19+
let newCode = code;
20+
const messageContent = `${entity}."${dragAnchor.id}"`;
21+
if (typeof dragAnchor.index !== "number") {
22+
const braces = dragAnchor.context?.braceBlock?.();
23+
if (braces) {
24+
console.log(braces);
25+
// insert new message inside empty braces
26+
const prev = code.slice(0, braces.start.start);
27+
const next = code.slice(braces.stop.stop + 1);
28+
const leadingSpaces = getLeadingSpaces(
29+
getCurrentLine(code, braces.start.start),
30+
);
31+
newCode = `${prev}{\n${leadingSpaces}${DEFAULT_INDENT}${messageContent}\n${leadingSpaces}}${next}`;
32+
} else {
33+
// insert new message with new braces
34+
const start = dragAnchor.context.children[0]?.start?.start;
35+
const insertPosition = getLineTail(code, start);
36+
const prev = code.slice(0, insertPosition);
37+
const next = code.slice(insertPosition);
38+
const leadingSpaces = getLeadingSpaces(
39+
getPrevLine(code, insertPosition + 1),
40+
);
41+
newCode = `${prev} {\n${leadingSpaces}${DEFAULT_INDENT}${messageContent}\n${leadingSpaces}}${next}`;
42+
}
43+
} else if (dragAnchor.index < dragAnchor.context.children.length) {
44+
// insert new message inside a block
45+
const start = dragAnchor.context.children[dragAnchor.index]?.start?.start;
46+
const insertPosition = getPrevNotCommentLineTail(code, start) + 1;
47+
const prev = code.slice(0, insertPosition);
48+
const next = code.slice(insertPosition);
49+
newCode = `${prev}${getLeadingSpaces(next)}${messageContent}\n${next}`;
50+
} else {
51+
// insert new message at the end of a block
52+
const start =
53+
dragAnchor.context.children.at(-1)?.stop?.stop || code.length;
54+
const insertPosition = getLineTail(code, start);
55+
const prev = code.slice(0, insertPosition);
56+
const next = code.slice(insertPosition);
57+
const leadingSpaces = getLeadingSpaces(
58+
getCurrentLine(code, insertPosition),
59+
);
60+
newCode = `${prev}\n${leadingSpaces}${messageContent}\n${next}`;
61+
}
62+
setCode(newCode);
63+
onContentChange(newCode);
64+
};
65+
66+
return { handleDrop };
67+
};

src/components/DiagramFrame/SeqDiagram/MessageLayer/Anchor.tsx

Lines changed: 132 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
import { diagramElementAtom, dragAnchorAtom, scaleAtom } from "@/store/Store";
2-
import { useAtomValue, useSetAtom } from "jotai";
1+
import {
2+
diagramElementAtom,
3+
dragAnchorAtom,
4+
lastCreatedStatementAtom,
5+
scaleAtom,
6+
} from "@/store/Store";
7+
import { cn } from "@/utils";
8+
import { useAtom, useAtomValue, useSetAtom } from "jotai";
39
import { useRef } from "react";
410

511
const icon = (
@@ -16,17 +22,131 @@ const icon = (
1622
</svg>
1723
);
1824

25+
const getRandomContent = () => {
26+
const wordList = [
27+
"valley",
28+
"tunnel",
29+
"lesson",
30+
"prosper",
31+
"burden",
32+
"alert",
33+
"lion",
34+
"shell",
35+
"rhythm",
36+
"turkey",
37+
"crouch",
38+
"angry",
39+
"garlic",
40+
"decade",
41+
"mistake",
42+
"ladder",
43+
"donor",
44+
"crop",
45+
"debate",
46+
"army",
47+
"boil",
48+
"figure",
49+
"half",
50+
"fall",
51+
"business",
52+
"pair",
53+
"remind",
54+
"clinic",
55+
"stereo",
56+
"hamster",
57+
"rookie",
58+
"sand",
59+
"huge",
60+
"gym",
61+
"lobster",
62+
"eyebrow",
63+
"castle",
64+
"youth",
65+
"middle",
66+
"custom",
67+
"flame",
68+
"exhibit",
69+
"pave",
70+
"kitten",
71+
"mirror",
72+
"pulp",
73+
"heavy",
74+
"adjust",
75+
"shrimp",
76+
"script",
77+
"energy",
78+
"hotel",
79+
"glue",
80+
"engage",
81+
"unlock",
82+
"fire",
83+
"child",
84+
"grass",
85+
"avoid",
86+
"gasp",
87+
"vessel",
88+
"ethics",
89+
"brass",
90+
"guilt",
91+
"palace",
92+
"limit",
93+
"upset",
94+
"lava",
95+
"embody",
96+
"narrow",
97+
"badge",
98+
"slogan",
99+
"river",
100+
"tooth",
101+
"license",
102+
"concert",
103+
"lemon",
104+
"quantum",
105+
"success",
106+
"creek",
107+
"ginger",
108+
"stock",
109+
"exhibit",
110+
"dolphin",
111+
"sweet",
112+
"nuclear",
113+
"pistol",
114+
"expire",
115+
"coin",
116+
"scare",
117+
"jump",
118+
"pencil",
119+
"unique",
120+
"game",
121+
"spice",
122+
"genuine",
123+
"swallow",
124+
"online",
125+
"equip",
126+
"twist",
127+
];
128+
return `${wordList[Math.floor(Math.random() * wordList.length)]} ${wordList[Math.floor(Math.random() * wordList.length)]}`;
129+
};
130+
19131
export const Anchor = (props: {
20132
context: any;
21133
participant: string;
22134
index?: number;
135+
offset?: number;
23136
}) => {
24137
const elRef = useRef<HTMLDivElement>(null);
25138
const scale = useAtomValue(scaleAtom) || 0;
26139
const diagramElement = useAtomValue(diagramElementAtom);
27-
const setAnchor = useSetAtom(dragAnchorAtom);
140+
const [anchor, setAnchor] = useAtom(dragAnchorAtom);
141+
const setLastCreatedStatement = useSetAtom(lastCreatedStatementAtom);
142+
const id = useRef<string>(getRandomContent());
28143
return (
29-
<div className="relative w-6 h-6 -my-1 -ml-[12.5px]">
144+
<div
145+
className={cn(
146+
"relative w-6 h-6 -my-1 -ml-[12.5px]",
147+
anchor?.id === id.current && "pt-20",
148+
)}
149+
>
30150
<div
31151
className="text-sky-500 cursor-pointer absolute w-6 h-6 inline-flex justify-center items-center pointer-events-auto [&:hover>svg]:visible overflow-hidden"
32152
ref={elRef}
@@ -39,12 +159,19 @@ export const Anchor = (props: {
39159
} = elRef.current?.getBoundingClientRect() || {};
40160
const diagramRect = diagramElement?.getBoundingClientRect();
41161
setAnchor({
162+
id: id.current,
42163
context: props.context,
43164
index: props.index,
44165
participant: props.participant,
45166
x: (left - (diagramRect?.left || 0)) / scale,
46-
y: (top + height / 2 - (diagramRect?.top || 0)) / scale,
167+
y:
168+
(top +
169+
height / 2 -
170+
(diagramRect?.top || 0) +
171+
(props.offset ?? 25)) /
172+
scale,
47173
});
174+
setLastCreatedStatement(id.current);
48175
}}
49176
>
50177
{icon}

0 commit comments

Comments
 (0)