Add ranges to /cut slash command

This commit is contained in:
Cohee 2023-11-08 23:04:32 +02:00
parent 606f2bd9bb
commit 6dc5906229
3 changed files with 77 additions and 21 deletions

View File

@ -1205,7 +1205,7 @@ async function replaceCurrentChat() {
const TRUNCATION_THRESHOLD = 100;
function showMoreMessages() {
export function showMoreMessages() {
let messageId = Number($('#chat').children('.mes').first().attr('mesid'));
let count = TRUNCATION_THRESHOLD;
@ -6217,8 +6217,8 @@ async function importCharacterChat(formData) {
});
}
function updateViewMessageIds() {
const minId = getFirstDisplayedMessageId();
function updateViewMessageIds(startFromZero = false) {
const minId = startFromZero ? 0 : getFirstDisplayedMessageId();
$('#chat').find(".mes").each(function (index, element) {
$(element).attr("mesid", minId + index);
@ -6231,7 +6231,7 @@ function updateViewMessageIds() {
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 minId = Math.min(...allIds);
return minId;
@ -8520,15 +8520,17 @@ jQuery(async function () {
count_view_mes--;
}
let startFromZero = Number(this_edit_mes_id) === 0;
this_edit_mes_id = undefined;
updateViewMessageIds();
await saveChatConditional();
eventSource.emit(event_types.MESSAGE_DELETED, count_view_mes);
updateViewMessageIds(startFromZero);
saveChatDebounced();
hideSwipeButtons();
showSwipeButtons();
await eventSource.emit(event_types.MESSAGE_DELETED, count_view_mes);
});
$(document).on("click", ".mes_edit_done", async function () {

View File

@ -15,6 +15,9 @@ import {
setCharacterId,
setEditedMessageId,
renderTemplate,
chat,
getFirstDisplayedMessageId,
showMoreMessages,
} from "../script.js";
import { isMobile, initMovingUI, favsToHotswap } from "./RossAscends-mods.js";
import {
@ -30,7 +33,7 @@ import {
import { registerSlashCommand } from "./slash-commands.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 {
loadPowerUserSettings,
@ -1750,25 +1753,49 @@ function doRandomChat() {
async function doMesCut(_, text) {
console.debug(`was asked to cut message id #${text}`)
const range = stringToRange(text, 0, chat.length - 1);
//reject invalid args or no args
if (text && isNaN(text) || !text) {
toastr.error(`Must enter a single number only, non-number characters disallowed.`)
if (!range) {
toastr.warning(`Must provide a Message ID or a range to cut.`)
return
}
let mesIDToCut = Number(text).toFixed(0)
let mesToCut = $("#chat").find(`.mes[mesid=${mesIDToCut}]`)
let totalMesToCut = (range.end - range.start) + 1;
let mesIDToCut = range.start;
if (!mesToCut.length) {
toastr.error(`Could not find message with ID: ${mesIDToCut}`)
return
for (let i = 0; i < totalMesToCut; i++) {
let done = false;
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) {
toastr.error(`Could not find message with ID: ${mesIDToCut}`)
return;
}
}
setEditedMessageId(mesIDToCut);
eventSource.once(event_types.MESSAGE_DELETED, () => {
done = true;
});
mesToCut.find('.mes_edit_delete').trigger('click', { fromSlashCommand: true });
while (!done) {
await delay(1);
}
}
setEditedMessageId(mesIDToCut);
mesToCut.find('.mes_edit_delete').trigger('click', { fromSlashCommand: true });
}
async function doDelMode(_, text) {
//first enter delmode
@ -2671,7 +2698,7 @@ $(document).ready(() => {
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('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('bgcol', setAvgBG, [], ' WIP test of auto-bg avg coloring', true, true);
});

View File

@ -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.
* @param {any} value Current value.