Last active
May 10, 2023 15:44
-
-
Save yurighensev/c638e18f394a7bf8530ad2afdfa457ff to your computer and use it in GitHub Desktop.
archidekt deck page improvements
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Archidekt deck page improvements | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description try to take over the world! | |
// @author You | |
// @include *archidekt.com/decks/* | |
// @grant GM_log | |
// @require https://code.jquery.com/jquery-3.5.1.min.js | |
// @updateURL https://gist.github.com/yurighensev/c638e18f394a7bf8530ad2afdfa457ff | |
// ==/UserScript== | |
$(document).ready(function() { | |
const startFilterCountUpdateLoop = () => { | |
var el = document.createElement('span') | |
el.style = 'width: 10px; margin-top: 22px' | |
var group = document.querySelector('div[class^=deckFilters_group]') | |
group.append(el) | |
setInterval(() => { | |
let sum = 0 | |
document.querySelectorAll('#inner_stack_container .imageCard_container__Kv4_c .cornerQuantity_quantity__dx7jg') | |
.forEach((e) => sum += Number(e.innerText)) | |
el.innerText = sum | |
}, 1000) | |
} | |
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)) | |
const waitPageLoadAndInstall = async () => { | |
// main and deck errors loaders must be gone | |
while ($('div.ui.tiny.active.inline.loader').length > 0 || | |
$('div.ui.active.inverted.dimmer').length > 0) { | |
console.log("sleeping waiting for loaders to hide...") | |
await sleep(1000) | |
} | |
while (document.querySelector('div[class^=deckFilters_group]') === null) { | |
console.log("sleeping waiting for deckFilters_group...") | |
await sleep(1000) | |
} | |
startFilterCountUpdateLoop() | |
} | |
waitPageLoadAndInstall(); | |
}) | |
function old() { | |
var searchInput = () => $('#StyledRecommendationTab').find('form input[type="text"].prompt') | |
var isCtrlEnter = (event) => (event.keyCode == 10 || event.keyCode == 13) && event.ctrlKey | |
// ctrl+enter on search input clicks the first '+' button found | |
searchInput().on('keydown', function(e) { | |
if (isCtrlEnter(e)) { | |
$('#StyledRecommendationTab') | |
.find('i.plus.icon:first').click() | |
$(this).select() | |
} | |
}) | |
//=================== | |
var errorCardsCount = (parent = 'body') => $(parent).find('div[name="ErrorCard"]').length | |
var startActualDeckSizeUpdateLoop = () => { | |
var deckSizeHolder = () => $('div.meta:first').next().find('span:first') | |
var deckSize = () => parseInt(deckSizeHolder().text()) || 0 | |
var createActualDeckSizeHolders = () => { | |
deckSizeHolder().after(`Actual Deck Size: <strong><span class="actualDeckSize sc-dXfzlN BPnfY"></span>`) | |
$('body').append(`<div style="z-index: 999; position: absolute; bottom: 0; right: 3px; border: 2px solid #517ca1; background-color: #ccc; width: 125px; height: 20px; font-size: 12px; padding: 0 4px"> | |
Actual Deck Size <strong class="actualDeckSize"></strong> | |
</div>`) | |
} | |
var findSection = (name) => $(`div.${name.split(' ').join('.')}`) | |
var toAddCount = () => { | |
const toAddSection = findSection('To Add') | |
if (toAddSection.length == 0) | |
return 0; | |
const header = toAddSection.find('div > div > h3 > span > span').text() | |
return parseInt(header.replace('(', '').replace(')', '')) || 0 | |
} | |
createActualDeckSizeHolders() | |
setInterval(() => { | |
// marking as error means marking the card to be removed from the deck | |
const actualDeckSize = deckSize() - (errorCardsCount() * 2) - toAddCount() | |
$('.actualDeckSize').text(actualDeckSize) | |
}, 500) | |
} | |
var startActualSectionSizeUpdateLoop = () => { | |
var extraBasicLandsCount = (cardEls) => { | |
var count = 0 | |
cardEls.each((i, e) => { | |
if ($(e).find('div[name="ErrorCard"]').length > 0) | |
return | |
const cardCount = parseInt($(e).find('div.corner > div').text()) || 0 | |
count += cardCount - 1 | |
}) | |
return count | |
} | |
setInterval(() => { | |
var sections = $('.DeckContainer > div:first > div > div') | |
sections.each((i, e) => { | |
var cardEls = $(e).find('div:first > div.dragSource') | |
const actualSectionSize = cardEls.length - errorCardsCount(e) + extraBasicLandsCount(cardEls) | |
var sectionSizeEl = $(e).find('div > div:first > h3 > span span') | |
sectionSizeEl.text(`(${actualSectionSize})`) | |
}) | |
}, 500) | |
} | |
//=================== | |
var cardsTextForColumn = (column) => document.querySelector(`span[title="${column}"]`).parentElement.parentElement.parentElement.querySelectorAll(`div.TextCard div`) | |
var cardsList = (column) => { | |
console.debug('cardsList - ' + column + ' - cardsTextForColumn:', cardsTextForColumn(column)) | |
var cards = [] | |
cardsTextForColumn(column).forEach((e) => { | |
cards.push(e.innerText.replace(/^\d[^a-zA-Z]*/, '')) | |
}) | |
return cards | |
} | |
var createCopyButton = (column) => { | |
var copyButton = document.createElement('button') | |
copyButton.style.zIndex = '999999' | |
copyButton.textContent = column | |
copyButton.style.border = 'border: 2px solid #517ca1' | |
copyButton.style.backgroundColor = '#ccc' | |
$(copyButton).on('click', () => { | |
var copiedContent = '' | |
console.log(cardsList(column)) | |
copyToClipboard(cardsList(column).sort().join("\n")) | |
}) | |
return copyButton | |
} | |
var copyToClipboard = (selectedContent) => { | |
var $tempClipboardArea = document.createElement('textarea') | |
document.body.append($tempClipboardArea) | |
$tempClipboardArea.value = selectedContent | |
$tempClipboardArea.select() | |
document.execCommand('copy') | |
$tempClipboardArea.remove() | |
} | |
var cardColumns = () => { | |
return document.querySelectorAll(".DeckContainer > div > div > div:nth-of-type(1)") | |
} | |
var addColumnClickCopyToClipboard = () => { | |
cardColumns().forEach((col) => { | |
let span = col.querySelector("div > h4 > span") | |
if (!span) { | |
console.error('SCRIPT ERROR: span not found for ', col) | |
console.log(col) | |
return | |
} else { | |
console.debug('span found', span) | |
} | |
span.onclick = () => { | |
console.debug('span clicked', span) | |
let colName = span.title | |
console.log(cardsList(colName)) | |
copyToClipboard(cardsList(colName).sort().join("\n")) | |
showAlert('column contents copied to clipboard') | |
} | |
}) | |
} | |
//=================== | |
var findStackByDropdown = () => { | |
var stackBy = ''; | |
document.querySelectorAll('span > span > label > i').forEach((e) => { | |
if (e.parentElement.innerText == "Stack By") { | |
stackBy = e.parentElement; | |
} | |
}) | |
return stackBy.parentElement.querySelector('div[role="listbox"] > div[role="alert"]') | |
} | |
var observeStackByChange = () => { | |
var observer = new MutationObserver(function(mutations) { | |
console.debug('mutation observer run') | |
mutations.forEach(function(mutation) { | |
console.debug('mutation occurred, type: ' + mutation.type, mutation) | |
if (mutation.type == 'characterData') { | |
console.debug('stack by changed') | |
addColumnClickCopyToClipboard() | |
} | |
}) | |
}) | |
console.log('starting to observe stack by changes') | |
console.debug('stackByDropdown:', findStackByDropdown()) | |
observer.observe(findStackByDropdown(), { characterData: true, attributes: true, childList: true, subtree: true }) | |
} | |
//=================== | |
var createAlert = () => { | |
var alertEl = document.createElement('span') | |
alertEl.setAttribute('style', 'border: 1px solid #ccc; position: absolute; bottom: 0; left: 50px; background: rgb(110, 110, 110); color: #fff; transition: 0.8s; opacity: 0') | |
alertEl.setAttribute('id', 'alert-el') | |
document.body.append(alertEl) | |
} | |
var showAlert = (msg) => { | |
var alertEl = document.getElementById('alert-el') | |
alertEl.textContent = msg | |
alertEl.style.opacity = 1 | |
setTimeout(() => { | |
alertEl.style.opacity = 0 | |
}, 1500) | |
} | |
//=================== | |
var removeAdBlockerMessage = () => { | |
const a = document.querySelector('a[href="https://www.patreon.com/archidekt"]') | |
a.parentElement.parentElement.parentElement.parentElement.remove() | |
} | |
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)) | |
const waitPageLoadAndInstall = async () => { | |
// main and deck errors loaders must be gone | |
while ($('div.ui.tiny.active.inline.loader').length > 0 || | |
$('div.ui.active.inverted.dimmer').length > 0) { | |
await sleep(500) | |
} | |
while (cardColumns().length == 0) { | |
console.debug('no card columns, sleeping...') | |
await sleep(500) | |
} | |
startActualDeckSizeUpdateLoop() | |
startActualSectionSizeUpdateLoop() | |
addColumnClickCopyToClipboard() | |
observeStackByChange() | |
createAlert() | |
console.log("loaded"); | |
//removeAdBlockerMessage() - breaking new interface on load | |
} | |
waitPageLoadAndInstall(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment