Paid for things

New pips!

  1. // ==UserScript==
  2. // @name Paid for things
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.5
  5. // @description New pips!
  6. // @author tharglet
  7. // @match https://myfigurecollection.net/?*mode=view&*tab=collection&*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=myfigurecollection.net
  9. // @grant GM_addStyle
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // ==/UserScript==
  13.  
  14. //Polyfill for GM_addStyle for Greasemonkey...
  15. if(typeof GM_addStyle == 'undefined') {
  16. GM_addStyle = (aCss) => {
  17. 'use strict';
  18. let head = document.getElementsByTagName('head')[0];
  19. if (head) {
  20. let style = document.createElement('style');
  21. style.setAttribute('type', 'text/css');
  22. style.textContent = aCss;
  23. head.appendChild(style);
  24. return style;
  25. }
  26. return null;
  27. };
  28. }
  29.  
  30. GM_addStyle(`
  31. .item-custompip {
  32. display: block;
  33. position: absolute;
  34. right: 1px;
  35. bottom: 1px;
  36. height: 16px;
  37. padding: 1px 2px 2px 3px;
  38. line-height: 16px;
  39. color: white;
  40. }
  41.  
  42. .item-is-paid {
  43. background-color: green;
  44. }
  45.  
  46. .item-is-shipped {
  47. background-color: gold;
  48. }
  49.  
  50. .item-is-stored {
  51. background-color: orangered;
  52. }
  53.  
  54. .icon-dollar:before {
  55. font-family: serif !important;
  56. content: "$";
  57. font-weight: bolder !important;
  58. }
  59.  
  60. .icon-plane:before {
  61. font-family: serif !important;
  62. content: "🛩️";
  63. font-weight: bolder !important;
  64. }
  65.  
  66. .icon-stored:before {
  67. font-family: serif !important;
  68. content: "🏭";
  69. font-weight: bolder !important;
  70. }
  71. `);
  72.  
  73. (async function() {
  74. 'use strict';
  75.  
  76. const parser = new DOMParser();
  77.  
  78. const appendPip = (itemClassName, pipClassName, itemElement) => {
  79. const shippedPipContainer = document.createElement('span');
  80. shippedPipContainer.classList.add('item-custompip', itemClassName);
  81. const shippedPip = document.createElement('span');
  82. shippedPip.classList.add('tiny-icon-only', pipClassName);
  83. shippedPipContainer.appendChild(shippedPip);
  84. itemElement.appendChild(shippedPipContainer);
  85. };
  86.  
  87. const isUsersPreorderPage = () => {
  88. const urlParams = new URLSearchParams(window.location.search);
  89. const status = urlParams.get("status");
  90. if(status == 1) {
  91. let loggedInUser = document.querySelector(".user-menu .handle");
  92. if(loggedInUser) {
  93. let userLink = loggedInUser.getAttribute("href");
  94. if(userLink === "/session/signup") {
  95. return false;
  96. } else {
  97. let userParam;
  98. const windowLocation = window.location.href;
  99. if(windowLocation.startsWith("https://myfigurecollection.net/profile/")) {
  100. userParam = windowLocation.match(/https:\/\/myfigurecollection\.net\/profile\/([^\/]*)/)[1];
  101. } else {
  102. const urlParams = new URLSearchParams(window.location.search);
  103. userParam = urlParams.get("username");
  104. }
  105. return userParam === userLink.substring("9");
  106. }
  107. } else {
  108. return false;
  109. }
  110. } else {
  111. return false;
  112. }
  113. };
  114.  
  115. const processPage = (parsedHtml) => {
  116. const foundItems = [];
  117. const items = parsedHtml.querySelectorAll('.row.tbx-checkable-row .cell:nth-child(2) a');
  118. if(items) {
  119. items.forEach((item) => {
  120. foundItems.push(item.getAttribute('href'));
  121. });
  122. }
  123. return foundItems;
  124. };
  125.  
  126. const processStoredPage = (parsedHtml) => {
  127. const foundItems = [];
  128. const isStoredCells = parsedHtml.querySelectorAll('.row.tbx-checkable-row .cell:nth-child(9)');
  129. if(isStoredCells) {
  130. isStoredCells.forEach((isStoredItem) => {
  131. if(isStoredItem.textContent.includes('Stored')) {
  132. const itemLink = isStoredItem.parentElement.querySelector('.cell:nth-child(2) a');
  133. foundItems.push(itemLink.getAttribute('href'));
  134. }
  135. });
  136. }
  137. return foundItems;
  138. };
  139.  
  140. const getPageCount = (parsedHtml) => {
  141. const itemCount = parsedHtml.querySelector('.results-count-value');
  142. const pageCountMatch = itemCount.innerText.match(/^(\d+)/);
  143. return Math.floor(parseInt(pageCountMatch[0], 10) / 50) + 1;
  144. };
  145.  
  146. const processItems = async (url, pageProcessor) => {
  147. const foundItems = [];
  148. let pageCount = 0;
  149. await fetch(url + '&page=1').then((response) => {
  150. return response.text();
  151. }).then((html) => {
  152. const parsedHtml = parser.parseFromString(html, 'text/html');
  153. Array.prototype.push.apply(foundItems, pageProcessor(parsedHtml));
  154. pageCount = getPageCount(parsedHtml);
  155. }).catch(function (err) {
  156. console.warn('Something went wrong.', err);
  157. });
  158. if (pageCount > 1) {
  159. for(let page = 2; page < pageCount + 1; page++) {
  160. await fetch(url + '&page=' + page).then((response) => {
  161. return response.text();
  162. }).then((html) => {
  163. const parsedHtml = parser.parseFromString(html, 'text/html');
  164. Array.prototype.push.apply(foundItems, pageProcessor(parsedHtml));
  165. }).catch(function (err) {
  166. console.warn('Something went wrong.', err);
  167. });
  168. }
  169. }
  170. return foundItems;
  171. };
  172.  
  173. if(isUsersPreorderPage()) {
  174. const paidItems = await processItems('/?mode=collection&tab=ordered&current=keywords&output=sheet&isPaid=1&_tb=manager', processPage);
  175. const storedItems = await processItems('/?mode=collection&tab=ordered&output=sheet&_tb=manager', processStoredPage);
  176. const shippedItems = await processItems('/?mode=collection&tab=ordered&current=keywords&output=sheet&isShipped=1&_tb=manager', processPage);
  177.  
  178. const itemIcons = document.querySelectorAll('.item-icon a');
  179. itemIcons.forEach((item) => {
  180. if(shippedItems.includes(item.getAttribute('href'))) {
  181. appendPip('item-is-shipped', 'icon-plane', item);
  182. } else if(storedItems.includes(item.getAttribute('href'))) {
  183. appendPip('item-is-stored', 'icon-stored', item);
  184. } else if(paidItems.includes(item.getAttribute('href'))) {
  185. appendPip('item-is-paid', 'icon-dollar', item);
  186. }
  187. });
  188. }
  189. })();