mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'staging' into macro-register
This commit is contained in:
@ -36,9 +36,6 @@ label[for="extensions_autoconnect"] {
|
|||||||
|
|
||||||
.extensions_info {
|
.extensions_info {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
max-height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding-right: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.extensions_info h3 {
|
.extensions_info h3 {
|
||||||
|
@ -115,12 +115,10 @@ dialog {
|
|||||||
background-color: var(--crimson-hover);
|
background-color: var(--crimson-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu_button.popup-button-custom {
|
|
||||||
/* Custom buttons should not scale to smallest size, otherwise they will always break to multiline */
|
|
||||||
width: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-controls .menu_button {
|
.popup-controls .menu_button {
|
||||||
|
/* Popup buttons should not scale to smallest size, otherwise they will always break to multiline if multiple words */
|
||||||
|
width: unset;
|
||||||
|
|
||||||
/* Fix weird animation issue with fonts on brightness filter */
|
/* Fix weird animation issue with fonts on brightness filter */
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
|
6
public/img/manual.svg
Normal file
6
public/img/manual.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M13.3252 3.05011L8.66765 20.4323L10.5995 20.9499L15.257 3.56775L13.3252 3.05011Z" />
|
||||||
|
<path d="M7.61222 18.3608L8.97161 16.9124L8.9711 16.8933L3.87681 12.1121L8.66724 7.00798L7.20892 5.63928L1.0498 12.2017L7.61222 18.3608Z" />
|
||||||
|
<path d="M16.3883 18.3608L15.0289 16.9124L15.0294 16.8933L20.1237 12.1121L15.3333 7.00798L16.7916 5.63928L22.9507 12.2017L16.3883 18.3608Z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 514 B |
@ -6400,9 +6400,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div id="rawPromptPopup" class="list-group">
|
|
||||||
<div id="rawPromptWrapper" class="tokenItemizingSubclass"></div>
|
|
||||||
</div>
|
|
||||||
<div id="user_avatar_template" class="template_element">
|
<div id="user_avatar_template" class="template_element">
|
||||||
<div class="avatar-container">
|
<div class="avatar-container">
|
||||||
<div imgfile="" class="avatar">
|
<div imgfile="" class="avatar">
|
||||||
|
127
public/script.js
127
public/script.js
@ -228,7 +228,7 @@ import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, de
|
|||||||
import { initPresetManager } from './scripts/preset-manager.js';
|
import { initPresetManager } from './scripts/preset-manager.js';
|
||||||
import { MacrosParser, evaluateMacros } from './scripts/macros.js';
|
import { MacrosParser, evaluateMacros } from './scripts/macros.js';
|
||||||
import { currentUser, setUserControls } from './scripts/user.js';
|
import { currentUser, setUserControls } from './scripts/user.js';
|
||||||
import { POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
|
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
|
||||||
import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
|
import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
|
||||||
import { ScraperManager } from './scripts/scrapers.js';
|
import { ScraperManager } from './scripts/scrapers.js';
|
||||||
import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
|
||||||
@ -513,9 +513,6 @@ let optionsPopper = Popper.createPopper(document.getElementById('options_button'
|
|||||||
let exportPopper = Popper.createPopper(document.getElementById('export_button'), document.getElementById('export_format_popup'), {
|
let exportPopper = Popper.createPopper(document.getElementById('export_button'), document.getElementById('export_format_popup'), {
|
||||||
placement: 'left',
|
placement: 'left',
|
||||||
});
|
});
|
||||||
let rawPromptPopper = Popper.createPopper(document.getElementById('dialogue_popup'), document.getElementById('rawPromptPopup'), {
|
|
||||||
placement: 'right',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Saved here for performance reasons
|
// Saved here for performance reasons
|
||||||
const messageTemplate = $('#message_template .mes');
|
const messageTemplate = $('#message_template .mes');
|
||||||
@ -4890,14 +4887,44 @@ async function promptItemize(itemizedPrompts, requestedMesId) {
|
|||||||
|
|
||||||
const params = await itemizedParams(itemizedPrompts, thisPromptSet);
|
const params = await itemizedParams(itemizedPrompts, thisPromptSet);
|
||||||
|
|
||||||
if (params.this_main_api == 'openai') {
|
const template = params.this_main_api == 'openai'
|
||||||
const template = await renderTemplateAsync('itemizationChat', params);
|
? await renderTemplateAsync('itemizationChat', params)
|
||||||
callPopup(template, 'text');
|
: await renderTemplateAsync('itemizationText', params);
|
||||||
|
|
||||||
} else {
|
const popup = new Popup(template, POPUP_TYPE.TEXT);
|
||||||
const template = await renderTemplateAsync('itemizationText', params);
|
|
||||||
callPopup(template, 'text');
|
popup.dlg.querySelector('#copyPromptToClipboard').addEventListener('click', function () {
|
||||||
}
|
let rawPrompt = itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt;
|
||||||
|
let rawPromptValues = rawPrompt;
|
||||||
|
|
||||||
|
if (Array.isArray(rawPrompt)) {
|
||||||
|
rawPromptValues = rawPrompt.map(x => x.content).join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.clipboard.writeText(rawPromptValues);
|
||||||
|
toastr.info('Copied!');
|
||||||
|
});
|
||||||
|
|
||||||
|
popup.dlg.querySelector('#showRawPrompt').addEventListener('click', function () {
|
||||||
|
//console.log(itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt);
|
||||||
|
console.log(PromptArrayItemForRawPromptDisplay);
|
||||||
|
console.log(itemizedPrompts);
|
||||||
|
console.log(itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt);
|
||||||
|
|
||||||
|
let rawPrompt = itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt;
|
||||||
|
let rawPromptValues = rawPrompt;
|
||||||
|
|
||||||
|
if (Array.isArray(rawPrompt)) {
|
||||||
|
rawPromptValues = rawPrompt.map(x => x.content).join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
//let DisplayStringifiedPrompt = JSON.stringify(itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt).replace(/\n+/g, '<br>');
|
||||||
|
const rawPromptWrapper = document.getElementById('rawPromptWrapper');
|
||||||
|
rawPromptWrapper.innerText = rawPromptValues;
|
||||||
|
$('#rawPromptPopup').slideToggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
await popup.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setInContextMessages(lastmsg, type) {
|
function setInContextMessages(lastmsg, type) {
|
||||||
@ -9184,13 +9211,6 @@ jQuery(async function () {
|
|||||||
if (popup_type == 'alternate_greeting' && menu_type !== 'create') {
|
if (popup_type == 'alternate_greeting' && menu_type !== 'create') {
|
||||||
createOrEditCharacter();
|
createOrEditCharacter();
|
||||||
}
|
}
|
||||||
if (popup_type === 'del_group') {
|
|
||||||
const groupId = $('#dialogue_popup').data('group_id');
|
|
||||||
|
|
||||||
if (groupId) {
|
|
||||||
deleteGroup(groupId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Make a new chat for selected character
|
//Make a new chat for selected character
|
||||||
if (
|
if (
|
||||||
popup_type == 'new_chat' &&
|
popup_type == 'new_chat' &&
|
||||||
@ -9224,9 +9244,6 @@ jQuery(async function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rawPromptPopper.update();
|
|
||||||
$('#rawPromptPopup').hide();
|
|
||||||
|
|
||||||
if (dialogueResolve) {
|
if (dialogueResolve) {
|
||||||
if (popup_type == 'input') {
|
if (popup_type == 'input') {
|
||||||
dialogueResolve($('#dialogue_popup_input').val());
|
dialogueResolve($('#dialogue_popup_input').val());
|
||||||
@ -9817,45 +9834,14 @@ jQuery(async function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).on('pointerup', '.mes_prompt', function () {
|
$(document).on('pointerup', '.mes_prompt', async function () {
|
||||||
let mesIdForItemization = $(this).closest('.mes').attr('mesId');
|
let mesIdForItemization = $(this).closest('.mes').attr('mesId');
|
||||||
console.log(`looking for mesID: ${mesIdForItemization}`);
|
console.log(`looking for mesID: ${mesIdForItemization}`);
|
||||||
if (itemizedPrompts.length !== undefined && itemizedPrompts.length !== 0) {
|
if (itemizedPrompts.length !== undefined && itemizedPrompts.length !== 0) {
|
||||||
promptItemize(itemizedPrompts, mesIdForItemization);
|
await promptItemize(itemizedPrompts, mesIdForItemization);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('pointerup', '#copyPromptToClipboard', function () {
|
|
||||||
let rawPrompt = itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt;
|
|
||||||
let rawPromptValues = rawPrompt;
|
|
||||||
|
|
||||||
if (Array.isArray(rawPrompt)) {
|
|
||||||
rawPromptValues = rawPrompt.map(x => x.content).join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
navigator.clipboard.writeText(rawPromptValues);
|
|
||||||
toastr.info('Copied!', '', { timeOut: 2000 });
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('pointerup', '#showRawPrompt', function () {
|
|
||||||
//console.log(itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt);
|
|
||||||
console.log(PromptArrayItemForRawPromptDisplay);
|
|
||||||
console.log(itemizedPrompts);
|
|
||||||
console.log(itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt);
|
|
||||||
|
|
||||||
let rawPrompt = itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt;
|
|
||||||
let rawPromptValues = rawPrompt;
|
|
||||||
|
|
||||||
if (Array.isArray(rawPrompt)) {
|
|
||||||
rawPromptValues = rawPrompt.map(x => x.content).join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
//let DisplayStringifiedPrompt = JSON.stringify(itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt).replace(/\n+/g, '<br>');
|
|
||||||
$('#rawPromptWrapper').text(rawPromptValues);
|
|
||||||
rawPromptPopper.update();
|
|
||||||
$('#rawPromptPopup').toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
//********************
|
//********************
|
||||||
//***Message Editor***
|
//***Message Editor***
|
||||||
$(document).on('click', '.mes_edit', async function () {
|
$(document).on('click', '.mes_edit', async function () {
|
||||||
@ -10060,7 +10046,7 @@ jQuery(async function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('click', '.mes_edit_copy', async function () {
|
$(document).on('click', '.mes_edit_copy', async function () {
|
||||||
const confirmation = await callPopup('Create a copy of this message?', 'confirm');
|
const confirmation = await callGenericPopup('Create a copy of this message?', POPUP_TYPE.CONFIRM);
|
||||||
if (!confirmation) {
|
if (!confirmation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -10086,24 +10072,33 @@ jQuery(async function () {
|
|||||||
|
|
||||||
$(document).on('click', '.mes_edit_delete', async function (event, customData) {
|
$(document).on('click', '.mes_edit_delete', async function (event, customData) {
|
||||||
const fromSlashCommand = customData?.fromSlashCommand || false;
|
const fromSlashCommand = customData?.fromSlashCommand || false;
|
||||||
const swipeExists = (!Array.isArray(chat[this_edit_mes_id].swipes) || chat[this_edit_mes_id].swipes.length <= 1 || chat[this_edit_mes_id].is_user || parseInt(this_edit_mes_id) !== chat.length - 1);
|
const canDeleteSwipe = (Array.isArray(chat[this_edit_mes_id].swipes) && chat[this_edit_mes_id].swipes.length > 1 && !chat[this_edit_mes_id].is_user && parseInt(this_edit_mes_id) === chat.length - 1);
|
||||||
|
|
||||||
|
let deleteOnlySwipe = false;
|
||||||
if (power_user.confirm_message_delete && fromSlashCommand !== true) {
|
if (power_user.confirm_message_delete && fromSlashCommand !== true) {
|
||||||
const confirmation = swipeExists ? await callPopup('Are you sure you want to delete this message?', 'confirm')
|
const result = await callGenericPopup('Are you sure you want to delete this message?', POPUP_TYPE.CONFIRM, null, {
|
||||||
: await callPopup('<h3>Delete this...</h3> <select id=\'del_type\'><option value=\'swipe\'>Swipe</option><option value=\'message\'>Message</option></select>', 'confirm');
|
okButton: canDeleteSwipe ? 'Delete Swipe' : 'Delete Message',
|
||||||
if (!confirmation) {
|
cancelButton: 'Cancel',
|
||||||
|
customButtons: canDeleteSwipe ? ['Delete Message'] : null,
|
||||||
|
});
|
||||||
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
deleteOnlySwipe = canDeleteSwipe && result === 1; // Default button, not the custom one
|
||||||
}
|
}
|
||||||
|
|
||||||
const mes = $(this).closest('.mes');
|
const messageElement = $(this).closest('.mes');
|
||||||
|
if (!messageElement) {
|
||||||
if (!mes) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('#del_type').val() === 'swipe') {
|
if (deleteOnlySwipe) {
|
||||||
const swipe_id = chat[this_edit_mes_id]['swipe_id'];
|
const message = chat[this_edit_mes_id];
|
||||||
chat[this_edit_mes_id]['swipes'].splice(swipe_id, 1);
|
const swipe_id = message.swipe_id;
|
||||||
|
message.swipes.splice(swipe_id, 1);
|
||||||
|
if (Array.isArray(message.swipe_info) && message.swipe_info.length) {
|
||||||
|
message.swipe_info.splice(swipe_id, 1);
|
||||||
|
}
|
||||||
if (swipe_id > 0) {
|
if (swipe_id > 0) {
|
||||||
$('.swipe_left:last').click();
|
$('.swipe_left:last').click();
|
||||||
} else {
|
} else {
|
||||||
@ -10111,7 +10106,7 @@ jQuery(async function () {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chat.splice(this_edit_mes_id, 1);
|
chat.splice(this_edit_mes_id, 1);
|
||||||
mes.remove();
|
messageElement.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
let startFromZero = Number(this_edit_mes_id) === 0;
|
let startFromZero = Number(this_edit_mes_id) === 0;
|
||||||
|
@ -16,7 +16,6 @@ import {
|
|||||||
eventSource,
|
eventSource,
|
||||||
menu_type,
|
menu_type,
|
||||||
substituteParams,
|
substituteParams,
|
||||||
callPopup,
|
|
||||||
sendTextareaMessage,
|
sendTextareaMessage,
|
||||||
} from '../script.js';
|
} from '../script.js';
|
||||||
|
|
||||||
@ -1004,20 +1003,21 @@ export function initRossMods() {
|
|||||||
if (skipConfirm) {
|
if (skipConfirm) {
|
||||||
doRegenerate();
|
doRegenerate();
|
||||||
} else {
|
} else {
|
||||||
const popupText = `
|
Popup.show.confirm('Regenerate Message', `
|
||||||
<div class="marginBot10">Are you sure you want to regenerate the latest message?</div>
|
<span>Are you sure you want to regenerate the latest message?</span>
|
||||||
<label class="checkbox_label justifyCenter" for="regenerateWithCtrlEnter">
|
<label class="checkbox_label justifyCenter marginTop10" for="regenerateWithCtrlEnter">
|
||||||
<input type="checkbox" id="regenerateWithCtrlEnter">
|
<input type="checkbox" id="regenerateWithCtrlEnter">
|
||||||
Don't ask again
|
Don't ask again
|
||||||
</label>`;
|
</label>`, {
|
||||||
callPopup(popupText, 'confirm').then(result => {
|
onClose: (popup) => {
|
||||||
if (!result) {
|
if (!popup.result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const regenerateWithCtrlEnter = $('#regenerateWithCtrlEnter').prop('checked');
|
const regenerateWithCtrlEnter = $('#regenerateWithCtrlEnter').prop('checked');
|
||||||
SaveLocal(skipConfirmKey, regenerateWithCtrlEnter);
|
SaveLocal(skipConfirmKey, regenerateWithCtrlEnter);
|
||||||
doRegenerate();
|
doRegenerate();
|
||||||
});
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -504,7 +504,7 @@ function addExtensionScript(name, manifest) {
|
|||||||
* @param {boolean} isDisabled - Whether the extension is disabled or not.
|
* @param {boolean} isDisabled - Whether the extension is disabled or not.
|
||||||
* @param {boolean} isExternal - Whether the extension is external or not.
|
* @param {boolean} isExternal - Whether the extension is external or not.
|
||||||
* @param {string} checkboxClass - The class for the checkbox HTML element.
|
* @param {string} checkboxClass - The class for the checkbox HTML element.
|
||||||
* @return {string} - The HTML string that represents the extension.
|
* @return {Promise<string>} - The HTML string that represents the extension.
|
||||||
*/
|
*/
|
||||||
async function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal, checkboxClass) {
|
async function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal, checkboxClass) {
|
||||||
const displayName = manifest.display_name;
|
const displayName = manifest.display_name;
|
||||||
@ -556,8 +556,10 @@ async function generateExtensionHtml(name, manifest, isActive, isDisabled, isExt
|
|||||||
} else if (!isDisabled) { // Neither active nor disabled
|
} else if (!isDisabled) { // Neither active nor disabled
|
||||||
const requirements = new Set(manifest.requires);
|
const requirements = new Set(manifest.requires);
|
||||||
modules.forEach(x => requirements.delete(x));
|
modules.forEach(x => requirements.delete(x));
|
||||||
const requirementsString = DOMPurify.sanitize([...requirements].join(', '));
|
if (requirements.size > 0) {
|
||||||
extensionHtml += `<p>Missing modules: <span class="failure">${requirementsString}</span></p>`;
|
const requirementsString = DOMPurify.sanitize([...requirements].join(', '));
|
||||||
|
extensionHtml += `<p>Missing modules: <span class="failure">${requirementsString}</span></p>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return extensionHtml;
|
return extensionHtml;
|
||||||
@ -642,7 +644,7 @@ async function showExtensionsDetails() {
|
|||||||
popup.complete(POPUP_RESULT.AFFIRMATIVE);
|
popup.complete(POPUP_RESULT.AFFIRMATIVE);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const popup = new Popup(`<div class="extensions_info">${html}</div>`, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: true, large: true, customButtons: [updateAllButton] });
|
const popup = new Popup(`<div class="extensions_info">${html}</div>`, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: true, large: true, customButtons: [updateAllButton], allowVerticalScrolling: true });
|
||||||
popupPromise = popup.show();
|
popupPromise = popup.show();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toastr.error('Error loading extensions. See browser console for details.');
|
toastr.error('Error loading extensions. See browser console for details.');
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { callPopup, main_api } from '../../../script.js';
|
import { main_api } from '../../../script.js';
|
||||||
import { getContext } from '../../extensions.js';
|
import { getContext } from '../../extensions.js';
|
||||||
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
||||||
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
|
||||||
import { getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, tokenizers } from '../../tokenizers.js';
|
import { getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, tokenizers } from '../../tokenizers.js';
|
||||||
import { resetScrollHeight, debounce } from '../../utils.js';
|
import { resetScrollHeight, debounce } from '../../utils.js';
|
||||||
import { debounce_timeout } from '../../constants.js';
|
import { debounce_timeout } from '../../constants.js';
|
||||||
|
import { POPUP_TYPE, callGenericPopup } from '../../popup.js';
|
||||||
|
|
||||||
function rgb2hex(rgb) {
|
function rgb2hex(rgb) {
|
||||||
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
|
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
|
||||||
@ -63,8 +64,7 @@ async function doTokenCounter() {
|
|||||||
}, debounce_timeout.relaxed);
|
}, debounce_timeout.relaxed);
|
||||||
dialog.find('#token_counter_textarea').on('input', () => countDebounced());
|
dialog.find('#token_counter_textarea').on('input', () => countDebounced());
|
||||||
|
|
||||||
$('#dialogue_popup').addClass('wide_dialogue_popup');
|
callGenericPopup(dialog, POPUP_TYPE.TEXT, '', { wide: true, large: true, allowVerticalScrolling: true });
|
||||||
callPopup(dialog, 'text', '', { wide: true, large: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
export { translate };
|
export { translate };
|
||||||
|
|
||||||
import {
|
import {
|
||||||
callPopup,
|
|
||||||
eventSource,
|
eventSource,
|
||||||
event_types,
|
event_types,
|
||||||
getRequestHeaders,
|
getRequestHeaders,
|
||||||
@ -11,6 +10,7 @@ import {
|
|||||||
updateMessageBlock,
|
updateMessageBlock,
|
||||||
} from '../../../script.js';
|
} from '../../../script.js';
|
||||||
import { extension_settings, getContext, renderExtensionTemplateAsync } from '../../extensions.js';
|
import { extension_settings, getContext, renderExtensionTemplateAsync } from '../../extensions.js';
|
||||||
|
import { POPUP_TYPE, callGenericPopup } from '../../popup.js';
|
||||||
import { findSecret, secret_state, writeSecret } from '../../secrets.js';
|
import { findSecret, secret_state, writeSecret } from '../../secrets.js';
|
||||||
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
||||||
@ -510,7 +510,7 @@ async function onTranslateChatClick() {
|
|||||||
|
|
||||||
async function onTranslationsClearClick() {
|
async function onTranslationsClearClick() {
|
||||||
const popupHtml = await renderExtensionTemplateAsync('translate', 'deleteConfirmation');
|
const popupHtml = await renderExtensionTemplateAsync('translate', 'deleteConfirmation');
|
||||||
const confirm = await callPopup(popupHtml, 'confirm');
|
const confirm = await callGenericPopup(popupHtml, POPUP_TYPE.CONFIRM);
|
||||||
|
|
||||||
if (!confirm) {
|
if (!confirm) {
|
||||||
return;
|
return;
|
||||||
@ -598,7 +598,7 @@ jQuery(async () => {
|
|||||||
$(document).on('click', '.mes_translate', onMessageTranslateClick);
|
$(document).on('click', '.mes_translate', onMessageTranslateClick);
|
||||||
$('#translate_key_button').on('click', async () => {
|
$('#translate_key_button').on('click', async () => {
|
||||||
const optionText = $('#translation_provider option:selected').text();
|
const optionText = $('#translation_provider option:selected').text();
|
||||||
const key = await callPopup(`<h3>${optionText} API Key</h3>`, 'input');
|
const key = await callGenericPopup(`<h3>${optionText} API Key</h3>`, POPUP_TYPE.INPUT);
|
||||||
|
|
||||||
if (key == false) {
|
if (key == false) {
|
||||||
return;
|
return;
|
||||||
@ -621,7 +621,7 @@ jQuery(async () => {
|
|||||||
const secretKey = extension_settings.translate.provider + '_url';
|
const secretKey = extension_settings.translate.provider + '_url';
|
||||||
const savedUrl = secret_state[secretKey] ? await findSecret(secretKey) : '';
|
const savedUrl = secret_state[secretKey] ? await findSecret(secretKey) : '';
|
||||||
|
|
||||||
const url = await callPopup(popupText, 'input', savedUrl);
|
const url = await callGenericPopup(popupText, POPUP_TYPE.INPUT, savedUrl);
|
||||||
|
|
||||||
if (url == false || url == '') {
|
if (url == false || url == '') {
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { callPopup, cancelTtsPlay, eventSource, event_types, isStreamingEnabled, name2, saveSettingsDebounced, substituteParams } from '../../../script.js';
|
import { cancelTtsPlay, eventSource, event_types, isStreamingEnabled, name2, saveSettingsDebounced, substituteParams } from '../../../script.js';
|
||||||
import { ModuleWorkerWrapper, doExtrasFetch, extension_settings, getApiUrl, getContext, modules, renderExtensionTemplateAsync } from '../../extensions.js';
|
import { ModuleWorkerWrapper, doExtrasFetch, extension_settings, getApiUrl, getContext, modules, renderExtensionTemplateAsync } from '../../extensions.js';
|
||||||
import { delay, escapeRegex, getBase64Async, getStringHash, onlyUnique } from '../../utils.js';
|
import { delay, escapeRegex, getBase64Async, getStringHash, onlyUnique } from '../../utils.js';
|
||||||
import { EdgeTtsProvider } from './edge.js';
|
import { EdgeTtsProvider } from './edge.js';
|
||||||
@ -21,6 +21,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '
|
|||||||
import { debounce_timeout } from '../../constants.js';
|
import { debounce_timeout } from '../../constants.js';
|
||||||
import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
|
||||||
import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
import { POPUP_TYPE, callGenericPopup } from '../../popup.js';
|
||||||
export { talkingAnimation };
|
export { talkingAnimation };
|
||||||
|
|
||||||
const UPDATE_INTERVAL = 1000;
|
const UPDATE_INTERVAL = 1000;
|
||||||
@ -310,7 +311,7 @@ async function onTtsVoicesClick() {
|
|||||||
popupText = 'Could not load voices list. Check your API key.';
|
popupText = 'Could not load voices list. Check your API key.';
|
||||||
}
|
}
|
||||||
|
|
||||||
callPopup(popupText, 'text');
|
callGenericPopup(popupText, POPUP_TYPE.TEXT, '', { allowVerticalScrolling: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUiAudioPlayState() {
|
function updateUiAudioPlayState() {
|
||||||
|
@ -24,7 +24,6 @@ import {
|
|||||||
characters,
|
characters,
|
||||||
default_avatar,
|
default_avatar,
|
||||||
addOneMessage,
|
addOneMessage,
|
||||||
callPopup,
|
|
||||||
clearChat,
|
clearChat,
|
||||||
Generate,
|
Generate,
|
||||||
select_rm_info,
|
select_rm_info,
|
||||||
@ -75,7 +74,7 @@ import {
|
|||||||
import { printTagList, createTagMapFromList, applyTagsOnCharacterSelect, tag_map, applyTagsOnGroupSelect } from './tags.js';
|
import { printTagList, createTagMapFromList, applyTagsOnCharacterSelect, tag_map, applyTagsOnGroupSelect } from './tags.js';
|
||||||
import { FILTER_TYPES, FilterHelper } from './filters.js';
|
import { FILTER_TYPES, FilterHelper } from './filters.js';
|
||||||
import { isExternalMediaAllowed } from './chats.js';
|
import { isExternalMediaAllowed } from './chats.js';
|
||||||
import { POPUP_TYPE, callGenericPopup } from './popup.js';
|
import { POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
selected_group,
|
selected_group,
|
||||||
@ -1300,14 +1299,20 @@ function isGroupMemberDisabled(avatarId) {
|
|||||||
return Boolean(thisGroup && thisGroup.disabled_members.includes(avatarId));
|
return Boolean(thisGroup && thisGroup.disabled_members.includes(avatarId));
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDeleteGroupClick() {
|
async function onDeleteGroupClick() {
|
||||||
|
if (!openGroupId) {
|
||||||
|
toastr.warning('Currently no group selected.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (is_group_generating) {
|
if (is_group_generating) {
|
||||||
toastr.warning('Not so fast! Wait for the characters to stop typing before deleting the group.');
|
toastr.warning('Not so fast! Wait for the characters to stop typing before deleting the group.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#dialogue_popup').data('group_id', openGroupId);
|
const confirm = await Popup.show.confirm('Delete the group?', '<p>This will also delete all your chats with that group. If you want to delete a single conversation, select a "View past chats" option in the lower left menu.</p>');
|
||||||
callPopup('<h3>Delete the group?</h3><p>This will also delete all your chats with that group. If you want to delete a single conversation, select a "View past chats" option in the lower left menu.</p>', 'del_group');
|
if (confirm) {
|
||||||
|
deleteGroup(openGroupId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onFavoriteGroupClick() {
|
async function onFavoriteGroupClick() {
|
||||||
@ -1476,8 +1481,7 @@ async function uploadGroupAvatar(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function restoreGroupAvatar() {
|
async function restoreGroupAvatar() {
|
||||||
const confirm = await callPopup('<h3>Are you sure you want to restore the group avatar?</h3> Your custom image will be deleted, and a collage will be used instead.', 'confirm');
|
const confirm = await Popup.show.confirm('Are you sure you want to restore the group avatar?', 'Your custom image will be deleted, and a collage will be used instead.');
|
||||||
|
|
||||||
if (!confirm) {
|
if (!confirm) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -590,7 +590,37 @@ function selectCurrentPersona() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function lockUserNameToChat() {
|
/**
|
||||||
|
* Checks if the persona is locked for the current chat.
|
||||||
|
* @returns {boolean} Whether the persona is locked
|
||||||
|
*/
|
||||||
|
function isPersonaLocked() {
|
||||||
|
return !!chat_metadata['persona'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks or unlocks the persona for the current chat.
|
||||||
|
* @param {boolean} state Desired lock state
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export async function setPersonaLockState(state) {
|
||||||
|
return state ? await lockPersona() : await unlockPersona();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle the persona lock state for the current chat.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export async function togglePersonaLock() {
|
||||||
|
return isPersonaLocked()
|
||||||
|
? await unlockPersona()
|
||||||
|
: await lockPersona();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock the persona for the current chat.
|
||||||
|
*/
|
||||||
|
async function unlockPersona() {
|
||||||
if (chat_metadata['persona']) {
|
if (chat_metadata['persona']) {
|
||||||
console.log(`Unlocking persona for this chat ${chat_metadata['persona']}`);
|
console.log(`Unlocking persona for this chat ${chat_metadata['persona']}`);
|
||||||
delete chat_metadata['persona'];
|
delete chat_metadata['persona'];
|
||||||
@ -599,9 +629,13 @@ async function lockUserNameToChat() {
|
|||||||
toastr.info('User persona is now unlocked for this chat. Click the "Lock" again to revert.', 'Persona unlocked');
|
toastr.info('User persona is now unlocked for this chat. Click the "Lock" again to revert.', 'Persona unlocked');
|
||||||
}
|
}
|
||||||
updateUserLockIcon();
|
updateUserLockIcon();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock the persona for the current chat.
|
||||||
|
*/
|
||||||
|
async function lockPersona() {
|
||||||
if (!(user_avatar in power_user.personas)) {
|
if (!(user_avatar in power_user.personas)) {
|
||||||
console.log(`Creating a new persona ${user_avatar}`);
|
console.log(`Creating a new persona ${user_avatar}`);
|
||||||
if (power_user.persona_show_notifications) {
|
if (power_user.persona_show_notifications) {
|
||||||
@ -625,6 +659,7 @@ async function lockUserNameToChat() {
|
|||||||
updateUserLockIcon();
|
updateUserLockIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function deleteUserAvatar(e) {
|
async function deleteUserAvatar(e) {
|
||||||
e?.stopPropagation();
|
e?.stopPropagation();
|
||||||
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
||||||
@ -973,7 +1008,7 @@ export function initPersonas() {
|
|||||||
$(document).on('click', '.bind_user_name', bindUserNameToPersona);
|
$(document).on('click', '.bind_user_name', bindUserNameToPersona);
|
||||||
$(document).on('click', '.set_default_persona', setDefaultPersona);
|
$(document).on('click', '.set_default_persona', setDefaultPersona);
|
||||||
$(document).on('click', '.delete_avatar', deleteUserAvatar);
|
$(document).on('click', '.delete_avatar', deleteUserAvatar);
|
||||||
$('#lock_user_name').on('click', lockUserNameToChat);
|
$('#lock_user_name').on('click', togglePersonaLock);
|
||||||
$('#create_dummy_persona').on('click', createDummyPersona);
|
$('#create_dummy_persona').on('click', createDummyPersona);
|
||||||
$('#persona_description').on('input', onPersonaDescriptionInput);
|
$('#persona_description').on('input', onPersonaDescriptionInput);
|
||||||
$('#persona_description_position').on('input', onPersonaDescriptionPositionInput);
|
$('#persona_description_position').on('input', onPersonaDescriptionPositionInput);
|
||||||
|
@ -74,6 +74,22 @@ const showPopupHelper = {
|
|||||||
const value = await popup.show();
|
const value = await popup.show();
|
||||||
return value ? String(value) : null;
|
return value ? String(value) : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously displays a confirmation popup with the given header and text, returning the clicked result button value.
|
||||||
|
*
|
||||||
|
* @param {string} header - The header text for the popup.
|
||||||
|
* @param {string} text - The main text for the popup.
|
||||||
|
* @param {PopupOptions} [popupOptions={}] - Options for the popup.
|
||||||
|
* @return {Promise<POPUP_RESULT>} A Promise that resolves with the result of the user's interaction.
|
||||||
|
*/
|
||||||
|
confirm: async (header, text, popupOptions = {}) => {
|
||||||
|
const content = PopupUtils.BuildTextWithHeader(header, text);
|
||||||
|
const popup = new Popup(content, POPUP_TYPE.CONFIRM, null, popupOptions);
|
||||||
|
const result = await popup.show();
|
||||||
|
if (typeof result === 'string' || typeof result === 'boolean') throw new Error(`Invalid popup result. CONFIRM popups only support numbers, or null. Result: ${result}`);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Popup {
|
export class Popup {
|
||||||
|
@ -2,7 +2,6 @@ import {
|
|||||||
saveSettingsDebounced,
|
saveSettingsDebounced,
|
||||||
scrollChatToBottom,
|
scrollChatToBottom,
|
||||||
characters,
|
characters,
|
||||||
callPopup,
|
|
||||||
reloadMarkdownProcessor,
|
reloadMarkdownProcessor,
|
||||||
reloadCurrentChat,
|
reloadCurrentChat,
|
||||||
getRequestHeaders,
|
getRequestHeaders,
|
||||||
@ -48,6 +47,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashComma
|
|||||||
import { AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js';
|
import { AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js';
|
||||||
import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
import { POPUP_TYPE, callGenericPopup } from './popup.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
loadPowerUserSettings,
|
loadPowerUserSettings,
|
||||||
@ -1432,7 +1432,7 @@ export function registerDebugFunction(functionId, name, description, func) {
|
|||||||
|
|
||||||
async function showDebugMenu() {
|
async function showDebugMenu() {
|
||||||
const template = await renderTemplateAsync('debug', { functions: debug_functions });
|
const template = await renderTemplateAsync('debug', { functions: debug_functions });
|
||||||
callPopup(template, 'text', '', { wide: true, large: true });
|
callGenericPopup(template, POPUP_TYPE.TEXT, '', { wide: true, large: true, allowVerticalScrolling: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
switchUiMode();
|
switchUiMode();
|
||||||
@ -2207,7 +2207,8 @@ async function deleteTheme() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirm = await callPopup(`Are you sure you want to delete the theme "${themeName}"?`, 'confirm', '', { okButton: 'Yes' });
|
const template = $(await renderTemplateAsync('themeDelete', { themeName }));
|
||||||
|
const confirm = await callGenericPopup(template, POPUP_TYPE.CONFIRM);
|
||||||
|
|
||||||
if (!confirm) {
|
if (!confirm) {
|
||||||
return;
|
return;
|
||||||
@ -2269,7 +2270,8 @@ async function importTheme(file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof parsed.custom_css === 'string' && parsed.custom_css.includes('@import')) {
|
if (typeof parsed.custom_css === 'string' && parsed.custom_css.includes('@import')) {
|
||||||
const confirm = await callPopup('This theme contains @import lines in the Custom CSS. Press "Yes" to proceed.', 'confirm', '', { okButton: 'Yes' });
|
const template = $(await renderTemplateAsync('themeImportWarning'));
|
||||||
|
const confirm = await callGenericPopup(template, POPUP_TYPE.CONFIRM);
|
||||||
if (!confirm) {
|
if (!confirm) {
|
||||||
throw new Error('Theme contains @import lines');
|
throw new Error('Theme contains @import lines');
|
||||||
}
|
}
|
||||||
@ -2294,11 +2296,13 @@ async function importTheme(file) {
|
|||||||
*/
|
*/
|
||||||
async function saveTheme(name = undefined, theme = undefined) {
|
async function saveTheme(name = undefined, theme = undefined) {
|
||||||
if (typeof name !== 'string') {
|
if (typeof name !== 'string') {
|
||||||
name = await callPopup('Enter a theme preset name:', 'input', power_user.theme);
|
const newName = await callGenericPopup('Enter a theme preset name:', POPUP_TYPE.INPUT, power_user.theme);
|
||||||
|
|
||||||
if (!name) {
|
if (!newName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = String(newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof theme !== 'object') {
|
if (typeof theme !== 'object') {
|
||||||
@ -2396,7 +2400,7 @@ function getNewTheme(parsed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function saveMovingUI() {
|
async function saveMovingUI() {
|
||||||
const name = await callPopup('Enter a name for the MovingUI Preset:', 'input');
|
const name = await callGenericPopup('Enter a name for the MovingUI Preset:', POPUP_TYPE.INPUT);
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return;
|
return;
|
||||||
|
@ -46,7 +46,7 @@ import { extension_settings, getContext, saveMetadataDebounced } from './extensi
|
|||||||
import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
|
import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
|
||||||
import { findGroupMemberId, getGroupMembers, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';
|
import { findGroupMemberId, getGroupMembers, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';
|
||||||
import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js';
|
import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js';
|
||||||
import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, user_avatar } from './personas.js';
|
import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js';
|
||||||
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
|
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
|
||||||
import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
|
import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
|
||||||
import { decodeTextTokens, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync } from './tokenizers.js';
|
import { decodeTextTokens, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync } from './tokenizers.js';
|
||||||
@ -118,9 +118,18 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
}));
|
}));
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'lock',
|
name: 'lock',
|
||||||
callback: bindCallback,
|
callback: lockPersonaCallback,
|
||||||
aliases: ['bind'],
|
aliases: ['bind'],
|
||||||
helpString: 'Locks/unlocks a persona (name and avatar) to the current chat',
|
helpString: 'Locks/unlocks a persona (name and avatar) to the current chat',
|
||||||
|
unnamedArgumentList: [
|
||||||
|
SlashCommandArgument.fromProps({
|
||||||
|
description: 'state',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
defaultValue: 'toggle',
|
||||||
|
enumProvider: commonEnumProviders.boolean('onOffToggle'),
|
||||||
|
}),
|
||||||
|
],
|
||||||
}));
|
}));
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'bg',
|
name: 'bg',
|
||||||
@ -1998,6 +2007,9 @@ async function addSwipeCallback(_, arg) {
|
|||||||
lastMessage.swipe_info = [{}];
|
lastMessage.swipe_info = [{}];
|
||||||
lastMessage.swipe_id = 0;
|
lastMessage.swipe_id = 0;
|
||||||
}
|
}
|
||||||
|
if (!Array.isArray(lastMessage.swipe_info)) {
|
||||||
|
lastMessage.swipe_info = lastMessage.swipes.map(() => ({}));
|
||||||
|
}
|
||||||
|
|
||||||
lastMessage.swipes.push(arg);
|
lastMessage.swipes.push(arg);
|
||||||
lastMessage.swipe_info.push({
|
lastMessage.swipe_info.push({
|
||||||
@ -2573,8 +2585,23 @@ function syncCallback() {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindCallback() {
|
async function lockPersonaCallback(_args, value) {
|
||||||
$('#lock_user_name').trigger('click');
|
if (['toggle', 't', ''].includes(value.trim().toLowerCase())) {
|
||||||
|
await togglePersonaLock();
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTrueBoolean(value)) {
|
||||||
|
await setPersonaLockState(true);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFalseBoolean(value)) {
|
||||||
|
await setPersonaLockState(false);
|
||||||
|
return '';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2700,9 +2727,26 @@ export async function sendMessageAs(args, text) {
|
|||||||
bias: bias.trim().length ? bias : null,
|
bias: bias.trim().length ? bias : null,
|
||||||
gen_id: Date.now(),
|
gen_id: Date.now(),
|
||||||
isSmallSys: compact,
|
isSmallSys: compact,
|
||||||
|
api: 'manual',
|
||||||
|
model: 'slash command',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
message.swipe_id = 0;
|
||||||
|
message.swipes = [message.mes];
|
||||||
|
message.swipes_info = [{
|
||||||
|
send_date: message.send_date,
|
||||||
|
gen_started: null,
|
||||||
|
gen_finished: null,
|
||||||
|
extra: {
|
||||||
|
bias: message.extra.bias,
|
||||||
|
gen_id: message.extra.gen_id,
|
||||||
|
isSmallSys: compact,
|
||||||
|
api: 'manual',
|
||||||
|
model: 'slash command',
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
|
||||||
const insertAt = Number(resolveVariable(args.at));
|
const insertAt = Number(resolveVariable(args.at));
|
||||||
|
|
||||||
if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) {
|
if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) {
|
||||||
@ -2745,6 +2789,8 @@ export async function sendNarratorMessage(args, text) {
|
|||||||
bias: bias.trim().length ? bias : null,
|
bias: bias.trim().length ? bias : null,
|
||||||
gen_id: Date.now(),
|
gen_id: Date.now(),
|
||||||
isSmallSys: compact,
|
isSmallSys: compact,
|
||||||
|
api: 'manual',
|
||||||
|
model: 'slash command',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2795,6 +2841,8 @@ export async function promptQuietForLoudResponse(who, text) {
|
|||||||
extra: {
|
extra: {
|
||||||
type: system_message_types.COMMENT,
|
type: system_message_types.COMMENT,
|
||||||
gen_id: Date.now(),
|
gen_id: Date.now(),
|
||||||
|
api: 'manual',
|
||||||
|
model: 'slash command',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2823,6 +2871,8 @@ async function sendCommentMessage(args, text) {
|
|||||||
type: system_message_types.COMMENT,
|
type: system_message_types.COMMENT,
|
||||||
gen_id: Date.now(),
|
gen_id: Date.now(),
|
||||||
isSmallSys: compact,
|
isSmallSys: compact,
|
||||||
|
api: 'manual',
|
||||||
|
model: 'slash command',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,25 +1,27 @@
|
|||||||
<h3 data-i18n="Debug Menu">Debug Menu</h3>
|
<div>
|
||||||
<div data-i18n="Debug Warning">
|
<h3 data-i18n="Debug Menu">Debug Menu</h3>
|
||||||
Functions in this category are for advanced users only. Don't click anything if you're not sure about the consequences.
|
<div data-i18n="Debug Warning">
|
||||||
</div>
|
Functions in this category are for advanced users only. Don't click anything if you're not sure about the consequences.
|
||||||
<table id="debug_table" class="responsiveTable">
|
</div>
|
||||||
{{#each functions}}
|
<table id="debug_table" class="responsiveTable">
|
||||||
{{#with this}}
|
{{#each functions}}
|
||||||
<tr>
|
{{#with this}}
|
||||||
<td>
|
<tr>
|
||||||
<div class="justifyLeft">
|
<td>
|
||||||
<b>{{this.name}}</b>
|
<div class="justifyLeft">
|
||||||
</div>
|
<b>{{this.name}}</b>
|
||||||
<div class="justifyLeft">
|
|
||||||
{{this.description}}
|
|
||||||
</div>
|
|
||||||
<div class="flex-container justifyCenter">
|
|
||||||
<div class="menu_button menu_button_icon" data-debug-function="{{this.functionId}}" data-i18n="Execute">
|
|
||||||
Execute
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="justifyLeft">
|
||||||
</td>
|
{{this.description}}
|
||||||
</tr>
|
</div>
|
||||||
{{/with}}
|
<div class="flex-container justifyCenter">
|
||||||
{{/each}}
|
<div class="menu_button menu_button_icon" data-debug-function="{{this.functionId}}" data-i18n="Execute">
|
||||||
</table>
|
Execute
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/with}}
|
||||||
|
{{/each}}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
@ -127,3 +127,6 @@ API Used: {{this_main_api}}<br>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
<div id="rawPromptPopup" class="list-group">
|
||||||
|
<div id="rawPromptWrapper" class="tokenItemizingSubclass"></div>
|
||||||
|
</div>
|
||||||
|
@ -107,3 +107,6 @@ API Used: {{this_main_api}}<br>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
<div id="rawPromptPopup" class="list-group">
|
||||||
|
<div id="rawPromptWrapper" class="tokenItemizingSubclass"></div>
|
||||||
|
</div>
|
||||||
|
3
public/scripts/templates/themeDelete.html
Normal file
3
public/scripts/templates/themeDelete.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
Are you sure you want to delete the theme "{{themeName}}"?
|
||||||
|
</div>
|
3
public/scripts/templates/themeImportWarning.html
Normal file
3
public/scripts/templates/themeImportWarning.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
This theme contains @import lines in the Custom CSS. Press "Yes" to proceed.
|
||||||
|
</div>
|
@ -1,8 +1,9 @@
|
|||||||
import { getContext } from './extensions.js';
|
import { getContext } from './extensions.js';
|
||||||
import { callPopup, getRequestHeaders } from '../script.js';
|
import { getRequestHeaders } from '../script.js';
|
||||||
import { isMobile } from './RossAscends-mods.js';
|
import { isMobile } from './RossAscends-mods.js';
|
||||||
import { collapseNewlines } from './power-user.js';
|
import { collapseNewlines } from './power-user.js';
|
||||||
import { debounce_timeout } from './constants.js';
|
import { debounce_timeout } from './constants.js';
|
||||||
|
import { Popup } from './popup.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pagination status string template.
|
* Pagination status string template.
|
||||||
@ -1821,7 +1822,7 @@ export async function checkOverwriteExistingData(type, existingNames, name, { in
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const overwrite = interactive ? await callPopup(`<h3>${type} ${actionName}</h3><p>A ${type.toLowerCase()} with the same name already exists:<br />${existing}</p>Do you want to overwrite it?`, 'confirm') : false;
|
const overwrite = interactive && await Popup.show.confirm(`${type} ${actionName}`, `<p>A ${type.toLowerCase()} with the same name already exists:<br />${existing}</p>Do you want to overwrite it?`);
|
||||||
if (!overwrite) {
|
if (!overwrite) {
|
||||||
toastr.warning(`${type} ${actionName.toLowerCase()} cancelled. A ${type.toLowerCase()} with the same name already exists:<br />${existing}`, `${type} ${actionName}`, { escapeHtml: false });
|
toastr.warning(`${type} ${actionName.toLowerCase()} cancelled. A ${type.toLowerCase()} with the same name already exists:<br />${existing}`, `${type} ${actionName}`, { escapeHtml: false });
|
||||||
return false;
|
return false;
|
||||||
|
@ -16,6 +16,7 @@ import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandE
|
|||||||
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
import { SlashCommandExecutor } from './slash-commands/SlashCommandExecutor.js';
|
import { SlashCommandExecutor } from './slash-commands/SlashCommandExecutor.js';
|
||||||
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
||||||
|
import { Popup } from './popup.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
world_info,
|
world_info,
|
||||||
@ -1684,8 +1685,7 @@ function displayWorldEntries(name, data, navigation = navigation_option.none, fl
|
|||||||
// Regardless of whether success is displayed or not. Make sure the delete button is available.
|
// Regardless of whether success is displayed or not. Make sure the delete button is available.
|
||||||
// Do not put this code behind.
|
// Do not put this code behind.
|
||||||
$('#world_popup_delete').off('click').on('click', async () => {
|
$('#world_popup_delete').off('click').on('click', async () => {
|
||||||
const confirmation = await callPopup(`<h3>Delete the World/Lorebook: "${name}"?</h3>This action is irreversible!`, 'confirm');
|
const confirmation = await Popup.show.confirm(`Delete the World/Lorebook: "${name}"?`, `This action is irreversible!`);
|
||||||
|
|
||||||
if (!confirmation) {
|
if (!confirmation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1862,7 +1862,7 @@ function displayWorldEntries(name, data, navigation = navigation_option.none, fl
|
|||||||
|
|
||||||
$('#world_duplicate').off('click').on('click', async () => {
|
$('#world_duplicate').off('click').on('click', async () => {
|
||||||
const tempName = getFreeWorldName();
|
const tempName = getFreeWorldName();
|
||||||
const finalName = await callPopup('<h3>Create a new World Info?</h3>Enter a name for the new file:', 'input', tempName);
|
const finalName = await Popup.show.input('Create a new World Info?', 'Enter a name for the new file:', tempName);
|
||||||
|
|
||||||
if (finalName) {
|
if (finalName) {
|
||||||
await saveWorldInfo(finalName, data, true);
|
await saveWorldInfo(finalName, data, true);
|
||||||
@ -3190,7 +3190,7 @@ async function saveWorldInfo(name, data, immediately) {
|
|||||||
|
|
||||||
async function renameWorldInfo(name, data) {
|
async function renameWorldInfo(name, data) {
|
||||||
const oldName = name;
|
const oldName = name;
|
||||||
const newName = await callPopup('<h3>Rename World Info</h3>Enter a new name:', 'input', oldName);
|
const newName = await Popup.show.input('Rename World Info', 'Enter a new name:', oldName);
|
||||||
|
|
||||||
if (oldName === newName || !newName) {
|
if (oldName === newName || !newName) {
|
||||||
console.debug('World info rename cancelled');
|
console.debug('World info rename cancelled');
|
||||||
@ -4138,11 +4138,9 @@ export async function importEmbeddedWorldInfo(skipPopup = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bookName = characters[chid]?.data?.character_book?.name || `${characters[chid]?.name}'s Lorebook`;
|
const bookName = characters[chid]?.data?.character_book?.name || `${characters[chid]?.name}'s Lorebook`;
|
||||||
const confirmationText = (`<h3>Are you sure you want to import "${bookName}"?</h3>`) + (world_names.includes(bookName) ? 'It will overwrite the World/Lorebook with the same name.' : '');
|
|
||||||
|
|
||||||
if (!skipPopup) {
|
if (!skipPopup) {
|
||||||
const confirmation = await callPopup(confirmationText, 'confirm');
|
const confirmation = await Popup.show.confirm(`Are you sure you want to import "${bookName}"?`, world_names.includes(bookName) ? 'It will overwrite the World/Lorebook with the same name.' : '');
|
||||||
|
|
||||||
if (!confirmation) {
|
if (!confirmation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4382,7 +4380,7 @@ jQuery(() => {
|
|||||||
|
|
||||||
$('#world_create_button').on('click', async () => {
|
$('#world_create_button').on('click', async () => {
|
||||||
const tempName = getFreeWorldName();
|
const tempName = getFreeWorldName();
|
||||||
const finalName = await callPopup('<h3>Create a new World Info?</h3>Enter a name for the new file:', 'input', tempName);
|
const finalName = await Popup.show.input('Create a new World Info', 'Enter a name for the new file:', tempName);
|
||||||
|
|
||||||
if (finalName) {
|
if (finalName) {
|
||||||
await createNewWorldInfo(finalName, { interactive: true });
|
await createNewWorldInfo(finalName, { interactive: true });
|
||||||
|
@ -82,7 +82,7 @@
|
|||||||
/*base variable calculated in rems*/
|
/*base variable calculated in rems*/
|
||||||
--fontScale: 1;
|
--fontScale: 1;
|
||||||
--mainFontSize: calc(var(--fontScale) * 15px);
|
--mainFontSize: calc(var(--fontScale) * 15px);
|
||||||
--mainFontFamily: "Noto Sans", "Noto Color Emoji", sans-serif;
|
--mainFontFamily: "Noto Sans", sans-serif;
|
||||||
--monoFontFamily: 'Noto Sans Mono', 'Courier New', Consolas, monospace;
|
--monoFontFamily: 'Noto Sans Mono', 'Courier New', Consolas, monospace;
|
||||||
|
|
||||||
/* base variable for blur strength slider calculations */
|
/* base variable for blur strength slider calculations */
|
||||||
@ -256,10 +256,6 @@ input[type='checkbox']:focus-visible {
|
|||||||
color: var(--SmartThemeEmColor);
|
color: var(--SmartThemeEmColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#rawPromptWrapper {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tokenGraph {
|
.tokenGraph {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid var(--SmartThemeBorderColor);
|
border: 1px solid var(--SmartThemeBorderColor);
|
||||||
@ -462,7 +458,7 @@ code {
|
|||||||
kbd {
|
kbd {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
font-family: Consolas, monospace;
|
font-family: var(--monoFontFamily);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/* background-color: #eeeeee; */
|
/* background-color: #eeeeee; */
|
||||||
background-color: rgba(255, 255, 255, 0.9);
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
@ -4367,8 +4363,7 @@ a {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#export_format_popup,
|
#export_format_popup {
|
||||||
#rawPromptPopup {
|
|
||||||
display: none;
|
display: none;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
@ -4376,7 +4371,7 @@ a {
|
|||||||
#rawPromptPopup {
|
#rawPromptPopup {
|
||||||
inset: 0px auto auto 0px;
|
inset: 0px auto auto 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
transform: translate(909px, 47px);
|
transform: translate(500px, 0px);
|
||||||
display: block;
|
display: block;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
@ -4395,7 +4390,8 @@ a {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rawPopupWrapper {
|
#rawPromptWrapper {
|
||||||
|
white-space: pre-wrap;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
|
Reference in New Issue
Block a user