mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add ranges to /cut slash command
This commit is contained in:
@ -1205,7 +1205,7 @@ async function replaceCurrentChat() {
|
|||||||
|
|
||||||
const TRUNCATION_THRESHOLD = 100;
|
const TRUNCATION_THRESHOLD = 100;
|
||||||
|
|
||||||
function showMoreMessages() {
|
export function showMoreMessages() {
|
||||||
let messageId = Number($('#chat').children('.mes').first().attr('mesid'));
|
let messageId = Number($('#chat').children('.mes').first().attr('mesid'));
|
||||||
let count = TRUNCATION_THRESHOLD;
|
let count = TRUNCATION_THRESHOLD;
|
||||||
|
|
||||||
@ -6217,8 +6217,8 @@ async function importCharacterChat(formData) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateViewMessageIds() {
|
function updateViewMessageIds(startFromZero = false) {
|
||||||
const minId = getFirstDisplayedMessageId();
|
const minId = startFromZero ? 0 : getFirstDisplayedMessageId();
|
||||||
|
|
||||||
$('#chat').find(".mes").each(function (index, element) {
|
$('#chat').find(".mes").each(function (index, element) {
|
||||||
$(element).attr("mesid", minId + index);
|
$(element).attr("mesid", minId + index);
|
||||||
@ -6231,7 +6231,7 @@ function updateViewMessageIds() {
|
|||||||
updateEditArrowClasses();
|
updateEditArrowClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFirstDisplayedMessageId() {
|
export function getFirstDisplayedMessageId() {
|
||||||
const allIds = Array.from(document.querySelectorAll('#chat .mes')).map(el => Number(el.getAttribute('mesid'))).filter(x => !isNaN(x));
|
const allIds = Array.from(document.querySelectorAll('#chat .mes')).map(el => Number(el.getAttribute('mesid'))).filter(x => !isNaN(x));
|
||||||
const minId = Math.min(...allIds);
|
const minId = Math.min(...allIds);
|
||||||
return minId;
|
return minId;
|
||||||
@ -8520,15 +8520,17 @@ jQuery(async function () {
|
|||||||
count_view_mes--;
|
count_view_mes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let startFromZero = Number(this_edit_mes_id) === 0;
|
||||||
|
|
||||||
this_edit_mes_id = undefined;
|
this_edit_mes_id = undefined;
|
||||||
|
|
||||||
updateViewMessageIds();
|
updateViewMessageIds(startFromZero);
|
||||||
await saveChatConditional();
|
saveChatDebounced();
|
||||||
|
|
||||||
eventSource.emit(event_types.MESSAGE_DELETED, count_view_mes);
|
|
||||||
|
|
||||||
hideSwipeButtons();
|
hideSwipeButtons();
|
||||||
showSwipeButtons();
|
showSwipeButtons();
|
||||||
|
|
||||||
|
await eventSource.emit(event_types.MESSAGE_DELETED, count_view_mes);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("click", ".mes_edit_done", async function () {
|
$(document).on("click", ".mes_edit_done", async function () {
|
||||||
|
@ -15,6 +15,9 @@ import {
|
|||||||
setCharacterId,
|
setCharacterId,
|
||||||
setEditedMessageId,
|
setEditedMessageId,
|
||||||
renderTemplate,
|
renderTemplate,
|
||||||
|
chat,
|
||||||
|
getFirstDisplayedMessageId,
|
||||||
|
showMoreMessages,
|
||||||
} from "../script.js";
|
} from "../script.js";
|
||||||
import { isMobile, initMovingUI, favsToHotswap } from "./RossAscends-mods.js";
|
import { isMobile, initMovingUI, favsToHotswap } from "./RossAscends-mods.js";
|
||||||
import {
|
import {
|
||||||
@ -30,7 +33,7 @@ import {
|
|||||||
import { registerSlashCommand } from "./slash-commands.js";
|
import { registerSlashCommand } from "./slash-commands.js";
|
||||||
import { tokenizers } from "./tokenizers.js";
|
import { tokenizers } from "./tokenizers.js";
|
||||||
|
|
||||||
import { countOccurrences, debounce, delay, isOdd, resetScrollHeight, sortMoments, timestampToMoment } from "./utils.js";
|
import { countOccurrences, debounce, delay, isOdd, resetScrollHeight, sortMoments, stringToRange, timestampToMoment } from "./utils.js";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
loadPowerUserSettings,
|
loadPowerUserSettings,
|
||||||
@ -1750,25 +1753,49 @@ function doRandomChat() {
|
|||||||
|
|
||||||
async function doMesCut(_, text) {
|
async function doMesCut(_, text) {
|
||||||
console.debug(`was asked to cut message id #${text}`)
|
console.debug(`was asked to cut message id #${text}`)
|
||||||
|
const range = stringToRange(text, 0, chat.length - 1);
|
||||||
|
|
||||||
//reject invalid args or no args
|
//reject invalid args or no args
|
||||||
if (text && isNaN(text) || !text) {
|
if (!range) {
|
||||||
toastr.error(`Must enter a single number only, non-number characters disallowed.`)
|
toastr.warning(`Must provide a Message ID or a range to cut.`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let mesIDToCut = Number(text).toFixed(0)
|
let totalMesToCut = (range.end - range.start) + 1;
|
||||||
|
let mesIDToCut = range.start;
|
||||||
|
|
||||||
|
for (let i = 0; i < totalMesToCut; i++) {
|
||||||
|
let done = false;
|
||||||
let mesToCut = $("#chat").find(`.mes[mesid=${mesIDToCut}]`)
|
let mesToCut = $("#chat").find(`.mes[mesid=${mesIDToCut}]`)
|
||||||
|
|
||||||
|
if (!mesToCut.length) {
|
||||||
|
while (getFirstDisplayedMessageId() > mesIDToCut && getFirstDisplayedMessageId() !== 0) {
|
||||||
|
showMoreMessages();
|
||||||
|
await delay(1);
|
||||||
|
mesToCut = $("#chat").find(`.mes[mesid=${mesIDToCut}]`);
|
||||||
|
|
||||||
|
if (mesToCut.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!mesToCut.length) {
|
if (!mesToCut.length) {
|
||||||
toastr.error(`Could not find message with ID: ${mesIDToCut}`)
|
toastr.error(`Could not find message with ID: ${mesIDToCut}`)
|
||||||
return
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setEditedMessageId(mesIDToCut);
|
setEditedMessageId(mesIDToCut);
|
||||||
|
eventSource.once(event_types.MESSAGE_DELETED, () => {
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
mesToCut.find('.mes_edit_delete').trigger('click', { fromSlashCommand: true });
|
mesToCut.find('.mes_edit_delete').trigger('click', { fromSlashCommand: true });
|
||||||
|
while (!done) {
|
||||||
|
await delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function doDelMode(_, text) {
|
async function doDelMode(_, text) {
|
||||||
|
|
||||||
//first enter delmode
|
//first enter delmode
|
||||||
@ -2671,7 +2698,7 @@ $(document).ready(() => {
|
|||||||
registerSlashCommand('newchat', doNewChat, [], '– start a new chat with current character', true, true);
|
registerSlashCommand('newchat', doNewChat, [], '– start a new chat with current character', true, true);
|
||||||
registerSlashCommand('random', doRandomChat, [], '– start a new chat with a random character', true, true);
|
registerSlashCommand('random', doRandomChat, [], '– start a new chat with a random character', true, true);
|
||||||
registerSlashCommand('delmode', doDelMode, ['del'], '<span class="monospace">(optional number)</span> – enter message deletion mode, and auto-deletes N messages if numeric argument is provided', true, true);
|
registerSlashCommand('delmode', doDelMode, ['del'], '<span class="monospace">(optional number)</span> – enter message deletion mode, and auto-deletes N messages if numeric argument is provided', true, true);
|
||||||
registerSlashCommand('cut', doMesCut, [], '<span class="monospace">(number)</span> – cuts the specified message from the chat', true, true);
|
registerSlashCommand('cut', doMesCut, [], '<span class="monospace">(number or range)</span> – cuts the specified message or continuous chunk from the chat, e.g. <tt>/cut 0-10</tt>. Ranges are inclusive!', true, true);
|
||||||
registerSlashCommand('resetpanels', doResetPanels, ['resetui'], '– resets UI panels to original state.', true, true);
|
registerSlashCommand('resetpanels', doResetPanels, ['resetui'], '– resets UI panels to original state.', true, true);
|
||||||
registerSlashCommand('bgcol', setAvgBG, [], '– WIP test of auto-bg avg coloring', true, true);
|
registerSlashCommand('bgcol', setAvgBG, [], '– WIP test of auto-bg avg coloring', true, true);
|
||||||
});
|
});
|
||||||
|
@ -27,6 +27,33 @@ export function isValidUrl(value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses ranges like 10-20 or 10.
|
||||||
|
* Range is inclusive. Start must be less than end.
|
||||||
|
* Returns null if invalid.
|
||||||
|
* @param {string} input The input string.
|
||||||
|
* @param {number} min The minimum value.
|
||||||
|
* @param {number} max The maximum value.
|
||||||
|
* @returns {{ start: number, end: number }} The parsed range.
|
||||||
|
*/
|
||||||
|
export function stringToRange(input, min, max) {
|
||||||
|
let start, end;
|
||||||
|
|
||||||
|
if (input.includes('-')) {
|
||||||
|
const parts = input.split('-');
|
||||||
|
start = parts[0] ? parseInt(parts[0], 10) : NaN;
|
||||||
|
end = parts[1] ? parseInt(parts[1], 10) : NaN;
|
||||||
|
} else {
|
||||||
|
start = end = parseInt(input, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(start) || isNaN(end) || start > end || start < min || end > max) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { start, end };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a value is unique in an array.
|
* Determines if a value is unique in an array.
|
||||||
* @param {any} value Current value.
|
* @param {any} value Current value.
|
||||||
|
Reference in New Issue
Block a user