Greasy Fork is available in English.

Slack Copy Reaction Names and Handles

Adds buttons to the Slack reaction bar to copy the list of people who reacted and their handles

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         Slack Copy Reaction Names and Handles
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Adds buttons to the Slack reaction bar to copy the list of people who reacted and their handles
// @match        https://app.slack.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Function to create the "Copy Reacted Names" button
    function createNamesButton() {
        const button = document.createElement('button');
        button.textContent = 'Copy Reacted Names';
        button.classList.add('c-button-unstyled', 'c-reaction', 'c-reaction--light');
        button.setAttribute('aria-label', 'Copy Reacted Names');
        button.setAttribute('type', 'button');
        button.addEventListener('click', copyReactedNames);
        return button;
    }

    // Function to create the "Copy Reacted Handles" button
    function createHandlesButton() {
        const button = document.createElement('button');
        button.textContent = 'Copy Reacted Handles';
        button.classList.add('c-button-unstyled', 'c-reaction', 'c-reaction--light');
        button.setAttribute('aria-label', 'Copy Reacted Handles');
        button.setAttribute('type', 'button');
        button.addEventListener('click', copyReactedHandles);
        return button;
    }

    // Function to simulate hover event on the reaction button
    function simulateHover(element) {
        const mouseOverEvent = new MouseEvent('mouseover', {
            view: window,
            bubbles: true,
            cancelable: true
        });
        element.dispatchEvent(mouseOverEvent);
    }

    // Function to copy the reacted names to the clipboard
    function copyReactedNames(event) {
        const reactionButton = event.target.closest('.c-reaction_bar').querySelector('.c-reaction');
        const tooltipElement = document.querySelector('.c-reaction__tip_group');

        if (!tooltipElement) {
            simulateHover(reactionButton);
            setTimeout(copyReactedNames, 100, event);
            return;
        }

        const reactedUsers = tooltipElement.textContent.split(', ');
        const userList = reactedUsers.slice(0, -1).join(', ');
        navigator.clipboard.writeText(userList);
        alert('Reacted names copied to clipboard!');
    }

    // Function to copy the reacted handles to the clipboard
    function copyReactedHandles(event) {
        const reactionButton = event.target.closest('.c-reaction_bar').querySelector('.c-reaction');
        const tooltipElement = document.querySelector('.c-reaction__tip_group');

        if (!tooltipElement) {
            simulateHover(reactionButton);
            setTimeout(copyReactedHandles, 100, event);
            return;
        }

        const reactedUsers = tooltipElement.textContent.split(', ');
        const userList = reactedUsers.slice(0, -1).map(user => `@${user}`).join(', ');
        navigator.clipboard.writeText(userList);
        alert('Reacted handles copied to clipboard!');
    }

    // Function to insert the buttons into the reaction bar
    function insertButtons(reactionBar) {
        const namesButton = createNamesButton();
        const handlesButton = createHandlesButton();
        reactionBar.appendChild(namesButton);
        reactionBar.appendChild(handlesButton);
    }

    // Function to observe changes in the DOM
    function observeDOM(callback) {
        const observer = new MutationObserver(callback);
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // Function to handle DOM changes
    function handleDOMChange(mutationsList, observer) {
        for (let mutation of mutationsList) {
            if (mutation.type === 'childList') {
                const reactionBars = document.querySelectorAll('.c-reaction_bar');
                reactionBars.forEach(reactionBar => {
                    if (!reactionBar.querySelector('button[aria-label="Copy Reacted Names"]')) {
                        insertButtons(reactionBar);
                    }
                });
            }
        }
    }

    // Start observing the DOM for changes
    observeDOM(handleDOMChange);
})();