// ==UserScript== // @name DIG Store Enhancer // @namespace https://github.com/Omicron666 // @version 0.4.0 // @description Adding some functionnalities to DailyIndieGame store // @author Omicron666 // @match *://*.dailyindiegame.com/* // @icon https://www.dailyindiegame.com/dailyindiegame.png // @require https://code.jquery.com/jquery-3.2.1.min.js // @require https://github.com/Mottie/tablesorter/raw/master/js/jquery.tablesorter.js // @homepageURL https://github.com/Omicron666/Steam // @supportURL https://github.com/Omicron666/Steam/issues // @downloadURL https://raw.githubusercontent.com/Omicron666/Steam/master/dig-store-enhancer.user.js // @updateURL https://raw.githubusercontent.com/Omicron666/Steam/master/dig-store-enhancer.user.js // @grant GM_addStyle // @grant GM_xmlhttpRequest // @run-at document-start // @connect store.steampowered.com // ==/UserScript== if (/^http\:/.test(window.location.href)){ window.location.replace(window.location.href.replace(/http\:/, 'https:')); } $(function() { 'use strict'; // let's fix style for them... GM_addStyle (`.DIG2TableGray { border: 1px solid #424242; border-collapse: separate; border-spacing: 1; background-color: #2D2D2D; padding: 0px; spacing: 0px; }`); // style for sorting + no-wrapping table cells GM_addStyle (` th:focus, td:focus {outline:none;} .headerSortUp:after{ content: ' \\21ca'; } .headerSortDown:after{ content: ' \\21c8'; } .headerDefault:after{ //content: ' \\21c5'; } .headerDefault, .headerSortUp, headerSortDown{cursor: pointer;} td{ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; -o-text-overflow: ellipsis; -ms-text-overflow: ellipsis; max-width: 200px; } .steam-review { max-width: 120px; } `); var appIdList = $('a[href*="store.steampowered.com/app/"]').map( function(i,e){ let appid = $(e).prop('href').match(/\d+/); $(e).closest('tr').data('appid', appid); // conveniently store appid on each row return appid; } ).toArray().join(); // add Font Awesome CSS $("head").append($("").attr({"rel":"stylesheet","href":"https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"})); let waitingPriceTD = ''; let waitingScoreTD = ''; if (/account_digstore|store_update.*2/.test(window.location.href)){ $('#TableKeys').addClass('DIG2TableGray'); // let's move this closer to relevant table $('#sortby').closest('table').find('tr > td:first-child').html('
Default:
'); $('#sortby').closest('table').insertBefore('#TableKeys'); // Weekly discounts table headers let $weeklyTable = $('td:contains(Weekly discounts):last').closest('table'); $weeklyTable.find('tbody > tr:first-child > td').prop('colspan','9'); $weeklyTable.find('tbody > tr').eq(1).append('SteamScore'); // Main table header $('#TableKeys > tbody > tr').eq(0).append('SteamScore'); // moving rows to proper table headers for sorting... $weeklyTable.prepend(''); //$weeklyTable.find('thead').append($weeklyTable.find('tbody > tr:lt(2)')); $weeklyTable.find('thead').append($weeklyTable.find('tbody > tr:first-child')); $weeklyTable.find('thead').append($weeklyTable.find('tbody > tr:first-child')); $('#TableKeys').prepend(''); // $('#TableKeys > thead').append($('#TableKeys > tbody > tr:lt(2)')); $('#TableKeys > thead').append($('#TableKeys > tbody > tr:first-child'));$('#TableKeys > thead').append($('#TableKeys > tbody > tr:first-child')); //$('#TableKeys > thead > tr').contents().unwrap().wrap(''); // display Steam price on each row $weeklyTable.find('tbody > tr').append(waitingPriceTD); $('#TableKeys > tbody > tr').append(waitingPriceTD); // display Steam review score on each row let ReviewScoreUpdateFunc = function(i,e){ let $waitingCell = $(waitingScoreTD); let $waitingTable = $waitingCell.closest('table'); $(e).append($waitingCell); let appid = $(e).data('appid'); // Get Steam review score GM_xmlhttpRequest({ method: "GET", url: 'http://store.steampowered.com/appreviews/'+ appid + '?' + $.param({ start_offset:0, day_range:30, // doesn't seem to be used filter:'summary', language:'all', review_type:'all', purchase_type:'all', review_beta_enabled:'0', l:'english', }), onload: function(xhr) { let data = JSON.parse(xhr.responseText); let result = 'N/A'; if (data.review_score){ let dataScore = data.review_score; let stats = /tooltip="(\d+).*?([0-9,]+)/g.exec(data.review_score); let tooltip = /tooltip="(.*)"/g.exec(data.review_score); let mostlyString = /tooltip.*>(.*)<\/span>/g.exec(data.review_score); if ( stats && tooltip && mostlyString) result = ''+ stats[1]+ '% of '+ stats[2]+' ('+ mostlyString[1] +')'; } $waitingCell.html(result); //$waitingTable.trigger("update"); // refresh sorting }, }); }; $weeklyTable.find('tbody > tr').each(ReviewScoreUpdateFunc); $('#TableKeys > tbody > tr').each(ReviewScoreUpdateFunc); // bonus GM_addStyle ('.feature{}'); $("table > tbody > tr, table > thead > tr").contents().filter(function(){ return this.nodeType == 8; }).each(function(i, e){ let $parent = $(e).parent(); let index = $(e).index(); $(e).replaceWith(e.nodeValue); $parent.children().eq(index).hide(); $parent.children().eq(index).addClass('feature'); }); $('#TableKeys td:contains(left)').css('vertical-align','top'); // 'valign' is not valid HTML5 attribute ! $('#TableKeys td:contains(left)').prop('rowspan', '2'); $('#TableKeys td:contains(left)').html($('#TableKeys td:contains(left)').html().replace(':','')); $weeklyTable.find('td:contains(left)').html($weeklyTable.find('td:contains(left)').html().replace(':','')); document.addEventListener('keyup', function(e){if (e.keyCode == 81) { $('.feature').toggle(); $weeklyTable.trigger("update"); $('#TableKeys').trigger("update"); }}, false); /* don't leak it or this might get disabled/impossible ! */ // add sorting $weeklyTable.tablesorter({ headers: { 0:{ sorter: false}, 4:{ sorter: false}, 5:{ sorter: false}, 8: {sorter: false}}, cssAsc: 'headerSortUp', cssDesc: 'headerSortDown', cssHeader: 'headerDefault'}); $('#TableKeys').tablesorter( { headers: { 7: {sorter: false}, 8: {sorter: false}, 11: {sorter: false}, 12: {sorter: false}, 13: {sorter: false}}, cssAsc: 'headerSortUp', cssDesc: 'headerSortDown', cssHeader: 'headerDefault'}); // Add style for filtering head cell GM_addStyle (` .filter-out:after{ content: ' \\2261'; }`); // filter out rows with empty cells //$('#TableKeys > thead td:contains(VR), #TableKeys > thead td:contains(Cards), #TableKeys > thead td:contains(Volume)').addClass('filter-out'); //$('#TableKeys > thead td:contains(Volume)').addClass('filter-out'); $(':contains(Volume DISCOUNT):last').html("Volume DISCOUNT ≡"); $('#TableKeys > thead td:contains(Volume)').on('click', function(){$('#TableKeys > tbody > tr:not(:has(td:gt(8):contains(Point)))').toggle();}); // FIXME: conflicting multiple toggle //$('#TableKeys > thead td:contains(VR)').on('click',function(){$('#TableKeys > tbody > tr:has(td:nth-child(3):empty)').toggle();}); //$('#TableKeys > thead td:contains(Cards)').on('click',function(){$('#TableKeys > tbody > tr:has(td:nth-child(4):empty)').toggle();}); } else if (/account_trades|store_update/.test(window.location.href)){ // Main table header: add Steam header $('#TableKeys > tbody > tr:first-child').append('Steam'); // add Steam price on each row $('#TableKeys > tbody > tr:not(:first-child)').append(waitingPriceTD); // move table headers for sorting... $('#TableKeys').prepend(''); $('#TableKeys > thead').append($('#TableKeys > tbody > tr:first-child')); $('#TableKeys').tablesorter({ headers: { 6:{ sorter: false}}, cssAsc: 'headerSortUp', cssDesc: 'headerSortDown', cssHeader: 'headerDefault'}); } else if (/content_digaccount/.test(window.location.href)){ // Table headers: add Steam header $('#TableKeys2 > tbody > tr:first-child, #TableKeys > tbody > tr:first-child').append('Steam'); // display Steam price on each row $('#TableKeys2 > tbody > tr:not(:first-child), #TableKeys > tbody > tr:not(:first-child)').append(waitingPriceTD); // move table headers for sorting... $('#TableKeys').prepend(''); $('#TableKeys > thead').append($('#TableKeys > tbody > tr:first-child')); $('#TableKeys2').prepend(''); $('#TableKeys2 > thead').append($('#TableKeys2 > tbody > tr:first-child')); $('#TableKeys').tablesorter({ cssAsc: 'headerSortUp', cssDesc: 'headerSortDown', cssHeader: 'headerDefault'}); $('#TableKeys2').tablesorter({ cssAsc: 'headerSortUp', cssDesc: 'headerSortDown', cssHeader: 'headerDefault'}); } // Get Steam prices GM_xmlhttpRequest({ method: "GET", url: 'https://store.steampowered.com/api/appdetails?appids='+ appIdList +'&cc=us&filters=price_overview', onload: function(xhr) { let data = JSON.parse(xhr.responseText); let $waitingCells = $('.waiting-for-steam-price'); let $waitingTable = $waitingCells.closest('table'); $waitingCells.each(function(){ let appid = $(this).closest('tr').data('appid'); let result = ""; if (data[appid].success && (data[appid].data !== undefined) && (data[appid].data.price_overview !== undefined)) result = '$'+ parseInt(data[appid].data.price_overview.initial)/100.0; else result = 'N/A'; $(this).replaceWith(result); }); $waitingTable.trigger("update"); // refresh sorting after Steam price updates } }); $( document ).ajaxComplete(function( event, request, settings ) { $( "table" ).trigger('update'); // update sorting wherever needed }); });