Last active
February 11, 2025 16:33
-
-
Save dougwithseismic/4cd6de525c591194c8c6c6f985094cf0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name DeepSeek Auto-Refresh on Server Busy | |
// @namespace Violentmonkey Scripts | |
// @match https://chat.deepseek.com/a/chat/* | |
// @grant none | |
// @version 1.1 | |
// @author Doug Silkstone <[email protected]> | |
// @description Auto-clicks refresh button when server is busy | |
// ==/UserScript== | |
(() => { | |
'use strict'; | |
let isProcessing = false; | |
let debugMode = true; // Enable to see detailed debugging info | |
// Debug logging function | |
const debug = (message, force = false) => { | |
if (debugMode || force) { | |
console.log(`[DeepSeek Refresh] ${message}`); | |
} | |
}; | |
// Create toast container | |
const toastContainer = document.createElement('div'); | |
toastContainer.style.cssText = ` | |
position: fixed; | |
bottom: 20px; | |
right: 20px; | |
background: rgba(0, 0, 0, 0.8); | |
color: white; | |
padding: 10px 20px; | |
border-radius: 5px; | |
z-index: 10000; | |
display: none; | |
transition: opacity 0.3s; | |
font-family: Arial, sans-serif; | |
`; | |
document.body.appendChild(toastContainer); | |
const showToast = (message, duration = null) => { | |
toastContainer.innerHTML = message; | |
toastContainer.style.display = 'block'; | |
toastContainer.style.opacity = '1'; | |
debug(`Toast shown: ${message}`); | |
if (duration) { | |
setTimeout(() => { | |
toastContainer.style.opacity = '0'; | |
setTimeout(() => { | |
toastContainer.style.display = 'none'; | |
}, 300); | |
}, duration); | |
} | |
}; | |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); | |
// Find the last regenerate button in the DOM | |
const findLastRegenerateButton = () => { | |
const regenerateRects = Array.from(document.querySelectorAll('rect[id="重新生成"]')); | |
debug(`Found ${regenerateRects.length} regenerate buttons`); | |
if (regenerateRects.length === 0) { | |
debug('No regenerate buttons found'); | |
return null; | |
} | |
const lastRect = regenerateRects[regenerateRects.length - 1]; | |
debug(`Selected last regenerate button: ${lastRect.outerHTML}`); | |
return lastRect; | |
}; | |
// Find the closest ds-markdown container | |
const findMarkdownContainer = (element) => { | |
let current = element; | |
while (current) { | |
const markdown = current.querySelector('.ds-markdown'); | |
if (markdown) { | |
debug('Found markdown container'); | |
return markdown; | |
} | |
current = current.parentElement; | |
} | |
debug('No markdown container found'); | |
return null; | |
}; | |
const shouldRefresh = () => { | |
const refreshRect = findLastRegenerateButton(); | |
if (!refreshRect) return false; | |
const markdownContainer = findMarkdownContainer(refreshRect); | |
if (!markdownContainer) { | |
debug('No markdown container found for button'); | |
return false; | |
} | |
const hasBusyMessage = markdownContainer.textContent.includes('The server is busy'); | |
debug(`Busy message present: ${hasBusyMessage}`); | |
return hasBusyMessage; | |
}; | |
const verifyRemoval = seconds => { | |
const stillExists = shouldRefresh(); | |
const statusDot = stillExists ? '🔴' : '🟢'; | |
const message = `${statusDot} ${seconds}s check: ${stillExists ? 'Still present' : 'Removed'}`; | |
debug(message); | |
return message; | |
}; | |
const findClickableParent = element => { | |
let parent = element; | |
let depth = 0; | |
while (parent && !parent.onclick && parent.tagName.toLowerCase() !== 'button' && depth < 10) { | |
debug(`Searching parent level ${depth}: ${parent.tagName}`); | |
parent = parent.parentElement; | |
depth++; | |
} | |
if (parent) { | |
debug(`Found clickable parent: ${parent.tagName}`); | |
} else { | |
debug('No clickable parent found'); | |
} | |
return parent; | |
}; | |
const clickRefresh = async () => { | |
if (isProcessing) { | |
debug('Already processing, skipping'); | |
return; | |
} | |
if (!shouldRefresh()) { | |
debug('Refresh not needed'); | |
return; | |
} | |
isProcessing = true; | |
debug('Starting refresh process'); | |
const refreshRect = findLastRegenerateButton(); | |
if (!refreshRect) { | |
debug('No refresh button found'); | |
isProcessing = false; | |
return; | |
} | |
const clickableElement = findClickableParent(refreshRect); | |
if (!clickableElement) { | |
showToast('Found rect but no clickable parent', 3000); | |
debug('No clickable parent found'); | |
isProcessing = false; | |
return; | |
} | |
debug('Clicking refresh button'); | |
clickableElement.click(); | |
showToast('Clicked refresh button (server was busy)<br>Checking removal...'); | |
// Verification checks | |
await delay(1000); | |
const check1 = verifyRemoval(1); | |
showToast(`${check1}<br>Checking more...`); | |
await delay(2000); | |
const check3 = verifyRemoval(3); | |
showToast(`${check1}<br>${check3}<br>Final check soon...`); | |
await delay(2000); | |
const check5 = verifyRemoval(5); | |
showToast(`${check1}<br>${check3}<br>${check5}`, 3000); | |
isProcessing = false; | |
debug('Refresh process completed'); | |
}; | |
// Observe DOM changes to trigger refresh check | |
const observer = new MutationObserver(() => { | |
debug('DOM mutation detected'); | |
clickRefresh(); | |
}); | |
observer.observe(document.body, { childList: true, subtree: true }); | |
debug('Observer started'); | |
// Initial check | |
clickRefresh(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment