Cart - Flip

Опции для корзины

  1. // ==UserScript==
  2. // @name Cart - Flip
  3. // @namespace scriptomatika
  4. // @author mouse-karaganda
  5. // @description Опции для корзины
  6. // @license MIT
  7. // @include https://*flip.kz/cart*
  8. // @include https://light.mail.ru/message/*
  9. // @require https://greasyfork.org/scripts/379902-include-tools/code/Include%20Tools.js
  10. // @version 1.8
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. const $ = window.jQuery;
  16. const $$ = window.__krokodil;
  17.  
  18. class WhereIs {
  19. static get inFlipKz() {
  20. return /flip\.kz\//.test(location.href);
  21. }
  22. static get inMailRu() {
  23. return /mail\.ru\//.test(location.href);
  24. }
  25. }
  26.  
  27. let runInFlipKz = function() {
  28. if (!WhereIs.inFlipKz) {
  29. return;
  30. }
  31.  
  32. $$.renderStyle(
  33. '.unavailable_frame { position: fixed; bottom: 0; right: 0; padding: 5px 0 5px 5px; border-radius: 10px 0 0 0; background-color: rgba(10, 121, 213, 0.9); }',
  34. '.product_frame { display: inline-block; }',
  35. '.product_frame > div { display: inline-block; }',
  36. '.product_frame img { width: 32px; border-radius: 5px; }',
  37. '.product_position { margin-left: 10px; color: white; font-size: 12px; }'
  38. );
  39.  
  40. let cartList;
  41.  
  42. let unavailableFrame = $('<div class="unavailable_frame" />').appendTo(document.body);
  43. let innerDiv = $('<div />').appendTo(unavailableFrame);
  44.  
  45. $('<a class="nbtn gray small m-r-10" />').appendTo(innerDiv).text('К недоступному')
  46. .on('click', function(event) {
  47. let listExists = (cartList && cartList.length > 0);
  48. let viewRow = (listExists) ? cartList[0].row : $('#module-cart .row').last();
  49. //viewRow.get(0).scrollIntoView();
  50. $('body, html').stop().animate({ scrollTop: viewRow.offset().top }, 300);
  51. });
  52.  
  53. $('<a class="nbtn gray small m-r-10" />').appendTo(innerDiv).text('Открыть 3')
  54. .on('click', function(event) {
  55. let period = 500;
  56. setTimeout(function() {
  57. window.open('', 'manual_postpone0', 'width=450,height=300,left=0,top=0');
  58. }, 1);
  59. setTimeout(function() {
  60. window.open('', 'manual_postpone1', 'width=450,height=300,left=455,top=0');
  61. }, period);
  62. setTimeout(function() {
  63. window.open('', 'manual_postpone2', 'width=450,height=300,left=910,top=0');
  64. }, period * 2);
  65. });
  66.  
  67. let position = {
  68. auto: {
  69. timer: 0,
  70. index: 0,
  71. length: 0
  72. },
  73. cart: {
  74. index: 0,
  75. length: 0
  76. },
  77. postponed: {
  78. page: 0,
  79. length: 0
  80. }
  81. };
  82.  
  83. let autoClickInCart = function() {
  84. if (position.auto.index >= position.auto.length) {
  85. clearInterval(position.auto.timer);
  86. return;
  87. }
  88. $('.postpone_frame .nbtn', cartList[position.auto.index].row).get(0).click();
  89. position.auto.index++;
  90.  
  91. // Предложим продолжить или прервать
  92. if ((position.auto.index < position.auto.length) && (position.auto.index % 3 == 0)) {
  93. if (confirm(`Открыто ${position.auto.index} / ${position.auto.length}.\nПрервать?`)) {
  94. clearInterval(position.auto.timer);
  95. }
  96. }
  97. };
  98.  
  99. $('<a class="nbtn gray small m-r-10" />').appendTo(innerDiv).text('Перекликать')
  100. .on('click', function(event) {
  101. let listExists = (cartList && cartList.length > 0);
  102. if (!listExists) {
  103. return;
  104. }
  105. position.auto.length = cartList.length;
  106. position.auto.index = 0;
  107. position.auto.timer = setInterval(autoClickInCart, 500);
  108. });
  109.  
  110. let productFrame = {
  111. clear: function() {
  112. this.outer.empty();
  113. this.outer.removeAttr('title');
  114. this.outer.addClass('m-r-10');
  115. },
  116. createAgain: function() {
  117. this.clear();
  118.  
  119. let div = $('<div />').appendTo(productFrame.outer);
  120. this.img = $('<img />').appendTo(div);
  121.  
  122. div = $('<div class="product_position" />').appendTo(productFrame.outer);
  123. this.name = $('<div />').appendTo(div);
  124. this.cartIndex = $('<div />').appendTo(div);
  125. this.postponedPage = $('<div />').appendTo(div);
  126. },
  127. setImg: function(product) {
  128. this.img.attr({
  129. src: product.img,
  130. alt: product.id
  131. });
  132. },
  133. setName: function(product) {
  134. this.name.text(product.name.substring(0, 5) + '…');
  135. this.outer.attr('title', product.name);
  136. },
  137. setCartIndex: function() {
  138. this.cartIndex.text(`товар ${position.cart.index + 1} / ${position.cart.length}`);
  139. },
  140. setPostponedPage: function() {
  141. this.postponedPage.text(`стр ${position.postponed.page + 1} / ${position.postponed.length}`);
  142. }
  143. };
  144.  
  145. let postponedList = [];
  146.  
  147. let findInPostponedList = function(productId) {
  148. let postponedPage = 0;
  149. };
  150.  
  151. let currentIndex, maxIndex;
  152. let currentPage, maxPage;
  153.  
  154. let requestPostponedItem = function() {
  155.  
  156. let product = cartList[position.cart.index].product;
  157.  
  158. productFrame.createAgain();
  159. productFrame.setImg(product);
  160. productFrame.setName(product);
  161. productFrame.setCartIndex();
  162. productFrame.setPostponedPage();
  163. return;
  164.  
  165. currentIndex++;
  166. if (currentIndex >= maxIndex)
  167. return;
  168.  
  169. $.get('/user?personalis=coming&page=' + currentPage, function(data) {
  170. let rowList = $('.table.goods .row', data);
  171. console.log('AJAX rowList == ', rowList);
  172. });
  173. };
  174.  
  175. $('<a class="nbtn gray small m-r-10" />').appendTo(innerDiv).text('Проверить')
  176. .on('click', function(event) {
  177. let listExists = (cartList && cartList.length > 0);
  178. if (!listExists) {
  179. alert('Недоступного нет');
  180. return;
  181. }
  182. position.cart.length = cartList.length;
  183. position.cart.index = 0;
  184.  
  185. // Получить список ожидаемых постранично до тех пор, пока не найдем нужный товар
  186. requestPostponedItem();
  187. });
  188.  
  189. productFrame.outer = $('<div class="product_frame" />').appendTo(innerDiv);
  190.  
  191. class ProductRow {
  192. constructor(rowElem) {
  193. this.row = $(rowElem);
  194. if (this.isCartPage) {
  195. this.delivery = $('label + div + div', rowElem);
  196. }
  197. }
  198. get isCartPage() {
  199. return /\/cart\b/.test(location.href);
  200. }
  201. get isUnavailable() {
  202. if (this.delivery) {
  203. return this.delivery.text().includes('Недоступен для заказа');
  204. }
  205. return false;
  206. }
  207. get product() {
  208. if (!this._product) {
  209. let catalogElem = $('a[href^="/catalog?prod="]', this.row);
  210. this._product = {
  211. id: catalogElem.attr('href').match(/prod=(\d+)/)[1],
  212. img: catalogElem.children('img').attr('src'),
  213. name: catalogElem.text()
  214. };
  215. }
  216. return this._product;
  217. }
  218. addPostponeFrame(winIndex) {
  219. this.row.addClass('add_postpone_row');
  220.  
  221. let div = $('<div class="postpone_frame" />').appendTo(this.delivery);
  222.  
  223. let btnDoPostpone = $('<a class="nbtn gray small" />').appendTo(div).text('Отложить')
  224. .attr({
  225. target: 'manual_postpone' + winIndex,
  226. href: '/subscribe?type=preorder&action=add&id=' + this.product.id
  227. })
  228. .on('click', function(event) {
  229. setTimeout(function() {
  230. $('<span />').text(' ✅ ').insertAfter(btnDoPostpone);
  231. }, 500);
  232. });
  233. }
  234. }
  235.  
  236. cartList = $('#module-cart .table.goods:first-child .row')
  237. .filter(function(index) {
  238. let prow = new ProductRow(this);
  239. return prow.isUnavailable;
  240. })
  241. .map(function(index) {
  242. let prow = new ProductRow(this);
  243. prow.addPostponeFrame(index % 3);
  244. return prow;
  245. })
  246. .get();
  247. console.log('cartList [%o] == ', cartList.length);
  248. };
  249.  
  250. let runInMailRu = function() {
  251. if (!WhereIs.inMailRu) {
  252. return;
  253. }
  254. };
  255.  
  256. runInFlipKz();
  257. runInMailRu();
  258.  
  259. console.log('Cart - Flip 💬 1.8');
  260. })();