mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'staging' into smol-tag-improvements
This commit is contained in:
@@ -29,10 +29,14 @@
|
||||
<input type="checkbox" id="qr--modal-executeShortcut">
|
||||
<span>Ctrl+Enter to execute</span>
|
||||
</label>
|
||||
<label class="checkbox_label">
|
||||
<input type="checkbox" id="qr--modal-syntax">
|
||||
<span>Syntax highlight</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="qr--modal-messageHolder">
|
||||
<pre id="qr--modal-messageSyntax"><code id="qr--modal-messageSyntaxInner" class="hljs language-stscript"></code></pre>
|
||||
<textarea class="monospace" id="qr--modal-message" spellcheck="false"></textarea>
|
||||
<textarea id="qr--modal-message" spellcheck="false"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -264,6 +264,13 @@ export class QuickReply {
|
||||
const updateSyntax = ()=>{
|
||||
messageSyntaxInner.innerHTML = hljs.highlight(`${message.value}${message.value.slice(-1) == '\n' ? ' ' : ''}`, { language:'stscript', ignoreIllegals:true })?.value;
|
||||
};
|
||||
const updateSyntaxEnabled = ()=>{
|
||||
if (JSON.parse(localStorage.getItem('qr--syntax'))) {
|
||||
dom.querySelector('#qr--modal-messageHolder').classList.remove('qr--noSyntax');
|
||||
} else {
|
||||
dom.querySelector('#qr--modal-messageHolder').classList.add('qr--noSyntax');
|
||||
}
|
||||
};
|
||||
/**@type {HTMLInputElement}*/
|
||||
const tabSize = dom.querySelector('#qr--modal-tabSize');
|
||||
tabSize.value = JSON.parse(localStorage.getItem('qr--tabSize') ?? '4');
|
||||
@@ -282,6 +289,13 @@ export class QuickReply {
|
||||
executeShortcut.addEventListener('click', () => {
|
||||
localStorage.setItem('qr--executeShortcut', JSON.stringify(executeShortcut.checked));
|
||||
});
|
||||
/**@type {HTMLInputElement}*/
|
||||
const syntax = dom.querySelector('#qr--modal-syntax');
|
||||
syntax.checked = JSON.parse(localStorage.getItem('qr--syntax') ?? 'true');
|
||||
syntax.addEventListener('click', () => {
|
||||
localStorage.setItem('qr--syntax', JSON.stringify(syntax.checked));
|
||||
updateSyntaxEnabled();
|
||||
});
|
||||
/**@type {HTMLTextAreaElement}*/
|
||||
const message = dom.querySelector('#qr--modal-message');
|
||||
message.value = this.message;
|
||||
@@ -352,8 +366,7 @@ export class QuickReply {
|
||||
}
|
||||
});
|
||||
window.addEventListener('resize', resizeListener);
|
||||
message.style.color = 'transparent';
|
||||
message.style.background = 'transparent';
|
||||
updateSyntaxEnabled();
|
||||
message.style.setProperty('text-shadow', 'none', 'important');
|
||||
/**@type {HTMLElement}*/
|
||||
const messageSyntaxInner = dom.querySelector('#qr--modal-messageSyntaxInner');
|
||||
|
@@ -301,6 +301,22 @@
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
.dialogue_popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder.qr--noSyntax > #qr--modal-messageSyntax {
|
||||
display: none;
|
||||
}
|
||||
.dialogue_popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder.qr--noSyntax > #qr--modal-message {
|
||||
background-color: var(--ac-style-color-background);
|
||||
color: var(--ac-style-color-text);
|
||||
}
|
||||
.dialogue_popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder.qr--noSyntax > #qr--modal-message::selection {
|
||||
color: unset;
|
||||
background-color: rgba(108 171 251 / 0.25);
|
||||
}
|
||||
@supports (color: rgb(from white r g b / 0.25)) {
|
||||
.dialogue_popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder.qr--noSyntax > #qr--modal-message::selection {
|
||||
background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25);
|
||||
}
|
||||
}
|
||||
.popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder > #qr--modal-messageSyntax {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
@@ -315,18 +331,30 @@
|
||||
height: 100%;
|
||||
}
|
||||
.popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder > #qr--modal-message {
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
caret-color: white;
|
||||
mix-blend-mode: difference;
|
||||
caret-color: var(--ac-style-color-text);
|
||||
overflow: auto;
|
||||
}
|
||||
.popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder > #qr--modal-message::-webkit-scrollbar,
|
||||
.popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder > #qr--modal-message::-webkit-scrollbar-thumb {
|
||||
visibility: hidden;
|
||||
cursor: default;
|
||||
}
|
||||
.dialogue_popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder > #qr--modal-message::selection {
|
||||
color: transparent;
|
||||
background-color: rgba(108 171 251 / 0.25);
|
||||
}
|
||||
@supports (color: rgb(from white r g b / 0.25)) {
|
||||
.dialogue_popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder > #qr--modal-message::selection {
|
||||
background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25);
|
||||
}
|
||||
}
|
||||
.popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder #qr--modal-message,
|
||||
.popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder #qr--modal-messageSyntaxInner {
|
||||
font-family: var(--monoFontFamily);
|
||||
padding: 0.75em;
|
||||
margin: 0;
|
||||
border: none;
|
||||
|
@@ -322,6 +322,22 @@
|
||||
display: grid;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
&.qr--noSyntax {
|
||||
> #qr--modal-messageSyntax {
|
||||
display: none;
|
||||
}
|
||||
> #qr--modal-message {
|
||||
background-color: var(--ac-style-color-background);
|
||||
color: var(--ac-style-color-text);
|
||||
&::selection {
|
||||
color: unset;
|
||||
background-color: rgba(108 171 251 / 0.25);
|
||||
@supports (color: rgb(from white r g b / 0.25)) {
|
||||
background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> #qr--modal-messageSyntax {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
@@ -336,16 +352,26 @@
|
||||
}
|
||||
}
|
||||
> #qr--modal-message {
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
caret-color: white;
|
||||
mix-blend-mode: difference;
|
||||
caret-color: var(--ac-style-color-text);
|
||||
overflow: auto;
|
||||
&::-webkit-scrollbar, &::-webkit-scrollbar-thumb {
|
||||
visibility: hidden;
|
||||
cursor: default;
|
||||
}
|
||||
&::selection {
|
||||
color: transparent;
|
||||
background-color: rgba(108 171 251 / 0.25);
|
||||
@supports (color: rgb(from white r g b / 0.25)) {
|
||||
background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
#qr--modal-message, #qr--modal-messageSyntaxInner {
|
||||
font-family: var(--monoFontFamily);
|
||||
padding: 0.75em;
|
||||
margin: 0;
|
||||
border: none;
|
||||
|
@@ -16,6 +16,7 @@ import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
||||
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
|
||||
import { splitRecursive } from '../../utils.js';
|
||||
import { renderTemplateAsync } from '../../templates.js';
|
||||
|
||||
export const autoModeOptions = {
|
||||
NONE: 'none',
|
||||
@@ -340,6 +341,34 @@ async function translateProviderBing(text, lang) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates text using the Yandex Translate API
|
||||
* @param {string} text Text to translate
|
||||
* @param {string} lang Target language code
|
||||
* @returns {Promise<string>} Translated text
|
||||
*/
|
||||
async function translateProviderYandex(text, lang) {
|
||||
let chunks = [];
|
||||
const chunkSize = 5000;
|
||||
if (text.length <= chunkSize) {
|
||||
chunks.push(text);
|
||||
} else {
|
||||
chunks = splitRecursive(text, chunkSize);
|
||||
}
|
||||
const response = await fetch('/api/translate/yandex', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({ chunks: chunks, lang: lang }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const result = await response.text();
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits text into chunks and translates each chunk separately
|
||||
* @param {string} text Text to translate
|
||||
@@ -389,6 +418,8 @@ async function translate(text, lang) {
|
||||
return await translateProviderOneRing(text, lang);
|
||||
case 'bing':
|
||||
return await chunkedTranslate(text, lang, translateProviderBing, 1000);
|
||||
case 'yandex':
|
||||
return await translateProviderYandex(text, lang);
|
||||
default:
|
||||
console.error('Unknown translation provider', extension_settings.translate.provider);
|
||||
return text;
|
||||
@@ -532,56 +563,10 @@ const handleMessageEdit = createEventHandler(translateMessageEdit, () => true);
|
||||
|
||||
window['translate'] = translate;
|
||||
|
||||
jQuery(() => {
|
||||
const html = `
|
||||
<div class="translation_settings">
|
||||
<div class="inline-drawer">
|
||||
<div class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Chat Translation</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<label for="translation_auto_mode" class="checkbox_label">Auto-mode</label>
|
||||
<select id="translation_auto_mode">
|
||||
<option value="none">None</option>
|
||||
<option value="responses">Translate responses</option>
|
||||
<option value="inputs">Translate inputs</option>
|
||||
<option value="both">Translate both</option>
|
||||
</select>
|
||||
<label for="translation_provider">Provider</label>
|
||||
<div class="flex-container gap5px flexnowrap marginBot5">
|
||||
<select id="translation_provider" name="provider" class="margin0">
|
||||
<option value="libre">Libre</option>
|
||||
<option value="google">Google</option>
|
||||
<option value="lingva">Lingva</option>
|
||||
<option value="deepl">DeepL</option>
|
||||
<option value="deeplx">DeepLX</option>
|
||||
<option value="bing">Bing</option>
|
||||
<option value="oneringtranslator">OneRingTranslator</option>
|
||||
<select>
|
||||
<div id="translate_key_button" class="menu_button fa-solid fa-key margin0"></div>
|
||||
<div id="translate_url_button" class="menu_button fa-solid fa-link margin0"></div>
|
||||
</div>
|
||||
<label for="translation_target_language">Target Language</label>
|
||||
<select id="translation_target_language" name="target_language"></select>
|
||||
<div id="translation_clear" class="menu_button">
|
||||
<i class="fa-solid fa-trash-can"></i>
|
||||
<span>Clear Translations</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
jQuery(async() => {
|
||||
const html = await renderTemplateAsync('translateIndex');
|
||||
|
||||
const buttonHtml = `
|
||||
<div id="translate_chat" class="list-group-item flex-container flexGap5">
|
||||
<div class="fa-solid fa-language extensionsMenuExtensionButton" /></div>
|
||||
Translate Chat
|
||||
</div>
|
||||
<div id="translate_input_message" class="list-group-item flex-container flexGap5">
|
||||
<div class="fa-solid fa-keyboard extensionsMenuExtensionButton" /></div>
|
||||
Translate Input
|
||||
</div>
|
||||
`;
|
||||
const buttonHtml = await renderTemplateAsync('translateButtons');
|
||||
$('#extensionsMenu').append(buttonHtml);
|
||||
$('#extensions_settings2').append(html);
|
||||
$('#translate_chat').on('click', onTranslateChatClick);
|
||||
@@ -624,7 +609,7 @@ jQuery(() => {
|
||||
'libre': 'http://127.0.0.1:5000/translate',
|
||||
'lingva': 'https://lingva.ml/api/v1',
|
||||
'oneringtranslator': 'http://127.0.0.1:4990/translate',
|
||||
'deeplx': 'http://127.0.0.1:1188/translate',
|
||||
'deeplx': 'http://127.0.0.1:1188/translate'
|
||||
};
|
||||
const popupText = `<h3>${optionText} API URL</h3><i>Example: <tt>${String(exampleURLs[extension_settings.translate.provider])}</tt></i>`;
|
||||
|
||||
|
@@ -19,6 +19,8 @@ class SBVits2TtsProvider {
|
||||
* @returns {string} Processed text
|
||||
*/
|
||||
processText(text) {
|
||||
// backup for auto_split
|
||||
text = text.replace(/\n+/g, '<br>');
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -276,6 +278,8 @@ class SBVits2TtsProvider {
|
||||
|
||||
const [model_id, speaker_id, style] = voiceId.split('-');
|
||||
const params = new URLSearchParams();
|
||||
// restore for auto_split
|
||||
inputText = inputText.replaceAll('<br>', '\n');
|
||||
params.append('text', inputText);
|
||||
params.append('model_id', model_id);
|
||||
params.append('speaker_id', speaker_id);
|
||||
|
Reference in New Issue
Block a user