// ==UserScript== // @name Dribbble Extender // @description Shows who follows you on your following list // @author Kos // @namespace http://tampermonkey.net/ // @version 0.3 // @license CC BY-SA 2.0 // @homepage https://greasyfork.org/scripts/22003-dribbble-extender // @include https://dribbble.com/*/following // @require https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js // @grant GM_addStyle // @downloadURL none // ==/UserScript== ;(function() { 'use strict'; // styles for checkmark GM_addStyle( '.us-follows-you-mark {color:#b3e3bd;font-weight:200}\ .us-fetch-ready {color:#2cff5a;font-weight:900}' ); var ACCESS_TOKEN = '9eafaa85aba0e22cdd7b7ddaa23181b59c29989dbd27000c78db21f5609110f4', followers = [], // username username = location.pathname.replace(/\/(.*?)\/.*/, '$1'), cacheKey = username; // functions for working with localStorage function lsTest() { var test = 'test'; try { localStorage.setItem(test, test); localStorage.removeItem(test); return true; } catch(e) { return false; } } function getLocalStorageArray(name) { var list = localStorage.getItem(name); if (!list) { return []; } return JSON.parse(list); } function saveUpdatedFollowersList(list) { localStorage.setItem(cacheKey+'_followers_latest', JSON.stringify(list)); } function addFollowerLocalStorage(id) { var list = getLocalStorageArray(cacheKey+'_followers_latest'); if (list.indexOf(id) == -1) { list.push(id); } saveUpdatedFollowersList(list); } function saveFinishedAmountOfFollowers() { var list = getLocalStorageArray(cacheKey+'_followers_latest'); localStorage.setItem(cacheKey+'_followers', JSON.stringify(list)); saveUpdatedFollowersList([]); // update on page followers = list; } var localStorageAvailable = lsTest(); $(document).ready(function(){ var fetchActive = false, fullFetchFinished = false, curPage = 1, perPage = 100, parseDelay = 200, repaintDelay = 500, waitForAllFetch = false, skipParseCounter = 0; if (localStorageAvailable) { followers = getLocalStorageArray(cacheKey+'_followers'); // if have previously saved followers, increase delay, // update on page only when all users parsed if (followers.length) { parseDelay += 300; waitForAllFetch = true; } // clear previously parsed data, to parse all new saveUpdatedFollowersList([]); } function getPage() { fetchActive = true; $.ajax({ type: 'GET', url: 'https://api.dribbble.com/v1/users/'+username+'/followers/?page='+curPage+'&per_page='+perPage, beforeSend: function(jqxhr) { jqxhr.setRequestHeader('Authorization', 'Bearer ' + ACCESS_TOKEN); }, success: function(res) { fetchActive = false; if (res.length === 0) { fullFetchFinished = true; return; } for (var i = 0; i < res.length; i++) { setFollowed(res[i].follower.id); } // if not full page, assume it last one if (res.length < perPage) { fullFetchFinished = true; } curPage++; }, error: function(jqxhr) { fetchActive = false; // skip next n parse times skipParseCounter = 20; } }); } function setFollowed(id) { id = Math.round(id); if (!waitForAllFetch && followers.indexOf(id) == -1) { followers.push(id); } if (localStorageAvailable) { addFollowerLocalStorage(id); } } function paintFollowed() { var following = $('ol.list-of-scrolling-rows').find('.scrolling-row'); for (var i = 0; i < following.length; i++) { var userId = Math.round(following[i].className.replace(/.*?user-row-(\d+).*/, '$1')), userBlock = $(following[i]), title = userBlock.find('.hover-card-parent'); // if not followed, remove mark if has one if (followers.indexOf(userId) == -1) { userBlock.removeClass('us-follows-you'); userBlock.find('.us-follows-you-mark').remove(); continue; } // if already marked as follower do nothing until all fetched if (userBlock.hasClass('us-follows-you')) { if (fullFetchFinished) { userBlock.find('.us-follows-you-mark').addClass('us-fetch-ready'); } continue; } // set mark of follower userBlock.addClass('us-follows-you'); title.html(''+title.html()); } } var intervalParse = setInterval(function(){ // skip and reduce counter if (skipParseCounter > 0) { skipParseCounter--; return; } if (fullFetchFinished) { clearInterval(intervalParse); if (localStorageAvailable) { saveFinishedAmountOfFollowers(); } return; } if (!fetchActive) { getPage(); } }, parseDelay); // paint then set repaint with delay paintFollowed(); var intervalPaint = setInterval(paintFollowed, repaintDelay); }); })();