// I think we should create another interface, // which copies the buttons, combined with their text inside, holding the index, // so you can trigger it from a button press which is always visible. // press ctrl+shift+j inside of the stream, then paste this. // a new menu will appear in the top right. you can open it and press on the buttons :) async function layoutMaker() { // // 1. define functions // // element selector function function $$(selector, node=document.body) { return node.querySelectorAll(selector) } // function to wait some time, combined with asynch, // it allows us to wait for some time in a synchronous style. function wait(ms) { return new Promise(function(resolve, reject) { setTimeout(resolve, ms) }) } //------------------------------------------------------ // // 2. program // // 1. open the rewards menu. $$('[aria-label="Points Balance"]')[0].click() // 2. wait untill the menu opens. await wait(20) // 3. put all of the reward item elements into a variable const rewardElements = Array.from($$("#channel-points-reward-center-body .reward-list-item")) const dataItems = [] // 4. loop through the rewardElements, putting all of the // relevant data into an array of objects // inside of this loop we will pull the data from 1 reward element for(let i = 0; i < rewardElements.length; i++) { const rewardEl = rewardElements[i] const data = { cost: 0, name: '', icon:'', index: i, } // 4.1. grab the cost data.cost = $$('[data-test-selector=cost]', rewardEl)[0].textContent // 4.2. grab the name data.name = $$('.reward-list-item > div > div', rewardEl)[0].textContent // 4.3. grab the icon data.icon = $$('img', rewardEl)[0].src // 4.4 put the item inside of array dataItems.push(data) } // 5. create an interface, with buttons containing the // same details as the reward buttons, with an onclick // function that actually does the reward handling, only // these buttons will instantly do the reward, and this // menu does not close. const detailsEl = document.createElement('details') detailsEl.className = 'third-party-reward-manager' const summaryEl = document.createElement('summary') summaryEl.textContent = 'reward-system' detailsEl.appendChild(summaryEl) // set a default style. const styleEl = document.createElement('style') styleEl.textContent = ` .third-party-reward-manager { width: 330px; position: absolute; top: 0; right: 0; background: black; z-index: 10000; } .third-party-reward-manager summary { padding: 10px; } .third-party-reward-manager > div { max-height: 600px; overflow: auto; } .third-party-reward-manager input { width: 100%; background: black; color: white; margin: 4px 0; border: 0; padding: 2px 4px; } .tp-reward-button { display: inline-block; width: 100px; text-align: center; overflow: hidden; border: 1px solid #888; } .tp-reward-button:hover, .tp-reward-button:focus { background: #444444; } .tp-reward-button:active { background: #ffffff; color: black; } .tp-reward-button.hidden { display: none; } ` detailsEl.appendChild(styleEl) // Search const inputEl = document.createElement('input') inputEl.placeholder = 'search' inputEl.oninput = function() { const val = inputEl.value.trim() const nameEls = $$('.name', detailsEl) console.log(nameEls) for(const el of nameEls) { const content = el.textContent.toLowerCase() const buttonEl = el.closest('button') if(val == '') { buttonEl.classList.remove('hidden') continue } if(content.indexOf(val) != -1) { buttonEl.classList.remove('hidden') } else { buttonEl.classList.add('hidden') } } } detailsEl.appendChild(inputEl) // div with items const divEl = document.createElement('div') detailsEl.appendChild(divEl) // button items for(const item of dataItems) { const buttonEl = document.createElement('button') buttonEl.className = 'tp-reward-button' const img = document.createElement('img') img.src = item.icon const nameEl = document.createElement('div') nameEl.className = 'name' nameEl.textContent = item.name const costEl = document.createElement('div') costEl.className = 'cost' costEl.textContent = `cost: ${item.cost}` buttonEl.appendChild(img) buttonEl.appendChild(nameEl) buttonEl.appendChild(costEl) divEl.appendChild(buttonEl) buttonEl.onclick = getClickFn(item) } // the main click function functionality for an item. function getClickFn(item) { return async function(e) { $$('[aria-label="Points Balance"]')[0].click() await wait(20) const rewardEl = $$("#channel-points-reward-center-body .reward-list-item")[item.index] const buttonEl = rewardEl.querySelector('button') buttonEl.click() await wait(100) $$('#channel-points-reward-center-body button')[0].click() } } // Add the divEl to the body. document.body.appendChild(detailsEl) } layoutMaker()