feat(slash-commands): 优化 /goto-floor 命令并加载所有消息 - 在执行 /goto-floor 命令前加载所有消息,确保目标元素存在 - 添加加载消息的步骤,解决因懒加载导致的元素找不到问题
| @@ -2134,8 +2134,15 @@ export function initDefaultSlashCommands() { | |||
| 2134 | name: 'goto-floor', | 2134 | name: 'goto-floor', |
| 2135 | aliases: ['floor', 'jump', 'scrollto'], | 2135 | aliases: ['floor', 'jump', 'scrollto'], |
| 2136 | callback: async (_, index) => { | 2136 | callback: async (_, index) => { |
| 2137 | // --- Load all messages first to ensure the target element exists --- | ||
| 2138 | console.log(`INFO: Loading all messages before attempting to goto-floor ${index}.`); | ||
| 2139 | await showMoreMessages(Number.MAX_SAFE_INTEGER); | ||
| 2140 | console.log(`INFO: All messages loaded (or loading initiated).`); | ||
| 2141 | // --- End of loading step --- | ||
| 2142 | |||
| 2143 | |||
| 2137 | const floorIndex = Number(index); | 2144 | const floorIndex = Number(index); |
| 2138 | 2145 | ||
| 2139 | // Validate input | 2146 | // Validate input |
| 2140 | if (isNaN(floorIndex) || floorIndex < 0 || (typeof chat !== 'undefined' && floorIndex >= chat.length)) { | 2147 | if (isNaN(floorIndex) || floorIndex < 0 || (typeof chat !== 'undefined' && floorIndex >= chat.length)) { |
| 2141 | const maxIndex = (typeof chat !== 'undefined' ? chat.length - 1 : 'unknown'); | 2148 | const maxIndex = (typeof chat !== 'undefined' ? chat.length - 1 : 'unknown'); |
| @@ -2143,21 +2150,25 @@ export function initDefaultSlashCommands() { | |||
| 2143 | console.warn(`WARN: Invalid message index provided for /goto-floor: ${index}. Max index: ${maxIndex}`); | 2150 | console.warn(`WARN: Invalid message index provided for /goto-floor: ${index}. Max index: ${maxIndex}`); |
| 2144 | return ''; | 2151 | return ''; |
| 2145 | } | 2152 | } |
| 2146 | 2153 | ||
| 2154 | // Give the rendering a moment to potentially catch up after showMoreMessages | ||
| 2155 | // This might be necessary depending on how showMoreMessages works internally | ||
| 2156 | await new Promise(resolve => setTimeout(resolve, 100)); // Adjust delay if needed | ||
| 2157 | |||
| 2147 | const messageElement = document.querySelector(`[mesid="${floorIndex}"]`); | 2158 | const messageElement = document.querySelector(`[mesid="${floorIndex}"]`); |
| 2148 | 2159 | ||
| 2149 | if (messageElement) { | 2160 | if (messageElement) { |
| 2150 | const headerElement = messageElement.querySelector('.mes_header') || | 2161 | const headerElement = messageElement.querySelector('.mes_header') || |
| 2151 | messageElement.querySelector('.mes_meta') || | 2162 | messageElement.querySelector('.mes_meta') || |
| 2152 | messageElement.querySelector('.mes_name_area') || | 2163 | messageElement.querySelector('.mes_name_area') || |
| 2153 | messageElement.querySelector('.mes_name'); | 2164 | messageElement.querySelector('.mes_name'); |
| 2154 | 2165 | ||
| 2155 | const elementToScroll = headerElement || messageElement; // Prefer header, fallback to whole message | 2166 | const elementToScroll = headerElement || messageElement; // Prefer header, fallback to whole message |
| 2156 | const blockPosition = headerElement ? 'center' : 'start'; // Center header, else start of message | 2167 | const blockPosition = headerElement ? 'center' : 'start'; // Center header, else start of message |
| 2157 | 2168 | ||
| 2158 | elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition }); | 2169 | elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition }); |
| 2159 | console.log(`INFO: Scrolled ${headerElement ? 'header of' : ''} message ${floorIndex} into view (block: ${blockPosition}).`); | 2170 | console.log(`INFO: Scrolled ${headerElement ? 'header of' : ''} message ${floorIndex} into view (block: ${blockPosition}).`); |
| 2160 | 2171 | ||
| 2161 | // --- Highlight with smooth animation --- | 2172 | // --- Highlight with smooth animation --- |
| 2162 | messageElement.classList.add('highlight-scroll'); | 2173 | messageElement.classList.add('highlight-scroll'); |
| 2163 | setTimeout(() => { | 2174 | setTimeout(() => { |
| @@ -2169,10 +2180,12 @@ export function initDefaultSlashCommands() { | |||
| 2169 | messageElement.classList.remove('highlight-scroll', 'highlight-scroll-fadeout'); | 2180 | messageElement.classList.remove('highlight-scroll', 'highlight-scroll-fadeout'); |
| 2170 | }, 500); // Matches the 0.5s transition duration | 2181 | }, 500); // Matches the 0.5s transition duration |
| 2171 | }, 1500); // Start fade out after 1.5 seconds | 2182 | }, 1500); // Start fade out after 1.5 seconds |
| 2172 | 2183 | ||
| 2173 | } else { | 2184 | } else { |
| 2174 | toastr.warning(`Could not find element for message ${floorIndex} (using [mesid="${floorIndex}"]). It might not be rendered yet. Try scrolling up or use /chat-render all.`); | 2185 | // This case is less likely now after showMoreMessages, but still possible |
| 2175 | console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor.`); | 2186 | // if the element hasn't been added to the DOM yet for some reason after loading. |
| 2187 | toastr.warning(`Could not find element for message ${floorIndex} (using [mesid="${floorIndex}"]) even after attempting to load all messages. It might not be rendered yet. Try scrolling up or use /chat-render all again if issues persist.`); | ||
| 2188 | console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor, even after attempting to load all messages.`); | ||
| 2176 | const chatContainer = document.getElementById('chat'); | 2189 | const chatContainer = document.getElementById('chat'); |
| 2177 | if (chatContainer) { | 2190 | if (chatContainer) { |
| 2178 | chatContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); | 2191 | chatContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
| @@ -2192,16 +2205,14 @@ export function initDefaultSlashCommands() { | |||
| 2192 | <div> | 2205 | <div> |
| 2193 | Scrolls the chat view to the specified message index. Uses the <code>[mesid]</code> attribute for locating the message element. Index starts at 0. | 2206 | Scrolls the chat view to the specified message index. Uses the <code>[mesid]</code> attribute for locating the message element. Index starts at 0. |
| 2194 | It attempts to center the character's name/header area within the message block. Highlights the message using the theme's 'matchedText' color with a smooth animation. | 2207 | It attempts to center the character's name/header area within the message block. Highlights the message using the theme's 'matchedText' color with a smooth animation. |
| 2208 | Automatically attempts to load all messages before scrolling to improve success rate, addressing issues with lazy loading. | ||
| 2195 | </div> | 2209 | </div> |
| 2196 | <div> | 2210 | <div> |
| 2197 | <strong>Example:</strong> <pre><code>/goto-floor 10</code></pre> Scrolls to the 11th message (mesid=10). | 2211 | <strong>Example:</strong> <pre><code>/goto-floor 10</code></pre> Scrolls to the 11th message (mesid=10). |
| 2198 | </div> | 2212 | </div> |
| 2199 | <div> | ||
| 2200 | Note: Due to virtual scrolling, very old messages might need loading first. | ||
| 2201 | </div> | ||
| 2202 | `, | 2213 | `, |
| 2203 | })); | 2214 | })); |
| 2204 | 2215 | ||
| 2205 | // --- Improved CSS for highlight --- | 2216 | // --- Improved CSS for highlight --- |
| 2206 | const styleId = 'goto-floor-highlight-style'; | 2217 | const styleId = 'goto-floor-highlight-style'; |
| 2207 | if (!document.getElementById(styleId)) { | 2218 | if (!document.getElementById(styleId)) { |