chchar slash cmd (#4916)
* Add an additional slash command to change a message's character and avatar. * Refactor message character change command to update message sender's name * Fix default value * Allow setting unbound message names --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Fuse, DOMPurify } from '../lib.js';
|
||||
import { canUseNegativeLookbehind, copyText, flashHighlight } from './utils.js';
|
||||
import { canUseNegativeLookbehind, copyText, findPersona, flashHighlight } from './utils.js';
|
||||
|
||||
import {
|
||||
Generate,
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
addOneMessage,
|
||||
characters,
|
||||
chat,
|
||||
chatElement,
|
||||
chat_metadata,
|
||||
comment_avatar,
|
||||
deactivateSendButtons,
|
||||
@@ -764,6 +765,50 @@ export function initDefaultSlashCommands() {
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||
name: 'message-name',
|
||||
callback: changeMessageName,
|
||||
returns: 'The updated name of the message sender',
|
||||
namedArgumentList: [
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'at',
|
||||
description: 'the ID of the message to modify (index-based, corresponding to message id). If omitted, the last message is chosen.\nNegative values are accepted and will work similarly to how \'depth\' usually works. For example, -1 will modify the message right before the last message in chat. At must be nonzero.',
|
||||
typeList: [ARGUMENT_TYPE.NUMBER],
|
||||
defaultValue: '',
|
||||
enumProvider: commonEnumProviders.messages({ allowIdAfter: true }),
|
||||
}),
|
||||
],
|
||||
unnamedArgumentList: [
|
||||
SlashCommandArgument.fromProps({
|
||||
description: 'Persona name, character name, or unique character identifier (avatar key)',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
enumProvider: (executor) => {
|
||||
let modifyAt = Number(executor.namedArgumentList.find(arg => arg.name === 'at')?.value ?? (chat.length - 1));
|
||||
if (!isNaN(modifyAt) && (modifyAt < 0 || Object.is(modifyAt, -0))) {
|
||||
modifyAt = chat.length + modifyAt;
|
||||
}
|
||||
return chat[modifyAt]?.is_user
|
||||
? commonEnumProviders.personas()
|
||||
: commonEnumProviders.characters('character')();
|
||||
},
|
||||
}),
|
||||
],
|
||||
helpString: `
|
||||
<div>
|
||||
Changes the name of a message sender to one of your choice.
|
||||
</div>
|
||||
<div>
|
||||
<strong>Example:</strong>
|
||||
<ul>
|
||||
<li>
|
||||
<pre><code>/message-name at=-2 "Chloe"</code></pre>
|
||||
Will change the third message from the bottom to be sent by "Chloe".
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||
name: 'sendas',
|
||||
rawQuotes: true,
|
||||
@@ -4510,6 +4555,72 @@ export function getNameAndAvatarForMessage(character, name = null) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the character name on a message at a given index.
|
||||
* @param {object?} args - Named arguments
|
||||
* @param {string} name - Name to change to.
|
||||
*
|
||||
* @returns {Promise<string>} The updated message name.
|
||||
*/
|
||||
export async function changeMessageName(args, name) {
|
||||
name = String(name ?? '').trim();
|
||||
if (!name) {
|
||||
toastr.warning(t`You must provide a name to change the message to.`);
|
||||
return '';
|
||||
}
|
||||
|
||||
let modifyAt = Number(args?.at ?? (chat.length - 1));
|
||||
// Convert possible depth parameter to index
|
||||
if (!isNaN(modifyAt) && (modifyAt < 0 || Object.is(modifyAt, -0))) {
|
||||
// Negative value means going back from current chat length. (E.g.: 8 messages, Depth 1 means insert at index 7)
|
||||
modifyAt = chat.length + modifyAt;
|
||||
}
|
||||
|
||||
const message = chat[modifyAt];
|
||||
if (!message) {
|
||||
toastr.warning(t`No message found at the specified index.`);
|
||||
return '';
|
||||
}
|
||||
|
||||
let newName = '';
|
||||
|
||||
if (message.is_user) {
|
||||
const persona = findPersona({ name: name });
|
||||
if (persona) {
|
||||
message.name = newName = persona.name;
|
||||
message.force_avatar = getThumbnailUrl('persona', persona.avatar);
|
||||
message.original_avatar = persona.avatar;
|
||||
} else {
|
||||
message.name = newName = name;
|
||||
message.force_avatar = default_avatar;
|
||||
message.original_avatar = default_avatar;
|
||||
}
|
||||
} else {
|
||||
const character = findChar({ name: name });
|
||||
if (character) {
|
||||
const characterInfo = getNameAndAvatarForMessage(character, name);
|
||||
message.name = newName = characterInfo.name;
|
||||
message.force_avatar = characterInfo.force_avatar;
|
||||
message.original_avatar = characterInfo.original_avatar;
|
||||
} else {
|
||||
message.name = newName = name;
|
||||
message.force_avatar = default_avatar;
|
||||
message.original_avatar = default_avatar;
|
||||
}
|
||||
}
|
||||
|
||||
await eventSource.emit(event_types.MESSAGE_EDITED, modifyAt);
|
||||
const existingMessage = chatElement.find(`.mes[mesid="${modifyAt}"]`);
|
||||
if (existingMessage.length) {
|
||||
addOneMessage(message, { forceId: modifyAt, insertAfter: modifyAt, scroll: false });
|
||||
existingMessage.remove();
|
||||
}
|
||||
await eventSource.emit(event_types.MESSAGE_UPDATED, modifyAt);
|
||||
await saveChatConditional();
|
||||
|
||||
return newName;
|
||||
}
|
||||
|
||||
export async function sendMessageAs(args, text) {
|
||||
let name = args.name?.trim();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user