v2-ui #94

Merged
Vishnu merged 38 commits from v2-ui into main 2025-05-26 05:09:47 +00:00
2 changed files with 75 additions and 13 deletions
Showing only changes of commit 53c2ad0917 - Show all commits

View File

@ -6,12 +6,15 @@ import { adjustHeight } from "./function/textAreaHeightAdjust";
const ThreadChat: React.FC = () => { const ThreadChat: React.FC = () => {
const [openThreadOptions, setOpenThreadOptions] = useState(false); const [openThreadOptions, setOpenThreadOptions] = useState(false);
const [inputActive, setInputActive] = useState(false); const [inputActive, setInputActive] = useState(false);
const [value, setValue] = useState<string>(""); const [value, setValue] = useState<string>("");
const textareaRef = useRef<HTMLTextAreaElement>(null); const textareaRef = useRef<HTMLTextAreaElement>(null);
const wrapperRef = useRef<HTMLDivElement>(null);
const [dragging, setDragging] = useState(false);
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
const [position, setPosition] = useState({ x: 100, y: 100 });
const messages = [ const messages = [
{ {
@ -34,17 +37,78 @@ const ThreadChat: React.FC = () => {
if (textareaRef.current) adjustHeight(textareaRef.current); if (textareaRef.current) adjustHeight(textareaRef.current);
}, [value]); }, [value]);
const clamp = (val: number, min: number, max: number) => {
return Math.min(Math.max(val, min), max);
};
const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
if (event.button !== 0) return;
const wrapper = wrapperRef.current;
if (!wrapper) return;
const rect = wrapper.getBoundingClientRect();
const offsetX = event.clientX - rect.left;
const offsetY = event.clientY - rect.top;
setDragging(true);
setDragOffset({ x: offsetX, y: offsetY });
wrapper.setPointerCapture(event.pointerId);
};
const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {
if (!dragging) return;
const container = document.getElementById("work-space-three-d-canvas");
const wrapper = wrapperRef.current;
if (!container || !wrapper) return;
const containerRect = container.getBoundingClientRect();
const wrapperRect = wrapper.getBoundingClientRect();
let newX = event.clientX - containerRect.left - dragOffset.x;
let newY = event.clientY - containerRect.top - dragOffset.y;
const maxX = containerRect.width - wrapper.offsetWidth;
const maxY = containerRect.height - wrapper.offsetHeight;
newX = clamp(newX, 0, maxX);
newY = clamp(newY, 0, maxY);
setPosition({ x: newX, y: newY });
};
const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
if (!dragging) return;
setDragging(false);
const wrapper = wrapperRef.current;
if (wrapper) wrapper.releasePointerCapture(event.pointerId);
};
return ( return (
<div className="thread-chat-wrapper"> <div
ref={wrapperRef}
className="thread-chat-wrapper"
onPointerDown={handlePointerDown}
onPointerMove={handlePointerMove}
onPointerUp={handlePointerUp}
style={{
position: "absolute",
left: position.x,
top: position.y,
cursor: dragging ? "grabbing" : "grab",
userSelect: "none",
zIndex: 9999,
}}
>
<div className="thread-chat-container"> <div className="thread-chat-container">
<div className="header-wrapper"> <div className="header-wrapper">
<div className="header">Comment</div> <div className="header">Comment</div>
<div className="header-options"> <div className="header-options">
<button <button
className="options-button" className="options-button"
onClick={() => { onClick={() => setOpenThreadOptions(!openThreadOptions)}
setOpenThreadOptions(!openThreadOptions);
}}
> >
<KebabIcon /> <KebabIcon />
</button> </button>
@ -60,11 +124,13 @@ const ThreadChat: React.FC = () => {
</button> </button>
</div> </div>
</div> </div>
<div className="messages-wrapper"> <div className="messages-wrapper">
{messages.map((val, i) => ( {messages.map((val, i) => (
<Messages val={val as Reply} i={i} key={val.replyId} /> <Messages val={val as any} i={i} key={val.replyId} />
))} ))}
</div> </div>
<div className="send-message-wrapper"> <div className="send-message-wrapper">
<div className={`input-container ${inputActive ? "active" : ""}`}> <div className={`input-container ${inputActive ? "active" : ""}`}>
<textarea <textarea
@ -76,11 +142,7 @@ const ThreadChat: React.FC = () => {
onBlur={() => setInputActive(false)} onBlur={() => setInputActive(false)}
style={{ resize: "none" }} style={{ resize: "none" }}
/> />
<div <div className={`sent-button ${value === "" ? "disable-send-btn" : ""}`}>
className={`sent-button ${
value === "" ? "disable-send-btn" : ""
}`}
>
<ExpandIcon /> <ExpandIcon />
</div> </div>
</div> </div>

View File

@ -98,7 +98,7 @@
// remove later // remove later
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); // transform: translate(-50%, -50%);
// ---- // ----
z-index: #{$z-index-ui-highest}; z-index: #{$z-index-ui-highest};
.thread-chat-container { .thread-chat-container {