X(Twitter) Like and Retweet with One Click

This script adds a button that combines liking and retweeting in one click.

当前为 2024-11-22 提交的版本,查看 最新版本

// ==UserScript==
// @name         X(Twitter) Like and Retweet with One Click
// @namespace    https://greasyfork.org/en/users/948789
// @version      1.1
// @description  This script adds a button that combines liking and retweeting in one click.
// @author       RayBTA
// @match        https://*.x.com/*
// ==/UserScript==

(function() {
    'use strict';

    // function to like and retweet
    function likeAndRetweet(post, button) {
        const likeButton = post.querySelector('[data-testid="like"]');
        const retweetButton = post.querySelector('[data-testid="retweet"]');
        const unlikeButton = post.querySelector('[data-testid="unlike"]');
        const undoRetweetButton = post.querySelector('[data-testid="unretweet"]');

        if (button.liked) {
            if (unlikeButton) {
                unlikeButton.click();
            }
            if (undoRetweetButton) {
                undoRetweetButton.click();
                setTimeout(() => {
                    const confirmUnretweetButton = document.querySelector('[data-testid="unretweetConfirm"]');
                    if (confirmUnretweetButton) confirmUnretweetButton.click();
                }, 0);
            }
        } else {
            if (likeButton) {
                likeButton.click();
            }
            if (retweetButton) {
                retweetButton.click();
                setTimeout(() => {
                    const confirmRetweetButton = document.querySelector('[data-testid="retweetConfirm"]');
                    if (confirmRetweetButton) confirmRetweetButton.click();
                }, 0);
            }
        }

        button.liked = !button.liked;
    }

    // Function to add "L & R" button
function addLikeRetweetButton(post) {
    if (post.querySelector('.auto-like-retweet')) return;

    // Make sure the element is actually a post with action bar
    const actionBar = post.querySelector('[role="group"]');
    if (!actionBar) return;

    const likeButton = post.querySelector('[data-testid="like"]');
    const retweetButton = post.querySelector('[data-testid="retweet"]');

    // Check if post is already liked and retweeted
    if (!likeButton || !retweetButton) return;

    const button = document.createElement('button');
    button.innerText = "L & R";
    button.classList.add('auto-like-retweet');
    button.liked = false;

    button.style.marginLeft = "10px";
    button.style.padding = "5px 8px";
    button.style.backgroundColor = "transparent";
    button.style.color = "#1DA1F2";
    button.style.border = "1px solid #1DA1F2";
    button.style.borderRadius = "20px";
    button.style.cursor = "pointer";
    button.style.fontSize = "14px";
    button.style.fontWeight = "bold";
    button.style.transition = "background-color 0.3s";

    button.onmouseover = () => button.style.backgroundColor = "rgba(29, 161, 242, 0.1)";
    button.onmouseout = () => button.style.backgroundColor = "transparent";

    button.addEventListener('click', () => likeAndRetweet(post, button));

    actionBar.appendChild(button);
}

// Function to observe new posts
function observePosts() {
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === 1 && node.matches('.css-175oi2r')) {
                    addLikeRetweetButton(node);
                }
            });
        });
    });

    const feed = document.querySelector('main, [aria-label="Timeline: Sua página inicial"], [role="main"]');
    if (feed) {
        observer.observe(feed, { childList: true, subtree: true });
        feed.querySelectorAll('.css-175oi2r').forEach(post => addLikeRetweetButton(post));
    } else {
        setTimeout(observePosts, 2000);
    }
}
observePosts();
})();