From 485d07b91f2bfc2e00e7de5dcbda55aa462e163f Mon Sep 17 00:00:00 2001
From: awaae001 <3271436144@qq.com>
Date: Tue, 22 Apr 2025 23:51:40 +0800
Subject: [PATCH 1/7] =?UTF-8?q?feat(slash-commands):=20=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=20/goto-floor=20=E5=91=BD=E4=BB=A4=E5=B9=B6=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E6=B6=88=E6=81=AF=E9=AB=98=E4=BA=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增 /goto-floor 命令,允许用户滚动到指定的消息索引
- 实现消息高亮功能,滚动到指定消息后进行突出显示
- 添加相关的 CSS 样式,确保高亮效果在不同浏览器中兼容
---
public/scripts/slash-commands.js | 121 +++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index e97e4955d..04ed35a13 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -2130,6 +2130,127 @@ export function initDefaultSlashCommands() {
`,
}));
+ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
+ name: 'goto-floor',
+ aliases: ['floor', 'jump', 'scrollto'],
+ callback: async (_, index) => {
+ const floorIndex = Number(index);
+
+ // Validate input
+ if (isNaN(floorIndex) || floorIndex < 0 || (typeof chat !== 'undefined' && floorIndex >= chat.length)) {
+ const maxIndex = (typeof chat !== 'undefined' ? chat.length - 1 : 'unknown');
+ toastr.warning(`Invalid message index: ${index}. Please enter a number between 0 and ${maxIndex}.`);
+ console.warn(`WARN: Invalid message index provided for /goto-floor: ${index}. Max index: ${maxIndex}`);
+ return '';
+ }
+
+ const messageElement = document.querySelector(`[mesid="${floorIndex}"]`);
+
+ if (messageElement) {
+ const headerElement = messageElement.querySelector('.mes_header') ||
+ messageElement.querySelector('.mes_meta') ||
+ messageElement.querySelector('.mes_name_area') ||
+ messageElement.querySelector('.mes_name');
+
+ const elementToScroll = headerElement || messageElement; // Prefer header, fallback to whole message
+ const blockPosition = headerElement ? 'center' : 'start'; // Center header, else start of message
+
+ elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition });
+ console.log(`INFO: Scrolled ${headerElement ? 'header of' : ''} message ${floorIndex} into view (block: ${blockPosition}).`);
+
+ // --- Highlight with smooth animation ---
+ messageElement.classList.add('highlight-scroll');
+ setTimeout(() => {
+ // Add a class to fade out, then remove the highlight class after fade
+ messageElement.classList.add('highlight-scroll-fadeout');
+ // Wait for fadeout transition to complete before removing the base class
+ // Match this duration to the transition duration in CSS
+ setTimeout(() => {
+ messageElement.classList.remove('highlight-scroll', 'highlight-scroll-fadeout');
+ }, 500); // Matches the 0.5s transition duration
+ }, 1500); // Start fade out after 1.5 seconds
+
+ } else {
+ 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.`);
+ console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor.`);
+ const chatContainer = document.getElementById('chat');
+ if (chatContainer) {
+ chatContainer.scrollIntoView({ behavior: 'smooth', block: 'start' });
+ }
+ }
+ return '';
+ },
+ unnamedArgumentList: [
+ SlashCommandArgument.fromProps({
+ description: 'The message index (0-based) to scroll to.',
+ typeList: [ARGUMENT_TYPE.NUMBER],
+ isRequired: true,
+ enumProvider: commonEnumProviders.messages(),
+ }),
+ ],
+ helpString: `
+
+ Scrolls the chat view to the specified message index. Uses the [mesid]
attribute for locating the message element. Index starts at 0.
+ 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.
+
+
+
Example: /goto-floor 10
Scrolls to the 11th message (mesid=10).
+
+
+ Note: Due to virtual scrolling, very old messages might need loading first.
+
+ `,
+ }));
+
+ // --- Improved CSS for highlight ---
+ const styleId = 'goto-floor-highlight-style';
+ if (!document.getElementById(styleId)) {
+ const style = document.createElement('style');
+ style.id = styleId;
+ style.textContent = `
+ /* Base state for elements that *can* be highlighted */
+ /* Ensures transition applies smoothly in both directions */
+ .mes, .mes_block {
+ transition: background-color 0.5s ease-in-out, box-shadow 0.5s ease-in-out;
+ /* Add position relative if not already present, needed for potential pseudo-elements */
+ position: relative;
+ }
+
+ /* --- Highlighting Style --- */
+ .mes.highlight-scroll,
+ .mes_block.highlight-scroll {
+ /* Use theme color for shadow, fallback to gold */
+ box-shadow: 0 0 10px var(--ac-style-color-matchedText, #FFD700) !important;
+ z-index: 5; /* Ensure highlight is visually prominent */
+ }
+
+ /* Modern browsers: Use color-mix for transparent background */
+ @supports (background-color: color-mix(in srgb, white 50%, black)) {
+ .mes.highlight-scroll,
+ .mes_block.highlight-scroll {
+ /* Mix theme color with transparent for background */
+ background-color: color-mix(in srgb, var(--ac-style-color-matchedText, #FFD700) 35%, transparent) !important;
+ }
+ }
+
+ /* Fallback for older browsers: Use a fixed semi-transparent background */
+ @supports not (background-color: color-mix(in srgb, white 50%, black)) {
+ .mes.highlight-scroll,
+ .mes_block.highlight-scroll {
+ background-color: rgba(255, 215, 0, 0.35) !important; /* Fallback semi-transparent gold */
+ }
+ }
+
+ /* --- Fade-out Control --- */
+ /* When fading out, explicitly transition back to transparent/none */
+ .mes.highlight-scroll-fadeout,
+ .mes_block.highlight-scroll-fadeout {
+ background-color: transparent !important;
+ box-shadow: none !important;
+ }
+ `;
+ document.head.appendChild(style);
+ }
registerVariableCommands();
}
From 6d0318eb36c864938c2abde8c3a51b391d9cfd76 Mon Sep 17 00:00:00 2001
From: awaae001 <3271436144@qq.com>
Date: Wed, 23 Apr 2025 00:05:35 +0800
Subject: [PATCH 2/7] =?UTF-8?q?refactor(slash-commands):=20=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=20/goto-floor=20=E5=91=BD=E4=BB=A4=E7=9A=84=E4=BB=A3?=
=?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=E5=92=8C=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 修正 EDLint 标记错误
---
public/scripts/slash-commands.js | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index 04ed35a13..f16ce9e7b 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -2135,29 +2135,29 @@ export function initDefaultSlashCommands() {
aliases: ['floor', 'jump', 'scrollto'],
callback: async (_, index) => {
const floorIndex = Number(index);
-
+
// Validate input
if (isNaN(floorIndex) || floorIndex < 0 || (typeof chat !== 'undefined' && floorIndex >= chat.length)) {
- const maxIndex = (typeof chat !== 'undefined' ? chat.length - 1 : 'unknown');
+ const maxIndex = (typeof chat !== 'undefined' ? chat.length - 1 : 'unknown');
toastr.warning(`Invalid message index: ${index}. Please enter a number between 0 and ${maxIndex}.`);
console.warn(`WARN: Invalid message index provided for /goto-floor: ${index}. Max index: ${maxIndex}`);
return '';
}
-
+
const messageElement = document.querySelector(`[mesid="${floorIndex}"]`);
-
+
if (messageElement) {
const headerElement = messageElement.querySelector('.mes_header') ||
messageElement.querySelector('.mes_meta') ||
messageElement.querySelector('.mes_name_area') ||
messageElement.querySelector('.mes_name');
-
+
const elementToScroll = headerElement || messageElement; // Prefer header, fallback to whole message
const blockPosition = headerElement ? 'center' : 'start'; // Center header, else start of message
-
+
elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition });
console.log(`INFO: Scrolled ${headerElement ? 'header of' : ''} message ${floorIndex} into view (block: ${blockPosition}).`);
-
+
// --- Highlight with smooth animation ---
messageElement.classList.add('highlight-scroll');
setTimeout(() => {
@@ -2169,7 +2169,7 @@ export function initDefaultSlashCommands() {
messageElement.classList.remove('highlight-scroll', 'highlight-scroll-fadeout');
}, 500); // Matches the 0.5s transition duration
}, 1500); // Start fade out after 1.5 seconds
-
+
} else {
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.`);
console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor.`);
@@ -2201,7 +2201,7 @@ export function initDefaultSlashCommands() {
`,
}));
-
+
// --- Improved CSS for highlight ---
const styleId = 'goto-floor-highlight-style';
if (!document.getElementById(styleId)) {
From ceeaeea1237edfff3455a329a00171455a82ac31 Mon Sep 17 00:00:00 2001
From: awaae001 <3271436144@qq.com>
Date: Wed, 23 Apr 2025 00:45:05 +0800
Subject: [PATCH 3/7] =?UTF-8?q?feat(slash-commands):=20=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=20/goto-floor=20=E5=91=BD=E4=BB=A4=E5=B9=B6=E5=8A=A0=E8=BD=BD?=
=?UTF-8?q?=E6=89=80=E6=9C=89=E6=B6=88=E6=81=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在执行 /goto-floor 命令前加载所有消息,确保目标元素存在
- 添加加载消息的步骤,解决因懒加载导致的元素找不到问题
---
public/scripts/slash-commands.js | 37 +++++++++++++++++++++-----------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index f16ce9e7b..1647cd55f 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -2134,8 +2134,15 @@ export function initDefaultSlashCommands() {
name: 'goto-floor',
aliases: ['floor', 'jump', 'scrollto'],
callback: async (_, index) => {
+ // --- Load all messages first to ensure the target element exists ---
+ console.log(`INFO: Loading all messages before attempting to goto-floor ${index}.`);
+ await showMoreMessages(Number.MAX_SAFE_INTEGER);
+ console.log(`INFO: All messages loaded (or loading initiated).`);
+ // --- End of loading step ---
+
+
const floorIndex = Number(index);
-
+
// Validate input
if (isNaN(floorIndex) || floorIndex < 0 || (typeof chat !== 'undefined' && floorIndex >= chat.length)) {
const maxIndex = (typeof chat !== 'undefined' ? chat.length - 1 : 'unknown');
@@ -2143,21 +2150,25 @@ export function initDefaultSlashCommands() {
console.warn(`WARN: Invalid message index provided for /goto-floor: ${index}. Max index: ${maxIndex}`);
return '';
}
-
+
+ // Give the rendering a moment to potentially catch up after showMoreMessages
+ // This might be necessary depending on how showMoreMessages works internally
+ await new Promise(resolve => setTimeout(resolve, 100)); // Adjust delay if needed
+
const messageElement = document.querySelector(`[mesid="${floorIndex}"]`);
-
+
if (messageElement) {
const headerElement = messageElement.querySelector('.mes_header') ||
messageElement.querySelector('.mes_meta') ||
messageElement.querySelector('.mes_name_area') ||
messageElement.querySelector('.mes_name');
-
+
const elementToScroll = headerElement || messageElement; // Prefer header, fallback to whole message
const blockPosition = headerElement ? 'center' : 'start'; // Center header, else start of message
-
+
elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition });
console.log(`INFO: Scrolled ${headerElement ? 'header of' : ''} message ${floorIndex} into view (block: ${blockPosition}).`);
-
+
// --- Highlight with smooth animation ---
messageElement.classList.add('highlight-scroll');
setTimeout(() => {
@@ -2169,10 +2180,12 @@ export function initDefaultSlashCommands() {
messageElement.classList.remove('highlight-scroll', 'highlight-scroll-fadeout');
}, 500); // Matches the 0.5s transition duration
}, 1500); // Start fade out after 1.5 seconds
-
+
} else {
- 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.`);
- console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor.`);
+ // This case is less likely now after showMoreMessages, but still possible
+ // if the element hasn't been added to the DOM yet for some reason after loading.
+ 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.`);
+ console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor, even after attempting to load all messages.`);
const chatContainer = document.getElementById('chat');
if (chatContainer) {
chatContainer.scrollIntoView({ behavior: 'smooth', block: 'start' });
@@ -2192,16 +2205,14 @@ export function initDefaultSlashCommands() {
Scrolls the chat view to the specified message index. Uses the [mesid]
attribute for locating the message element. Index starts at 0.
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.
+ Automatically attempts to load all messages before scrolling to improve success rate, addressing issues with lazy loading.
Example: /goto-floor 10
Scrolls to the 11th message (mesid=10).
-
- Note: Due to virtual scrolling, very old messages might need loading first.
-
`,
}));
-
+
// --- Improved CSS for highlight ---
const styleId = 'goto-floor-highlight-style';
if (!document.getElementById(styleId)) {
From ee11f021ebfae786dc1be56b9ef02a77c9f05642 Mon Sep 17 00:00:00 2001
From: awaae001 <3271436144@qq.com>
Date: Wed, 23 Apr 2025 01:04:52 +0800
Subject: [PATCH 4/7] =?UTF-8?q?refactor(slash-commands):=20=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=20/goto-floor=20=E5=91=BD=E4=BB=A4=E5=B9=B6=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E9=AB=98=E4=BA=AE=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 重新组织消息加载和滚动逻辑,提高命令成功率
- 添加消息元素高亮功能,使用 flashHighlight 或临时 CSS 类
---
public/scripts/slash-commands.js | 137 +++++++++++--------------------
1 file changed, 49 insertions(+), 88 deletions(-)
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index 1647cd55f..53f3ba364 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -1,4 +1,5 @@
import { Fuse, DOMPurify } from '../lib.js';
+import { flashHighlight } from './utils.js';
import {
Generate,
@@ -2134,64 +2135,67 @@ export function initDefaultSlashCommands() {
name: 'goto-floor',
aliases: ['floor', 'jump', 'scrollto'],
callback: async (_, index) => {
- // --- Load all messages first to ensure the target element exists ---
- console.log(`INFO: Loading all messages before attempting to goto-floor ${index}.`);
- await showMoreMessages(Number.MAX_SAFE_INTEGER);
- console.log(`INFO: All messages loaded (or loading initiated).`);
- // --- End of loading step ---
-
-
const floorIndex = Number(index);
- // Validate input
- if (isNaN(floorIndex) || floorIndex < 0 || (typeof chat !== 'undefined' && floorIndex >= chat.length)) {
- const maxIndex = (typeof chat !== 'undefined' ? chat.length - 1 : 'unknown');
+ const chatLength = typeof chat !== 'undefined' ? chat.length : -1; // Use -1 if chat is undefined to avoid errors
+ if (isNaN(floorIndex) || floorIndex < 0 || (chatLength !== -1 && floorIndex >= chatLength)) {
+ const maxIndex = (chatLength !== -1 ? chatLength - 1 : 'unknown');
toastr.warning(`Invalid message index: ${index}. Please enter a number between 0 and ${maxIndex}.`);
console.warn(`WARN: Invalid message index provided for /goto-floor: ${index}. Max index: ${maxIndex}`);
return '';
}
- // Give the rendering a moment to potentially catch up after showMoreMessages
- // This might be necessary depending on how showMoreMessages works internally
- await new Promise(resolve => setTimeout(resolve, 100)); // Adjust delay if needed
+ // --- Load all messages first to ensure the target element exists ---
+ console.log(`INFO: Attempting to load all messages before attempting to goto-floor ${index}.`);
+ try {
+ // Assuming showMoreMessages is available globally or within scope
+ await showMoreMessages(Number.MAX_SAFE_INTEGER);
+ console.log(`INFO: All messages loaded (or loading initiated).`);
+ // Give the rendering a moment to potentially catch up after showMoreMessages
+ await new Promise(resolve => setTimeout(resolve, 100)); // Adjust delay if needed
+ } catch (error) {
+ console.error('Error loading messages:', error);
+ toastr.error('An error occurred while trying to load messages.');
+ return ''; // Exit if loading fails
+ }
+ // --- End of loading step ---
const messageElement = document.querySelector(`[mesid="${floorIndex}"]`);
if (messageElement) {
- const headerElement = messageElement.querySelector('.mes_header') ||
- messageElement.querySelector('.mes_meta') ||
- messageElement.querySelector('.mes_name_area') ||
- messageElement.querySelector('.mes_name');
-
- const elementToScroll = headerElement || messageElement; // Prefer header, fallback to whole message
- const blockPosition = headerElement ? 'center' : 'start'; // Center header, else start of message
+ // --- Corrected: Use the actual class from the template ---
+ const headerElement = messageElement.querySelector('.ch_name');
+ const elementToScroll = headerElement || messageElement; // Fallback to the entire message div
+ const blockPosition = headerElement ? 'center' : 'start';
elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition });
- console.log(`INFO: Scrolled ${headerElement ? 'header of' : ''} message ${floorIndex} into view (block: ${blockPosition}).`);
- // --- Highlight with smooth animation ---
- messageElement.classList.add('highlight-scroll');
- setTimeout(() => {
- // Add a class to fade out, then remove the highlight class after fade
- messageElement.classList.add('highlight-scroll-fadeout');
- // Wait for fadeout transition to complete before removing the base class
- // Match this duration to the transition duration in CSS
- setTimeout(() => {
- messageElement.classList.remove('highlight-scroll', 'highlight-scroll-fadeout');
- }, 500); // Matches the 0.5s transition duration
- }, 1500); // Start fade out after 1.5 seconds
+ // Highlight the message element
+ if (messageElement instanceof HTMLElement) {
+ if (typeof $ !== 'undefined') { // Check if jQuery is available
+ flashHighlight($(messageElement), 1500);
+ } else {
+ console.warn('jQuery not available, cannot use flashHighlight.');
+ // Optional: Add a temporary CSS class highlight if jQuery/flashHighlight is missing
+ messageElement.style.transition = 'background-color 0.5s ease';
+ messageElement.style.backgroundColor = 'yellow'; // Or some highlight color
+ setTimeout(() => {
+ messageElement.style.backgroundColor = ''; // Remove highlight
+ }, 1500); // Match flash duration
+ }
+
+ } else {
+ console.warn('Message element is not an HTMLElement, cannot flash highlight.');
+ }
+
} else {
- // This case is less likely now after showMoreMessages, but still possible
- // if the element hasn't been added to the DOM yet for some reason after loading.
- 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.`);
+ // Only warn if element is not found *after* attempting to load all messages
+ 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 or the index is invalid.`);
console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor, even after attempting to load all messages.`);
- const chatContainer = document.getElementById('chat');
- if (chatContainer) {
- chatContainer.scrollIntoView({ behavior: 'smooth', block: 'start' });
- }
+ // Do NOT scroll the chat container in this case
}
- return '';
+ return ''; // Return empty string as expected by some slash command parsers
},
unnamedArgumentList: [
SlashCommandArgument.fromProps({
@@ -2204,8 +2208,9 @@ export function initDefaultSlashCommands() {
helpString: `
Scrolls the chat view to the specified message index. Uses the [mesid]
attribute for locating the message element. Index starts at 0.
- 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.
+ It attempts to center the character's name/header area within the message block by targeting the .ch_name
element. Highlights the message using a flash animation.
Automatically attempts to load all messages before scrolling to improve success rate, addressing issues with lazy loading.
+ A warning is displayed if the message element cannot be located even after attempting to load all messages.
Example: /goto-floor 10
Scrolls to the 11th message (mesid=10).
@@ -2213,55 +2218,11 @@ export function initDefaultSlashCommands() {
`,
}));
- // --- Improved CSS for highlight ---
const styleId = 'goto-floor-highlight-style';
- if (!document.getElementById(styleId)) {
- const style = document.createElement('style');
- style.id = styleId;
- style.textContent = `
- /* Base state for elements that *can* be highlighted */
- /* Ensures transition applies smoothly in both directions */
- .mes, .mes_block {
- transition: background-color 0.5s ease-in-out, box-shadow 0.5s ease-in-out;
- /* Add position relative if not already present, needed for potential pseudo-elements */
- position: relative;
- }
-
- /* --- Highlighting Style --- */
- .mes.highlight-scroll,
- .mes_block.highlight-scroll {
- /* Use theme color for shadow, fallback to gold */
- box-shadow: 0 0 10px var(--ac-style-color-matchedText, #FFD700) !important;
- z-index: 5; /* Ensure highlight is visually prominent */
- }
-
- /* Modern browsers: Use color-mix for transparent background */
- @supports (background-color: color-mix(in srgb, white 50%, black)) {
- .mes.highlight-scroll,
- .mes_block.highlight-scroll {
- /* Mix theme color with transparent for background */
- background-color: color-mix(in srgb, var(--ac-style-color-matchedText, #FFD700) 35%, transparent) !important;
- }
- }
-
- /* Fallback for older browsers: Use a fixed semi-transparent background */
- @supports not (background-color: color-mix(in srgb, white 50%, black)) {
- .mes.highlight-scroll,
- .mes_block.highlight-scroll {
- background-color: rgba(255, 215, 0, 0.35) !important; /* Fallback semi-transparent gold */
- }
- }
-
- /* --- Fade-out Control --- */
- /* When fading out, explicitly transition back to transparent/none */
- .mes.highlight-scroll-fadeout,
- .mes_block.highlight-scroll-fadeout {
- background-color: transparent !important;
- box-shadow: none !important;
- }
- `;
- document.head.appendChild(style);
+ if (document.getElementById(styleId)) {
+ document.getElementById(styleId).remove();
}
+
registerVariableCommands();
}
From 59ebf2e5b8a23080bec1ed05d152ad1c61a323ec Mon Sep 17 00:00:00 2001
From: awaae001 <3271436144@qq.com>
Date: Wed, 23 Apr 2025 01:12:57 +0800
Subject: [PATCH 5/7] =?UTF-8?q?refactor(slash-commands):=20=E9=87=8D?=
=?UTF-8?q?=E5=91=BD=E5=90=8D=20goto-floor=20=E5=91=BD=E4=BB=A4=E4=B8=BA?=
=?UTF-8?q?=20chat-jump?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 将命令名称从 'goto-floor' 修改为 'chat-jump',以更好地反映其功能
---
public/scripts/slash-commands.js | 46 ++++++++++++++++----------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index 53f3ba364..1ba7a3a5f 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -2132,25 +2132,25 @@ export function initDefaultSlashCommands() {
}));
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
- name: 'goto-floor',
+ name: 'chat-jump',
aliases: ['floor', 'jump', 'scrollto'],
callback: async (_, index) => {
const floorIndex = Number(index);
-
+
const chatLength = typeof chat !== 'undefined' ? chat.length : -1; // Use -1 if chat is undefined to avoid errors
if (isNaN(floorIndex) || floorIndex < 0 || (chatLength !== -1 && floorIndex >= chatLength)) {
const maxIndex = (chatLength !== -1 ? chatLength - 1 : 'unknown');
toastr.warning(`Invalid message index: ${index}. Please enter a number between 0 and ${maxIndex}.`);
- console.warn(`WARN: Invalid message index provided for /goto-floor: ${index}. Max index: ${maxIndex}`);
+ console.warn(`WARN: Invalid message index provided for /chat-jump: ${index}. Max index: ${maxIndex}`);
return '';
}
-
+
// --- Load all messages first to ensure the target element exists ---
- console.log(`INFO: Attempting to load all messages before attempting to goto-floor ${index}.`);
+ console.log(`INFO: Attempting to load all messages before attempting to chat-jump ${index}.`);
try {
// Assuming showMoreMessages is available globally or within scope
await showMoreMessages(Number.MAX_SAFE_INTEGER);
- console.log(`INFO: All messages loaded (or loading initiated).`);
+ console.log('INFO: All messages loaded (or loading initiated).');
// Give the rendering a moment to potentially catch up after showMoreMessages
await new Promise(resolve => setTimeout(resolve, 100)); // Adjust delay if needed
} catch (error) {
@@ -2159,40 +2159,40 @@ export function initDefaultSlashCommands() {
return ''; // Exit if loading fails
}
// --- End of loading step ---
-
+
const messageElement = document.querySelector(`[mesid="${floorIndex}"]`);
-
+
if (messageElement) {
// --- Corrected: Use the actual class from the template ---
const headerElement = messageElement.querySelector('.ch_name');
const elementToScroll = headerElement || messageElement; // Fallback to the entire message div
const blockPosition = headerElement ? 'center' : 'start';
-
+
elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition });
-
+
// Highlight the message element
if (messageElement instanceof HTMLElement) {
if (typeof $ !== 'undefined') { // Check if jQuery is available
- flashHighlight($(messageElement), 1500);
+ flashHighlight($(messageElement), 1500);
} else {
console.warn('jQuery not available, cannot use flashHighlight.');
// Optional: Add a temporary CSS class highlight if jQuery/flashHighlight is missing
- messageElement.style.transition = 'background-color 0.5s ease';
- messageElement.style.backgroundColor = 'yellow'; // Or some highlight color
- setTimeout(() => {
- messageElement.style.backgroundColor = ''; // Remove highlight
- }, 1500); // Match flash duration
+ messageElement.style.transition = 'background-color 0.5s ease';
+ messageElement.style.backgroundColor = 'yellow'; // Or some highlight color
+ setTimeout(() => {
+ messageElement.style.backgroundColor = ''; // Remove highlight
+ }, 1500); // Match flash duration
}
-
+
} else {
console.warn('Message element is not an HTMLElement, cannot flash highlight.');
}
-
-
+
+
} else {
// Only warn if element is not found *after* attempting to load all messages
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 or the index is invalid.`);
- console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /goto-floor, even after attempting to load all messages.`);
+ console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /chat-jump, even after attempting to load all messages.`);
// Do NOT scroll the chat container in this case
}
return ''; // Return empty string as expected by some slash command parsers
@@ -2213,12 +2213,12 @@ export function initDefaultSlashCommands() {
A warning is displayed if the message element cannot be located even after attempting to load all messages.
-
Example: /goto-floor 10
Scrolls to the 11th message (mesid=10).
+
Example: /chat-jump 10
Scrolls to the 11th message (mesid=10).
`,
}));
-
- const styleId = 'goto-floor-highlight-style';
+
+ const styleId = 'chat-jump-highlight-style';
if (document.getElementById(styleId)) {
document.getElementById(styleId).remove();
}
From b39b7998ce5cfed8e5945d0bd29e3851eb9a205a Mon Sep 17 00:00:00 2001
From: awaae001 <3271436144@qq.com>
Date: Wed, 23 Apr 2025 01:34:29 +0800
Subject: [PATCH 6/7] =?UTF-8?q?refactor(slash-commands):=20=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E6=B6=88=E6=81=AF=E5=AE=9A=E4=BD=8D=E5=92=8C=E6=BB=9A?=
=?UTF-8?q?=E5=8A=A8=E6=95=88=E6=9E=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/scripts/slash-commands.js | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index 1ba7a3a5f..6ac0e445c 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -2161,14 +2161,22 @@ export function initDefaultSlashCommands() {
// --- End of loading step ---
const messageElement = document.querySelector(`[mesid="${floorIndex}"]`);
+ const chatContainer = document.getElementById('chat');
- if (messageElement) {
- // --- Corrected: Use the actual class from the template ---
+ if (messageElement && chatContainer) {
const headerElement = messageElement.querySelector('.ch_name');
const elementToScroll = headerElement || messageElement; // Fallback to the entire message div
- const blockPosition = headerElement ? 'center' : 'start';
- elementToScroll.scrollIntoView({ behavior: 'smooth', block: blockPosition });
+ // Calculate position relative to chat container
+ const elementRect = elementToScroll.getBoundingClientRect();
+ const containerRect = chatContainer.getBoundingClientRect();
+ const scrollPosition = elementRect.top - containerRect.top + chatContainer.scrollTop;
+
+ const viewportOffset = chatContainer.clientHeight * 0.1; // 25% from top
+ chatContainer.scrollTo({
+ top: scrollPosition - viewportOffset,
+ behavior: 'smooth',
+ });
// Highlight the message element
if (messageElement instanceof HTMLElement) {
@@ -2183,12 +2191,9 @@ export function initDefaultSlashCommands() {
messageElement.style.backgroundColor = ''; // Remove highlight
}, 1500); // Match flash duration
}
-
} else {
console.warn('Message element is not an HTMLElement, cannot flash highlight.');
}
-
-
} else {
// Only warn if element is not found *after* attempting to load all messages
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 or the index is invalid.`);
From 870abe077675f30e3546a9c4eaa6a4b68b1c234e Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Tue, 22 Apr 2025 22:36:01 +0300
Subject: [PATCH 7/7] Code clean-up
---
public/scripts/slash-commands.js | 85 +++++++++-----------------------
1 file changed, 24 insertions(+), 61 deletions(-)
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index 6ac0e445c..ae1523039 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -22,6 +22,7 @@ import {
extractMessageBias,
generateQuietPrompt,
generateRaw,
+ getFirstDisplayedMessageId,
getThumbnailUrl,
is_send_press,
main_api,
@@ -2133,74 +2134,44 @@ export function initDefaultSlashCommands() {
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
name: 'chat-jump',
- aliases: ['floor', 'jump', 'scrollto'],
+ aliases: ['chat-scrollto', 'floor-teleport'],
callback: async (_, index) => {
- const floorIndex = Number(index);
+ const messageIndex = Number(index);
- const chatLength = typeof chat !== 'undefined' ? chat.length : -1; // Use -1 if chat is undefined to avoid errors
- if (isNaN(floorIndex) || floorIndex < 0 || (chatLength !== -1 && floorIndex >= chatLength)) {
- const maxIndex = (chatLength !== -1 ? chatLength - 1 : 'unknown');
- toastr.warning(`Invalid message index: ${index}. Please enter a number between 0 and ${maxIndex}.`);
- console.warn(`WARN: Invalid message index provided for /chat-jump: ${index}. Max index: ${maxIndex}`);
+ if (isNaN(messageIndex) || messageIndex < 0 || messageIndex >= chat.length) {
+ toastr.warning(t`Invalid message index: ${index}. Please enter a number between 0 and ${chat.length}.`);
+ console.warn(`WARN: Invalid message index provided for /chat-jump: ${index}. Max index: ${chat.length}`);
return '';
}
- // --- Load all messages first to ensure the target element exists ---
- console.log(`INFO: Attempting to load all messages before attempting to chat-jump ${index}.`);
- try {
- // Assuming showMoreMessages is available globally or within scope
- await showMoreMessages(Number.MAX_SAFE_INTEGER);
- console.log('INFO: All messages loaded (or loading initiated).');
- // Give the rendering a moment to potentially catch up after showMoreMessages
- await new Promise(resolve => setTimeout(resolve, 100)); // Adjust delay if needed
- } catch (error) {
- console.error('Error loading messages:', error);
- toastr.error('An error occurred while trying to load messages.');
- return ''; // Exit if loading fails
+ // Load more messages if needed
+ const firstDisplayedMessageId = getFirstDisplayedMessageId();
+ if (isFinite(firstDisplayedMessageId) && messageIndex < firstDisplayedMessageId) {
+ const needToLoadCount = firstDisplayedMessageId - messageIndex;
+ await showMoreMessages(needToLoadCount);
+ await delay(1);
}
- // --- End of loading step ---
- const messageElement = document.querySelector(`[mesid="${floorIndex}"]`);
const chatContainer = document.getElementById('chat');
+ const messageElement = document.querySelector(`#chat .mes[mesid="${messageIndex}"]`);
- if (messageElement && chatContainer) {
- const headerElement = messageElement.querySelector('.ch_name');
- const elementToScroll = headerElement || messageElement; // Fallback to the entire message div
-
- // Calculate position relative to chat container
- const elementRect = elementToScroll.getBoundingClientRect();
+ if (messageElement instanceof HTMLElement && chatContainer instanceof HTMLElement) {
+ const elementRect = messageElement.getBoundingClientRect();
const containerRect = chatContainer.getBoundingClientRect();
- const scrollPosition = elementRect.top - containerRect.top + chatContainer.scrollTop;
- const viewportOffset = chatContainer.clientHeight * 0.1; // 25% from top
+ const scrollPosition = elementRect.top - containerRect.top + chatContainer.scrollTop;
chatContainer.scrollTo({
- top: scrollPosition - viewportOffset,
+ top: scrollPosition,
behavior: 'smooth',
});
- // Highlight the message element
- if (messageElement instanceof HTMLElement) {
- if (typeof $ !== 'undefined') { // Check if jQuery is available
- flashHighlight($(messageElement), 1500);
- } else {
- console.warn('jQuery not available, cannot use flashHighlight.');
- // Optional: Add a temporary CSS class highlight if jQuery/flashHighlight is missing
- messageElement.style.transition = 'background-color 0.5s ease';
- messageElement.style.backgroundColor = 'yellow'; // Or some highlight color
- setTimeout(() => {
- messageElement.style.backgroundColor = ''; // Remove highlight
- }, 1500); // Match flash duration
- }
- } else {
- console.warn('Message element is not an HTMLElement, cannot flash highlight.');
- }
+ flashHighlight($(messageElement), 2000);
} else {
- // Only warn if element is not found *after* attempting to load all messages
- 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 or the index is invalid.`);
- console.warn(`WARN: Element not found for message index ${floorIndex} using querySelector [mesid="${floorIndex}"] in /chat-jump, even after attempting to load all messages.`);
- // Do NOT scroll the chat container in this case
+ toastr.warning(t`Could not find element for message ${messageIndex}. It might not be rendered yet or the index is invalid.`);
+ console.warn(`WARN: Element not found for message index ${messageIndex} in /chat-jump.`);
}
- return ''; // Return empty string as expected by some slash command parsers
+
+ return '';
},
unnamedArgumentList: [
SlashCommandArgument.fromProps({
@@ -2212,22 +2183,14 @@ export function initDefaultSlashCommands() {
],
helpString: `
- Scrolls the chat view to the specified message index. Uses the [mesid]
attribute for locating the message element. Index starts at 0.
- It attempts to center the character's name/header area within the message block by targeting the .ch_name
element. Highlights the message using a flash animation.
- Automatically attempts to load all messages before scrolling to improve success rate, addressing issues with lazy loading.
- A warning is displayed if the message element cannot be located even after attempting to load all messages.
+ Scrolls the chat view to the specified message index. Index starts at 0.
-
Example: /chat-jump 10
Scrolls to the 11th message (mesid=10).
+
Example: /chat-jump 10
Scrolls to the 11th message (id=10).
`,
}));
- const styleId = 'chat-jump-highlight-style';
- if (document.getElementById(styleId)) {
- document.getElementById(styleId).remove();
- }
-
registerVariableCommands();
}