Copy magnet URI's of selected/searched tables
// ==UserScript== // @name nyaa.si magnet copy/paste // @namespace http://tampermonkey.net/ // @version 1.5 // @description Copy magnet URI's of selected/searched tables // @match https://nyaa.si/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; const uncheckedIcon = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20"><rect x="3" y="3" width="18" height="18" rx="2" ry="2" stroke-width="2"/></svg>`; const checkedIcon = `<svg xmlns="http://www.w3.org/2000/svg" fill="#1976d2" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20"><rect x="3" y="3" width="18" height="18" rx="2" ry="2" stroke-width="2"/><path d="M6 12l4 4 8-8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`; const copyIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="currentColor" d="M3 7v6a9 9 0 0 0 9 9a9 9 0 0 0 9-9V7h-4v6a5 5 0 0 1-5 5a5 5 0 0 1-5-5V7m10-2h4V2h-4M3 5h4V2H3"/></svg>`; const checkIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 512 512"><path fill="currentColor" d="m106.667 64l298.666 201.671l-115.905 40.035l66.066 110.419L298.28 448l-66.067-110.419l-93.883 76.841z"/></svg>`; function addStyles() { const style = document.createElement('style'); style.textContent = ` /* Style for the select column header & cells */ th.select-col, td.select-col { text-align: center; vertical-align: middle; padding: 0.5rem; } /* Row select button styling */ .shadcn-select-btn { padding: 4px; background-color: transparent; border: none; cursor: pointer; transition: transform 0.2s ease; } .shadcn-select-btn:hover { transform: scale(1.1); } /* Top buttons container */ .magnet-button-container { margin: 20px 0; display: flex; gap: 12px; } /* Top buttons with icon & text */ .magnet-button { display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; font-size: 14px; cursor: pointer; background-color: #1976d2; border: none; border-radius: 4px; color: #fff; transition: background-color 0.3s ease, transform 0.2s ease; } .magnet-button:hover { background-color: #115293; transform: translateY(-1px); } /* Style for selected rows */ tr.selected-row { background-color: #d0ebff !important; transition: background-color 0.3s ease; } /* Icon within top buttons */ .btn-icon { display: inline-flex; vertical-align: middle; } .btn-text { display: inline-flex; vertical-align: middle; } `; document.head.appendChild(style); } function addSelectColumnHeader(table) { const thead = table.querySelector('thead'); if (thead) { const headerRow = thead.querySelector('tr'); if (headerRow) { const selectTh = document.createElement('th'); selectTh.className = 'select-col'; selectTh.style.width = '50px'; selectTh.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>`; headerRow.insertBefore(selectTh, headerRow.firstChild); } } } function addSelectButtonsToRows(table) { const rows = table.querySelectorAll('tbody tr'); rows.forEach(row => { const selectTd = document.createElement('td'); selectTd.className = 'select-col'; const btn = document.createElement('button'); btn.className = 'shadcn-select-btn'; btn.innerHTML = uncheckedIcon; btn.addEventListener('click', function(e) { e.stopPropagation(); btn.classList.toggle('selected'); if (btn.classList.contains('selected')) { btn.innerHTML = checkedIcon; row.classList.add('selected-row'); } else { btn.innerHTML = uncheckedIcon; row.classList.remove('selected-row'); } }); selectTd.appendChild(btn); row.insertBefore(selectTd, row.firstChild); }); } function addCopyButtons() { const table = document.querySelector('table.torrent-list'); if (!table) return; const container = document.createElement('div'); container.className = 'magnet-button-container'; const copyAllBtn = document.createElement('button'); copyAllBtn.className = 'magnet-button'; copyAllBtn.innerHTML = `<span class="btn-icon">${copyIcon}</span><span class="btn-text">Copy Magnets</span>`; container.appendChild(copyAllBtn); const copySelectedBtn = document.createElement('button'); copySelectedBtn.className = 'magnet-button'; copySelectedBtn.innerHTML = `<span class="btn-icon">${checkIcon}</span><span class="btn-text">Copy Selected</span>`; container.appendChild(copySelectedBtn); table.parentNode.insertBefore(container, table); copyAllBtn.addEventListener('click', () => { let magnetLinks = Array.from(table.querySelectorAll('a[href^="magnet:"]')) .map(a => a.href); magnetLinks = Array.from(new Set(magnetLinks)); const magnetsText = magnetLinks.join('\n'); navigator.clipboard.writeText(magnetsText) .then(() => { const originalHTML = copyAllBtn.innerHTML; copyAllBtn.innerHTML = `<span class="btn-icon">${copyIcon}</span><span class="btn-text">Copied!</span>`; setTimeout(() => { copyAllBtn.innerHTML = originalHTML; }, 2000); }) .catch(err => console.error('Error copying all magnet links:', err)); }); copySelectedBtn.addEventListener('click', () => { const selectedRows = table.querySelectorAll('tbody tr.selected-row'); if (selectedRows.length === 0) { alert('Please select one or more rows using the select buttons first.'); return; } let selectedMagnets = []; selectedRows.forEach(row => { const magnets = Array.from(row.querySelectorAll('a[href^="magnet:"]')) .map(a => a.href); selectedMagnets = selectedMagnets.concat(magnets); }); selectedMagnets = Array.from(new Set(selectedMagnets)); const magnetsText = selectedMagnets.join('\n'); navigator.clipboard.writeText(magnetsText) .then(() => { const originalHTML = copySelectedBtn.innerHTML; copySelectedBtn.innerHTML = `<span class="btn-icon">${checkIcon}</span><span class="btn-text">Copied!</span>`; setTimeout(() => { copySelectedBtn.innerHTML = originalHTML; }, 2000); }) .catch(err => console.error('Error copying selected magnet links:', err)); }); } window.addEventListener('load', function() { const table = document.querySelector('table.torrent-list'); if (table) { addStyles(); addSelectColumnHeader(table); addSelectButtonsToRows(table); addCopyButtons(); } }); })();