Iwara Custom Sort

Automatically sort video results in a page on /videos, /images, /subscriptions, /users, and sidebars using customizable sort function.

目前為 2019-02-12 提交的版本,檢視 最新版本

// ==UserScript==
// @name     Iwara Custom Sort
// @version  0.121
// @grant    GM.setValue
// @grant    GM.getValue
// @grant    GM.deleteValue
// @run-at   document-start
// @match    https://ecchi.iwara.tv/*
// @match    https://www.iwara.tv/*
// @match    http://ecchi.iwara.tv/*
// @match    http://www.iwara.tv/*
// @description  Automatically sort video results in a page on /videos, /images, /subscriptions, /users, and sidebars using customizable sort function.
// @namespace https://gf.qytechs.cn/users/245195
// ==/UserScript==

/* jshint esversion: 6 */
'use strict';

const logDebug = (...args) => {
    const debugging = true;
    if (debugging) {
        console.log(...args);
    }
}

logDebug('Parsed.');
logDebug(document.readyState);

const parsePrefixed = (str) => {
    return Number.parseFloat(str) * (str.includes('k') ? 1000 : 1);
}

const getNearbyNumber = (element) => {
    return element ? parsePrefixed(element.parentElement.textContent) : 0;
}

const evalSortValue = (item, valueExpression) => {
    return new Function('views', 'likes', 'ratio', `return (${valueExpression})`)(
        item.viewCount,
        item.likeCount,
        Math.min(item.likeCount / Math.max(1, item.viewCount), 1)
    );
};

const sortVideos = (container, valueExpression) => {
    GM.setValue('sortValue', valueExpression);
    const videoDivs = Array.from(container.querySelectorAll('.clearfix'));
    const videoItem = videoDivs.map((div) => ({
            div,
            viewCount: getNearbyNumber(div.querySelector('.glyphicon-eye-open')),
            likeCount: getNearbyNumber(div.querySelector('.glyphicon-heart')),
        }))
        .sort((itemA, itemB) => evalSortValue(itemB, valueExpression) - evalSortValue(itemA, valueExpression));
    videoDivs.map((div) => {
            const anchor = document.createElement('div');
            div.before(anchor);
            return anchor;
        })
        .forEach((div, index) => div.replaceWith(videoItem[index].div));
};

const sortAllVideos = (containers, sortValueExpression) => {
    let sortedCount = 0;
    try {
        containers.forEach((container) => {
            sortVideos(container, sortValueExpression);
            sortedCount++;
        });
    } catch (message) {
        alert(message);
    }
    logDebug(`${sortedCount} containers sorted.`);
};

const requestMorePages = async (URL, pageCount) => {
    /*
    const params = URL.searchParams;
    const page = params.has('page') ? Number.parseInt(params.get('page')) : 0;
    params.set('page', page + 1);
    try {
      const newPage = await fetch(URL);
      logDebug(page, pageCount, URL, new DOMParser().parseFromString(await newPage.text(), 'text/html'));
    } catch (message) {
      logDebug(message);
    }
    */
}

const init = async () => {
    const videoContainers = Array.from(document.querySelectorAll('.views-responsive-grid'));
    if (videoContainers.length === 0) {
        return;
    }
    if (/\/(videos|images|subscriptions)/.test(location.pathname)) {
        const additionalPageCount = 2;
        requestMorePages(new URL(location), additionalPageCount);
    }
    const sortValueInput = document.createElement('input');
    sortValueInput.type = 'text';
    sortValueInput.maxLength = 80;
    sortValueInput.value = await GM.getValue('sortValue', '100 * ratio + Math.sqrt(likes) / 25');
    const UIDiv = document.createElement('div');
    UIDiv.style.display = 'inline';
    UIDiv.style.margin = '5px';
    const sortButton = document.createElement('button');
    sortButton.innerHTML = 'Sort';
    UIDiv.append(sortValueInput, sortButton);
    sortValueInput.addEventListener('keyup', (event) => {
        if (event.key !== "Enter") {
            return;
        }
        sortButton.click();
        event.preventDefault();
    });
    const temp = document.querySelector('.list-inline');
    if (temp) {
        temp.append(UIDiv);
    } else {
        document.querySelector('#user-links')
            .prepend(UIDiv);
    }
    sortButton.addEventListener('click', () => sortAllVideos(videoContainers, sortValueInput.value));
    sortAllVideos(videoContainers, sortValueInput.value);
};

document.addEventListener('DOMContentLoaded', init);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址