diff --git a/src/components/create.tsx b/src/components/create.tsx index 5886cb0..3a74529 100644 --- a/src/components/create.tsx +++ b/src/components/create.tsx @@ -1,7 +1,7 @@ import { Client } from "@atcute/client"; import { remove } from "@mary/exif-rm"; import { useNavigate, useParams } from "@solidjs/router"; -import { createSignal, onCleanup, Show } from "solid-js"; +import { createSignal, onCleanup, onMount, Show } from "solid-js"; import { Editor, editorView } from "../components/editor.jsx"; import { agent } from "../components/login.jsx"; import { setNotif } from "../layout.jsx"; @@ -128,6 +128,80 @@ export const RecordEditor = (props: { create: boolean; record?: any; refetch?: a } }; + const dragDiv = (box: HTMLDivElement) => { + let currentBox: HTMLDivElement | null = null; + let isDragging = false; + let offsetX: number; + let offsetY: number; + + const handleMouseDown = (e: MouseEvent) => { + if (!(e.target instanceof HTMLElement)) return; + + const closestDraggable = e.target.closest("[data-draggable]") as HTMLElement; + if (closestDraggable && closestDraggable !== box) return; + + if ( + ["INPUT", "SELECT", "BUTTON", "LABEL"].includes(e.target.tagName) || + e.target.closest("#editor") + ) + return; + + e.preventDefault(); + isDragging = true; + box.classList.add("cursor-grabbing"); + currentBox = box; + + const rect = box.getBoundingClientRect(); + + box.style.left = rect.left + "px"; + box.style.top = rect.top + "px"; + + box.classList.remove("-translate-x-1/2"); + + offsetX = e.clientX - rect.left; + offsetY = e.clientY - rect.top; + }; + + const handleMouseMove = (e: MouseEvent) => { + if (isDragging && box === currentBox) { + let newLeft = e.clientX - offsetX; + let newTop = e.clientY - offsetY; + + const boxWidth = box.offsetWidth; + const boxHeight = box.offsetHeight; + + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + + newLeft = Math.max(0, Math.min(newLeft, viewportWidth - boxWidth)); + newTop = Math.max(0, Math.min(newTop, viewportHeight - boxHeight)); + + box.style.left = newLeft + "px"; + box.style.top = newTop + "px"; + } + }; + + const handleMouseUp = () => { + if (isDragging && box === currentBox) { + isDragging = false; + box.classList.remove("cursor-grabbing"); + currentBox = null; + } + }; + + onMount(() => { + box.addEventListener("mousedown", handleMouseDown); + document.addEventListener("mousemove", handleMouseMove); + document.addEventListener("mouseup", handleMouseUp); + }); + + onCleanup(() => { + box.removeEventListener("mousedown", handleMouseDown); + document.removeEventListener("mousemove", handleMouseMove); + document.removeEventListener("mouseup", handleMouseUp); + }); + }; + const FileUpload = (props: { file: File }) => { const [uploading, setUploading] = createSignal(false); const [error, setError] = createSignal(""); @@ -175,7 +249,11 @@ export const RecordEditor = (props: { create: boolean; record?: any; refetch?: a }; return ( -