Greasy Fork

Greasy Fork is available in English.

HiAnime Dark Theme

Dark themes with other features! Fun fact: this project started as for hianime to look like crunchy roll (i gave up on that and made this instead!)

当前为 2024-12-19 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         HiAnime Dark Theme
// @namespace    https://hianime.to/
// @version      2.0
// @description  Dark themes with other features! Fun fact: this project started as for hianime to look like crunchy roll (i gave up on that and made this instead!)
// @author       Jet
// @match        *://hianime.to/*
// @icon         https://www.crunchyroll.com/favicon.ico
// @grant        none
// @run-at       document-end
// @license     GNU GPLv3
// ==/UserScript==

(function () {
    'use strict';

    // CSS to inject for dark theme, text color, visible buttons and removing spotlight
    const darkThemeCSS = `
        body {
            background-color: #121212;
            color: #1ABDBB;
            font-family: 'Arial', sans-serif;
        }

        a {
            color: #1ABDBB;
        }

        a:hover {
            color: #33B8C8;
        }

        button, .button, .menu-item, .anime-card, .card {
            background-color: #333;
            color: #1ABDBB;
            padding: 10px 20px;
            cursor: pointer;
            transition: all 0.3s ease;
            border: none; /* Remove border */
            border-radius: 12px;
        }

        button:hover, .button:hover, .menu-item:hover, .anime-card:hover, .card:hover {
            background-color: #444;
            box-shadow: 0 0 0 4px #33B8C8 inset; /* Change shadow color on hover */
        }

        input, textarea, select {
            background-color: #222;
            color: #1ABDBB;
            border: none; /* Remove border */
            padding: 8px 12px;
            border-radius: 8px;
        }

        input:focus, textarea:focus, select:focus {
            box-shadow: 0 0 0 2px #33B8C8 inset; /* Change shadow color on focus */
            outline: none;
        }

        img, .anime-card img {
            border-radius: 8px;
            border: none; /* Remove border */
        }

        .d_w-icon {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        #header, .header, .navbar {
            background-color: #1c1c1c;
            padding: 10px 20px;
            border-radius: 10px;
        }

        .sidebar {
            background-color: #222;
            border-radius: 10px;
            padding: 15px;
            position: fixed;
            right: -300px;
            top: 0;
            width: 250px;
            height: 100%;
            transition: all 0.3s ease;
            z-index: 9999;
            opacity: 1;
            overflow-y: auto;
            display: flex;
            flex-direction: column;
        }

        .sidebar.open {
            right: 0;
        }

        .sidebar .hst-item {
            margin-bottom: 20px;
        }

        .sidebar .hst-icon {
            color: #1ABDBB;
            font-size: 24px;
        }

        .sidebar .hst-item .description {
            color: #ccc;
            font-size: 12px;
        }

        footer, .footer-wrapper {
            background-color: #1c1c1c;
            color: #999;
            padding: 10px 20px;
            text-align: center;
            border-radius: 10px;
        }

        .anime-card, .card {
            background-color: #333;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
            transition: transform 0.3s ease;
        }

        .anime-card:hover, .card:hover {
            transform: scale(1.05);
        }

        .swiper-slide {
            background-color: #333;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
        }

        /* Hide spotlight */
        .deslide-item .desi-sub-text:contains('Spotlight'),
        .deslide-item .tick-item:contains('Spotlight') {
            display: none !important;
        }

        .deslide-wrap {
            display: none !important;
        }

        .fixed {
            background-color: transparent !important;
        }

        .three-dots {
            font-size: 30px;
            cursor: pointer;
            color: #1ABDBB;
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 10000;
        }

        .select-anime-name {
            background-color: #333;
            border-radius: 8px;
            color: #1ABDBB;
            margin-top: auto; /* Push it to the bottom */
        }

        /* Ensure sidebar is focusable and accessible */
        .sidebar a, .sidebar button {
            outline: none;
        }

        .sidebar a:focus, .sidebar button:focus {
            box-shadow: 0 0 0 3px #33B8C8 inset; /* Highlight focused elements */
        }
         #user-buttons {
            position: fixed;
            bottom: 20px;
            left: 20px;
            display: flex;
            gap: 10px;
            z-index: 10000;
        }

        #user-buttons button {
            padding: 10px 15px;
            background-color: #1ABDBB;
            color: #121212;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
            transition: background-color 0.3s ease;
        }

        #user-buttons button:hover {
            background-color: #33B8C8;
        }
     #popup {
            position: fixed;
            bottom: 100px;
            left: 50%;
            transform: translateX(-50%);
            background-color: #333;
            color: #1ABDBB;
            padding: 15px 20px;
            border-radius: 10px;
            font-size: 14px;
            font-weight: bold;
            text-align: center;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
            z-index: 10001;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease, transform 0.3s ease;
        }

        #popup.show {
            opacity: 1;
            pointer-events: auto;
            transform: translateX(-50%) translateY(-10px);
        }

        .continue-watching-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            margin: 10px;
            padding: 10px;
            background-color: #222;
            border-radius: 10px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
        }
        .continue-watching-title {
            color: #1ABDBB;
            font-size: 16px;
            font-weight: bold;
            margin-bottom: 10px;
        }
        .continue-watching-button {
            display: flex;
            flex-direction: column;
            align-items: center;
            text-decoration: none;
            color: inherit;
        }
        .continue-watching-poster {
            width: 150px;
            height: 200px;
            border-radius: 8px;
            margin-bottom: 5px;
        }
        .continue-watching-episode {
            font-size: 14px;
            color: #ccc;
        }
    `;

    const styleElement = document.createElement('style');
    styleElement.innerHTML = darkThemeCSS;
    document.head.appendChild(styleElement);

    async function fetchContinueWatching() {
        try {
            const response = await fetch('https://hianime.to/user/continue-watching');
            const text = await response.text();
            const parser = new DOMParser();
            const doc = parser.parseFromString(text, 'text/html');
            const firstItem = doc.querySelector('.flw-item');

            if (firstItem) {
                const posterImg = firstItem.querySelector('.film-poster-img').src;
                const episode = firstItem.querySelector('.tick-item.tick-eps').textContent;
                const titleLink = firstItem.querySelector('.film-name a');
                const title = titleLink.textContent;
                const url = titleLink.href;

                return { posterImg, episode, title, url };
            }
        } catch (error) {
            console.error('Error fetching Continue Watching data:', error);
        }
        return null;
    }

    async function createContinueWatchingContainer(side) {
        const data = await fetchContinueWatching();
        if (!data) return;

        const container = document.createElement('div');
        container.className = 'continue-watching-container';

        container.innerHTML = `
            <div class="continue-watching-title">Continue Watching</div>
            <a href="${data.url}" class="continue-watching-button">
                <img src="${data.posterImg}" alt="${data.title}" class="continue-watching-poster">
                <div>${data.title}</div>
                <div class="continue-watching-episode">Episode: ${data.episode}</div>
            </a>
        `;

        const parent = document.querySelector('.d_w-icon').parentElement;
        if (side === 'left') {
            parent.insertBefore(container, document.querySelector('.d_w-icon'));
        } else if (side === 'right') {
            parent.appendChild(container);
        }
    }

    createContinueWatchingContainer('left');
    createContinueWatchingContainer('right');

        function showPopup(message) {
            let popup = document.querySelector('#popup');
            if (!popup) {
                popup = document.createElement('div');
                popup.id = 'popup';
                document.body.appendChild(popup);
            }
            popup.textContent = message;
            popup.classList.add('show');
            setTimeout(() => popup.classList.remove('show'), 3000);
        }
    
        // Ensure remaining elements are hidden
        ['.deslide-wrap', '.d_w-list', '.zrg-title', '.zrg-list', '.header-setting', '.hs-toggles']
            .forEach(selector => {
                const element = document.querySelector(selector);
                if (element) element.remove();
            });
    })();

    const deslideWrapElement = document.querySelector('.deslide-wrap');
    if (deslideWrapElement) {
        deslideWrapElement.remove();
    }

    const dwlistElement = document.querySelector('.d_w-list');
    if (dwlistElement) {
        dwlistElement.remove();
    }

    const zrgTitleElement = document.querySelector('.zrg-title');
    if (zrgTitleElement) {
        zrgTitleElement.remove();
    }

    const zrgListElement = document.querySelector('.zrg-list');
    if (zrgListElement) {
        zrgListElement.remove();
    }

    const headerSettingElement = document.querySelector('.header-setting');
    if (headerSettingElement) {
        headerSettingElement.remove();
    }

    const hsTogglesElement = document.querySelector('.hs-toggles');
    if (hsTogglesElement) {
        hsTogglesElement.remove();
    }

    // Add Copy ID and Profile buttons
    if (window.location.href.includes('/user/profile')) {
        const buttonContainer = document.createElement('div');
        buttonContainer.id = 'user-buttons';

        const copyIdButton = document.createElement('button');
        copyIdButton.textContent = 'Copy ID';
        copyIdButton.addEventListener('click', () => {
            showPopup('This feature is not yet supported! Check back later!');
        });

        const profileButton = document.createElement('button');
        profileButton.textContent = 'Profile';
        profileButton.addEventListener('click', () => {
            window.location.href = 'https://hianime.to/community/my-zone';
        });

        buttonContainer.appendChild(copyIdButton);
        buttonContainer.appendChild(profileButton);
        document.body.appendChild(buttonContainer);
    }

    function showPopup(message) {
        let popup = document.querySelector('#popup');
        if (!popup) {
            popup = document.createElement('div');
            popup.id = 'popup';
            document.body.appendChild(popup);
        }

        popup.textContent = message;
        popup.classList.add('show');
        setTimeout(() => {
            popup.classList.remove('show');
        }, 3000);
    }

    const sidebar = document.createElement('div');
    sidebar.classList.add('sidebar');
    sidebar.innerHTML = `
        <div class="hst-item">
            <a href="https://hianime.to/watch2gether" target="_blank" class="hst-link">
                <div class="hst-icon"><i class="zicon zicon-20 zicon-live"></i></div>
                <div class="description">Watch Parties</div>
            </a>
        </div>
        <div class="hst-item">
            <a href="https://hianime.to/random" target="_blank" class="hst-link">
                <div class="hst-icon"><i class="fas fa-random"></i></div>
                <div class="description">Random Anime</div>
            </a>
        </div>
        <div class="hst-item">
            <a href="https://hianime.to/community/board" target="_blank" class="hst-link">
                <div class="hst-icon"><i class="fas fa-comments"></i></div>
                <div class="description">Community</div>
            </a>
        </div>
        <div class="hst-item" data-toggle="tooltip" title="" data-original-title="Select language of anime name to display.">
                    <div class="select-anime-name toggle-lang"><span class="en">EN</span><span class="jp">JP</span></div>
                    <div class="name"><span>Anime Name</span></div>
                </div>
    `;
    document.body.appendChild(sidebar);

    const threeDotsButton = document.createElement('div');
    threeDotsButton.classList.add('three-dots');
    threeDotsButton.innerHTML = '...';
    document.body.appendChild(threeDotsButton);

    threeDotsButton.addEventListener('click', () => {
        sidebar.classList.toggle('open');
    });