an appview-less Bluesky client using Constellation and PDS Queries reddwarf.app
frontend spa bluesky reddwarf microcosm

for real this time

rimar1337 fe5744ad 2f2f25fa

Changed files
+38 -24
src
components
routes
utils
+4 -1
src/components/UniversalPostRenderer.tsx
··· 5 5 import * as React from "react"; 6 6 import { type SVGProps } from "react"; 7 7 8 - import { composerAtom, likedPostsAtom } from "~/utils/atoms"; 8 + import { composerAtom, constellationURLAtom, likedPostsAtom } from "~/utils/atoms"; 9 9 import { useHydratedEmbed } from "~/utils/useHydrated"; 10 10 import { 11 11 useQueryConstellation, ··· 401 401 // path: ".reply.parent.uri", 402 402 // }); 403 403 404 + const [constellationurl] = useAtom(constellationURLAtom) 405 + 404 406 const infinitequeryresults = useInfiniteQuery({ 405 407 ...yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks( 406 408 { 409 + constellation: constellationurl, 407 410 method: "/links", 408 411 target: atUri, 409 412 collection: "app.bsky.feed.post",
+9 -1
src/routes/profile.$did/post.$rkey.tsx
··· 1 1 import { AtUri } from "@atproto/api"; 2 2 import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query"; 3 3 import { createFileRoute, Outlet } from "@tanstack/react-router"; 4 + import { useAtom } from "jotai"; 4 5 import React, { useLayoutEffect } from "react"; 5 6 6 7 import { Header } from "~/components/Header"; 7 8 import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer"; 9 + import { constellationURLAtom, slingshotURLAtom } from "~/utils/atoms"; 8 10 //import { usePersistentStore } from '~/providers/PersistentStoreProvider'; 9 11 import { 10 12 constructPostQuery, ··· 275 277 // path: ".reply.parent.uri", 276 278 // }); 277 279 // const replies = repliesData?.linking_records.slice(0, 50) ?? []; 280 + const [constellationurl] = useAtom(constellationURLAtom) 281 + 278 282 const infinitequeryresults = useInfiniteQuery({ 279 283 ...yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks( 280 284 { 285 + constellation: constellationurl, 281 286 method: "/links", 282 287 target: atUri, 283 288 collection: "app.bsky.feed.post", ··· 386 391 } 387 392 }, [parents, layoutReady]); 388 393 394 + 395 + const [slingshoturl] = useAtom(slingshotURLAtom) 396 + 389 397 React.useEffect(() => { 390 398 if (parentsLoading) { 391 399 setLayoutReady(false); ··· 414 422 while (currentParentUri && safetyCounter < MAX_PARENTS) { 415 423 try { 416 424 const parentPost = await queryClient.fetchQuery( 417 - constructPostQuery(currentParentUri) 425 + constructPostQuery(currentParentUri, slingshoturl) 418 426 ); 419 427 if (!parentPost) break; 420 428 parentChain.push(parentPost);
+5 -4
src/routes/settings.tsx
··· 30 30 <Login /> 31 31 <TextInputSetting 32 32 atom={constellationURLAtom} 33 - title={"Constellation URL"} 33 + title={"Constellation"} 34 34 description={ 35 - "customize the Constellation instance to be used by Red Dwarf" 35 + "Customize the Constellation instance to be used by Red Dwarf" 36 36 } 37 37 init={defaultconstellationURL} 38 38 /> 39 39 <TextInputSetting 40 40 atom={slingshotURLAtom} 41 - title={"Slingshot URL"} 42 - description={"customize the Slingshot instance to be used by Red Dwarf"} 41 + title={"Slingshot"} 42 + description={"Customize the Slingshot instance to be used by Red Dwarf"} 43 43 init={defaultslingshotURL} 44 44 /> 45 + <span className="text-gray-500 dark:text-gray-400 py-4 px-6">please restart/refresh the app if changes arent applying correctly</span> 45 46 </> 46 47 ); 47 48 }
+20 -18
src/utils/useQuery.ts
··· 6 6 useInfiniteQuery, 7 7 useQuery, 8 8 type UseQueryResult} from "@tanstack/react-query"; 9 + import { useAtom } from "jotai"; 9 10 10 - import { constellationURLAtom, slingshotURLAtom, store } from "./atoms"; 11 + import { constellationURLAtom, slingshotURLAtom } from "./atoms"; 11 12 12 - export function constructIdentityQuery(didorhandle?: string) { 13 + export function constructIdentityQuery(didorhandle?: string, slingshoturl?: string) { 13 14 return queryOptions({ 14 15 queryKey: ["identity", didorhandle], 15 16 queryFn: async () => { 16 17 if (!didorhandle) return undefined as undefined 17 - const slingshoturl = store.get(slingshotURLAtom) 18 18 const res = await fetch( 19 19 `https://${slingshoturl}/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=${encodeURIComponent(didorhandle)}` 20 20 ); ··· 58 58 Error 59 59 > 60 60 export function useQueryIdentity(didorhandle?: string) { 61 - return useQuery(constructIdentityQuery(didorhandle)); 61 + const [slingshoturl] = useAtom(slingshotURLAtom) 62 + return useQuery(constructIdentityQuery(didorhandle, slingshoturl)); 62 63 } 63 64 64 - export function constructPostQuery(uri?: string) { 65 + export function constructPostQuery(uri?: string, slingshoturl?: string) { 65 66 return queryOptions({ 66 67 queryKey: ["post", uri], 67 68 queryFn: async () => { 68 69 if (!uri) return undefined as undefined 69 - const slingshoturl = store.get(slingshotURLAtom) 70 70 const res = await fetch( 71 71 `https://${slingshoturl}/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 72 72 ); ··· 122 122 Error 123 123 > 124 124 export function useQueryPost(uri?: string) { 125 - return useQuery(constructPostQuery(uri)); 125 + const [slingshoturl] = useAtom(slingshotURLAtom) 126 + return useQuery(constructPostQuery(uri, slingshoturl)); 126 127 } 127 128 128 - export function constructProfileQuery(uri?: string) { 129 + export function constructProfileQuery(uri?: string, slingshoturl?: string) { 129 130 return queryOptions({ 130 131 queryKey: ["profile", uri], 131 132 queryFn: async () => { 132 133 if (!uri) return undefined as undefined 133 - const slingshoturl = store.get(slingshotURLAtom) 134 134 const res = await fetch( 135 135 `https://${slingshoturl}/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 136 136 ); ··· 186 186 Error 187 187 > 188 188 export function useQueryProfile(uri?: string) { 189 - return useQuery(constructProfileQuery(uri)); 189 + const [slingshoturl] = useAtom(slingshotURLAtom) 190 + return useQuery(constructProfileQuery(uri, slingshoturl)); 190 191 } 191 192 192 193 // export function constructConstellationQuery( ··· 222 223 // target: string 223 224 // ): QueryOptions<linksAllResponse, Error>; 224 225 export function constructConstellationQuery(query?:{ 226 + constellation: string, 225 227 method: 226 228 | "/links" 227 229 | "/links/distinct-dids" ··· 254 256 const path = query?.path 255 257 const cursor = query.cursor 256 258 const dids = query?.dids 257 - const constellation = store.get(constellationURLAtom); 258 259 const res = await fetch( 259 - `https://${constellation}${method}?target=${encodeURIComponent(target)}${collection ? `&collection=${encodeURIComponent(collection)}` : ""}${path ? `&path=${encodeURIComponent(path)}` : ""}${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}${dids ? dids.map((did) => `&did=${encodeURIComponent(did)}`).join("") : ""}` 260 + `https://${query.constellation}${method}?target=${encodeURIComponent(target)}${collection ? `&collection=${encodeURIComponent(collection)}` : ""}${path ? `&path=${encodeURIComponent(path)}` : ""}${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}${dids ? dids.map((did) => `&did=${encodeURIComponent(did)}`).join("") : ""}` 260 261 ); 261 262 if (!res.ok) throw new Error("Failed to fetch post"); 262 263 try { ··· 345 346 > 346 347 | undefined { 347 348 //if (!query) return; 349 + const [constellationurl] = useAtom(constellationURLAtom) 348 350 return useQuery( 349 - constructConstellationQuery(query) 351 + constructConstellationQuery(query && {constellation: constellationurl, ...query}) 350 352 ); 351 353 } 352 354 ··· 451 453 452 454 453 455 454 - export function constructArbitraryQuery(uri?: string) { 456 + export function constructArbitraryQuery(uri?: string, slingshoturl?: string) { 455 457 return queryOptions({ 456 458 queryKey: ["arbitrary", uri], 457 459 queryFn: async () => { 458 460 if (!uri) return undefined as undefined 459 - const slingshoturl = store.get(slingshotURLAtom) 460 461 const res = await fetch( 461 462 `https://${slingshoturl}/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 462 463 ); ··· 511 512 Error 512 513 >; 513 514 export function useQueryArbitrary(uri?: string) { 514 - return useQuery(constructArbitraryQuery(uri)); 515 + const [slingshoturl] = useAtom(slingshotURLAtom) 516 + return useQuery(constructArbitraryQuery(uri, slingshoturl)); 515 517 } 516 518 517 519 export function constructFallbackNothingQuery(){ ··· 626 628 627 629 628 630 export function yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks(query?: { 631 + constellation: string, 629 632 method: '/links' 630 633 target?: string 631 634 collection: string 632 635 path: string 633 636 }) { 634 - const constellationHost = store.get(constellationURLAtom) 635 637 console.log( 636 638 'yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks', 637 639 query, ··· 657 659 const cursor = pageParam 658 660 659 661 const res = await fetch( 660 - `https://${constellationHost}${method}?target=${encodeURIComponent(target)}${ 662 + `https://${query.constellation}${method}?target=${encodeURIComponent(target)}${ 661 663 collection ? `&collection=${encodeURIComponent(collection)}` : '' 662 664 }${path ? `&path=${encodeURIComponent(path)}` : ''}${ 663 665 cursor ? `&cursor=${encodeURIComponent(cursor)}` : ''