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

reposted by indicators

rimar1337 78b79fd1 bd1ce421

Changed files
+58 -15
src
+33 -9
src/components/InfiniteCustomFeed.tsx
··· 2 2 //import { useInView } from "react-intersection-observer"; 3 3 import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer"; 4 4 import { useAuth } from "~/providers/PassAuthProvider"; 5 - import { useQueryArbitrary, useQueryIdentity, useInfiniteQueryFeedSkeleton } from "~/utils/useQuery"; 5 + import { 6 + useQueryArbitrary, 7 + useQueryIdentity, 8 + useInfiniteQueryFeedSkeleton, 9 + } from "~/utils/useQuery"; 6 10 7 11 interface InfiniteCustomFeedProps { 8 12 feedUri: string; ··· 10 14 feedServiceDid?: string; 11 15 } 12 16 13 - export function InfiniteCustomFeed({ feedUri, pdsUrl, feedServiceDid }: InfiniteCustomFeedProps) { 17 + export function InfiniteCustomFeed({ 18 + feedUri, 19 + pdsUrl, 20 + feedServiceDid, 21 + }: InfiniteCustomFeedProps) { 14 22 const { agent, authed } = useAuth(); 15 - 23 + 16 24 // const identityresultmaybe = useQueryIdentity(agent?.did); 17 25 // const identity = identityresultmaybe?.data; 18 26 // const feedGenGetRecordQuery = useQueryArbitrary(feedUri); ··· 46 54 } 47 55 48 56 if (isError) { 49 - return <div className="p-4 text-center text-red-500">Error: {error.message}</div>; 57 + return ( 58 + <div className="p-4 text-center text-red-500">Error: {error.message}</div> 59 + ); 50 60 } 51 61 52 - const allPosts = data?.pages.flatMap((page) => {if (page) return page.feed}) ?? []; 62 + const allPosts = 63 + data?.pages.flatMap((page) => { 64 + if (page) return page.feed; 65 + }) ?? []; 53 66 54 67 if (!allPosts || typeof allPosts !== "object" || allPosts.length === 0) { 55 - return <div className="p-4 text-center text-gray-500">No posts in this feed.</div>; 68 + return ( 69 + <div className="p-4 text-center text-gray-500"> 70 + No posts in this feed. 71 + </div> 72 + ); 56 73 } 57 74 58 75 return ( 59 76 <> 60 77 {allPosts.map((item, i) => { 61 - if (item) return ( 62 - <UniversalPostRendererATURILoader key={item.post || i} atUri={item.post} /> 63 - )})} 78 + if (item) 79 + return ( 80 + <UniversalPostRendererATURILoader 81 + key={item.post || i} 82 + atUri={item.post} 83 + feedviewpost={true} 84 + repostedby={!!item.reason?.$type && (item.reason as any)?.repost} 85 + /> 86 + ); 87 + })} 64 88 {/* allPosts?: {allPosts ? "true" : "false"} 65 89 hasNextPage?: {hasNextPage ? "true" : "false"} 66 90 isFetchingNextPage?: {isFetchingNextPage ? "true" : "false"} */}
+25 -6
src/components/UniversalPostRenderer.tsx
··· 25 25 topReplyLine?: boolean; 26 26 bottomBorder?: boolean; 27 27 feedviewpost?: boolean; 28 + repostedby?: string; 28 29 } 29 30 30 31 // export async function cachedGetRecord({ ··· 128 129 topReplyLine, 129 130 bottomBorder = true, 130 131 feedviewpost = false, 132 + repostedby, 131 133 }: UniversalPostRendererATURILoaderProps) { 132 134 console.log("atUri", atUri); 133 135 //const { get, set } = usePersistentStore(); ··· 381 383 // }); 382 384 // } 383 385 // }; 386 + if (!postQuery?.value) { 387 + // deleted post more often than a non-resolvable post 388 + return (<></>) 389 + } 384 390 385 391 return ( 386 392 <UniversalPostRendererRawRecordShim ··· 396 402 topReplyLine={topReplyLine} 397 403 bottomBorder={bottomBorder} 398 404 feedviewpost={feedviewpost} 405 + repostedby={repostedby} 399 406 /> 400 407 ); 401 408 } ··· 413 420 topReplyLine = false, 414 421 bottomBorder = true, 415 422 feedviewpost = false, 423 + repostedby, 416 424 }: { 417 425 postRecord: any; 418 426 profileRecord: any; ··· 426 434 topReplyLine?: boolean; 427 435 bottomBorder?: boolean; 428 436 feedviewpost?: boolean; 437 + repostedby?: string; 429 438 }) { 430 439 console.log(`received aturi: ${aturi} of post content: ${postRecord}`); 431 440 const navigate = useNavigate(); ··· 583 592 feedviewpost ? feedviewpostreplydid : undefined 584 593 ); 585 594 const feedviewpostreplyhandle = replyhookvalue?.data?.handle; 595 + 596 + 597 + const aturirepostbydid = repostedby ? new AtUri(repostedby).host : undefined 598 + const repostedbyhookvalue = useQueryIdentity( 599 + repostedby ? aturirepostbydid : undefined 600 + ); 601 + const feedviewpostrepostedbyhandle = repostedbyhookvalue?.data?.handle; 586 602 return ( 587 603 <> 588 604 {/* <p> ··· 616 632 bottomBorder={bottomBorder} 617 633 //extraOptionalItemInfo={{reply: postRecord?.value?.reply as AppBskyFeedDefs.ReplyRef, post: fakepost}} 618 634 feedviewpostreplyhandle={feedviewpostreplyhandle} 635 + repostedby={feedviewpostrepostedbyhandle} 619 636 /> 620 637 </> 621 638 ); ··· 1058 1075 bottomBorder = true, 1059 1076 feedviewpostreplyhandle, 1060 1077 depth = 0, 1078 + repostedby, 1061 1079 }: { 1062 1080 post: PostView; 1063 1081 // optional for now because i havent ported every use to this yet ··· 1076 1094 bottomBorder?: boolean; 1077 1095 feedviewpostreplyhandle?: string; 1078 1096 depth?: number; 1097 + repostedby?: string; 1079 1098 }) { 1080 1099 const navigate = useNavigate(); 1081 1100 const [hasRetweeted, setHasRetweeted] = useState<Boolean>( ··· 1124 1143 } 1125 1144 }; 1126 1145 1127 - const isRepost = extraOptionalItemInfo 1146 + const isRepost = repostedby ? repostedby : extraOptionalItemInfo 1128 1147 ? AppBskyFeedDefs.isReasonRepost(extraOptionalItemInfo.reason) 1129 1148 ? extraOptionalItemInfo.reason?.by.displayName 1130 1149 : undefined ··· 1190 1209 }} 1191 1210 className="text-gray-500 dark:text-gray-400" 1192 1211 > 1193 - <MdiRepost /> Reposted by {isRepost}{" "} 1212 + <MdiRepost /> Reposted by @{isRepost}{" "} 1194 1213 </div> 1195 1214 )} 1196 1215 {!isQuote && ( ··· 1292 1311 maxWidth: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`, 1293 1312 width: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`, 1294 1313 marginLeft: !expanded ? (isQuote ? 26 : 0) : 54, 1295 - marginBottom: !expanded ? 4 : 0, 1314 + marginBottom: !expanded ? 4 : 6, 1296 1315 }} 1297 1316 > 1298 1317 <div ··· 1308 1327 gap: expanded ? 0 : 6, 1309 1328 alignItems: expanded ? "flex-start" : "center", 1310 1329 flexDirection: expanded ? "column" : "row", 1311 - height: expanded ? 48 : "1rem", 1330 + height: expanded ? 42 : "1rem", 1312 1331 }} 1313 1332 > 1314 1333 <span ··· 1395 1414 }} 1396 1415 className="text-gray-500 dark:text-gray-400" 1397 1416 > 1398 - <MdiReply /> Reply to {feedviewpostreplyhandle} 1417 + <MdiReply /> Reply to @{feedviewpostreplyhandle} 1399 1418 </div> 1400 1419 )} 1401 1420 <div ··· 1428 1447 ) : null} 1429 1448 {post.embed && depth > 0 && ( 1430 1449 <> 1431 - <div className="border-gray-300 dark:border-gray-600 p-3 rounded-xl border italic text-gray-400"> 1450 + <div className="border-gray-300 dark:border-gray-600 p-3 rounded-xl border italic text-gray-400 text-[14px]"> 1432 1451 (there is an embed here thats too deep to render) 1433 1452 </div> 1434 1453 </>