Advertisement
silver_hr

Market listing sell buttons

Jan 16th, 2016
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        Steam Inventory - Add Buy & Sell orders
  3. // @namespace   madjoki
  4. // @include     http://steamcommunity.com/*/inventory*
  5. // @include     http://steamcommunity.com/market*
  6. // @include     https://steamcommunity.com/*/inventory*
  7. // @include     https://steamcommunity.com/market*
  8. // @version     16
  9. // @downloadURL https://gist.githubusercontent.com/nikop/a80168b747a9693b9175/raw/steam_market.user.js
  10. // @grant       none
  11. // ==/UserScript==
  12.  
  13. "use strict";
  14.  
  15. var selectedItem = null;
  16. var wallet = null;
  17. var cache2 = {};
  18.  
  19. (function (){
  20.  
  21. try
  22. {
  23.     // Ensure we have wallet data (user is logged in)
  24.     if (typeof(window.g_rgWalletInfo) === "undefined" || g_rgWalletInfo && g_rgWalletInfo.success === false)
  25.         return;
  26.    
  27.     wallet = window.g_rgWalletInfo;
  28.    
  29.     // Ensure we have valid wallet currency. Default to US$.
  30.     if (typeof(wallet.wallet_country) === "undefined" || typeof(wallet.wallet_currency) === "undefined" || wallet.wallet_country == '' || !wallet.wallet_currency) {
  31.         wallet.wallet_country = 'US';
  32.         wallet.wallet_currency = 1;
  33.     }
  34.    
  35.     $J('\
  36.    <style type="text/css">\
  37.        #inv_settings { display: none; }\
  38.        .item_market_orders table { margin: auto; }\
  39.        .orders_summary { text-align: center; }\
  40.        .orders_table { margin-bottom: 0.5em; }\
  41.        .market_commodity_orders_table tr:nth-child(even) { background-color: #262626; }\
  42.        .market_commodity_orders_table td, .market_commodity_orders_table th { min-width: 100px; text-align: center; }\
  43.    </style>').appendTo("head");
  44.    
  45.     $J('body').append('\
  46.    <div id="inv_settings" class="market_modal_dialog">\
  47.        <div class="market_dialog_title">\
  48.            <span>\
  49.            Settings\
  50.            <span class="market_dialog_cancel">\
  51.                <a href="#" class="market_dialog_title_cancel">Close<span class="market_dialog_title_cancel_X">X</span></a>\
  52.            </span>\
  53.        </div>\
  54.        <div class="market_dialog_contents">\
  55.        </div>\
  56.    </div>');
  57.        
  58.     setInterval(function ()
  59.     {
  60.         if (g_ActiveInventory && selectedItem != g_ActiveInventory.selectedItem)
  61.             updateWithSelectedItem();
  62.  
  63.     }, 200);
  64.  
  65.     // Inventory page
  66.     if (/inventory/.exec(window.location.pathname))
  67.     {
  68.         // Check SSA agreement.
  69.         $J('#market_sell_dialog_accept_ssa') .attr('checked', 'checked');
  70.         // Styles
  71.        
  72.         // Add div to both iteminfo sections. Steam alternates between two to provide fade animation.
  73.         for (var i = 0; i < 2; i++) {
  74.             $J('#iteminfo' + i + '_market_content') .append('<div id="iteminfo' + i + '_market_orders" class="item_market_actions item_market_orders"></div>');
  75.             $J('#iteminfo' + i + '_market_orders') .hide();
  76.         }
  77.        
  78.         $J('#inventories').on( 'click', '.itemHolder, .newitem', updateWithSelectedItem);
  79.  
  80.         // We're in the iframe, need to show only the quicksell buttons if the item is in the inventory
  81.         if(/market_hash_name/.exec(window.location.search)) {
  82.             // Prevent the page from creating a popup after clicking the item
  83.             window.Economy_UseResponsiveLayout = function() { return false; };
  84.            
  85.             // Make the iframe look seamless in the parent page
  86.             $J("body").css("background-color", "transparent");
  87.  
  88.             $J("body").append($J("#iteminfo0_item_market_actions"));
  89.             $J("body > *").hide();
  90.            
  91.             // Find the item in the URL
  92.             let market_hash_name = decodeURIComponent(/market_hash_name=([^&;#]+)/.exec(window.location.search)[1].replace(/\+/g, " "));
  93.            
  94.             selectItem(market_hash_name);
  95.            
  96.             // If the item is posted for sale, the inventory pages reload and the selection changes so need to refresh the quicksell buttons
  97.             let oldOnSuccess = SellItemDialog.OnSuccess;
  98.             let myOnSuccess = function(transport) {
  99.                 SellItemDialog.OnSuccess = oldOnSuccess;               
  100.                 SellItemDialog.OnSuccess(transport);
  101.                 SellItemDialog.OnSuccess = myOnSuccess;
  102.  
  103.                 let removeModal = function() { $J("#sellButtons", parent.document.body).removeClass("sellButtonsModal"); };
  104.            
  105.                 // The trade requires confirmation so there is an additional dialog that we need to hook into
  106.                 if(transport.responseJSON && transport.responseJSON.requires_confirmation) {
  107.                     $J("div.newmodal_background").click(removeModal);
  108.                     $J("div.newmodal:contains('Additional confirmation needed') div.btn_grey_white_innerfade.btn_medium").click(removeModal);
  109.                     $J("div.newmodal:contains('Additional confirmation needed') div.newmodal_close").click(removeModal);
  110.                 }
  111.                 else {
  112.                     removeModal();
  113.                     selectItem(market_hash_name);
  114.                 }
  115.             };
  116.             SellItemDialog.OnSuccess = myOnSuccess;
  117.         }
  118.     }
  119.     // Market listing page
  120.     else if(/market\/listing/.exec(window.location.pathname))
  121.     {
  122.         // Modal and regular style for the iframe
  123.         $J("head").append("\
  124.         <style type='text/css'>\
  125.         .sellButtonsModal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; }\
  126.         #sellButtons {\
  127.             background-image: url('http://steamcommunity-a.akamaihd.net/public/images/login/throbber.gif');\
  128.             background-position: top center; \
  129.             background-repeat: no-repeat;\
  130.             border: 0px;\
  131.             overflow: hidden;\
  132.         }\
  133.         </style>");
  134.  
  135.         let appid;
  136.         for(let _appid in g_rgAssets)
  137.             appid = _appid;
  138.        
  139.         let market_hash_name;
  140.         for(let context in g_rgAssets[appid])
  141.             for(let id in g_rgAssets[appid][context])
  142.                 market_hash_name = g_rgAssets[appid][context][id].market_hash_name;
  143.        
  144.         let iframe = $J("<iframe scrolling='no' id='sellButtons' src='http://steamcommunity.com/my/inventory/?modal=1&market=1&market_hash_name=" + market_hash_name + "#" + appid + "'></iframe>");
  145.         let sellButton = $J("a.market_commodity_buy_button:Contains('Sell')");
  146.         sellButton.after(iframe);
  147.  
  148.         // Add click handlers to sell buttons to make iframe modal
  149.         iframe.load(function() {
  150.             let iframeBody = iframe[0].contentWindow.document.body;
  151.             let buttonContainers = $J("#iteminfo0_item_market_actions, #iteminfo1_item_market_actions", iframeBody);
  152.            
  153.             // Remove modal class from iframe when the close button on the modal sell dialog is clicked
  154.             let removeModal = function() { iframe.removeClass("sellButtonsModal"); };
  155.             $J("#market_sell_dialog div.newmodal_close", iframeBody).click(removeModal);
  156.  
  157.             buttonContainers.on("DOMSubtreeModified", function() {
  158.                 let buttons = $J(".item_market_action_button", iframeBody);
  159.  
  160.                 buttons.click(function() {
  161.                     // Wait until modal background loads and hook into it to remove modal class from iframe when clicked
  162.                     let timerId = setInterval(function() {
  163.                         let modalBackground = $J("div.newmodal_background", iframeBody);
  164.                        
  165.                         if(modalBackground.length > 0) {
  166.                             clearInterval(timerId);
  167.                            
  168.                             modalBackground.click(removeModal);
  169.                         }
  170.                     }, 100);
  171.  
  172.                     iframe.addClass("sellButtonsModal");
  173.                 });
  174.             });
  175.         });
  176.     }
  177.     // Market Page
  178.     else if (/market/.exec(window.location.pathname))
  179.     {
  180.         /*$J('div.my_listing_section:eq(0) div.market_listing_my_price .market_table_value').each(function (i, el)
  181.         {
  182.             var price = SellItemDialog.GetPriceValueAsInt( $J(el).children('.market_listing_price').text() );
  183.             var feeInfo = CalculateAmountToSendForDesiredReceivedAmount( price, g_rgWalletInfo['wallet_publisher_fee_percent_default'] );
  184.             $J(el).append(" (" + v_currencyformat(price + feeInfo.fees, GetCurrencyCode(g_rgWalletInfo.wallet_currency)) + ")");
  185.         });*/
  186.     }
  187. }
  188. catch (err)
  189. {
  190.     window.alert(err);
  191. }
  192.    
  193. })();
  194.  
  195. function showSettings()
  196. {
  197.     window.showModal('inv_settings');
  198. }
  199.  
  200. function closeSettings()
  201. {
  202.     window.hideModal('inv_settings');
  203. }
  204.  
  205. function get_cents(text) {
  206.     return GetPriceValueAsInt(text);
  207. }
  208.  
  209. function currencyformat(cents) {
  210.     return window.v_currencyformat(cents, window.GetCurrencyCode(wallet.wallet_currency));
  211. }
  212.  
  213. function unique_values(array) {
  214.     return $J.grep(array, function (el, index) {
  215.         return index == $J.inArray(el, array);
  216.     });
  217. }
  218.  
  219. function triggerMouseEvent(node, eventType) {
  220.     var clickEvent = document.createEvent('MouseEvents');
  221.     clickEvent.initEvent(eventType, true, true);
  222.     node.dispatchEvent(clickEvent);
  223. }
  224.  
  225. function set_sell_price(text)
  226. {
  227.      $J('#market_sell_buyercurrency_input').val(text);
  228.    
  229.     // Let Steam handle and validate changed value
  230.      SellItemDialog.OnBuyerPriceInputKeyUp(null);
  231. }
  232.  
  233. function quick_sell_click() {
  234.     // Open sell window
  235.     window.SellCurrentSelection();
  236.    set_sell_price( $J(this).children('.item_market_action_button_contents') .text() );
  237.    
  238.     triggerMouseEvent($J('#market_sell_dialog_accept') [0], 'click');
  239.    
  240.     // Prevent default handler
  241.     return false;
  242. }
  243.  
  244. function get_buy_orders_by_market_url(market_url, callback) {
  245.     if (localStorage.getItem('marketid_' + market_url) === null) {
  246.         var oReq = new XMLHttpRequest();
  247.         oReq.onload = function () {
  248.             //
  249.             var m = /Market_LoadOrderSpread\( (\d+) \)/.exec(this.responseText);
  250.             if (m) {
  251.                 localStorage['marketid_' + market_url] = m[1];
  252.                 get_buy_orders_by_market_id(m[1], callback);
  253.             }
  254.         };
  255.         oReq.onerror = function () {
  256.             console.error(this.statusText);
  257.         }
  258.         oReq.open('get', market_url);
  259.         oReq.send();
  260.     } else {
  261.         get_buy_orders_by_market_id(localStorage['marketid_' + market_url], callback);
  262.     }
  263. }
  264.  
  265. function get_buy_orders_by_market_id(market_id, callback) {
  266.     var history_url = '//steamcommunity.com/market/itemordershistogram?country=' + wallet.wallet_country + '&language=' + window.g_strLanguage + '&currency=' + wallet.wallet_currency + '&item_nameid=' + market_id;
  267.     /*if (history_url in cache2) {
  268.         callback(cache2[history_url]);
  269.     } */
  270.    
  271.     var oReq = new XMLHttpRequest();
  272.     oReq.onload = function () {
  273.         var j = JSON.parse(this.responseText);
  274.         cache2[history_url] = j;
  275.         callback(j);
  276.     }
  277.     oReq.onerror = function () {
  278.         console.error(this.statusText);
  279.     }
  280.     oReq.open('get', history_url);
  281.     oReq.send();
  282. }
  283.  
  284. function addQuickSellButtons(itemid, prices)
  285. {
  286.     $J.each(prices, function (index, value) {
  287.         var btn = $J('<a href="#" class="item_market_action_button item_market_action_button_green"><span class="item_market_action_button_edge item_market_action_button_left"></span><span class="item_market_action_button_contents"></span><span class="item_market_action_button_edge item_market_action_button_right"></span><span class="item_market_action_button_preload"></span></a>');
  288.         $J(btn) .children('.item_market_action_button_contents') .text(currencyformat(value));
  289.         $J(btn) .click(quick_sell_click);
  290.         $J('#iteminfo' + itemid + '_item_market_actions') .append(btn);
  291.     });        
  292. }
  293.  
  294. function updateWithSelectedItem() {
  295.     var itemid = window.iActiveSelectView;
  296.     selectedItem = window.g_ActiveInventory.selectedItem;
  297.    
  298.     $J('#iteminfo' + itemid + '_market_orders').hide();
  299.  
  300.     // Item needs to be marketable
  301.     if (!selectedItem.marketable)
  302.         return;
  303.  
  304.     // Show buy & sell orders for commodities
  305.     if (selectedItem.commodity)
  306.     {
  307.         $J('#iteminfo' + itemid + '_market_orders').show();
  308.         $J('#iteminfo' + itemid + '_market_orders').html('Loading buy & sell orders...');
  309.  
  310.         // Get market id, so we can fetch buy & sell orders
  311.         get_buy_orders_by_market_url($J('#iteminfo' + itemid + '_item_market_actions > div > div a:eq(0)').attr('href'), function (j)
  312.         {
  313.             $J('#iteminfo' + itemid + '_market_orders') .html('\
  314.                 <div class="orders_summary" id="sell_order_summary_' + itemid + '"></div>\
  315.                 <div class="orders_table" id="sell_order_table_' + itemid + '"></div>\
  316.                 <div class="orders_summary" id="buy_order_summary_' + itemid + '"></div>\
  317.                 <div class="orders_table" id="buy_order_table_' + itemid + '"></div>'
  318.             );
  319.  
  320.             $J('#sell_order_summary_' + itemid).html(j.sell_order_summary);
  321.             $J('#sell_order_table_' + itemid).html(j.sell_order_table);
  322.             $J('#buy_order_summary_' + itemid).html(j.buy_order_summary);
  323.             $J('#buy_order_table_' + itemid).html(j.buy_order_table);
  324.  
  325.             var buyOrderMax = get_cents($J('#buy_order_summary_' + itemid + ' .market_commodity_orders_header_promote:eq(1)') .text());
  326.             var sellOrderMin = get_cents($J('#sell_order_summary_' + itemid + ' .market_commodity_orders_header_promote:eq(1)') .text());
  327.             var common_values = [];
  328.  
  329.             if (sellOrderMin) {
  330.                 common_values.push(sellOrderMin);
  331.                 // 3 cents is min price
  332.                 if (sellOrderMin > 3)
  333.                     common_values.push(sellOrderMin - 1);
  334.             } else {
  335.                 sellOrderMin = 3;
  336.             }
  337.  
  338.             if (buyOrderMax)
  339.                 common_values.push(buyOrderMax);
  340.  
  341.             var extra_values = [];
  342.  
  343.             for (var i = sellOrderMin - 5; i <= sellOrderMin + 5; i++)
  344.                 if (i > 2 && i >= buyOrderMax && common_values.indexOf(i) == - 1)
  345.                     extra_values.push(i);
  346.  
  347.             addQuickSellButtons(itemid, unique_values(common_values));
  348.             addQuickSellButtons(itemid, unique_values(extra_values));
  349.         });
  350.     }
  351.     // Otherwise show just quick sell buttons
  352.     else
  353.     {
  354.         addQuickSellButtons(itemid, [3, 4, 5, 6, 7, 8, 9, 10]);
  355.        
  356.         return;
  357.     }
  358. }
  359.  
  360. // For use in iframe; if it finds a market_hash_name item in the list of inventory pages, it hides everything but the quicksell buttons, otherwise it removes the iframe
  361. function selectItem(market_hash_name) {
  362.     let parentSellButton = $J("a.market_commodity_buy_button:Contains('Sell')", parent.document.body);
  363.    
  364.     // Might contain old quicksell buttons, so need to hide it
  365.     $J("#iteminfo0_item_market_actions").hide();
  366.  
  367.     // Wait until the inventory is ready and select the item
  368.     let timerId = setInterval(function() {
  369.         if(g_ActiveInventory && g_ActiveInventory.bNeedsRepagination === false) {
  370.             let pages = $J.grep(g_ActiveInventory.pageList, function(page) {
  371.                 let items = $J.grep(page.children, function(item) {
  372.                     if(typeof item.rgItem == "undefined")
  373.                         return false;
  374.                    
  375.                     return item.rgItem.market_hash_name == market_hash_name;
  376.                 });
  377.                
  378.                 // Found the item in the inventory
  379.                 if(items.length > 0) {
  380.                     $J("> div > a", items[0]).click();
  381.                    
  382.                     // Hide the big sell button in the parent
  383.                     parentSellButton.hide();
  384.  
  385.                     // Make only the sell buttons visible
  386.                     $J("#iteminfo0_item_market_actions > div").hide();
  387.                     $J("#iteminfo0_item_market_actions").show();
  388.                    
  389.                     // This one pops up after an ajax call returns so need to hide it this way
  390.                     let timerId = setInterval(function() {
  391.                         if($J("#es_item0").is(":visible")) {
  392.                             $J("#es_item0").hide();
  393.                             clearInterval(timerId);
  394.                         }
  395.                     }, 300);
  396.                    
  397.                     return true;
  398.                 }
  399.                
  400.                 return false;
  401.             });
  402.            
  403.             // The item was not found so remove the iframe
  404.             if(pages.length == 0) {
  405.                 parentSellButton.show();
  406.                 $J("#sellButtons", parent.document.body).remove();
  407.             }
  408.            
  409.             clearInterval(timerId);
  410.         }
  411.     }, 300);
  412. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement