VK comments blacklist

Hides comments from blacklisted users

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         VK comments blacklist
// @namespace    http://tampermonkey.net/
// @version      0.7.0
// @description  Hides comments from blacklisted users
// @author       Akaky Schmalhausen
// @match        https://vk.com/*
// @icon         https://www.google.com/s2/favicons?domain=vk.com
// @grant        none
// @require      http://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==

(function(){
var interval = setInterval(function(){
    let vkIsDefined = typeof(vk) !== 'undefined';
    let bodyIsNode = typeof(document.body) == 'object' && document.body.nodeType;
    if(vkIsDefined && bodyIsNode){
        clearInterval(interval);
        start();
    }
},500);

function start() {
    'use strict';
    vk = vk || {};
    const classUfo = 'vkcbl-ufo';
    const classHidden = 'vkcbl-hidden';
    const classHasButton = 'vkcbl-has-button';
    const classButton = 'vkcbl-btn';
    const yourId = vk.id || '';

    var $ = $ || jQuery;
    var blacklist = window.localStorage.getItem('vkBlacklistIds') || '';
    blacklist = blacklist ? JSON.parse(blacklist) : {};
    var scheduled = false;

    const button = '<button onmouseover="showTitle(this);" style="height:16px; display:inline-block; float:right;margin-bottom: 4px" class="'+classButton+' vkuiInternalTappable vkuiIconButton__host vkuiIconButton__densityCompact vkuiTappable__host vkuiTappable__withBorderOnSmallTabletMinus vkuiTappable__hasPointerNone vkuiClickable__host vkuiClickable__realClickable vkuistyles__focusVisible vkuiRootComponent__host" type="button" data-testid=""></button>';
    const comment = '<div class = "reply reply_dived clear reply_replieable _post '+classUfo+'"></div>';
    const ufo = '<div style="color:#aaa; margin: 7px 12px 7px 48px">НЛО прилетело и оставило здесь эту запись</div>';
    const ufoDeep = '<div style="color:#aaa; margin: 7px 12px 7px 48px">Ребята, не стоит вскрывать эту тему. Вы молодые, шутливые...</div>';

    var buttonToBL = $(button)
    .html('🚫')
    .attr("data-title","В ЧС")
    .on("click",function(e){
        let parent = $(e.target).parents('div[data-testid="wall_comments_comment_in_thread"]').first();
        if(!parent.length) {
            parent = $(e.target).parents('div[data-testid="wall_comments_comment_root"]').first();
        }
        let userid = parent.attr('id').split('_')[0];
        addToBlacklist(userid, false);
        e.stopPropagation();
    });

    var buttonFromBL = $(button)
    .html('🔼')
    .attr("data-title","Убрать из ЧС")
    .on("click", function(e){
        let userid = $(e.target).data('userid');
        forgive(userid);
        e.stopPropagation();
    });

    var buttonUnsee = $(button)
    .html('🤬')
    .attr("data-title","Я пожалел об этом")
    .on("click", function(e){
        let userid = $(e.target).data('userid');
        $("div[id^='"+userid+"_']").removeClass(classHidden);
        addToBlacklist(userid, true)
        e.stopPropagation();
    });

    var buttonShow = $(button)
    .html('👀')
    .attr("data-title","Показать сообщение")
    .on("click", function(e){
        let userid = $(e.target).attr('data-userid');
        let ufo = $(e.target).parents('div.'+classUfo).first()
        let comment = ufo.prev();
        let actions = comment.find('div[class^="vkitCommentBase__actions"]');
        ufo.hide();
        comment.show();
        actions.find('button.'+classButton).remove();
        actions.append(buttonFromBL.clone(true).attr('data-userid',userid));
        if(!blacklist[userid].never){
            actions.append(buttonUnsee.clone(true).attr('data-userid',userid));
        }
        e.stopPropagation();
    });

    function saveToStorage()
    {
        window.localStorage.setItem('vkBlacklistIds', JSON.stringify(blacklist));
    }


    function addToBlacklist(userid, never)
    {
	    blacklist[userid] = {
            "id": userid,
            "blacklisted": true,
            "never": never
        };
	    saveToStorage();
        hideBlacklisted();
    }


	function removeFromBlacklist(userid)
	{
        if(blacklist[userid]){
            delete blacklist[userid];
        }
        saveToStorage();
	}


    function forgive(userid)
    {
		removeFromBlacklist(userid);
        let comment = $("div[id^='"+userid+"_']");
        comment.removeClass(classHidden).show();
        comment.parent().find("div."+classUfo).remove();
        let actions = comment.find('div[class^="vkitCommentBase__actions"]');
        actions.removeClass(classHasButton);
        actions.find('button.'+classButton).remove();
        addButtons();
    }


    function hideBlacklisted()
    {
        for (const [userid, entry] of Object.entries(blacklist)) {
            $("div[id^='"+userid+"_']:not(."+classHidden+")")
            .add($("#pv_box a[data-from-id='"+userid+"']").parents("div[id^='post']:not(."+classHidden+")"))
                .addClass(classHidden)
                .hide()
                .after(
                $(comment).append(
                    $(entry.never ? ufoDeep : ufo)
                    .append(buttonShow.clone(true).attr('data-userid',userid))
                )
            );
        }
    }


    function hideNotifications()
    {
        for (const [userid, entry] of Object.entries(blacklist)) {
            $('div.feedback_row_wrap:has(a[mention_id="id'+userid+'"])').hide();
        }
    }


    function addButtons()
    {
        $("div[id^='"+yourId+"_']").find("div[class^='vkitCommentBase__actions").addClass(classHasButton);
        let posts = $("div[class^='vkitCommentBase__actions']:not(."+classHasButton+")");
        posts.append(buttonToBL.clone(true)).addClass(classHasButton);
    }


    function scheduleRoutine()
    {
        if(!scheduled){
            scheduled = true;
            setTimeout(function(){
                hideBlacklisted();
                addButtons();
                scheduled = false;
            },100);
        }
    }


    var observer = new MutationObserver(function(mrs){
        for (let mr=0; mr<mrs.length; mr++){
            if (mrs[mr].addedNodes.length>0){
                scheduleRoutine();
                break;
            }
        }
    });
    observer.observe(document.body, {childList: true, subtree: true});

/*
    $('body').on('DOMNodeInserted', '#top_notify_wrap', function(e){
        hideNotifications();
    });
*/
}
})();