Joeviocoe / DISQUS for Mobile

// ==UserScript==
// @name         DISQUS for Mobile
// @namespace
// @version      3.3.2
// @description  DISQUS Enhancer for Mobile
// @include      https://disqus.com/home/discussion*
// @include      https://disqus.com/home/inbox/
// @include      https://disqus.com/home/
// @include      https://disqus.com/home/forum/*
// @include      https://disqus.com/by/*
// @include      https://disqus.com/
// @copyright    2017+, Joeviocoe
// @license      MIT
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @icon         https://www.google.com/s2/favicons?domain=disqus.com
// @grant        none
// @noframes
// ==/UserScript==

// Copyright (c) 2017, Joeviocoe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Joeviocoe nor the names of its contributors
//   may be used to endorse or promote products derived from this software
//   without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/*jslint browser: true*/
/*global $, jQuery, alert */

var dsq, body, win, api = "E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F";

////////////////////////////////////////////////////////////////////////////////////////////////////////

function waitFor(selector, inside, callback) {
    if ( $(inside).contents().find(selector).length ) {
        callback();
    } else {
        setTimeout(function() {
            waitFor(selector, inside, callback);
        }, 250);
    }
}

function repeater(callback, delay, repetitions) {
    var x = 0;
    var intervalID = window.setInterval(function () {
       callback();
       if (++x === repetitions) {
           window.clearInterval(intervalID);
       }
    }, delay);
}

function getBody(){
    var d = new Date(), h = d.getHours(), m = d.getMinutes(), s = d.getSeconds();
    dsq = $('iframe[id*="dsq"]').last().attr("id"); console.log("DE: DSQ: " + dsq + " - " + h+":"+m+":"+s);
    body = ''; if ( typeof dsq == 'undefined') { body = $('body'); } else { body = $("#"+dsq).contents().find('body'); }
    win = ''; if ( typeof dsq == 'undefined') { win = $('window'); } else { win = $("#"+dsq)[0].contentWindow; }
}

function Buttons() {
    $('header.site-nav--wrapper').css("position","fixed");
    $('a[href="/"]').attr("href", "/home/discussions/");

    $('button[data-action="create-discussion"]').attr("data-action","refresh-drawer").attr("onclick", "location.reload(true)");
    $('span.icon-create-discussion').attr("class","icon-refresh icon-medium").wrap('<a href="#">');

    var home = $('a[href="/home/"][data-page-icon="home"]');
    var notifications = $('a[href="/home/inbox/"][data-page-icon="inbox"]');
    if ( home.length > 0 & notifications.length > 0 ) {
        home.children('span').html(home.children('span').html().replace("Home",""))
        home.attr("href", "/home/discussions/").css("margin-left","25px");
        notifications.children('span').html(notifications.children('span').html().replace("Notifications",""))
        notifications.css("margin-left","25px");
    }

    $('.align:first').append(home).append(notifications);
    $('.notif-count').css("top","auto").css("margin-top","3px").css("margin-right","5px").css("left","auto");
    $('.site-nav--secondary').remove();

    body.find('.wysiwyg__item.hidden-md').removeClass('hidden-md');
}

function RemoveTrollAvatar() {
    body.find('img[src*="avatar92.jpg?1500479976"]').attr('src','//a.disquscdn.com/1523321660/images/noavatar92.png');
    body.find('img[src*="avatar92.jpg?1513645725"]').attr('src','//a.disquscdn.com/1523321660/images/noavatar92.png');
    body.find('img[src*="avatar92.jpg?1546868353"]').attr('src','//a.disquscdn.com/1523321660/images/noavatar92.png');
    body.find('#reactions__container').remove();
}

function unReferLinks() {
    setTimeout(function() {
        $('a.button-lnk[href*="/home/discussion"]').each(function() {
            $(this).attr("target","_newtab")
        });
        body.find('.comment-policy').remove();
        if ( window.location.href.indexOf('//disqus.com/home/inbox/') >= 0 ) {
            $('.view-comment').not('.cloned').addClass('cloned').css("margin-left","10px").each(function() {
                $(this).clone().addClass('all-comments').appendTo( $(this).parent() );
                $(this).children('span:contains("View")').text("Comment");
            });
            $('.all-comments').each(function(){
                $(this).attr("href",$(this).attr("href").split("#")[0]).css("margin-left","2px");
                $(this).children('span:contains("View")').text("Discussion");
            });
        }
        body.find('a[href*="disq.us"]').each(function(){
            $(this).attr("href", decodeURIComponent($(this).attr("href")).replace("/url","/").split("disq.us/?url=")[1].split(":").slice(0,2).join(':') );
            $(this).attr("href", $(this).attr("href").split("&key=")[0] );
        });
    }, 1000);
}

function Downvotes(){
    body.find('.vote-down[dvmark!="1"]').attr('dvmark','1').each(function(){
        if ( $(this).attr('class').indexOf('count-') >= 0 ) {
            var dv = $(this).attr('class').split('count-')[1].split(' ')[0];
            if ( dv > 0 ) {
                $(this).append("<span class='updatable count' data-role='likes' style='color: gray;position: relative;top: -1px;font-size: 13px;'>   " + dv + "</span>");
            }
        }
    });
}

function showDetails(username){
    var userdetails = [];
    var req = "https://disqus.com/api/3.0/users/details?user=username%3A"+username+"&api_key="+api;
    $.get(req, function(data) {
        var arr = data.response;
        userdetails.push("Name:       "+arr["name"]);
		userdetails.push("Username:   "+arr["username"]);
        userdetails.push("Joined:     "+arr["joinedAt"].replace('T','    '));
		userdetails.push("Private:    "+arr["isPrivate"]);
        userdetails.push("ID:         "+arr["id"]+"\n");
        userdetails.push("Posts:      "+arr["numPosts"]);
        userdetails.push("Upvotes:    "+arr["numLikesReceived"]);
        userdetails.push("Reputation: "+arr["reputationLabel"]+" ("+arr["rep"]+")");
        userdetails.push("Followers:  "+arr["numFollowers"]);
        userdetails.push("Following:  "+arr["numFollowing"]);
        userdetails.push("Forums:     "+arr["numForumsFollowing"]+"\n");
        userdetails.push("Primary:    "+arr["isPrimary"]);
        userdetails.push("Anonymous:  "+arr["isAnonymous"]);
        userdetails.push("Moderator:  "+arr["isPowerContributor"]);
        userdetails.push("disable3rdPartyTrackers:   "+arr["disable3rdPartyTrackers"]+"\n");
        userdetails.push("ProfileUrl: "+arr["profileUrl"]);
        userdetails.push("URL:        "+arr["url"]);
        userdetails.push("SignedUrl:  "+arr["signedUrl"]);
        userdetails.push("Location:   "+arr["location"]);
        userdetails.push("About:      "+arr["about"]);
        alert(userdetails.join('\n'));
        console.log(userdetails.join('\n'));
    });
}

function getDetails(){
    body.find('span.author').children('a[data-action="profile"][cloned!="1"]').attr('cloned','1').each(function(){
        var button = $(this).clone();
        var username = button.attr('data-username');
        button.attr('class','profile_details').insertAfter( $(this) ).text("ℹ").removeAttr('href').removeAttr('data-action');
        button.css('padding-top','4px').css('padding-left','12px').css('padding-right','20px'); button[0].style.setProperty( 'color', 'gray', 'important' );
        button.off().on('click',function(){
            showDetails(username);
        });
    });
    body.find('a.name[cloned!="1"]').attr('cloned','1').each(function(){
        var button = $(this).clone();
        var username = button.attr('href').split('/by/')[1].replace('/','');
        button.attr('class','profile_details').insertAfter( $(this) ).text("ℹ").removeAttr('href');
        button.css('padding-top','4px').css('padding-left','12px').css('padding-right','20px'); button[0].style.setProperty( 'color', 'gray', 'important' );
        button.off().on('click',function(){
            showDetails(username);
        });
    });
}

function getUpvotes(){
    body.find('a.vote-up[cloned!="1"]').attr('cloned','1').each(function() {
        if ( parseInt($(this).get(0).innerText) > 0 ) {
            var button = $(this).clone();
            button.attr('class','vote-up showvoted').insertAfter( $(this) ).text("ℹ").removeAttr('href').removeAttr('data-action');
            button.css('padding-top','4px'); button[0].style.setProperty( 'color', 'gray', 'important' );
            button.off().on('click',function(){
                var thread = button.siblings('a.view-comment').attr('data-thread-id') || $('meta[content*="threads"]').attr("content");
                thread = thread.split("threads/")[1] || thread;
                var post = button.siblings('a.view-comment').attr('href') || button.parents('li.post').attr('id');
                post = post.split("comment-")[1] || post.split('post-')[1];
                console.log("DSQ:  Parse upvotes for thread " + thread + " post " + post);
                var req = "https://disqus.com/api/3.0/posts/listUsersVotedPost?post="+post+"&thread="+thread+"&vote=1&limit=50&api_key="+api;
                $.get( req, function( data ) {
                    for ( i=0; i<data.response.length; i++ ){
                        var upvoter = data.response[i];
                        showDetails(upvoter["username"]);
                    }
                });
            });
        }
    });
}

function expandTruncate() {
    waitFor('.truncate', 'body', function() {
        if ( $('.truncate').length > 0 || $('.truncate-line').length > 0 ) {
            $('.truncate').each(function() { $(this).text( $(this).attr("title") ); });
            $(".truncate").removeClass("truncate"); $(".truncate-line").removeClass("truncate-line").removeAttr("href");
        }
    });
}

function orderFeeds() {
    waitFor('.card[age]', 'body', function() {
        var timearray = ["second","minute","hour","day","month"];
        $.each(timearray, function(i, time) {
            for (i=1; i<60; i++) {
                if ( i == 1 ) { j="a" } else { j=i }
                if ( i == 1 && time == "hour" ) { j="an" }
                $('.card[age*="'+j+" "+time+'"]').detach().appendTo('.layout__content.homepage-feed');
            }
            expandTruncate();
            $('.card-body').css('width','auto').css('padding-bottom','20px');
        });
    });
}

function feedFrame(id, src, name){
    $('div[data-jester-area="feed"]').remove();
    $('<iframe>', {
        id:  id,
        src:  src,
        class:  'feedframe',
        width: $(window).width(),
        height: 1,
        frameborder: 0,
        scrolling: 'no'
    }).appendTo('#container-page').on('load',function(){
        repeater(function() {
            $('iframe#'+id).contents().find('.card.card-profile.card-profile-forum').attr("forum",name).detach().appendTo('.layout__content.homepage-feed');
            $('.card[forum="'+name+'"]').find('.card-reason').each(function() {
                $(this).text( $(this).text().replace("Recent activity", ""+name+": ") );
                $(this).parents('.card.card-profile.card-profile-forum').attr("age",$(this).text().split(": ")[1].trim());
            });
            orderFeeds();
            expandTruncate();
        }, 1000, 30);
    });
}

function feedFrames(){
    var name = $('.name')[0].href.split("/")[4];
    var req = "https://disqus.com/api/3.0/users/listFollowingForums?limit=100&user=username:"+name+"&order=desc&cursor=&api_key="+api;
    $.get( req, function( data ) {
        for ( i=0; i<data.response.length; i++ ){
            var id = data.response[i].id;
            var src = "https://disqus.com/home/forum/"+id+"/";
            var name = data.response[i].name;
            feedFrame(id, src, name);
        }
    });
}


////////////////////////////////////////////////////////////////////////////////////////////////////////

function run(){
    getBody();
    Buttons();
    RemoveTrollAvatar();
    unReferLinks();
    Downvotes();
    getUpvotes();
    getDetails();
    expandTruncate();
}

function Initialize(){
    var counter = 0, el = $(window), lastY = el.scrollTop();
    getBody();

    window.addEventListener('scroll', function() {
        if ( counter === 0 ) {
            setTimeout (function() {
                run();
                var currY = el.scrollTop();
                if ( currY > lastY) {
                    $('header.site-nav--wrapper').slideUp();
                    lastY = currY - 100;
                } else {
                    $('header.site-nav--wrapper').slideDown();
                    lastY = currY + 100;
                }
                counter = 0;
            }, 100);
        }
        counter++;
    });

    window.addEventListener('click', function() {
        if ( counter === 0 ) { setTimeout (function() { console.log("DE: Click (window)"); run(); counter = 0; }, 500); }
        counter++;
    });

    body.off().on('click', function() {
        if ( counter === 0 ) { setTimeout (function() { console.log("DE: Click (body)"); run(); counter = 0; }, 500); }
        counter++;
    });
    body.click();

    if (window.location.href.indexOf('https://disqus.com/home/discussions/') >=0 ) {
        setTimeout(function(){
            feedFrames();
        },2000);
    }
}

console.log( "DE: Start of DISQUS_ENHANCER" );

setTimeout (function() {
    var expand_timer = setInterval (function() {
        console.log( "DE: Waiting" );
        getBody();
        if ( $(".card__content").length > 0 || $(".card-profile").length > 0 ) {
            clearInterval(expand_timer);
            console.log( "DE: Initializing" );
            Initialize();
            Buttons();
        }
    }, 1000);
}, 1000);