BaseTao - GL/RL extension

Mark the items you want to keep or return

  1. // ==UserScript==
  2. // @name BaseTao - GL/RL extension
  3. // @namespace https://www.reddit.com/user/RobotOilInc
  4. // @version 1.0.2
  5. // @description Mark the items you want to keep or return
  6. // @author RobotOilInc
  7. // @match https://www.basetao.com/index/myhome/myorder/arrived.html
  8. // @match https://basetao.com/index/myhome/myorder/arrived.html
  9. // @grant GM_addStyle
  10. // @grant GM_getResourceText
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @license MIT
  14. // @homepageURL https://gf.qytechs.cn/en/scripts/432121-basetao-gl-rl-extension
  15. // @supportURL https://gf.qytechs.cn/en/scripts/432121-basetao-gl-rl-extension
  16. // @require https://unpkg.com/sweetalert2@11/dist/sweetalert2.js
  17. // @require https://unpkg.com/js-logger@1.6.1/src/logger.js
  18. // @require https://unpkg.com/jquery@3.6.0/dist/jquery.js
  19. // @resource sweetalert2 https://unpkg.com/sweetalert2@11.0.15/dist/sweetalert2.min.css
  20. // @run-at document-end
  21. // ==/UserScript==
  22.  
  23. // Define default toast
  24. const Toast = Swal.mixin({
  25. showConfirmButton: false,
  26. timerProgressBar: true,
  27. position: 'top-end',
  28. timer: 4000,
  29. toast: true,
  30. didOpen: (toast) => {
  31. toast.addEventListener('mouseenter', Swal.stopTimer);
  32. toast.addEventListener('mouseleave', Swal.resumeTimer);
  33. },
  34. });
  35.  
  36. /**
  37. * @param text {string}
  38. * @param type {null|('success'|'error'|'warning'|'info')}
  39. */
  40. const Snackbar = function (text, type = null) {
  41. Toast.fire({ title: text, icon: type != null ? type : 'info' });
  42. };
  43.  
  44. const STATES = Object.freeze({
  45. GREEN_LIGHT: 'green_light',
  46. RED_LIGHT: 'red_light',
  47. });
  48.  
  49. class Storage {
  50. get(orderId) {
  51. return GM_getValue(orderId, null);
  52. }
  53.  
  54. exists(orderId) {
  55. return this.get(orderId) !== null;
  56. }
  57.  
  58. set(orderId, state) {
  59. if (!Object.values(STATES).includes(state)) {
  60. throw new Error('Invalid state has been passed');
  61. }
  62.  
  63. return GM_setValue(orderId, state);
  64. }
  65. }
  66.  
  67. class BaseTaoElement {
  68. constructor($element) {
  69. this.object = $element;
  70.  
  71. // eslint-disable-next-line prefer-destructuring
  72. this.orderId = $element.find('td:nth-child(7) > ul:nth-child(3) > li > a').first().attr('href').trim().match(/itemimg\/(\d+)\.html/)[1];
  73. }
  74. }
  75.  
  76. class BaseTao {
  77. constructor() {
  78. // Ensure the toast looks decent on Basetao
  79. GM_addStyle('.swal2-popup.swal2-toast .swal2-title {font-size: 1.5em; font-weight: bolder}');
  80.  
  81. // Get the username
  82. const username = $('#dropdownMenu1').text();
  83. if (typeof username === 'undefined' || username == null || username === '') {
  84. Snackbar('You need to be logged in to use this extension.');
  85.  
  86. return this;
  87. }
  88.  
  89. this.storage = new Storage();
  90.  
  91. return this;
  92. }
  93.  
  94. /**
  95. * @return {Promise<void>}
  96. */
  97. async process() {
  98. // Make copy of the current this, so we can use it later
  99. const agent = this;
  100.  
  101. // Get the container
  102. const $container = $('.myparcels-ul').first();
  103.  
  104. // Add icons to all elements
  105. $container.find('.tr-bodnone').each(function () {
  106. agent._buildElement($(this));
  107. });
  108. }
  109.  
  110. /**
  111. * @private
  112. * @param $this
  113. * @return {Promise<BaseTaoElement>}
  114. */
  115. async _buildElement($this) {
  116. const element = new BaseTaoElement($this);
  117. const agent = this;
  118.  
  119. const $marker = $('<ul class="gl-rl" style="min-width: 4em;padding: 0;border: 1px black dotted;"><li style="width: 100%;text-align: center;"></li></ul>');
  120. $this.find('td:nth-child(6)').append($marker);
  121.  
  122. const $gl = $('<span style="width: 49%;padding: 2px;font-weight: bold;" title="Green light">✔️</span>');
  123. const $rl = $('<span style="width: 49%;padding: 2px;font-weight: bold;" title="Red light">🛑</span>');
  124. const $swap = $('<span style="width: 49%;cursor: pointer;padding: 2px;font-weight: bold;" title="Swap">🔁</span>');
  125.  
  126. // Always assign the click to swap, because it doesn't matter
  127. $swap.on('click', () => {
  128. if (this.storage.get(element.orderId) === STATES.GREEN_LIGHT) {
  129. this.storage.set(element.orderId, STATES.RED_LIGHT);
  130. Snackbar('Swapped to RL!');
  131.  
  132. // Remove and rebuild
  133. $marker.remove();
  134. agent._buildElement($this);
  135.  
  136. return;
  137. }
  138.  
  139. if (this.storage.get(element.orderId) === STATES.RED_LIGHT) {
  140. this.storage.set(element.orderId, STATES.GREEN_LIGHT);
  141. Snackbar('Swapped to GL!');
  142.  
  143. // Remove and rebuild
  144. $marker.remove();
  145. agent._buildElement($this);
  146. }
  147. });
  148.  
  149. // If it already exists, show swap or gl/rl without pointers
  150. if (this.storage.exists(element.orderId)) {
  151. if (this.storage.get(element.orderId) === STATES.GREEN_LIGHT) {
  152. $marker.find('li').append($gl);
  153. }
  154.  
  155. if (this.storage.get(element.orderId) === STATES.RED_LIGHT) {
  156. $marker.find('li').append($rl);
  157. }
  158.  
  159. $marker.find('li').append($swap);
  160.  
  161. return element;
  162. }
  163.  
  164. // Make the spans pointers
  165. $gl.css('cursor', 'pointer');
  166. $rl.css('cursor', 'pointer');
  167.  
  168. $gl.on('click', () => {
  169. this.storage.set(element.orderId, STATES.GREEN_LIGHT);
  170. Snackbar('GL, good stuff!');
  171.  
  172. // Remove and rebuild
  173. $marker.remove();
  174. agent._buildElement($this);
  175. });
  176.  
  177. $rl.on('click', () => {
  178. this.storage.set(element.orderId, STATES.RED_LIGHT);
  179. Snackbar('RL? Sucks to suck');
  180.  
  181. // Remove and rebuild
  182. $marker.remove();
  183. agent._buildElement($this);
  184. });
  185.  
  186. $marker.find('li').append($gl, $rl);
  187.  
  188. return element;
  189. }
  190. }
  191.  
  192. // Inject snackbar css style
  193. GM_addStyle(GM_getResourceText('sweetalert2'));
  194.  
  195. // eslint-disable-next-line func-names
  196. (async function () {
  197. // Setup the logger.
  198. Logger.useDefaults();
  199.  
  200. // Log the start of the script.
  201. Logger.info(`Starting extension '${GM_info.script.name}', version ${GM_info.script.version}`);
  202.  
  203. // Start building the GL/RL list
  204. try {
  205. await new BaseTao().process();
  206. } catch (error) {
  207. Snackbar(`An unknown issue has occurred when trying to setup the extension: ${error.message}`);
  208. Logger.error('An unknown issue has occurred', error);
  209. }
  210. }());

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址