···
import { getSession, OAuthUserAgent } from "@atcute/oauth-browser-client";
import { remove } from "@mary/exif-rm";
import { useNavigate, useParams } from "@solidjs/router";
6
-
import { createEffect, createSignal, For, onCleanup, onMount, Show } from "solid-js";
6
+
import { createEffect, createSignal, For, onCleanup, Show } from "solid-js";
import { Editor, editorView } from "../components/editor.jsx";
import { agent } from "../components/login.jsx";
import { sessions } from "./account.jsx";
···
const [notice, setNotice] = createSignal("");
const [openUpload, setOpenUpload] = createSignal(false);
const [validate, setValidate] = createSignal<boolean | undefined>(undefined);
25
-
const [nonBlocking, setNonBlocking] = createSignal(false);
25
+
const [isMaximized, setIsMaximized] = createSignal(false);
26
+
const [isMinimized, setIsMinimized] = createSignal(false);
let blobInput!: HTMLInputElement;
let formRef!: HTMLFormElement;
···
65
-
setNonBlocking(false);
···
161
-
const dragBox = (box: HTMLDivElement) => {
162
-
let isDragging = false;
163
-
let offsetX: number;
164
-
let offsetY: number;
166
-
const handleMouseDown = (e: MouseEvent) => {
167
-
if (!(e.target instanceof HTMLElement)) return;
169
-
const closestDraggable = e.target.closest("[data-draggable]") as HTMLElement;
170
-
if (closestDraggable && closestDraggable !== box) return;
173
-
["INPUT", "SELECT", "BUTTON", "LABEL"].includes(e.target.tagName) ||
174
-
e.target.closest("#editor, #close")
178
-
e.preventDefault();
180
-
box.classList.add("cursor-grabbing");
182
-
const rect = box.getBoundingClientRect();
184
-
box.style.left = rect.left + "px";
185
-
box.style.top = rect.top + "px";
187
-
box.classList.remove("-translate-x-1/2");
189
-
offsetX = e.clientX - rect.left;
190
-
offsetY = e.clientY - rect.top;
193
-
const handleMouseMove = (e: MouseEvent) => {
195
-
let newLeft = e.clientX - offsetX;
196
-
let newTop = e.clientY - offsetY;
198
-
const boxWidth = box.offsetWidth;
199
-
const boxHeight = box.offsetHeight;
201
-
const viewportWidth = window.innerWidth;
202
-
const viewportHeight = window.innerHeight;
204
-
newLeft = Math.max(0, Math.min(newLeft, viewportWidth - boxWidth));
205
-
newTop = Math.max(0, Math.min(newTop, viewportHeight - boxHeight));
207
-
box.style.left = newLeft + "px";
208
-
box.style.top = newTop + "px";
212
-
const handleMouseUp = () => {
214
-
isDragging = false;
215
-
box.classList.remove("cursor-grabbing");
220
-
box.addEventListener("mousedown", handleMouseDown);
221
-
document.addEventListener("mousemove", handleMouseMove);
222
-
document.addEventListener("mouseup", handleMouseUp);
226
-
box.removeEventListener("mousedown", handleMouseDown);
227
-
document.removeEventListener("mousemove", handleMouseMove);
228
-
document.removeEventListener("mouseup", handleMouseUp);
const FileUpload = (props: { file: File }) => {
const [uploading, setUploading] = createSignal(false);
const [error, setError] = createSignal("");
···
281
-
class="dark:bg-dark-300 dark:shadow-dark-700 absolute top-70 left-[50%] w-[20rem] -translate-x-1/2 rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-4 shadow-md transition-opacity duration-200 dark:border-neutral-700 starting:opacity-0"
208
+
<div class="dark:bg-dark-300 dark:shadow-dark-700 absolute top-70 left-[50%] w-[20rem] -translate-x-1/2 rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-4 shadow-md transition-opacity duration-200 dark:border-neutral-700 starting:opacity-0">
<h2 class="mb-2 font-semibold">Upload blob</h2>
<div class="flex flex-col gap-2 text-sm">
<div class="flex flex-col gap-1">
···
onClose={() => setOpenDialog(false)}
340
-
nonBlocking={nonBlocking()}
265
+
nonBlocking={isMinimized()}
345
-
"dark:bg-dark-300 dark:shadow-dark-700 pointer-events-auto absolute top-18 left-[50%] max-w-3xl w-[calc(100%-1rem)] -translate-x-1/2 cursor-grab rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-4 shadow-md transition-opacity duration-200 dark:border-neutral-700 starting:opacity-0": true,
346
-
"opacity-60 hover:opacity-100": nonBlocking(),
269
+
"dark:bg-dark-300 dark:shadow-dark-700 pointer-events-auto absolute top-18 left-1/2 -translate-x-1/2 flex flex-col rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-4 shadow-md transition-all duration-200 dark:border-neutral-700 starting:opacity-0": true,
270
+
"w-[calc(100%-1rem)] max-w-3xl h-[60vh]": !isMaximized(),
271
+
"w-[calc(100%-1rem)] max-w-7xl h-[85vh]": isMaximized(),
272
+
hidden: isMinimized(),
<div class="mb-2 flex w-full justify-between text-base">
<div class="flex items-center gap-2">
<span class="font-semibold select-none">
{props.create ? "Creating" : "Editing"} record
355
-
<Tooltip text={nonBlocking() ? "Lock" : "Unlock"}>
358
-
onclick={() => setNonBlocking(!nonBlocking())}
359
-
class="flex items-center rounded-lg p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
362
-
class={`iconify ${nonBlocking() ? "lucide--lock-open" : "lucide--lock"}`}
369
-
onclick={() => setOpenDialog(false)}
370
-
class="flex items-center rounded-lg p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
372
-
<span class="iconify lucide--x"></span>
281
+
<div class="flex items-center gap-1">
284
+
onclick={() => setIsMinimized(true)}
285
+
class="flex items-center rounded-lg p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
287
+
<span class="iconify lucide--minus"></span>
291
+
onclick={() => setIsMaximized(!isMaximized())}
292
+
class="flex items-center rounded-lg p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
295
+
class={`iconify ${isMaximized() ? "lucide--minimize-2" : "lucide--maximize-2"}`}
300
+
onclick={() => setOpenDialog(false)}
301
+
class="flex items-center rounded-lg p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
303
+
<span class="iconify lucide--x"></span>
375
-
<form ref={formRef} class="flex flex-col gap-y-2">
307
+
<form ref={formRef} class="flex min-h-0 flex-1 flex-col gap-y-2 overflow-y-auto">
<Show when={props.create}>
<div class="flex flex-wrap items-center gap-1 text-sm">
···
409
-
content={JSON.stringify(
410
-
!props.create ? props.record
411
-
: params.rkey ? placeholder()
412
-
: defaultPlaceholder(),
340
+
<div class="min-h-0 flex-1">
342
+
content={JSON.stringify(
343
+
!props.create ? props.record
344
+
: params.rkey ? placeholder()
345
+
: defaultPlaceholder(),
<div class="flex flex-col gap-2">
<div class="text-sm text-red-500 dark:text-red-400">{notice()}</div>
···
414
+
<Show when={isMinimized() && openDialog()}>
416
+
class="dark:bg-dark-300 dark:hover:bg-dark-200 dark:active:bg-dark-100 fixed right-4 bottom-4 z-30 flex items-center gap-2 rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 px-3 py-2 shadow-md hover:bg-neutral-100 active:bg-neutral-200 dark:border-neutral-700"
417
+
onclick={() => setIsMinimized(false)}
419
+
<span class="iconify lucide--square-pen text-lg"></span>
420
+
<span class="text-sm font-medium">{props.create ? "Creating" : "Editing"} record</span>
<Tooltip text={`${props.create ? "Create" : "Edit"} record`}>
class={`flex items-center p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600 ${props.create ? "rounded-lg" : "rounded-sm"}`}
429
+
setIsMinimized(false);