atmosphere explorer pds.ls
tool typescript atproto
434
fork

Configure Feed

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

add datetime picker to jetstream cursor

Juliet 3cf38430 d13b0c7f

+72 -32
+2
src/views/stream/config.ts
··· 6 6 name: string; 7 7 label: string; 8 8 type: "text" | "checkbox" | "tags"; 9 + datetimePicker?: boolean; 9 10 placeholder?: string; 10 11 searchParam: string; 11 12 }; ··· 62 63 type: "text", 63 64 placeholder: "Leave empty for live-tail", 64 65 searchParam: "cursor", 66 + datetimePicker: true, 65 67 }, 66 68 { 67 69 name: "allEvents",
+70 -32
src/views/stream/index.tsx
··· 13 13 14 14 const LIMIT = 20; 15 15 16 + const microsToDatetimeLocal = (micros: string): string => { 17 + const ms = Math.floor(Number(micros) / 1000); 18 + if (isNaN(ms)) return ""; 19 + const d = new Date(ms); 20 + const pad = (n: number) => n.toString().padStart(2, "0"); 21 + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; 22 + }; 23 + 24 + const datetimeLocalToMicros = (dt: string): string => { 25 + if (!dt) return ""; 26 + return (new Date(dt).getTime() * 1000).toString(); 27 + }; 28 + 16 29 const TYPE_COLORS: Record<string, string> = { 17 30 create: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300", 18 31 update: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300", ··· 366 379 </label> 367 380 368 381 <For each={config().fields}> 369 - {(field) => ( 370 - <label class={`flex justify-end gap-x-1 ${field.type === "tags" ? "items-start" : "items-center"}`}> 371 - <Show when={field.type === "checkbox"}> 372 - <input 373 - type="checkbox" 374 - name={field.name} 375 - id={field.name} 376 - checked={searchParams[field.searchParam] === "on"} 377 - /> 378 - </Show> 379 - <span class={`min-w-21 select-none ${field.type === "tags" ? "mt-1" : ""}`}>{field.label}</span> 380 - <Show when={field.type === "tags"}> 381 - <TagInput 382 - name={field.name} 383 - placeholder={field.placeholder} 384 - initialValues={ 385 - (searchParams[field.searchParam] as string) 386 - ?.split(",") 387 - .filter((v) => v.trim().length > 0) ?? [] 388 - } 389 - /> 390 - </Show> 382 + {(field) => { 383 + let inputRef!: HTMLInputElement; 384 + return ( 385 + <label 386 + class={`flex justify-end gap-x-1 ${field.type === "tags" ? "items-start" : "items-center"}`} 387 + > 388 + <Show when={field.type === "checkbox"}> 389 + <input 390 + type="checkbox" 391 + name={field.name} 392 + id={field.name} 393 + checked={searchParams[field.searchParam] === "on"} 394 + /> 395 + </Show> 396 + <span class={`min-w-21 select-none ${field.type === "tags" ? "mt-1" : ""}`}> 397 + {field.label} 398 + </span> 399 + <Show when={field.type === "tags"}> 400 + <TagInput 401 + name={field.name} 402 + placeholder={field.placeholder} 403 + initialValues={ 404 + (searchParams[field.searchParam] as string) 405 + ?.split(",") 406 + .filter((v) => v.trim().length > 0) ?? [] 407 + } 408 + /> 409 + </Show> 391 410 392 - <Show when={field.type === "text"}> 393 - <TextInput 394 - name={field.name} 395 - placeholder={field.placeholder} 396 - value={(searchParams[field.searchParam] as string) ?? ""} 397 - class="grow" 398 - /> 399 - </Show> 400 - </label> 401 - )} 411 + <Show when={field.type === "text"}> 412 + <div class="flex grow flex-col gap-1 sm:flex-row sm:items-center"> 413 + <TextInput 414 + ref={inputRef} 415 + name={field.name} 416 + placeholder={field.placeholder} 417 + value={(searchParams[field.searchParam] as string) ?? ""} 418 + class="grow" 419 + /> 420 + <Show when={field.datetimePicker}> 421 + <input 422 + type="datetime-local" 423 + step="1" 424 + value={microsToDatetimeLocal( 425 + (searchParams[field.searchParam] as string) ?? 426 + (Date.now() * 1000).toString(), 427 + )} 428 + class="dark:bg-dark-100 rounded-md bg-white px-2 py-1 text-sm outline-1 outline-neutral-200 select-none focus:outline-neutral-400 dark:scheme-dark dark:outline-neutral-600 dark:focus:outline-neutral-400" 429 + onInput={(e) => { 430 + const micros = datetimeLocalToMicros(e.currentTarget.value); 431 + inputRef.value = micros; 432 + }} 433 + /> 434 + </Show> 435 + </div> 436 + </Show> 437 + </label> 438 + ); 439 + }} 402 440 </For> 403 441 404 442 <div class="flex justify-end gap-2">