E-Hentai - UX Tweaks

Complex tag highlights and blacklisting

Versione datata 26/09/2023. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         E-Hentai - UX Tweaks
// @namespace    brazenvoid
// @version      1.2.3
// @author       brazenvoid
// @license      GPL-3.0-only
// @description  Complex tag highlights and blacklisting
// @match        https://e-hentai.org/*
// @match        https://exhentai.org/*
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
// @require      https://greasyfork.org/scripts/375557-base-brazen-resource/code/Base%20Brazen%20Resource.js?version=1244990
// @require      https://greasyfork.org/scripts/416104-brazen-ui-generator/code/Brazen%20UI%20Generator.js?version=1256211
// @require      https://greasyfork.org/scripts/418665-brazen-configuration-manager/code/Brazen%20Configuration%20Manager.js?version=1245040
// @require      https://greasyfork.org/scripts/429587-brazen-item-attributes-resolver/code/Brazen%20Item%20Attributes%20Resolver.js?version=1244644
// @require      https://greasyfork.org/scripts/416105-brazen-base-search-enhancer/code/Brazen%20Base%20Search%20Enhancer.js?version=1256208
// @grant        GM_addStyle
// @run-at       document-end
// ==/UserScript==

GM_addStyle(
    `#settings-wrapper{min-width:270px;width:270px}.disliked-tag{background-color:lightcoral !important;color:white !important}.disliked-tag:hover{background-color:indianred !important}.disliked-tag > a{color:white !important}.disliked-tag.favourite-tag{background-color:orange !important}.disliked-tag.favourite-tag:hover{background-color:darkorange !important}.favourite-tag{background-color:mediumseagreen !important;color:white !important}.favourite-tag:hover{background-color:forestgreen !important}.favourite-tag > a{color:white !important}`)

const IS_GALLERY_PAGE = $('#gdt').length
const IS_SMALL_WINDOW = $('.stuffbox').length

const UI_FAVOURITE_TAGS = 'Favourite Tags'
const UI_DISLIKED_TAGS = 'Disliked Tags'
const UI_VISITED_HIGHLIGHT = 'Highlight Visited'
const UI_AUTO_NEXT_ON_OPEN_ALL_IMAGES = 'Auto Next Page'

class EHentaiSearchAndUITweaks extends BrazenBaseSearchEnhancer
{
    constructor()
    {
        super({
            isUserLoggedIn: false,
            itemDeepAnalysisSelector: '',
            itemLinkSelector: 'td.gl3m.glname > a, td.gl3c.glname > a, div.gl2e > div > a, a',
            itemListSelectors: 'table.itg, div.itg',
            itemNameSelector: 'td.gl3m.glname > a > div.glink, td.gl3c.glname > a > div.glink, div.gl4e.glname > div.glink, div.gl4t.glname.glink',
            itemSelectors: 'td.gl2e, div.gl1t',
            requestDelay: 0,
            scriptPrefix: 'e-hentai-ux-',
            tagSelectorGenerator: (tag) => {
                tag = tag.trim()
                if (IS_GALLERY_PAGE) {
                    return 'div[id="td_' + tag.replace(' ', '_') + '"]'
                }
                return 'div.gt[title="' + tag + '"], div.gtl[title="' + tag + '"]'
            },
        })
        this._setupFeatures()
        this._setupUI()
        this._setupEvents()
    }

    _setupEvents()
    {
        this._onValidateInit = () => !IS_SMALL_WINDOW

        this._onBeforeUIBuild.push(() => this._performOperation(
            UI_VISITED_HIGHLIGHT, () => GM_addStyle(`td.gl2e > div > a:visited > .glname > .glink {color: black;}`)))

        this._onAfterUIBuild.push(() => this._uiGen.getSelectedSection()[0].userScript = this)

        this._onItemHide = (item) => {
            if (item.is('td.gl2e')) {
                item.parent().addClass('noncompliant-item')
                item.parent().hide()
            } else {
                item.removeClass('noncompliant-item')
                item.hide()
            }
        }

        this._onItemShow = (item) => {
            if (item.is('td.gl2e')) {
                item.parent().removeClass('noncompliant-item')
                item.parent().show()
            } else {
                item.removeClass('noncompliant-item')
                item.show()
            }
        }
    }

    /**
     * @private
     */
    _setupFeatures()
    {
        this._configurationManager
            .addFlagField(UI_AUTO_NEXT_ON_OPEN_ALL_IMAGES, 'Automatically navigates to the next page after opening all images.')
            .addFlagField(UI_VISITED_HIGHLIGHT, 'Colours the visited gallery links black, to make them distinct.')

        let otherTagSections = IS_GALLERY_PAGE ? $('#taglist') : null

        this._addItemTagHighlights(UI_FAVOURITE_TAGS, otherTagSections, 'favourite-tag', 'Specify favourite tags to highlight.', 10)
        this._addItemTagHighlights(UI_DISLIKED_TAGS, otherTagSections, 'disliked-tag', 'Specify disliked tags to highlight.', 10)
        this._addItemTagBlacklistFilter(20)
    }

    /**
     * @private
     */
    _setupUI()
    {
        let openGalleryPages = []
        if (IS_GALLERY_PAGE) {
            openGalleryPages = [
                this._uiGen.createSeparator(),
                this._uiGen.createFormButton(
                    'Open Gallery Images',
                    'Opens all images on current page of this gallery.',
                    () => {

                        let images = $('div.gdtl a > img, div.gdtm a > img')
                        let firstPage = images.first().attr('alt')
                        let firstPageNumber = Number(firstPage)
                        let paddedPageLength = firstPage.length
                        let maxPages = firstPageNumber + images.length - 1

                        for (let page = maxPages; page >= firstPageNumber; page--) {

                            let paddedPage = page.toString().padStart(paddedPageLength, '0')
                            window.open(images.filter('[alt="' + paddedPage + '"]').parent().attr('href'))
                        }

                        if (this._getConfig(UI_AUTO_NEXT_ON_OPEN_ALL_IMAGES)) {

                            let page = window.location.href.split('=')[1]
                            if (typeof page === 'undefined') {
                                page = 0
                            }

                            let pageNavs = $('.ptt td')
                            let maxPages = Number.parseInt(pageNavs.eq(pageNavs.length - 2).children('a').attr('href').split('=')[1])
                            if (typeof maxPages === 'undefined') {
                                maxPages = 1
                            }

                            if (maxPages > 1 && page < maxPages) {

                                let uri = window.location.href
                                if (page === 0) {
                                    uri += '?p=1'
                                } else {
                                    uri = uri.replace('?p=' + page++, '?p=' + page)
                                }
                                window.location = uri
                            }
                        }
                    }),
                this._uiGen.createBreakSeparator(),
                this._configurationManager.createElement(UI_AUTO_NEXT_ON_OPEN_ALL_IMAGES),
            ]
        }

        this._userInterface = [
            this._uiGen.createTabsSection(['Filters', 'Highlights', 'Global'], [
                this._uiGen.createTabPanel('Filters', true).append([
                    this._configurationManager.createElement(OPTION_ENABLE_BLACKLIST),
                    this._configurationManager.createElement(FILTER_TAG_BLACKLIST),
                    // this._uiGen.createSeparator(),
                    // this._configurationManager.createElement(OPTION_DISABLE_COMPLIANCE_VALIDATION),
                ]),
                this._uiGen.createTabPanel('Highlights').append([
                    this._configurationManager.createElement(UI_FAVOURITE_TAGS),
                    this._configurationManager.createElement(UI_DISLIKED_TAGS),
                ]),
                this._uiGen.createTabPanel('Global').append([
                    this._configurationManager.createElement(UI_VISITED_HIGHLIGHT),
                    this._configurationManager.createElement(OPTION_ALWAYS_SHOW_SETTINGS_PANE),
                    this._uiGen.createSeparator(),
                    this._createSettingsBackupRestoreFormActions(),
                ]),
            ]),
            this._uiGen.createStatisticsFormGroup(FILTER_TAG_BLACKLIST),
            ...openGalleryPages,
            this._uiGen.createSeparator(),
            // this._uiGen.createStatisticsTotalsGroup(),
            this._createSettingsFormActions(),
            this._uiGen.createSeparator(),
            this._uiGen.createStatusSection(),
        ]
    }
}

(new EHentaiSearchAndUITweaks).init()