Chapter Downloader

Add a control panel for novel reading

当前为 2025-03-09 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Chapter Downloader
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  Add a control panel for novel reading
// @author       You
// @match        https://truyen.tangthuvien.net/doc-truyen/*
// @match        https://truyen.tangthuvien.net/doc-truyen/*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Create panel container
    const panel = document.createElement('div');
    panel.id = 'reader-panel';
    panel.style.cssText = `
        position: fixed;
        top: 10%;
        right: 10px;
        width: 300px;
        background-color: #f8f8f8;
        border: 1px solid #ccc;
        border-radius: 5px;
        padding: 10px;
        z-index: 9999;
        box-shadow: 0 0 10px rgba(0,0,0,0.2);
        font-family: Arial, sans-serif;
    `;

    // Create textarea
    const textarea = document.createElement('textarea');
    textarea.id = 'content-textarea';
    textarea.style.cssText = `
        width: 100%;
        height: 300px;
        margin-bottom: 10px;
        padding: 8px;
        border: 1px solid #ddd;
        border-radius: 4px;
        resize: vertical;
    `;

    // Create start button
    const startButton = document.createElement('button');
    startButton.textContent = 'Bắt đầu';
    startButton.style.cssText = `
        width: 100%;
        padding: 8px;
        margin-bottom: 10px;
        background-color: #4CAF50;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
    `;

    // Create container for getTextButton and nextChapterButton (same row)
    const buttonRow1 = document.createElement('div');
    buttonRow1.style.cssText = `
        display: flex;
        justify-content: space-between;
        margin-bottom: 10px;
    `;

    // Create get text button
    const getTextButton = document.createElement('button');
    getTextButton.textContent = 'Lấy Text';
    getTextButton.style.cssText = `
        flex: 1;
        padding: 8px;
        margin-right: 5px;
        background-color: #2196F3;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
    `;

    // Create next chapter button
    const nextChapterButton = document.createElement('button');
    nextChapterButton.textContent = 'Chương Tiếp';
    nextChapterButton.style.cssText = `
        flex: 1;
        padding: 8px;
        margin-left: 5px;
        background-color: #ff9800;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
    `;

    // Create container for clearButton and copyButton (same row)
    const buttonRow2 = document.createElement('div');
    buttonRow2.style.cssText = `
        display: flex;
        justify-content: space-between;
    `;

    // Create clear button
    const clearButton = document.createElement('button');
    clearButton.textContent = 'Xoá';
    clearButton.style.cssText = `
        flex: 1;
        padding: 8px;
        margin-right: 5px;
        background-color: #f44336;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
    `;

    // Create copy button
    const copyButton = document.createElement('button');
    copyButton.textContent = 'Sao Chép';
    copyButton.style.cssText = `
        flex: 1;
        padding: 8px;
        margin-left: 5px;
        background-color: #9c27b0;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
    `;

    // Add buttons to their respective row containers
    buttonRow1.appendChild(getTextButton);
    buttonRow1.appendChild(nextChapterButton);
    buttonRow2.appendChild(clearButton);
    buttonRow2.appendChild(copyButton);

    // Add all elements to panel
    panel.appendChild(textarea);
    panel.appendChild(startButton);
    panel.appendChild(buttonRow1);
    panel.appendChild(buttonRow2);

    // Add panel to body
    document.body.appendChild(panel);

    // Add event listeners
    startButton.addEventListener('click', () => {
        console.log('Start button clicked');
        // Add your start functionality here
    });

    getTextButton.addEventListener('click', () => {
        console.log('Get text button clicked');
        // Add your get text functionality here
        // For example:
        const contentElement = document.querySelector('#content'); // Replace with actual content selector
        if (contentElement) {
            textarea.value = contentElement.innerText;
        }
    });

    nextChapterButton.addEventListener('click', () => {
        console.log('Next chapter button clicked');
        // Add your next chapter functionality here
        // For example, find and click the next chapter link
        const nextChapterLink = document.querySelector('.next-chapter'); // Replace with actual next chapter selector
        if (nextChapterLink) {
            nextChapterLink.click();
        }
    });

    clearButton.addEventListener('click', () => {
        console.log('Clear button clicked');
        textarea.value = '';
    });

    copyButton.addEventListener('click', () => {
        console.log('Copy button clicked');
        textarea.select();
        document.execCommand('copy');
    });

    // Make panel draggable
    let isDragging = false;
    let offsetX, offsetY;

    panel.addEventListener('mousedown', (e) => {
        if (e.target === panel) {
            isDragging = true;
            offsetX = e.clientX - panel.getBoundingClientRect().left;
            offsetY = e.clientY - panel.getBoundingClientRect().top;
        }
    });

    document.addEventListener('mousemove', (e) => {
        if (isDragging) {
            panel.style.left = (e.clientX - offsetX) + 'px';
            panel.style.top = (e.clientY - offsetY) + 'px';
            panel.style.right = 'auto';
        }
    });

    document.addEventListener('mouseup', () => {
        isDragging = false;
    });
})();