Skip to content

Instantly share code, notes, and snippets.

@LenAnderson
Last active December 21, 2023 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LenAnderson/0b2a1466bcc1b2e5b447162c26ad6ced to your computer and use it in GitHub Desktop.
Save LenAnderson/0b2a1466bcc1b2e5b447162c26ad6ced to your computer and use it in GitHub Desktop.
SillyTavern - Quickly Change Message Names
// ==UserScript==
// @name SillyTavern - Change Message Name
// @namespace https://github.com/LenAnderson
// @version 0.2
// @description Quickly edit message names
// @author You
// @match http://localhost:8000/
// @grant none
// ==/UserScript==
(function() {
'use strict';
const wait = async(millis)=>(new Promise(resolve=>setTimeout(resolve,millis)));
const debounce = (func, delay=100)=>{
let to;
return (...args) => {
if (to) clearTimeout(to);
to = setTimeout(()=>func.apply(this, args), delay);
};
}
const listen = ()=>{
console.log('[STCMN]', 'listen');
let ok;
let cancel;
Array.from(document.querySelectorAll('.mes_block .name_text:not([data-stcmn])')).filter(it=>!it.closest('.template_element')).forEach(el=>{
console.log('[STCMN]', el);
el.setAttribute('data-stcmn', 1);
el.addEventListener('click', ()=>{
console.log('[STCMN]', 'click', el);
el.style.display = 'none';
const inp = document.createElement('input'); {
inp.value = el.textContent.trim();
inp.style.background = 'none';
inp.style.border = 'none';
inp.style.font = 'inherit';
inp.style.color = 'inherit';
inp.style.marginBottom = '-3px';
inp.style.borderBottom = '1px solid var(--SmartThemeBodyColor)';
inp.addEventListener('keydown', evt=>{
switch (evt.key) {
case 'Enter': {
ok.click();
break;
}
case 'Escape': {
cancel.click();
break;
}
}
});
el.insertAdjacentElement('afterend', inp);
inp.select();
}
const acts = document.createElement('span'); {
acts.style.height = '1px';
acts.style.display = 'inline-block';
ok = document.createElement('span'); {
ok.classList.add('menu_button');
ok.classList.add('menu_button_icon');
ok.style.margin = 0;
ok.addEventListener('click', async()=>{
el.textContent = inp.value.trim();
inp.remove();
ok.remove();
cancel.remove();
el.style.display = '';
const id = Number(el.closest('[mesid]').getAttribute('mesid'));
SillyTavern.getContext().executeSlashCommands(`/sendas name="${inp.value.trim()}" at=${id} ${SillyTavern.getContext().chat[id].mes.replace(/\|/g, '\|')} | /cut ${id+1}`);
await wait(200);
document.querySelector(`[mesid="${id}"]`).scrollIntoView();
});
const icon = document.createElement('span'); {
icon.classList.add('fa-solid');
icon.classList.add('fa-save');
ok.append(icon);
}
acts.append(ok);
}
cancel = document.createElement('span'); {
cancel.classList.add('menu_button');
cancel.classList.add('menu_button_icon');
cancel.style.margin = 0;
cancel.addEventListener('click', ()=>{
el.textContent = inp.value.trim();
inp.remove();
ok.remove();
cancel.remove();
el.style.display = '';
});
const icon = document.createElement('span'); {
icon.classList.add('fa-solid');
icon.classList.add('fa-circle-xmark');
cancel.append(icon);
}
inp.insertAdjacentElement('afterend', cancel);
}
inp.insertAdjacentElement('afterend', acts);
}
});
});
};
listen();
const mo = new MutationObserver(debounce(listen));
mo.observe(document.body, {childList:true, subtree:true, attributes:true, characterData:true});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment