import { createFileRoute } from "@tanstack/react-router"; import { useAtom } from "jotai"; import * as React from "react"; import { useLayoutEffect, useState } from "react"; import { Header } from "~/components/Header"; import { InfiniteCustomFeed } from "~/components/InfiniteCustomFeed"; import { useAuth } from "~/providers/UnifiedAuthProvider"; import { feedScrollPositionsAtom, isAtTopAtom, quickAuthAtom, selectedFeedUriAtom, } from "~/utils/atoms"; //import { usePersistentStore } from "~/providers/PersistentStoreProvider"; import { //constructArbitraryQuery, //constructIdentityQuery, //constructInfiniteFeedSkeletonQuery, //constructPostQuery, useQueryArbitrary, useQueryIdentity, useQueryPreferences, } from "~/utils/useQuery"; export const Route = createFileRoute("/")({ // loader: async ({ context }) => { // const { queryClient } = context; // const atomauth = store.get(authedAtom); // const atomagent = store.get(agentAtom); // let identitypds: string | undefined; // const initialselectedfeed = store.get(selectedFeedUriAtom); // if (atomagent && atomauth && atomagent?.did) { // const identityopts = constructIdentityQuery(atomagent.did); // const identityresultmaybe = // await queryClient.ensureQueryData(identityopts); // identitypds = identityresultmaybe?.pds; // } // const arbitraryopts = constructArbitraryQuery( // initialselectedfeed ?? // "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot" // ); // const feedGengetrecordquery = // await queryClient.ensureQueryData(arbitraryopts); // const feedServiceDid = (feedGengetrecordquery?.value as any)?.did; // //queryClient.ensureInfiniteQueryData() // const { queryKey, queryFn } = constructInfiniteFeedSkeletonQuery({ // feedUri: // initialselectedfeed ?? // "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot", // agent: atomagent ?? undefined, // isAuthed: atomauth ?? false, // pdsUrl: identitypds, // feedServiceDid: feedServiceDid, // }); // const res = await queryClient.ensureInfiniteQueryData({ // queryKey, // queryFn, // initialPageParam: undefined as never, // getNextPageParam: (lastPage: any) => lastPage.cursor as null | undefined, // staleTime: Infinity, // //refetchOnWindowFocus: false, // //enabled: true, // }); // await Promise.all( // res.pages.map(async (page) => { // await Promise.all( // page.feed.map(async (feedviewpost) => { // if (!feedviewpost.post) return; // // /*mass comment*/ console.log("preloading: ", feedviewpost.post); // const opts = constructPostQuery(feedviewpost.post); // try { // await queryClient.ensureQueryData(opts); // } catch (e) { // // /*mass comment*/ console.log(" failed:", e); // } // }) // ); // }) // ); // }, component: Home, pendingComponent: PendingHome, // PendingHome, staticData: { keepAlive: true }, }); function PendingHome() { return
loading... (prefetching your timeline)
; } //function Homer() { // return
//} export function Home({ hidden = false }: { hidden?: boolean }) { const { agent, status, authMethod, loginWithPassword, loginWithOAuth, logout, } = useAuth(); const authed = !!agent?.did; // i dont remember why this is even here // useEffect(() => { // if (agent?.did) { // store.set(authedAtom, true); // } else { // store.set(authedAtom, false); // } // }, [status, agent, authed]); // useEffect(() => { // if (agent) { // // eslint-disable-next-line @typescript-eslint/ban-ts-comment // // @ts-ignore is it just me or is the type really weird here it should be Agent not AtpAgent // store.set(agentAtom, agent); // } else { // store.set(agentAtom, null); // } // }, [status, agent, authed]); //const { get, set } = usePersistentStore(); // const [feed, setFeed] = React.useState([]); // const [loading, setLoading] = React.useState(true); // const [error, setError] = React.useState(null); // const [prefs, setPrefs] = React.useState({}); // React.useEffect(() => { // if (!loadering && authed && agent && agent.did) { // const run = async () => { // try { // if (!agent.did) return; // const prefs = await cachedGetPrefs({ // did: agent.did, // agent, // get, // set, // }); // // /*mass comment*/ console.log("alistoffeeds", prefs); // setPrefs(prefs || {}); // } catch (err) { // console.error("alistoffeeds Fetch error in preferences effect:", err); // } // }; // run(); // } // }, [loadering, authed, agent]); // const savedFeedsPref = React.useMemo(() => { // if (!prefs?.preferences) return null; // return prefs.preferences.find( // (p: any) => p?.$type === "app.bsky.actor.defs#savedFeedsPrefV2", // ); // }, [prefs]); // const savedFeeds = savedFeedsPref?.items || []; const [quickAuth, setQuickAuth] = useAtom(quickAuthAtom); const isAuthRestoring = quickAuth ? status === "loading" : false; const identityresultmaybe = useQueryIdentity(!isAuthRestoring ? agent?.did : undefined); const identity = identityresultmaybe?.data; const prefsresultmaybe = useQueryPreferences({ agent: !isAuthRestoring ? (agent ?? undefined) : undefined, pdsUrl: !isAuthRestoring ? (identity?.pds) : undefined, }); const prefs = prefsresultmaybe?.data; const savedFeeds = React.useMemo(() => { const savedFeedsPref = prefs?.preferences?.find( (p: any) => p?.$type === "app.bsky.actor.defs#savedFeedsPrefV2" ); return savedFeedsPref?.items || []; }, [prefs]); const [persistentSelectedFeed, setPersistentSelectedFeed] = useAtom(selectedFeedUriAtom); const [unauthedSelectedFeed, setUnauthedSelectedFeed] = useState(persistentSelectedFeed); const selectedFeed = agent?.did ? persistentSelectedFeed : unauthedSelectedFeed; const setSelectedFeed = agent?.did ? setPersistentSelectedFeed : setUnauthedSelectedFeed; // /*mass comment*/ console.log("my selectedFeed is: ", selectedFeed); React.useEffect(() => { const fallbackFeed = "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot"; if (authed) { if (selectedFeed) return; if (savedFeeds.length > 0) { setSelectedFeed((prev) => prev && savedFeeds.some((f: any) => f.value === prev) ? prev : savedFeeds[0].value ); } else { if (selectedFeed) return; setSelectedFeed(fallbackFeed); } } else { if (selectedFeed) return; setSelectedFeed(fallbackFeed); } }, [savedFeeds, authed, setSelectedFeed]); // React.useEffect(() => { // if (loadering || !selectedFeed) return; // let ignore = false; // const run = async () => { // setLoading(true); // setError(null); // try { // if (authed && agent) { // if (!agent.did) return; // const pdsurl = await cachedResolveIdentity({ // didOrHandle: agent.did, // get, // set, // }); // const fetchstringcomplex = `${pdsurl.pdsUrl}/xrpc/app.bsky.feed.getFeedSkeleton?feed=${selectedFeed}`; // // /*mass comment*/ console.log("fetching feed authed: " + fetchstringcomplex); // const feeddef = await cachedGetRecord({ // atUri: selectedFeed, // get, // set, // }); // const feedservicedid = feeddef.value.did; // const res = await agent.fetchHandler(fetchstringcomplex, { // method: "GET", // headers: { // "atproto-proxy": `${feedservicedid}#bsky_fg`, // "Content-Type": "application/json", // }, // }); // if (!res.ok) throw new Error("Failed to fetch feed"); // const data = await res.json(); // if (!ignore) setFeed(data.feed || []); // } else { // // /*mass comment*/ console.log("falling back"); // // always use fallback feed for not logged in // const fallbackFeed = // "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot"; // // const feeddef = await cachedGetRecord({ // // atUri: fallbackFeed, // // get, // // set, // // }); // //const feedservicedid = "did:web:discover.bsky.app" //feeddef.did; // const fetchstringsimple = `https://discover.bsky.app/xrpc/app.bsky.feed.getFeedSkeleton?feed=${fallbackFeed}`; // // /*mass comment*/ console.log("fetching feed unauthed: " + fetchstringsimple); // const res = await fetch(fetchstringsimple); // if (!res.ok) throw new Error("Failed to fetch feed"); // const data = await res.json(); // if (!ignore) setFeed(data.feed || []); // } // } catch (e) { // if (!ignore) { // if (e instanceof Error) { // setError(e.message); // } else { // setError("Unknown error"); // } // } // } finally { // if (!ignore) setLoading(false); // } // }; // run(); // return () => { // ignore = true; // }; // }, [authed, agent, loadering, selectedFeed, get, set]); const [scrollPositions, setScrollPositions] = useAtom( feedScrollPositionsAtom ); const scrollPositionsRef = React.useRef(scrollPositions); React.useEffect(() => { scrollPositionsRef.current = scrollPositions; }, [scrollPositions]); useLayoutEffect(() => { if (isAuthRestoring) return; const savedPosition = scrollPositions[selectedFeed ?? "null"] ?? 0; window.scrollTo({ top: savedPosition, behavior: "instant" }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedFeed, isAuthRestoring]); useLayoutEffect(() => { if (!selectedFeed || isAuthRestoring) return; const handleScroll = () => { scrollPositionsRef.current = { ...scrollPositionsRef.current, [selectedFeed]: window.scrollY, }; }; window.addEventListener("scroll", handleScroll, { passive: true }); return () => { window.removeEventListener("scroll", handleScroll); setScrollPositions(scrollPositionsRef.current); }; }, [isAuthRestoring, selectedFeed, setScrollPositions]); const feedGengetrecordquery = useQueryArbitrary(!isAuthRestoring ? selectedFeed ?? undefined : undefined); const feedServiceDid = !isAuthRestoring ? (feedGengetrecordquery?.data?.value as any)?.did as string | undefined : undefined; // const { // data: feedData, // isLoading: isFeedLoading, // error: feedError, // } = useQueryFeedSkeleton({ // feedUri: selectedFeed!, // agent: agent ?? undefined, // isAuthed: authed ?? false, // pdsUrl: identity?.pds, // feedServiceDid: feedServiceDid, // }); // const feed = feedData?.feed || []; const isReadyForAuthedFeed = !isAuthRestoring && authed && agent && identity?.pds && feedServiceDid; const isReadyForUnauthedFeed = !isAuthRestoring && !authed && selectedFeed; const [isAtTop] = useAtom(isAtTopAtom); return (
{!isAuthRestoring && savedFeeds.length > 0 ? (
{savedFeeds.map((item: any, idx: number) => {return })}
) : ( // Home
)} {/* {isFeedLoading &&
Loading...
} {feedError &&
{feedError.message}
} {!isFeedLoading && !feedError && feed.length === 0 && (
No posts found.
)} */} {/* {feed.map((item, i) => ( ))} */} {isAuthRestoring || authed && (!identity?.pds || !feedServiceDid) && (
Preparing your feed...
)} {!isAuthRestoring && (isReadyForAuthedFeed || isReadyForUnauthedFeed) ? ( ) : (
Loading.......
)} {/* {false && restoringScrollPosition && (
restoringScrollPosition
)} */}
); } // todo please use types this is dangerous very dangerous. // todo fix this whenever proper preferences is handled function FeedTabOnTop({item, idx}:{item: any, idx: number}) { const [persistentSelectedFeed, setPersistentSelectedFeed] = useAtom(selectedFeedUriAtom); const selectedFeed = persistentSelectedFeed const setSelectedFeed = setPersistentSelectedFeed const rkey = item.value.split("/").pop() || item.value; const isActive = selectedFeed === item.value; const { data: feedrecord } = useQueryArbitrary(item.value) const label = feedrecord?.value?.displayName || rkey return ( ); } // not even used lmaooo // export async function cachedResolveDIDWEBDOC({ // didweb, // cacheTimeout = CACHE_TIMEOUT, // get, // set, // }: { // didweb: string; // cacheTimeout?: number; // get: (key: string) => any; // set: (key: string, value: string) => void; // }): Promise { // const isDidInput = didweb.startsWith("did:web:"); // const cacheKey = `didwebdoc:${didweb}`; // const now = Date.now(); // const cached = get(cacheKey); // if ( // cached && // cached.value && // cached.time && // now - cached.time < cacheTimeout // ) { // try { // return JSON.parse(cached.value); // } catch (_e) {/* whatever*/ } // } // const url = `https://free-fly-24.deno.dev/resolve-did-web?did=${encodeURIComponent( // didweb // )}`; // const res = await fetch(url); // if (!res.ok) throw new Error("Failed to resolve didwebdoc"); // const data = await res.json(); // set(cacheKey, JSON.stringify(data)); // if (!isDidInput && data.did) { // set(`didwebdoc:${data.did}`, JSON.stringify(data)); // } // return data; // } // export async function cachedGetPrefs({ // did, // agent, // get, // set, // cacheTimeout = CACHE_TIMEOUT, // }: { // did: string; // agent: any; // or type properly if available // get: (key: string) => any; // set: (key: string, value: string) => void; // cacheTimeout?: number; // }): Promise { // const cacheKey = `prefs:${did}`; // const cached = get(cacheKey); // const now = Date.now(); // if ( // cached && // cached.value && // cached.time && // now - cached.time < cacheTimeout // ) { // try { // return JSON.parse(cached.value); // } catch { // // fall through to fetch // } // } // const resolved = await cachedResolveIdentity({ // didOrHandle: did, // get, // set, // }); // if (!resolved?.pdsUrl) throw new Error("Missing resolved PDS info"); // const fetchUrl = `${resolved.pdsUrl}/xrpc/app.bsky.actor.getPreferences`; // const res = await agent.fetchHandler(fetchUrl, { // method: "GET", // headers: { // "Content-Type": "application/json", // }, // }); // if (!res.ok) throw new Error(`Failed to fetch preferences: ${res.status}`); // const text = await res.text(); // let data: any; // try { // data = JSON.parse(text); // } catch (err) { // console.error("Failed to parse preferences JSON:", err); // throw err; // } // set(cacheKey, JSON.stringify(data)); // return data; // }