atmosphere explorer
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

maximize/minimize create record window

Juliet 717a741f b5a1ac15

+60 -114
+56 -112
src/components/create.tsx
··· 3 3 import { getSession, OAuthUserAgent } from "@atcute/oauth-browser-client"; 4 4 import { remove } from "@mary/exif-rm"; 5 5 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"; 7 7 import { Editor, editorView } from "../components/editor.jsx"; 8 8 import { agent } from "../components/login.jsx"; 9 9 import { sessions } from "./account.jsx"; ··· 22 22 const [notice, setNotice] = createSignal(""); 23 23 const [openUpload, setOpenUpload] = createSignal(false); 24 24 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); 26 27 let blobInput!: HTMLInputElement; 27 28 let formRef!: HTMLFormElement; 28 29 ··· 62 63 createEffect(() => { 63 64 if (openDialog()) { 64 65 setValidate(undefined); 65 - setNonBlocking(false); 66 66 } 67 67 }); 68 68 ··· 158 158 } 159 159 }; 160 160 161 - const dragBox = (box: HTMLDivElement) => { 162 - let isDragging = false; 163 - let offsetX: number; 164 - let offsetY: number; 165 - 166 - const handleMouseDown = (e: MouseEvent) => { 167 - if (!(e.target instanceof HTMLElement)) return; 168 - 169 - const closestDraggable = e.target.closest("[data-draggable]") as HTMLElement; 170 - if (closestDraggable && closestDraggable !== box) return; 171 - 172 - if ( 173 - ["INPUT", "SELECT", "BUTTON", "LABEL"].includes(e.target.tagName) || 174 - e.target.closest("#editor, #close") 175 - ) 176 - return; 177 - 178 - e.preventDefault(); 179 - isDragging = true; 180 - box.classList.add("cursor-grabbing"); 181 - 182 - const rect = box.getBoundingClientRect(); 183 - 184 - box.style.left = rect.left + "px"; 185 - box.style.top = rect.top + "px"; 186 - 187 - box.classList.remove("-translate-x-1/2"); 188 - 189 - offsetX = e.clientX - rect.left; 190 - offsetY = e.clientY - rect.top; 191 - }; 192 - 193 - const handleMouseMove = (e: MouseEvent) => { 194 - if (isDragging) { 195 - let newLeft = e.clientX - offsetX; 196 - let newTop = e.clientY - offsetY; 197 - 198 - const boxWidth = box.offsetWidth; 199 - const boxHeight = box.offsetHeight; 200 - 201 - const viewportWidth = window.innerWidth; 202 - const viewportHeight = window.innerHeight; 203 - 204 - newLeft = Math.max(0, Math.min(newLeft, viewportWidth - boxWidth)); 205 - newTop = Math.max(0, Math.min(newTop, viewportHeight - boxHeight)); 206 - 207 - box.style.left = newLeft + "px"; 208 - box.style.top = newTop + "px"; 209 - } 210 - }; 211 - 212 - const handleMouseUp = () => { 213 - if (isDragging) { 214 - isDragging = false; 215 - box.classList.remove("cursor-grabbing"); 216 - } 217 - }; 218 - 219 - onMount(() => { 220 - box.addEventListener("mousedown", handleMouseDown); 221 - document.addEventListener("mousemove", handleMouseMove); 222 - document.addEventListener("mouseup", handleMouseUp); 223 - }); 224 - 225 - onCleanup(() => { 226 - box.removeEventListener("mousedown", handleMouseDown); 227 - document.removeEventListener("mousemove", handleMouseMove); 228 - document.removeEventListener("mouseup", handleMouseUp); 229 - }); 230 - }; 231 - 232 161 const FileUpload = (props: { file: File }) => { 233 162 const [uploading, setUploading] = createSignal(false); 234 163 const [error, setError] = createSignal(""); ··· 276 205 }; 277 206 278 207 return ( 279 - <div 280 - data-draggable 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" 282 - ref={dragBox} 283 - > 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"> 284 209 <h2 class="mb-2 font-semibold">Upload blob</h2> 285 210 <div class="flex flex-col gap-2 text-sm"> 286 211 <div class="flex flex-col gap-1"> ··· 337 262 open={openDialog()} 338 263 onClose={() => setOpenDialog(false)} 339 264 closeOnClick={false} 340 - nonBlocking={nonBlocking()} 265 + nonBlocking={isMinimized()} 341 266 > 342 267 <div 343 - data-draggable 344 268 classList={{ 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(), 347 273 }} 348 - ref={dragBox} 349 274 > 350 275 <div class="mb-2 flex w-full justify-between text-base"> 351 276 <div class="flex items-center gap-2"> 352 277 <span class="font-semibold select-none"> 353 278 {props.create ? "Creating" : "Editing"} record 354 279 </span> 355 - <Tooltip text={nonBlocking() ? "Lock" : "Unlock"}> 356 - <button 357 - type="button" 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" 360 - > 361 - <span 362 - class={`iconify ${nonBlocking() ? "lucide--lock-open" : "lucide--lock"}`} 363 - ></span> 364 - </button> 365 - </Tooltip> 366 280 </div> 367 - <button 368 - id="close" 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" 371 - > 372 - <span class="iconify lucide--x"></span> 373 - </button> 281 + <div class="flex items-center gap-1"> 282 + <button 283 + type="button" 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" 286 + > 287 + <span class="iconify lucide--minus"></span> 288 + </button> 289 + <button 290 + type="button" 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" 293 + > 294 + <span 295 + class={`iconify ${isMaximized() ? "lucide--minimize-2" : "lucide--maximize-2"}`} 296 + ></span> 297 + </button> 298 + <button 299 + id="close" 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" 302 + > 303 + <span class="iconify lucide--x"></span> 304 + </button> 305 + </div> 374 306 </div> 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"> 376 308 <Show when={props.create}> 377 309 <div class="flex flex-wrap items-center gap-1 text-sm"> 378 310 <span>at://</span> ··· 405 337 /> 406 338 </div> 407 339 </Show> 408 - <Editor 409 - content={JSON.stringify( 410 - !props.create ? props.record 411 - : params.rkey ? placeholder() 412 - : defaultPlaceholder(), 413 - null, 414 - 2, 415 - )} 416 - /> 340 + <div class="min-h-0 flex-1"> 341 + <Editor 342 + content={JSON.stringify( 343 + !props.create ? props.record 344 + : params.rkey ? placeholder() 345 + : defaultPlaceholder(), 346 + null, 347 + 2, 348 + )} 349 + /> 350 + </div> 417 351 <div class="flex flex-col gap-2"> 418 352 <Show when={notice()}> 419 353 <div class="text-sm text-red-500 dark:text-red-400">{notice()}</div> ··· 477 411 </form> 478 412 </div> 479 413 </Modal> 414 + <Show when={isMinimized() && openDialog()}> 415 + <button 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)} 418 + > 419 + <span class="iconify lucide--square-pen text-lg"></span> 420 + <span class="text-sm font-medium">{props.create ? "Creating" : "Editing"} record</span> 421 + </button> 422 + </Show> 480 423 <Tooltip text={`${props.create ? "Create" : "Edit"} record`}> 481 424 <button 482 425 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"}`} 483 426 onclick={() => { 484 427 setNotice(""); 485 428 setOpenDialog(true); 429 + setIsMinimized(false); 486 430 }} 487 431 > 488 432 <div
+4 -2
src/components/editor.tsx
··· 30 30 }, 31 31 ".cm-scroller": { 32 32 overflow: "auto", 33 - maxHeight: "20rem", 33 + }, 34 + "&": { 35 + height: "100%", 34 36 }, 35 37 }); 36 38 ··· 58 60 <div 59 61 ref={editorDiv} 60 62 id="editor" 61 - class="dark:shadow-dark-700 cursor-auto border-[0.5px] border-neutral-300 shadow-xs dark:border-neutral-700" 63 + class="dark:shadow-dark-700 h-full cursor-auto border-[0.5px] border-neutral-300 shadow-xs dark:border-neutral-700" 62 64 ></div> 63 65 ); 64 66 };