Skip to content

Instantly share code, notes, and snippets.

@CircuitRCAY
Forked from busybox11/twitterblue-nerd.js
Last active November 10, 2022 05:21
Show Gist options
  • Save CircuitRCAY/297408d564e71b4dafed131450b2ea82 to your computer and use it in GitHub Desktop.
Save CircuitRCAY/297408d564e71b4dafed131450b2ea82 to your computer and use it in GitHub Desktop.
Twitter Blue Nerd: Drip Edition
// ==UserScript==
// @name @chaoticvibing @CircuitRCAY Twitter Blue Drip - twitter.com
// @namespace Violentmonkey Scripts
// @match *://*.twitter.com/*
// @grant none
// @version 1.2.0
// @author @chaoticvibing - GH @busybox11 | @CircuitRCAY
// @description 11/9/2022, 11:45:28 PM
// @updateURL https://gist.githubusercontent.com/CircuitRCAY/297408d564e71b4dafed131450b2ea82/raw/twitterblue-nerd.js
// @downloadURL https://gist.githubusercontent.com/CircuitRCAY/297408d564e71b4dafed131450b2ea82/raw/twitterblue-nerd.js
// ==/UserScript==
// YOU'RE FREE TO DO WHATEVER YOU WANT WITH THIS SCRIPT BUT IF YOU DO MAKE SOMETHING
// PLEASE MAKE SURE TO MENTION ME SOMEWHERE - I hope you'll understand why :)
// Also https://paypal.me/busybox11 because I am broke
/* INSTRUCTIONS
*
* - Install a userscript browser extension
* (I used ViolentMonkey https://chrome.google.com/webstore/detail/violentmonkey/jinjaccalgkegednnccohejagnlnfdag,
* but you can use any extension you want, such as tampermonkey, it should work fine)
* FIREFOX USERS: It seems to work better with TamperMonkey: https://addons.mozilla.org/fr/firefox/addon/tampermonkey/
* - Import the script
* On ViolentMonkey, click on the extension icon, then gear icon (Open dashboard)
* There should be a plus icon on the top left hand corner, click on it and select Install from URL
* Use this URL: https://gist.githubusercontent.com/busybox11/53c76f57a577a47a19fab649a76f18e3/raw/twitterblue-nerd.js
* It should now work and update by itself
*
*/
/*
* DISCLAIMER
* I made this in a rush because of a challenge I convinced myself to do in reply to a tweet:
* https://twitter.com/Quinten0508/status/1590464705822224384?s=20&t=R_KhoR4a-_3fI4n4mbmmGA
* It might have horrible performance and it could not be reliable as I've tested this very quickly
* on some places I could find Twitter blue checkmarks, but I haven't made much research on it.
* At least it runs fine on my Ryzen 9 5900HS laptop and I don't see any noticeable frame drops
* on my 165Hz QHD display since I made this script, which might be a sign it's not impacting much.
* (I don't care anyway, fell free to modify it if it isn't)
*/
// 1.1.0 ALSO UPDATE ON HEADER OF PROFILE
// 1.1.1 AUTO UPDATE
// 1.1.2 Better handling of verified notifications
// 1.1.3 Better error logging
// 1.2.0 INITIAL VERY WIP FIREFOX SUPPORT
const driptick = `
<g><path fill="#5DADEC" d="M28.344 17.768L18.148 1.09 8.7 17.654c-2.2 3.51-2.392 8.074-.081 11.854 3.285 5.373 10.363 7.098 15.811 3.857 5.446-3.24 7.199-10.22 3.914-15.597z"/></g>`
const regulartick = `
<g><path d="M22.25 12c0-1.43-.88-2.67-2.19-3.34.46-1.39.2-2.9-.81-3.91s-2.52-1.27-3.91-.81c-.66-1.31-1.91-2.19-3.34-2.19s-2.67.88-3.33 2.19c-1.4-.46-2.91-.2-3.92.81s-1.26 2.52-.8 3.91c-1.31.67-2.2 1.91-2.2 3.34s.89 2.67 2.2 3.34c-.46 1.39-.21 2.9.8 3.91s2.52 1.26 3.91.81c.67 1.31 1.91 2.19 3.34 2.19s2.68-.88 3.34-2.19c1.39.45 2.9.2 3.91-.81s1.27-2.52.81-3.91c1.31-.67 2.19-1.91 2.19-3.34zm-11.71 4.2L6.8 12.46l1.41-1.42 2.26 2.26 4.8-5.23 1.47 1.36-6.2 6.77z"></path></g>
`
// STOLEN FROM https://stackoverflow.com/questions/70507318/how-to-get-react-element-props-from-html-element-with-javascript
function getReactProps(parent, target) {
// INITIAL VERY WIP FIREFOX HANDLING
parent = (window.chrome) ? parent : parent.wrappedJSObject;
const keyof_ReactProps = Object.keys(parent).find(k => k.startsWith("__reactProps$"));
const symof_ReactFragment = Symbol.for("react.fragment");
//Find the path from target to parent
let path = [];
let elem = (window.chrome) ? target : target.wrappedJSObject;
while (elem !== parent) {
let index = 0;
for (let sibling = elem; sibling != null;) {
if (sibling[keyof_ReactProps]) index++;
sibling = sibling.previousElementSibling;
}
path.push({ child: elem, index });
elem = elem.parentElement;
}
//Walk down the path to find the react state props
let state = elem[keyof_ReactProps];
for (let i = path.length - 1; i >= 0 && state != null; i--) {
//Find the target child state index
let childStateIndex = 0, childElemIndex = 0;
while (childStateIndex < state.children.length) {
let childState = state.children[childStateIndex];
if (childState instanceof Object) {
//Fragment children are inlined in the parent DOM element
let isFragment = childState.type === symof_ReactFragment && childState.props.children.length;
childElemIndex += isFragment ? childState.props.children.length : 1;
if (childElemIndex === path[i].index) break;
}
childStateIndex++;
}
let childState = state.children[childStateIndex] ?? (childStateIndex === 0 ? state.children : null);
state = childState?.props;
elem = path[i].child;
}
return state;
}
function updateBlueTick(elem, props) {
if (props.isBlueVerified) {
elem.setAttribute('viewBox', '0 0 32 36')
elem.innerHTML = driptick
} else {
elem.setAttribute('viewBox', '0 0 24 24')
elem.innerHTML = regulartick
}
}
function handleMutation(mutations) {
try {
for (mutation of mutations) {
for (elem of mutation.addedNodes) {
const blueticks = elem.querySelectorAll('[aria-label="Verified account"]')
try {
for (bluetick of blueticks) {
if (bluetick !== null) {
let propsElem = getReactProps(bluetick.parentElement, bluetick)
if (propsElem.children !== undefined) {
const props = propsElem.children[0][0].props
if (props.isBlueVerified !== undefined) {
updateBlueTick(bluetick, props)
} else {
// VERY HACKY FIX DO BETTER NEXT TIME
const otherProps = propsElem.children[0][2].props
updateBlueTick(bluetick, otherProps)
}
} else {
const propsElemParent = getReactProps(bluetick.parentElement.parentElement.parentElement, bluetick.parentElement.parentElement)
const propsParent = propsElemParent.children[0][0].props
updateBlueTick(bluetick, propsParent)
}
}
}
} catch(e) {console.log(e)}
}
}
} catch(e) {}
}
const observer = new MutationObserver(handleMutation)
observer.observe(document, { childList: true, subtree: true })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment