Subscribe and Unsubscribe Items from Steam Workshop without going into item and clicking button. Just do it from list!
// ==UserScript==
// @name Steam Workshop Fast Subscribe
// @homepage https://zakku.tk
// @version 2.0
// @description Subscribe and Unsubscribe Items from Steam Workshop without going into item and clicking button. Just do it from list!
// @author ZaKKu
// @match http://steamcommunity.com/workshop/browse/*
// @match http://steamcommunity.com/id/*/myworkshopfiles/*
// @match https://steamcommunity.com/workshop/browse/*
// @match https://steamcommunity.com/id/*/myworkshopfiles/*
// @require https://code.jquery.com/jquery-2.0.3.min.js
// @downloadURL https://gist.github.com/zaker102/562cceea6b5e6f8ba2755e0b0c35deea/raw/01fd4f8a4753e030391d01e4fd9c9d7917931def/Steam%2520Workshop%2520Fast%2520Subscribe.user.js
// @updateURL https://gist.github.com/zaker102/562cceea6b5e6f8ba2755e0b0c35deea/raw/01fd4f8a4753e030391d01e4fd9c9d7917931def/Steam%2520Workshop%2520Fast%2520Subscribe.user.js
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
let idList = [];
let compere = [];
let defaultList = document.querySelector('.workshopBrowsePagingInfo').innerHTML;
let subscribedList = [];
function getIds() {
let url = window.location.href;
let testURL = /^(http|https):\/\/steamcommunity.com\/id.*[a-z]\/myworkshopfiles\/\?appid=.*[0-9]/g.exec(url);
let items = document.querySelectorAll('.workshopItem a[href*="//steamcommunity.com/sharedfiles/filedetails/?id="]:first-child');
for(var i = 0; i < items.length; i++) {
let id = items[i].href.split("id=")[1].split("&")[0];
let url = items[i].href.split('&searchtext=')[0];
let title = document.querySelectorAll('.workshopItem .workshopItemTitle')[i].innerHTML;
let author = (testURL === null ? document.querySelectorAll('.workshopItemAuthorName a')[i].innerHTML : document.querySelector('#HeaderUserInfoName a').innerHTML);
let img = document.querySelectorAll('.workshopItemPreviewImage')[i].src.split("?")[0];
let rating = document.querySelectorAll('.fileRating')[i].src.split('/').pop().split("-")[0];
let incompatible = document.querySelectorAll('.workshop_checkmark')[i].style.display === 'block';
let favorited = false;
let nodes = document.querySelectorAll('.workshopItem')[i].childNodes;
for(var j = 0; j < nodes.length; j++) {
if(nodes[j].className === "user_action_history_icon favorited") {
favorited = true;
}
}
idList.push({id: id, name: title, author: author, rating: rating, favorited: favorited, incompatible: incompatible, url: url, image: img});
}
if (unsafeWindow.items === undefined) {
unsafeWindow.items = idList;
}
}
function getSubscribeData() {
var url = window.location.href;
var appid = /appid=([^&]+)/.exec(url)[1];
let a = document.querySelector('.user_avatar.playerAvatar').href.split('/');
let username = a[a.length - 2];
return { session: g_sessionID, appid: appid, username: username };
}
function createFilter() {
let pattern = '<div class="filterOption"><input type="checkbox" id="%id%" value="%id%" class="inputTagsFilter" %checked%><label for="%id%">%name%</label></div>';
let panel = document.querySelector('.rightDetailsBlock');
panel.innerHTML = '<div class="rightSectionTitle"><div class="tagSearch">Loading ' + idList.length + ' items..</div></div>';
getSubscribedItems(function(list) {
for(var i = 0; i < idList.length; i++) {
compere.push(idList[i].id);
let pc = pattern;
let index = list.indexOf(idList[i].id);
if(index > -1) {
pc = replaceAll(pc, "%checked%", "checked");
} else {
pc = replaceAll(pc, "%checked%", "");
}
pc = replaceAll(pc, "%id%", idList[i].id);
pc = replaceAll(pc, "%name%", idList[i].name);
panel.innerHTML += pc;
}
updateStatus();
listenToFilter();
});
}
function listenToFilter() {
$('.filterOption').click(function(e) {
let target = $(e.target);
if(target.is(":checked")) {
subscribeMod(target.val(), function(result) { if(result !== 1) target.prop('checked', false); });
} else {
unsubscribeMod(target.val(), function(result) { if(result !== 1) target.prop('checked', true); });
}
});
}
function getSubscribedItems(callback) {
let data = getSubscribeData();
let url = '//steamcommunity.com/id/'+ data.username +'/myworkshopfiles/?appid='+ data.appid +'&browsefilter=mysubscriptions';
let result = [];
let outstandingRequests = 0;
$.ajax({
type: 'GET',
url: url,
success: function(response) {
let button = $(response).find('a.pagelink[href^="?appid='+ data.appid +'&browsefilter=mysubscriptions&p="]');
let count = ($(button).length > 0 ? Number($(button[button.length -1]).html()) : 0);
for(var i = 0; i <= count; i++) {
outstandingRequests++;
$.ajax({
type: 'GET',
url: url + '&p=' + i,
success: function(response) {
let items = $(response).find('.workshopItemSubscriptionDetails a[href*="//steamcommunity.com/sharedfiles/filedetails/?id="]');
for(var j = 0; j < items.length; j++) {
result.push(items[j].href.split("id=")[1].split("&")[0]);
subscribedList.push(items[j].href.split("id=")[1].split("&")[0]);
}
if (!(--outstandingRequests)) {
callback(result);
}
}
});
}
}
});
}
function subscribeMod(id, callback) {
let data = getSubscribeData();
var index = findWithAttr(idList, 'id', id);
if(index == -1) return;
$.ajax({
type: "POST",
url: "//steamcommunity.com/sharedfiles/subscribe",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
data: {
id: idList[index].id,
appid: data.appid,
sessionid: data.session
},
success: function (response) {
console.log(response);
if(response.success == 1) {
subscribedList.push(id);
updateStatus();
}
return callback(response.success);
}
});
}
function unsubscribeMod(id, callback) {
let data = getSubscribeData();
var index = subscribedList.indexOf(id);
if(index == -1) return;
$.ajax({
type: "POST",
url: "//steamcommunity.com/sharedfiles/unsubscribe",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
data: {
id: subscribedList[index],
appid: data.appid,
sessionid: data.session
},
success: function (response) {
console.log(response);
if(response.success == 1) {
let i = subscribedList.indexOf(id);
if(i > -1) {
subscribedList.splice(i, 1);
updateStatus();
}
}
return callback(response.success);
}
});
}
function updateStatus() {
for(var i = 0; i < idList.length; i++) {
let item = document.querySelectorAll('.workshopItem')[i];
let pattern = document.createElement('div');
pattern.setAttribute("id", "user_action_history_icon_subscribed" + idList[i].id);
pattern.setAttribute("data-tooltip-content", "You are subscribed to this item.");
pattern.className = "user_action_history_icon subscribed tooltip";
$('#user_action_history_icon_subscribed' + idList[i].id).remove();
if(subscribedList.indexOf(idList[i].id) > -1) {
$('.fileRating')[i].before(pattern);
} else {
$('#user_action_history_icon_subscribed' + idList[i].id).remove();
}
}
let notDisplayedCount = subscribedList.filter(function(i) {return compere.indexOf(i) < 0;}).length;
document.querySelector('.workshopBrowsePagingInfo').innerHTML = defaultList + ', ' + notDisplayedCount + ' subscribed ' + (notDisplayedCount > 1 || notDisplayedCount === 0 ? 'items are' : 'item is') + ' not displayed';
document.querySelector('.rightSectionTitle .tagSearch').innerHTML = "Subscribed to " + subscribedList.length + " " + (subscribedList.length > 1 ? "mods" : "mod");
}
function replaceAll(str, search, replace) {
return str.split(search).join(replace);
}
function findWithAttr(array, attr, value) {
for(var i = 0; i < array.length; i += 1) {
if(array[i][attr] === value) {
return i;
}
}
return -1;
}
getIds();
createFilter();
if (unsafeWindow.data === undefined) {
unsafeWindow.data = getSubscribeData();
}
if (unsafeWindow.list === undefined) {
unsafeWindow.list = subscribedList;
}
})();