Items Page Flower and Plushie Filter and Sort (PDA Optimized)

Grey out irrelevant flowers, move them to the bottom of the list, reorder flowers by quantity, and sort plushies by quantity on Torn's items page.

  1. // ==UserScript==
  2. // @name Items Page Flower and Plushie Filter and Sort (PDA Optimized)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.4
  5. // @description Grey out irrelevant flowers, move them to the bottom of the list, reorder flowers by quantity, and sort plushies by quantity on Torn's items page.
  6. // @match https://www.torn.com/item.php*
  7. // @grant none
  8. // @license MIT
  9. // ==/UserScript==
  10. (function () {
  11. 'use strict';
  12. // List of irrelevant flowers
  13. const irrelevantFlowers = [
  14. "Bunch of Carnations",
  15. "Bunch of Flowers",
  16. "Daffodil",
  17. "Bunch of Black Roses",
  18. "Dozen Roses",
  19. "Funeral Wreath",
  20. "Single Red Rose",
  21. ];
  22. function processItems() {
  23. // Handle Flowers
  24. const flowerItems = Array.from(document.querySelectorAll('#flowers-items > li'));
  25. if (flowerItems.length) {
  26. const relevantFlowers = [];
  27. const irrelevantFlowersList = [];
  28. flowerItems.forEach((item) => {
  29. const itemName = item.querySelector('.name-wrap .name')?.textContent.trim();
  30. const qtyElement = item.querySelector('.item-amount.qty');
  31. const qty = parseInt(qtyElement?.textContent.replace(/[^0-9]/g, '') || 0, 10);
  32. if (!itemName) return;
  33. if (irrelevantFlowers.includes(itemName)) {
  34. // Grey out irrelevant flowers
  35. item.style.opacity = "0.5";
  36. item.style.backgroundColor = "#f9f9f9";
  37. irrelevantFlowersList.push(item);
  38. } else {
  39. relevantFlowers.push({ element: item, quantity: qty });
  40. }
  41. });
  42. // Sort relevant flowers by quantity (ascending)
  43. relevantFlowers.sort((a, b) => a.quantity - b.quantity);
  44. // Append items back to the DOM
  45. const flowerList = document.querySelector('#flowers-items');
  46. if (flowerList) {
  47. relevantFlowers.forEach(({ element }) => flowerList.appendChild(element));
  48. irrelevantFlowersList.forEach((item) => flowerList.appendChild(item));
  49. }
  50. }
  51. // Handle Plushies
  52. const plushieItems = Array.from(document.querySelectorAll('#plushies-items > li'));
  53. if (plushieItems.length) {
  54. const plushies = plushieItems.map((item) => {
  55. const qtyElement = item.querySelector('.item-amount.qty');
  56. const qty = parseInt(qtyElement?.textContent.replace(/[^0-9]/g, '') || 0, 10);
  57. return { element: item, quantity: qty };
  58. });
  59. // Sort plushies by quantity (ascending)
  60. plushies.sort((a, b) => a.quantity - b.quantity);
  61. // Append sorted plushies back to the DOM
  62. const plushieList = document.querySelector('#plushies-items');
  63. if (plushieList) {
  64. plushies.forEach(({ element }) => plushieList.appendChild(element));
  65. }
  66. }
  67. }
  68. // Throttled observer callback for DOM changes
  69. const throttle = (callback, delay) => {
  70. let lastCall = 0;
  71. return (...args) => {
  72. const now = Date.now();
  73. if (now - lastCall >= delay) {
  74. lastCall = now;
  75. callback(...args);
  76. }
  77. };
  78. };
  79. // Set up a MutationObserver for dynamic content updates
  80. const observer = new MutationObserver(
  81. throttle(() => {
  82. processItems();
  83. }, 500)
  84. );
  85. // Observe the list containers for changes
  86. const flowerTargetNode = document.querySelector('#flowers-items');
  87. const plushieTargetNode = document.querySelector('#plushies-items');
  88. if (flowerTargetNode) {
  89. observer.observe(flowerTargetNode, { childList: true, subtree: true });
  90. }
  91. if (plushieTargetNode) {
  92. observer.observe(plushieTargetNode, { childList: true, subtree: true });
  93. }
  94. // Initial run
  95. processItems();
  96. })();