komica發文自訂名稱跟類別(Komica name and category custom settings)

為快速回覆表單添加自訂名稱和類別功能,保持拖拽功能,支持點擊No.插入引用到快速回覆內文並更新標題,通過AJAX刷新最新回覆,保留無貼圖、連貼機能、SAGE等功能,優化503錯誤處理與刷新邏輯

当前为 2025-04-25 提交的版本,查看 最新版本

// ==UserScript==
// @name         komica發文自訂名稱跟類別(Komica name and category custom settings)
// @namespace    http://tampermonkey.net/
// @version      1.8
// @description  為快速回覆表單添加自訂名稱和類別功能,保持拖拽功能,支持點擊No.插入引用到快速回覆內文並更新標題,通過AJAX刷新最新回覆,保留無貼圖、連貼機能、SAGE等功能,優化503錯誤處理與刷新邏輯
// @author       Grok
// @match        *://*.komica1.org/*
// @exclude      *://*.komica1.org/*/src/*
// @exclude      *://*.komica1.org/*/thumb/*
// @grant        none
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// @require      https://code.jquery.com/ui/1.12.1/jquery-ui.min.js
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 等待DOM加載完成
    $(document).ready(function() {
        // 檢查quickreply表單並啟用拖拽
        var $quickReply = $('#quickreply');
        if ($quickReply.length) {
            $quickReply.draggable({
                handle: '.quickreply-head',
                containment: 'window'
            });
        }

        // 處理名稱輸入框
        var $nameInputFname = $('#fname');
        var $nameInputPlaceholder = $("input[placeholder='名稱']:not(.hide)");
        var $nameInputs = $().add($nameInputFname).add($nameInputPlaceholder);

        if ($nameInputs.length) {
            $nameInputs.each(function() {
                var $input = $(this);
                var $setNameBtn = $('<button type="button" style="font-family: Arial; margin-left: 5px;">設置名稱</button>');
                $input.after($setNameBtn);

                $setNameBtn.on('click', function() {
                    var customName = prompt('請輸入自訂名稱:', $input.val() || '');
                    if (customName !== null && customName.trim() !== '') {
                        if ($input.attr('id') === 'fname') {
                            customName = customName.substring(0, 100);
                        }
                        $input.val(customName);
                        localStorage.setItem('input-name-' + ($input.attr('id') || 'placeholder'), customName);
                    }
                });

                var savedName = localStorage.getItem('input-name-' + ($input.attr('id') || 'placeholder'));
                if (savedName) {
                    $input.val(savedName);
                }
            });
        }

        // 處理類別輸入框
        var $categoryInputs = $("input[name='category']");
        if ($categoryInputs.length) {
            $categoryInputs.each(function() {
                var $input = $(this);
                var $setCategoryBtn = $('<button type="button" style="font-family: Arial; margin-left: 5px;">設置類別</button>');
                $input.after($setCategoryBtn);

                $setCategoryBtn.on('click', function() {
                    var customCategory = prompt('請輸入類別標籤(以逗號分隔):', $input.val() || '');
                    if (customCategory !== null && customCategory.trim() !== '') {
                        var tags = customCategory.split(',').map(tag => tag.trim()).filter(tag => tag !== '');
                        if (tags.length > 0) {
                            var categoryValue = tags.join(', ');
                            $input.val(categoryValue);
                            localStorage.setItem('input-category-' + ($input.attr('name') || 'category'), categoryValue);
                        } else {
                            alert('請輸入至少一個有效的標籤!');
                        }
                    }
                });

                var savedCategory = localStorage.getItem('input-category-' + ($input.attr('name') || 'category'));
                if (savedCategory) {
                    $input.val(savedCategory);
                }
            });
        }

        // 處理點擊No.插入引用並更新標題
        $('.qlink').on('click', function(e) {
            e.preventDefault();
            var postNo = $(this).attr('data-no');
            var quoteText = `>>No.${postNo}\n`;

            var $quickReplyTextarea = $('#quickreply textarea[name="pOBvrtyJK"]');
            if ($quickReplyTextarea.length) {
                $quickReply.css('display', 'block');
                var currentText = $quickReplyTextarea.val();
                $quickReplyTextarea.val(quoteText + currentText);
                $quickReplyTextarea.focus();

                var $quickReplyTitle = $('.quickreply-title');
                if ($quickReplyTitle.length) {
                    $quickReplyTitle.text(`Quick Reply >>No.${postNo}`);
                }
            } else {
                console.warn('未找到快速回覆表單的textarea');
            }
        });

        // 處理快速回覆表單關閉按鈕
        $('.quickreply-close').on('click', function() {
            $quickReply.css('display', 'none');
        });

        // 處理快速回覆表單提交(帶重試機制)
        function submitReply(formData, $form, attempt = 1, maxAttempts = 3) {
            console.log(`提交表單(嘗試 ${attempt}/${maxAttempts}):`, Array.from(formData.entries()));

            $.ajax({
                url: $form.attr('action') || 'pixmicat.php',
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                success: function(response, status, xhr) {
                    console.log('提交成功,回應狀態:', xhr.status, '回應內容:', response);

                    // 重置表單
                    $form.find('textarea[name="pOBvrtyJK"]').val('');
                    $form.find('input[name="upfile"]').val('');
                    $form.find('input[name="noimg"]').prop('checked', false);
                    $form.find('input[name="up_series"]').prop('checked', false);
                    $form.find('input[name="ObHGyhdTR"]').prop('checked', false);
                    $form.find('input[name="category"]').val(localStorage.getItem('input-category-category') || '');
                    $form.find('input[name="bvUFbdrIC"]').val(localStorage.getItem('input-name-placeholder') || '');

                    // 刷新線程
                    refreshThread();
                },
                error: function(xhr, status, error) {
                    console.error(`提交失敗(嘗試 ${attempt}/${maxAttempts}):`, status, error, '回應狀態:', xhr.status, '回應內容:', xhr.responseText);

                    // 處理503錯誤或潛在成功
                    if (xhr.status === 503 && attempt < maxAttempts) {
                        console.log(`檢測到503錯誤,重試 ${attempt + 1}/${maxAttempts}...`);
                        setTimeout(() => submitReply(formData, $form, attempt + 1, maxAttempts), 2000);
                    } else if (xhr.status === 200 || xhr.status === 302 || xhr.responseText.includes('成功')) {
                        console.log('檢測到可能的成功提交,嘗試刷新線程');
                        refreshThread();
                    } else {
                        alert('回覆提交失敗(狀態碼: ' + xhr.status + '),請檢查網絡或稍後重試。手動刷新頁面可能顯示您的回覆。');
                        // 仍嘗試刷新以檢查是否成功
                        refreshThread();
                    }
                }
            });
        }

        // 表單提交事件
        $('#quickreply-form').on('submit', function(e) {
            e.preventDefault();

            var $form = $(this);
            var formData = new FormData(this);

            // 確保Cloudflare Turnstile token包含
            var $turnstileResponse = $('.cf-turnstile input[name="cf-turnstile-response"]');
            if ($turnstileResponse.length) {
                formData.append('cf-turnstile-response', $turnstileResponse.val());
            } else {
                console.warn('未找到Cloudflare Turnstile token,可能導致提交失敗');
            }

            // 開始提交
            submitReply(formData, $form);
        });

        // 刷新線程函數(帶重試機制並規避$.isMobile錯誤)
        function refreshThread(attempt = 1, maxAttempts = 3) {
            var threadNo = $('#quickreply-form input[name="resto"]').val();
            if (!threadNo) {
                console.warn('無法獲取線程ID');
                alert('無法刷新線程,請手動重新整理頁面。');
                return;
            }

            var $thread = $(`div.thread[data-no="${threadNo}"]`);
            var existingReplyIds = $thread.find('.post.reply').map(function() {
                return $(this).attr('data-no');
            }).get();

            console.log('正在刷新線程:', threadNo, '現有回覆ID:', existingReplyIds);

            $.ajax({
                url: `pixmicat.php?res=${threadNo}`,
                type: 'GET',
                cache: false,
                success: function(data) {
                    console.log('線程數據獲取成功,解析新回覆...');
                    var $newContent = $('<div>').html(data);
                    var $newReplies = $newContent.find(`div.thread[data-no="${threadNo}"] .post.reply`);

                    if ($newReplies.length === 0) {
                        console.warn('未找到新回覆,可能是伺服器延遲');
                        if (attempt < maxAttempts) {
                            console.log(`重試 ${attempt + 1}/${maxAttempts}...`);
                            setTimeout(() => refreshThread(attempt + 1, maxAttempts), 2000);
                            return;
                        } else {
                            alert('未檢測到新回覆,請手動刷新頁面確認。');
                            return;
                        }
                    }

                    var newRepliesAdded = false;
                    $newReplies.each(function() {
                        var replyId = $(this).attr('data-no');
                        if (!existingReplyIds.includes(replyId)) {
                            try {
                                $thread.find('hr').before($(this));
                                newRepliesAdded = true;
                                console.log('添加新回覆:', replyId);
                            } catch (e) {
                                console.error('添加回覆時發生錯誤(可能是Komica原生腳本問題):', e);
                            }
                        }
                    });

                    if (newRepliesAdded) {
                        console.log('線程已刷新,新回覆已添加');
                        // 模擬點擊新回覆以觸發Komica的展開邏輯(規避$.isMobile錯誤)
                        $thread.find('.post.reply').each(function() {
                            var $post = $(this);
                            if ($post.find('.post-content').is(':hidden')) {
                                try {
                                    $post.find('.post-title').trigger('click');
                                } catch (e) {
                                    console.warn('模擬展開回覆失敗:', e);
                                }
                            }
                        });
                    } else {
                        console.warn('未找到新回覆,可能是伺服器延遲或無新內容');
                        if (attempt < maxAttempts) {
                            console.log(`重試 ${attempt + 1}/${maxAttempts}...`);
                            setTimeout(() => refreshThread(attempt + 1, maxAttempts), 2000);
                        } else {
                            alert('未檢測到新回覆,請手動刷新頁面確認。');
                        }
                    }
                },
                error: function(xhr, status, error) {
                    console.error('線程刷新失敗:', status, error, '回應狀態:', xhr.status, '回應內容:', xhr.responseText);
                    if (attempt < maxAttempts) {
                        console.log(`重試 ${attempt + 1}/${maxAttempts}...`);
                        setTimeout(() => refreshThread(attempt + 1, maxAttempts), 2000);
                    } else {
                        alert('無法刷新線程,請手動重新整理頁面。');
                    }
                }
            });
        }
    });
})();