Skip to content

Instantly share code, notes, and snippets.

@skeddles
Last active October 29, 2024 22:09
Show Gist options
  • Save skeddles/cd435a97dc946a36ea211c2973c15df3 to your computer and use it in GitHub Desktop.
Save skeddles/cd435a97dc946a36ea211c2973c15df3 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name BlueSky Profile Follower Count Updater
// @namespace http://tampermonkey.net/
// @version 1.14
// @description Update the follower count on BlueSky profile pages with commas, even on URL changes
// @author skeddles
// @homepage https://bsky.app/profile/skeddles.com
// @match https://bsky.app/profile/*
// @grant GM.xmlHttpRequest
// @connect public.api.bsky.app
// ==/UserScript==
(function () {
'use strict';
let username = null;
let checkInterval = null;
// Function to update the username and trigger follower link check
function updateUsernameAndCheckLink() {
const newUsername = window.location.pathname.split('/').pop();
// Check if the username has changed
if (newUsername !== username) {
username = newUsername;
console.log("FOLLOW COUNT: Username updated:", username);
// Clear any previous interval before starting a new one
if (checkInterval) clearInterval(checkInterval);
// Start a retry interval to find the follower link and update follower count
let attempts = 0;
checkInterval = setInterval(() => {
attempts++;
console.log("FOLLOW COUNT: Attempting to find follower link, attempt:", attempts);
// Look for the follower link for the current profile
const followerLink = document.querySelector(`a[href="/profile/${username}/followers"]`);
if (followerLink) {
console.log("FOLLOW COUNT: Follower link found!", followerLink);
// Check the current follower count before making the API request
const followerCountSpan = followerLink.querySelector("span");
if (followerCountSpan) {
const currentCountText = followerCountSpan.textContent.trim();
console.log('FOLLOW COUNT: kkkkk ', currentCountText.toLowerCase().includes('k'))
// Check if the current count contains 'k' or 'K'
if (currentCountText.toLowerCase().includes('k')) {
console.log(`FOLLOW COUNT: Current follower is over 999 (${currentCountText}). Proceeding to update.`);
// Stop retrying once the link is found
clearInterval(checkInterval);
// Fetch the followers count from the API
GM.xmlHttpRequest({
method: "GET",
url: `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${username}`,
headers: {
"Accept": "application/json"
},
onload: function (response) {
if (response.status === 200) {
try {
const data = JSON.parse(response.responseText);
const followersCount = data.followersCount;
if (typeof followersCount !== 'undefined') {
// Format the follower count with commas
const formattedCount = followersCount.toLocaleString();
// Replace the text of the first child span in the follower link with a space after the formatted number
if (followerCountSpan) {
followerCountSpan.textContent = formattedCount + " ";
console.log("FOLLOW COUNT: Success! Updated follower count to:", formattedCount);
}
} else {
console.error("FOLLOW COUNT: Followers count not found in the API response.");
}
} catch (e) {
console.error("FOLLOW COUNT: Error parsing API response:", e);
}
} else {
console.error("FOLLOW COUNT: API request failed with status:", response.status);
}
},
onerror: function (error) {
console.error("FOLLOW COUNT: Request failed:", error);
}
});
} else {
console.log(`FOLLOW COUNT: Exiting early with current follower count: ${currentCountText}`);
clearInterval(checkInterval); // Stop further attempts
}
}
}
// Stop trying after 30 seconds
if (attempts >= 120) {
clearInterval(checkInterval);
console.error("FOLLOW COUNT: Timeout - Follower link not found.");
}
}, 250);
}
}
// Observe changes to the URL by overriding pushState and adding a popstate listener
function observeUrlChanges() {
// Override pushState to trigger URL change detection
const originalPushState = history.pushState;
history.pushState = function () {
originalPushState.apply(this, arguments);
updateUsernameAndCheckLink();
};
// Listen to the popstate event for back/forward navigation
window.addEventListener("popstate", updateUsernameAndCheckLink);
}
// Initial setup
observeUrlChanges();
updateUsernameAndCheckLink(); // Run the initial check on first page load
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment