From 5635885d52a9317339ed04f53cf8f608529edeff Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Thu, 21 Aug 2025 13:30:43 -0400 Subject: [PATCH] add page for boris --- app/lish/sorry-boris/fixFeeds.ts | 35 +++++++++++++ app/lish/sorry-boris/fixFeedsButton.tsx | 31 +++++++++++ app/lish/sorry-boris/page.tsx | 69 +++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 app/lish/sorry-boris/fixFeeds.ts create mode 100644 app/lish/sorry-boris/fixFeedsButton.tsx create mode 100644 app/lish/sorry-boris/page.tsx diff --git a/app/lish/sorry-boris/fixFeeds.ts b/app/lish/sorry-boris/fixFeeds.ts new file mode 100644 index 00000000..abca7b02 --- /dev/null +++ b/app/lish/sorry-boris/fixFeeds.ts @@ -0,0 +1,35 @@ +"use server"; + +import { AppBskyActorDefs, Agent as BskyAgent } from "@atproto/api"; +import { getIdentityData } from "actions/getIdentityData"; +import { createOauthClient } from "src/atproto-oauth"; +const leafletFeedURI = + "at://did:plc:btxrwcaeyodrap5mnjw2fvmz/app.bsky.feed.generator/subscribedPublications"; + +export async function fixFeeds() { + const oauthClient = await createOauthClient(); + let identity = await getIdentityData(); + if (!identity || !identity.atp_did) { + throw new Error("Invalid identity data"); + } + + let credentialSession = await oauthClient.restore(identity.atp_did); + let bsky = new BskyAgent(credentialSession); + let prefs = await bsky.app.bsky.actor.getPreferences(); + let savedFeeds = prefs.data.preferences.find( + (pref) => pref.$type === "app.bsky.actor.defs#savedFeedsPrefV2", + ) as AppBskyActorDefs.SavedFeedsPrefV2; + + let pubFeeds = savedFeeds.items.filter( + (feed) => feed.value === leafletFeedURI, + ); + await bsky.removeSavedFeeds(pubFeeds.map((f) => f.id)); + + await bsky.addSavedFeeds([ + { + value: leafletFeedURI, + pinned: true, + type: "feed", + }, + ]); +} diff --git a/app/lish/sorry-boris/fixFeedsButton.tsx b/app/lish/sorry-boris/fixFeedsButton.tsx new file mode 100644 index 00000000..545d4425 --- /dev/null +++ b/app/lish/sorry-boris/fixFeedsButton.tsx @@ -0,0 +1,31 @@ +"use client"; + +import { useSmoker } from "components/Toast"; +import { fixFeeds } from "./fixFeeds"; +import { ButtonPrimary } from "components/Buttons"; +import { DotLoader } from "components/utils/DotLoader"; +import { useState } from "react"; + +export function FixFeedsButton() { + let smoker = useSmoker(); + let [loading, setLoading] = useState(false); + return ( + { + let rect = e.currentTarget?.getBoundingClientRect(); + setLoading(true); + await fixFeeds(); + setLoading(false); + smoker({ + position: { + x: rect.left + (rect.right - rect.left) / 2, + y: rect.top - 16, + }, + text: "Fixed your feeds!", + }); + }} + > + {loading ? : "Fix My Feeds"} + + ); +} diff --git a/app/lish/sorry-boris/page.tsx b/app/lish/sorry-boris/page.tsx new file mode 100644 index 00000000..6131343a --- /dev/null +++ b/app/lish/sorry-boris/page.tsx @@ -0,0 +1,69 @@ +import { getIdentityData } from "actions/getIdentityData"; +import { BlueskyLogin } from "app/login/LoginForm"; +import { codeToHtml } from "shiki"; +import { FixFeedsButton } from "./fixFeedsButton"; + +export default async function Page() { + let identity = await getIdentityData(); + if (!identity) { + return ( + + + + ); + } + let code = await codeToHtml(source, { + lang: "typescript", + theme: "catppuccin-latte", + }); + return ( + + +
+    
+  );
+}
+
+function Layout(props: { children: React.ReactNode }) {
+  return (
+    
+ {props.children} +
+ ); +} + +let source = ` + import { AppBskyActorDefs, Agent as BskyAgent } from "@atproto/api"; + import { getIdentityData } from "actions/getIdentityData"; + import { createOauthClient } from "src/atproto-oauth"; + const leafletFeedURI = + "at://did:plc:btxrwcaeyodrap5mnjw2fvmz/app.bsky.feed.generator/subscribedPublications"; + + export async function fixFeeds() { + const oauthClient = await createOauthClient(); + let identity = await getIdentityData(); + if (!identity || !identity.atp_did) { + throw new Error("Invalid identity data"); + } + + let credentialSession = await oauthClient.restore(identity.atp_did); + let bsky = new BskyAgent(credentialSession); + let prefs = await bsky.app.bsky.actor.getPreferences(); + let savedFeeds = prefs.data.preferences.find( + (pref) => pref.$type === "app.bsky.actor.defs#savedFeedsPrefV2", + ) as AppBskyActorDefs.SavedFeedsPrefV2; + + let pubFeeds = savedFeeds.items.filter( + (feed) => feed.value === leafletFeedURI, + ); + await bsky.removeSavedFeeds(pubFeeds.map((f) => f.id)); + + await bsky.addSavedFeeds([ + { + value: leafletFeedURI, + pinned: true, + type: "feed", + }, + ]); + } + `; -- 2.51.2