Preserve chat scroll when setting a hypebot text

This commit is contained in:
Cohee 2023-08-27 21:51:33 +03:00
parent 636c06ffdd
commit 8566fda1cd
1 changed files with 19 additions and 8 deletions

View File

@ -6,6 +6,7 @@ import { bufferToBase64, debounce } from "../../utils.js";
import { decodeTextTokens, getTextTokens, tokenizers } from "../../tokenizers.js"; import { decodeTextTokens, getTextTokens, tokenizers } from "../../tokenizers.js";
const MODULE_NAME = 'hypebot'; const MODULE_NAME = 'hypebot';
const WAITING_VERBS = ['thinking', 'typing', 'brainstorming', 'cooking', 'conjuring'];
const MAX_PROMPT = 1024; const MAX_PROMPT = 1024;
const MAX_LENGTH = 50; const MAX_LENGTH = 50;
const MAX_STRING_LENGTH = MAX_PROMPT * 4; const MAX_STRING_LENGTH = MAX_PROMPT * 4;
@ -20,8 +21,7 @@ const settings = {
* @returns {string} Random waiting verb * @returns {string} Random waiting verb
*/ */
function getWaitingVerb() { function getWaitingVerb() {
const waitingVerbs = ['thinking', 'typing', 'brainstorming', 'cooking', 'conjuring']; return WAITING_VERBS[Math.floor(Math.random() * WAITING_VERBS.length)];
return waitingVerbs[Math.floor(Math.random() * waitingVerbs.length)];
} }
/** /**
@ -49,8 +49,7 @@ function getVerb(text) {
* @returns {string} Formatted HTML text * @returns {string} Formatted HTML text
*/ */
function formatReply(text) { function formatReply(text) {
const verb = getVerb(text); return `<span class="hypebot_name">${settings.name} ${getVerb(text)}:</span>&nbsp;<span class="hypebot_text">${text}</span>`;
return DOMPurify.sanitize(`<span class="hypebot_name">${settings.name} ${verb}:</span>&nbsp;<span class="hypebot_text">${text}</span>`);
} }
let hypeBotBar; let hypeBotBar;
@ -58,13 +57,25 @@ let abortController;
const generateDebounced = debounce(() => generateHypeBot(), 500); const generateDebounced = debounce(() => generateHypeBot(), 500);
/**
* Sets the HypeBot text. Preserves scroll position of the chat.
* @param {string} text Text to set
*/
function setHypeBotText(text) {
const blockA = $('#chat');
var originalScrollBottom = blockA[0].scrollHeight - (blockA.scrollTop() + blockA.outerHeight());
hypeBotBar.html(DOMPurify.sanitize(text));
var newScrollTop = blockA[0].scrollHeight - (blockA.outerHeight() + originalScrollBottom);
blockA.scrollTop(newScrollTop);
}
/** /**
* Called when a chat event occurs to generate a HypeBot reply. * Called when a chat event occurs to generate a HypeBot reply.
* @param {boolean} clear Clear the hypebot bar. * @param {boolean} clear Clear the hypebot bar.
*/ */
function onChatEvent(clear) { function onChatEvent(clear) {
if (clear) { if (clear) {
hypeBotBar.text(''); setHypeBotText('');
} }
abortController?.abort(); abortController?.abort();
@ -80,12 +91,12 @@ async function generateHypeBot() {
} }
if (!secret_state[SECRET_KEYS.NOVEL]) { if (!secret_state[SECRET_KEYS.NOVEL]) {
hypeBotBar.html('<span class="hypebot_nokey">No API key found. Please enter your API key in the NovelAI API Settings</span>'); setHypeBotText('<span class="hypebot_nokey">No API key found. Please enter your API key in the NovelAI API Settings</span>');
return; return;
} }
console.debug('Generating HypeBot reply'); console.debug('Generating HypeBot reply');
hypeBotBar.html(DOMPurify.sanitize(`<span class="hypebot_name">${settings.name}</span> is ${getWaitingVerb()}...`)); setHypeBotText(`<span class="hypebot_name">${settings.name}</span> is ${getWaitingVerb()}...`);
const context = getContext(); const context = getContext();
const chat = context.chat.slice(); const chat = context.chat.slice();
@ -160,7 +171,7 @@ async function generateHypeBot() {
const ids = Array.from(new Uint16Array(Uint8Array.from(atob(data.output), c => c.charCodeAt(0)).buffer)); const ids = Array.from(new Uint16Array(Uint8Array.from(atob(data.output), c => c.charCodeAt(0)).buffer));
const output = decodeTextTokens(tokenizers.GPT2, ids).replace(/<2F>/g, '').trim(); const output = decodeTextTokens(tokenizers.GPT2, ids).replace(/<2F>/g, '').trim();
hypeBotBar.html(formatReply(output)); setHypeBotText(formatReply(output));
} }
} }