Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Neopets Inventory Direct Quick Stockinator
- // @namespace http://tampermonkey.net/
- // @version 1.6 [28/5/26]
- // @description Quick Stock interface directly from inventory
- // @author Rippy
- // @icon https://www.google.com/s2/favicons?sz=64&domain=neopets.com
- // @include *://*.neopets.com/inventory.phtml*
- // @grant unsafeWindow
- // @grant GM_setValue
- // @grant GM_getValue
- // ==/UserScript==
- /* ========================= INSTRUCTIONS =========================
- - Adds a new menu to the top of the inventory page to start quickstock selection
- - Click on items to select/deselect them, then pick an action button (stock/deposit/discard/etc)
- - Unlike regular quickstock, you can only do one action at a time but you get a nicer visual interface I guess
- - Donate and Discard will prompt a confirmation before proceeding
- - If your selection includes some invalid items for your action choice e.g. picking a mix of wearables and nonwearables and then clicking Place in Closet should only move the wearables,
- leaving the nonwearables behind
- - If the entire selection is invalid for the action e.g. picking only nonwearables and then clicking Place in Closet should prompt an error pop-up
- - Tick the Bulk Select option to select a ton of items at once, similar to "Check All". When you click on an unselected item, that item and everything to its left will automatically be selected.
- Clicking on a selected item will deselect that item only. This option is useful if you have a group of default items you always want in your inventory e.g. a bunch of Pant Devil Attractors,
- so you can just click on the item to its left and quickstock everything past that point without touching those default items.
- - If you want "Check All" functionality, just use Bulk Select and click on the bottom right-most item and that will naturally select everything.
- - Probably works best in unstacked view, but should also work in stacked view although obviously you won't be able to access multiples of an item.
- - Also works in NC view.
- - NOTE: When discarding NC items, make sure your PIN requirement for NC discarding is disabled. Additionally, only one item can be discarded at a time due to Neopets's internal limitations.
- - v1.1: Now saves your inventory preference of stacked vs unstacked, even after closing the page
- - v1.2: Minor support for smaller screen sizes
- - v1.3: Update to support quickstocking within inventory categories/tabs
- - v1.4: Make the quickstock button smaller and less intrusive
- - v1.5: Include ref_ck value as part of request payload
- - v1.6: Added some support for discarding NC items
- ================================================================
- */
- (function() {
- 'use strict';
- $(".inv-title-container").before('<div class="buttonpad"><input id="toggleqs"type="submit" value="Start Quick Stock" class="button-default__2020 button-green__2020"></div>');
- $(".inv-title-container").after('<div id="quickstock-menu"></div><br>');
- let quickstocking = false;
- let selected = [];
- let isNC = false;
- let bulkSelect = GM_getValue("quickStockBulkSelect", false);
- let displaySettings = GM_getValue("displaySettings", {type: "np", filter: "", action: "0", stack: "1"});
- const moveLimit = 70;
- const ref_ck = document.body.innerHTML.match(/"_ref_ck":'(.+)'/)[1];
- function updateBulkSelect() {
- if ($("#bulkSelectCheck").length) {
- bulkSelect = $("#bulkSelectCheck").is(":checked");
- GM_setValue("quickStockBulkSelect", bulkSelect);
- }
- }
- function selectItem(id, objid) { // clean this up (that will probably never happen)
- const inventoryTab = document.getElementById("invDisplay").dataset.action;
- const targetDisplay = `#invDisplay${parseInt(inventoryTab)+1}`; // which inventory display is active e.g. Full Inventory/Food/Books/Wearable etc.
- if (bulkSelect) {
- const items = $(targetDisplay).find(".grid-item > .item-img");
- console.log("action: " + inventoryTab);
- for (let i in items) {
- const did = items[i].getAttribute("id");
- const oid = items[i].getAttribute("data-objid");
- if (oid == objid && selected.includes(objid)) { // if the item that was directly clicked on was already selected
- selected.splice(selected.indexOf(objid), 1); // deselect that item only
- $(`#selected-item-${did}`).remove();
- }
- else if (!selected.includes(oid)) {
- selected.push(oid);
- // this convoluted thing is necessary to target the right item id div within the right invDisplay to place the checkmark on, because those item id divs are duplicated across ALL invDisplay divs and are just hidden, so depending on how the page loads the selector may not pick the right one if you just do $(#id)
- $(`${targetDisplay} > #tableRowsId > .grid-item > #${did}`).after(`<div id='selected-item-${did}' style='background-position: top; background-repeat: no-repeat; width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2; background-image: url(https://images.neopets.com/neggfest/y23/np/negg-found.svg); background-size: 80%;'></div>`);
- $(`#selected-item-${did}`).attr("onclick", `selectItem('${did}', '${oid}')`);
- }
- if (oid == objid) {
- break;
- }
- }
- console.log(selected.length);
- }
- else {
- if (!selected.includes(objid)) {
- selected.push(objid);
- $(`${targetDisplay} > #tableRowsId > .grid-item > #${id}`).after(`<div id='selected-item-${id}' style='background-position: top; background-repeat: no-repeat; width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2; background-image: url(https://images.neopets.com/neggfest/y23/np/negg-found.svg); background-size: 80%;'></div>`);
- $(`#selected-item-${id}`).attr("onclick", `selectItem('${id}', '${objid}')`);
- }
- else {
- selected.splice(selected.indexOf(objid), 1);
- $(`#selected-item-${id}`).remove();
- }
- }
- }
- function quickStockAction(act, confirm=false) {
- console.log(act);
- const actions = ['stock', 'deposit', 'donate', 'discard', 'gallery', 'closet', 'shed', 'chamber'];
- if (!actions.includes(act)) {
- return;
- }
- if (['donate', 'discard'].includes(act) && !confirm) {
- return;
- }
- if (!selected.length) {
- return;
- }
- const payload = {
- items: [],
- cashItems: [],
- _ref_ck: ref_ck
- };
- selected = selected.slice(0, moveLimit);
- for (let i = 0; i < selected.length; i++) {
- if (isNC) {
- payload.cashItems.push({cashObjId: parseInt(selected[i]), action: act});
- }
- else {
- payload.items.push({objId: parseInt(selected[i]), action: act});
- }
- }
- if (act === "discard" && isNC) {
- $.ajax({
- type: "POST",
- url: "/np-templates/views/process_cash_object.phtml",
- data: {
- cash_obj_id: payload.cashItems[0].cashObjId,
- action: "drop",
- confirm: "1"
- },
- dataType: "html",
- success: function (response) {
- console.log("Successfully discarded NC item");
- window.location.href = "inventory.phtml";
- },
- error: function () {
- console.log("Error");
- alert("Failed to discard NC item!");
- },
- complete: function () {
- $("#invResult").find(".popup-footer__2020").show();
- }
- });
- }
- else {
- fetch("/np-templates/ajax/process_quickstock.php", {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(payload),
- })
- .then(function(resp) { return resp.json(); })
- .then(function(data) {
- if (data.success) {
- console.log(data.message);
- window.location.href = "inventory.phtml";
- } else {
- console.log(data.message);
- alert("This action is not applicable to any of the selected items!");
- }
- })
- .catch(function() {
- console.log("oops");
- });
- }
- }
- function discardConfirm(act) {
- if (!selected.length) {
- return;
- }
- const msg = `Warning! You are about to ${act.toUpperCase()} ${selected.length} item(s)! Are you sure?`;
- if (!confirm(msg)) {
- return;
- }
- quickStockAction(act, true);
- }
- const inventorySetup = () => {
- const items = $("#invDisplay").find(".grid-item > .item-img");
- if (!items.length) {
- return false;
- }
- items.each((i, e) => {
- const id = e.getAttribute("id");
- const objid = e.getAttribute("data-objid");
- e.setAttribute("onclick", quickstocking ? `invView2('${id}');` : `selectItem('${id}', '${objid}')`);
- });
- isNC = document.getElementById("invDisplay").dataset.type === "nc";
- return true;
- };
- const resetQuickStock = () => {
- $("#toggleqs").attr("class", "button-default__2020 button-green__2020");
- $("#toggleqs").attr("value", "Start Quick Stock");
- $("[id^='selected-item']").remove();
- $("#quickstock-buttons").remove();
- $("#bulkSelect").remove();
- selected = [];
- quickstocking = false;
- };
- const startQuickStock = () => {
- $("#toggleqs").attr("class", "button-default__2020 button-red__2020");
- $("#toggleqs").attr("value", "Cancel Quick Stock");
- $("#quickstock-menu").append(`<div id='bulkSelect'><p style=\"font-family:'CafeteriaBlack'; font-size: 17px; text-align: center;\">Bulk Select?<input type='checkbox' id='bulkSelectCheck' onClick='updateBulkSelect()'/></p></div>
- <div id="quickstock-buttons" class="inv-menubar">
- <ul class="inv-menulinks" style="margin-bottom: 0px !important; background: rgba(0,0,0,0);">
- <li style='width:12.5%'><input class="action-deposit button-default__2020 button-blue__2020" type="submit" value="Deposit"></li>
- <li style='width:12.5%'><input class="action-closet button-default__2020 button-blue__2020" type="submit" value="Place in Closet"></li>
- <li style='width:12.5%'><input class="action-stock button-default__2020 button-blue__2020" type="submit" value="Stock in Shop"></li>
- <li style='width:12.5%'><input class="action-gallery button-default__2020 button-blue__2020" type="submit" value="Place in Gallery"></li>
- <li style='width:12.5%'><input class="action-shed button-default__2020 button-blue__2020" type="submit" value="Place in Shed"></li>
- <li style='width:12.5%'><input class="action-chamber button-default__2020 button-blue__2020" type="submit" value="Place in Chamber"></li>
- <li style='width:12.5%'><input class="action-donate button-default__2020 button-red__2020" type="submit" value="Donate"></li>
- <li style='width:12.5%'><input class="action-discard button-default__2020 button-red__2020" type="submit" value="Discard"></li>
- </ul>
- <ul class="inv-menulinks mobile" style="margin-bottom: 0px !important; background: rgba(0,0,0,0);">
- <li style='width:10%'><input class="action-deposit button-default__2020 button-blue__2020" type="submit" value="SDB"></li>
- <li style='width:10%'><input class="action-closet button-default__2020 button-blue__2020" type="submit" value="Closet"></li>
- <li style='width:10%'><input class="action-stock button-default__2020 button-blue__2020" type="submit" value="Shop"></li>
- <li style='width:10%'><input class="action-gallery button-default__2020 button-blue__2020" type="submit" value="Gallery"></li>
- <li style='width:10%'><input class="action-shed button-default__2020 button-blue__2020" type="submit" value="Shed"></li>
- <li style='width:10%'><input class="action-chamber button-default__2020 button-blue__2020" type="submit" value="Style"></li>
- <li style='width:10%'><input class="action-donate button-default__2020 button-red__2020" type="submit" value="Donate"></li>
- <li style='width:10%'><input class="action-discard button-default__2020 button-red__2020" type="submit" value="Discard"></li>
- </ul>
- </div>`);
- $(".action-stock").attr("onclick", `quickStockAction("stock")`);
- $(".action-deposit").attr("onclick", `quickStockAction("deposit")`);
- $(".action-gallery").attr("onclick", `quickStockAction("gallery")`);
- $(".action-closet").attr("onclick", `quickStockAction("closet")`);
- $(".action-shed").attr("onclick", `quickStockAction("shed")`);
- $(".action-chamber").attr("onclick", `quickStockAction("chamber")`);
- $(".action-donate").attr("onclick", `discardConfirm("donate")`);
- $(".action-discard").attr("onclick", `discardConfirm("discard")`);
- $("#bulkSelectCheck").prop("checked", bulkSelect);
- };
- const toggleQuickStock = () => {
- if (!inventorySetup()) {
- return;
- }
- quickstocking = !quickstocking;
- if (quickstocking) {
- startQuickStock();
- }
- else {
- resetQuickStock();
- }
- };
- const _toggleInvFilter2 = toggleInvFilter2;
- toggleInvFilter2 = (filterid, filtervalue) => {
- resetQuickStock();
- _toggleInvFilter2(filterid, filtervalue);
- const data = document.getElementById("invDisplay").dataset;
- displaySettings = {type: data.type, filter: data.filter, action: data.action, stack: data.stack};
- GM_setValue("displaySettings", displaySettings);
- console.log(JSON.stringify(displaySettings));
- };
- const observer = new MutationObserver(() => {
- observer.disconnect();
- if (displaySettings.stack != document.getElementById("invDisplay").dataset.stack) {
- console.log("Swapping to stored stack preference");
- _toggleInvFilter2(4);
- }
- });
- observer.observe(document.querySelector("#invDisplay"), {childList: true, subtree: true});
- $("#toggleqs").click(toggleQuickStock);
- unsafeWindow.selectItem = selectItem; // page needs access to these
- unsafeWindow.quickStockAction = quickStockAction;
- unsafeWindow.discardConfirm = discardConfirm;
- unsafeWindow.updateBulkSelect = updateBulkSelect;
- const style = document.createElement("style");
- style.innerHTML = `
- #toggleqs {
- width: 150px;
- position: absolute;
- left: 3%;
- top: 5px;
- }
- @media screen and (max-width:950px) {
- #toggleqs {
- position: relative;
- margin: auto;
- left: unset;
- }
- .buttonpad {
- padding: 10px;
- }
- }`;
- document.head.appendChild(style);
- })();
Advertisement
Add Comment
Please, Sign In to add comment