Dribbble Extender

Shows who follows you on your following list

Fra 05.08.2016. Se den seneste versjonen.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==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
// ==/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('<span title="Follows you" class="us-follows-you-mark'+(fullFetchFinished ? ' us-fetch-ready' : '')+'">✓ </span>'+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);
    });
})();