the home of serif.blue
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: avoid recreating existing ellements

+113 -62
+113 -62
bluesky-community-verifications.user.js
··· 1 1 (() => { 2 + // Script has already been initialized check 3 + if (window.bskyTrustedUsersInitialized) { 4 + console.log("Trusted Users script already initialized"); 5 + return; 6 + } 7 + 8 + // Mark script as initialized 9 + window.bskyTrustedUsersInitialized = true; 10 + 2 11 // Define a storage key for trusted users 3 12 const TRUSTED_USERS_STORAGE_KEY = "bsky_trusted_users"; 4 13 ··· 46 55 `Checking if any trusted users have verified ${currentProfileDid}`, 47 56 ); 48 57 49 - let isVerifiedByTrustedUser = false; 50 - 51 58 // Use Promise.all to fetch all verification data in parallel 52 59 const verificationPromises = trustedUsers.map(async (trustedUser) => { 53 60 try { ··· 66 73 67 74 // Add to verifiers list 68 75 profileVerifiers.push(trustedUser); 69 - isVerifiedByTrustedUser = true; 70 76 } 71 77 } 72 78 } ··· 214 220 }); 215 221 }; 216 222 217 - // Create settings button and modal 223 + // Create settings UI - only once 224 + let settingsButton = null; 225 + let settingsModal = null; 226 + 227 + // Function to create the settings UI if it doesn't exist yet 218 228 const createSettingsUI = () => { 229 + // Check if UI already exists 230 + if (document.getElementById("bsky-trusted-settings-button")) { 231 + return; 232 + } 233 + 219 234 // Create settings button 220 - const settingsButton = document.createElement("button"); 235 + settingsButton = document.createElement("button"); 236 + settingsButton.id = "bsky-trusted-settings-button"; 221 237 settingsButton.textContent = "Trusted Users Settings"; 222 238 settingsButton.style.cssText = ` 223 239 position: fixed; ··· 234 250 `; 235 251 236 252 // Create modal container 237 - const modal = document.createElement("div"); 238 - modal.style.cssText = ` 253 + settingsModal = document.createElement("div"); 254 + settingsModal.id = "bsky-trusted-settings-modal"; 255 + settingsModal.style.cssText = ` 239 256 display: none; 240 257 position: fixed; 241 258 top: 0; ··· 299 316 modalContent.appendChild(form); 300 317 modalContent.appendChild(trustedUsersList); 301 318 modalContent.appendChild(closeButton); 302 - modal.appendChild(modalContent); 319 + settingsModal.appendChild(modalContent); 303 320 304 321 // Add elements to the document 305 322 document.body.appendChild(settingsButton); 306 - document.body.appendChild(modal); 323 + document.body.appendChild(settingsModal); 307 324 308 325 // Function to update the list of trusted users in the UI 309 326 const updateTrustedUsersList = () => { ··· 346 363 347 364 // Event listeners 348 365 settingsButton.addEventListener("click", () => { 349 - modal.style.display = "flex"; 366 + settingsModal.style.display = "flex"; 350 367 updateTrustedUsersList(); 351 368 }); 352 369 353 370 closeButton.addEventListener("click", () => { 354 - modal.style.display = "none"; 371 + settingsModal.style.display = "none"; 355 372 }); 356 373 357 374 document ··· 367 384 }); 368 385 369 386 // Close modal when clicking outside 370 - modal.addEventListener("click", (e) => { 371 - if (e.target === modal) { 372 - modal.style.display = "none"; 387 + settingsModal.addEventListener("click", (e) => { 388 + if (e.target === settingsModal) { 389 + settingsModal.style.display = "none"; 373 390 } 374 391 }); 375 392 }; 376 393 377 - const currentUrl = window.location.href; 378 - if (currentUrl.includes("bsky.app/profile/")) { 379 - const handle = currentUrl.split("/profile/")[1].split("/")[0]; 380 - console.log("Extracted handle:", handle); 394 + // Function to check the current profile 395 + const checkCurrentProfile = () => { 396 + const currentUrl = window.location.href; 397 + if (currentUrl.includes("bsky.app/profile/")) { 398 + const handle = currentUrl.split("/profile/")[1].split("/")[0]; 399 + console.log("Extracted handle:", handle); 381 400 382 - // Create and add the settings UI 383 - createSettingsUI(); 401 + // Create and add the settings UI (only once) 402 + createSettingsUI(); 384 403 385 - // Fetch user profile data 386 - fetch( 387 - `https://bsky.social/xrpc/com.atproto.repo.getRecord?repo=${handle}&collection=app.bsky.actor.profile&rkey=self`, 388 - ) 389 - .then((response) => response.json()) 390 - .then((data) => { 391 - console.log("User profile data:", data); 404 + // Fetch user profile data 405 + fetch( 406 + `https://bsky.social/xrpc/com.atproto.repo.getRecord?repo=${handle}&collection=app.bsky.actor.profile&rkey=self`, 407 + ) 408 + .then((response) => response.json()) 409 + .then((data) => { 410 + console.log("User profile data:", data); 392 411 393 - // Extract the DID from the profile data 394 - const did = data.uri.split("/")[2]; 395 - console.log("User DID:", did); 412 + // Extract the DID from the profile data 413 + const did = data.uri.split("/")[2]; 414 + console.log("User DID:", did); 415 + 416 + // Now fetch the app.bsky.graph.verification data specifically 417 + fetch( 418 + `https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=${handle}&collection=app.bsky.graph.verification`, 419 + ) 420 + .then((response) => response.json()) 421 + .then((verificationData) => { 422 + console.log("Verification data:", verificationData); 423 + if ( 424 + verificationData.records && 425 + verificationData.records.length > 0 426 + ) { 427 + console.log( 428 + "User has app.bsky.graph.verification:", 429 + verificationData.records, 430 + ); 431 + } else { 432 + console.log("User does not have app.bsky.graph.verification"); 433 + } 396 434 397 - // Now fetch the app.bsky.graph.verification data specifically 398 - fetch( 399 - `https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=${handle}&collection=app.bsky.graph.verification`, 400 - ) 401 - .then((response) => response.json()) 402 - .then((verificationData) => { 403 - console.log("Verification data:", verificationData); 404 - if ( 405 - verificationData.records && 406 - verificationData.records.length > 0 407 - ) { 408 - console.log( 409 - "User has app.bsky.graph.verification:", 410 - verificationData.records, 435 + // Check if any trusted users have verified this profile using the DID 436 + checkTrustedUserVerifications(did); 437 + }) 438 + .catch((verificationError) => { 439 + console.error( 440 + "Error fetching verification data:", 441 + verificationError, 411 442 ); 412 - } else { 413 - console.log("User does not have app.bsky.graph.verification"); 414 - } 443 + }); 444 + }) 445 + .catch((error) => { 446 + console.error("Error checking profile:", error); 447 + }); 448 + 449 + console.log("Bluesky profile detected"); 450 + } 451 + }; 452 + 453 + // Initial check 454 + checkCurrentProfile(); 455 + 456 + // Set up a MutationObserver to watch for URL changes 457 + const observeUrlChanges = () => { 458 + let lastUrl = location.href; 459 + 460 + const observer = new MutationObserver(() => { 461 + if (location.href !== lastUrl) { 462 + lastUrl = location.href; 463 + console.log("URL changed to:", location.href); 464 + 465 + // Remove any existing badges when URL changes 466 + const existingBadge = document.getElementById( 467 + "user-trusted-verification-badge", 468 + ); 469 + if (existingBadge) { 470 + existingBadge.remove(); 471 + } 472 + 473 + // Check if we're on a profile page now 474 + checkCurrentProfile(); 475 + } 476 + }); 415 477 416 - // Check if any trusted users have verified this profile using the DID 417 - checkTrustedUserVerifications(did); 418 - }) 419 - .catch((verificationError) => { 420 - console.error( 421 - "Error fetching verification data:", 422 - verificationError, 423 - ); 424 - }); 425 - }) 426 - .catch((error) => { 427 - console.error("Error checking profile:", error); 428 - }); 478 + observer.observe(document, { subtree: true, childList: true }); 479 + }; 429 480 430 - console.log("Example domain detected"); 431 - } 481 + // Start observing for URL changes 482 + observeUrlChanges(); 432 483 })();