// ==UserScript==
// @name WhatNot Quantity
// @namespace http://tampermonkey.net/
// @version 2024-04-19.002
// @description This is a new description.
// @author You
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// @license MIT
// @match https://www.whatnot.com/dashboard/listings*
// ==/UserScript==
(async function() {
'use strict';
console.log('initting tools')
function createToolsNode() {
var parentNode = document.createElement('div');
parentNode.style.position = 'fixed';
parentNode.style.top = '50%';
parentNode.style.right = '0';
parentNode.style.transform = 'translateY(-50%)';
parentNode.style.backgroundColor = 'green';
parentNode.style.padding = '10px';
parentNode.style.fontSize = '2em'; // 2 times bigger font size
parentNode.style.zIndex = '9000'; // Set a high z-index
document.body.appendChild(parentNode);
return parentNode
}
let toolsNode = createToolsNode()
function createQuantityTool(parentNode) {
console.log('quantity tool is initting')
async function upkeepQuantity() {
while (true) {
if (!isRunning) {
console.log('disabled')
break
}
let tbody = document.querySelectorAll('tbody')[0]
console.log('iterating', tbody, tbody.childNodes)
for (let tr of Array.from(tbody.childNodes).reverse()) {
let availabilityTd = tr.childNodes[4]
let parent = availabilityTd.childNodes[0]
let div = parent.childNodes[0]
if (div.innerText != '0' ) {
//console.log('no', div)
continue
}
div.click()
setTimeout(() => {
let quantity = document.querySelector('[name="quantity"]')
console.log(quantity)
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
'value').set;
console.log('set from', quantity.value, 1)
nativeInputValueSetter.call(quantity, 1);
const event = new Event('input', { bubbles: true });
quantity.dispatchEvent(event);
setTimeout(() => {
let commonParent = quantity.parentNode.parentNode.parentNode.parentNode
let buttons = commonParent.childNodes[1]
let updateButton = buttons.childNodes[1]
console.log('click', quantity.value)
updateButton.click()
}, 1000)
}, 1000)
console.log('sleeping iteration')
await sleep(5000)
}
console.log('sleeping while')
await sleep(1000)
console.log('going to inactive')
document.querySelector('[value="Inactive"]').click()
await sleep(10000)
console.log('going to active')
document.querySelector('[value="Active"]').click()
await sleep(60000)
}
}
// Create a new div for the quantity tool
var quantityDiv = document.createElement('div');
quantityDiv.style.border = '1px solid black'; // Add border
quantityDiv.style.padding = '10px'; // Add padding for spacing
parentNode.appendChild(quantityDiv);
// Add text "Quantity" above the button
var quantityText = document.createElement('div');
quantityText.textContent = 'Quantity';
quantityDiv.appendChild(quantityText);
var button = document.createElement('button');
button.innerHTML = 'Start';
button.style.width = '100px'; // Adjust width as necessary
button.style.height = '50px'; // Adjust height as necessary
button.style.fontSize = '1em'; // Reset font size for button
quantityDiv.appendChild(button);
parentNode.appendChild(quantityDiv)
var isRunning = false;
// Function to start/stop action
function toggleAction() {
let oldIsRunning = isRunning
isRunning = !isRunning;
if (oldIsRunning) {
// Stop action
console.log('Action will be stopped after current cycle');
button.innerHTML = 'Start';
parentNode.style.backgroundColor = 'green'; // Reset background color
// Add your stop action code here
} else {
// Start action
console.log('Action started');
button.innerHTML = 'Stop';
parentNode.style.backgroundColor = 'red'; // Apply green background color
// Add your start action code here
upkeepQuantity()
}
}
// Attach click event listener to the button
button.addEventListener('click', toggleAction);
console.log('quantity tool was init')
}
function createSleepFeedback(parentNode) {
//Time node
var timeNode = document.createElement('div');
timeNode.innerHTML = 'Time left: 0'; // Initial text
parentNode.appendChild(timeNode);// Example function to update the time left text
function updateTimeLeft(time) {
timeNode.innerHTML = 'Time left: ' + time;
}
return (delay) => {
let totalTime = delay / 1000
updateTimeLeft(totalTime)
let intervalId = setInterval(() => {
totalTime -= 0.1
updateTimeLeft(Math.round(totalTime * 10) / 10);
}, 100)
let promise = (new Promise((resolve) => setTimeout(resolve, delay))).then(() => {
clearInterval( intervalId)
updateTimeLeft(0)
})
return promise
}
}
function createDuplicateTool(parentNode) {
// Create a new div for the quantity tool
var parentDiv = document.createElement('div');
parentDiv.style.border = '1px solid black'; // Add border
parentDiv.style.padding = '10px'; // Add padding for spacing
// Add text "Quantity" above the button
var quantityText = document.createElement('div');
quantityText.textContent = 'Duplicate';
parentDiv.appendChild(quantityText);
// Create a text input
const input = document.createElement('input');
input.type = 'text';
input.placeholder = '';
input.style.width = '50px'; // Adjust width as necessary
parentDiv.appendChild(input);
// Create a button
const dButton = document.createElement('button');
dButton.textContent = 'Duplicate';
parentDiv.appendChild(dButton);
var duplicateAmountNode = document.createElement('div');
duplicateAmountNode.innerHTML = 'Items left: 0'; // Initial text
parentDiv.appendChild(duplicateAmountNode);
parentNode.appendChild(parentDiv);
// Add click event listener to the button
dButton.addEventListener('click', async () => {
// Read the value from the input field
let duplicateAmount = parseInt(input.value);
if (duplicateAmount <= 0 || duplicateAmount == NaN) {
console.log('invalid amount', input.value)
return
}
dButton.disabled = true
for (;duplicateAmount >= 1; duplicateAmount--) {
updateDuplicateAmountLeft(duplicateAmount)
await sleep(1000)
let optionsButton = null
while (!optionsButton) {
let buttons = Array.from(document.querySelectorAll('button'))
let optionsButtons = buttons.filter(i => i.innerText == 'Options')
if (optionsButtons.length > 0 && !optionsButtons[0].disabled) {
console.log('options button found', optionsButtons[0])
optionsButton = optionsButtons[0]
} else {
console.log('no options button found')
await sleep(1000)
}
}
await sleep(1000)
optionsButton.click()
let duplicateButton = null
while (!duplicateButton) {
let buttons = Array.from(document.querySelectorAll('a'))
let duplicateButtons = buttons.filter(i => i.textContent.includes("Duplicate listing"))
if (duplicateButtons.length > 0 && !duplicateButtons[0].disabled) {
console.log('duplicate button found', duplicateButtons[0])
duplicateButton = duplicateButtons[0]
} else {
console.log('no duplicate button found')
await sleep(1000)
}
}
await sleep(1000)
duplicateButton.click()
let reviewButton = null
while (!reviewButton) {
let buttons = Array.from(document.querySelectorAll('button'))
let reviewButtons = buttons.filter(i => i.innerText == 'Review Listing')
if (reviewButtons.length > 0 && !reviewButtons[0].disabled) {
console.log('review button found', reviewButtons[0])
reviewButton = reviewButtons[0]
} else {
console.log('no review button found')
await sleep(1000)
}
}
await sleep(1000)
reviewButton.click()
let listButton = null
while (!listButton) {
let buttons = Array.from(document.querySelectorAll('button'))
let listButtons = buttons.filter(i => i.innerText == 'List Now')
if (listButtons.length > 0 && !listButtons[0].disabled) {
console.log('list button found', listButtons[0])
listButton = listButtons[0]
} else {
console.log('no list button found')
await sleep(1000)
}
}
await sleep(1000)
listButton.click()
}
updateDuplicateAmountLeft(0)
dButton.disabled = false
});
// Example function to update the time left text
function updateDuplicateAmountLeft(amount) {
duplicateAmountNode.innerHTML = 'Items left: ' + amount;
}
}
let currentSet = 0
const OBJECTS_KEY = 'boxes_'
function getCurrentObjectsKey() {
return OBJECTS_KEY + currentSet
}
let objects = []
function updateCurrentObjects() {
localStorage.setItem(getCurrentObjectsKey(), JSON.stringify(objects));
}
function loadCurrentObjects() {
objects = JSON.parse(localStorage.getItem(getCurrentObjectsKey()) ?? '[]')
}
loadCurrentObjects()
let currentPrefix = ''
const CURRENT_PREFIX = 'CURRENT_PREFIX'
function updateCurrentPrefix() {
console.log('saving', currentPrefix)
localStorage.setItem(CURRENT_PREFIX, currentPrefix);
}
function loadCurrentPrefix() {
currentPrefix = localStorage.getItem(CURRENT_PREFIX)
}
loadCurrentPrefix()
var editBreakOverlay
function createEditBreakTool(parentNode) {
// Create a new div for the "Edit break" tool
var editBreakSection = document.createElement('div');
editBreakSection.style.border = '1px solid black'; // Add border
editBreakSection.style.padding = '10px'; // Add padding for spacing
// Add text "Quantity" above the button
var quantityText = document.createElement('div');
quantityText.textContent = 'Auctions';
editBreakSection.appendChild(quantityText);
// Create a button for the "Edit break" tool
var editBreakButton = document.createElement('button');
editBreakButton.textContent = 'Edit break';
editBreakButton.addEventListener('click', function() {
toggleOverlay(); // Toggle overlay on button click
});
editBreakSection.appendChild(editBreakButton);
// Create a text input under the "Edit break" button
var breakTextInputDiv = document.createElement('div');
var breakTextInput = document.createElement('input');
breakTextInput.type = 'text';
breakTextInput.style.width = '200px';
breakTextInputDiv.appendChild(breakTextInput);
editBreakSection.appendChild(breakTextInputDiv)
async function changeDescription(value) {
let tbody = document.querySelectorAll('tbody')[0]
console.log('iterating', tbody, tbody.childNodes)
for (let tr of Array.from(tbody.childNodes).reverse()) {
let titleTd = tr.childNodes[1]
let flex = titleTd.childNodes[0]
let flex2 = flex.childNodes[0]
let parent = flex2.childNodes[1]
parent.click()
await sleep(500)
parent.click()
let optionsButton = null
while (!optionsButton) {
let buttons = Array.from(document.querySelectorAll('button'))
let optionsButtons = buttons.filter(i => i.innerText === 'Options')
if (optionsButtons.length > 0 && !optionsButtons[0].disabled) {
console.log('update button found', optionsButtons[0])
optionsButton = optionsButtons[0]
} else {
console.log('no update button found')
await sleep(1000)
}
}
let buttonsParent = optionsButton.parentNode
let editButton = buttonsParent.childNodes[1]
await sleep(250)
editButton.click()
await sleep(250)
let description = null
while (!description) {
description = document.querySelector('input[name="description"]')
if (!description) {
console.log('no description field found')
await sleep(1000)
}
}
console.log(description)
console.log('set from', description.value, value)
description.dispatchEvent(new Event('input', { bubbles: true }));
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
'value').set;
nativeInputValueSetter.call(description, value);
const event = new Event('input', { bubbles: true });
description.dispatchEvent(event);
await sleep(1000)
let reviewButton = null
while (!reviewButton) {
let buttons = Array.from(document.querySelectorAll('button'))
let reviewButtons = buttons.filter(i => i.innerText == 'Review Listing')
if (reviewButtons.length > 0 && !reviewButtons[0].disabled) {
console.log('review button found', reviewButtons[0])
reviewButton = reviewButtons[0]
} else {
console.log('no review button found')
await sleep(1000)
}
}
await sleep(500)
reviewButton.click()
let listButton = null
while (!listButton) {
let buttons = Array.from(document.querySelectorAll('button'))
let listButtons = buttons.filter(i => i.innerText == 'List Now')
if (listButtons.length > 0 && !listButtons[0].disabled) {
console.log('list button found', listButtons[0])
listButton = listButtons[0]
} else {
console.log('no list button found')
await sleep(1000)
}
}
await sleep(500)
listButton.click()
await sleep(500)
}
}
var setDescriptionButton = document.createElement('button');
setDescriptionButton.textContent = 'Set All';
setDescriptionButton.addEventListener('click', function() {
changeDescription(breakTextInput.value); // Toggle overlay on button click
});
editBreakSection.appendChild(setDescriptionButton);
parentNode.appendChild(editBreakSection)
function toggleOverlay() {
editBreakOverlay.style.display = editBreakOverlay.style.display === 'none' ? 'block' : 'none'
}
function createEditBreakOverlay() {
editBreakOverlay = document.createElement('div');
editBreakOverlay.id = 'editBreakOverlay';
editBreakOverlay.style.display = 'none'
editBreakOverlay.style.position = 'fixed';
editBreakOverlay.style.top = '0';
editBreakOverlay.style.left = '0';
editBreakOverlay.style.width = '100%';
editBreakOverlay.style.height = '100%';
editBreakOverlay.style.backgroundColor = 'rgb(0, 0, 0)'; // Semi-transparent black background
editBreakOverlay.style.zIndex = '9999';
var buttonsDiv = document.createElement('div')
buttonsDiv.style.position = 'absolute';
buttonsDiv.style.top = '10px';
buttonsDiv.style.right = '10px';
var closeButton = document.createElement('button');
closeButton.textContent = 'Close';
closeButton.style.display = 'block'
closeButton.addEventListener('click', function() {
toggleOverlay(); // Close overlay on close button click
});
buttonsDiv.appendChild(closeButton);
let prefixDiv = document.createElement('div')
const prefixLabel = document.createElement('label');
prefixLabel.textContent = 'Prefix: ';
prefixLabel.style.color = 'white';
const prefixInput = document.createElement('input');
prefixInput.type = 'text';
prefixInput.value = currentPrefix;
prefixInput.style.width = '250px';
prefixInput.addEventListener('input', () => {
currentPrefix = prefixInput.value;
updateCurrentPrefix()
});
prefixDiv.appendChild(prefixLabel);
prefixDiv.appendChild(prefixInput);
buttonsDiv.appendChild(prefixDiv);
function setDescription() {
let description = currentPrefix + ' '
objects.forEach((object, index) => {
description += `${object.amount} - ${object.name}; `
})
breakTextInput.value = description
}
var setButton = document.createElement('button');
setButton.textContent = 'Set description';
setButton.style.display = 'block'
setButton.addEventListener('click', function() {
setDescription(); // Close overlay on close button click
setTimeout(() => {
console.log('trying to close')
toggleOverlay()
}, 250)
});
buttonsDiv.appendChild(setButton);
editBreakOverlay.appendChild(buttonsDiv);
let setDiv = document.createElement('div')
const presetLabel = document.createElement('label');
presetLabel.textContent = 'Preset: ';
presetLabel.style.color = 'white';
const presetInput = document.createElement('input');
presetInput.type = 'number';
presetInput.value = currentSet;
presetInput.style.width = '35px';
presetInput.addEventListener('input', () => {
currentSet = parseInt(presetInput.value);
loadCurrentObjects();
createObjectInputs()
});
setDiv.appendChild(presetLabel);
setDiv.appendChild(presetInput);
editBreakOverlay.appendChild(setDiv);
let objectsParent = document.createElement('div');
objectsParent.style.display = 'inline-block'; // Make the parent div shrink-wrap its contents
editBreakOverlay.appendChild(objectsParent);
// Create add button
var addButton = document.createElement('button');
addButton.textContent = '+';
addButton.style.position = 'relative';
addButton.addEventListener('click', function() {
addObject();
});
editBreakOverlay.appendChild(addButton);
document.body.appendChild(editBreakOverlay);
function createObjectInputs() {
while (objectsParent.firstChild) {
objectsParent.removeChild(objectsParent.firstChild);
}
objects.forEach((object, index) => {
const objectDiv = document.createElement('div');
objectDiv.style.border = '1px solid black';
objectDiv.style.padding = '10px';
objectDiv.style.marginBottom = '10px';
const nameLabel = document.createElement('label');
nameLabel.textContent = 'Name: ';
nameLabel.style.color = 'white';
const nameInput = document.createElement('input');
nameInput.type = 'text';
nameInput.value = object.name;
nameInput.style.width = '250px';
nameInput.addEventListener('input', () => {
object.name = nameInput.value;
updateCurrentObjects();
});
const amountLabel = document.createElement('label');
amountLabel.textContent = 'Amount: ';
amountLabel.style.color = 'white';
const amountInput = document.createElement('input');
amountInput.type = 'number';
amountInput.value = object.amount;
amountInput.style.width = '35px';
amountInput.addEventListener('input', () => {
object.amount = parseInt(amountInput.value);
updateCurrentObjects();
});
const removeButton = document.createElement('button');
removeButton.textContent = 'Remove';
removeButton.addEventListener('click', () => {
objects.splice(index, 1);
updateCurrentObjects();
createObjectInputs(); // Re-render inputs after removing an object
});
objectDiv.appendChild(nameLabel);
objectDiv.appendChild(nameInput);
objectDiv.appendChild(amountLabel);
objectDiv.appendChild(amountInput);
objectDiv.appendChild(removeButton);
objectsParent.appendChild(objectDiv);
});
}
function addObject() {
objects.push({ name: '', amount: 0 });
updateCurrentObjects();
createObjectInputs();
}
createObjectInputs()
}
createEditBreakOverlay()
}
let sleep = createSleepFeedback(toolsNode)
// Add a dropdown list for selecting tools
function createToolSelector(parentNode) {
var toolSelector = document.createElement('select');
toolSelector.style.marginBottom = '10px'; // Add some margin for spacing
parentNode.appendChild(toolSelector);
var button = document.createElement('button')
button.textContent = 'X'
parentNode.appendChild(button);
button.addEventListener('click', function () {
document.body.removeChild(toolsNode)
})
var toolContainer = document.createElement('div')
parentNode.appendChild(toolContainer);
// Define tool options
var toolOptions = [
{ name: 'Quantity', tool: createQuantityTool },
{ name: 'Duplicate', tool: createDuplicateTool },
{ name: 'Edit Break', tool: createEditBreakTool }
// Add more options as needed
];
// Populate dropdown options
toolOptions.forEach(function(option) {
var optionElement = document.createElement('option');
optionElement.value = option.name;
optionElement.textContent = option.name;
toolSelector.appendChild(optionElement);
});
// Function to hide all tool interfaces
function hideAllToolInterfaces() {
// Remove all child nodes from the parent node
while (toolContainer.firstChild) {
toolContainer.removeChild(toolContainer.firstChild);
}
}
toolSelector.addEventListener('change', function() {
var selectedTool = toolOptions.find(option => option.name === toolSelector.value);
hideAllToolInterfaces()
selectedTool.tool(toolContainer);
});
toolOptions[0].tool(toolContainer)
}
// Call createToolSelector to add the dropdown list
createToolSelector(toolsNode);
// createQuantityTool(toolsNode)
// createDuplicateTool(toolsNode)
//createEditBreakTool(toolsNode)
console.log('tools were init')
})();