···825825 // Initial check
826826 checkCurrentProfile();
827827828828+ const checkUserLinksOnPage = async () => {
829829+ // Look for profile links with handles
830830+ // Find all profile links and filter to get only one link per parent
831831+ const allProfileLinks = Array.from(
832832+ document.querySelectorAll('a[href^="/profile/"]:not(:has(*))'),
833833+ );
834834+835835+ // Use a Map to keep track of parent elements and their first child link
836836+ const parentMap = new Map();
837837+838838+ // For each link, store only the first one found for each parent
839839+ for (const link of allProfileLinks) {
840840+ const parent = link.parentElement;
841841+ if (parent && !parentMap.has(parent)) {
842842+ parentMap.set(parent, link);
843843+ }
844844+ }
845845+846846+ // Get only the first link for each parent
847847+ const profileLinks = Array.from(parentMap.values());
848848+849849+ if (profileLinks.length === 0) return;
850850+851851+ console.log(`Found ${profileLinks.length} possible user links on page`);
852852+853853+ // Process profile links to identify user containers
854854+ for (const link of profileLinks) {
855855+ try {
856856+ // Check if we already processed this link
857857+ if (link.getAttribute("data-verification-checked") === "true") continue;
858858+859859+ // Mark as checked
860860+ link.setAttribute("data-verification-checked", "true");
861861+862862+ // Extract handle from href
863863+ const handle = link.getAttribute("href").split("/profile/")[1];
864864+ if (!handle) continue;
865865+866866+ // check if there is anything after the handle
867867+ const handleTrailing = handle.split("/").length > 1;
868868+ if (handleTrailing) continue;
869869+870870+ // Find parent container that might contain the handle and verification icon
871871+ // Look for containers where this link is followed by another link with the same handle
872872+ const parent = link.parentElement;
873873+874874+ // If we found a container with the verification icon
875875+ if (parent) {
876876+ // Check if this user already has our verification badge
877877+ if (parent.querySelector(".trusted-user-inline-badge")) continue;
878878+879879+ try {
880880+ // Fetch user profile data to get DID
881881+ const response = await fetch(
882882+ `https://public.api.bsky.app/xrpc/com.atproto.repo.getRecord?repo=${handle}&collection=app.bsky.actor.profile&rkey=self`,
883883+ );
884884+ const data = await response.json();
885885+886886+ // Extract the DID from the profile data
887887+ const did = data.uri.split("/")[2];
888888+889889+ // Check if this user is verified by our trusted users
890890+ const trustedUsers = getTrustedUsers();
891891+ let isVerified = false;
892892+ const verifiers = [];
893893+894894+ // Check cache first for each trusted user
895895+ for (const trustedUser of trustedUsers) {
896896+ const cachedData = getCachedVerifications(trustedUser);
897897+898898+ if (cachedData && isCacheValid(cachedData)) {
899899+ // Use cached verification data
900900+ const records = cachedData.records;
901901+902902+ for (const record of records) {
903903+ if (record.value && record.value.subject === did) {
904904+ isVerified = true;
905905+ verifiers.push(trustedUser);
906906+ break;
907907+ }
908908+ }
909909+ }
910910+ }
911911+912912+ // If verified, add a small badge
913913+ if (isVerified && verifiers.length > 0) {
914914+ // Create a badge element
915915+ const smallBadge = document.createElement("span");
916916+ smallBadge.className = "trusted-user-inline-badge";
917917+ smallBadge.innerHTML = "✓";
918918+919919+ // Create tooltip text with all verifiers
920920+ const verifiersText =
921921+ verifiers.length > 1
922922+ ? `Verified by: ${verifiers.join(", ")}`
923923+ : `Verified by ${verifiers[0]}`;
924924+925925+ smallBadge.title = verifiersText;
926926+ smallBadge.style.cssText = `
927927+ background-color: #0070ff;
928928+ color: white;
929929+ border-radius: 50%;
930930+ width: 14px;
931931+ height: 14px;
932932+ font-size: 10px;
933933+ font-weight: bold;
934934+ cursor: help;
935935+ display: inline-flex;
936936+ align-items: center;
937937+ justify-content: center;
938938+ margin-left: 4px;
939939+ `;
940940+941941+ // Add click event to show verifiers
942942+ smallBadge.addEventListener("click", (e) => {
943943+ e.stopPropagation();
944944+ showVerifiersPopup(verifiers);
945945+ });
946946+947947+ // Insert badge after the SVG element
948948+ parent.firstChild.after(smallBadge);
949949+ parent.style.flexDirection = "row";
950950+ parent.style.alignItems = "center";
951951+ }
952952+ } catch (error) {
953953+ console.error(`Error checking verification for ${handle}:`, error);
954954+ }
955955+ }
956956+ } catch (error) {
957957+ console.error("Error processing profile link:", error);
958958+ }
959959+ }
960960+ };
961961+962962+ const observeContentChanges = () => {
963963+ // Use a debounced function to check for new user links
964964+ const debouncedCheck = () => {
965965+ clearTimeout(window.userLinksCheckTimeout);
966966+ window.userLinksCheckTimeout = setTimeout(() => {
967967+ checkUserLinksOnPage();
968968+ }, 300);
969969+ };
970970+971971+ // Create a mutation observer that watches for DOM changes
972972+ const observer = new MutationObserver((mutations) => {
973973+ let hasRelevantChanges = false;
974974+975975+ // Check if any mutations involve adding new nodes
976976+ for (const mutation of mutations) {
977977+ if (mutation.addedNodes.length > 0) {
978978+ for (const node of mutation.addedNodes) {
979979+ if (node.nodeType === Node.ELEMENT_NODE) {
980980+ // Check if this element or its children might contain profile links
981981+ if (
982982+ node.querySelector('a[href^="/profile/"]') ||
983983+ (node.tagName === "A" &&
984984+ node.getAttribute("href")?.startsWith("/profile/"))
985985+ ) {
986986+ hasRelevantChanges = true;
987987+ break;
988988+ }
989989+ }
990990+ }
991991+ }
992992+ if (hasRelevantChanges) break;
993993+ }
994994+995995+ if (hasRelevantChanges) {
996996+ debouncedCheck();
997997+ }
998998+ });
999999+10001000+ // Observe the entire document for content changes that might include profile links
10011001+ observer.observe(document.body, { childList: true, subtree: true });
10021002+10031003+ // Also check periodically for posts that might have been loaded but not caught by the observer
10041004+ setInterval(debouncedCheck, 5000);
10051005+ };
10061006+10071007+ // Add these calls to the initialization section
10081008+ // Initial check for user links
10091009+ setTimeout(checkUserLinksOnPage, 1000); // Slight delay to ensure page has loaded
10101010+10111011+ // Start observing for content changes to detect newly loaded posts
10121012+ observeContentChanges();
10131013+8281014 // Set up a MutationObserver to watch for URL changes
8291015 const observeUrlChanges = () => {
8301016 let lastUrl = location.href;