Add ranges to /cut slash command
This commit is contained in:
parent
606f2bd9bb
commit
6dc5906229
|
@ -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 () {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue