view who was fronting when a record was made
at main 3.9 kB view raw
1import { decodeStorageKey } from "@/lib/cache"; 2import { expect } from "@/lib/result"; 3import { 4 displayNameCache, 5 Fronter, 6 fronterGetSocialAppHref, 7 fronterGetSocialAppHrefs, 8 frontersCache, 9 FronterView, 10 parseSocialAppPostUrl, 11} from "@/lib/utils"; 12import { parseResourceUri, ResourceUri } from "@atcute/lexicons"; 13 14export default defineContentScript({ 15 matches: ["<all_urls>"], 16 runAt: "document_start", 17 world: "ISOLATED", 18 main: (ctx) => { 19 const checkFronter = async (url: string) => { 20 // match https://*/profile/<actor_identifier>/post/<rkey> regex with named params to extract actor_identifier and rkey 21 const match = parseSocialAppPostUrl(url); 22 if (!match) return false; 23 const recordUri = 24 `at://${match.actorIdentifier}/app.bsky.feed.post/${match.rkey}` as ResourceUri; 25 const fronter = await frontersCache.get(recordUri); 26 if (!fronter) return false; 27 browser.runtime.sendMessage({ 28 type: "TAB_FRONTER", 29 recordUri, 30 fronter, 31 }); 32 return true; 33 }; 34 35 const respEventName = Math.random().toString(36).slice(2); 36 window.addEventListener(`${respEventName}-isolated`, async (event) => { 37 const data = (event as any).detail; 38 // console.log("passing response event to bg", event); 39 await browser.runtime.sendMessage({ 40 type: "RESPONSE_CAPTURED", 41 data, 42 }); 43 }); 44 const bgMessageTypes = ["APPLY_FRONTERS"]; 45 browser.runtime.onMessage.addListener((message) => { 46 if (!bgMessageTypes.includes(message.type)) return; 47 window.postMessage(message); 48 }); 49 const updateOnUrlChange = async () => { 50 const fronters = await frontersCache.getAll(); 51 const updated = new Map<string, FronterView | null>(); 52 for (const [storageKey, fronter] of fronters.entries()) { 53 const uri = decodeStorageKey(storageKey); 54 const parsedUri = expect(parseResourceUri(uri)); 55 if (!fronter) { 56 updated.set( 57 fronterGetSocialAppHref(parsedUri.repo, parsedUri.rkey!), 58 null, 59 ); 60 continue; 61 } 62 const view: FronterView = { 63 type: 64 parsedUri.collection === "app.bsky.feed.repost" ? "repost" : "post", 65 rkey: parsedUri.rkey!, 66 ...fronter, 67 }; 68 for (const href of fronterGetSocialAppHrefs(view)) { 69 updated.set(href, view); 70 } 71 } 72 // add entry for current page 73 const match = parseSocialAppPostUrl(document.location.href); 74 if (match && !updated.has(`/profile/${match.actorIdentifier}`)) { 75 const maybeFronter = updated.get( 76 `/profile/${match.actorIdentifier}/post/${match.rkey}`, 77 ); 78 if (maybeFronter) { 79 const displayName = await displayNameCache.get(match.actorIdentifier); 80 if (displayName) { 81 const view: FronterView = { 82 ...maybeFronter, 83 type: "thread_post", 84 depth: 0, 85 displayName, 86 rkey: match.rkey, 87 }; 88 updated.set(`/profile/${maybeFronter.did}`, view); 89 if (maybeFronter.handle) { 90 updated.set(`/profile/${maybeFronter.handle}`, view); 91 } 92 } 93 } 94 } 95 window.postMessage({ 96 type: "APPLY_CACHED_FRONTERS", 97 fronters: Object.fromEntries(updated), 98 }); 99 // check for tab fronter for the current "post" 100 await checkFronter(document.location.href); 101 }; 102 window.addEventListener("popstate", updateOnUrlChange); 103 ctx.addEventListener(window, "wxt:locationchange", updateOnUrlChange); 104 105 // setup response "channel" 106 document.dispatchEvent( 107 new CustomEvent("at-fronter-channel-setup", { 108 detail: respEventName, 109 }), 110 ); 111 112 // checkFronter(document.URL); 113 }, 114});