SpankBang - Search and UI Enhancer

Various search filters and user experience enhancers

24.10.2022 itibariyledir. En son verisyonu görün.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

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

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

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.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         SpankBang - Search and UI Enhancer
// @namespace    brazenvoid
// @version      1.1.1
// @author       brazenvoid
// @license      GPL-3.0-only
// @description  Various search filters and user experience enhancers
// @match        https://spankbang.com/*
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js
// @require      https://greasyfork.org/scripts/375557-base-resource/code/Base%20Resource.js?version=899286
// @require      https://greasyfork.org/scripts/416104-brazen-ui-generator/code/Brazen%20UI%20Generator.js?version=899448
// @require      https://greasyfork.org/scripts/418665-brazen-configuration-manager/code/Brazen%20Configuration%20Manager.js?version=892799
// @require      https://greasyfork.org/scripts/416105-brazen-base-search-enhancer/code/Brazen%20Base%20Search%20Enhancer.js?version=899428
// @grant        GM_addStyle
// @run-at       document-end
// ==/UserScript==

GM_addStyle(
    `button.show-settings{height:60vh;top:20vh}#settings-wrapper{top:20vh;width:300px}.bg-brand{background-color:#69150d}.font-primary{color:white}.font-secondary{color:black}hr{background:white}`);

const PAGE_PATH_NAME = window.location.pathname;
const PAGE_PATH_FRAGMENTS = PAGE_PATH_NAME.split('/');

const IS_HOME_PAGE = PAGE_PATH_NAME === '/';
const IS_VIDEO_PAGE = PAGE_PATH_FRAGMENTS[2] === 'video' || PAGE_PATH_FRAGMENTS[2] === 'playlist';

const ITEM_CLASSES = 'div.video-item';
const ITEM_LISTS_SELECTOR = 'div.video-list';
const ITEM_TEXT_NODE_SELECTOR = 'a.n';

const SCRIPT_PREFIX = 'sb-sui-';

// Configuration

const FILTER_VIDEOS_SD = 'Show Only HD Videos';
const FILTER_VIDEOS_DURATION = 'Duration';
const FILTER_VIDEOS_MAXIMUM_AGE = 'Maximum Age';
const FILTER_VIDEOS_MAXIMUM_AGE_UNIT = 'Maximum Age Unit';
const FILTER_VIDEOS_MINIMUM_AGE = 'Minimum Age';
const FILTER_VIDEOS_MINIMUM_AGE_UNIT = 'Minimum Age Unit';
const FILTER_VIDEOS_RATING = 'Rating';
const FILTER_VIDEOS_VIEWS = 'Views';

const UI_REMOVE_AD_BOX_VIDEO_LISTS = 'Remove Ad in Video Lists';
const UI_REMOVE_EMBED_VIDEO_SECTION = 'Remove Embed Video Section';
const UI_REMOVE_LIVE_MODEL_SECTIONS = 'Remove Live Model Sections';
const UI_REDIRECT_SUBSCRIPTIONS_LINK = 'Redirect Subscriptions Link';
const UI_REPOSITION_SCREENSHOTS = 'Reposition Video Screenshots';
const UI_REPOSITION_VIDEO_DETAILS = 'Reposition Video Details';
const UI_SWAP_RELATED_VIDEOS = 'Reposition Related Videos';

// Item attributes

const ITEM_AGE = 'scriptAge';
const ITEM_DURATION = 'scriptDuration';
const ITEM_RATING = 'scriptRating';
const ITEM_RESOLUTION = 'scriptResolution';
const ITEM_VIEWS = 'scriptViews';

class SpankBangSearchAndUIEnhancer extends BrazenBaseSearchEnhancer
{
    constructor()
    {
        super(SCRIPT_PREFIX, ITEM_CLASSES);

        this._configurationManager.
            addFlagField(FILTER_VIDEOS_SD, 'Filter videos of less than 720p resolution.').
            addFlagField(UI_REMOVE_AD_BOX_VIDEO_LISTS, 'Removes the ad box found in the first row of videos lists.').
            addFlagField(UI_REMOVE_EMBED_VIDEO_SECTION, 'Removes embed video section on video pages.').
            addFlagField(UI_REMOVE_LIVE_MODEL_SECTIONS, 'Removes live model sections from the site.').
            addFlagField(UI_REDIRECT_SUBSCRIPTIONS_LINK, 'Redirects subscription videos page shortcut on user bar to new subscribed videos view.').
            addFlagField(UI_REPOSITION_SCREENSHOTS, 'Move video screenshots above video player on video pages.').
            addFlagField(UI_REPOSITION_VIDEO_DETAILS, 'Move video details section to the top of the right pane.').
            addFlagField(UI_SWAP_RELATED_VIDEOS, 'Swaps related videos section with comments section').
            addNumberField(FILTER_VIDEOS_MAXIMUM_AGE, 0, 100, 'Maximum age filter value.').
            addNumberField(FILTER_VIDEOS_MINIMUM_AGE, 0, 100, 'Minimum age filter value.').
            addRangeField(FILTER_VIDEOS_DURATION, 0, 100000, 'Filter videos by duration in minutes.').
            addRangeField(FILTER_VIDEOS_RATING, 0, 100, 'Filter videos by duration.').
            addRangeField(FILTER_VIDEOS_VIEWS, 0, 9999999999, 'Filter videos by view count.');

        this._setupUI();
        this._setupCompliance();
        this._setupComplianceFilters();
    }

    _analyseItem(item)
    {
        let durationBadge = item.find('span.l')
        item[0][ITEM_DURATION] = durationBadge.length ? parseInt(durationBadge.text().replace('m', '')) : null;

        let resolutionBadge = item.find('span.h')
        item[0][ITEM_RESOLUTION] = resolutionBadge.length ? resolutionBadge.text() : 'SD';

        let stats = item.find('div.stats > .v.d');
        if (stats.length) {
            stats = stats.html().trim().split('   ')
          console.log(stats)
            item[0][ITEM_VIEWS] = stats[0];
            item[0][ITEM_RATING] = stats[1];
        } else {
            item[0][ITEM_RATING] = null;
            item[0][ITEM_VIEWS] = null;
        }
    }

    /**
     * @private
     */
    _redirectSubscriptionsLink()
    {
        if (this._configurationManager.getValue(UI_REDIRECT_SUBSCRIPTIONS_LINK)) {
            $('a[href="/users/social"]').attr('href', '/users/social?sort=new');
        }
    }

    _removeAdBoxInVideoLists()
    {
        if (this._configurationManager.getValue(UI_REMOVE_AD_BOX_VIDEO_LISTS)) {
            $(ITEM_CLASSES + ' ins').parent().remove();
        }
    }

    /**
     * @private
     */
    _removeEmbedVideoSection()
    {
        if (this._configurationManager.getValue(UI_REMOVE_EMBED_VIDEO_SECTION)) {
            $('.embed').remove();
        }
    }

    /**
     * @private
     */
    _removeLiveModelSections()
    {
        if (this._configurationManager.getValue(UI_REMOVE_EMBED_VIDEO_SECTION)) {
            let liveModelsSection = $('.lv_cm_cl_mx_why');
            if (IS_HOME_PAGE) {
                liveModelsSection.prev().remove();
                liveModelsSection.next().remove();
            }
            liveModelsSection.remove();
        }
    }

    /**
     * @return {JQuery<HTMLElement> | jQuery | HTMLElement}
     * @private
     */
    _generatePseudoLeftSection()
    {
        return $('<div class="left" style="padding: 23px 0 0 0"></div>');
    }

    /**
     * @private
     */
    _repositionVideoDetails()
    {
        if (this._configurationManager.getValue(UI_REPOSITION_VIDEO_DETAILS)) {
            let rightPane = $('div.right');

            let pseudoLeftSection = this._generatePseudoLeftSection();
            rightPane.prepend(pseudoLeftSection);
            pseudoLeftSection.append($('div.left section.details'));
        }
    }

    /**
     * @private
     */
    _repositionVideoScreenshots()
    {
        if (this._configurationManager.getValue(UI_REPOSITION_SCREENSHOTS)) {
            $('div.left section.timeline').insertBefore('#player_wrapper_outer');
        }
    }

    /**
     * @private
     */
    _setupCompliance()
    {
        this._onGetItemLists = () => $(ITEM_LISTS_SELECTOR);

        this._onGetItemName = (videoItem) => videoItem.find(ITEM_TEXT_NODE_SELECTOR).text();

        this._onFirstHitBeforeCompliance = (item) => this._analyseItem(item);

        this._onFirstHitAfterCompliance = (item) => {
            Validator.sanitizeTextNode(item.find(ITEM_TEXT_NODE_SELECTOR), this._configurationManager.getFieldOrFail(FILTER_TEXT_SANITIZATION).optimized);
        };
    }

    /**
     * @private
     */
    _setupComplianceFilters()
    {
        this._addItemTextSanitizationFilter(
            'Censor video names by substituting offensive phrases. Each rule in separate line with comma separated target phrases. Example Rule: boyfriend=stepson,stepdad');

        this._addItemWhitelistFilter('Show videos with specified phrases in their names. Separate the phrases with line breaks.');

        this._addItemTextSearchFilter();

        this._addItemComplianceFilter(FILTER_VIDEOS_RATING, (item, range) =>
            item[0][ITEM_RATING] ? Validator.isInRange(item[0][ITEM_RATING], range.minimum, range.maximum) : true);

        this._addItemComplianceFilter(FILTER_VIDEOS_DURATION, (item, range) =>
            Validator.isInRange(item[0][ITEM_DURATION], range.minimum, range.maximum))

        this._addItemComplianceFilter(FILTER_VIDEOS_VIEWS, (item, range) => {
            let viewsString = item[0][ITEM_VIEWS];
            if (!viewsString) {
                return true;
            }
            let viewsAmount = parseFloat(viewsString.replace('K', '').replace('M', '').replace('B', ''));
            if (viewsString.endsWith('K')) {
                viewsAmount *= 1000;
            } else {
                if (viewsString.endsWith('M')) {
                    viewsAmount *= 1000000;
                } else {
                    if (viewsString.endsWith('B')) {
                        viewsAmount *= 1000000000;
                    }
                }
            }
            return Validator.isInRange(viewsAmount, range.minimum, range.maximum);
        });

        this._addItemComplianceFilter(FILTER_VIDEOS_SD, (item) => Validator.doesChildExist(item, 'span.h'));

        this._addItemBlacklistFilter('Hide videos with specified phrases in their names. Separate the phrases with line breaks.');
    }

    /**
     * @private
     */
    _setupUI()
    {
        this._onBeforeUIBuild = () => {
            this._redirectSubscriptionsLink();
            this._removeLiveModelSections();
            this._removeAdBoxInVideoLists();

            if (IS_VIDEO_PAGE) {
                this._removeEmbedVideoSection();
                this._repositionVideoDetails();
                this._repositionVideoScreenshots();
                this._swapRelatedVideos();
                Validator.sanitizeNodeOfSelector('div.video > div.left > h1', this._configurationManager.getFieldOrFail(FILTER_TEXT_SANITIZATION).optimized);
            }
        };

        this._onUIBuild = () =>
            this._uiGen.createSettingsSection().append([
                this._uiGen.createTabsSection(['Filters', 'Text', 'UI', 'Global', 'Stats'], [
                    this._uiGen.createTabPanel('Filters', true).append([
                        this._configurationManager.createElement(FILTER_VIDEOS_DURATION),
                        this._configurationManager.createElement(FILTER_VIDEOS_RATING),
                        this._configurationManager.createElement(FILTER_VIDEOS_VIEWS),
                        this._configurationManager.createElement(FILTER_VIDEOS_SD),
                        this._uiGen.createSeparator(),
                        this._configurationManager.createElement(OPTION_DISABLE_COMPLIANCE_VALIDATION),
                    ]),
                    this._uiGen.createTabPanel('Text').append([
                        this._configurationManager.createElement(FILTER_TEXT_SEARCH),
                        this._configurationManager.createElement(FILTER_TEXT_BLACKLIST),
                        this._configurationManager.createElement(FILTER_TEXT_WHITELIST),
                        this._configurationManager.createElement(FILTER_TEXT_SANITIZATION),
                    ]),
                    this._uiGen.createTabPanel('UI').append([
                        this._configurationManager.createElement(UI_REMOVE_AD_BOX_VIDEO_LISTS),
                        this._configurationManager.createElement(UI_REDIRECT_SUBSCRIPTIONS_LINK),
                        this._configurationManager.createElement(UI_REMOVE_EMBED_VIDEO_SECTION),
                        this._configurationManager.createElement(UI_REMOVE_LIVE_MODEL_SECTIONS),
                        this._configurationManager.createElement(UI_SWAP_RELATED_VIDEOS),
                        this._configurationManager.createElement(UI_REPOSITION_VIDEO_DETAILS),
                        this._configurationManager.createElement(UI_REPOSITION_SCREENSHOTS),
                        this._uiGen.createSeparator(),
                        this._configurationManager.createElement(OPTION_ALWAYS_SHOW_SETTINGS_PANE),
                    ]),
                    this._uiGen.createTabPanel('Global').append([
                        this._createSettingsBackupRestoreFormActions(),
                    ]),
                    this._uiGen.createTabPanel('Stats').append([
                        this._uiGen.createStatisticsFormGroup(FILTER_VIDEOS_DURATION),
                        this._uiGen.createStatisticsFormGroup(FILTER_VIDEOS_RATING),
                        this._uiGen.createStatisticsFormGroup(FILTER_VIDEOS_VIEWS),
                        this._uiGen.createStatisticsFormGroup(FILTER_VIDEOS_SD),
                        this._uiGen.createStatisticsFormGroup(FILTER_TEXT_SEARCH),
                        this._uiGen.createStatisticsFormGroup(FILTER_TEXT_BLACKLIST),
                        this._uiGen.createStatisticsFormGroup(FILTER_TEXT_WHITELIST),
                        this._uiGen.createSeparator(),
                        this._uiGen.createStatisticsTotalsGroup(),
                    ]),
                ]),
                this._createSettingsFormActions(),
                this._uiGen.createSeparator(),
                this._uiGen.createStatusSection(),
            ]);

        this._onAfterUIBuild = () => {
            this._uiGen.getSelectedSection()[0].userScript = this;
        };
    }

    /**
     * @private
     */
    _swapRelatedVideos()
    {
        if (this._configurationManager.getValue(UI_SWAP_RELATED_VIDEOS)) {
            let newRelatedVideosSection = $('<section class="user_uploads"></section>');
            newRelatedVideosSection.insertAfter('section.all_comments');
            newRelatedVideosSection.append('<h2>Similar Videos</h2>');
            newRelatedVideosSection.append($('.similar div.video-list'));
            $('.similar').remove();

            let pseudoLeftSection = this._configurationManager.getValue(UI_REPOSITION_VIDEO_DETAILS) ? $('div.right div.left') : this._generatePseudoLeftSection();
            pseudoLeftSection.append($('section.all_comments'));
        }
    }
}

(new SpankBangSearchAndUIEnhancer).init();