mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add clickable buttons in Welcome chat message.
Add bool `uses_system_ui` on system messages to override sanitizer for buttons when set Modify uponSanitizeAttribute DOMPurify hook to allow unmangled class names on attributes in some cases Add event listener for .drawer-opener to open a navbar drawer
This commit is contained in:
192
public/script.js
192
public/script.js
@ -293,10 +293,17 @@ DOMPurify.addHook('afterSanitizeAttributes', function (node) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
DOMPurify.addHook('uponSanitizeAttribute', (_, data, config) => {
|
DOMPurify.addHook('uponSanitizeAttribute', (node, data, config) => {
|
||||||
if (!config['MESSAGE_SANITIZE']) {
|
if (!config['MESSAGE_SANITIZE']) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Retain the classes on UI elements of messages that interact with the main UI */
|
||||||
|
const permittedNodeTypes = ['BUTTON', 'DIV'];
|
||||||
|
if (config['MESSAGE_ALLOW_SYSTEM_UI'] && node.classList.contains('menu_button') && permittedNodeTypes.includes(node.nodeName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (data.attrName) {
|
switch (data.attrName) {
|
||||||
case 'class': {
|
case 'class': {
|
||||||
if (data.attrValue) {
|
if (data.attrValue) {
|
||||||
@ -650,7 +657,8 @@ async function getSystemMessages() {
|
|||||||
force_avatar: system_avatar,
|
force_avatar: system_avatar,
|
||||||
is_user: false,
|
is_user: false,
|
||||||
is_system: true,
|
is_system: true,
|
||||||
mes: await renderTemplateAsync('welcome', { displayVersion }),
|
uses_system_ui: true,
|
||||||
|
mes: await renderTemplateAsync('welcome', { displayVersion } ),
|
||||||
},
|
},
|
||||||
group: {
|
group: {
|
||||||
name: systemUserName,
|
name: systemUserName,
|
||||||
@ -1916,9 +1924,10 @@ export async function sendTextareaMessage() {
|
|||||||
* @param {boolean} isSystem If the message was sent by the system
|
* @param {boolean} isSystem If the message was sent by the system
|
||||||
* @param {boolean} isUser If the message was sent by the user
|
* @param {boolean} isUser If the message was sent by the user
|
||||||
* @param {number} messageId Message index in chat array
|
* @param {number} messageId Message index in chat array
|
||||||
|
* @param {object} [sanitizerOverrides] DOMPurify sanitizer option overrides
|
||||||
* @returns {string} HTML string
|
* @returns {string} HTML string
|
||||||
*/
|
*/
|
||||||
export function messageFormatting(mes, ch_name, isSystem, isUser, messageId) {
|
export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, sanitizerOverrides = {}) {
|
||||||
if (!mes) {
|
if (!mes) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -2029,7 +2038,7 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @type {any} */
|
/** @type {any} */
|
||||||
const config = { MESSAGE_SANITIZE: true, ADD_TAGS: ['custom-style'] };
|
const config = { MESSAGE_SANITIZE: true, ADD_TAGS: ['custom-style'], ...sanitizerOverrides };
|
||||||
mes = encodeStyleTags(mes);
|
mes = encodeStyleTags(mes);
|
||||||
mes = DOMPurify.sanitize(mes, config);
|
mes = DOMPurify.sanitize(mes, config);
|
||||||
mes = decodeStyleTags(mes);
|
mes = decodeStyleTags(mes);
|
||||||
@ -2234,6 +2243,18 @@ export function addCopyToCodeBlocks(messageElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a single message to the chat.
|
||||||
|
* @param {object} mes Message object
|
||||||
|
* @param {object} [options] Options
|
||||||
|
* @param {string} [options.type='normal'] Message type
|
||||||
|
* @param {number} [options.insertAfter=null] Message ID to insert the new message after
|
||||||
|
* @param {boolean} [options.scroll=true] Whether to scroll to the new message
|
||||||
|
* @param {number} [options.insertBefore=null] Message ID to insert the new message before
|
||||||
|
* @param {number} [options.forceId=null] Force the message ID
|
||||||
|
* @param {boolean} [options.showSwipes=true] Whether to show swipe buttons
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll = true, insertBefore = null, forceId = null, showSwipes = true } = {}) {
|
export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll = true, insertBefore = null, forceId = null, showSwipes = true } = {}) {
|
||||||
let messageText = mes['mes'];
|
let messageText = mes['mes'];
|
||||||
const momentDate = timestampToMoment(mes.send_date);
|
const momentDate = timestampToMoment(mes.send_date);
|
||||||
@ -2262,7 +2283,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll
|
|||||||
} else if (this_chid === undefined) {
|
} else if (this_chid === undefined) {
|
||||||
avatarImg = system_avatar;
|
avatarImg = system_avatar;
|
||||||
} else {
|
} else {
|
||||||
if (characters[this_chid].avatar != 'none') {
|
if (characters[this_chid].avatar !== 'none') {
|
||||||
avatarImg = getThumbnailUrl('avatar', characters[this_chid].avatar);
|
avatarImg = getThumbnailUrl('avatar', characters[this_chid].avatar);
|
||||||
} else {
|
} else {
|
||||||
avatarImg = default_avatar;
|
avatarImg = default_avatar;
|
||||||
@ -2277,12 +2298,16 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll
|
|||||||
avatarImg = mes['force_avatar'];
|
avatarImg = mes['force_avatar'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if mes.uses_system_ui is true, set an override on the sanitizer options
|
||||||
|
const sanitizerOverrides = mes.uses_system_ui ? { MESSAGE_ALLOW_SYSTEM_UI: true } : {};
|
||||||
|
|
||||||
messageText = messageFormatting(
|
messageText = messageFormatting(
|
||||||
messageText,
|
messageText,
|
||||||
mes.name,
|
mes.name,
|
||||||
isSystem,
|
isSystem,
|
||||||
mes.is_user,
|
mes.is_user,
|
||||||
chat.indexOf(mes),
|
chat.indexOf(mes),
|
||||||
|
sanitizerOverrides,
|
||||||
);
|
);
|
||||||
const bias = messageFormatting(mes.extra?.bias ?? '', '', false, false, -1);
|
const bias = messageFormatting(mes.extra?.bias ?? '', '', false, false, -1);
|
||||||
let bookmarkLink = mes?.extra?.bookmark_link ?? '';
|
let bookmarkLink = mes?.extra?.bookmark_link ?? '';
|
||||||
@ -2330,7 +2355,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll
|
|||||||
}
|
}
|
||||||
|
|
||||||
//shows or hides the Prompt display button
|
//shows or hides the Prompt display button
|
||||||
let mesIdToFind = type == 'swipe' ? params.mesId - 1 : params.mesId; //Number(newMessage.attr('mesId'));
|
let mesIdToFind = type === 'swipe' ? params.mesId - 1 : params.mesId; //Number(newMessage.attr('mesId'));
|
||||||
|
|
||||||
//if we have itemized messages, and the array isn't null..
|
//if we have itemized messages, and the array isn't null..
|
||||||
if (params.isUser === false && Array.isArray(itemizedPrompts) && itemizedPrompts.length > 0) {
|
if (params.isUser === false && Array.isArray(itemizedPrompts) && itemizedPrompts.length > 0) {
|
||||||
@ -2651,7 +2676,7 @@ export function sendSystemMessage(type, text, extra = {}) {
|
|||||||
newMessage.mes = text;
|
newMessage.mes = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == system_message_types.SLASH_COMMANDS) {
|
if (type === system_message_types.SLASH_COMMANDS) {
|
||||||
newMessage.mes = getSlashCommandsHelp();
|
newMessage.mes = getSlashCommandsHelp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2665,7 +2690,7 @@ export function sendSystemMessage(type, text, extra = {}) {
|
|||||||
chat.push(newMessage);
|
chat.push(newMessage);
|
||||||
addOneMessage(newMessage);
|
addOneMessage(newMessage);
|
||||||
is_send_press = false;
|
is_send_press = false;
|
||||||
if (type == system_message_types.SLASH_COMMANDS) {
|
if (type === system_message_types.SLASH_COMMANDS) {
|
||||||
const browser = new SlashCommandBrowser();
|
const browser = new SlashCommandBrowser();
|
||||||
const spinner = document.querySelector('#chat .last_mes .custom-slashHelp');
|
const spinner = document.querySelector('#chat .last_mes .custom-slashHelp');
|
||||||
const parent = spinner.parentElement;
|
const parent = spinner.parentElement;
|
||||||
@ -7854,7 +7879,7 @@ function openAlternateGreetings() {
|
|||||||
if (menu_type !== 'create') {
|
if (menu_type !== 'create') {
|
||||||
await createOrEditCharacter();
|
await createOrEditCharacter();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let index = 0; index < getArray().length; index++) {
|
for (let index = 0; index < getArray().length; index++) {
|
||||||
@ -9070,6 +9095,90 @@ function doTogglePanels() {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler to open a navbar drawer when a drawer open button is clicked.
|
||||||
|
* Handles click events on .drawer-opener elements.
|
||||||
|
* Opens the drawer associated with the clicked button according to the data-target attribute.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function doDrawerOpenClick() {
|
||||||
|
const targetDrawerID = $(this).attr('data-target');
|
||||||
|
const drawer = $(`#${targetDrawerID}`);
|
||||||
|
const drawerToggle = drawer.find('.drawer-toggle');
|
||||||
|
const drawerWasOpenAlready = drawerToggle.parent().find('.drawer-content').hasClass('openDrawer');
|
||||||
|
if (drawerWasOpenAlready || drawer.hasClass('resizing') ) { return; }
|
||||||
|
doNavbarIconClick.call(drawerToggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler to open or close a navbar drawer when a navbar icon is clicked.
|
||||||
|
* Handles click events on .drawer-toggle elements.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function doNavbarIconClick() {
|
||||||
|
var icon = $(this).find('.drawer-icon');
|
||||||
|
var drawer = $(this).parent().find('.drawer-content');
|
||||||
|
if (drawer.hasClass('resizing')) { return; }
|
||||||
|
var drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');
|
||||||
|
let targetDrawerID = $(this).parent().find('.drawer-content').attr('id');
|
||||||
|
const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');
|
||||||
|
|
||||||
|
if (!drawerWasOpenAlready) { //to open the drawer
|
||||||
|
$('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
|
||||||
|
await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
|
||||||
|
});
|
||||||
|
$('.openIcon').toggleClass('closedIcon openIcon');
|
||||||
|
$('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');
|
||||||
|
icon.toggleClass('openIcon closedIcon');
|
||||||
|
drawer.toggleClass('openDrawer closedDrawer');
|
||||||
|
|
||||||
|
//console.log(targetDrawerID);
|
||||||
|
if (targetDrawerID === 'right-nav-panel') {
|
||||||
|
$(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle({
|
||||||
|
duration: 200,
|
||||||
|
easing: 'swing',
|
||||||
|
start: function () {
|
||||||
|
jQuery(this).css('display', 'flex'); //flex needed to make charlist scroll
|
||||||
|
},
|
||||||
|
complete: async function () {
|
||||||
|
favsToHotswap();
|
||||||
|
await delay(50);
|
||||||
|
$(this).closest('.drawer-content').removeClass('resizing');
|
||||||
|
$('#rm_print_characters_block').trigger('scroll');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle(200, 'swing', async function () {
|
||||||
|
await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the height of "autoSetHeight" textareas within the drawer to their scroll height
|
||||||
|
if (!CSS.supports('field-sizing', 'content')) {
|
||||||
|
$(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight').each(async function () {
|
||||||
|
await resetScrollHeight($(this));
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (drawerWasOpenAlready) { //to close manually
|
||||||
|
icon.toggleClass('closedIcon openIcon');
|
||||||
|
|
||||||
|
if (pinnedDrawerClicked) {
|
||||||
|
$(drawer).addClass('resizing').slideToggle(200, 'swing', async function () {
|
||||||
|
await delay(50); $(this).removeClass('resizing');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
|
||||||
|
await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
drawer.toggleClass('closedDrawer openDrawer');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function addDebugFunctions() {
|
function addDebugFunctions() {
|
||||||
const doBackfill = async () => {
|
const doBackfill = async () => {
|
||||||
for (const message of chat) {
|
for (const message of chat) {
|
||||||
@ -10659,69 +10768,8 @@ jQuery(async function () {
|
|||||||
stopScriptExecution();
|
stopScriptExecution();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.drawer-toggle').on('click', function () {
|
$(document).on('click', '.drawer-opener', doDrawerOpenClick);
|
||||||
var icon = $(this).find('.drawer-icon');
|
$('.drawer-toggle').on('click', doNavbarIconClick);
|
||||||
var drawer = $(this).parent().find('.drawer-content');
|
|
||||||
if (drawer.hasClass('resizing')) { return; }
|
|
||||||
var drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');
|
|
||||||
let targetDrawerID = $(this).parent().find('.drawer-content').attr('id');
|
|
||||||
const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');
|
|
||||||
|
|
||||||
if (!drawerWasOpenAlready) { //to open the drawer
|
|
||||||
$('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
|
|
||||||
await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
|
|
||||||
});
|
|
||||||
$('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon');
|
|
||||||
$('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');
|
|
||||||
icon.toggleClass('openIcon closedIcon');
|
|
||||||
drawer.toggleClass('openDrawer closedDrawer');
|
|
||||||
|
|
||||||
//console.log(targetDrawerID);
|
|
||||||
if (targetDrawerID === 'right-nav-panel') {
|
|
||||||
$(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle({
|
|
||||||
duration: 200,
|
|
||||||
easing: 'swing',
|
|
||||||
start: function () {
|
|
||||||
jQuery(this).css('display', 'flex'); //flex needed to make charlist scroll
|
|
||||||
},
|
|
||||||
complete: async function () {
|
|
||||||
favsToHotswap();
|
|
||||||
await delay(50);
|
|
||||||
$(this).closest('.drawer-content').removeClass('resizing');
|
|
||||||
$('#rm_print_characters_block').trigger('scroll');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle(200, 'swing', async function () {
|
|
||||||
await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the height of "autoSetHeight" textareas within the drawer to their scroll height
|
|
||||||
if (!CSS.supports('field-sizing', 'content')) {
|
|
||||||
$(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight').each(async function () {
|
|
||||||
await resetScrollHeight($(this));
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (drawerWasOpenAlready) { //to close manually
|
|
||||||
icon.toggleClass('closedIcon openIcon');
|
|
||||||
|
|
||||||
if (pinnedDrawerClicked) {
|
|
||||||
$(drawer).addClass('resizing').slideToggle(200, 'swing', async function () {
|
|
||||||
await delay(50); $(this).removeClass('resizing');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
|
|
||||||
await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
drawer.toggleClass('closedDrawer openDrawer');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('html').on('touchstart mousedown', function (e) {
|
$('html').on('touchstart mousedown', function (e) {
|
||||||
var clickTarget = $(e.target);
|
var clickTarget = $(e.target);
|
||||||
|
@ -1,65 +1,95 @@
|
|||||||
<h3>
|
<h3>
|
||||||
<span id="version_display_welcome">{{displayVersion}}</span>
|
<span id="version_display_welcome">{{displayVersion}}</span>
|
||||||
</h3>
|
</h3>
|
||||||
<a href="https://docs.sillytavern.app/usage/update/" target="_blank" data-i18n="Want to update?">
|
<a href="https://docs.sillytavern.app/usage/update/" target="_blank" data-i18n="Want to update?">
|
||||||
Want to update?
|
Want to update?
|
||||||
</a>
|
</a>
|
||||||
<hr>
|
<hr>
|
||||||
<h3 data-i18n="How to start chatting?">How to start chatting?</h3>
|
<h3 data-i18n="How to start chatting?">How to start chatting?</h3>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
<span data-i18n="Click _space">Click </span><code><i class="fa-solid fa-plug"></i></code><span data-i18n="and select a"> and select a </span><a href="https://docs.sillytavern.app/usage/api-connections/" target="_blank" data-i18n="Chat API">Chat API</a>.</span>
|
<span data-i18n="Click _space">Click </span>
|
||||||
</li>
|
<button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="sys-settings-button">
|
||||||
<li>
|
<i class="fa-solid fa-plug"></i>
|
||||||
<span data-i18n="Click _space">Click </span><code><i class="fa-solid fa-address-card"></i></code><span data-i18n="and pick a character."> and pick a character.</span>
|
<span data-i18n="[title]API Connections">API Connections</span>
|
||||||
</li>
|
</button>
|
||||||
|
<span data-i18n="and select a">and select a</span>
|
||||||
|
<a href="https://docs.sillytavern.app/usage/api-connections/" target="_blank">
|
||||||
|
<span class="fa-solid fa-circle-question"></span>
|
||||||
|
<span data-i18n="Chat API">Chat API</span></a>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span data-i18n="Click _space">Click </span>
|
||||||
|
<button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="rightNavHolder">
|
||||||
|
<i class="fa-solid fa-address-card"></i>
|
||||||
|
<span data-i18n="[title]Character Management">Character Management</span>
|
||||||
|
</button>
|
||||||
|
<span data-i18n="and pick a character."> and pick a character.</span>
|
||||||
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<div>
|
|
||||||
<span data-i18n="You can browse a list of bundled characters in the">
|
<p>
|
||||||
You can browse a list of bundled characters in the
|
<span data-i18n="You can add more">You can add more</span>
|
||||||
</span>
|
<button class="open_characters_library menu_button menu_button_icon inline-flex">
|
||||||
<i data-i18n="Download Extensions & Assets">
|
<i class="fa-solid fa-image-portrait"></i>
|
||||||
Download Extensions & Assets
|
<span data-i18n="Sample characters">Sample characters</span>
|
||||||
</i>
|
</button>
|
||||||
<span data-i18n="menu within">
|
<span data-i18n="or">or</span>
|
||||||
menu within
|
<button class="external_import_button menu_button menu_button_icon inline-flex">
|
||||||
</span>
|
<i class="fa-solid fa-cloud-arrow-down"></i>
|
||||||
<code><i class="fa-solid fa-cubes"></i></code>
|
<span data-i18n="Import Characters">Import characters</span>
|
||||||
<span>.</span>
|
</button>
|
||||||
</div>
|
<span data-i18n="from other websites">from other websites.</span>
|
||||||
|
|
||||||
|
<span data-i18n="Go to the">Go to the</span>
|
||||||
|
|
||||||
|
<i data-i18n="Download Extensions & Assets">Download Extensions & Assets</i>
|
||||||
|
<span data-i18n="menu within">menu within</span>
|
||||||
|
|
||||||
|
<button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="extensions-settings-button">
|
||||||
|
<i class="fa-solid fa-cubes"></i>
|
||||||
|
<span data-i18n="[title]Extensions">Extensions</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<span data-i18n="to install additional features.">to install additional features.</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<h3 data-i18n="Confused or lost?">Confused or lost?</h3>
|
<h3 data-i18n="Confused or lost?">Confused or lost?</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<span class="note-link-span"><a class="fa-solid fa-circle-question" target="_blank" href="https://docs.sillytavern.app/"></a></span> - <span data-i18n="click these icons!">click these icons!</span>
|
<span class="note-link-span"><a class="fa-solid fa-circle-question" target="_blank"
|
||||||
</li>
|
href="https://docs.sillytavern.app/"></a></span> - <span
|
||||||
<li>
|
data-i18n="click these icons!">click these icons!</span>
|
||||||
<span data-i18n="Enter">Enter </span><code>/?</code><span data-i18n="in the chat bar"> in the chat bar</span>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<span data-i18n="Enter">Enter </span><code>/?</code><span data-i18n="in the chat bar"> in the chat bar</span>
|
||||||
<a target="_blank" href="https://docs.sillytavern.app/" data-i18n="SillyTavern Documentation Site">
|
</li>
|
||||||
SillyTavern Documentation Site
|
<li>
|
||||||
</a>
|
<a target="_blank" href="https://docs.sillytavern.app/" data-i18n="SillyTavern Documentation Site">
|
||||||
</li>
|
SillyTavern Documentation Site
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<h3 data-i18n="Still have questions?">Still have questions?</h3>
|
<h3 data-i18n="Still have questions?">Still have questions?</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="https://discord.gg/sillytavern" data-i18n="Join the SillyTavern Discord">
|
<a target="_blank" href="https://discord.gg/sillytavern" data-i18n="Join the SillyTavern Discord">
|
||||||
Join the SillyTavern Discord
|
Join the SillyTavern Discord
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="https://github.com/SillyTavern/SillyTavern/issues" data-i18n="Post a GitHub issue">
|
<a target="_blank" href="https://github.com/SillyTavern/SillyTavern/issues" data-i18n="Post a GitHub issue">
|
||||||
Post a GitHub issue
|
Post a GitHub issue
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="https://github.com/SillyTavern/SillyTavern#questions-or-suggestions" data-i18n="Contact the developers">
|
<a target="_blank" href="https://github.com/SillyTavern/SillyTavern#questions-or-suggestions"
|
||||||
Contact the developers
|
data-i18n="Contact the developers">
|
||||||
</a>
|
Contact the developers
|
||||||
</li>
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -1208,8 +1208,9 @@ textarea.autoSetHeight {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
select {
|
select,
|
||||||
font-family: var(--mainFontFamily);
|
button {
|
||||||
|
font-family: var(--mainFontFamily), sans-serif;
|
||||||
font-size: var(--mainFontSize);
|
font-size: var(--mainFontSize);
|
||||||
color: var(--SmartThemeBodyColor);
|
color: var(--SmartThemeBodyColor);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user