modules/historybutton.js

import $ from 'jquery';

import * as TBApi from '../tbapi.ts';
import * as TBCore from '../tbcore.js';
import * as TBHelpers from '../tbhelpers.js';
import TBListener from '../tblistener.js';
import {Module} from '../tbmodule.jsx';
import * as TBStorage from '../tbstorage.js';
import * as TBui from '../tbui.js';

const self = new Module({
    name: 'History Button',
    id: 'HButton',
    enabledByDefault: true,
    settings: [
        {
            id: 'rtsComment',
            type: 'boolean',
            default: true,
            description: 'Post user summary when submitting spam reports',
        },
        {
            id: 'alwaysComments',
            type: 'boolean',
            default: true,
            advanced: true,
            description: 'Load comment history immediately',
        },
        {
            id: 'commentCount',
            type: 'selector',
            values: ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'],
            default: '1000',
            advanced: true,
            description: 'Number of comments to retrieve per user history',
        },
        {
            id: 'onlyshowInhover',
            type: 'boolean',
            default: () => TBStorage.getSettingAsync('GenSettings', 'onlyshowInhover', true),
            hidden: true,
        },
        {
            id: 'includeNsfwSearches',
            type: 'boolean',
            default: false,
            description: 'Include NSFW submissions in searches',
        },
    ],
}, init);

// This should be a setting, methinks.
self.SPAM_REPORT_SUB = 'spam';
self.fetched = {}; // fetched histories

/**
 * Attach an [H] button to all users
 */

self.attachHistoryButton = function ($target, author, subreddit, buttonText = 'H') {
    requestAnimationFrame(() => {
        $target.append(
            `<a href="javascript:;" class="user-history-button tb-bracket-button" data-author="${author}" ${
                subreddit && `data-subreddit="${subreddit}"`
            } title="view & analyze user's submission and comment history">${buttonText}</a>`,
        );
    });
};

self.runJsAPI = function ({onlyshowInhover}) {
    self.log('run');

    TBListener.on('author', e => {
        const $target = $(e.target);
        // Skip adding the button next to the username if:
        // - the onlyShowInHover preference is set,
        // - we're not on old reddit (since the preference doesn't work there), and
        // - we didn't make the thing the author is on (since the hovercard doesn't show up on constructed things).
        if (onlyshowInhover && !TBCore.isOldReddit && !$target.closest('.tb-thing').length) {
            return;
        }
        const author = e.detail.data.author;
        const subreddit = e.detail.data.subreddit && e.detail.data.subreddit.name;

        if (author === '[deleted]') {
            return;
        }

        self.attachHistoryButton($target, author, subreddit);
    });

    TBListener.on('userHovercard', e => {
        const $target = $(e.target);
        const author = e.detail.data.user.username;
        const subreddit = e.detail.data.subreddit && e.detail.data.subreddit.name;
        self.attachHistoryButton($target, author, subreddit, 'User History');
    });

    window.addEventListener('TBNewPage', event => {
        if (event.detail.pageType === 'userProfile') {
            const user = event.detail.pageDetails.user;
            TBui.contextTrigger('tb-user-history', {
                addTrigger: true,
                triggerText: 'user history',
                triggerIcon: TBui.icons.history,
                title: `Show history for /u/${user}`,
                dataAttributes: {
                    author: user,
                },
            });
        } else {
            TBui.contextTrigger('tb-user-profile', {addTrigger: false});
        }
    });
};

/**
 * Initiate the module
 */
async function init (options) {
    self.log('init');
    const $body = $('body');
    if (!await TBCore.modSubCheck()) {
        self.log('mscheck failed');
        return;
    }

    self.log('mscheck passed');

    self.runJsAPI(options);

    $body.on('click', '.user-history-button, #tb-user-history', function (event) {
        const $this = $(this);
        const $target = $(event.currentTarget);
        const author = $target.attr('data-author');
        const thisSubreddit = $target.attr('data-subreddit');

        const positions = TBui.drawPosition(event);

        const subreddits = {submissions: {}, comments: {}};
        const counters = {submissions: 0, comments: 0, commentsOP: 0};
        const accounts = {};
        const subredditList = [];
        const domainList = [];
        const commentSubredditList = [];

        const gettingUserData = true;
        const domains = [];
        const domainslist = [];

        const popupContent = `
            <div>
                <a href="${TBCore.link(`/user/${author}`)}" target="_blank">${author}</a>
                <span class="karma"></span>
                ${TBui.button('comment history', 'comment-report')}
                ${TBui.button('view report in markdown', 'markdown-report')}
                <button class="rts-report tb-general-button" style="display: none" data-commentbody="">report spammer</button>
                <br/>
                <span class="redditorTime"></span>
                <br/>
                <p class="tb-history-disclaimer">
                    <strong>Disclaimer: </strong> The information shown below is an <i>indication</i> not a complete picture, it lacks the context you would get from having a look at a person's profile.
                </p>
                <b>Available history:</b> <br/>
                <label class="submission-count"></label> submissions
                <br/>
                <span class="tb-history-comment-stats" style="display:none">
                    <label class="comment-count"></label> comments, of those <label class="comment-count-OP"></label> are in their own posts (commented as OP).
                </span>
            </div>
            <div class="history-table-wrapper">
                <div class="table domain-table">
                    <table>
                        <thead>
                            <tr>
                                <th class="url-td">domain submitted from</th>
                                <th class="url-count">count</th><th class="url-percentage">%</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr><td colspan="6" class="error">loading...</td></tr>
                        </tbody>
                    </table>
                </div>
                <div class="table subreddit-table">
                    <table>
                        <thead>
                            <tr>
                                <th class="url-td">subreddit submitted to</th>
                                <th class="url-count">count</th>
                                <th class="url-percentage">%</th>
                                <th class="url-karma">karma</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td colspan="6" class="error">loading...</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
            <div class="history-table-wrapper">
                <div class="table comment-table" style="display: none">
                    <table>
                        <thead>
                            <tr>
                                <th class="url-td">subreddit commented in</th>
                                <th class="url-count">count</th>
                                <th class="url-percentage">%</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr><td colspan="6" class="error">loading...</td></tr>
                        </tbody>
                    </table>
                </div>
                <div class="table account-table">
                    <table>
                        <thead>
                            <tr>
                                <th class="url-td">account submitted from</th>
                                <th class="url-count">count</th>
                                <th class="url-percentage">%</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr><td colspan="6" class="error">loading...</td></tr>
                        </tbody>
                    </table>
                </div>
            </div>
        `;

        const $overlay = $this.closest('.tb-page-overlay');
        let $appendTo;
        if ($overlay.length) {
            $appendTo = $overlay;
        } else {
            $appendTo = $('body');
        }

        const $popup = TBui.popup({
            title: 'History Button',
            tabs: [
                {
                    title: 'Tab1',
                    tooltip: 'Tooltip shown when hovering tab.',
                    content: popupContent,
                    footer: '',
                },
            ],
            cssClass: 'history-button-popup',
            draggable: true,
        }).appendTo($appendTo)
            .css({
                left: positions.leftPosition,
                top: positions.topPosition,
                display: 'block',
            });

        self.fetched[author] = {
            popup: $popup,
            subreddits,
            counters,
            accounts,
            subredditList,
            domainList,
            commentSubredditList,
            author,
            gettingUserData,
            domains,
            domainslist,
        };

        self.showAuthorInformation(author);
        self.populateSubmissionHistory('', author, thisSubreddit, options);

        $popup.on('click', '.markdown-report', self.showMarkdownReport.bind(self, author));
        $popup.on('click', '.rts-report', self.reportAuthorToSpam.bind(self, author, options));
        $popup.on('click.comment-report', '.comment-report', function () {
            $(this).hide();
            $popup.off('click.comment-report');
            self.populateCommentHistory('', author, thisSubreddit, options);
        });

        if (options.alwaysComments) {
            $popup.find('.comment-report').click();
        }
    });
}

/**
 * Show author information (Karma, How long they've been a redditor for)
 */
self.showAuthorInformation = async function (author) {
    const $contentBox = self.fetched[author].popup;

    const d = await TBApi.getJSON(`/user/${author}/about.json`);
    TBStorage.purifyObject(d);
    const joinedDate = new Date(d.data.created_utc * 1000);
    const redditorTime = TBHelpers.niceDateDiff(joinedDate);

    requestAnimationFrame(() => {
        $contentBox.find('.karma').text(`(${d.data.link_karma} | ${d.data.comment_karma})`);
        $contentBox.find('.redditorTime').text(`redditor for ${redditorTime}`);
    });
};

/**
 * Show the markdown report
 */
self.showMarkdownReport = function (author) {
    const $contentBox = self.fetched[author].popup;
    const markdownReport = $contentBox.find('.rts-report').attr('data-commentbody');
    const $markdown = $contentBox.find('.submission-markdown-text');

    if ($markdown.length > 0) {
        $markdown.html(markdownReport).toggle();
    } else {
        $contentBox.find('.table.domain-table').before(`
            <div class="submission-markdown">
                <textarea class="tb-input submission-markdown-text">${markdownReport}</textarea>
            </div>
        `);
    }
};

/**
 * Populate the submission history for a user
 *
 * @param after A token given by reddit for paginated results, allowing us to get the next page of results
 * @param author The author whose history we're fetching
 * @param thisSubreddit The name of the subreddit to highlight in generated tables
 */
self.populateSubmissionHistory = function (after, author, thisSubreddit, options) {
    const user = self.fetched[author];
    const $contentBox = user.popup;
    const $rtsLink = $contentBox.find('.rts-report');
    const $submissionCount = $contentBox.find('.submission-count');
    const $domainTable = $contentBox.find('.domain-table tbody');
    const $subredditTable = $contentBox.find('.subreddit-table tbody');
    const $error = $contentBox.find('.subreddit-table .error, .domain-table .error, .account-table-table .error');
    const $accountTable = $contentBox.find('.account-table tbody');
    const TYPE = {
        PATH: 1, // e.g. example.org/path/user
        SUBDOMAIN: 2, // e.g. user.example.org
    };
    const domainSpecs = {
        // keys are the supported sites, and determine if we have a match
        'flickr.com': {
            path: 'photos/',
            provider: 'flickr',
            type: TYPE.PATH,
        },
        'medium.com': {
            path: '@',
            provider: 'Medium',
            type: TYPE.PATH,
        },
        'speakerdeck.com': {
            provider: 'Speaker Deck',
            type: TYPE.PATH,
        },
        'blogspot.com': {
            provider: 'Blogspot',
            type: TYPE.SUBDOMAIN,
        },
        'tumblr.com': {
            provider: 'Tumblr',
            type: TYPE.SUBDOMAIN,
        },
        'deviantart.com': {
            provider: 'deviantart',
            type: TYPE.SUBDOMAIN,
        },
        'artstation.com': {
            path: 'artwork/',
            provider: 'artstation',
            type: TYPE.PATH,
        },
        'twitter.com': {
            provider: 'Twitter',
            type: TYPE.PATH,
        },
    };

    TBui.longLoadNonPersistent(true);

    TBApi.getJSON(`/user/${author}/submitted.json`, {
        after,
        sort: 'new',
        limit: 100,
    }).catch(() => {
        self.log('Shadowbanned?');
        $error.html('unable to load userdata</br>shadowbanned?');
        TBui.longLoadNonPersistent(false);
    }).then(d => {
        if (!d) {
            return;
        }
        TBStorage.purifyObject(d);
        // This is another exit point of the script. Hits this code after loading 1000 submissions for a user
        if ($.isEmptyObject(d.data.children)) {
            requestAnimationFrame(() => {
                if (user.counters.submissions > 0) {
                    $submissionCount.html(TBStorage.purify(`${user.counters.submissions}+`));
                } else {
                    $submissionCount.html(TBStorage.purify(user.counters.submissions));
                }

                // If the error elements can be seen it is because there are no submissions
                $error.html('no submissions');
            });

            user.gettingUserData = false;

            TBui.longLoadNonPersistent(false);
            return;
        }

        const after = d.data.after;
        let commentBody = `Available submission history for /u/${author}:\n\ndomain submitted from|count|%\n:-|-:|-:`;

        user.counters.submissions += d.data.children.length;
        // There's still more subsmissions to load, so we're going to run again
        if (after) {
            $submissionCount.html(TBStorage.purify(`Loading... (${user.counters.submissions})`));
            self.populateSubmissionHistory(after, author, thisSubreddit, options);
        } else {
            // All of the submissions have been loaded at this point
            user.gettingUserData = false;
            $submissionCount.html(TBStorage.purify(user.counters.submissions));
        }

        TBui.longLoadNonPersistent(false);
        // For every submission, incremenet the count for the subreddit and domain by one.
        d.data.children.forEach(value => {
            const data = value.data;

            if (!user.domains[data.domain]) {
                user.domains[data.domain] = {
                    count: 0,
                };
                user.domainList.push(data.domain);
            }
            user.domains[data.domain].count++;

            if (!user.subreddits.submissions[data.subreddit]) {
                user.subreddits.submissions[data.subreddit] = {
                    count: 0,
                    karma: 0,
                };
                user.subredditList.push(data.subreddit);
            }
            user.subreddits.submissions[data.subreddit].count++;
            user.subreddits.submissions[data.subreddit].karma += data.score;

            if (data.media && data.media.oembed && data.media.oembed.author_url) {
                const oembed = data.media.oembed;

                addAccount({
                    name: oembed.author_name,
                    provider: oembed.provider_name,
                    provider_url: oembed.provider_url,
                    url: oembed.author_url,
                });
            } else {
                let spec = domainSpecs[data.domain];
                let details;
                let domain;

                if (!spec) {
                    // "sub.dom.ain.domain.com" -> "domain.com" (NOTE: does not support "domain.co.uk")
                    domain = data.domain.split('.').slice(-2).join('.');
                    spec = domainSpecs[domain];
                }

                if (spec) {
                    spec.domain = domain || data.domain;
                    details = getDomainDetails(spec, data.url);
                    if (details) {
                        addAccount(details);
                    }
                }
            }
        });

        // Sort the domains by submission count
        user.domainList.sort((a, b) => user.domains[b].count - user.domains[a].count);

        // Empty the domain table
        $domainTable.empty();

        // Get the total account od domain submissions
        let totalDomainCount = 0;

        for (const domain in user.domains) {
            if (Object.prototype.hasOwnProperty.call(user.domains, domain)) {
                totalDomainCount += user.domains[domain].count;
            }
        }

        // Are there more domains than are shown?
        let moreDomains = 0;

        const maybeNsfwParam = options.includeNsfwSearches ? '&include_over_18=on' : '';

        // Append all domains to the table and to the report comment
        user.domainList.forEach((domain, index) => {
            const domainCount = user.domains[domain].count;
            const match = domain.match(/^self.(\w+)$/);
            const percentage = Math.round(domainCount / totalDomainCount * 100);

            let cssClass = '';
            if (percentage >= 10 && domainCount > 4) {
                cssClass = percentage >= 20 ? 'tb-history-row-danger' : 'tb-history-row-warning';
            }

            let url = TBCore.link(
                `/search?q=site%3A${domain}+author%3A${author}+is_self%3A0&restrict_sr=off${maybeNsfwParam}&sort=new&feature=legacy_search`,
            );
            // If the domain is a self post, change the URL
            if (match) {
                url = TBCore.link(
                    `/r/${
                        match[1]
                    }/search?q=author%3A${author}+is_self%3A1&restrict_sr=on${maybeNsfwParam}&sort=new&feature=legacy_search`,
                );
            }

            // Append domain to the table
            requestAnimationFrame(() => {
                $domainTable.append(`
                        <tr class="${cssClass}">
                            <td class="url-td"><a target="_blank" href="${url}" title="view links ${author} recently submitted from '${domain}'">${domain}</a></td>
                            <td class="count-td">${domainCount}</td>
                            <td class="percentage-td">${percentage}%</td>
                        </tr>
                    `);
            });

            // Append the first 20 domains to the report comment
            if (index < 20) {
                commentBody += `\n[${domain}](${url})|${domainCount}|${percentage}%`;
            }
            moreDomains = index;
        });

        // If there were 20 or more domains, append to the report comment that we only displayed 20
        if (moreDomains >= 20) {
            commentBody += `\n\n_^...and ^${user.domainList.length - 20} ^more_`;
        }

        commentBody += '\n\nsubreddit submitted to|count|%\n:-|-:|-:';

        // Sort subreddit list by count
        user.subredditList.sort((a, b) => user.subreddits.submissions[b].count - user.subreddits.submissions[a].count);

        // Empty the subreddit table
        $subredditTable.empty();

        // Get the total count of subreddit submissions
        let totalSubredditCount = 0;
        for (const subreddit of Object.keys(user.subreddits.submissions)) {
            totalSubredditCount += user.subreddits.submissions[subreddit].count;
        }

        // Append a list of subreddits submitted to the subreddit table and to the comment body for reports
        user.subredditList.forEach((subreddit, index) => {
            const subredditCount = user.subreddits.submissions[subreddit].count;
            const subredditKarma = user.subreddits.submissions[subreddit].karma;
            const url = TBCore.link(
                `/r/${subreddit}/search?q=author%3A${author}&restrict_sr=on${maybeNsfwParam}&sort=new&feature=legacy_search`,
            );
            const percentage = Math.round(subredditCount / totalSubredditCount * 100);

            let cssClass = '';
            if (percentage >= 10 && subredditCount > 4) {
                cssClass = percentage >= 20 ? 'tb-history-row-danger' : 'tb-history-row-warning';
            }
            if (subreddit === thisSubreddit) {
                cssClass += ' tb-history-row-current-subreddit';
            }

            requestAnimationFrame(() => {
                $subredditTable.append(`
                        <tr class="${cssClass}">
                            <td class="url-td"><a target="_blank" href="${url}" title="view links ${author} recently submitted to /r/${subreddit}/">${subreddit}</a></td>
                            <td class="count-td">${subredditCount}</td>
                            <td class="percentage-td">${percentage}%</td>
                            <td class="karma-td">${subredditKarma}</td>
                        </tr>
                    `);
            });

            if (index < 20) {
                commentBody += `\n[${subreddit}](${url})|${subredditCount}|${percentage}%`;
            }
        });

        // If there were more than 20 subreddits, we only put the first 20 in the report, and say that there are more
        if (moreDomains >= 20) {
            commentBody += `\n\n_^...and ^${user.subredditList.length - 20} ^more_`;
        }

        $rtsLink.attr('data-commentbody', commentBody);

        tableify(); // TODO: why is this another function? What does it actually do?
    });

    function tableify () {
        // Get the total account of account submissions
        $accountTable.empty();

        const accountList = [];

        for (const account of Object.keys(user.accounts)) {
            accountList.push(account);
        }

        // Sort the domains by submission count
        accountList.sort((a, b) => user.accounts[b].count - user.accounts[a].count);

        accountList.forEach(account => {
            account = user.accounts[account];
            const percentage = Math.round(account.count / user.counters.submissions * 100);
            let cssClass = '';
            if (percentage >= 10 && account.count > 4) {
                cssClass = percentage >= 20 ? 'tb-history-row-danger' : 'tb-history-row-warning';
            }

            requestAnimationFrame(() => {
                $accountTable.append(`
                        <tr class="${cssClass}">
                            <td class="url-td">
                                <a href="${account.url}" target="_blank">${account.name}</a> - <a href="${account.provider_url}" target="_blank">${account.provider}</a>
                            </td>
                            <td class="count-td">${account.count}</td>
                            <td class="percentage-td">${percentage}%</td>
                        </tr>
                    `);
            });
        });
    }

    /**
     * Take an object and add it to `self.accounts`.
     *
     * @param details {Object}
     */
    function addAccount (details) {
        details.url = details.url.replace('https://', 'http://');
        if (!user.accounts[details.url]) {
            user.accounts[details.url] = details;
            user.accounts[details.url].count = 0;
        }
        user.accounts[details.url].count++;
    }

    /**
     * Generate a `details` object that mimics the oembed object to be passed to `addAccount()`.
     *
     * @param spec {Object} from domainSpecs
     * @param url {String}
     * @returns {Object|undefined}
     */
    function getDomainDetails (spec, url) {
        // cache the dynamic rx's
        if (!spec.rx) {
            if (spec.type === TYPE.PATH) {
                spec.rx = new RegExp(`${spec.domain}/${spec.path || ''}([\\w-@]+)`);
            } else if (spec.type === TYPE.SUBDOMAIN) {
                spec.rx = new RegExp(`://([\\w-]+).${spec.domain}`);
            }
        }

        const match = url.match(spec.rx);
        const author = match && match[1];
        let scheme;
        let author_url;
        let provider_url;

        if (author) {
            scheme = `${url.split('://')[0]}://`;
            provider_url = `${scheme + spec.domain}/`;

            if (spec.type === TYPE.PATH) {
                author_url = provider_url + (spec.path || '') + author;
            } else if (spec.type === TYPE.SUBDOMAIN) {
                author_url = `${scheme + author}.${spec.domain}`;
            }

            return {
                name: author,
                provider: spec.provider,
                provider_url,
                url: author_url,
            };
        }
    }
};

self.populateCommentHistory = function (after, author, thisSubreddit, options) {
    TBui.longLoadNonPersistent(true);

    const user = self.fetched[author];
    const $contentBox = user.popup;
    const $commentCount = $contentBox.find('.comment-count');
    const $commentCountOp = $contentBox.find('.comment-count-OP');
    const $commentTable = $contentBox.find('.comment-table tbody');

    $commentTable.empty();

    $contentBox.find('.comment-table').show();
    $contentBox.find('.tb-history-comment-stats').show();
    $commentTable.append(`<tr><td colspan="6" class="error">Loading... (${user.counters.comments})</td></tr>`);

    TBApi.getJSON(`/user/${author}/comments.json`, {
        after,
        sort: 'new',
        limit: 100,
    }).catch(() => {
        $commentTable.find('.error').html('unable to load userdata <br /> shadowbanned?');
        TBui.longLoadNonPersistent(false);
    }).then(d => {
        if (!d) {
            return;
        }
        TBStorage.purifyObject(d);
        d.data.children.forEach(value => {
            const data = value.data;

            if (!user.subreddits.comments[data.subreddit]) {
                user.subreddits.comments[data.subreddit] = {count: 0};
                user.commentSubredditList.push(data.subreddit);
            }

            user.subreddits.comments[data.subreddit].count++;
            user.counters.comments++;

            if (data.link_author === data.author) {
                user.counters.commentsOP++;
            }
        });

        const after = d.data.after;

        if (after && user.counters.comments < Number(options.commentCount)) {
            self.populateCommentHistory(after, author, thisSubreddit, options);
        }

        user.commentSubredditList.sort((a, b) => user.subreddits.comments[b].count - user.subreddits.comments[a].count);

        $commentTable.empty();

        user.commentSubredditList.forEach(subreddit => {
            const count = user.subreddits.comments[subreddit].count;
            const percentage = Math.round(count / user.counters.comments * 100);

            let cssClass = '';
            if (subreddit === thisSubreddit) {
                cssClass += ' tb-history-row-current-subreddit';
            }

            requestAnimationFrame(() => {
                $commentTable.append(`
                        <tr class="${cssClass}">
                            <td>${subreddit}</td><td>${count}</td><td>${percentage}</td>
                        </tr>
                    `);
            });
        });
        // `|| 0` to handle NaN
        const percentageOP = Math.round(user.counters.commentsOP / user.counters.comments * 100) || 0;

        $commentCount.html(TBStorage.purify(user.counters.comments));
        $commentCountOp.html(TBStorage.purify(`${user.counters.commentsOP} (${percentageOP}%)`));

        TBui.longLoadNonPersistent(false);
    });
};

/**
 * Report the use to /r/spam
 */
self.reportAuthorToSpam = function (author, options) {
    const user = self.fetched[author];
    const $contentBox = user.popup;
    const rtsComment = options.rtsComment;
    const $rtsLink = $contentBox.find('.rts-report');
    const rtsNativeLink = $rtsLink.get(0);
    const commentBody = rtsNativeLink.getAttribute('data-commentbody');

    rtsNativeLink.textContent = 'Submitting...';
    rtsNativeLink.className = '.rts-report-clicked';

    // Submit to RTS
    const link = `https://www.reddit.com/user/${author}`;
    const title = `Overview for ${author}`;

    TBApi.postLink(link, title, self.SPAM_REPORT_SUB).then(submission => {
        if (submission.json.errors.length) {
            $rtsLink.after(`<span class="error" style="font-size:x-small">${submission.json.errors[0][1]}</error>`);
            // $rtsLink.hide();
            if (submission.json.errors[0][0] === 'ALREADY_SUB') {
                rtsNativeLink.href = TBCore.link(
                    `/r/${self.SPAM_REPORT_SUB}/search?q=http%3A%2F%2Fwww.reddit.com%2Fuser%2F${author}&restrict_sr=on&feature=legacy_search`,
                );
            }
            return;
        }

        // Post stats as a comment.
        if (!commentBody.length || !rtsComment) {
            rtsNativeLink.textContent = 'reported';
            rtsNativeLink.href = submission.json.data.url;
            rtsNativeLink.className = 'tb-general-button';
            return;
        }

        TBApi.postComment(submission.json.data.name, commentBody).then(comment => {
            // $rtsLink.hide();
            if (comment.json.errors.length) {
                $rtsLink.after(
                    `<span class="error" style="font-size:x-small; cursor: default;">${comment.json.errors[1]}</error>`,
                );
                // $rtsLink.hide();
                return;
            }
            rtsNativeLink.textContent = 'reported';
            rtsNativeLink.href = submission.json.data.url;
            rtsNativeLink.className = 'tb-general-button';
        }).catch(error => {
            $rtsLink.after(
                `<span class="error" style="font-size:x-small; cursor: default;">an error occurred. ${
                    error[0][1]
                }</span>`,
            );
        });
    }).catch(error => {
        $rtsLink.after(
            `<span class="error" style="font-size:x-small; cursor: default;">an error occurred: ${error[0][1]}</span>`,
        );
    });
};

export default self;