atmosphere explorer pds.ls
tool typescript atproto
434
fork

Configure Feed

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

creation insert menu

Juliet 06b4443c 3668ccde

+57 -9
+57 -9
src/components/create.tsx
··· 21 21 const [openDialog, setOpenDialog] = createSignal(false); 22 22 const [notice, setNotice] = createSignal(""); 23 23 const [openUpload, setOpenUpload] = createSignal(false); 24 + const [openInsertMenu, setOpenInsertMenu] = createSignal(false); 24 25 const [validate, setValidate] = createSignal<boolean | undefined>(undefined); 25 26 const [isMaximized, setIsMaximized] = createSignal(false); 26 27 const [isMinimized, setIsMinimized] = createSignal(false); 27 28 let blobInput!: HTMLInputElement; 28 29 let formRef!: HTMLFormElement; 30 + let insertMenuRef!: HTMLDivElement; 31 + 32 + createEffect(() => { 33 + if (openInsertMenu()) { 34 + const handleClickOutside = (e: MouseEvent) => { 35 + if (insertMenuRef && !insertMenuRef.contains(e.target as Node)) { 36 + setOpenInsertMenu(false); 37 + } 38 + }; 39 + document.addEventListener("mousedown", handleClickOutside); 40 + onCleanup(() => document.removeEventListener("mousedown", handleClickOutside)); 41 + } 42 + }); 29 43 30 44 const defaultPlaceholder = () => { 31 45 return { ··· 156 170 } catch (err: any) { 157 171 setNotice(err.message); 158 172 } 173 + }; 174 + 175 + const insertTimestamp = () => { 176 + const timestamp = new Date().toISOString(); 177 + editorView.dispatch({ 178 + changes: { 179 + from: editorView.state.selection.main.head, 180 + insert: `"${timestamp}"`, 181 + }, 182 + }); 183 + setOpenInsertMenu(false); 159 184 }; 160 185 161 186 const FileUpload = (props: { file: File }) => { ··· 353 378 <div class="text-sm text-red-500 dark:text-red-400">{notice()}</div> 354 379 </Show> 355 380 <div class="flex justify-between gap-2"> 356 - <button 357 - type="button" 358 - class="dark:hover:bg-dark-200 dark:shadow-dark-700 dark:active:bg-dark-100 flex w-fit rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 text-xs shadow-xs hover:bg-neutral-100 active:bg-neutral-200 dark:border-neutral-700 dark:bg-neutral-800" 359 - > 381 + <div class="relative" ref={insertMenuRef}> 382 + <button 383 + type="button" 384 + class="dark:hover:bg-dark-200 dark:shadow-dark-700 dark:active:bg-dark-100 flex w-fit rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 px-2 py-1.5 text-xs shadow-xs hover:bg-neutral-100 active:bg-neutral-200 dark:border-neutral-700 dark:bg-neutral-800" 385 + onClick={() => setOpenInsertMenu(!openInsertMenu())} 386 + > 387 + <span class="iconify lucide--plus select-none"></span> 388 + </button> 389 + <Show when={openInsertMenu()}> 390 + <div class="dark:bg-dark-300 dark:shadow-dark-700 absolute bottom-full left-0 mb-1 flex w-40 flex-col rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 shadow-md dark:border-neutral-700 z-10"> 391 + <button 392 + type="button" 393 + class="flex items-center gap-2 px-3 py-2 text-left text-xs hover:bg-neutral-100 active:bg-neutral-200 dark:hover:bg-neutral-700 dark:active:bg-neutral-600 rounded-t-lg" 394 + onClick={() => { 395 + setOpenInsertMenu(false); 396 + blobInput.click(); 397 + }} 398 + > 399 + <span class="iconify lucide--upload"></span> 400 + <span>Upload blob</span> 401 + </button> 402 + <button 403 + type="button" 404 + class="flex items-center gap-2 px-3 py-2 text-left text-xs hover:bg-neutral-100 active:bg-neutral-200 dark:hover:bg-neutral-700 dark:active:bg-neutral-600 rounded-b-lg" 405 + onClick={insertTimestamp} 406 + > 407 + <span class="iconify lucide--clock"></span> 408 + <span>Insert timestamp</span> 409 + </button> 410 + </div> 411 + </Show> 360 412 <input 361 413 type="file" 362 414 id="blob" ··· 366 418 if (e.target.files !== null) setOpenUpload(true); 367 419 }} 368 420 /> 369 - <label class="flex items-center gap-1 px-2 py-1.5 select-none" for="blob"> 370 - <span class="iconify lucide--upload"></span> 371 - Upload 372 - </label> 373 - </button> 421 + </div> 374 422 <Modal 375 423 open={openUpload()} 376 424 onClose={() => setOpenUpload(false)}