view who was fronting when a record was made

fix: set fronters for depth 0 thread view items on router url change

ptr.pet b172643d a88e7061

verified
Changed files
+60 -23
src
+7 -1
src/entrypoints/background.ts
··· 10 10 putFronter, 11 11 frontersCache, 12 12 parseSocialAppPostUrl, 13 + displayNameCache, 13 14 } from "@/lib/utils"; 14 15 import { 15 16 parseCanonicalResourceUri, ··· 201 202 ...fronter, 202 203 }; 203 204 if (item.depth === 0) await setTabFronter(item.uri, fronter); 205 + const displayName = item.value.post.author.displayName; 206 + // cache display name for later use 207 + if (fronter.handle) 208 + await displayNameCache.set(fronter.handle, displayName); 209 + await displayNameCache.set(fronter.did, displayName); 204 210 return { 205 211 rkey: parsedUri.rkey!, 206 - displayName: item.value.post.author.displayName, 212 + displayName, 207 213 depth: item.depth, 208 214 ...fronter, 209 215 };
+7 -17
src/entrypoints/content.ts
··· 72 72 body, 73 73 authToken: getAuthToken(), 74 74 }; 75 + } else if (response.url.includes("/xrpc/com.atproto.repo.deleteRecord")) { 75 76 } else if (response.url.includes("/xrpc/com.atproto.repo.createRecord")) { 76 77 detail = { 77 78 type: "writeOne", ··· 124 125 respEventSetup.then((name) => (respEventName = name)); 125 126 126 127 const applyFronterName = (el: Element, fronters: Fronter["members"]) => { 127 - if (el.getAttribute("data-fronter")) return; 128 + if (el.hasAttribute("data-fronter")) return; 128 129 const s = fronters.map((f) => f.name).join(", "); 129 130 el.textContent += ` [f: ${s}]`; 130 131 el.setAttribute("data-fronter", s); ··· 135 136 ) => { 136 137 // console.log("applyFrontersToPage", fronters); 137 138 const match = parseSocialAppPostUrl(document.URL); 138 - console.log("applyFrontersToPage", match, fronters); 139 139 if (pageChange) { 140 140 console.log( 141 141 "page change so clearing all elements with data-fronter attribute", ··· 150 150 el.removeAttribute("data-fronter"); 151 151 } 152 152 } 153 + console.log("applyFrontersToPage", match, fronters); 153 154 if (fronters.size === 0) return; 154 155 for (const el of document.getElementsByTagName("a")) { 155 156 const path = `/${el.href.split("/").slice(3).join("/")}`; 156 157 const fronter = fronters.get(path); 157 - if (!fronter || fronter.members.length === 0) continue; 158 + if (!fronter || fronter.members?.length === 0) continue; 159 + if (el.hasAttribute("data-fronter")) continue; 158 160 const isFocusedPost = fronter.depth === 0; 159 161 if (isFocusedPost) if (match && match.rkey !== fronter.rkey) continue; 160 162 if (isFocusedPost) if (el.ariaLabel !== fronter.displayName) continue; ··· 171 173 window.addEventListener("message", (event) => { 172 174 if (event.data.type !== "APPLY_CACHED_FRONTERS") return; 173 175 const applyFronters = () => { 174 - const fronters = event.data.fronters as Map<string, Fronter | null>; 175 - const updated = new Map( 176 - fronters.entries().flatMap(([storageKey, fronter]) => { 177 - if (!fronter) return []; 178 - const uri = decodeStorageKey(storageKey); 179 - const rkey = expect(parseResourceUri(uri)).rkey!; 180 - return fronterGetSocialAppHrefs(fronter, rkey).map((href) => [ 181 - href, 182 - fronter, 183 - ]); 184 - }), 185 - ); 186 - console.log("applying cached fronters", updated); 187 - applyFrontersToPage(updated, true); 176 + console.log("applying cached fronters", event.data.fronters); 177 + applyFrontersToPage(event.data.fronters, true); 188 178 }; 189 179 // check if we are on profile so we can update fronters if the post tab is clicked on 190 180 const postTabElement = document.querySelector(
+41 -5
src/entrypoints/isolated.content.ts
··· 1 - import { Fronter, frontersCache, parseSocialAppPostUrl } from "@/lib/utils"; 2 - import { ResourceUri } from "@atcute/lexicons"; 1 + import { decodeStorageKey } from "@/lib/cache"; 2 + import { expect } from "@/lib/result"; 3 + import { 4 + displayNameCache, 5 + Fronter, 6 + fronterGetSocialAppHrefs, 7 + frontersCache, 8 + parseSocialAppPostUrl, 9 + } from "@/lib/utils"; 10 + import { parseResourceUri, ResourceUri } from "@atcute/lexicons"; 3 11 4 12 export default defineContentScript({ 5 13 matches: ["<all_urls>"], ··· 36 44 if (!messageTypes.includes(message.type)) return; 37 45 window.postMessage(message); 38 46 }); 39 - window.addEventListener("popstate", async (event) => { 47 + const updateOnUrlChange = async () => { 48 + const fronters = await frontersCache.getAll(); 49 + const updated = new Map<string, any>( 50 + fronters.entries().flatMap(([storageKey, fronter]) => { 51 + if (!fronter) return []; 52 + const uri = decodeStorageKey(storageKey); 53 + const rkey = expect(parseResourceUri(uri)).rkey!; 54 + return fronterGetSocialAppHrefs(fronter, rkey).map((href) => [ 55 + href, 56 + fronter, 57 + ]); 58 + }), 59 + ); 60 + // add entry for current page 61 + const match = parseSocialAppPostUrl(document.location.href); 62 + if (match && !updated.has(`/profile/${match.actorIdentifier}`)) { 63 + const maybeFronter = updated.get( 64 + `/profile/${match.actorIdentifier}/post/${match.rkey}`, 65 + ); 66 + if (maybeFronter) 67 + updated.set(`/profile/${match.actorIdentifier}`, { 68 + depth: 0, 69 + displayName: await displayNameCache.get(match.actorIdentifier), 70 + rkey: match.rkey, 71 + ...maybeFronter, 72 + }); 73 + } 40 74 window.postMessage({ 41 75 type: "APPLY_CACHED_FRONTERS", 42 - fronters: await frontersCache.getAll(), 76 + fronters: updated, 43 77 }); 44 78 // check for tab fronter for the current "post" 45 79 await checkFronter(document.location.href); 46 - }); 80 + }; 81 + window.addEventListener("popstate", updateOnUrlChange); 82 + ctx.addEventListener(window, "wxt:locationchange", updateOnUrlChange); 47 83 48 84 // setup response "channel" 49 85 document.dispatchEvent(
+5
src/lib/utils.ts
··· 334 334 const [website, actorIdentifier, rkey] = match; 335 335 return { actorIdentifier, rkey }; 336 336 }; 337 + 338 + export const displayNameCache = new PersistentCache<string>( 339 + "displayNameCache", 340 + 1, 341 + );