Merge pull request #3955 from SillyTavern/pin-styles Add style pin feature for greeting messages
Signed| @@ -4778,6 +4778,10 @@ | ||
| 4778 | 4778 | <input id="show_group_chat_queue" type="checkbox" /> |
| 4779 | 4779 | <small data-i18n="Show group chat queue">Show group chat queue</small> |
| 4780 | 4780 | </label> |
| 4781 | + <label class="checkbox_label" for="pin_styles" title="Always render style tags from greetings, even if the message is unloaded due to lazy loading." data-i18n="[title]Always render style tags from greetings, even if the message is unloaded due to lazy loading."> | |
| 4782 | + <input id="pin_styles" type="checkbox" /> | |
| 4783 | + <small data-i18n="Pin greeting message styles">Pin greeting message styles</small> | |
| 4784 | + </label> | |
| 4781 | 4785 | <div class="inline-drawer wide100p flexFlowColumn"> |
| 4782 | 4786 | <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically reject and re-generate AI message based on configurable criteria." data-i18n="[title]Automatically reject and re-generate AI message based on configurable criteria"> |
| 4783 | 4787 | <b><span data-i18n="Auto-swipe">Auto-swipe</span></b> |
| @@ -97,6 +97,7 @@ import { | ||
| 97 | 97 | forceCharacterEditorTokenize, |
| 98 | 98 | applyPowerUserSettings, |
| 99 | 99 | generatedTextFiltered, |
| 100 | + applyStylePins, | |
| 100 | 101 | } from './scripts/power-user.js'; |
| 101 | 102 | |
| 102 | 103 | import { |
| @@ -1920,6 +1921,7 @@ export async function showMoreMessages(messagesToLoad = null) { | ||
| 1920 | 1921 | $('#chat').scrollTop(newHeight - prevHeight); |
| 1921 | 1922 | } |
| 1922 | 1923 | |
| 1924 | + applyStylePins(); | |
| 1923 | 1925 | await eventSource.emit(event_types.MORE_MESSAGES_LOADED); |
| 1924 | 1926 | } |
| 1925 | 1927 | |
| @@ -1957,6 +1959,7 @@ export async function printMessages() { | ||
| 1957 | 1959 | hideSwipeButtons(); |
| 1958 | 1960 | showSwipeButtons(); |
| 1959 | 1961 | scrollChatToBottom(); |
| 1962 | + applyStylePins(); | |
| 1960 | 1963 | |
| 1961 | 1964 | function incrementAndCheck() { |
| 1962 | 1965 | imagesLoaded++; |
| @@ -25,6 +25,7 @@ import { | ||
| 25 | 25 | setActiveCharacter, |
| 26 | 26 | entitiesFilter, |
| 27 | 27 | doNewChat, |
| 28 | + messageFormatting, | |
| 28 | 29 | } from '../script.js'; |
| 29 | 30 | import { isMobile, initMovingUI, favsToHotswap } from './RossAscends-mods.js'; |
| 30 | 31 | import { |
| @@ -318,6 +319,7 @@ let power_user = { | ||
| 318 | 319 | forbid_external_media: true, |
| 319 | 320 | external_media_allowed_overrides: [], |
| 320 | 321 | external_media_forbidden_overrides: [], |
| 322 | + pin_styles: true, | |
| 321 | 323 | }; |
| 322 | 324 | |
| 323 | 325 | let themes = []; |
| @@ -1390,6 +1392,50 @@ function applyPowerUserSettings() { | ||
| 1390 | 1392 | switchSwipeNumAllMessages(); |
| 1391 | 1393 | } |
| 1392 | 1394 | |
| 1395 | +export function applyStylePins() { | |
| 1396 | + try { | |
| 1397 | + const existingPins = document.querySelector('#chat > .style-pins'); | |
| 1398 | + if (existingPins) { | |
| 1399 | + existingPins.remove(); | |
| 1400 | + } | |
| 1401 | + | |
| 1402 | + if (!power_user.pin_styles) { | |
| 1403 | + return; | |
| 1404 | + } | |
| 1405 | + | |
| 1406 | + const firstDisplayed = getFirstDisplayedMessageId(); | |
| 1407 | + if (firstDisplayed === 0 || !isFinite(firstDisplayed)) { | |
| 1408 | + return; | |
| 1409 | + } | |
| 1410 | + | |
| 1411 | + const chatElement = document.getElementById('chat'); | |
| 1412 | + if (!chatElement) { | |
| 1413 | + return; | |
| 1414 | + } | |
| 1415 | + | |
| 1416 | + const firstMessage = chat[0]; | |
| 1417 | + if (!firstMessage) { | |
| 1418 | + return; | |
| 1419 | + } | |
| 1420 | + | |
| 1421 | + const formattedMessage = messageFormatting(firstMessage.mes, firstMessage.name, firstMessage.is_system, firstMessage.is_user, 0, {}, false); | |
| 1422 | + const htmlElement = document.createElement('div'); | |
| 1423 | + htmlElement.innerHTML = formattedMessage; | |
| 1424 | + | |
| 1425 | + const styleTags = htmlElement.querySelectorAll('style'); | |
| 1426 | + if (styleTags.length === 0) { | |
| 1427 | + return; | |
| 1428 | + } | |
| 1429 | + | |
| 1430 | + const pinsElement = document.createElement('div'); | |
| 1431 | + pinsElement.classList.add('style-pins'); | |
| 1432 | + pinsElement.append(...Array.from(styleTags)); | |
| 1433 | + chatElement.prepend(pinsElement); | |
| 1434 | + } catch (error) { | |
| 1435 | + console.error('Error applying style pins:', error); | |
| 1436 | + } | |
| 1437 | +} | |
| 1438 | + | |
| 1393 | 1439 | function getExampleMessagesBehavior() { |
| 1394 | 1440 | if (power_user.strip_examples) { |
| 1395 | 1441 | return 'strip'; |
| @@ -1600,6 +1646,7 @@ async function loadPowerUserSettings(settings, data) { | ||
| 1600 | 1646 | $('#auto-connect-checkbox').prop('checked', power_user.auto_connect); |
| 1601 | 1647 | $('#auto-load-chat-checkbox').prop('checked', power_user.auto_load_chat); |
| 1602 | 1648 | $('#forbid_external_media').prop('checked', power_user.forbid_external_media); |
| 1649 | + $('#pin_styles').prop('checked', power_user.pin_styles); | |
| 1603 | 1650 | |
| 1604 | 1651 | for (const theme of themes) { |
| 1605 | 1652 | const option = document.createElement('option'); |
| @@ -3876,6 +3923,12 @@ $(document).ready(() => { | ||
| 3876 | 3923 | reloadCurrentChat(); |
| 3877 | 3924 | }); |
| 3878 | 3925 | |
| 3926 | + $('#pin_styles').on('input', function () { | |
| 3927 | + power_user.pin_styles = !!$(this).prop('checked'); | |
| 3928 | + saveSettingsDebounced(); | |
| 3929 | + applyStylePins(); | |
| 3930 | + }); | |
| 3931 | + | |
| 3879 | 3932 | $('#ui_preset_import_button').on('click', function () { |
| 3880 | 3933 | $('#ui_preset_import_file').trigger('click'); |
| 3881 | 3934 | }); |
| @@ -4227,7 +4280,7 @@ $(document).ready(() => { | ||
| 4227 | 4280 | enumList: commonEnumProviders.boolean('trueFalse')(), |
| 4228 | 4281 | }), |
| 4229 | 4282 | ], |
| 4230 | 4283 | unnamedArgumentList: [ |
| 4231 | 4284 | SlashCommandArgument.fromProps({ |
| 4232 | 4285 | description: 'value', |
| 4233 | 4286 | typeList: [ARGUMENT_TYPE.STRING], |
| @@ -1205,6 +1205,17 @@ body .panelControlBar { | ||
| 1205 | 1205 | background-color: rgb(102, 0, 0); |
| 1206 | 1206 | } |
| 1207 | 1207 | |
| 1208 | +#chat .style-pins { | |
| 1209 | + visibility: hidden; | |
| 1210 | + position: fixed; | |
| 1211 | + left: -9999px; | |
| 1212 | + top: -9999px; | |
| 1213 | + width: 0; | |
| 1214 | + height: 0; | |
| 1215 | + opacity: 0; | |
| 1216 | + pointer-events: none; | |
| 1217 | +} | |
| 1218 | + | |
| 1208 | 1219 | .mes q:before, |
| 1209 | 1220 | .mes q:after { |
| 1210 | 1221 | content: ''; |