- {/* @ts-ignore */}
+ {/* @ts-expect-error css */}
{
const session = localStorage.getItem("sess");
if (service && session) {
- console.log("Auto-login service is:", service);
+ // /*mass comment*/ console.log("Auto-login service is:", service);
const apiAgent = new AtpAgent({ service });
try {
if (!apiAgent) {
- console.log("Agent is null or undefined");
+ // /*mass comment*/ console.log("Agent is null or undefined");
return;
}
let sess: AtpSessionData = JSON.parse(session);
- console.log("resuming session is:", sess);
+ // /*mass comment*/ console.log("resuming session is:", sess);
const { data } = await apiAgent.resumeSession(sess);
- console.log("!!!8!!! agent resume session");
+ // /*mass comment*/ console.log("!!!8!!! agent resume session");
setAgent(apiAgent);
setLoginStatus(true);
setLoading(false);
setAuthed(true);
} catch (e) {
- console.log("Failed to resume session" + e);
+ // /*mass comment*/ console.log("Failed to resume session" + e);
setLoginStatus(true);
localStorage.removeItem("sess");
localStorage.removeItem("service");
@@ -63,7 +63,7 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
setAuthed(false);
}
} catch (e) {
- console.log("Failed to auto-login:", e);
+ // /*mass comment*/ console.log("Failed to auto-login:", e);
} finally {
setLoading(false);
}
@@ -86,7 +86,7 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
},
});
await apiAgent.login({ identifier: user, password });
- console.log("!!!8!!! agent logged on");
+ // /*mass comment*/ console.log("!!!8!!! agent logged on");
localStorage.setItem("service", service);
// await AsyncStorage.setItem('user', user);
@@ -118,11 +118,11 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
localStorage.removeItem("sess");
}
await agent.logout();
- console.log("!!!8!!! agent logout");
+ // /*mass comment*/ console.log("!!!8!!! agent logout");
setLoginStatus(false);
setAuthed(undefined);
await agent.com.atproto.server.deleteSession();
- console.log("!!!8!!! agent deltesession");
+ // /*mass comment*/ console.log("!!!8!!! agent deltesession");
//setAgent(null);
setIncrement(increment + 1);
} catch (e) {
diff --git a/src/providers/UnifiedAuthProvider.tsx b/src/providers/UnifiedAuthProvider.tsx
index 094c335..58bd054 100644
--- a/src/providers/UnifiedAuthProvider.tsx
+++ b/src/providers/UnifiedAuthProvider.tsx
@@ -1,20 +1,21 @@
// src/providers/UnifiedAuthProvider.tsx
-import React, {
- createContext,
- useState,
- useEffect,
- useContext,
- useCallback,
-} from "react";
// Import both Agent and the (soon to be deprecated) AtpAgent
import { Agent, AtpAgent, type AtpSessionData } from "@atproto/api";
-import { oauthClient } from "../utils/oauthClient"; // Adjust path if needed
import {
type OAuthSession,
TokenInvalidError,
TokenRefreshError,
TokenRevokedError,
} from "@atproto/oauth-client-browser";
+import React, {
+ createContext,
+ use,
+ useCallback,
+ useEffect,
+ useState,
+} from "react";
+
+import { oauthClient } from "../utils/oauthClient"; // Adjust path if needed
// Define the unified status and authentication method
type AuthStatus = "loading" | "signedIn" | "signedOut";
@@ -52,7 +53,7 @@ export const UnifiedAuthProvider = ({
try {
const oauthResult = await oauthClient.init();
if (oauthResult) {
- console.log("OAuth session restored.");
+ // /*mass comment*/ console.log("OAuth session restored.");
const apiAgent = new Agent(oauthResult.session); // Standard Agent
setAgent(apiAgent);
setOauthSession(oauthResult.session);
@@ -70,13 +71,13 @@ export const UnifiedAuthProvider = ({
const sessionString = localStorage.getItem("sess");
if (service && sessionString) {
- console.log("Resuming password-based session using AtpAgent...");
+ // /*mass comment*/ console.log("Resuming password-based session using AtpAgent...");
// Use the original, working AtpAgent logic
const apiAgent = new AtpAgent({ service });
const session: AtpSessionData = JSON.parse(sessionString);
await apiAgent.resumeSession(session);
- console.log("Password-based session resumed successfully.");
+ // /*mass comment*/ console.log("Password-based session resumed successfully.");
setAgent(apiAgent); // This works because AtpAgent is a subclass of Agent
setAuthMethod("password");
setStatus("signedIn");
@@ -89,7 +90,7 @@ export const UnifiedAuthProvider = ({
}
// --- 3. If neither worked, user is signed out ---
- console.log("No active session found.");
+ // /*mass comment*/ console.log("No active session found.");
setStatus("signedOut");
setAgent(null);
setAuthMethod(null);
@@ -139,7 +140,7 @@ export const UnifiedAuthProvider = ({
setAgent(apiAgent); // Store the AtpAgent instance in our state
setAuthMethod("password");
setStatus("signedIn");
- console.log("Successfully logged in with password.");
+ // /*mass comment*/ console.log("Successfully logged in with password.");
} else {
throw new Error("Session data not persisted after login.");
}
@@ -168,13 +169,13 @@ export const UnifiedAuthProvider = ({
try {
if (authMethod === "oauth" && oauthSession) {
await oauthClient.revoke(oauthSession.sub);
- console.log("OAuth session revoked.");
+ // /*mass comment*/ console.log("OAuth session revoked.");
} else if (authMethod === "password") {
localStorage.removeItem("service");
localStorage.removeItem("sess");
// AtpAgent has its own logout methods
await (agent as AtpAgent).com.atproto.server.deleteSession();
- console.log("Password-based session deleted.");
+ // /*mass comment*/ console.log("Password-based session deleted.");
}
} catch (e) {
console.error("Logout failed:", e);
@@ -187,7 +188,7 @@ export const UnifiedAuthProvider = ({
}, [status, authMethod, agent, oauthSession]);
return (
-
{children}
-
+
);
};
-export const useAuth = () => useContext(AuthContext);
\ No newline at end of file
+export const useAuth = () => use(AuthContext);
\ No newline at end of file
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 225019a..a7cc504 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -78,12 +78,12 @@ export const Route = createFileRoute("/")({
await Promise.all(
page.feed.map(async (feedviewpost) => {
if (!feedviewpost.post) return;
- console.log("preloading: ", feedviewpost.post);
+ // /*mass comment*/ console.log("preloading: ", feedviewpost.post);
const opts = constructPostQuery(feedviewpost.post);
try {
await queryClient.ensureQueryData(opts);
} catch (e) {
- console.log(" failed:", e);
+ // /*mass comment*/ console.log(" failed:", e);
}
})
);
@@ -141,7 +141,7 @@ function Home() {
// set,
// });
- // console.log("alistoffeeds", prefs);
+ // // /*mass comment*/ console.log("alistoffeeds", prefs);
// setPrefs(prefs || {});
// } catch (err) {
// console.error("alistoffeeds Fetch error in preferences effect:", err);
@@ -189,7 +189,7 @@ function Home() {
? setPersistentSelectedFeed
: setUnauthedSelectedFeed;
- console.log("my selectedFeed is: ", selectedFeed);
+ // /*mass comment*/ console.log("my selectedFeed is: ", selectedFeed);
React.useEffect(() => {
const fallbackFeed =
"at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot";
@@ -231,7 +231,7 @@ function Home() {
// });
// const fetchstringcomplex = `${pdsurl.pdsUrl}/xrpc/app.bsky.feed.getFeedSkeleton?feed=${selectedFeed}`;
- // console.log("fetching feed authed: " + fetchstringcomplex);
+ // // /*mass comment*/ console.log("fetching feed authed: " + fetchstringcomplex);
// const feeddef = await cachedGetRecord({
// atUri: selectedFeed,
@@ -254,7 +254,7 @@ function Home() {
// if (!ignore) setFeed(data.feed || []);
// } else {
- // console.log("falling back");
+ // // /*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";
@@ -266,7 +266,7 @@ function Home() {
// //const feedservicedid = "did:web:discover.bsky.app" //feeddef.did;
// const fetchstringsimple = `https://discover.bsky.app/xrpc/app.bsky.feed.getFeedSkeleton?feed=${fallbackFeed}`;
- // console.log("fetching feed unauthed: " + fetchstringsimple);
+ // // /*mass comment*/ console.log("fetching feed unauthed: " + fetchstringsimple);
// const res = await fetch(fetchstringsimple);
// if (!res.ok) throw new Error("Failed to fetch feed");
@@ -313,7 +313,7 @@ function Home() {
useEffect(() => {
return () => {
if (!donerestored) return;
- console.log("FEEDSCROLLSHIT saving at uhhh: ", scrollRef.current);
+ // /*mass comment*/ console.log("FEEDSCROLLSHIT saving at uhhh: ", scrollRef.current);
//if (!selectedFeed) return;
setScrollPositions((prev) => ({
...prev,
diff --git a/src/routes/notifications.tsx b/src/routes/notifications.tsx
index e7cfb0c..f572cda 100644
--- a/src/routes/notifications.tsx
+++ b/src/routes/notifications.tsx
@@ -10,7 +10,7 @@ export const Route = createFileRoute("/notifications")({
});
function NotificationsComponent() {
- console.log("NotificationsComponent render");
+ // /*mass comment*/ console.log("NotificationsComponent render");
const { agent, authed, loading: authLoading } = useAuth();
const { get, set } = usePersistentStore();
const [did, setDid] = useState
(null);
@@ -28,7 +28,7 @@ function NotificationsComponent() {
}, [authed, agent, authLoading]);
async function handleSubmit() {
- console.log("handleSubmit called");
+ // /*mass comment*/ console.log("handleSubmit called");
setError(null);
setResponses([null, null, null]);
const value = inputRef.current?.value?.trim() || "";
diff --git a/src/routes/profile.$did/index.tsx b/src/routes/profile.$did/index.tsx
index 64949f1..a1ad164 100644
--- a/src/routes/profile.$did/index.tsx
+++ b/src/routes/profile.$did/index.tsx
@@ -1,19 +1,15 @@
+import { useQueryClient } from "@tanstack/react-query";
import { createFileRoute, Link } from "@tanstack/react-router";
import React from "react";
-import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer";
-import { useQueryClient } from "@tanstack/react-query";
+import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer";
+import { useAuth } from "~/providers/UnifiedAuthProvider";
+import { toggleFollow, useGetFollowState } from "~/utils/followState";
import {
+ useInfiniteQueryAuthorFeed,
useQueryIdentity,
useQueryProfile,
- useInfiniteQueryAuthorFeed,
- useQueryConstellation,
- type linksRecordsResponse,
} from "~/utils/useQuery";
-import { useAuth } from "~/providers/UnifiedAuthProvider";
-import { AtUri } from "@atproto/api";
-import { TID } from "@atproto/common-web";
-import { toggleFollow, useGetFollowState } from "~/utils/followState";
export const Route = createFileRoute("/profile/$did/")({
component: ProfileComponent,
@@ -114,9 +110,11 @@ function ProfileComponent() {
className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg"
onClick={(e) => {
e.preventDefault();
- window.history.length > 1
- ? window.history.back()
- : window.location.assign("/");
+ if (window.history.length > 1) {
+ window.history.back()
+ } else {
+ window.location.assign("/");
+ }
}}
aria-label="Go back"
>
diff --git a/src/routes/profile.$did/post.$rkey.tsx b/src/routes/profile.$did/post.$rkey.tsx
index 71ea30a..13c9d36 100644
--- a/src/routes/profile.$did/post.$rkey.tsx
+++ b/src/routes/profile.$did/post.$rkey.tsx
@@ -1,15 +1,14 @@
import { useQueryClient } from "@tanstack/react-query";
import { createFileRoute, Link } from "@tanstack/react-router";
import React, { useLayoutEffect } from "react";
-import ShrinkingBox from "~/components/shrinkpadding";
+
import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer";
//import { usePersistentStore } from '~/providers/PersistentStoreProvider';
import {
+ constructPostQuery,
+ useQueryConstellation,
useQueryIdentity,
useQueryPost,
- useQueryConstellation,
- constructPostQuery,
- useQueryArbitrary,
} from "~/utils/useQuery";
//const HANDLE_DID_CACHE_TIMEOUT = 60 * 60 * 1000; // 1 hour
@@ -297,9 +296,11 @@ function ProfilePostComponent({ did, rkey }: { did: string; rkey: string }) {
className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg"
onClick={(e) => {
e.preventDefault();
- window.history.length > 1
- ? window.history.back()
- : window.location.assign("/");
+ if (window.history.length > 1) {
+ window.history.back();
+ } else {
+ window.location.assign("/");
+ }
}}
aria-label="Go back"
>
diff --git a/src/utils/oauthClient.ts b/src/utils/oauthClient.ts
index 494e1ed..45ce2f8 100644
--- a/src/utils/oauthClient.ts
+++ b/src/utils/oauthClient.ts
@@ -7,7 +7,7 @@ const handleResolverPDS = 'https://bsky.social';
// This assumes your client-metadata.json is in the /public folder
// and will be served at the root of your domain.
-import clientMetadata from '../../public/client-metadata.json' assert { type: 'json' };
+import clientMetadata from '../../public/client-metadata.json' with { type: 'json' };
export const oauthClient = new BrowserOAuthClient({
// The type assertion is needed because the static import isn't strictly typed
diff --git a/src/utils/useHydrated.ts b/src/utils/useHydrated.ts
index 163a5b2..aff98f4 100644
--- a/src/utils/useHydrated.ts
+++ b/src/utils/useHydrated.ts
@@ -1,18 +1,17 @@
-import { useState, useEffect, useMemo } from "react";
import {
+ type $Typed,
+ AppBskyActorDefs,
AppBskyEmbedExternal,
AppBskyEmbedImages,
AppBskyEmbedRecord,
AppBskyEmbedRecordWithMedia,
AppBskyEmbedVideo,
- AppBskyActorDefs,
AppBskyFeedPost,
AtUri,
- type $Typed,
} from "@atproto/api";
-import * as ATPAPI from "@atproto/api"
+import { useEffect, useMemo,useState } from "react";
-import { useQueryPost, useQueryProfile, useQueryIdentity } from "./useQuery";
+import { useQueryIdentity,useQueryPost, useQueryProfile } from "./useQuery";
type QueryResultData any> = ReturnType extends
| { data: infer D }
diff --git a/src/utils/useQuery.ts b/src/utils/useQuery.ts
index c87071b..cdb17a7 100644
--- a/src/utils/useQuery.ts
+++ b/src/utils/useQuery.ts
@@ -1,12 +1,10 @@
+import * as ATPAPI from "@atproto/api";
import {
+ type QueryFunctionContext,
queryOptions,
- useQuery,
useInfiniteQuery,
- type QueryFunctionContext,
- type UseQueryResult,
- type InfiniteData
-} from "@tanstack/react-query";
-import * as ATPAPI from "@atproto/api";
+ useQuery,
+ type UseQueryResult} from "@tanstack/react-query";
export function constructIdentityQuery(didorhandle?: string) {
return queryOptions({
@@ -28,6 +26,8 @@ export function constructIdentityQuery(didorhandle?: string) {
return undefined;
}
},
+ staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes
+ gcTime: /*0//*/5 * 60 * 1000,
});
}
export function useQueryIdentity(didorhandle: string): UseQueryResult<
@@ -65,17 +65,34 @@ export function constructPostQuery(uri?: string) {
const res = await fetch(
`https://slingshot.microcosm.blue/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}`
);
- if (!res.ok) throw new Error("Failed to fetch post");
+ let data: any;
try {
- return (await res.json()) as {
+ data = await res.json();
+ } catch {
+ return undefined;
+ }
+ if (res.status === 400) return undefined;
+ if (data?.error === "InvalidRequest" && data.message?.includes("Could not find repo")) {
+ return undefined; // cache “not found”
+ }
+ try {
+ if (!res.ok) throw new Error("Failed to fetch post");
+ return (data) as {
uri: string;
cid: string;
- value: ATPAPI.AppBskyFeedPost.Record;
+ value: any;
};
} catch (_e) {
return undefined;
}
},
+ retry: (failureCount, error) => {
+ // dont retry 400 errors
+ if ((error as any)?.message?.includes("400")) return false;
+ return failureCount < 2;
+ },
+ staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes
+ gcTime: /*0//*/5 * 60 * 1000,
});
}
export function useQueryPost(uri: string): UseQueryResult<
@@ -111,17 +128,34 @@ export function constructProfileQuery(uri?: string) {
const res = await fetch(
`https://slingshot.microcosm.blue/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}`
);
- if (!res.ok) throw new Error("Failed to fetch post");
+ let data: any;
try {
- return (await res.json()) as {
+ data = await res.json();
+ } catch {
+ return undefined;
+ }
+ if (res.status === 400) return undefined;
+ if (data?.error === "InvalidRequest" && data.message?.includes("Could not find repo")) {
+ return undefined; // cache “not found”
+ }
+ try {
+ if (!res.ok) throw new Error("Failed to fetch post");
+ return (data) as {
uri: string;
cid: string;
- value: ATPAPI.AppBskyActorProfile.Record;
+ value: any;
};
} catch (_e) {
return undefined;
}
},
+ retry: (failureCount, error) => {
+ // dont retry 400 errors
+ if ((error as any)?.message?.includes("400")) return false;
+ return failureCount < 2;
+ },
+ staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes
+ gcTime: /*0//*/5 * 60 * 1000,
});
}
export function useQueryProfile(uri: string): UseQueryResult<
@@ -418,9 +452,19 @@ export function constructArbitraryQuery(uri?: string) {
const res = await fetch(
`https://slingshot.microcosm.blue/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}`
);
- if (!res.ok) throw new Error("Failed to fetch post");
+ let data: any;
try {
- return (await res.json()) as {
+ data = await res.json();
+ } catch {
+ return undefined;
+ }
+ if (res.status === 400) return undefined;
+ if (data?.error === "InvalidRequest" && data.message?.includes("Could not find repo")) {
+ return undefined; // cache “not found”
+ }
+ try {
+ if (!res.ok) throw new Error("Failed to fetch post");
+ return (data) as {
uri: string;
cid: string;
value: any;
@@ -429,6 +473,13 @@ export function constructArbitraryQuery(uri?: string) {
return undefined;
}
},
+ retry: (failureCount, error) => {
+ // dont retry 400 errors
+ if ((error as any)?.message?.includes("400")) return false;
+ return failureCount < 2;
+ },
+ staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes
+ gcTime: /*0//*/5 * 60 * 1000,
});
}
export function useQueryArbitrary(uri: string): UseQueryResult<
diff --git a/vite.config.ts b/vite.config.ts
index 4becafd..d191573 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,6 +1,10 @@
-import { defineConfig } from "vite";
-import viteReact from "@vitejs/plugin-react";
+import { resolve } from "node:path";
+
import tailwindcss from "@tailwindcss/vite";
+import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
+import viteReact from "@vitejs/plugin-react";
+import { defineConfig } from "vite";
+
import { generateMetadataPlugin } from "./oauthdev.mts";
const PROD_URL = "https://reddwarf.whey.party"
@@ -10,9 +14,6 @@ function shp(url: string): string {
return url.replace(/^https?:\/\//, '');
}
-import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
-import { resolve } from "node:path";
-
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
@@ -21,7 +22,11 @@ export default defineConfig({
dev: DEV_URL,
}),
TanStackRouterVite({ autoCodeSplitting: true }),
- viteReact(),
+ viteReact({
+ babel: {
+ plugins: ['babel-plugin-react-compiler'],
+ },
+ }),
tailwindcss(),
],
// test: {