adds "add user to your favourite list" button next to users while scrolling through feed to save a few clicks (be sure to edit the variable "lists")
当前为
// ==UserScript==
// @name x-add-to-list-button
// @name:ja x-add-to-list-button
// @namespace x
// @version 0.1.0
// @description adds "add user to your favourite list" button next to users while scrolling through feed to save a few clicks (be sure to edit the variable "lists")
// @description:ja リストにワンクリックで追加するボタンを表示します(変数"lists"を必ず編集してください)
// @author fuwawascoco
// @match https://twitter.com/*
// @match https://mobile.twitter.com/*
// @match https://x.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant none
// @license MIT
// ==/UserScript==
// original script from https://greasyfork.org/en/scripts/485053-twitter-add-to-list-button
(function() {
'use strict';
const lists = ['test','illustrators','animators']; // be sure to change to the NAME of your lists (not IDs)
// too many lists or too long names will look ugly so you can either
// 1) shorten list names
// 2) limit to few lists
// 3) fix css below
const checkInterval = 512; // ms
const tryInterval = 64; // ms
function onClick(userProfile, list) {
const newTab = open(userProfile);
const intervalID = setInterval(()=>{
const moreButton = newTab.document.querySelector('div[aria-label="More"]');
if (moreButton === null) return;
clearInterval(intervalID);
moreButton.click();
const listButton = newTab.document.querySelector('[href="/i/lists/add_member"]');
listButton.click();
const listIntervalID = setInterval(()=>{
const modal = newTab.document.querySelector('[aria-modal="true"]');
if (modal === null) return;
const spans = modal.getElementsByTagName('span');
let theListNameSpan = null;
for (let i = 0; i < spans.length; ++i) {
if (spans[i].textContent !== list) continue;
theListNameSpan = spans[i];
break;
}
if (theListNameSpan === null) {
const checkbox = modal.querySelector('[aria-checked]');
if (checkbox === null) return;
newTab.alert(`"${list}" was not found`);
newTab.close();
clearInterval(listIntervalID);
return;
}
clearInterval(listIntervalID);
let checkbox = theListNameSpan;
while (!checkbox.hasAttribute('aria-checked')) {
checkbox = checkbox.parentElement;
}
if (checkbox.ariaChecked === 'false') {
checkbox.click();
const saveButton = spans[2];
saveButton.click();
}
newTab.close();
}, tryInterval);
}, tryInterval);
}
function ListButton(userProfile, list) {
const button = document.createElement('button');
const styles = {
fontSize: '90%',
margin: '0 0.25em',
};
for (const prop in styles) {
button.style[prop] = styles[prop];
}
button.textContent = list;
button.addEventListener('click', onClick.bind(null, userProfile, list));
return button;
}
function ListButtons(userProfile) {
const buttons = document.createElement('div');
const styles = {
position: 'relative',
left: '2%',
opacity: 0.5,
};
for (const prop in styles) {
buttons.style[prop] = styles[prop];
}
lists.forEach(list => {
buttons.appendChild(ListButton(userProfile, list));
});
buttons.classList.add('listButtons');
return buttons;
}
function addButtons() {
const selector = '[data-testid="User-Name"]:not(:has(.listButtons))';
const nodes = document.querySelectorAll(selector);
nodes.forEach(node => {
let userProfile = '';
function rec(children) {
for (const child of children) {
if (child.nodeName === 'A') {
userProfile = child.href;
return;
}
rec(child.childNodes);
if (userProfile !== '') return;
}
}
rec(node.childNodes);
node.appendChild(ListButtons(userProfile));
});
}
setInterval(addButtons, checkInterval)
})();