2023-07-20 19:32:15 +02:00
import {
saveSettingsDebounced ,
scrollChatToBottom ,
characters ,
reloadMarkdownProcessor ,
reloadCurrentChat ,
getRequestHeaders ,
substituteParams ,
eventSource ,
event _types ,
getCurrentChatId ,
2024-03-30 03:06:40 +01:00
printCharactersDebounced ,
2023-07-20 19:32:15 +02:00
setCharacterId ,
2023-08-27 22:20:43 +02:00
setEditedMessageId ,
2023-11-08 22:04:32 +01:00
chat ,
getFirstDisplayedMessageId ,
showMoreMessages ,
2023-12-06 16:23:54 +01:00
saveSettings ,
saveChatConditional ,
2023-12-10 19:02:25 +01:00
setAnimationDuration ,
ANIMATION _DURATION _DEFAULT ,
2024-03-26 17:30:12 +01:00
setActiveGroup ,
setActiveCharacter ,
2024-04-30 04:30:39 +02:00
entitiesFilter ,
2024-06-27 01:39:05 +02:00
doNewChat ,
2023-12-02 19:04:51 +01:00
} from '../script.js' ;
import { isMobile , initMovingUI , favsToHotswap } from './RossAscends-mods.js' ;
2023-07-20 19:32:15 +02:00
import {
groups ,
resetSelectedGroup ,
2023-12-02 19:04:51 +01:00
} from './group-chats.js' ;
2023-08-23 20:17:45 +02:00
import {
instruct _presets ,
loadInstructMode ,
selectInstructPreset ,
2023-12-02 19:04:51 +01:00
} from './instruct-mode.js' ;
2023-07-20 19:32:15 +02:00
2024-06-22 05:03:05 +02:00
import { getTagsList , tag _import _setting , tag _map , tags } from './tags.js' ;
2023-12-02 19:04:51 +01:00
import { tokenizers } from './tokenizers.js' ;
2023-12-18 21:38:28 +01:00
import { BIAS _CACHE } from './logit-bias.js' ;
2024-04-11 21:39:42 +02:00
import { renderTemplateAsync } from './templates.js' ;
2023-07-20 19:32:15 +02:00
2024-07-03 20:32:05 +02:00
import { countOccurrences , debounce , delay , download , getFileText , getStringHash , isOdd , isTrueBoolean , onlyUnique , resetScrollHeight , shuffle , sortMoments , stringToRange , timestampToMoment } from './utils.js' ;
2024-04-30 04:30:39 +02:00
import { FILTER _TYPES } from './filters.js' ;
2024-05-12 21:15:05 +02:00
import { PARSER _FLAG , SlashCommandParser } from './slash-commands/SlashCommandParser.js' ;
import { SlashCommand } from './slash-commands/SlashCommand.js' ;
2024-06-27 01:39:05 +02:00
import { ARGUMENT _TYPE , SlashCommandArgument , SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js' ;
2024-07-19 13:41:57 +02:00
import { AUTOCOMPLETE _SELECT _KEY , AUTOCOMPLETE _WIDTH } from './autocomplete/AutoComplete.js' ;
2024-06-20 20:33:45 +02:00
import { SlashCommandEnumValue , enumTypes } from './slash-commands/SlashCommandEnumValue.js' ;
2024-06-21 20:04:55 +02:00
import { commonEnumProviders , enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js' ;
2024-06-25 23:15:16 +02:00
import { POPUP _TYPE , callGenericPopup } from './popup.js' ;
2023-07-20 19:32:15 +02:00
export {
loadPowerUserSettings ,
loadMovingUIState ,
collapseNewlines ,
playMessageSound ,
2023-08-18 22:13:15 +02:00
sortEntitiesList ,
2023-07-20 19:32:15 +02:00
fixMarkdown ,
power _user ,
send _on _enter _options ,
2023-10-20 07:56:17 +02:00
getContextSettings ,
2024-08-23 18:49:00 +02:00
applyPowerUserSettings ,
2023-07-20 19:32:15 +02:00
} ;
2023-10-26 06:20:47 +02:00
export const MAX _CONTEXT _DEFAULT = 8192 ;
2023-12-03 17:30:21 +01:00
export const MAX _RESPONSE _DEFAULT = 2048 ;
const MAX _CONTEXT _UNLOCKED = 200 * 1024 ;
const MAX _RESPONSE _UNLOCKED = 16 * 1024 ;
2023-12-03 13:02:38 +01:00
const unlockedMaxContextStep = 512 ;
2023-10-27 12:22:46 +02:00
const maxContextMin = 512 ;
2023-12-15 18:45:42 +01:00
const maxContextStep = 64 ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
const defaultStoryString = '{{#if system}}{{system}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}\'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}' ;
2023-08-17 21:47:34 +02:00
const defaultExampleSeparator = '***' ;
const defaultChatStart = '***' ;
2023-07-20 19:32:15 +02:00
const avatar _styles = {
ROUND : 0 ,
RECTANGULAR : 1 ,
2023-11-26 14:27:54 +01:00
SQUARE : 2 ,
2023-12-02 20:11:06 +01:00
} ;
2023-07-20 19:32:15 +02:00
export const chat _styles = {
DEFAULT : 0 ,
BUBBLES : 1 ,
DOCUMENT : 2 ,
2023-12-02 20:11:06 +01:00
} ;
2023-07-20 19:32:15 +02:00
const send _on _enter _options = {
DISABLED : - 1 ,
AUTO : 0 ,
ENABLED : 1 ,
2023-12-02 20:11:06 +01:00
} ;
2023-07-20 19:32:15 +02:00
export const persona _description _positions = {
2023-08-28 23:09:41 +02:00
IN _PROMPT : 0 ,
/ * *
* @ deprecated Use persona _description _positions . IN _PROMPT instead .
* /
2023-07-20 19:32:15 +02:00
AFTER _CHAR : 1 ,
TOP _AN : 2 ,
BOTTOM _AN : 3 ,
2024-05-21 00:57:04 +02:00
AT _DEPTH : 4 ,
2024-08-28 20:08:32 +02:00
NONE : 9 ,
2023-12-02 20:11:06 +01:00
} ;
2023-07-20 19:32:15 +02:00
let power _user = {
2023-08-04 13:17:05 +02:00
tokenizer : tokenizers . BEST _MATCH ,
2023-07-20 19:32:15 +02:00
token _padding : 64 ,
collapse _newlines : false ,
pin _examples : false ,
2023-08-19 18:25:07 +02:00
strip _examples : false ,
2023-07-20 19:32:15 +02:00
trim _sentences : false ,
include _newline : false ,
always _force _name2 : false ,
user _prompt _bias : '' ,
show _user _prompt _bias : true ,
2023-09-15 20:34:41 +02:00
auto _continue : {
enabled : false ,
allow _chat _completions : false ,
target _length : 400 ,
} ,
2023-07-20 19:32:15 +02:00
markdown _escape _strings : '' ,
2023-11-19 20:57:54 +01:00
chat _truncation : 100 ,
2023-12-12 21:11:23 +01:00
streaming _fps : 30 ,
2024-04-02 13:56:15 +02:00
smooth _streaming : false ,
2024-04-02 21:52:51 +02:00
smooth _streaming _speed : 50 ,
2023-07-20 19:32:15 +02:00
fast _ui _mode : true ,
avatar _style : avatar _styles . ROUND ,
chat _display : chat _styles . DEFAULT ,
chat _width : 50 ,
never _resize _avatars : false ,
show _card _avatar _urls : false ,
play _message _sound : false ,
play _sound _unfocused : true ,
auto _save _msg _edits : false ,
confirm _message _delete : true ,
sort _field : 'name' ,
sort _order : 'asc' ,
sort _rule : null ,
font _scale : 1 ,
blur _strength : 10 ,
shadow _width : 2 ,
main _text _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeBodyColor' ) . trim ( ) } ` ,
italics _text _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeEmColor' ) . trim ( ) } ` ,
2024-03-01 06:33:37 +01:00
underline _text _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeUnderlineColor' ) . trim ( ) } ` ,
2023-07-20 19:32:15 +02:00
quote _text _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeQuoteColor' ) . trim ( ) } ` ,
blur _tint _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeBlurTintColor' ) . trim ( ) } ` ,
2023-09-22 09:54:51 +02:00
chat _tint _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeChatTintColor' ) . trim ( ) } ` ,
2023-07-20 19:32:15 +02:00
user _mes _blur _tint _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeUserMesBlurTintColor' ) . trim ( ) } ` ,
bot _mes _blur _tint _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeBotMesBlurTintColor' ) . trim ( ) } ` ,
shadow _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeShadowColor' ) . trim ( ) } ` ,
2023-09-16 08:42:26 +02:00
border _color : ` ${ getComputedStyle ( document . documentElement ) . getPropertyValue ( '--SmartThemeBorderColor' ) . trim ( ) } ` ,
2023-09-22 20:13:58 +02:00
custom _css : '' ,
2023-07-20 19:32:15 +02:00
waifuMode : false ,
movingUI : false ,
movingUIState : { } ,
movingUIPreset : '' ,
noShadows : false ,
theme : 'Default (Dark) 1.7.1' ,
2023-10-23 03:54:17 +02:00
gestures : true ,
2023-07-20 19:32:15 +02:00
auto _swipe : false ,
auto _swipe _minimum _length : 0 ,
auto _swipe _blacklist : [ ] ,
auto _swipe _blacklist _threshold : 2 ,
auto _scroll _chat _to _bottom : true ,
auto _fix _generated _markdown : true ,
send _on _enter : send _on _enter _options . AUTO ,
console _log _prompts : false ,
2024-01-23 06:00:31 +01:00
request _token _probabilities : false ,
2024-07-04 15:52:56 +02:00
show _group _chat _queue : false ,
2023-07-20 19:32:15 +02:00
render _formulas : false ,
allow _name1 _display : false ,
allow _name2 _display : false ,
hotswap _enabled : true ,
timer _enabled : true ,
timestamps _enabled : true ,
2023-08-14 00:43:16 +02:00
timestamp _model _icon : false ,
2023-07-20 19:32:15 +02:00
mesIDDisplay _enabled : false ,
2024-04-25 05:51:56 +02:00
hideChatAvatars _enabled : false ,
2023-07-20 19:32:15 +02:00
max _context _unlocked : false ,
2023-08-31 16:10:01 +02:00
message _token _count _enabled : false ,
2023-09-14 14:23:51 +02:00
expand _message _actions : false ,
2023-11-04 21:47:53 +01:00
enableZenSliders : false ,
2023-11-10 08:17:38 +01:00
enableLabMode : false ,
2023-07-20 19:32:15 +02:00
prefer _character _prompt : true ,
prefer _character _jailbreak : true ,
2023-08-24 00:37:44 +02:00
quick _continue : false ,
2024-08-02 14:17:29 +02:00
quick _impersonate : false ,
2023-08-24 14:13:04 +02:00
continue _on _send : false ,
2023-07-20 19:32:15 +02:00
trim _spaces : true ,
2023-08-04 22:49:55 +02:00
relaxed _api _urls : false ,
2023-10-10 17:08:08 +02:00
world _import _dialog : true ,
2024-08-18 03:38:07 +02:00
enable _auto _select _input : false ,
2024-06-22 05:03:05 +02:00
tag _import _setting : tag _import _setting . ASK ,
2023-08-30 15:31:53 +02:00
disable _group _trimming : false ,
2023-10-27 20:02:03 +02:00
single _line : false ,
2023-07-20 19:32:15 +02:00
2023-08-19 19:18:39 +02:00
default _instruct : '' ,
2023-07-20 19:32:15 +02:00
instruct : {
enabled : false ,
2023-12-02 19:04:51 +01:00
preset : 'Alpaca' ,
system _prompt : 'Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\nWrite {{char}}\'s next reply in a fictional roleplay chat between {{user}} and {{char}}.\n' ,
input _sequence : '### Instruction:' ,
2024-03-27 22:40:10 +01:00
input _suffix : '' ,
2023-12-02 19:04:51 +01:00
output _sequence : '### Response:' ,
2024-03-27 22:40:10 +01:00
output _suffix : '' ,
system _sequence : '' ,
system _suffix : '' ,
2024-04-04 21:27:08 +02:00
last _system _sequence : '' ,
2023-12-02 19:04:51 +01:00
first _output _sequence : '' ,
last _output _sequence : '' ,
system _sequence _prefix : '' ,
system _sequence _suffix : '' ,
stop _sequence : '' ,
2023-07-20 19:32:15 +02:00
wrap : true ,
2023-08-25 22:34:08 +02:00
macro : true ,
2023-07-20 19:32:15 +02:00
names : false ,
2023-08-08 16:11:38 +02:00
names _force _groups : true ,
2023-12-02 19:04:51 +01:00
activation _regex : '' ,
2023-12-21 14:12:30 +01:00
bind _to _context : false ,
2024-03-27 22:40:10 +01:00
user _alignment _message : '' ,
2024-03-27 23:52:20 +01:00
system _same _as _user : false ,
2024-03-27 22:40:10 +01:00
/** @deprecated Use output_suffix instead */
separator _sequence : '' ,
2023-07-20 19:32:15 +02:00
} ,
2023-08-26 12:09:47 +02:00
default _context : 'Default' ,
2023-08-17 21:47:34 +02:00
context : {
preset : 'Default' ,
story _string : defaultStoryString ,
chat _start : defaultChatStart ,
example _separator : defaultExampleSeparator ,
2023-12-01 22:06:37 +01:00
use _stop _strings : true ,
2024-03-12 22:22:29 +01:00
allow _jailbreak : false ,
2024-07-28 21:22:36 +02:00
names _as _stop _strings : true ,
2023-08-17 21:47:34 +02:00
} ,
2023-07-20 19:32:15 +02:00
personas : { } ,
default _persona : null ,
persona _descriptions : { } ,
persona _description : '' ,
2023-08-28 23:09:41 +02:00
persona _description _position : persona _description _positions . IN _PROMPT ,
2024-05-21 00:57:04 +02:00
persona _description _role : 0 ,
persona _description _depth : 2 ,
2023-08-03 13:24:45 +02:00
persona _show _notifications : true ,
2024-02-02 03:07:51 +01:00
persona _sort _order : 'asc' ,
2023-07-20 19:32:15 +02:00
custom _stopping _strings : '' ,
2023-08-04 16:53:49 +02:00
custom _stopping _strings _macro : true ,
2023-07-27 23:38:43 +02:00
fuzzy _search : false ,
2023-08-10 10:47:17 +02:00
encode _tags : false ,
2023-09-08 21:44:06 +02:00
servers : [ ] ,
2023-11-10 20:56:25 +01:00
bogus _folders : false ,
2024-04-14 16:59:51 +02:00
zoomed _avatar _magnification : false ,
2024-02-19 03:15:45 +01:00
show _tag _filters : false ,
2023-11-11 17:25:43 +01:00
aux _field : 'character_version' ,
2024-05-12 21:15:05 +02:00
stscript : {
matching : 'fuzzy' ,
autocomplete : {
2024-05-13 20:56:36 +02:00
autoHide : false ,
2024-05-12 21:15:05 +02:00
style : 'theme' ,
font : {
scale : 0.8 ,
} ,
width : {
left : AUTOCOMPLETE _WIDTH . CHAT ,
right : AUTOCOMPLETE _WIDTH . CHAT ,
} ,
2024-07-19 13:41:57 +02:00
select : AUTOCOMPLETE _SELECT _KEY . TAB + AUTOCOMPLETE _SELECT _KEY . ENTER ,
2024-05-12 21:15:05 +02:00
} ,
parser : {
/**@type {Object.<PARSER_FLAG,boolean>} */
flags : { } ,
} ,
} ,
2023-11-27 23:29:34 +01:00
restore _user _input : true ,
2023-12-10 19:02:25 +01:00
reduced _motion : false ,
2023-12-16 00:35:28 +01:00
compact _input _area : true ,
2024-01-05 19:27:19 +01:00
auto _connect : false ,
auto _load _chat : false ,
2024-04-20 00:11:37 +02:00
forbid _external _media : true ,
2024-04-04 23:39:54 +02:00
external _media _allowed _overrides : [ ] ,
external _media _forbidden _overrides : [ ] ,
2023-07-20 19:32:15 +02:00
} ;
let themes = [ ] ;
let movingUIPresets = [ ] ;
2023-08-23 20:17:45 +02:00
export let context _presets = [ ] ;
2023-07-20 19:32:15 +02:00
const storage _keys = {
2024-01-05 19:27:19 +01:00
auto _connect _legacy : 'AutoConnectEnabled' ,
auto _load _chat _legacy : 'AutoLoadChatEnabled' ,
2024-07-03 20:32:05 +02:00
storyStringValidationCache : 'StoryStringValidationCache' ,
2023-07-20 19:32:15 +02:00
} ;
2023-10-20 07:56:17 +02:00
const contextControls = [
// Power user context scoped settings
2023-12-02 19:04:51 +01:00
{ id : 'context_story_string' , property : 'story_string' , isCheckbox : false , isGlobalSetting : false } ,
{ id : 'context_example_separator' , property : 'example_separator' , isCheckbox : false , isGlobalSetting : false } ,
{ id : 'context_chat_start' , property : 'chat_start' , isCheckbox : false , isGlobalSetting : false } ,
{ id : 'context_use_stop_strings' , property : 'use_stop_strings' , isCheckbox : true , isGlobalSetting : false , defaultValue : false } ,
2024-03-12 22:22:29 +01:00
{ id : 'context_allow_jailbreak' , property : 'allow_jailbreak' , isCheckbox : true , isGlobalSetting : false , defaultValue : false } ,
2024-07-28 21:22:36 +02:00
{ id : 'context_names_as_stop_strings' , property : 'names_as_stop_strings' , isCheckbox : true , isGlobalSetting : false , defaultValue : true } ,
2023-10-20 07:56:17 +02:00
// Existing power user settings
2023-12-02 19:04:51 +01:00
{ id : 'always-force-name2-checkbox' , property : 'always_force_name2' , isCheckbox : true , isGlobalSetting : true , defaultValue : true } ,
{ id : 'trim_sentences_checkbox' , property : 'trim_sentences' , isCheckbox : true , isGlobalSetting : true , defaultValue : false } ,
{ id : 'include_newline_checkbox' , property : 'include_newline' , isCheckbox : true , isGlobalSetting : true , defaultValue : false } ,
{ id : 'single_line' , property : 'single_line' , isCheckbox : true , isGlobalSetting : true , defaultValue : false } ,
2023-10-20 07:56:17 +02:00
] ;
2023-07-20 19:32:15 +02:00
let browser _has _focus = true ;
2023-08-27 22:20:43 +02:00
const debug _functions = [ ] ;
2023-07-20 19:32:15 +02:00
2024-04-28 06:21:47 +02:00
const setHotswapsDebounced = debounce ( favsToHotswap ) ;
2023-09-14 14:56:01 +02:00
2023-07-20 19:32:15 +02:00
function playMessageSound ( ) {
if ( ! power _user . play _message _sound ) {
return ;
}
if ( power _user . play _sound _unfocused && browser _has _focus ) {
return ;
}
const audio = document . getElementById ( 'audio_message_sound' ) ;
2023-08-22 12:07:24 +02:00
if ( audio instanceof HTMLAudioElement ) {
audio . volume = 0.8 ;
audio . pause ( ) ;
audio . currentTime = 0 ;
audio . play ( ) ;
}
2023-07-20 19:32:15 +02:00
}
2023-08-22 12:07:24 +02:00
/ * *
* Replaces consecutive newlines with a single newline .
* @ param { string } x String to be processed .
* @ returns { string } Processed string .
* @ example
* collapseNewlines ( "\n\n\n" ) ; // "\n"
* /
2023-07-20 19:32:15 +02:00
function collapseNewlines ( x ) {
2023-12-02 19:04:51 +01:00
return x . replaceAll ( /\n+/g , '\n' ) ;
2023-07-20 19:32:15 +02:00
}
2023-08-22 12:07:24 +02:00
/ * *
* Fix formatting problems in markdown .
* @ param { string } text Text to be processed .
2023-08-31 13:39:31 +02:00
* @ param { boolean } forDisplay Whether the text is being processed for display .
2023-08-22 12:07:24 +02:00
* @ returns { string } Processed text .
* @ example
* "^example * text*\n" // "^example *text*\n"
* "^*example * text\n" // "^*example* text\n"
* "^example *text *\n" // "^example *text*\n"
* "^* example * text\n" // "^*example* text\n"
* // take note that the side you move the asterisk depends on where its pairing is
* // i.e. both of the following strings have the same broken asterisk ' * ',
* // but you move the first to the left and the second to the right, to match the non-broken asterisk
* "^example * text*\n" // "^*example * text\n"
* // and you HAVE to handle the cases where multiple pairs of asterisks exist in the same line
* "^example * text* * harder problem *\n" // "^example *text* *harder problem*\n"
* /
2023-08-31 13:39:31 +02:00
function fixMarkdown ( text , forDisplay ) {
2023-07-20 19:32:15 +02:00
// Find pairs of formatting characters and capture the text in between them
2023-12-02 16:17:31 +01:00
const format = /([*_]{1,2})([\s\S]*?)\1/gm ;
2023-07-20 19:32:15 +02:00
let matches = [ ] ;
let match ;
while ( ( match = format . exec ( text ) ) !== null ) {
matches . push ( match ) ;
}
// Iterate through the matches and replace adjacent spaces immediately beside formatting characters
let newText = text ;
for ( let i = matches . length - 1 ; i >= 0 ; i -- ) {
let matchText = matches [ i ] [ 0 ] ;
2023-07-29 00:35:36 +02:00
let replacementText = matchText . replace ( /(\*|_)([\t \u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]+)|([\t \u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]+)(\*|_)/g , '$1$4' ) ;
2023-07-20 19:32:15 +02:00
newText = newText . slice ( 0 , matches [ i ] . index ) + replacementText + newText . slice ( matches [ i ] . index + matchText . length ) ;
}
2023-08-31 13:39:31 +02:00
// Don't auto-fix asterisks if this is a message clean-up procedure.
// It botches the continue function. Apply this to display only.
if ( ! forDisplay ) {
return newText ;
}
const splitText = newText . split ( '\n' ) ;
// Fix asterisks, and quotes that are not paired
for ( let index = 0 ; index < splitText . length ; index ++ ) {
const line = splitText [ index ] ;
const charsToCheck = [ '*' , '"' ] ;
for ( const char of charsToCheck ) {
if ( line . includes ( char ) && isOdd ( countOccurrences ( line , char ) ) ) {
splitText [ index ] = line . trimEnd ( ) + char ;
}
}
}
newText = splitText . join ( '\n' ) ;
2023-07-20 19:32:15 +02:00
return newText ;
}
function switchHotswap ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'no-hotswap' , ! power _user . hotswap _enabled ) ;
$ ( '#hotswapEnabled' ) . prop ( 'checked' , power _user . hotswap _enabled ) ;
2023-07-20 19:32:15 +02:00
}
function switchTimer ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'no-timer' , ! power _user . timer _enabled ) ;
$ ( '#messageTimerEnabled' ) . prop ( 'checked' , power _user . timer _enabled ) ;
2023-07-20 19:32:15 +02:00
}
function switchTimestamps ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'no-timestamps' , ! power _user . timestamps _enabled ) ;
$ ( '#messageTimestampsEnabled' ) . prop ( 'checked' , power _user . timestamps _enabled ) ;
2023-07-20 19:32:15 +02:00
}
2023-08-14 00:43:16 +02:00
function switchIcons ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'no-modelIcons' , ! power _user . timestamp _model _icon ) ;
$ ( '#messageModelIconEnabled' ) . prop ( 'checked' , power _user . timestamp _model _icon ) ;
2023-08-14 00:43:16 +02:00
}
2023-08-31 16:10:01 +02:00
function switchTokenCount ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'no-tokenCount' , ! power _user . message _token _count _enabled ) ;
$ ( '#messageTokensEnabled' ) . prop ( 'checked' , power _user . message _token _count _enabled ) ;
2023-08-31 16:10:01 +02:00
}
2023-09-22 15:16:24 +02:00
function switchMesIDDisplay ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'no-mesIDDisplay' , ! power _user . mesIDDisplay _enabled ) ;
$ ( '#mesIDDisplayEnabled' ) . prop ( 'checked' , power _user . mesIDDisplay _enabled ) ;
2023-09-22 15:16:24 +02:00
}
2024-04-25 05:51:56 +02:00
function switchHideChatAvatars ( ) {
$ ( 'body' ) . toggleClass ( 'hideChatAvatars' , power _user . hideChatAvatars _enabled ) ;
$ ( '#hideChatAvatarsEnabled' ) . prop ( 'checked' , power _user . hideChatAvatars _enabled ) ;
}
2023-09-14 14:23:51 +02:00
function switchMessageActions ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'expandMessageActions' , power _user . expand _message _actions ) ;
$ ( '#expandMessageActions' ) . prop ( 'checked' , power _user . expand _message _actions ) ;
2023-10-21 14:41:27 +02:00
$ ( '.extraMesButtons, .extraMesButtonsHint' ) . removeAttr ( 'style' ) ;
2023-09-14 14:23:51 +02:00
}
2023-12-10 19:02:25 +01:00
function switchReducedMotion ( ) {
jQuery . fx . off = power _user . reduced _motion ;
const overrideDuration = power _user . reduced _motion ? 0 : ANIMATION _DURATION _DEFAULT ;
setAnimationDuration ( overrideDuration ) ;
$ ( '#reduced_motion' ) . prop ( 'checked' , power _user . reduced _motion ) ;
2024-03-09 23:55:34 +01:00
$ ( 'body' ) . toggleClass ( 'reduced-motion' , power _user . reduced _motion ) ;
2023-12-10 19:02:25 +01:00
}
2023-12-16 00:35:28 +01:00
function switchCompactInputArea ( ) {
$ ( '#send_form' ) . toggleClass ( 'compact' , power _user . compact _input _area ) ;
$ ( '#compact_input_area' ) . prop ( 'checked' , power _user . compact _input _area ) ;
}
2023-12-02 20:11:06 +01:00
var originalSliderValues = [ ] ;
2023-11-10 08:17:38 +01:00
async function switchLabMode ( ) {
2023-11-12 09:23:29 +01:00
/ * i f ( p o w e r _ u s e r . e n a b l e Z e n S l i d e r s & & p o w e r _ u s e r . e n a b l e L a b M o d e ) {
toastr . warning ( "Can't start Lab Mode while Zen Sliders are active" )
return
//$("#enableZenSliders").trigger('click')
}
* /
2023-12-02 20:11:06 +01:00
await delay ( 100 ) ;
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'enableLabMode' , power _user . enableLabMode ) ;
$ ( '#enableLabMode' ) . prop ( 'checked' , power _user . enableLabMode ) ;
2023-11-10 08:17:38 +01:00
if ( power _user . enableLabMode ) {
//save all original slider values into an array
2023-12-02 19:04:51 +01:00
$ ( '#advanced-ai-config-block input' ) . each ( function ( ) {
2023-12-02 20:11:06 +01:00
let id = $ ( this ) . attr ( 'id' ) ;
let min = $ ( this ) . attr ( 'min' ) ;
let max = $ ( this ) . attr ( 'max' ) ;
let step = $ ( this ) . attr ( 'step' ) ;
2023-11-10 08:17:38 +01:00
originalSliderValues . push ( { id , min , max , step } ) ;
2023-12-02 20:11:06 +01:00
} ) ;
2023-11-10 08:17:38 +01:00
//console.log(originalSliderValues)
//remove limits on all inputs and hide sliders
2023-12-02 19:04:51 +01:00
$ ( '#advanced-ai-config-block input' )
2023-11-10 08:17:38 +01:00
. attr ( 'min' , '-99999' )
. attr ( 'max' , '99999' )
2023-12-02 20:11:06 +01:00
. attr ( 'step' , '0.001' ) ;
$ ( '#labModeWarning' ) . removeClass ( 'displayNone' ) ;
2023-11-10 08:17:38 +01:00
//$("#advanced-ai-config-block input[type='range']").hide()
2024-02-01 07:24:35 +01:00
$ ( '#amount_gen' ) . attr ( 'min' , '1' )
. attr ( 'max' , '99999' )
. attr ( 'step' , '1' ) ;
2023-11-10 08:17:38 +01:00
} else {
//re apply the original sliders values to each input
originalSliderValues . forEach ( function ( slider ) {
2023-12-02 19:04:51 +01:00
$ ( '#' + slider . id )
2023-11-10 08:17:38 +01:00
. attr ( 'min' , slider . min )
. attr ( 'max' , slider . max )
. attr ( 'step' , slider . step )
2023-12-02 20:11:06 +01:00
. trigger ( 'input' ) ;
2023-11-10 08:17:38 +01:00
} ) ;
2023-12-02 20:11:06 +01:00
$ ( '#advanced-ai-config-block input[type=\'range\']' ) . show ( ) ;
$ ( '#labModeWarning' ) . addClass ( 'displayNone' ) ;
2024-02-01 07:24:35 +01:00
$ ( '#amount_gen' ) . attr ( 'min' , '16' )
. attr ( 'max' , '2048' )
. attr ( 'step' , '1' ) ;
2023-11-10 08:17:38 +01:00
}
}
2023-11-04 21:47:53 +01:00
async function switchZenSliders ( ) {
2023-12-02 20:11:06 +01:00
await delay ( 100 ) ;
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'enableZenSliders' , power _user . enableZenSliders ) ;
$ ( '#enableZenSliders' ) . prop ( 'checked' , power _user . enableZenSliders ) ;
2023-11-04 21:47:53 +01:00
if ( power _user . enableZenSliders ) {
2023-12-02 20:11:06 +01:00
$ ( '#clickSlidersTips' ) . hide ( ) ;
2023-12-02 19:04:51 +01:00
$ ( '#pro-settings-block input[type=\'number\']' ) . hide ( ) ;
2023-11-09 10:31:44 +01:00
//hide number inputs that are not 'seed' inputs
2024-01-04 03:52:42 +01:00
$ ( ` #textgenerationwebui_api-settings :input[type='number']:not([id^='seed']):not([id^='n_']),
2023-12-02 20:11:06 +01:00
# kobold _api - settings : input [ type = 'number' ] : not ( [ id ^= 'seed' ] ) ` ).hide();
2023-11-09 10:31:44 +01:00
//hide original sliders
2023-11-05 22:42:13 +01:00
$ ( ` #textgenerationwebui_api-settings input[type='range'],
2023-11-09 10:31:44 +01:00
# kobold _api - settings input [ type = 'range' ] ,
2023-11-29 03:37:18 +01:00
# pro - settings - block input [ type = 'range' ] : not ( # max _context ) ` ) //exclude max context because its creation is handled by switchMaxContext()
2023-11-05 22:42:13 +01:00
. hide ( )
. each ( function ( ) {
2023-11-09 10:31:44 +01:00
//make a zen slider for each original slider
2023-12-02 20:11:06 +01:00
CreateZenSliders ( $ ( this ) ) ;
} ) ;
2023-11-15 10:58:47 +01:00
//this is for when zensliders is toggled after pageload
2023-12-02 20:11:06 +01:00
switchMaxContextSize ( ) ;
2023-11-04 21:47:53 +01:00
} else {
2023-12-02 20:11:06 +01:00
$ ( '#clickSlidersTips' ) . show ( ) ;
2023-11-04 21:47:53 +01:00
revertOriginalSliders ( ) ;
}
2023-11-09 10:31:44 +01:00
function revertOriginalSliders ( ) {
2023-12-02 19:04:51 +01:00
$ ( '#pro-settings-block input[type=\'number\']' ) . show ( ) ;
2023-11-09 10:31:44 +01:00
$ ( ` #textgenerationwebui_api-settings input[type='number'],
# kobold _api - settings input [ type = 'number' ] ` ).show();
$ ( ` #textgenerationwebui_api-settings input[type='range'],
# kobold _api - settings input [ type = 'range' ] ,
# pro - settings - block input [ type = 'range' ] ` ).each(function () {
$ ( this ) . show ( ) ;
} ) ;
$ ( 'div[id$="_zenslider"]' ) . remove ( ) ;
}
2023-11-15 10:58:47 +01:00
}
async function CreateZenSliders ( elmnt ) {
var originalSlider = elmnt ;
2023-12-02 20:11:06 +01:00
var sliderID = originalSlider . attr ( 'id' ) ;
var sliderMin = Number ( originalSlider . attr ( 'min' ) ) ;
var sliderMax = Number ( originalSlider . attr ( 'max' ) ) ;
2023-11-15 10:58:47 +01:00
var sliderValue = originalSlider . val ( ) ;
2023-12-02 20:11:06 +01:00
var sliderRange = sliderMax - sliderMin ;
2023-12-15 23:01:05 +01:00
var numSteps = 20 ;
2023-12-02 20:11:06 +01:00
var decimals = 2 ;
var offVal , allVal ;
var stepScale ;
var steps ;
2023-11-15 10:58:47 +01:00
if ( sliderID == 'amount_gen' ) {
2023-12-02 20:11:06 +01:00
decimals = 0 ;
2023-12-02 16:57:53 +01:00
steps = [ 16 , 50 , 100 , 150 , 200 , 256 , 300 , 400 , 512 , 1024 ] ;
2023-12-02 20:11:06 +01:00
sliderMin = 0 ;
sliderMax = steps . length - 1 ;
2023-11-15 10:58:47 +01:00
stepScale = 1 ;
2023-12-02 20:11:06 +01:00
numSteps = 10 ;
sliderValue = steps . indexOf ( Number ( sliderValue ) ) ;
if ( sliderValue === - 1 ) { sliderValue = 4 ; } // default to '200' if origSlider has value we can't use
2023-11-15 10:58:47 +01:00
}
2023-11-28 19:35:02 +01:00
if ( sliderID == 'rep_pen_range_textgenerationwebui' ) {
if ( power _user . max _context _unlocked ) {
2023-12-02 16:57:53 +01:00
steps = [ 0 , 256 , 512 , 768 , 1024 , 2048 , 4096 , 8192 , 16355 , 24576 , 32768 , 49152 , 65536 , - 1 ] ;
2023-12-02 20:11:06 +01:00
numSteps = 13 ;
allVal = 13 ;
2023-11-28 19:35:02 +01:00
} else {
2023-12-02 16:57:53 +01:00
steps = [ 0 , 256 , 512 , 768 , 1024 , 2048 , 4096 , 8192 , - 1 ] ;
2023-12-02 20:11:06 +01:00
numSteps = 8 ;
allVal = 8 ;
2023-11-28 19:35:02 +01:00
}
2023-12-02 20:11:06 +01:00
decimals = 0 ;
offVal = 0 ;
sliderMin = 0 ;
sliderMax = steps . length - 1 ;
2023-11-28 19:35:02 +01:00
stepScale = 1 ;
2023-12-02 20:11:06 +01:00
sliderValue = steps . indexOf ( Number ( sliderValue ) ) ;
if ( sliderValue === - 1 ) { sliderValue = allVal ; } // default to allValue if origSlider has value we can't use
2023-11-28 19:35:02 +01:00
}
2023-11-15 10:58:47 +01:00
//customize decimals
if ( sliderID == 'max_context' ||
sliderID == 'mirostat_mode_textgenerationwebui' ||
sliderID == 'mirostat_tau_textgenerationwebui' ||
sliderID == 'top_k_textgenerationwebui' ||
sliderID == 'num_beams_textgenerationwebui' ||
sliderID == 'no_repeat_ngram_size_textgenerationwebui' ||
sliderID == 'min_length_textgenerationwebui' ||
sliderID == 'top_k' ||
sliderID == 'mirostat_mode_kobold' ||
2024-02-29 00:55:25 +01:00
sliderID == 'rep_pen_range' ||
2024-05-22 19:46:52 +02:00
sliderID == 'dry_allowed_length_textgenerationwebui' ||
2024-05-22 22:37:51 +02:00
sliderID == 'rep_pen_decay_textgenerationwebui' ||
2024-05-22 19:46:52 +02:00
sliderID == 'dry_penalty_last_n_textgenerationwebui' ||
2024-02-29 00:55:25 +01:00
sliderID == 'max_tokens_second_textgenerationwebui' ) {
2023-12-02 20:11:06 +01:00
decimals = 0 ;
2023-11-15 10:58:47 +01:00
}
2024-01-09 04:20:27 +01:00
if ( sliderID == 'min_temp_textgenerationwebui' ||
2024-01-28 21:14:21 +01:00
sliderID == 'max_temp_textgenerationwebui' ||
sliderID == 'dynatemp_exponent_textgenerationwebui' ||
2024-03-01 07:06:34 +01:00
sliderID == 'smoothing_curve_textgenerationwebui' ||
2024-05-22 19:46:52 +02:00
sliderID == 'smoothing_factor_textgenerationwebui' ||
sliderID == 'dry_multiplier_textgenerationwebui' ||
sliderID == 'dry_base_textgenerationwebui' ) {
2024-01-05 08:08:44 +01:00
decimals = 2 ;
}
2023-11-15 10:58:47 +01:00
if ( sliderID == 'eta_cutoff_textgenerationwebui' ||
sliderID == 'epsilon_cutoff_textgenerationwebui' ) {
2023-12-02 20:11:06 +01:00
numSteps = 50 ;
decimals = 1 ;
2023-11-15 10:58:47 +01:00
}
//customize steps
if ( sliderID == 'mirostat_mode_textgenerationwebui' ||
sliderID == 'mirostat_mode_kobold' ) {
2023-12-02 20:11:06 +01:00
numSteps = 2 ;
2023-11-15 10:58:47 +01:00
}
if ( sliderID == 'encoder_rep_pen_textgenerationwebui' ) {
2023-12-02 20:11:06 +01:00
numSteps = 14 ;
2023-11-15 10:58:47 +01:00
}
if ( sliderID == 'max_context' ) {
2023-12-02 20:11:06 +01:00
numSteps = 15 ;
2023-11-15 10:58:47 +01:00
}
if ( sliderID == 'mirostat_tau_textgenerationwebui' ||
sliderID == 'top_k_textgenerationwebui' ||
sliderID == 'num_beams_textgenerationwebui' ||
sliderID == 'no_repeat_ngram_size_textgenerationwebui' ||
sliderID == 'epsilon_cutoff_textgenerationwebui' ||
sliderID == 'tfs_textgenerationwebui' ||
sliderID == 'min_p_textgenerationwebui' ||
sliderID == 'temp_textgenerationwebui' ||
2024-01-09 04:20:27 +01:00
sliderID == 'temp' ) {
2023-12-02 20:11:06 +01:00
numSteps = 20 ;
2023-11-15 10:58:47 +01:00
}
if ( sliderID == 'mirostat_eta_textgenerationwebui' ||
sliderID == 'penalty_alpha_textgenerationwebui' ||
2024-01-09 04:20:27 +01:00
sliderID == 'length_penalty_textgenerationwebui' ||
sliderID == 'min_temp_textgenerationwebui' ||
sliderID == 'max_temp_textgenerationwebui' ) {
2023-12-02 20:11:06 +01:00
numSteps = 50 ;
2023-11-15 10:58:47 +01:00
}
//customize off values
if ( sliderID == 'presence_pen_textgenerationwebui' ||
sliderID == 'freq_pen_textgenerationwebui' ||
sliderID == 'mirostat_mode_textgenerationwebui' ||
sliderID == 'mirostat_mode_kobold' ||
sliderID == 'mirostat_tau_textgenerationwebui' ||
sliderID == 'mirostat_tau_kobold' ||
sliderID == 'mirostat_eta_textgenerationwebui' ||
sliderID == 'mirostat_eta_kobold' ||
sliderID == 'min_p_textgenerationwebui' ||
sliderID == 'min_p' ||
sliderID == 'no_repeat_ngram_size_textgenerationwebui' ||
sliderID == 'penalty_alpha_textgenerationwebui' ||
sliderID == 'length_penalty_textgenerationwebui' ||
sliderID == 'epsilon_cutoff_textgenerationwebui' ||
sliderID == 'rep_pen_range' ||
sliderID == 'eta_cutoff_textgenerationwebui' ||
sliderID == 'top_a_textgenerationwebui' ||
sliderID == 'top_a' ||
sliderID == 'top_k_textgenerationwebui' ||
sliderID == 'top_k' ||
sliderID == 'rep_pen_slope' ||
2024-02-11 07:32:32 +01:00
sliderID == 'smoothing_factor_textgenerationwebui' ||
2024-03-01 07:06:34 +01:00
sliderID == 'smoothing_curve_textgenerationwebui' ||
2024-05-22 22:26:47 +02:00
sliderID == 'skew_textgenerationwebui' ||
2024-05-22 19:46:52 +02:00
sliderID == 'dry_multiplier_textgenerationwebui' ||
2023-11-15 10:58:47 +01:00
sliderID == 'min_length_textgenerationwebui' ) {
2023-12-02 20:11:06 +01:00
offVal = 0 ;
2023-11-15 10:58:47 +01:00
}
if ( sliderID == 'rep_pen_textgenerationwebui' ||
sliderID == 'rep_pen' ||
sliderID == 'tfs_textgenerationwebui' ||
sliderID == 'tfs' ||
sliderID == 'top_p_textgenerationwebui' ||
sliderID == 'top_p' ||
sliderID == 'typical_p_textgenerationwebui' ||
sliderID == 'typical_p' ||
sliderID == 'encoder_rep_pen_textgenerationwebui' ||
sliderID == 'temp_textgenerationwebui' ||
sliderID == 'temp' ||
2024-02-11 07:32:32 +01:00
sliderID == 'min_temp_textgenerationwebui' ||
sliderID == 'max_temp_textgenerationwebui' ||
sliderID == 'dynatemp_exponent_textgenerationwebui' ||
2023-11-15 10:58:47 +01:00
sliderID == 'guidance_scale_textgenerationwebui' ||
2024-06-05 21:05:41 +02:00
sliderID == 'rep_pen_slope_textgenerationwebui' ||
2023-11-15 10:58:47 +01:00
sliderID == 'guidance_scale' ) {
2023-12-02 20:11:06 +01:00
offVal = 1 ;
2023-11-15 10:58:47 +01:00
}
if ( sliderID == 'guidance_scale_textgenerationwebui' ) {
2023-12-02 20:11:06 +01:00
numSteps = 78 ;
2023-11-15 10:58:47 +01:00
}
2024-02-14 00:45:07 +01:00
if ( sliderID == 'top_k_textgenerationwebui' ) {
sliderMin = 0 ;
}
2023-11-15 10:58:47 +01:00
//customize amt gen steps
2023-11-28 19:35:02 +01:00
if ( sliderID !== 'amount_gen' && sliderID !== 'rep_pen_range_textgenerationwebui' ) {
2023-12-02 20:11:06 +01:00
stepScale = sliderRange / numSteps ;
2023-11-15 10:58:47 +01:00
}
2023-12-02 19:04:51 +01:00
var newSlider = $ ( '<div>' )
2023-11-15 10:58:47 +01:00
. attr ( 'id' , ` ${ sliderID } _zenslider ` )
2023-12-02 19:04:51 +01:00
. css ( 'width' , '100%' )
2023-11-15 10:58:47 +01:00
. insertBefore ( originalSlider ) ;
newSlider . slider ( {
value : sliderValue ,
step : stepScale ,
min : sliderMin ,
max : sliderMax ,
2023-12-03 13:59:21 +01:00
create : async function ( ) {
2023-12-04 18:32:41 +01:00
await delay ( 100 ) ;
2023-12-02 19:04:51 +01:00
var handle = $ ( this ) . find ( '.ui-slider-handle' ) ;
2023-12-02 16:57:53 +01:00
var handleText , stepNumber , leftMargin ;
2023-11-28 19:35:02 +01:00
//handling creation of amt_gen
2023-11-12 15:57:51 +01:00
if ( newSlider . attr ( 'id' ) == 'amount_gen_zenslider' ) {
2023-12-02 20:11:06 +01:00
handleText = steps [ sliderValue ] ;
stepNumber = sliderValue ;
leftMargin = ( ( stepNumber ) / numSteps ) * 50 * - 1 ;
2023-11-15 10:58:47 +01:00
handle . text ( handleText )
2023-12-02 20:11:06 +01:00
. css ( 'margin-left' , ` ${ leftMargin } px ` ) ;
2023-11-28 19:35:02 +01:00
//console.log(`${newSlider.attr('id')} initial value:${handleText}, stepNum:${stepNumber}, numSteps:${numSteps}, left-margin:${leftMargin}`)
2023-12-03 13:59:21 +01:00
}
//handling creation of rep_pen_range for ooba
else if ( newSlider . attr ( 'id' ) == 'rep_pen_range_textgenerationwebui_zenslider' ) {
2023-11-28 19:35:02 +01:00
if ( $ ( '#rep_pen_range_textgenerationwebui_zensliders' ) . length !== 0 ) {
2023-12-02 20:11:06 +01:00
$ ( '#rep_pen_range_textgenerationwebui_zensliders' ) . remove ( ) ;
2023-11-28 19:35:02 +01:00
}
2023-12-02 20:11:06 +01:00
handleText = steps [ sliderValue ] ;
stepNumber = sliderValue ;
leftMargin = ( ( stepNumber ) / numSteps ) * 50 * - 1 ;
2023-11-29 03:37:18 +01:00
if ( sliderValue === offVal ) {
2023-12-02 20:11:06 +01:00
handleText = 'Off' ;
2023-11-29 03:37:18 +01:00
handle . css ( 'color' , 'rgba(128,128,128,0.5' ) ;
}
2023-12-02 20:11:06 +01:00
else if ( sliderValue === allVal ) { handleText = 'All' ; }
2023-11-29 03:37:18 +01:00
else { handle . css ( 'color' , '' ) ; }
2023-11-28 19:35:02 +01:00
handle . text ( handleText )
2023-12-02 20:11:06 +01:00
. css ( 'margin-left' , ` ${ leftMargin } px ` ) ;
2023-11-29 03:37:18 +01:00
//console.log(sliderValue, handleText, offVal, allVal)
//console.log(`${newSlider.attr('id')} sliderValue = ${sliderValue}, handleText:${handleText}, stepNum:${stepNumber}, numSteps:${numSteps}, left-margin:${leftMargin}`)
originalSlider . val ( steps [ sliderValue ] ) ;
2023-12-03 13:59:21 +01:00
}
//create all other sliders
else {
2023-12-02 20:11:06 +01:00
var numVal = Number ( sliderValue ) . toFixed ( decimals ) ;
offVal = Number ( offVal ) . toFixed ( decimals ) ;
2023-11-15 10:58:47 +01:00
if ( numVal === offVal ) {
handle . text ( 'Off' ) . css ( 'color' , 'rgba(128,128,128,0.5' ) ;
} else {
handle . text ( numVal ) . css ( 'color' , '' ) ;
}
2023-12-02 20:11:06 +01:00
stepNumber = ( ( sliderValue - sliderMin ) / stepScale ) ;
leftMargin = ( stepNumber / numSteps ) * 50 * - 1 ;
2023-12-03 13:59:21 +01:00
originalSlider . val ( numVal )
2023-12-04 18:32:41 +01:00
. data ( 'newSlider' , newSlider ) ;
2023-12-03 13:59:21 +01:00
//console.log(`${newSlider.attr('id')} sliderValue = ${sliderValue}, handleText:${handleText, numVal}, stepNum:${stepNumber}, numSteps:${numSteps}, left-margin:${leftMargin}`)
2023-12-02 20:11:06 +01:00
var isManualInput = false ;
var valueBeforeManualInput ;
2023-11-15 10:58:47 +01:00
handle . css ( 'margin-left' , ` ${ leftMargin } px ` )
2023-11-29 03:37:18 +01:00
2023-11-15 10:58:47 +01:00
. attr ( 'contenteditable' , 'true' )
2023-12-03 13:59:21 +01:00
//these sliders need listeners for manual inputs
2023-11-15 10:58:47 +01:00
. on ( 'click' , function ( ) {
//this just selects all the text in the handle so user can overwrite easily
//needed because JQUery UI uses left/right arrow keys as well as home/end to move the slider..
2023-12-02 20:11:06 +01:00
valueBeforeManualInput = newSlider . val ( ) ;
console . log ( valueBeforeManualInput ) ;
2023-11-15 10:58:47 +01:00
let handleElement = handle . get ( 0 ) ;
let range = document . createRange ( ) ;
range . selectNodeContents ( handleElement ) ;
let selection = window . getSelection ( ) ;
selection . removeAllRanges ( ) ;
selection . addRange ( range ) ;
} )
2023-12-03 13:59:21 +01:00
. on ( 'keyup' , function ( e ) {
valueBeforeManualInput = numVal ;
//console.log(valueBeforeManualInput, numVal, handleText);
2023-12-02 20:11:06 +01:00
isManualInput = true ;
2023-12-03 13:59:21 +01:00
//allow enter to trigger slider update
if ( e . key === 'Enter' ) {
2024-04-14 23:39:15 +02:00
e . preventDefault ( ) ;
2023-12-04 18:32:41 +01:00
handle . trigger ( 'blur' ) ;
2023-12-03 13:59:21 +01:00
}
2023-11-15 10:58:47 +01:00
} )
//trigger slider changes when user clicks away
. on ( 'mouseup blur' , function ( ) {
2023-12-02 20:11:06 +01:00
let manualInput = parseFloat ( handle . text ( ) ) . toFixed ( decimals ) ;
2023-11-15 10:58:47 +01:00
if ( isManualInput ) {
//disallow manual inputs outside acceptable range
if ( manualInput >= sliderMin && manualInput <= sliderMax ) {
//if value is ok, assign to slider and update handle text and position
2023-12-02 20:11:06 +01:00
newSlider . val ( manualInput ) ;
2023-11-15 10:58:47 +01:00
handleSlideEvent . call ( newSlider , null , { value : parseFloat ( manualInput ) } , 'manual' ) ;
2023-12-02 20:11:06 +01:00
valueBeforeManualInput = manualInput ;
2023-11-15 10:58:47 +01:00
} else {
//if value not ok, warn and reset to last known valid value
2023-12-02 20:11:06 +01:00
toastr . warning ( ` Invalid value. Must be between ${ sliderMin } and ${ sliderMax } ` ) ;
console . log ( valueBeforeManualInput ) ;
newSlider . val ( valueBeforeManualInput ) ;
handle . text ( valueBeforeManualInput ) ;
2023-12-03 13:59:21 +01:00
handleSlideEvent . call ( newSlider , null , { value : parseFloat ( valueBeforeManualInput ) } , 'manual' ) ;
2023-11-15 10:58:47 +01:00
}
}
2023-12-02 20:11:06 +01:00
isManualInput = false ;
} ) ;
2023-11-12 15:57:51 +01:00
}
2023-12-03 13:59:21 +01:00
//zenSlider creation done, hide the original
originalSlider . hide ( ) ;
2023-11-15 10:58:47 +01:00
} ,
2023-12-02 21:06:57 +01:00
slide : handleSlideEvent ,
2023-11-15 10:58:47 +01:00
} ) ;
2023-11-29 03:37:18 +01:00
2023-11-15 10:58:47 +01:00
function handleSlideEvent ( event , ui , type ) {
2023-12-02 19:04:51 +01:00
var handle = $ ( this ) . find ( '.ui-slider-handle' ) ;
2023-11-15 10:58:47 +01:00
var numVal = Number ( ui . value ) . toFixed ( decimals ) ;
offVal = Number ( offVal ) . toFixed ( decimals ) ;
2023-11-29 03:37:18 +01:00
allVal = Number ( allVal ) . toFixed ( decimals ) ;
2023-12-02 20:11:06 +01:00
console . log ( numVal , sliderMin , sliderMax , numVal > sliderMax , numVal < sliderMin ) ;
2023-12-03 13:59:21 +01:00
if ( numVal > sliderMax ) { numVal = sliderMax ; }
if ( numVal < sliderMin ) { numVal = sliderMin ; }
2023-11-15 10:58:47 +01:00
var stepNumber = ( ( ui . value - sliderMin ) / stepScale ) . toFixed ( 0 ) ;
var handleText = ( ui . value ) ;
var leftMargin = ( stepNumber / numSteps ) * 50 * - 1 ;
2023-12-02 20:11:06 +01:00
var perStepPercent = 1 / numSteps ; //how far in % each step should be on the slider
var leftPos = newSlider . width ( ) * ( stepNumber * perStepPercent ) ; //how big of a left margin to give the slider for manual inputs
2023-11-29 03:37:18 +01:00
/ * c o n s o l e . l o g ( `
numVal : $ { numVal } ,
sliderMax : $ { sliderMax }
sliderMin : $ { sliderMin }
sliderValRange : $ { sliderValRange }
stepScale : $ { stepScale }
Step : $ { stepNumber } of $ { numSteps }
offVal : $ { offVal }
allVal = $ { allVal }
initial value : $ { handleText }
left - margin : $ { leftMargin }
width : $ { newSlider . width ( ) }
percent of max : $ { percentOfMax }
left : $ { leftPos } ` ) */
2023-11-15 10:58:47 +01:00
//special handling for response length slider, pulls text aliases for step values from an array
if ( newSlider . attr ( 'id' ) == 'amount_gen_zenslider' ) {
2023-12-02 20:11:06 +01:00
handleText = steps [ stepNumber ] ;
2023-11-15 10:58:47 +01:00
handle . text ( handleText ) ;
2023-12-02 20:11:06 +01:00
newSlider . val ( stepNumber ) ;
2023-12-05 13:12:06 +01:00
numVal = steps [ stepNumber ] ;
2023-11-15 10:58:47 +01:00
}
2023-11-29 03:37:18 +01:00
//special handling for TextCompletion rep pen range slider, pulls text aliases for step values from an array
2023-11-28 19:35:02 +01:00
else if ( newSlider . attr ( 'id' ) == 'rep_pen_range_textgenerationwebui_zenslider' ) {
2023-12-02 20:11:06 +01:00
handleText = steps [ stepNumber ] ;
2023-11-28 19:35:02 +01:00
handle . text ( handleText ) ;
2023-12-02 20:11:06 +01:00
newSlider . val ( stepNumber ) ;
2023-11-28 19:35:02 +01:00
if ( numVal === offVal ) { handle . text ( 'Off' ) . css ( 'color' , 'rgba(128,128,128,0.5' ) ; }
2023-12-02 20:11:06 +01:00
else if ( numVal === allVal ) { handle . text ( 'All' ) ; }
2023-11-28 19:35:02 +01:00
else { handle . css ( 'color' , '' ) ; }
2023-12-07 03:52:10 +01:00
numVal = steps [ stepNumber ] ;
2023-11-28 19:35:02 +01:00
}
2023-11-15 10:58:47 +01:00
//everything else uses the flat slider value
2023-11-29 03:37:18 +01:00
//also note: the above sliders are not custom inputtable due to the array aliasing
2023-11-15 10:58:47 +01:00
else {
//show 'off' if disabled value is set
if ( numVal === offVal ) { handle . text ( 'Off' ) . css ( 'color' , 'rgba(128,128,128,0.5' ) ; }
else { handle . text ( ui . value . toFixed ( decimals ) ) . css ( 'color' , '' ) ; }
2023-12-02 20:11:06 +01:00
newSlider . val ( handleText ) ;
2023-11-15 10:58:47 +01:00
}
//for manually typed-in values we must adjust left position because JQUI doesn't do it for us
2023-12-02 20:11:06 +01:00
handle . css ( 'left' , leftPos ) ;
2023-11-15 10:58:47 +01:00
//adjust a negative left margin to avoid overflowing right side of slider body
handle . css ( 'margin-left' , ` ${ leftMargin } px ` ) ;
2023-12-03 13:59:21 +01:00
originalSlider . val ( numVal ) ;
2023-11-15 10:58:47 +01:00
originalSlider . trigger ( 'input' ) ;
originalSlider . trigger ( 'change' ) ;
}
2023-12-02 16:15:03 +01:00
}
2023-07-20 19:32:15 +02:00
function switchUiMode ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'no-blur' , power _user . fast _ui _mode ) ;
$ ( '#fast_ui_mode' ) . prop ( 'checked' , power _user . fast _ui _mode ) ;
2023-09-22 15:16:24 +02:00
if ( power _user . fast _ui _mode ) {
2023-12-02 20:11:06 +01:00
$ ( '#blur-strength-block' ) . css ( 'opacity' , '0.2' ) ;
$ ( '#blur_strength' ) . prop ( 'disabled' , true ) ;
2023-09-23 04:56:24 +02:00
} else {
2023-12-02 20:11:06 +01:00
$ ( '#blur-strength-block' ) . css ( 'opacity' , '1' ) ;
$ ( '#blur_strength' ) . prop ( 'disabled' , false ) ;
2023-09-23 04:56:24 +02:00
}
2023-07-20 19:32:15 +02:00
}
function toggleWaifu ( ) {
2023-12-02 19:04:51 +01:00
$ ( '#waifuMode' ) . trigger ( 'click' ) ;
2024-06-15 21:35:38 +02:00
return '' ;
2023-07-20 19:32:15 +02:00
}
function switchWaifuMode ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'waifuMode' , power _user . waifuMode ) ;
$ ( '#waifuMode' ) . prop ( 'checked' , power _user . waifuMode ) ;
2023-07-20 19:32:15 +02:00
scrollChatToBottom ( ) ;
}
function switchSpoilerMode ( ) {
if ( power _user . spoiler _free _mode ) {
2024-03-03 10:55:16 +01:00
$ ( '#descriptionWrapper' ) . hide ( ) ;
$ ( '#firstMessageWrapper' ) . hide ( ) ;
$ ( '#spoiler_free_desc' ) . addClass ( 'flex1' ) ;
$ ( '#creator_notes_spoiler' ) . show ( ) ;
2023-07-20 19:32:15 +02:00
}
else {
2024-03-03 10:55:16 +01:00
$ ( '#descriptionWrapper' ) . show ( ) ;
$ ( '#firstMessageWrapper' ) . show ( ) ;
$ ( '#spoiler_free_desc' ) . removeClass ( 'flex1' ) ;
$ ( '#creator_notes_spoiler' ) . hide ( ) ;
2023-07-20 19:32:15 +02:00
}
}
function peekSpoilerMode ( ) {
2024-03-03 10:55:16 +01:00
$ ( '#descriptionWrapper' ) . toggle ( ) ;
$ ( '#firstMessageWrapper' ) . toggle ( ) ;
$ ( '#creator_notes_spoiler' ) . toggle ( ) ;
$ ( '#spoiler_free_desc' ) . toggleClass ( 'flex1' ) ;
2023-07-20 19:32:15 +02:00
}
function switchMovingUI ( ) {
2024-03-19 00:40:02 +01:00
$ ( '.drawer-content.maximized' ) . each ( function ( ) {
$ ( this ) . find ( '.inline-drawer-maximize' ) . trigger ( 'click' ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'movingUI' , power _user . movingUI ) ;
2023-07-20 19:32:15 +02:00
if ( power _user . movingUI === true ) {
2023-12-02 20:11:06 +01:00
initMovingUI ( ) ;
2023-07-20 19:32:15 +02:00
if ( power _user . movingUIState ) {
loadMovingUIState ( ) ;
}
2024-08-04 14:39:24 +02:00
} else {
if ( Object . keys ( power _user . movingUIState ) . length !== 0 ) {
power _user . movingUIState = { } ;
resetMovablePanels ( ) ;
saveSettingsDebounced ( ) ;
}
2023-12-02 16:15:03 +01:00
}
2023-07-20 19:32:15 +02:00
}
2024-08-23 18:49:00 +02:00
function applyNoShadows ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'noShadows' , power _user . noShadows ) ;
$ ( '#noShadowsmode' ) . prop ( 'checked' , power _user . noShadows ) ;
2023-09-22 15:16:24 +02:00
if ( power _user . noShadows ) {
2023-12-02 20:11:06 +01:00
$ ( '#shadow-width-block' ) . css ( 'opacity' , '0.2' ) ;
$ ( '#shadow_width' ) . prop ( 'disabled' , true ) ;
2023-09-23 04:56:24 +02:00
} else {
2023-12-02 20:11:06 +01:00
$ ( '#shadow-width-block' ) . css ( 'opacity' , '1' ) ;
$ ( '#shadow_width' ) . prop ( 'disabled' , false ) ;
2023-09-23 04:56:24 +02:00
}
2023-07-20 19:32:15 +02:00
scrollChatToBottom ( ) ;
}
function applyAvatarStyle ( ) {
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . toggleClass ( 'big-avatars' , power _user . avatar _style === avatar _styles . RECTANGULAR ) ;
$ ( 'body' ) . toggleClass ( 'square-avatars' , power _user . avatar _style === avatar _styles . SQUARE ) ;
$ ( '#avatar_style' ) . val ( power _user . avatar _style ) . prop ( 'selected' , true ) ;
2023-07-20 19:32:15 +02:00
}
function applyChatDisplay ( ) {
if ( ! power _user . chat _display === ( null || undefined ) ) {
2023-12-02 20:11:06 +01:00
console . debug ( 'applyChatDisplay: saw no chat display type defined' ) ;
return ;
2023-07-20 19:32:15 +02:00
}
2023-12-02 20:11:06 +01:00
console . debug ( ` poweruser.chat_display ${ power _user . chat _display } ` ) ;
2023-12-02 19:04:51 +01:00
$ ( '#chat_display' ) . val ( power _user . chat _display ) . prop ( 'selected' , true ) ;
2023-07-20 19:32:15 +02:00
switch ( power _user . chat _display ) {
case 0 : {
2024-07-06 14:29:47 +02:00
console . debug ( 'applying default chat' ) ;
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . removeClass ( 'bubblechat' ) ;
$ ( 'body' ) . removeClass ( 'documentstyle' ) ;
2023-12-02 20:11:06 +01:00
break ;
2023-07-20 19:32:15 +02:00
}
case 1 : {
2024-07-06 14:29:47 +02:00
console . debug ( 'applying bubblechat' ) ;
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . addClass ( 'bubblechat' ) ;
$ ( 'body' ) . removeClass ( 'documentstyle' ) ;
2023-12-02 20:11:06 +01:00
break ;
2023-07-20 19:32:15 +02:00
}
case 2 : {
2024-07-06 14:29:47 +02:00
console . debug ( 'applying document style' ) ;
2023-12-02 19:04:51 +01:00
$ ( 'body' ) . removeClass ( 'bubblechat' ) ;
$ ( 'body' ) . addClass ( 'documentstyle' ) ;
2023-12-02 20:11:06 +01:00
break ;
2023-07-20 19:32:15 +02:00
}
}
}
2023-09-22 15:16:24 +02:00
function applyChatWidth ( type ) {
if ( type === 'forced' ) {
let r = document . documentElement ;
r . style . setProperty ( '--sheldWidth' , ` ${ power _user . chat _width } vw ` ) ;
$ ( '#chat_width_slider' ) . val ( power _user . chat _width ) ;
//document.documentElement.style.setProperty('--sheldWidth', power_user.chat_width);
} else {
//this is to prevent the slider from updating page in real time
2023-12-02 19:04:51 +01:00
$ ( '#chat_width_slider' ) . off ( 'mouseup touchend' ) . on ( 'mouseup touchend' , async ( ) => {
2023-09-28 20:33:03 +02:00
// This is a hack for Firefox to let it render before applying the block width.
// Otherwise it takes the incorrect slider position with the new value AFTER the resizing.
2023-09-28 20:30:41 +02:00
await delay ( 1 ) ;
2023-09-22 15:16:24 +02:00
document . documentElement . style . setProperty ( '--sheldWidth' , ` ${ power _user . chat _width } vw ` ) ;
2023-09-28 20:30:41 +02:00
await delay ( 1 ) ;
2023-12-02 20:11:06 +01:00
} ) ;
2023-09-22 15:16:24 +02:00
}
2023-09-22 15:56:01 +02:00
2023-10-26 06:20:47 +02:00
$ ( '#chat_width_slider_counter' ) . val ( power _user . chat _width ) ;
2023-07-20 19:32:15 +02:00
}
2024-09-04 21:15:29 +02:00
function applyThemeColor ( type ) {
2023-07-20 19:32:15 +02:00
if ( type === 'main' ) {
document . documentElement . style . setProperty ( '--SmartThemeBodyColor' , power _user . main _text _color ) ;
2023-11-21 02:26:43 +01:00
const color = power _user . main _text _color . split ( '(' ) [ 1 ] . split ( ')' ) [ 0 ] . split ( ',' ) ;
document . documentElement . style . setProperty ( '--SmartThemeCheckboxBgColorR' , color [ 0 ] ) ;
document . documentElement . style . setProperty ( '--SmartThemeCheckboxBgColorG' , color [ 1 ] ) ;
document . documentElement . style . setProperty ( '--SmartThemeCheckboxBgColorB' , color [ 2 ] ) ;
document . documentElement . style . setProperty ( '--SmartThemeCheckboxBgColorA' , color [ 3 ] ) ;
2023-07-20 19:32:15 +02:00
}
if ( type === 'italics' ) {
document . documentElement . style . setProperty ( '--SmartThemeEmColor' , power _user . italics _text _color ) ;
}
2024-03-01 06:33:37 +01:00
if ( type === 'underline' ) {
document . documentElement . style . setProperty ( '--SmartThemeUnderlineColor' , power _user . underline _text _color ) ;
}
2023-07-20 19:32:15 +02:00
if ( type === 'quote' ) {
document . documentElement . style . setProperty ( '--SmartThemeQuoteColor' , power _user . quote _text _color ) ;
}
/ * i f ( t y p e = = = ' f a s t U I B G ' ) {
document . documentElement . style . setProperty ( '--SmartThemeFastUIBGColor' , power _user . fastui _bg _color ) ;
} * /
if ( type === 'blurTint' ) {
document . documentElement . style . setProperty ( '--SmartThemeBlurTintColor' , power _user . blur _tint _color ) ;
}
2023-09-22 09:54:51 +02:00
if ( type === 'chatTint' ) {
document . documentElement . style . setProperty ( '--SmartThemeChatTintColor' , power _user . chat _tint _color ) ;
}
2023-07-20 19:32:15 +02:00
if ( type === 'userMesBlurTint' ) {
document . documentElement . style . setProperty ( '--SmartThemeUserMesBlurTintColor' , power _user . user _mes _blur _tint _color ) ;
}
if ( type === 'botMesBlurTint' ) {
document . documentElement . style . setProperty ( '--SmartThemeBotMesBlurTintColor' , power _user . bot _mes _blur _tint _color ) ;
}
if ( type === 'shadow' ) {
document . documentElement . style . setProperty ( '--SmartThemeShadowColor' , power _user . shadow _color ) ;
}
2023-09-16 08:42:26 +02:00
if ( type === 'border' ) {
document . documentElement . style . setProperty ( '--SmartThemeBorderColor' , power _user . border _color ) ;
}
2023-07-20 19:32:15 +02:00
}
2024-09-04 21:15:29 +02:00
function applyCustomCSS ( ) {
2023-12-02 19:04:51 +01:00
$ ( '#customCSS' ) . val ( power _user . custom _css ) ;
var styleId = 'custom-style' ;
2023-09-22 20:13:58 +02:00
var style = document . getElementById ( styleId ) ;
2023-09-22 20:49:30 +02:00
if ( ! style ) {
2023-12-02 19:04:51 +01:00
style = document . createElement ( 'style' ) ;
style . setAttribute ( 'type' , 'text/css' ) ;
style . setAttribute ( 'id' , styleId ) ;
2023-09-22 20:13:58 +02:00
document . head . appendChild ( style ) ;
}
style . innerHTML = power _user . custom _css ;
}
2024-09-04 21:15:29 +02:00
function applyBlurStrength ( ) {
2024-08-24 21:53:50 +02:00
document . documentElement . style . setProperty ( '--blurStrength' , String ( power _user . blur _strength ) ) ;
2023-12-02 19:04:51 +01:00
$ ( '#blur_strength_counter' ) . val ( power _user . blur _strength ) ;
$ ( '#blur_strength' ) . val ( power _user . blur _strength ) ;
2023-07-20 19:32:15 +02:00
}
2024-09-04 21:15:29 +02:00
function applyShadowWidth ( ) {
2024-08-24 21:53:50 +02:00
document . documentElement . style . setProperty ( '--shadowWidth' , String ( power _user . shadow _width ) ) ;
2023-12-02 19:04:51 +01:00
$ ( '#shadow_width_counter' ) . val ( power _user . shadow _width ) ;
$ ( '#shadow_width' ) . val ( power _user . shadow _width ) ;
2023-07-20 19:32:15 +02:00
}
2024-09-04 21:15:29 +02:00
function applyFontScale ( type ) {
2023-08-25 00:06:52 +02:00
//this is to allow forced setting on page load, theme swap, etc
if ( type === 'forced' ) {
2024-08-24 21:53:50 +02:00
document . documentElement . style . setProperty ( '--fontScale' , String ( power _user . font _scale ) ) ;
2023-08-25 00:06:52 +02:00
} else {
//this is to prevent the slider from updating page in real time
2023-12-02 19:04:51 +01:00
$ ( '#font_scale' ) . off ( 'mouseup touchend' ) . on ( 'mouseup touchend' , ( ) => {
2024-08-24 21:53:50 +02:00
document . documentElement . style . setProperty ( '--fontScale' , String ( power _user . font _scale ) ) ;
2023-12-02 20:11:06 +01:00
} ) ;
2023-08-25 00:06:52 +02:00
}
2023-12-02 19:04:51 +01:00
$ ( '#font_scale_counter' ) . val ( power _user . font _scale ) ;
$ ( '#font_scale' ) . val ( power _user . font _scale ) ;
2023-07-20 19:32:15 +02:00
}
2024-09-04 21:15:29 +02:00
function applyTheme ( name ) {
2023-07-20 19:32:15 +02:00
const theme = themes . find ( x => x . name == name ) ;
if ( ! theme ) {
return ;
}
const themeProperties = [
{ key : 'main_text_color' , selector : '#main-text-color-picker' , type : 'main' } ,
{ key : 'italics_text_color' , selector : '#italics-color-picker' , type : 'italics' } ,
2024-03-01 06:33:37 +01:00
{ key : 'underline_text_color' , selector : '#underline-color-picker' , type : 'underline' } ,
2023-07-20 19:32:15 +02:00
{ key : 'quote_text_color' , selector : '#quote-color-picker' , type : 'quote' } ,
{ key : 'blur_tint_color' , selector : '#blur-tint-color-picker' , type : 'blurTint' } ,
2023-09-22 09:54:51 +02:00
{ key : 'chat_tint_color' , selector : '#chat-tint-color-picker' , type : 'chatTint' } ,
2023-07-20 19:32:15 +02:00
{ key : 'user_mes_blur_tint_color' , selector : '#user-mes-blur-tint-color-picker' , type : 'userMesBlurTint' } ,
{ key : 'bot_mes_blur_tint_color' , selector : '#bot-mes-blur-tint-color-picker' , type : 'botMesBlurTint' } ,
{ key : 'shadow_color' , selector : '#shadow-color-picker' , type : 'shadow' } ,
2023-09-16 08:42:26 +02:00
{ key : 'border_color' , selector : '#border-color-picker' , type : 'border' } ,
2023-07-20 19:32:15 +02:00
{
key : 'blur_strength' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
applyBlurStrength ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
2023-09-22 20:13:58 +02:00
{
key : 'custom_css' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
applyCustomCSS ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-09-22 20:13:58 +02:00
} ,
2023-07-20 19:32:15 +02:00
{
key : 'shadow_width' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
applyShadowWidth ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'font_scale' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
applyFontScale ( 'forced' ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'fast_ui_mode' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
switchUiMode ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'waifuMode' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
switchWaifuMode ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'chat_display' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
applyChatDisplay ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'avatar_style' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
applyAvatarStyle ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'noShadows' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2024-08-23 18:49:00 +02:00
applyNoShadows ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'chat_width' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-22 17:09:50 +02:00
// If chat width is not set, set it to 50
if ( ! power _user . chat _width ) {
power _user . chat _width = 50 ;
}
2023-09-22 15:16:24 +02:00
applyChatWidth ( 'forced' ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'timer_enabled' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
switchTimer ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
{
key : 'timestamps_enabled' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
switchTimestamps ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
2023-08-14 00:43:16 +02:00
{
key : 'timestamp_model_icon' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-08-14 00:43:16 +02:00
switchIcons ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-08-14 00:43:16 +02:00
} ,
2023-08-31 16:10:01 +02:00
{
2023-09-22 15:16:24 +02:00
key : 'message_token_count_enabled' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-08-31 16:10:01 +02:00
switchTokenCount ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-08-31 16:10:01 +02:00
} ,
2023-07-20 19:32:15 +02:00
{
key : 'mesIDDisplay_enabled' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
switchMesIDDisplay ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-07-20 19:32:15 +02:00
} ,
2024-04-25 05:51:56 +02:00
{
key : 'hideChatAvatars_enabled' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2024-04-25 05:51:56 +02:00
switchHideChatAvatars ( ) ;
} ,
} ,
2023-09-14 14:23:51 +02:00
{
key : 'expand_message_actions' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-09-14 14:23:51 +02:00
switchMessageActions ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-09-14 14:23:51 +02:00
} ,
2023-11-04 21:47:53 +01:00
{
key : 'enableZenSliders' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-11-04 21:47:53 +01:00
switchMessageActions ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-11-04 21:47:53 +01:00
} ,
2023-11-10 08:17:38 +01:00
{
key : 'enableLabMode' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-11-10 08:17:38 +01:00
switchMessageActions ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-11-10 08:17:38 +01:00
} ,
2023-07-20 19:32:15 +02:00
{
key : 'hotswap_enabled' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-07-20 19:32:15 +02:00
switchHotswap ( ) ;
2023-12-02 21:06:57 +01:00
} ,
2023-11-10 20:56:25 +01:00
} ,
{
key : 'bogus_folders' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-11-10 20:56:25 +01:00
$ ( '#bogus_folders' ) . prop ( 'checked' , power _user . bogus _folders ) ;
2024-03-30 03:06:40 +01:00
printCharactersDebounced ( ) ;
2023-11-10 20:56:25 +01:00
} ,
} ,
2024-04-14 16:59:51 +02:00
{
key : 'zoomed_avatar_magnification' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2024-04-14 16:59:51 +02:00
$ ( '#zoomed_avatar_magnification' ) . prop ( 'checked' , power _user . zoomed _avatar _magnification ) ;
printCharactersDebounced ( ) ;
} ,
} ,
2023-12-10 19:02:25 +01:00
{
key : 'reduced_motion' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-12-10 19:02:25 +01:00
$ ( '#reduced_motion' ) . prop ( 'checked' , power _user . reduced _motion ) ;
2023-12-16 00:35:28 +01:00
switchReducedMotion ( ) ;
} ,
} ,
{
key : 'compact_input_area' ,
2024-09-04 21:15:29 +02:00
action : ( ) => {
2023-12-16 00:35:28 +01:00
$ ( '#compact_input_area' ) . prop ( 'checked' , power _user . compact _input _area ) ;
switchCompactInputArea ( ) ;
2023-12-10 19:02:25 +01:00
} ,
} ,
2023-07-20 19:32:15 +02:00
] ;
for ( const { key , selector , type , action } of themeProperties ) {
if ( theme [ key ] !== undefined ) {
power _user [ key ] = theme [ key ] ;
if ( selector ) $ ( selector ) . attr ( 'color' , power _user [ key ] ) ;
2024-09-04 21:15:29 +02:00
if ( type ) applyThemeColor ( type ) ;
if ( action ) action ( ) ;
2023-07-20 19:32:15 +02:00
} else {
2023-12-02 20:11:06 +01:00
if ( selector ) { $ ( selector ) . attr ( 'color' , 'rgba(0,0,0,0)' ) ; }
2023-07-20 19:32:15 +02:00
console . debug ( ` Empty theme key: ${ key } ` ) ;
power _user [ key ] = '' ;
}
}
console . log ( 'theme applied: ' + name ) ;
}
async function applyMovingUIPreset ( name ) {
2024-05-20 05:56:48 +02:00
await resetMovablePanels ( 'quiet' ) ;
2023-07-20 19:32:15 +02:00
const movingUIPreset = movingUIPresets . find ( x => x . name == name ) ;
if ( ! movingUIPreset ) {
return ;
}
power _user . movingUIState = movingUIPreset . movingUIState ;
console . log ( 'MovingUI Preset applied: ' + name ) ;
2023-12-02 20:11:06 +01:00
loadMovingUIState ( ) ;
2024-05-21 00:57:04 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
}
2023-08-27 22:20:43 +02:00
/ * *
* Register a function to be executed when the debug menu is opened .
* @ param { string } functionId Unique ID for the function .
* @ param { string } name Name of the function .
* @ param { string } description Description of the function .
* @ param { function } func Function to be executed .
* /
export function registerDebugFunction ( functionId , name , description , func ) {
debug _functions . push ( { functionId , name , description , func } ) ;
}
2024-04-11 21:36:23 +02:00
async function showDebugMenu ( ) {
const template = await renderTemplateAsync ( 'debug' , { functions : debug _functions } ) ;
2024-06-25 23:35:21 +02:00
callGenericPopup ( template , POPUP _TYPE . TEXT , '' , { wide : true , large : true , allowVerticalScrolling : true } ) ;
2023-08-27 22:20:43 +02:00
}
2024-08-23 18:49:00 +02:00
function applyPowerUserSettings ( ) {
switchUiMode ( ) ;
applyFontScale ( 'forced' ) ;
applyThemeColor ( ) ;
applyChatWidth ( 'forced' ) ;
applyAvatarStyle ( ) ;
applyBlurStrength ( ) ;
applyShadowWidth ( ) ;
applyCustomCSS ( ) ;
switchMovingUI ( ) ;
applyNoShadows ( ) ;
switchHotswap ( ) ;
switchTimer ( ) ;
switchTimestamps ( ) ;
switchIcons ( ) ;
switchMesIDDisplay ( ) ;
switchHideChatAvatars ( ) ;
switchTokenCount ( ) ;
switchMessageActions ( ) ;
}
2023-07-20 19:32:15 +02:00
2023-10-20 19:09:31 +02:00
function getExampleMessagesBehavior ( ) {
if ( power _user . strip _examples ) {
return 'strip' ;
}
if ( power _user . pin _examples ) {
return 'keep' ;
}
return 'normal' ;
}
2024-08-05 05:03:46 +02:00
async function loadPowerUserSettings ( settings , data ) {
2024-05-12 21:15:05 +02:00
const defaultStscript = JSON . parse ( JSON . stringify ( power _user . stscript ) ) ;
2023-07-20 19:32:15 +02:00
// Load from settings.json
if ( settings . power _user !== undefined ) {
Object . assign ( power _user , settings . power _user ) ;
}
2024-05-12 21:15:05 +02:00
if ( power _user . stscript === undefined ) {
power _user . stscript = defaultStscript ;
} else {
if ( power _user . stscript . autocomplete === undefined ) {
power _user . stscript . autocomplete = defaultStscript . autocomplete ;
} else {
if ( power _user . stscript . autocomplete . width === undefined ) {
power _user . stscript . autocomplete . width = defaultStscript . autocomplete . width ;
}
if ( power _user . stscript . autocomplete . font === undefined ) {
power _user . stscript . autocomplete . font = defaultStscript . autocomplete . font ;
}
2024-06-24 21:35:09 +02:00
if ( power _user . stscript . autocomplete . style === undefined ) {
power _user . stscript . autocomplete . style = power _user . stscript . autocomplete _style || defaultStscript . autocomplete . style ;
}
2024-07-19 13:41:57 +02:00
if ( power _user . stscript . autocomplete . select === undefined ) {
power _user . stscript . autocomplete . select = defaultStscript . autocomplete . select ;
}
2024-05-12 21:15:05 +02:00
}
if ( power _user . stscript . parser === undefined ) {
power _user . stscript . parser = defaultStscript . parser ;
} else if ( power _user . stscript . parser . flags === undefined ) {
power _user . stscript . parser . flags = defaultStscript . parser . flags ;
}
2024-06-24 21:35:09 +02:00
// Cleanup old flags
delete power _user . stscript . autocomplete _style ;
2024-05-12 21:15:05 +02:00
}
2023-07-20 19:32:15 +02:00
if ( data . themes !== undefined ) {
themes = data . themes ;
}
if ( data . movingUIPresets !== undefined ) {
movingUIPresets = data . movingUIPresets ;
}
2023-08-17 21:47:34 +02:00
if ( data . context !== undefined ) {
context _presets = data . context ;
}
2024-08-25 14:45:39 +02:00
// These are still local storage. Delete in 1.12.7
2024-01-05 19:27:19 +01:00
const autoLoadChat = localStorage . getItem ( storage _keys . auto _load _chat _legacy ) ;
const autoConnect = localStorage . getItem ( storage _keys . auto _connect _legacy ) ;
if ( autoLoadChat ) {
power _user . auto _load _chat = autoLoadChat === 'true' ;
localStorage . removeItem ( storage _keys . auto _load _chat _legacy ) ;
}
if ( autoConnect ) {
power _user . auto _connect = autoConnect === 'true' ;
localStorage . removeItem ( storage _keys . auto _connect _legacy ) ;
}
2023-07-20 19:32:15 +02:00
if ( power _user . chat _display === '' ) {
power _user . chat _display = chat _styles . DEFAULT ;
}
if ( power _user . waifuMode === '' ) {
power _user . waifuMode = false ;
}
2023-07-22 17:09:50 +02:00
if ( power _user . chat _width === '' ) {
power _user . chat _width = 50 ;
}
2023-08-27 21:14:39 +02:00
if ( power _user . tokenizer === tokenizers . LEGACY ) {
power _user . tokenizer = tokenizers . GPT2 ;
}
2024-06-22 05:03:05 +02:00
// Clean up old/legacy settings
2024-06-22 11:53:03 +02:00
if ( power _user . import _card _tags !== undefined ) {
power _user . tag _import _setting = power _user . import _card _tags ? tag _import _setting . ASK : tag _import _setting . NONE ;
delete power _user . import _card _tags ;
}
2024-06-22 05:03:05 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#single_line' ) . prop ( 'checked' , power _user . single _line ) ;
$ ( '#relaxed_api_urls' ) . prop ( 'checked' , power _user . relaxed _api _urls ) ;
$ ( '#world_import_dialog' ) . prop ( 'checked' , power _user . world _import _dialog ) ;
2024-08-18 03:38:07 +02:00
$ ( '#enable_auto_select_input' ) . prop ( 'checked' , power _user . enable _auto _select _input ) ;
2023-12-02 19:04:51 +01:00
$ ( '#trim_spaces' ) . prop ( 'checked' , power _user . trim _spaces ) ;
$ ( '#continue_on_send' ) . prop ( 'checked' , power _user . continue _on _send ) ;
$ ( '#quick_continue' ) . prop ( 'checked' , power _user . quick _continue ) ;
2024-08-02 14:17:29 +02:00
$ ( '#quick_impersonate' ) . prop ( 'checked' , power _user . quick _continue ) ;
2023-08-24 00:37:44 +02:00
$ ( '#mes_continue' ) . css ( 'display' , power _user . quick _continue ? '' : 'none' ) ;
2024-08-02 14:17:29 +02:00
$ ( '#mes_impersonate' ) . css ( 'display' , power _user . quick _impersonate ? '' : 'none' ) ;
2023-12-02 19:04:51 +01:00
$ ( '#gestures-checkbox' ) . prop ( 'checked' , power _user . gestures ) ;
$ ( '#auto_swipe' ) . prop ( 'checked' , power _user . auto _swipe ) ;
2023-07-20 19:32:15 +02:00
$ ( '#auto_swipe_minimum_length' ) . val ( power _user . auto _swipe _minimum _length ) ;
2023-12-02 19:04:51 +01:00
$ ( '#auto_swipe_blacklist' ) . val ( power _user . auto _swipe _blacklist . join ( ', ' ) ) ;
2023-07-20 19:32:15 +02:00
$ ( '#auto_swipe_blacklist_threshold' ) . val ( power _user . auto _swipe _blacklist _threshold ) ;
2024-08-05 07:30:15 +02:00
$ ( '#custom_stopping_strings' ) . text ( power _user . custom _stopping _strings ) ;
2023-12-02 19:04:51 +01:00
$ ( '#custom_stopping_strings_macro' ) . prop ( 'checked' , power _user . custom _stopping _strings _macro ) ;
$ ( '#fuzzy_search_checkbox' ) . prop ( 'checked' , power _user . fuzzy _search ) ;
$ ( '#persona_show_notifications' ) . prop ( 'checked' , power _user . persona _show _notifications ) ;
$ ( '#encode_tags' ) . prop ( 'checked' , power _user . encode _tags ) ;
2023-10-20 19:09:31 +02:00
$ ( '#example_messages_behavior' ) . val ( getExampleMessagesBehavior ( ) ) ;
2023-12-02 19:04:51 +01:00
$ ( ` #example_messages_behavior option[value=" ${ getExampleMessagesBehavior ( ) } "] ` ) . prop ( 'selected' , true ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#console_log_prompts' ) . prop ( 'checked' , power _user . console _log _prompts ) ;
2024-01-23 06:00:31 +01:00
$ ( '#request_token_probabilities' ) . prop ( 'checked' , power _user . request _token _probabilities ) ;
2024-07-04 15:52:56 +02:00
$ ( '#show_group_chat_queue' ) . prop ( 'checked' , power _user . show _group _chat _queue ) ;
2023-12-02 19:04:51 +01:00
$ ( '#auto_fix_generated_markdown' ) . prop ( 'checked' , power _user . auto _fix _generated _markdown ) ;
$ ( '#auto_scroll_chat_to_bottom' ) . prop ( 'checked' , power _user . auto _scroll _chat _to _bottom ) ;
$ ( '#bogus_folders' ) . prop ( 'checked' , power _user . bogus _folders ) ;
2024-04-14 16:59:51 +02:00
$ ( '#zoomed_avatar_magnification' ) . prop ( 'checked' , power _user . zoomed _avatar _magnification ) ;
2023-07-20 19:32:15 +02:00
$ ( ` #tokenizer option[value=" ${ power _user . tokenizer } "] ` ) . attr ( 'selected' , true ) ;
2023-12-02 19:04:51 +01:00
$ ( ` #send_on_enter option[value= ${ power _user . send _on _enter } ] ` ) . attr ( 'selected' , true ) ;
$ ( '#confirm_message_delete' ) . prop ( 'checked' , power _user . confirm _message _delete !== undefined ? ! ! power _user . confirm _message _delete : true ) ;
$ ( '#spoiler_free_mode' ) . prop ( 'checked' , power _user . spoiler _free _mode ) ;
$ ( '#collapse-newlines-checkbox' ) . prop ( 'checked' , power _user . collapse _newlines ) ;
$ ( '#always-force-name2-checkbox' ) . prop ( 'checked' , power _user . always _force _name2 ) ;
$ ( '#trim_sentences_checkbox' ) . prop ( 'checked' , power _user . trim _sentences ) ;
$ ( '#include_newline_checkbox' ) . prop ( 'checked' , power _user . include _newline ) ;
$ ( '#render_formulas' ) . prop ( 'checked' , power _user . render _formulas ) ;
$ ( '#disable_group_trimming' ) . prop ( 'checked' , power _user . disable _group _trimming ) ;
$ ( '#markdown_escape_strings' ) . val ( power _user . markdown _escape _strings ) ;
$ ( '#fast_ui_mode' ) . prop ( 'checked' , power _user . fast _ui _mode ) ;
$ ( '#waifuMode' ) . prop ( 'checked' , power _user . waifuMode ) ;
$ ( '#movingUImode' ) . prop ( 'checked' , power _user . movingUI ) ;
$ ( '#noShadowsmode' ) . prop ( 'checked' , power _user . noShadows ) ;
2024-08-05 07:30:15 +02:00
$ ( '#start_reply_with' ) . text ( power _user . user _prompt _bias ) ;
2023-12-02 19:04:51 +01:00
$ ( '#chat-show-reply-prefix-checkbox' ) . prop ( 'checked' , power _user . show _user _prompt _bias ) ;
$ ( '#auto_continue_enabled' ) . prop ( 'checked' , power _user . auto _continue . enabled ) ;
$ ( '#auto_continue_allow_chat_completions' ) . prop ( 'checked' , power _user . auto _continue . allow _chat _completions ) ;
$ ( '#auto_continue_target_length' ) . val ( power _user . auto _continue . target _length ) ;
$ ( '#play_message_sound' ) . prop ( 'checked' , power _user . play _message _sound ) ;
$ ( '#play_sound_unfocused' ) . prop ( 'checked' , power _user . play _sound _unfocused ) ;
$ ( '#never_resize_avatars' ) . prop ( 'checked' , power _user . never _resize _avatars ) ;
$ ( '#show_card_avatar_urls' ) . prop ( 'checked' , power _user . show _card _avatar _urls ) ;
$ ( '#auto_save_msg_edits' ) . prop ( 'checked' , power _user . auto _save _msg _edits ) ;
$ ( '#allow_name1_display' ) . prop ( 'checked' , power _user . allow _name1 _display ) ;
$ ( '#allow_name2_display' ) . prop ( 'checked' , power _user . allow _name2 _display ) ;
2023-07-20 19:32:15 +02:00
//$("#removeXML").prop("checked", power_user.removeXML);
2023-12-02 19:04:51 +01:00
$ ( '#hotswapEnabled' ) . prop ( 'checked' , power _user . hotswap _enabled ) ;
$ ( '#messageTimerEnabled' ) . prop ( 'checked' , power _user . timer _enabled ) ;
$ ( '#messageTimestampsEnabled' ) . prop ( 'checked' , power _user . timestamps _enabled ) ;
$ ( '#messageModelIconEnabled' ) . prop ( 'checked' , power _user . timestamp _model _icon ) ;
$ ( '#mesIDDisplayEnabled' ) . prop ( 'checked' , power _user . mesIDDisplay _enabled ) ;
2024-08-25 14:29:14 +02:00
$ ( '#hideChatAvatarsEnabled' ) . prop ( 'checked' , power _user . hideChatAvatars _enabled ) ;
2023-12-02 19:04:51 +01:00
$ ( '#prefer_character_prompt' ) . prop ( 'checked' , power _user . prefer _character _prompt ) ;
$ ( '#prefer_character_jailbreak' ) . prop ( 'checked' , power _user . prefer _character _jailbreak ) ;
$ ( '#enableZenSliders' ) . prop ( 'checked' , power _user . enableZenSliders ) . trigger ( 'input' ) ;
$ ( '#enableLabMode' ) . prop ( 'checked' , power _user . enableLabMode ) . trigger ( 'input' ) ;
$ ( ` input[name="avatar_style"][value=" ${ power _user . avatar _style } "] ` ) . prop ( 'checked' , true ) ;
$ ( ` #chat_display option[value= ${ power _user . chat _display } ] ` ) . attr ( 'selected' , true ) . trigger ( 'change' ) ;
2023-07-20 19:32:15 +02:00
$ ( '#chat_width_slider' ) . val ( power _user . chat _width ) ;
2023-12-02 19:04:51 +01:00
$ ( '#token_padding' ) . val ( power _user . token _padding ) ;
$ ( '#aux_field' ) . val ( power _user . aux _field ) ;
2024-06-22 05:03:05 +02:00
$ ( '#tag_import_setting' ) . val ( power _user . tag _import _setting ) ;
2024-05-12 21:15:05 +02:00
2024-05-13 20:56:36 +02:00
$ ( '#stscript_autocomplete_autoHide' ) . prop ( 'checked' , power _user . stscript . autocomplete . autoHide ? ? false ) . trigger ( 'input' ) ;
2024-05-12 21:15:05 +02:00
$ ( '#stscript_matching' ) . val ( power _user . stscript . matching ? ? 'fuzzy' ) ;
2024-06-24 21:35:09 +02:00
$ ( '#stscript_autocomplete_style' ) . val ( power _user . stscript . autocomplete . style ? ? 'theme' ) ;
document . body . setAttribute ( 'data-stscript-style' , power _user . stscript . autocomplete . style ) ;
2024-07-19 22:42:20 +02:00
$ ( '#stscript_autocomplete_select' ) . val ( power _user . stscript . autocomplete . select ? ? ( AUTOCOMPLETE _SELECT _KEY . TAB + AUTOCOMPLETE _SELECT _KEY . ENTER ) ) ;
2024-05-12 21:15:05 +02:00
$ ( '#stscript_parser_flag_strict_escaping' ) . prop ( 'checked' , power _user . stscript . parser . flags [ PARSER _FLAG . STRICT _ESCAPING ] ? ? false ) ;
$ ( '#stscript_parser_flag_replace_getvar' ) . prop ( 'checked' , power _user . stscript . parser . flags [ PARSER _FLAG . REPLACE _GETVAR ] ? ? false ) ;
$ ( '#stscript_autocomplete_font_scale' ) . val ( power _user . stscript . autocomplete . font . scale ? ? defaultStscript . autocomplete . font . scale ) ;
$ ( '#stscript_autocomplete_font_scale_counter' ) . val ( power _user . stscript . autocomplete . font . scale ? ? defaultStscript . autocomplete . font . scale ) ;
document . body . style . setProperty ( '--ac-font-scale' , power _user . stscript . autocomplete . font . scale ? ? defaultStscript . autocomplete . font . scale . toString ( ) ) ;
$ ( '#stscript_autocomplete_width_left' ) . val ( power _user . stscript . autocomplete . width . left ? ? AUTOCOMPLETE _WIDTH . CHAT ) ;
2024-05-20 05:56:48 +02:00
document . querySelector ( '#stscript_autocomplete_width_left' ) . dispatchEvent ( new Event ( 'input' , { bubbles : true } ) ) ;
2024-05-12 21:15:05 +02:00
$ ( '#stscript_autocomplete_width_right' ) . val ( power _user . stscript . autocomplete . width . right ? ? AUTOCOMPLETE _WIDTH . CHAT ) ;
2024-05-20 05:56:48 +02:00
document . querySelector ( '#stscript_autocomplete_width_right' ) . dispatchEvent ( new Event ( 'input' , { bubbles : true } ) ) ;
2024-05-12 21:15:05 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#restore_user_input' ) . prop ( 'checked' , power _user . restore _user _input ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#chat_truncation' ) . val ( power _user . chat _truncation ) ;
2023-11-19 20:57:54 +01:00
$ ( '#chat_truncation_counter' ) . val ( power _user . chat _truncation ) ;
2023-12-12 21:11:23 +01:00
$ ( '#streaming_fps' ) . val ( power _user . streaming _fps ) ;
$ ( '#streaming_fps_counter' ) . val ( power _user . streaming _fps ) ;
2024-04-02 13:56:15 +02:00
$ ( '#smooth_streaming' ) . prop ( 'checked' , power _user . smooth _streaming ) ;
2024-04-02 21:52:51 +02:00
$ ( '#smooth_streaming_speed' ) . val ( power _user . smooth _streaming _speed ) ;
2024-04-02 13:56:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#font_scale' ) . val ( power _user . font _scale ) ;
$ ( '#font_scale_counter' ) . val ( power _user . font _scale ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#blur_strength' ) . val ( power _user . blur _strength ) ;
$ ( '#blur_strength_counter' ) . val ( power _user . blur _strength ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#shadow_width' ) . val ( power _user . shadow _width ) ;
$ ( '#shadow_width_counter' ) . val ( power _user . shadow _width ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#main-text-color-picker' ) . attr ( 'color' , power _user . main _text _color ) ;
$ ( '#italics-color-picker' ) . attr ( 'color' , power _user . italics _text _color ) ;
2024-03-01 06:33:37 +01:00
$ ( '#underline-color-picker' ) . attr ( 'color' , power _user . underline _text _color ) ;
2023-12-02 19:04:51 +01:00
$ ( '#quote-color-picker' ) . attr ( 'color' , power _user . quote _text _color ) ;
$ ( '#blur-tint-color-picker' ) . attr ( 'color' , power _user . blur _tint _color ) ;
$ ( '#chat-tint-color-picker' ) . attr ( 'color' , power _user . chat _tint _color ) ;
$ ( '#user-mes-blur-tint-color-picker' ) . attr ( 'color' , power _user . user _mes _blur _tint _color ) ;
$ ( '#bot-mes-blur-tint-color-picker' ) . attr ( 'color' , power _user . bot _mes _blur _tint _color ) ;
$ ( '#shadow-color-picker' ) . attr ( 'color' , power _user . shadow _color ) ;
$ ( '#border-color-picker' ) . attr ( 'color' , power _user . border _color ) ;
2023-12-10 19:02:25 +01:00
$ ( '#reduced_motion' ) . prop ( 'checked' , power _user . reduced _motion ) ;
2024-01-05 19:27:19 +01:00
$ ( '#auto-connect-checkbox' ) . prop ( 'checked' , power _user . auto _connect ) ;
$ ( '#auto-load-chat-checkbox' ) . prop ( 'checked' , power _user . auto _load _chat ) ;
2024-04-20 00:11:37 +02:00
$ ( '#forbid_external_media' ) . prop ( 'checked' , power _user . forbid _external _media ) ;
2023-07-20 19:32:15 +02:00
for ( const theme of themes ) {
const option = document . createElement ( 'option' ) ;
option . value = theme . name ;
option . innerText = theme . name ;
option . selected = theme . name == power _user . theme ;
2023-12-02 19:04:51 +01:00
$ ( '#themes' ) . append ( option ) ;
2023-07-20 19:32:15 +02:00
}
for ( const movingUIPreset of movingUIPresets ) {
const option = document . createElement ( 'option' ) ;
option . value = movingUIPreset . name ;
option . innerText = movingUIPreset . name ;
option . selected = movingUIPreset . name == power _user . movingUIPreset ;
2023-12-02 19:04:51 +01:00
$ ( '#movingUIPresets' ) . append ( option ) ;
2023-07-20 19:32:15 +02:00
}
2023-12-02 19:04:51 +01:00
$ ( ` #character_sort_order option[data-order=" ${ power _user . sort _order } "][data-field=" ${ power _user . sort _field } "] ` ) . prop ( 'selected' , true ) ;
2023-12-10 19:02:25 +01:00
switchReducedMotion ( ) ;
2023-12-16 00:35:28 +01:00
switchCompactInputArea ( ) ;
2023-07-20 19:32:15 +02:00
reloadMarkdownProcessor ( power _user . render _formulas ) ;
2024-09-01 17:01:21 +02:00
await loadInstructMode ( data ) ;
2024-08-05 05:03:46 +02:00
await loadContextSettings ( ) ;
2023-07-20 19:32:15 +02:00
loadMaxContextUnlocked ( ) ;
switchWaifuMode ( ) ;
switchSpoilerMode ( ) ;
loadMovingUIState ( ) ;
loadCharListState ( ) ;
}
async function loadCharListState ( ) {
2023-08-19 14:58:17 +02:00
if ( document . querySelector ( '.character_select' ) !== null ) {
2023-12-02 20:11:06 +01:00
console . debug ( 'setting charlist state to...' ) ;
2023-07-20 19:32:15 +02:00
if ( power _user . charListGrid === true ) {
2023-12-02 20:11:06 +01:00
console . debug ( '..to grid' ) ;
$ ( '#charListGridToggle' ) . trigger ( 'click' ) ;
} else { console . debug ( '..to list' ) ; }
2023-07-20 19:32:15 +02:00
} else {
2023-12-02 20:11:06 +01:00
console . debug ( 'charlist not ready yet' ) ;
await delay ( 100 ) ;
2023-07-20 19:32:15 +02:00
loadCharListState ( ) ;
}
}
function loadMovingUIState ( ) {
2023-12-15 00:05:59 +01:00
if ( ! isMobile ( )
2023-07-20 19:32:15 +02:00
&& power _user . movingUIState
&& power _user . movingUI === true ) {
2023-12-02 20:11:06 +01:00
console . debug ( 'loading movingUI state' ) ;
2023-07-20 19:32:15 +02:00
for ( var elmntName of Object . keys ( power _user . movingUIState ) ) {
var elmntState = power _user . movingUIState [ elmntName ] ;
try {
var elmnt = $ ( '#' + $ . escapeSelector ( elmntName ) ) ;
if ( elmnt . length ) {
2023-12-02 20:11:06 +01:00
console . debug ( ` loading state for ${ elmntName } ` ) ;
2023-07-20 19:32:15 +02:00
elmnt . css ( elmntState ) ;
} else {
2023-12-02 20:11:06 +01:00
console . debug ( ` skipping ${ elmntName } because it doesn't exist in the DOM ` ) ;
2023-07-20 19:32:15 +02:00
}
} catch ( err ) {
2023-12-02 20:11:06 +01:00
console . debug ( ` error occurred while processing ${ elmntName } : ${ err } ` ) ;
2023-07-20 19:32:15 +02:00
}
}
} else {
2023-12-02 20:11:06 +01:00
console . debug ( 'skipping movingUI state load' ) ;
return ;
2023-07-20 19:32:15 +02:00
}
}
function loadMaxContextUnlocked ( ) {
$ ( '#max_context_unlocked' ) . prop ( 'checked' , power _user . max _context _unlocked ) ;
$ ( '#max_context_unlocked' ) . on ( 'change' , function ( ) {
power _user . max _context _unlocked = ! ! $ ( this ) . prop ( 'checked' ) ;
switchMaxContextSize ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
switchMaxContextSize ( ) ;
}
function switchMaxContextSize ( ) {
2024-05-22 19:46:52 +02:00
const elements = [
$ ( '#max_context' ) ,
$ ( '#max_context_counter' ) ,
$ ( '#rep_pen_range' ) ,
$ ( '#rep_pen_range_counter' ) ,
$ ( '#rep_pen_range_textgenerationwebui' ) ,
$ ( '#rep_pen_range_counter_textgenerationwebui' ) ,
$ ( '#dry_penalty_last_n_textgenerationwebui' ) ,
$ ( '#dry_penalty_last_n_counter_textgenerationwebui' ) ,
2024-05-22 22:37:51 +02:00
$ ( '#rep_pen_decay_textgenerationwebui' ) ,
$ ( '#rep_pen_decay_counter_textgenerationwebui' ) ,
2024-05-22 19:46:52 +02:00
] ;
2023-07-20 19:32:15 +02:00
const maxValue = power _user . max _context _unlocked ? MAX _CONTEXT _UNLOCKED : MAX _CONTEXT _DEFAULT ;
2023-10-27 12:22:46 +02:00
const minValue = power _user . max _context _unlocked ? maxContextMin : maxContextMin ;
const steps = power _user . max _context _unlocked ? unlockedMaxContextStep : maxContextStep ;
2023-12-02 20:11:06 +01:00
$ ( '#rep_pen_range_textgenerationwebui_zenslider' ) . remove ( ) ; //unsure why, but this is necessary.
2024-05-22 19:46:52 +02:00
$ ( '#dry_penalty_last_n_textgenerationwebui_zenslider' ) . remove ( ) ;
2024-05-22 22:37:51 +02:00
$ ( '#rep_pen_decay_textgenerationwebui_zenslider' ) . remove ( ) ;
2023-08-26 20:27:37 +02:00
for ( const element of elements ) {
2023-11-12 16:27:40 +01:00
const id = element . attr ( 'id' ) ;
2023-08-26 20:27:37 +02:00
element . attr ( 'max' , maxValue ) ;
2023-10-27 20:09:53 +02:00
2023-11-12 16:27:40 +01:00
if ( typeof id === 'string' && id ? . indexOf ( 'max_context' ) !== - 1 ) {
2023-10-27 20:09:53 +02:00
element . attr ( 'min' , minValue ) ;
2023-12-02 20:11:06 +01:00
element . attr ( 'step' , steps ) ; //only change setps for max context, because rep pen range needs step of 1 due to important values of -1 and 0
2023-10-27 20:09:53 +02:00
}
2023-08-26 20:27:37 +02:00
const value = Number ( element . val ( ) ) ;
if ( value >= maxValue ) {
element . val ( maxValue ) . trigger ( 'input' ) ;
}
2023-07-20 19:32:15 +02:00
}
2023-12-03 17:30:21 +01:00
const maxAmountGen = power _user . max _context _unlocked ? MAX _RESPONSE _UNLOCKED : MAX _RESPONSE _DEFAULT ;
$ ( '#amount_gen' ) . attr ( 'max' , maxAmountGen ) ;
$ ( '#amount_gen_counter' ) . attr ( 'max' , maxAmountGen ) ;
if ( Number ( $ ( '#amount_gen' ) . val ( ) ) >= maxAmountGen ) {
$ ( '#amount_gen' ) . val ( maxAmountGen ) . trigger ( 'input' ) ;
}
2023-11-15 10:58:47 +01:00
if ( power _user . enableZenSliders ) {
2023-12-02 20:11:06 +01:00
$ ( '#max_context_zenslider' ) . remove ( ) ;
CreateZenSliders ( $ ( '#max_context' ) ) ;
$ ( '#rep_pen_range_textgenerationwebui_zenslider' ) . remove ( ) ;
CreateZenSliders ( $ ( '#rep_pen_range_textgenerationwebui' ) ) ;
2024-05-22 19:46:52 +02:00
$ ( '#dry_penalty_last_n_textgenerationwebui_zenslider' ) . remove ( ) ;
CreateZenSliders ( $ ( '#dry_penalty_last_n_textgenerationwebui' ) ) ;
2024-05-22 22:37:51 +02:00
$ ( '#rep_pen_decay_textgenerationwebui_zenslider' ) . remove ( ) ;
CreateZenSliders ( $ ( '#rep_pen_decay_textgenerationwebui' ) ) ;
2023-11-15 10:58:47 +01:00
}
2023-07-20 19:32:15 +02:00
}
2023-10-20 07:56:17 +02:00
// Fetch a compiled object of all preset settings
function getContextSettings ( ) {
let compiledSettings = { } ;
contextControls . forEach ( ( control ) => {
let value = control . isGlobalSetting ? power _user [ control . property ] : power _user . context [ control . property ] ;
// Force to a boolean if the setting is a checkbox
if ( control . isCheckbox ) {
value = ! ! value ;
}
compiledSettings [ control . property ] = value ;
} ) ;
2023-08-17 21:47:34 +02:00
2023-10-20 07:56:17 +02:00
return compiledSettings ;
}
2023-08-17 21:47:34 +02:00
2023-10-20 07:56:17 +02:00
// TODO: Maybe add a refresh button to reset settings to preset
// TODO: Add "global state" if a preset doesn't set the power_user checkboxes
2024-08-05 05:03:46 +02:00
async function loadContextSettings ( ) {
2023-10-20 07:56:17 +02:00
contextControls . forEach ( control => {
2023-08-17 21:47:34 +02:00
const $element = $ ( ` # ${ control . id } ` ) ;
2023-10-26 14:01:31 +02:00
if ( control . isGlobalSetting ) {
return ;
}
2023-12-01 22:06:37 +01:00
if ( control . defaultValue !== undefined && power _user . context [ control . property ] === undefined ) {
power _user . context [ control . property ] = control . defaultValue ;
}
2023-08-17 21:47:34 +02:00
if ( control . isCheckbox ) {
$element . prop ( 'checked' , power _user . context [ control . property ] ) ;
} else {
2024-09-05 18:48:21 +02:00
$element . val ( power _user . context [ control . property ] ) ;
2023-08-17 21:47:34 +02:00
}
2024-08-05 07:30:15 +02:00
console . log ( ` Setting ${ $element . prop ( 'id' ) } to ${ power _user . context [ control . property ] } ` ) ;
2023-08-17 21:47:34 +02:00
2023-10-20 07:56:17 +02:00
// If the setting already exists, no need to duplicate it
// TODO: Maybe check the power_user object for the setting instead of a flag?
2024-09-05 18:48:21 +02:00
$element . on ( 'input' , async function ( ) {
const value = control . isCheckbox ? ! ! $ ( this ) . prop ( 'checked' ) : $ ( this ) . val ( ) ;
2023-10-20 07:56:17 +02:00
if ( control . isGlobalSetting ) {
power _user [ control . property ] = value ;
} else {
power _user . context [ control . property ] = value ;
}
2024-09-05 18:48:21 +02:00
console . log ( ` Setting ${ $element . prop ( 'id' ) } to ${ value } ` ) ;
2024-09-05 19:00:45 +02:00
if ( ! CSS . supports ( 'field-sizing' , 'content' ) ) {
2024-09-05 18:48:21 +02:00
await resetScrollHeight ( $ ( this ) ) ;
}
2023-08-17 21:47:34 +02:00
saveSettingsDebounced ( ) ;
} ) ;
} ) ;
context _presets . forEach ( ( preset ) => {
const name = preset . name ;
const option = document . createElement ( 'option' ) ;
option . value = name ;
option . innerText = name ;
option . selected = name === power _user . context . preset ;
$ ( '#context_presets' ) . append ( option ) ;
} ) ;
$ ( '#context_presets' ) . on ( 'change' , function ( ) {
2024-08-05 07:30:15 +02:00
const name = String ( $ ( this ) . find ( ':selected' ) . text ( ) ) ;
2023-08-17 21:47:34 +02:00
const preset = context _presets . find ( x => x . name === name ) ;
if ( ! preset ) {
return ;
}
power _user . context . preset = name ;
2023-10-20 07:56:17 +02:00
contextControls . forEach ( control => {
2023-10-27 20:02:03 +02:00
const presetValue = preset [ control . property ] ? ? control . defaultValue ;
if ( presetValue !== undefined ) {
2023-10-20 07:56:17 +02:00
if ( control . isGlobalSetting ) {
2023-10-27 20:02:03 +02:00
power _user [ control . property ] = presetValue ;
2023-10-20 07:56:17 +02:00
} else {
2023-10-27 20:02:03 +02:00
power _user . context [ control . property ] = presetValue ;
2023-10-20 07:56:17 +02:00
}
2023-08-17 21:47:34 +02:00
const $element = $ ( ` # ${ control . id } ` ) ;
if ( control . isCheckbox ) {
2023-10-21 03:50:33 +02:00
$element
. prop ( 'checked' , control . isGlobalSetting ? power _user [ control . property ] : power _user . context [ control . property ] )
. trigger ( 'input' ) ;
2023-08-17 21:47:34 +02:00
} else {
2024-09-05 18:48:21 +02:00
$element . val ( control . isGlobalSetting ? power _user [ control . property ] : power _user . context [ control . property ] ) ;
2024-08-05 07:30:15 +02:00
$element . trigger ( 'input' ) ;
2023-08-17 21:47:34 +02:00
}
}
} ) ;
2023-08-23 20:17:45 +02:00
2023-12-21 14:12:30 +01:00
if ( power _user . instruct . bind _to _context ) {
// Select matching instruct preset
for ( const instruct _preset of instruct _presets ) {
// If instruct preset matches the context template
if ( instruct _preset . name === name ) {
selectInstructPreset ( instruct _preset . name ) ;
break ;
}
2023-08-23 20:17:45 +02:00
}
}
2023-08-26 12:09:47 +02:00
highlightDefaultContext ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#context_set_default' ) . on ( 'click' , function ( ) {
if ( power _user . context . preset !== power _user . default _context ) {
power _user . default _context = power _user . context . preset ;
$ ( this ) . addClass ( 'default' ) ;
toastr . info ( ` Default context template set to ${ power _user . default _context } ` ) ;
highlightDefaultContext ( ) ;
saveSettingsDebounced ( ) ;
}
2023-08-17 21:47:34 +02:00
} ) ;
2023-08-26 12:09:47 +02:00
highlightDefaultContext ( ) ;
}
function highlightDefaultContext ( ) {
$ ( '#context_set_default' ) . toggleClass ( 'default' , power _user . default _context === power _user . context . preset ) ;
2023-08-26 14:52:23 +02:00
$ ( '#context_set_default' ) . toggleClass ( 'disabled' , power _user . default _context === power _user . context . preset ) ;
$ ( '#context_delete_preset' ) . toggleClass ( 'disabled' , power _user . default _context === power _user . context . preset ) ;
2023-08-17 21:47:34 +02:00
}
2024-04-30 04:30:39 +02:00
/ * *
* Fuzzy search characters by a search term
* @ param { string } searchValue - The search term
2024-05-10 04:48:30 +02:00
* @ returns { FuseResult [ ] } Results as items with their score
2024-04-30 04:30:39 +02:00
* /
2023-07-27 23:38:43 +02:00
export function fuzzySearchCharacters ( searchValue ) {
2024-04-30 01:39:47 +02:00
// @ts-ignore
2023-07-27 23:38:43 +02:00
const fuse = new Fuse ( characters , {
keys : [
2024-04-30 22:12:49 +02:00
{ name : 'data.name' , weight : 20 } ,
{ name : '#tags' , weight : 10 , getFn : ( character ) => getTagsList ( character . avatar ) . map ( x => x . name ) . join ( '||' ) } ,
2023-07-27 23:38:43 +02:00
{ name : 'data.description' , weight : 3 } ,
{ name : 'data.mes_example' , weight : 3 } ,
{ name : 'data.scenario' , weight : 2 } ,
{ name : 'data.personality' , weight : 2 } ,
{ name : 'data.first_mes' , weight : 2 } ,
{ name : 'data.creator_notes' , weight : 2 } ,
{ name : 'data.creator' , weight : 1 } ,
{ name : 'data.tags' , weight : 1 } ,
2023-12-02 21:06:57 +01:00
{ name : 'data.alternate_greetings' , weight : 1 } ,
2023-07-27 23:38:43 +02:00
] ,
includeScore : true ,
ignoreLocation : true ,
2024-04-30 23:12:52 +02:00
useExtendedSearch : true ,
2023-07-27 23:38:43 +02:00
threshold : 0.2 ,
} ) ;
const results = fuse . search ( searchValue ) ;
2023-08-14 16:35:48 +02:00
console . debug ( 'Characters fuzzy search results for ' + searchValue , results ) ;
2024-04-30 04:30:39 +02:00
return results ;
2023-07-27 23:38:43 +02:00
}
2024-04-30 01:39:47 +02:00
/ * *
* Fuzzy search world info entries by a search term
* @ param { * [ ] } data - WI items data array
* @ param { string } searchValue - The search term
2024-05-10 04:48:30 +02:00
* @ returns { FuseResult [ ] } Results as items with their score
2024-04-30 01:39:47 +02:00
* /
2023-08-22 00:51:31 +02:00
export function fuzzySearchWorldInfo ( data , searchValue ) {
2024-04-30 01:39:47 +02:00
// @ts-ignore
2023-08-22 00:51:31 +02:00
const fuse = new Fuse ( data , {
keys : [
2024-04-30 22:12:49 +02:00
{ name : 'key' , weight : 20 } ,
{ name : 'group' , weight : 15 } ,
{ name : 'comment' , weight : 10 } ,
{ name : 'keysecondary' , weight : 10 } ,
2023-08-22 00:51:31 +02:00
{ name : 'content' , weight : 3 } ,
{ name : 'uid' , weight : 1 } ,
2024-04-30 22:12:49 +02:00
{ name : 'automationId' , weight : 1 } ,
2023-08-22 00:51:31 +02:00
] ,
includeScore : true ,
ignoreLocation : true ,
2024-04-30 23:12:52 +02:00
useExtendedSearch : true ,
2023-08-22 00:51:31 +02:00
threshold : 0.2 ,
} ) ;
const results = fuse . search ( searchValue ) ;
console . debug ( 'World Info fuzzy search results for ' + searchValue , results ) ;
2024-04-30 01:39:47 +02:00
return results ;
2023-08-22 00:51:31 +02:00
}
2024-04-30 02:27:44 +02:00
/ * *
* Fuzzy search persona entries by a search term
* @ param { * [ ] } data - persona data array
* @ param { string } searchValue - The search term
2024-05-10 04:48:30 +02:00
* @ returns { FuseResult [ ] } Results as items with their score
2024-04-30 02:27:44 +02:00
* /
2024-01-30 18:12:56 +01:00
export function fuzzySearchPersonas ( data , searchValue ) {
2024-04-30 02:27:44 +02:00
data = data . map ( x => ( { key : x , name : power _user . personas [ x ] ? ? '' , description : power _user . persona _descriptions [ x ] ? . description ? ? '' } ) ) ;
2024-04-30 01:39:47 +02:00
// @ts-ignore
2024-01-30 18:12:56 +01:00
const fuse = new Fuse ( data , {
keys : [
2024-04-30 22:12:49 +02:00
{ name : 'name' , weight : 20 } ,
{ name : 'description' , weight : 3 } ,
2024-01-30 18:12:56 +01:00
] ,
includeScore : true ,
ignoreLocation : true ,
2024-04-30 23:12:52 +02:00
useExtendedSearch : true ,
2024-01-30 18:12:56 +01:00
threshold : 0.2 ,
} ) ;
const results = fuse . search ( searchValue ) ;
console . debug ( 'Personas fuzzy search results for ' + searchValue , results ) ;
2024-04-30 02:27:44 +02:00
return results ;
2024-01-30 18:12:56 +01:00
}
2024-04-30 04:30:39 +02:00
/ * *
* Fuzzy search tags by a search term
* @ param { string } searchValue - The search term
2024-05-10 04:48:30 +02:00
* @ returns { FuseResult [ ] } Results as items with their score
2024-04-30 04:30:39 +02:00
* /
2023-11-10 20:56:25 +01:00
export function fuzzySearchTags ( searchValue ) {
2024-04-30 01:39:47 +02:00
// @ts-ignore
2023-11-10 20:56:25 +01:00
const fuse = new Fuse ( tags , {
keys : [
2023-11-12 09:23:29 +01:00
{ name : 'name' , weight : 1 } ,
2023-11-10 20:56:25 +01:00
] ,
includeScore : true ,
ignoreLocation : true ,
2024-04-30 23:12:52 +02:00
useExtendedSearch : true ,
2023-12-02 21:06:57 +01:00
threshold : 0.2 ,
2023-11-10 20:56:25 +01:00
} ) ;
const results = fuse . search ( searchValue ) ;
console . debug ( 'Tags fuzzy search results for ' + searchValue , results ) ;
2024-04-30 04:30:39 +02:00
return results ;
2023-11-10 20:56:25 +01:00
}
2024-04-30 04:30:39 +02:00
/ * *
* Fuzzy search groups by a search term
* @ param { string } searchValue - The search term
2024-05-10 04:48:30 +02:00
* @ returns { FuseResult [ ] } Results as items with their score
2024-04-30 04:30:39 +02:00
* /
2023-08-14 16:35:48 +02:00
export function fuzzySearchGroups ( searchValue ) {
2024-04-30 01:39:47 +02:00
// @ts-ignore
2023-08-14 16:35:48 +02:00
const fuse = new Fuse ( groups , {
keys : [
2024-04-30 22:12:49 +02:00
{ name : 'name' , weight : 20 } ,
{ name : 'members' , weight : 15 } ,
{ name : '#tags' , weight : 10 , getFn : ( group ) => getTagsList ( group . id ) . map ( x => x . name ) . join ( '||' ) } ,
2024-04-30 05:40:31 +02:00
{ name : 'id' , weight : 1 } ,
2023-08-14 16:35:48 +02:00
] ,
includeScore : true ,
ignoreLocation : true ,
2024-04-30 23:12:52 +02:00
useExtendedSearch : true ,
2023-08-14 16:35:48 +02:00
threshold : 0.2 ,
} ) ;
const results = fuse . search ( searchValue ) ;
console . debug ( 'Groups fuzzy search results for ' + searchValue , results ) ;
2024-04-30 04:30:39 +02:00
return results ;
2023-08-14 16:35:48 +02:00
}
2023-08-26 00:32:39 +02:00
/ * *
* Renders a story string template with the given parameters .
* @ param { object } params Template parameters .
* @ returns { string } The rendered story string .
* /
2023-08-17 21:47:34 +02:00
export function renderStoryString ( params ) {
try {
2024-07-03 20:32:05 +02:00
// Validate and log possible warnings/errors
validateStoryString ( power _user . context . story _string , params ) ;
2023-08-26 00:32:39 +02:00
// compile the story string template into a function, with no HTML escaping
2023-08-18 12:53:54 +02:00
const compiledTemplate = Handlebars . compile ( power _user . context . story _string , { noEscape : true } ) ;
2023-08-26 00:32:39 +02:00
// render the story string template with the given params
2023-08-17 21:47:34 +02:00
let output = compiledTemplate ( params ) ;
2023-08-26 00:32:39 +02:00
// substitute {{macro}} params that are not defined in the story string
2023-08-17 21:47:34 +02:00
output = substituteParams ( output , params . user , params . char ) ;
2023-08-26 00:32:39 +02:00
2024-01-03 23:00:47 +01:00
// remove leading newlines
output = output . replace ( /^\n+/ , '' ) ;
2023-08-26 00:32:39 +02:00
// add a newline to the end of the story string if it doesn't have one
2023-10-18 10:44:45 +02:00
if ( output . length > 0 && ! output . endsWith ( '\n' ) ) {
2024-04-09 23:04:20 +02:00
if ( ! power _user . instruct . enabled || power _user . instruct . wrap ) {
output += '\n' ;
}
2023-08-26 00:32:39 +02:00
}
2023-08-17 21:47:34 +02:00
return output ;
} catch ( e ) {
toastr . error ( 'Check the story string template for validity' , 'Error rendering story string' ) ;
console . error ( 'Error rendering story string' , e ) ;
2023-08-26 00:32:39 +02:00
throw e ; // rethrow the error
2023-08-17 21:47:34 +02:00
}
}
2024-07-03 20:32:05 +02:00
/ * *
* Validate the story string for possible warnings or issues
*
* @ param { string } storyString - The story string
* @ param { Object } params - The story string parameters
* /
function validateStoryString ( storyString , params ) {
/** @type {{hashCache: {[hash: string]: {fieldsWarned: {[key: string]: boolean}}}}} */
const cache = JSON . parse ( localStorage . getItem ( storage _keys . storyStringValidationCache ) ) ? ? { hashCache : { } } ;
const hash = getStringHash ( storyString ) ;
// Initialize the cache for the current hash if it doesn't exist
if ( ! cache . hashCache [ hash ] ) {
cache . hashCache [ hash ] = { fieldsWarned : { } } ;
}
const currentCache = cache . hashCache [ hash ] ;
const fieldsToWarn = [ ] ;
function validateMissingField ( field , fallbackLegacyField = null ) {
const contains = storyString . includes ( ` {{ ${ field } }} ` ) || ( ! ! fallbackLegacyField && storyString . includes ( ` {{ ${ fallbackLegacyField } }} ` ) ) ;
if ( ! contains && params [ field ] ) {
const wasLogged = currentCache . fieldsWarned [ field ] ;
if ( ! wasLogged ) {
fieldsToWarn . push ( field ) ;
currentCache . fieldsWarned [ field ] = true ;
}
console . warn ( ` The story string does not contain {{ ${ field } }}, but it would contain content: \n ` , params [ field ] ) ;
}
}
validateMissingField ( 'description' ) ;
validateMissingField ( 'personality' ) ;
validateMissingField ( 'persona' ) ;
validateMissingField ( 'scenario' ) ;
2024-07-26 22:10:09 +02:00
// validateMissingField('system');
2024-07-03 20:32:05 +02:00
validateMissingField ( 'wiBefore' , 'loreBefore' ) ;
validateMissingField ( 'wiAfter' , 'loreAfter' ) ;
if ( fieldsToWarn . length > 0 ) {
const fieldsList = fieldsToWarn . map ( field => ` {{ ${ field } }} ` ) . join ( ', ' ) ;
toastr . warning ( ` The story string does not contain the following fields, but they would contain content: ${ fieldsList } ` , 'Story String Validation' ) ;
}
localStorage . setItem ( storage _keys . storyStringValidationCache , JSON . stringify ( cache ) ) ;
}
2023-07-20 19:32:15 +02:00
const sortFunc = ( a , b ) => power _user . sort _order == 'asc' ? compareFunc ( a , b ) : compareFunc ( b , a ) ;
const compareFunc = ( first , second ) => {
2023-09-10 13:30:29 +02:00
const a = first [ power _user . sort _field ] ;
const b = second [ power _user . sort _field ] ;
2023-08-31 18:30:56 +02:00
2023-09-10 13:30:29 +02:00
if ( power _user . sort _field === 'create_date' ) {
return sortMoments ( timestampToMoment ( b ) , timestampToMoment ( a ) ) ;
}
2023-08-31 18:30:56 +02:00
2023-09-10 13:30:29 +02:00
switch ( power _user . sort _rule ) {
case 'boolean' :
2023-07-20 19:32:15 +02:00
if ( a === true || a === 'true' ) return 1 ; // Prioritize 'true' or true
if ( b === true || b === 'true' ) return - 1 ; // Prioritize 'true' or true
if ( a && ! b ) return - 1 ; // Move truthy values to the end
if ( ! a && b ) return 1 ; // Move falsy values to the beginning
if ( a === b ) return 0 ; // Sort equal values normally
return a < b ? - 1 : 1 ; // Sort non-boolean values normally
default :
2023-12-02 19:04:51 +01:00
return typeof a == 'string'
2023-09-10 13:30:29 +02:00
? a . localeCompare ( b )
: a - b ;
2023-07-20 19:32:15 +02:00
}
} ;
2023-08-22 13:30:49 +02:00
/ * *
* Sorts an array of entities based on the current sort settings
* @ param { any [ ] } entities An array of objects with an ` item ` property
* /
2023-08-18 22:13:15 +02:00
function sortEntitiesList ( entities ) {
if ( power _user . sort _field == undefined || entities . length === 0 ) {
2023-07-20 19:32:15 +02:00
return ;
}
2023-12-10 04:37:49 +01:00
if ( power _user . sort _order === 'random' ) {
shuffle ( entities ) ;
return ;
}
2024-04-30 04:30:39 +02:00
const isSearch = $ ( '#character_sort_order option[data-field="search"]' ) . is ( ':selected' ) ;
2023-11-11 13:53:08 +01:00
entities . sort ( ( a , b ) => {
2024-04-30 04:30:39 +02:00
// Sort tags/folders will always be at the top
2023-11-11 13:53:08 +01:00
if ( a . type === 'tag' && b . type !== 'tag' ) {
return - 1 ;
}
if ( a . type !== 'tag' && b . type === 'tag' ) {
return 1 ;
}
2024-04-30 04:30:39 +02:00
// If we have search sorting, we take scores and use those
if ( isSearch ) {
const aScore = entitiesFilter . getScore ( FILTER _TYPES . SEARCH , ` ${ a . type } . ${ a . id } ` ) ;
const bScore = entitiesFilter . getScore ( FILTER _TYPES . SEARCH , ` ${ b . type } . ${ b . id } ` ) ;
return ( aScore - bScore ) ;
}
2023-11-11 13:53:08 +01:00
return sortFunc ( a . item , b . item ) ;
} ) ;
2023-07-20 19:32:15 +02:00
}
2023-08-22 13:30:49 +02:00
2023-12-16 00:45:48 +01:00
/ * *
* Updates the current UI theme file .
* /
async function updateTheme ( ) {
await saveTheme ( power _user . theme ) ;
toastr . success ( 'Theme saved.' ) ;
}
2023-07-20 19:32:15 +02:00
2024-03-19 23:14:32 +01:00
async function deleteTheme ( ) {
const themeName = power _user . theme ;
if ( ! themeName ) {
toastr . info ( 'No theme selected.' ) ;
return ;
}
2024-06-25 23:15:16 +02:00
const template = $ ( await renderTemplateAsync ( 'themeDelete' , { themeName } ) ) ;
const confirm = await callGenericPopup ( template , POPUP _TYPE . CONFIRM ) ;
2024-03-19 23:14:32 +01:00
if ( ! confirm ) {
return ;
}
const response = await fetch ( '/api/themes/delete' , {
method : 'POST' ,
headers : getRequestHeaders ( ) ,
body : JSON . stringify ( { name : themeName } ) ,
} ) ;
if ( ! response . ok ) {
toastr . error ( 'Failed to delete theme. Check the console for more information.' ) ;
return ;
}
const themeIndex = themes . findIndex ( x => x . name == themeName ) ;
if ( themeIndex !== - 1 ) {
themes . splice ( themeIndex , 1 ) ;
$ ( ` #themes option[value=" ${ themeName } "] ` ) . remove ( ) ;
power _user . theme = themes [ 0 ] ? . name ;
saveSettingsDebounced ( ) ;
if ( power _user . theme ) {
2024-09-04 21:15:29 +02:00
applyTheme ( power _user . theme ) ;
2024-03-19 23:14:32 +01:00
}
toastr . success ( 'Theme deleted.' ) ;
}
}
2024-02-10 22:12:16 +01:00
/ * *
* Exports the current theme to a file .
* /
async function exportTheme ( ) {
const themeFile = await saveTheme ( power _user . theme ) ;
const fileName = ` ${ themeFile . name } .json ` ;
download ( JSON . stringify ( themeFile , null , 4 ) , fileName , 'application/json' ) ;
}
/ * *
* Imports a theme from a file .
* @ param { File } file File to import .
* @ returns { Promise < void > } A promise that resolves when the theme is imported .
* /
async function importTheme ( file ) {
if ( ! file ) {
return ;
}
const fileText = await getFileText ( file ) ;
const parsed = JSON . parse ( fileText ) ;
if ( ! parsed . name ) {
throw new Error ( 'Missing name' ) ;
}
if ( themes . some ( t => t . name === parsed . name ) ) {
throw new Error ( 'Theme with that name already exists' ) ;
}
2024-03-14 23:22:10 +01:00
if ( typeof parsed . custom _css === 'string' && parsed . custom _css . includes ( '@import' ) ) {
2024-06-25 23:18:44 +02:00
const template = $ ( await renderTemplateAsync ( 'themeImportWarning' ) ) ;
const confirm = await callGenericPopup ( template , POPUP _TYPE . CONFIRM ) ;
2024-03-14 23:20:46 +01:00
if ( ! confirm ) {
throw new Error ( 'Theme contains @import lines' ) ;
}
}
2024-02-10 22:12:16 +01:00
themes . push ( parsed ) ;
2024-06-18 01:14:22 +02:00
await saveTheme ( parsed . name , getNewTheme ( parsed ) ) ;
2024-02-10 22:12:16 +01:00
const option = document . createElement ( 'option' ) ;
2024-06-18 01:14:22 +02:00
option . selected = false ;
2024-02-10 22:12:16 +01:00
option . value = parsed . name ;
option . innerText = parsed . name ;
$ ( '#themes' ) . append ( option ) ;
saveSettingsDebounced ( ) ;
2024-06-18 01:14:22 +02:00
toastr . success ( parsed . name , 'Theme imported' ) ;
2024-02-10 22:12:16 +01:00
}
2023-12-16 00:45:48 +01:00
/ * *
* Saves the current theme to the server .
* @ param { string | undefined } name Theme name . If undefined , a popup will be shown to enter a name .
2024-06-18 01:14:22 +02:00
* @ param { object | undefined } theme Theme object . If undefined , the current theme will be saved .
2024-02-10 22:12:16 +01:00
* @ returns { Promise < object > } A promise that resolves when the theme is saved .
2023-12-16 00:45:48 +01:00
* /
2024-06-18 01:14:22 +02:00
async function saveTheme ( name = undefined , theme = undefined ) {
2023-12-16 00:45:48 +01:00
if ( typeof name !== 'string' ) {
2024-06-25 23:24:21 +02:00
const newName = await callGenericPopup ( 'Enter a theme preset name:' , POPUP _TYPE . INPUT , power _user . theme ) ;
2023-12-16 00:45:48 +01:00
2024-06-25 23:24:21 +02:00
if ( ! newName ) {
2023-12-16 00:45:48 +01:00
return ;
}
2024-06-25 23:24:21 +02:00
name = String ( newName ) ;
2023-07-20 19:32:15 +02:00
}
2024-06-18 01:14:22 +02:00
if ( typeof theme !== 'object' ) {
theme = getThemeObject ( name ) ;
}
const response = await fetch ( '/api/themes/save' , {
method : 'POST' ,
headers : getRequestHeaders ( ) ,
body : JSON . stringify ( theme ) ,
} ) ;
2024-06-28 03:28:16 +02:00
if ( ! response . ok ) {
toastr . error ( 'Check the server connection and reload the page to prevent data loss.' , 'Theme could not be saved' ) ;
console . error ( 'Theme could not be saved' , response ) ;
2024-06-28 11:01:28 +02:00
throw new Error ( 'Theme could not be saved' ) ;
2024-06-28 03:28:16 +02:00
}
2024-06-18 01:14:22 +02:00
2024-06-28 03:28:16 +02:00
const themeIndex = themes . findIndex ( x => x . name == name ) ;
2024-06-18 01:14:22 +02:00
2024-06-28 03:28:16 +02:00
if ( themeIndex == - 1 ) {
themes . push ( theme ) ;
const option = document . createElement ( 'option' ) ;
option . selected = true ;
option . value = name ;
option . innerText = name ;
$ ( '#themes' ) . append ( option ) ;
}
else {
themes [ themeIndex ] = theme ;
$ ( ` #themes option[value=" ${ name } "] ` ) . attr ( 'selected' , true ) ;
2024-06-18 01:14:22 +02:00
}
2024-06-28 03:28:16 +02:00
power _user . theme = name ;
saveSettingsDebounced ( ) ;
2024-06-18 01:14:22 +02:00
return theme ;
}
/ * *
* Gets a snapshot of the current theme settings .
* @ param { string } name Name of the theme
* @ returns { object } Theme object
* /
function getThemeObject ( name ) {
return {
2023-07-20 19:32:15 +02:00
name ,
blur _strength : power _user . blur _strength ,
main _text _color : power _user . main _text _color ,
italics _text _color : power _user . italics _text _color ,
2024-03-01 06:33:37 +01:00
underline _text _color : power _user . underline _text _color ,
2023-07-20 19:32:15 +02:00
quote _text _color : power _user . quote _text _color ,
blur _tint _color : power _user . blur _tint _color ,
2023-09-22 09:54:51 +02:00
chat _tint _color : power _user . chat _tint _color ,
2023-07-20 19:32:15 +02:00
user _mes _blur _tint _color : power _user . user _mes _blur _tint _color ,
bot _mes _blur _tint _color : power _user . bot _mes _blur _tint _color ,
shadow _color : power _user . shadow _color ,
shadow _width : power _user . shadow _width ,
2023-09-16 08:42:26 +02:00
border _color : power _user . border _color ,
2023-07-20 19:32:15 +02:00
font _scale : power _user . font _scale ,
fast _ui _mode : power _user . fast _ui _mode ,
waifuMode : power _user . waifuMode ,
avatar _style : power _user . avatar _style ,
chat _display : power _user . chat _display ,
noShadows : power _user . noShadows ,
chat _width : power _user . chat _width ,
timer _enabled : power _user . timer _enabled ,
timestamps _enabled : power _user . timestamps _enabled ,
2023-08-14 00:43:16 +02:00
timestamp _model _icon : power _user . timestamp _model _icon ,
2023-09-22 15:16:24 +02:00
2023-07-20 19:32:15 +02:00
mesIDDisplay _enabled : power _user . mesIDDisplay _enabled ,
2024-04-25 05:51:56 +02:00
hideChatAvatars _enabled : power _user . hideChatAvatars _enabled ,
2023-09-22 15:16:24 +02:00
message _token _count _enabled : power _user . message _token _count _enabled ,
expand _message _actions : power _user . expand _message _actions ,
2023-11-04 21:47:53 +01:00
enableZenSliders : power _user . enableZenSliders ,
2023-11-10 08:17:38 +01:00
enableLabMode : power _user . enableLabMode ,
2023-07-20 19:32:15 +02:00
hotswap _enabled : power _user . hotswap _enabled ,
2023-09-22 20:13:58 +02:00
custom _css : power _user . custom _css ,
2023-11-10 20:56:25 +01:00
bogus _folders : power _user . bogus _folders ,
2024-04-14 16:59:51 +02:00
zoomed _avatar _magnification : power _user . zoomed _avatar _magnification ,
2023-12-16 00:35:28 +01:00
reduced _motion : power _user . reduced _motion ,
compact _input _area : power _user . compact _input _area ,
2023-07-20 19:32:15 +02:00
} ;
2024-06-18 01:14:22 +02:00
}
2023-07-20 19:32:15 +02:00
2024-06-18 01:14:22 +02:00
/ * *
* Applies imported theme properties to the theme object .
* @ param { object } parsed Parsed object to get the theme from .
* @ returns { object } Theme assigned to the parsed object .
* /
function getNewTheme ( parsed ) {
const theme = getThemeObject ( parsed . name ) ;
for ( const key in parsed ) {
if ( Object . hasOwn ( theme , key ) ) {
theme [ key ] = parsed [ key ] ;
2023-07-20 19:32:15 +02:00
}
}
2024-02-10 22:12:16 +01:00
return theme ;
2023-07-20 19:32:15 +02:00
}
async function saveMovingUI ( ) {
2024-06-28 11:01:28 +02:00
const popupResult = await callGenericPopup ( 'Enter a name for the MovingUI Preset:' , POPUP _TYPE . INPUT ) ;
2023-07-20 19:32:15 +02:00
2024-06-28 11:01:28 +02:00
if ( ! popupResult ) {
2023-07-20 19:32:15 +02:00
return ;
}
2024-06-28 11:01:28 +02:00
const name = String ( popupResult ) ;
2023-07-20 19:32:15 +02:00
const movingUIPreset = {
name ,
2023-12-02 21:06:57 +01:00
movingUIState : power _user . movingUIState ,
2023-12-02 20:11:06 +01:00
} ;
console . log ( movingUIPreset ) ;
2023-07-20 19:32:15 +02:00
2024-03-20 00:07:28 +01:00
const response = await fetch ( '/api/moving-ui/save' , {
2023-07-20 19:32:15 +02:00
method : 'POST' ,
headers : getRequestHeaders ( ) ,
2023-12-02 21:06:57 +01:00
body : JSON . stringify ( movingUIPreset ) ,
2023-07-20 19:32:15 +02:00
} ) ;
if ( response . ok ) {
const movingUIPresetIndex = movingUIPresets . findIndex ( x => x . name == name ) ;
if ( movingUIPresetIndex == - 1 ) {
movingUIPresets . push ( movingUIPreset ) ;
const option = document . createElement ( 'option' ) ;
option . selected = true ;
option . value = name ;
option . innerText = name ;
$ ( '#movingUIPresets' ) . append ( option ) ;
}
else {
movingUIPresets [ movingUIPresetIndex ] = movingUIPreset ;
$ ( ` #movingUIPresets option[value=" ${ name } "] ` ) . attr ( 'selected' , true ) ;
}
power _user . movingUIPreset = name ;
saveSettingsDebounced ( ) ;
} else {
2024-06-28 11:01:28 +02:00
toastr . error ( 'Failed to save MovingUI state.' ) ;
2024-06-28 03:28:16 +02:00
console . error ( 'MovingUI could not be saved' , response ) ;
2023-07-20 19:32:15 +02:00
}
}
2024-03-19 00:40:02 +01:00
/ * *
* Resets the movable styles of the given element to their unset values .
* @ param { string } id Element ID
* /
export function resetMovableStyles ( id ) {
const panelStyles = [ 'top' , 'left' , 'right' , 'bottom' , 'height' , 'width' , 'margin' ] ;
const panel = document . getElementById ( id ) ;
if ( panel ) {
panelStyles . forEach ( ( style ) => {
panel . style [ style ] = '' ;
} ) ;
}
}
2023-07-20 19:32:15 +02:00
async function resetMovablePanels ( type ) {
const panelIds = [
'sheld' ,
'left-nav-panel' ,
'right-nav-panel' ,
'WorldInfo' ,
'floatingPrompt' ,
'expression-holder' ,
2023-10-09 21:49:35 +02:00
'groupMemberListPopout' ,
2023-10-13 17:29:41 +02:00
'summaryExtensionPopout' ,
2023-12-02 21:06:57 +01:00
'gallery' ,
2024-03-19 00:40:02 +01:00
'logprobsViewer' ,
'cfgConfig' ,
2023-07-20 19:32:15 +02:00
] ;
2024-05-02 00:34:47 +02:00
/ * *
* @ type { HTMLElement [ ] } Generic panels that don ' t have a known ID
* /
const draggedElements = Array . from ( document . querySelectorAll ( '[data-dragged]' ) ) ;
const allDraggable = panelIds . map ( id => document . getElementById ( id ) ) . concat ( draggedElements ) . filter ( onlyUnique ) ;
2023-07-20 19:32:15 +02:00
2024-05-02 00:34:47 +02:00
const panelStyles = [ 'top' , 'left' , 'right' , 'bottom' , 'height' , 'width' , 'margin' ] ;
allDraggable . forEach ( ( panel ) => {
2023-07-20 19:32:15 +02:00
if ( panel ) {
$ ( panel ) . addClass ( 'resizing' ) ;
panelStyles . forEach ( ( style ) => {
panel . style [ style ] = '' ;
} ) ;
}
} ) ;
2024-05-02 00:34:47 +02:00
/ * *
* @ type { HTMLElement [ ] } Zoomed avatars that are currently being resized
* /
const zoomedAvatars = Array . from ( document . querySelectorAll ( '.zoomed_avatar' ) ) ;
2023-07-20 19:32:15 +02:00
if ( zoomedAvatars . length > 0 ) {
zoomedAvatars . forEach ( ( avatar ) => {
avatar . classList . add ( 'resizing' ) ;
panelStyles . forEach ( ( style ) => {
avatar . style [ style ] = '' ;
} ) ;
} ) ;
}
$ ( '[data-dragged="true"]' ) . removeAttr ( 'data-dragged' ) ;
2023-12-02 20:11:06 +01:00
await delay ( 50 ) ;
2023-07-20 19:32:15 +02:00
power _user . movingUIState = { } ;
//if user manually resets panels, deselect the current preset
if ( type !== 'quiet' && type !== 'resize' ) {
2023-12-02 20:11:06 +01:00
power _user . movingUIPreset = 'Default' ;
2023-12-02 19:04:51 +01:00
$ ( '#movingUIPresets option[value="Default"]' ) . prop ( 'selected' , true ) ;
2023-07-20 19:32:15 +02:00
}
saveSettingsDebounced ( ) ;
eventSource . emit ( event _types . MOVABLE _PANELS _RESET ) ;
eventSource . once ( event _types . SETTINGS _UPDATED , ( ) => {
2023-12-02 19:04:51 +01:00
$ ( '.resizing' ) . removeClass ( 'resizing' ) ;
2023-07-20 19:32:15 +02:00
//if happening as part of preset application, do it quietly.
if ( type === 'quiet' ) {
2023-12-02 20:11:06 +01:00
return ;
2023-07-22 17:09:50 +02:00
//if happening due to resize, tell user.
2023-07-20 19:32:15 +02:00
} else if ( type === 'resize' ) {
toastr . warning ( 'Panel positions reset due to zoom/resize' ) ;
2023-07-22 17:09:50 +02:00
//if happening due to manual button press
2023-07-20 19:32:15 +02:00
} else {
toastr . success ( 'Panel positions reset' ) ;
}
} ) ;
}
2024-04-20 01:43:51 +02:00
/ * *
* Finds the ID of the tag with the given name .
* @ param { string } name
* @ returns { string } The ID of the tag with the given name .
* /
function findTagIdByName ( name ) {
const matchTypes = [
( a , b ) => a === b ,
( a , b ) => a . startsWith ( b ) ,
( a , b ) => a . includes ( b ) ,
] ;
// Only get tags that contain at least one record in the tag_map
const liveTagIds = new Set ( Object . values ( tag _map ) . flat ( ) ) ;
const liveTags = tags . filter ( x => liveTagIds . has ( x . id ) ) ;
const exactNameMatchIndex = liveTags . map ( x => x . name . toLowerCase ( ) ) . indexOf ( name . toLowerCase ( ) ) ;
if ( exactNameMatchIndex !== - 1 ) {
return liveTags [ exactNameMatchIndex ] . id ;
}
for ( const matchType of matchTypes ) {
const index = liveTags . findIndex ( x => matchType ( x . name . toLowerCase ( ) , name . toLowerCase ( ) ) ) ;
if ( index !== - 1 ) {
return liveTags [ index ] . id ;
}
}
}
async function doRandomChat ( _ , tagName ) {
/ * *
* Gets the ID of a random character .
* @ returns { string } The order index of the randomly selected character .
* /
function getRandomCharacterId ( ) {
if ( ! tagName ) {
return Math . floor ( Math . random ( ) * characters . length ) . toString ( ) ;
}
const tagId = findTagIdByName ( tagName ) ;
const taggedCharacters = Object . entries ( tag _map )
. filter ( x => x [ 1 ] . includes ( tagId ) ) // Get only records that include the tag
. map ( x => x [ 0 ] ) // Map the character avatar
. filter ( x => characters . find ( y => y . avatar === x ) ) ; // Filter out characters that don't exist
const randomCharacter = taggedCharacters [ Math . floor ( Math . random ( ) * taggedCharacters . length ) ] ;
2024-04-25 05:51:56 +02:00
const randomIndex = characters . findIndex ( x => x . avatar === randomCharacter ) ;
2024-04-20 01:43:51 +02:00
if ( randomIndex === - 1 ) {
return ;
}
return randomIndex . toString ( ) ;
}
2023-07-20 19:32:15 +02:00
resetSelectedGroup ( ) ;
2024-04-20 01:43:51 +02:00
const characterId = getRandomCharacterId ( ) ;
if ( ! characterId ) {
toastr . error ( 'No characters found' ) ;
return ;
}
2023-11-27 01:18:36 +01:00
setCharacterId ( characterId ) ;
2024-03-26 17:30:12 +01:00
setActiveCharacter ( characters [ characterId ] ? . avatar ) ;
setActiveGroup ( null ) ;
2023-11-27 01:18:36 +01:00
await delay ( 1 ) ;
await reloadCurrentChat ( ) ;
return characters [ characterId ] ? . name ;
2023-07-20 19:32:15 +02:00
}
2023-11-08 22:27:03 +01:00
/ * *
* Loads the chat until the given message ID is displayed .
* @ param { number } mesId
* @ returns JQuery < HTMLElement >
* /
async function loadUntilMesId ( mesId ) {
let target ;
while ( getFirstDisplayedMessageId ( ) > mesId && getFirstDisplayedMessageId ( ) !== 0 ) {
showMoreMessages ( ) ;
await delay ( 1 ) ;
2023-12-02 19:04:51 +01:00
target = $ ( '#chat' ) . find ( ` .mes[mesid= ${ mesId } ] ` ) ;
2023-11-08 22:27:03 +01:00
if ( target . length ) {
break ;
}
}
if ( ! target . length ) {
2023-12-02 20:11:06 +01:00
toastr . error ( ` Could not find message with ID: ${ mesId } ` ) ;
2023-11-08 22:27:03 +01:00
return target ;
}
return target ;
}
2023-07-20 19:32:15 +02:00
async function doMesCut ( _ , text ) {
2023-12-02 20:11:06 +01:00
console . debug ( ` was asked to cut message id # ${ text } ` ) ;
2023-11-08 22:04:32 +01:00
const range = stringToRange ( text , 0 , chat . length - 1 ) ;
2023-07-20 19:32:15 +02:00
//reject invalid args or no args
2023-11-08 22:04:32 +01:00
if ( ! range ) {
2023-12-02 20:11:06 +01:00
toastr . warning ( 'Must provide a Message ID or a range to cut.' ) ;
return ;
2023-07-20 19:32:15 +02:00
}
2023-11-08 22:04:32 +01:00
let totalMesToCut = ( range . end - range . start ) + 1 ;
let mesIDToCut = range . start ;
2024-04-18 17:12:10 +02:00
let cutText = '' ;
2023-07-20 19:32:15 +02:00
2023-11-08 22:04:32 +01:00
for ( let i = 0 ; i < totalMesToCut ; i ++ ) {
2024-04-18 17:12:10 +02:00
cutText += ( chat [ mesIDToCut ] ? . mes || '' ) + '\n' ;
2023-11-08 22:04:32 +01:00
let done = false ;
2023-12-02 20:11:06 +01:00
let mesToCut = $ ( '#chat' ) . find ( ` .mes[mesid= ${ mesIDToCut } ] ` ) ;
2023-07-20 19:32:15 +02:00
2023-11-08 22:04:32 +01:00
if ( ! mesToCut . length ) {
2023-11-08 22:27:03 +01:00
mesToCut = await loadUntilMesId ( mesIDToCut ) ;
2023-07-20 19:32:15 +02:00
2023-11-08 22:27:03 +01:00
if ( ! mesToCut || ! mesToCut . length ) {
2023-11-08 22:04:32 +01:00
return ;
}
}
setEditedMessageId ( mesIDToCut ) ;
eventSource . once ( event _types . MESSAGE _DELETED , ( ) => {
done = true ;
} ) ;
mesToCut . find ( '.mes_edit_delete' ) . trigger ( 'click' , { fromSlashCommand : true } ) ;
while ( ! done ) {
await delay ( 1 ) ;
}
}
2024-04-18 17:12:10 +02:00
return cutText ;
2023-11-08 22:04:32 +01:00
}
2023-07-20 19:32:15 +02:00
async function doDelMode ( _ , text ) {
//reject invalid args
if ( text && isNaN ( text ) ) {
2023-12-02 20:11:06 +01:00
toastr . warning ( 'Must enter a number or nothing.' ) ;
2024-06-15 21:35:38 +02:00
return '' ;
2023-07-20 19:32:15 +02:00
}
2024-07-11 20:35:39 +02:00
// Just enter the delete mode.
if ( ! text ) {
$ ( '#option_delete_mes' ) . trigger ( 'click' , { fromSlashCommand : true } ) ;
return '' ;
}
2023-11-08 22:27:03 +01:00
2024-07-11 20:35:39 +02:00
const count = Number ( text ) ;
2023-11-08 22:27:03 +01:00
2024-07-11 20:35:39 +02:00
// Nothing to delete.
if ( count < 1 ) {
return '' ;
}
2023-07-20 19:32:15 +02:00
2024-07-11 20:35:39 +02:00
if ( count > chat . length ) {
toastr . warning ( ` Cannot delete more than ${ chat . length } messages. ` ) ;
2024-06-15 21:35:38 +02:00
return '' ;
2023-07-20 19:32:15 +02:00
}
2024-06-15 21:35:38 +02:00
2024-07-11 20:35:39 +02:00
const range = ` ${ chat . length - count } - ${ chat . length - 1 } ` ;
return doMesCut ( _ , range ) ;
2023-07-20 19:32:15 +02:00
}
function doResetPanels ( ) {
2023-12-02 19:04:51 +01:00
$ ( '#movingUIreset' ) . trigger ( 'click' ) ;
2024-06-15 21:35:38 +02:00
return '' ;
2023-07-20 19:32:15 +02:00
}
function setAvgBG ( ) {
const bgimg = new Image ( ) ;
bgimg . src = $ ( '#bg1' )
. css ( 'background-image' )
. replace ( /^url\(['"]?/ , '' )
. replace ( /['"]?\)$/ , '' ) ;
/ * c o n s t c h a r A v a t a r = n e w I m a g e ( )
charAvatar . src = $ ( "#avatar_load_preview" )
. attr ( 'src' )
. replace ( /^url\(['"]?/ , '' )
. replace ( /['"]?\)$/ , '' ) ;
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
const userAvatar = new Image ( )
userAvatar . src = $ ( "#user_avatar_block .avatar.selected img" )
. attr ( 'src' )
. replace ( /^url\(['"]?/ , '' )
. replace ( /['"]?\)$/ , '' ) ; * /
bgimg . onload = function ( ) {
var rgb = getAverageRGB ( bgimg ) ;
//console.log(`average color of the bg is:`)
//console.log(rgb);
2023-12-02 19:04:51 +01:00
$ ( '#blur-tint-color-picker' ) . attr ( 'color' , 'rgb(' + rgb . r + ',' + rgb . g + ',' + rgb . b + ')' ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
const backgroundColorString = $ ( '#blur-tint-color-picker' ) . attr ( 'color' )
2023-07-20 19:32:15 +02:00
. replace ( 'rgba' , '' )
. replace ( 'rgb' , '' )
. replace ( '(' , '[' )
. replace ( ')' , ']' ) ; //[50, 120, 200, 1]; // Example background color
2023-12-02 20:11:06 +01:00
const backgroundColorArray = JSON . parse ( backgroundColorString ) ; //[200, 200, 200, 1]
console . log ( backgroundColorArray ) ;
2023-12-02 19:04:51 +01:00
$ ( '#main-text-color-picker' ) . attr ( 'color' , getReadableTextColor ( backgroundColorArray ) ) ;
console . log ( $ ( '#main-text-color-picker' ) . attr ( 'color' ) ) ; // Output: 'rgba(0, 47, 126, 1)'
2023-12-02 20:11:06 +01:00
} ;
2023-07-20 19:32:15 +02:00
/ * c h a r A v a t a r . o n l o a d = f u n c t i o n ( ) {
var rgb = getAverageRGB ( charAvatar ) ;
//console.log(`average color of the AI avatar is:`);
//console.log(rgb);
$ ( "#bot-mes-blur-tint-color-picker" ) . attr ( 'color' , 'rgb(' + rgb . r + ',' + rgb . g + ',' + rgb . b + ')' ) ;
}
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
userAvatar . onload = function ( ) {
var rgb = getAverageRGB ( userAvatar ) ;
//console.log(`average color of the user avatar is:`);
//console.log(rgb);
$ ( "#user-mes-blur-tint-color-picker" ) . attr ( 'color' , 'rgb(' + rgb . r + ',' + rgb . g + ',' + rgb . b + ')' ) ;
} * /
function getAverageRGB ( imgEl ) {
var blockSize = 5 , // only visit every 5 pixels
defaultRGB = { r : 0 , g : 0 , b : 0 } , // for non-supporting envs
canvas = document . createElement ( 'canvas' ) ,
context = canvas . getContext && canvas . getContext ( '2d' ) ,
data , width , height ,
i = - 4 ,
length ,
rgb = { r : 0 , g : 0 , b : 0 } ,
count = 0 ;
if ( ! context ) {
return defaultRGB ;
}
height = canvas . height = imgEl . naturalHeight || imgEl . offsetHeight || imgEl . height ;
width = canvas . width = imgEl . naturalWidth || imgEl . offsetWidth || imgEl . width ;
context . drawImage ( imgEl , 0 , 0 ) ;
try {
data = context . getImageData ( 0 , 0 , width , height ) ;
} catch ( e ) {
2023-12-02 20:56:16 +01:00
/* security error, img on diff domain */ alert ( 'x' ) ;
2023-07-20 19:32:15 +02:00
return defaultRGB ;
}
length = data . data . length ;
while ( ( i += blockSize * 4 ) < length ) {
++ count ;
rgb . r += data . data [ i ] ;
rgb . g += data . data [ i + 1 ] ;
rgb . b += data . data [ i + 2 ] ;
}
// ~~ used to floor values
rgb . r = ~ ~ ( rgb . r / count ) ;
rgb . g = ~ ~ ( rgb . g / count ) ;
rgb . b = ~ ~ ( rgb . b / count ) ;
return rgb ;
}
2023-08-22 13:30:49 +02:00
/ * *
* Converts an HSL color value to RGB .
* @ param { number } h Hue value
* @ param { number } s Saturation value
* @ param { number } l Luminance value
* @ return { Array } The RGB representation
* /
2023-07-20 19:32:15 +02:00
function hslToRgb ( h , s , l ) {
const hueToRgb = ( p , q , t ) => {
if ( t < 0 ) t += 1 ;
if ( t > 1 ) t -= 1 ;
if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t ;
if ( t < 1 / 2 ) return q ;
if ( t < 2 / 3 ) return p + ( q - p ) * ( 2 / 3 - t ) * 6 ;
return p ;
} ;
if ( s === 0 ) {
return [ l , l , l ] ;
}
const q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s ;
const p = 2 * l - q ;
const r = hueToRgb ( p , q , h + 1 / 3 ) ;
const g = hueToRgb ( p , q , h ) ;
const b = hueToRgb ( p , q , h - 1 / 3 ) ;
return [ r * 255 , g * 255 , b * 255 ] ;
}
//this version keeps BG and main text in same hue
/ * f u n c t i o n g e t R e a d a b l e T e x t C o l o r ( r g b ) {
const [ r , g , b ] = rgb ;
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
// Convert RGB to HSL
const rgbToHsl = ( r , g , b ) => {
const max = Math . max ( r , g , b ) ;
const min = Math . min ( r , g , b ) ;
const d = max - min ;
const l = ( max + min ) / 2 ;
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
if ( d === 0 ) return [ 0 , 0 , l ] ;
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
const s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min ) ;
const h = ( ( ) => {
switch ( max ) {
case r :
return ( g - b ) / d + ( g < b ? 6 : 0 ) ;
case g :
return ( b - r ) / d + 2 ;
case b :
return ( r - g ) / d + 4 ;
}
} ) ( ) / 6 ;
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
return [ h , s , l ] ;
} ;
const [ h , s , l ] = rgbToHsl ( r / 255 , g / 255 , b / 255 ) ;
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
// Calculate appropriate text color based on background color
const targetLuminance = l > 0.5 ? 0.2 : 0.8 ;
const targetSaturation = s > 0.5 ? s - 0.2 : s + 0.2 ;
const [ rNew , gNew , bNew ] = hslToRgb ( h , targetSaturation , targetLuminance ) ;
2023-11-05 18:55:53 +01:00
2023-07-20 19:32:15 +02:00
// Return the text color in RGBA format
return ` rgba( ${ rNew . toFixed ( 0 ) } , ${ gNew . toFixed ( 0 ) } , ${ bNew . toFixed ( 0 ) } , 1) ` ;
} * /
//this version makes main text complimentary color to BG color
function getReadableTextColor ( rgb ) {
const [ r , g , b ] = rgb ;
// Convert RGB to HSL
const rgbToHsl = ( r , g , b ) => {
const max = Math . max ( r , g , b ) ;
const min = Math . min ( r , g , b ) ;
const d = max - min ;
const l = ( max + min ) / 2 ;
if ( d === 0 ) return [ 0 , 0 , l ] ;
const s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min ) ;
const h = ( ( ) => {
switch ( max ) {
case r :
return ( g - b ) / d + ( g < b ? 6 : 0 ) ;
case g :
return ( b - r ) / d + 2 ;
case b :
return ( r - g ) / d + 4 ;
}
} ) ( ) / 6 ;
return [ h , s , l ] ;
} ;
const [ h , s , l ] = rgbToHsl ( r / 255 , g / 255 , b / 255 ) ;
// Calculate complementary color based on background color
const complementaryHue = ( h + 0.5 ) % 1 ;
const complementarySaturation = s > 0.5 ? s - 0.6 : s + 0.6 ;
const complementaryLuminance = l > 0.5 ? 0.2 : 0.8 ;
// Convert complementary color back to RGB
const [ rNew , gNew , bNew ] = hslToRgb ( complementaryHue , complementarySaturation , complementaryLuminance ) ;
// Return the text color in RGBA format
return ` rgba( ${ rNew . toFixed ( 0 ) } , ${ gNew . toFixed ( 0 ) } , ${ bNew . toFixed ( 0 ) } , 1) ` ;
}
2024-06-17 03:30:52 +02:00
return '' ;
2023-07-20 19:32:15 +02:00
}
2024-07-28 01:15:55 +02:00
async function setThemeCallback ( _ , themeName ) {
if ( ! themeName ) {
// allow reporting of the theme name if called without args
// for use in ST Scripts via pipe
return power _user . theme ;
}
2024-04-30 01:39:47 +02:00
// @ts-ignore
2023-11-15 23:57:23 +01:00
const fuse = new Fuse ( themes , {
keys : [
{ name : 'name' , weight : 1 } ,
] ,
} ) ;
2024-07-28 01:15:55 +02:00
const results = fuse . search ( themeName ) ;
console . debug ( 'Theme fuzzy search results for ' + themeName , results ) ;
2023-11-15 23:57:23 +01:00
const theme = results [ 0 ] ? . item ;
if ( ! theme ) {
2024-07-28 01:15:55 +02:00
toastr . warning ( ` Could not find theme with name: ${ themeName } ` ) ;
2023-11-15 23:57:23 +01:00
return ;
}
power _user . theme = theme . name ;
applyTheme ( theme . name ) ;
2023-12-02 19:04:51 +01:00
$ ( '#themes' ) . val ( theme . name ) ;
2023-11-15 23:57:23 +01:00
saveSettingsDebounced ( ) ;
2024-06-15 21:35:38 +02:00
return '' ;
2023-11-15 23:57:23 +01:00
}
2023-08-25 23:12:11 +02:00
2023-11-23 14:32:47 +01:00
async function setmovingUIPreset ( _ , text ) {
2024-04-30 01:39:47 +02:00
// @ts-ignore
2023-11-23 14:32:47 +01:00
const fuse = new Fuse ( movingUIPresets , {
keys : [
{ name : 'name' , weight : 1 } ,
] ,
} ) ;
const results = fuse . search ( text ) ;
console . debug ( 'movingUI preset fuzzy search results for ' + text , results ) ;
const preset = results [ 0 ] ? . item ;
if ( ! preset ) {
toastr . warning ( ` Could not find preset with name: ${ text } ` ) ;
return ;
}
power _user . movingUIPreset = preset . name ;
applyMovingUIPreset ( preset . name ) ;
2023-12-02 19:04:51 +01:00
$ ( '#movingUIPresets' ) . val ( preset . name ) ;
2023-11-23 14:32:47 +01:00
saveSettingsDebounced ( ) ;
2024-06-15 21:35:38 +02:00
return '' ;
2023-11-23 14:32:47 +01:00
}
2023-11-23 23:51:27 +01:00
const EPHEMERAL _STOPPING _STRINGS = [ ] ;
/ * *
* Adds a stopping string to the list of stopping strings that are only used for the next generation .
* @ param { string } value The stopping string to add
* /
export function addEphemeralStoppingString ( value ) {
if ( ! EPHEMERAL _STOPPING _STRINGS . includes ( value ) ) {
console . debug ( 'Adding ephemeral stopping string:' , value ) ;
EPHEMERAL _STOPPING _STRINGS . push ( value ) ;
}
}
export function flushEphemeralStoppingStrings ( ) {
2023-11-24 18:06:31 +01:00
if ( EPHEMERAL _STOPPING _STRINGS . length === 0 ) {
return ;
}
2023-11-23 23:51:27 +01:00
console . debug ( 'Flushing ephemeral stopping strings:' , EPHEMERAL _STOPPING _STRINGS ) ;
2023-11-24 18:10:09 +01:00
EPHEMERAL _STOPPING _STRINGS . splice ( 0 , EPHEMERAL _STOPPING _STRINGS . length ) ;
2023-11-23 23:51:27 +01:00
}
2023-08-25 23:12:11 +02:00
/ * *
* Gets the custom stopping strings from the power user settings .
2023-08-28 23:47:35 +02:00
* @ param { number | undefined } limit Number of strings to return . If 0 or undefined , returns all strings .
2023-08-25 23:12:11 +02:00
* @ returns { string [ ] } An array of custom stopping strings
* /
export function getCustomStoppingStrings ( limit = undefined ) {
2023-11-23 23:51:27 +01:00
function getPermanent ( ) {
try {
// If there's no custom stopping strings, return an empty array
if ( ! power _user . custom _stopping _strings ) {
return [ ] ;
}
2023-08-25 23:12:11 +02:00
2023-11-23 23:51:27 +01:00
// Parse the JSON string
let strings = JSON . parse ( power _user . custom _stopping _strings ) ;
2023-07-20 19:32:15 +02:00
2023-11-23 23:51:27 +01:00
// Make sure it's an array
if ( ! Array . isArray ( strings ) ) {
return [ ] ;
}
2023-07-20 19:32:15 +02:00
2023-11-23 23:51:27 +01:00
// Make sure all the elements are strings and non-empty.
strings = strings . filter ( s => typeof s === 'string' && s . length > 0 ) ;
2023-08-28 23:47:35 +02:00
2023-11-23 23:51:27 +01:00
// Substitute params if necessary
if ( power _user . custom _stopping _strings _macro ) {
strings = strings . map ( x => substituteParams ( x ) ) ;
}
2023-08-28 23:47:35 +02:00
2023-11-23 23:51:27 +01:00
return strings ;
} catch ( error ) {
// If there's an error, return an empty array
console . warn ( 'Error parsing custom stopping strings:' , error ) ;
return [ ] ;
}
2023-07-20 19:32:15 +02:00
}
2023-11-23 23:51:27 +01:00
const permanent = getPermanent ( ) ;
const ephemeral = EPHEMERAL _STOPPING _STRINGS ;
2023-11-23 23:54:23 +01:00
const strings = [ ... permanent , ... ephemeral ] ;
// Apply the limit. If limit is 0, return all strings.
if ( limit > 0 ) {
return strings . slice ( 0 , limit ) ;
}
return strings ;
2023-07-20 19:32:15 +02:00
}
2024-04-13 20:05:31 +02:00
export function forceCharacterEditorTokenize ( ) {
$ ( '[data-token-counter]' ) . each ( function ( ) {
$ ( document . getElementById ( $ ( this ) . data ( 'token-counter' ) ) ) . data ( 'last-value-hash' , '' ) ;
} ) ;
$ ( '#rm_ch_create_block' ) . trigger ( 'input' ) ;
$ ( '#character_popup' ) . trigger ( 'input' ) ;
}
2023-07-20 19:32:15 +02:00
$ ( document ) . ready ( ( ) => {
2024-04-04 23:39:54 +02:00
const adjustAutocompleteDebounced = debounce ( ( ) => {
$ ( '.ui-autocomplete-input' ) . each ( function ( ) {
const isOpen = $ ( this ) . autocomplete ( 'widget' ) [ 0 ] . style . display !== 'none' ;
if ( isOpen ) {
$ ( this ) . autocomplete ( 'search' ) ;
}
} ) ;
} ) ;
const reportZoomLevelDebounced = debounce ( ( ) => {
2024-05-21 06:55:00 +02:00
const zoomLevel = Number ( window . devicePixelRatio ) . toFixed ( 2 ) || 1 ;
2024-04-04 23:39:54 +02:00
const winWidth = window . innerWidth ;
const winHeight = window . innerHeight ;
2024-05-21 06:55:00 +02:00
const originalWidth = winWidth * zoomLevel ;
const originalHeight = winHeight * zoomLevel ;
2024-07-06 14:29:47 +02:00
console . log ( ` Window resize: ${ coreTruthWinWidth } x ${ coreTruthWinHeight } -> ${ window . innerWidth } x ${ window . innerHeight } ` ) ;
2024-05-21 06:55:00 +02:00
console . debug ( ` Zoom: ${ zoomLevel } , X: ${ winWidth } , Y: ${ winHeight } , original: ${ originalWidth } x ${ originalHeight } ` ) ;
return zoomLevel ;
2024-04-04 23:39:54 +02:00
} ) ;
2023-07-20 19:32:15 +02:00
2024-05-21 06:55:00 +02:00
var coreTruthWinWidth = window . innerWidth ;
var coreTruthWinHeight = window . innerHeight ;
2023-07-20 19:32:15 +02:00
$ ( window ) . on ( 'resize' , async ( ) => {
2024-04-04 23:39:54 +02:00
adjustAutocompleteDebounced ( ) ;
setHotswapsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
if ( isMobile ( ) ) {
2023-12-02 20:11:06 +01:00
return ;
2023-07-20 19:32:15 +02:00
}
2024-04-04 23:39:54 +02:00
reportZoomLevelDebounced ( ) ;
2024-05-21 06:55:00 +02:00
//attempt to scale movingUI elements naturally across window resizing/zooms
//this will still break if the zoom level causes mobile styles to come into play.
const scaleY = Number ( window . innerHeight / coreTruthWinHeight ) . toFixed ( 4 ) ;
const scaleX = Number ( window . innerWidth / coreTruthWinWidth ) . toFixed ( 4 ) ;
2023-07-20 19:32:15 +02:00
if ( Object . keys ( power _user . movingUIState ) . length > 0 ) {
2024-05-21 06:55:00 +02:00
for ( var elmntName of Object . keys ( power _user . movingUIState ) ) {
var elmntState = power _user . movingUIState [ elmntName ] ;
var oldHeight = elmntState . height ;
var oldWidth = elmntState . width ;
var oldLeft = elmntState . left ;
var oldTop = elmntState . top ;
var oldBottom = elmntState . bottom ;
var oldRight = elmntState . right ;
var newHeight , newWidth , newTop , newBottom , newLeft , newRight ;
newHeight = Number ( oldHeight * scaleY ) . toFixed ( 0 ) ;
newWidth = Number ( oldWidth * scaleX ) . toFixed ( 0 ) ;
newLeft = Number ( oldLeft * scaleX ) . toFixed ( 0 ) ;
newTop = Number ( oldTop * scaleY ) . toFixed ( 0 ) ;
newBottom = Number ( oldBottom * scaleY ) . toFixed ( 0 ) ;
newRight = Number ( oldRight * scaleX ) . toFixed ( 0 ) ;
try {
var elmnt = $ ( '#' + $ . escapeSelector ( elmntName ) ) ;
if ( elmnt . length ) {
console . log ( ` scaling ${ elmntName } by ${ scaleX } x ${ scaleY } to ${ newWidth } x ${ newHeight } ` ) ;
elmnt . css ( 'height' , newHeight ) ;
elmnt . css ( 'width' , newWidth ) ;
elmnt . css ( 'inset' , ` ${ newTop } px ${ newRight } px ${ newBottom } px ${ newLeft } px ` ) ;
power _user . movingUIState [ elmntName ] . height = newHeight ;
power _user . movingUIState [ elmntName ] . width = newWidth ;
power _user . movingUIState [ elmntName ] . top = newTop ;
power _user . movingUIState [ elmntName ] . bottom = newBottom ;
power _user . movingUIState [ elmntName ] . left = newLeft ;
power _user . movingUIState [ elmntName ] . right = newRight ;
} else {
console . log ( ` skipping ${ elmntName } because it doesn't exist in the DOM ` ) ;
}
} catch ( err ) {
console . log ( ` error occurred while processing ${ elmntName } : ${ err } ` ) ;
}
}
} else {
2024-07-06 14:29:47 +02:00
console . debug ( 'aborting MUI reset' , Object . keys ( power _user . movingUIState ) . length ) ;
2023-07-20 19:32:15 +02:00
}
2024-05-21 06:55:00 +02:00
saveSettingsDebounced ( ) ;
coreTruthWinWidth = window . innerWidth ;
coreTruthWinHeight = window . innerHeight ;
2023-07-20 19:32:15 +02:00
} ) ;
// Settings that go to settings.json
2023-12-02 19:04:51 +01:00
$ ( '#collapse-newlines-checkbox' ) . change ( function ( ) {
power _user . collapse _newlines = ! ! $ ( this ) . prop ( 'checked' ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
// include newline is the child of trim sentences
// if include newline is checked, trim sentences must be checked
// if trim sentences is unchecked, include newline must be unchecked
2023-12-02 19:04:51 +01:00
$ ( '#trim_sentences_checkbox' ) . change ( function ( ) {
power _user . trim _sentences = ! ! $ ( this ) . prop ( 'checked' ) ;
if ( ! $ ( this ) . prop ( 'checked' ) ) {
$ ( '#include_newline_checkbox' ) . prop ( 'checked' , false ) ;
2023-07-20 19:32:15 +02:00
power _user . include _newline = false ;
}
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#include_newline_checkbox' ) . change ( function ( ) {
power _user . include _newline = ! ! $ ( this ) . prop ( 'checked' ) ;
if ( $ ( this ) . prop ( 'checked' ) ) {
$ ( '#trim_sentences_checkbox' ) . prop ( 'checked' , true ) ;
2023-07-20 19:32:15 +02:00
power _user . trim _sentences = true ;
}
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#single_line' ) . on ( 'input' , function ( ) {
2023-10-27 20:02:03 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . single _line = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#always-force-name2-checkbox' ) . change ( function ( ) {
power _user . always _force _name2 = ! ! $ ( this ) . prop ( 'checked' ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#markdown_escape_strings' ) . on ( 'input' , function ( ) {
2023-08-22 13:30:49 +02:00
power _user . markdown _escape _strings = String ( $ ( this ) . val ( ) ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
reloadMarkdownProcessor ( power _user . render _formulas ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#start_reply_with' ) . on ( 'input' , function ( ) {
2024-09-05 18:48:21 +02:00
power _user . user _prompt _bias = String ( $ ( this ) . val ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#chat-show-reply-prefix-checkbox' ) . change ( function ( ) {
power _user . show _user _prompt _bias = ! ! $ ( this ) . prop ( 'checked' ) ;
2023-07-20 19:32:15 +02:00
reloadCurrentChat ( ) ;
saveSettingsDebounced ( ) ;
2023-12-02 20:11:06 +01:00
} ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#auto_continue_enabled' ) . on ( 'change' , function ( ) {
power _user . auto _continue . enabled = $ ( this ) . prop ( 'checked' ) ;
2023-09-15 20:34:41 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#auto_continue_allow_chat_completions' ) . on ( 'change' , function ( ) {
2023-09-15 20:34:41 +02:00
power _user . auto _continue . allow _chat _completions = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#auto_continue_target_length' ) . on ( 'input' , function ( ) {
2023-09-15 20:34:41 +02:00
power _user . auto _continue . target _length = Number ( $ ( this ) . val ( ) ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-10-20 19:09:31 +02:00
$ ( '#example_messages_behavior' ) . on ( 'change' , function ( ) {
const selectedOption = String ( $ ( this ) . find ( ':selected' ) . val ( ) ) ;
console . log ( 'Setting example messages behavior to' , selectedOption ) ;
switch ( selectedOption ) {
case 'normal' :
power _user . pin _examples = false ;
power _user . strip _examples = false ;
break ;
case 'keep' :
power _user . pin _examples = true ;
power _user . strip _examples = false ;
break ;
case 'strip' :
power _user . pin _examples = false ;
power _user . strip _examples = true ;
break ;
}
console . debug ( 'power_user.pin_examples' , power _user . pin _examples ) ;
console . debug ( 'power_user.strip_examples' , power _user . strip _examples ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#fast_ui_mode' ) . change ( function ( ) {
power _user . fast _ui _mode = $ ( this ) . prop ( 'checked' ) ;
2023-07-20 19:32:15 +02:00
switchUiMode ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#waifuMode' ) . on ( 'change' , ( ) => {
power _user . waifuMode = $ ( '#waifuMode' ) . prop ( 'checked' ) ;
2023-07-20 19:32:15 +02:00
switchWaifuMode ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2024-08-07 23:21:18 +02:00
$ ( '#customCSS' ) . on ( 'input' , ( ) => {
power _user . custom _css = String ( $ ( '#customCSS' ) . val ( ) ) ;
2023-09-22 20:13:58 +02:00
saveSettingsDebounced ( ) ;
applyCustomCSS ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#movingUImode' ) . change ( function ( ) {
power _user . movingUI = $ ( this ) . prop ( 'checked' ) ;
2023-07-20 19:32:15 +02:00
switchMovingUI ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#noShadowsmode' ) . change ( function ( ) {
power _user . noShadows = $ ( this ) . prop ( 'checked' ) ;
2024-08-23 18:49:00 +02:00
applyNoShadows ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#movingUIreset' ) . on ( 'click' , resetMovablePanels ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#avatar_style' ) . on ( 'change' , function ( ) {
2023-09-22 15:16:24 +02:00
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . avatar _style = Number ( value ) ;
2023-07-20 19:32:15 +02:00
applyAvatarStyle ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#chat_display' ) . on ( 'change' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . chat _display = Number ( value ) ;
applyChatDisplay ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2024-07-27 20:38:03 +02:00
$ ( '#chat_width_slider' ) . on ( 'input' , function ( e , data ) {
const applyMode = data ? . forced ? 'forced' : 'normal' ;
2023-07-20 19:32:15 +02:00
power _user . chat _width = Number ( e . target . value ) ;
2024-07-27 20:38:03 +02:00
applyChatWidth ( applyMode ) ;
2024-08-23 19:49:30 +02:00
saveSettingsDebounced ( ) ;
2023-09-14 14:56:01 +02:00
setHotswapsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-11-19 20:57:54 +01:00
$ ( '#chat_truncation' ) . on ( 'input' , function ( ) {
power _user . chat _truncation = Number ( $ ( '#chat_truncation' ) . val ( ) ) ;
$ ( '#chat_truncation_counter' ) . val ( power _user . chat _truncation ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-12 21:11:23 +01:00
$ ( '#streaming_fps' ) . on ( 'input' , function ( ) {
power _user . streaming _fps = Number ( $ ( '#streaming_fps' ) . val ( ) ) ;
$ ( '#streaming_fps_counter' ) . val ( power _user . streaming _fps ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-04-02 13:56:15 +02:00
$ ( '#smooth_streaming' ) . on ( 'input' , function ( ) {
power _user . smooth _streaming = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-04-02 21:52:51 +02:00
$ ( '#smooth_streaming_speed' ) . on ( 'input' , function ( ) {
power _user . smooth _streaming _speed = Number ( $ ( '#smooth_streaming_speed' ) . val ( ) ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-07-27 20:38:03 +02:00
$ ( 'input[name="font_scale"]' ) . on ( 'input' , async function ( e , data ) {
const applyMode = data ? . forced ? 'forced' : 'normal' ;
2023-07-20 19:32:15 +02:00
power _user . font _scale = Number ( e . target . value ) ;
2023-12-02 19:04:51 +01:00
$ ( '#font_scale_counter' ) . val ( power _user . font _scale ) ;
2024-09-04 21:15:29 +02:00
applyFontScale ( applyMode ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( 'input[name="blur_strength"]' ) . on ( 'input' , async function ( e ) {
2023-07-20 19:32:15 +02:00
power _user . blur _strength = Number ( e . target . value ) ;
2023-12-02 19:04:51 +01:00
$ ( '#blur_strength_counter' ) . val ( power _user . blur _strength ) ;
2024-09-04 21:15:29 +02:00
applyBlurStrength ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( 'input[name="shadow_width"]' ) . on ( 'input' , async function ( e ) {
2023-07-20 19:32:15 +02:00
power _user . shadow _width = Number ( e . target . value ) ;
2023-12-02 19:04:51 +01:00
$ ( '#shadow_width_counter' ) . val ( power _user . shadow _width ) ;
2024-09-04 21:15:29 +02:00
applyShadowWidth ( ) ;
2023-09-22 15:16:24 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#main-text-color-picker' ) . on ( 'change' , ( evt ) => {
2023-07-20 19:32:15 +02:00
power _user . main _text _color = evt . detail . rgba ;
applyThemeColor ( 'main' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#italics-color-picker' ) . on ( 'change' , ( evt ) => {
2023-07-20 19:32:15 +02:00
power _user . italics _text _color = evt . detail . rgba ;
applyThemeColor ( 'italics' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-03-01 06:33:37 +01:00
$ ( '#underline-color-picker' ) . on ( 'change' , ( evt ) => {
power _user . underline _text _color = evt . detail . rgba ;
applyThemeColor ( 'underline' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#quote-color-picker' ) . on ( 'change' , ( evt ) => {
2023-07-20 19:32:15 +02:00
power _user . quote _text _color = evt . detail . rgba ;
applyThemeColor ( 'quote' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#blur-tint-color-picker' ) . on ( 'change' , ( evt ) => {
2023-07-20 19:32:15 +02:00
power _user . blur _tint _color = evt . detail . rgba ;
applyThemeColor ( 'blurTint' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#chat-tint-color-picker' ) . on ( 'change' , ( evt ) => {
2023-09-22 09:54:51 +02:00
power _user . chat _tint _color = evt . detail . rgba ;
applyThemeColor ( 'chatTint' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#user-mes-blur-tint-color-picker' ) . on ( 'change' , ( evt ) => {
2023-07-20 19:32:15 +02:00
power _user . user _mes _blur _tint _color = evt . detail . rgba ;
applyThemeColor ( 'userMesBlurTint' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#bot-mes-blur-tint-color-picker' ) . on ( 'change' , ( evt ) => {
2023-07-20 19:32:15 +02:00
power _user . bot _mes _blur _tint _color = evt . detail . rgba ;
applyThemeColor ( 'botMesBlurTint' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#shadow-color-picker' ) . on ( 'change' , ( evt ) => {
2023-07-20 19:32:15 +02:00
power _user . shadow _color = evt . detail . rgba ;
applyThemeColor ( 'shadow' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#border-color-picker' ) . on ( 'change' , ( evt ) => {
2023-09-16 08:42:26 +02:00
power _user . border _color = evt . detail . rgba ;
applyThemeColor ( 'border' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#themes' ) . on ( 'change' , function ( ) {
2023-08-22 13:30:49 +02:00
const themeSelected = String ( $ ( this ) . find ( ':selected' ) . val ( ) ) ;
2023-07-20 19:32:15 +02:00
power _user . theme = themeSelected ;
applyTheme ( themeSelected ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#movingUIPresets' ) . on ( 'change' , async function ( ) {
2023-12-02 20:11:06 +01:00
console . log ( 'saw MUI preset change' ) ;
2023-08-22 13:30:49 +02:00
const movingUIPresetSelected = String ( $ ( this ) . find ( ':selected' ) . val ( ) ) ;
2023-07-20 19:32:15 +02:00
power _user . movingUIPreset = movingUIPresetSelected ;
applyMovingUIPreset ( movingUIPresetSelected ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-16 00:45:48 +01:00
$ ( '#ui-preset-save-button' ) . on ( 'click' , ( ) => saveTheme ( ) ) ;
$ ( '#ui-preset-update-button' ) . on ( 'click' , ( ) => updateTheme ( ) ) ;
2024-03-19 23:14:32 +01:00
$ ( '#ui-preset-delete-button' ) . on ( 'click' , ( ) => deleteTheme ( ) ) ;
2023-12-02 19:04:51 +01:00
$ ( '#movingui-preset-save-button' ) . on ( 'click' , saveMovingUI ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#never_resize_avatars' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . never _resize _avatars = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-08-18 22:13:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#show_card_avatar_urls' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . show _card _avatar _urls = ! ! $ ( this ) . prop ( 'checked' ) ;
2024-03-30 03:06:40 +01:00
printCharactersDebounced ( ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#play_message_sound' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . play _message _sound = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#play_sound_unfocused' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . play _sound _unfocused = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#auto_save_msg_edits' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . auto _save _msg _edits = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#character_sort_order' ) . on ( 'change' , function ( ) {
2024-04-30 04:30:39 +02:00
const field = String ( $ ( this ) . find ( ':selected' ) . data ( 'field' ) ) ;
// Save sort order, but do not save search sorting, as this is a temporary sorting option
if ( field !== 'search' ) {
power _user . sort _field = field ;
power _user . sort _order = $ ( this ) . find ( ':selected' ) . data ( 'order' ) ;
power _user . sort _rule = $ ( this ) . find ( ':selected' ) . data ( 'rule' ) ;
}
2024-03-30 03:06:40 +01:00
printCharactersDebounced ( ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-10-23 03:54:17 +02:00
$ ( '#gestures-checkbox' ) . on ( 'change' , function ( ) {
power _user . gestures = ! ! $ ( '#gestures-checkbox' ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-07-20 19:32:15 +02:00
$ ( '#auto_swipe' ) . on ( 'input' , function ( ) {
power _user . auto _swipe = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#auto_swipe_blacklist' ) . on ( 'input' , function ( ) {
2023-08-22 13:30:49 +02:00
power _user . auto _swipe _blacklist = String ( $ ( this ) . val ( ) )
2023-12-02 19:04:51 +01:00
. split ( ',' )
2023-07-20 19:32:15 +02:00
. map ( str => str . trim ( ) )
. filter ( str => str ) ;
2023-12-02 20:11:06 +01:00
console . log ( 'power_user.auto_swipe_blacklist' , power _user . auto _swipe _blacklist ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#auto_swipe_minimum_length' ) . on ( 'input' , function ( ) {
2023-08-22 13:30:49 +02:00
const number = Number ( $ ( this ) . val ( ) ) ;
2023-07-20 19:32:15 +02:00
if ( ! isNaN ( number ) ) {
power _user . auto _swipe _minimum _length = number ;
saveSettingsDebounced ( ) ;
}
} ) ;
$ ( '#auto_swipe_blacklist_threshold' ) . on ( 'input' , function ( ) {
2023-08-22 13:30:49 +02:00
const number = Number ( $ ( this ) . val ( ) ) ;
2023-07-20 19:32:15 +02:00
if ( ! isNaN ( number ) ) {
power _user . auto _swipe _blacklist _threshold = number ;
saveSettingsDebounced ( ) ;
}
} ) ;
$ ( '#auto_fix_generated_markdown' ) . on ( 'input' , function ( ) {
power _user . auto _fix _generated _markdown = ! ! $ ( this ) . prop ( 'checked' ) ;
reloadCurrentChat ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#console_log_prompts' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . console _log _prompts = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-01-23 06:00:31 +01:00
$ ( '#request_token_probabilities' ) . on ( 'input' , function ( ) {
power _user . request _token _probabilities = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-07-04 15:52:56 +02:00
$ ( '#show_group_chat_queue' ) . on ( 'input' , function ( ) {
power _user . show _group _chat _queue = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#auto_scroll_chat_to_bottom' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . auto _scroll _chat _to _bottom = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#tokenizer' ) . on ( 'change' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . tokenizer = Number ( value ) ;
2023-12-18 21:38:28 +01:00
BIAS _CACHE . clear ( ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
// Trigger character editor re-tokenize
2024-04-13 20:05:31 +02:00
forceCharacterEditorTokenize ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#send_on_enter' ) . on ( 'change' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . send _on _enter = Number ( value ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#confirm_message_delete' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . confirm _message _delete = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#render_formulas' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . render _formulas = ! ! $ ( this ) . prop ( 'checked' ) ;
reloadMarkdownProcessor ( power _user . render _formulas ) ;
reloadCurrentChat ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-06 16:23:54 +01:00
$ ( '#reload_chat' ) . on ( 'click' , async function ( ) {
2023-07-20 19:32:15 +02:00
const currentChatId = getCurrentChatId ( ) ;
if ( currentChatId !== undefined && currentChatId !== null ) {
2023-12-06 16:23:54 +01:00
await saveSettings ( ) ;
await saveChatConditional ( ) ;
await reloadCurrentChat ( ) ;
2023-07-20 19:32:15 +02:00
}
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#allow_name1_display' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . allow _name1 _display = ! ! $ ( this ) . prop ( 'checked' ) ;
reloadCurrentChat ( ) ;
saveSettingsDebounced ( ) ;
2023-12-02 20:11:06 +01:00
} ) ;
2023-07-20 19:32:15 +02:00
2023-12-02 19:04:51 +01:00
$ ( '#allow_name2_display' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . allow _name2 _display = ! ! $ ( this ) . prop ( 'checked' ) ;
reloadCurrentChat ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#token_padding' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
power _user . token _padding = Number ( $ ( this ) . val ( ) ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#messageTimerEnabled' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . timer _enabled = value ;
switchTimer ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#messageTimestampsEnabled' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . timestamps _enabled = value ;
switchTimestamps ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#messageModelIconEnabled' ) . on ( 'input' , function ( ) {
2023-08-14 00:43:16 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . timestamp _model _icon = value ;
switchIcons ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-08-14 00:43:16 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#messageTokensEnabled' ) . on ( 'input' , function ( ) {
2023-08-31 16:10:01 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . message _token _count _enabled = value ;
switchTokenCount ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-08-31 16:10:01 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#expandMessageActions' ) . on ( 'input' , function ( ) {
2023-09-14 14:23:51 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . expand _message _actions = value ;
switchMessageActions ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-09-14 14:23:51 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#enableZenSliders' ) . on ( 'input' , function ( ) {
2023-11-12 09:23:29 +01:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
if ( power _user . enableLabMode === true && value === true ) {
2023-11-10 08:17:38 +01:00
//disallow zenSliders while Lab Mode is active
2023-12-02 20:11:06 +01:00
toastr . warning ( 'Disable Mad Lab Mode before enabling Zen Sliders' ) ;
2023-11-12 09:23:29 +01:00
$ ( this ) . prop ( 'checked' , false ) . trigger ( 'input' ) ;
2023-12-02 20:11:06 +01:00
return ;
2023-11-10 08:17:38 +01:00
}
2023-11-04 21:47:53 +01:00
power _user . enableZenSliders = value ;
switchZenSliders ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-11-04 21:47:53 +01:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#enableLabMode' ) . on ( 'input' , function ( ) {
2023-11-12 09:23:29 +01:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
if ( power _user . enableZenSliders === true && value === true ) {
2023-11-10 08:17:38 +01:00
//disallow Lab Mode if ZenSliders are active
2023-12-02 20:11:06 +01:00
toastr . warning ( 'Disable Zen Sliders before enabling Mad Lab Mode' ) ;
2023-12-02 16:15:03 +01:00
$ ( this ) . prop ( 'checked' , false ) . trigger ( 'input' ) ;
2023-12-02 20:11:06 +01:00
return ;
2023-11-10 08:17:38 +01:00
}
2023-11-12 09:23:29 +01:00
2023-11-10 08:17:38 +01:00
power _user . enableLabMode = value ;
switchLabMode ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-11-10 08:17:38 +01:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#mesIDDisplayEnabled' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . mesIDDisplay _enabled = value ;
switchMesIDDisplay ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2024-04-25 05:51:56 +02:00
$ ( '#hideChatAvatarsEnabled' ) . on ( 'input' , function ( ) {
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . hideChatAvatars _enabled = value ;
switchHideChatAvatars ( ) ;
2024-08-25 14:48:20 +02:00
saveSettingsDebounced ( ) ;
2024-04-25 05:51:56 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#hotswapEnabled' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . hotswap _enabled = value ;
switchHotswap ( ) ;
2024-08-23 18:49:00 +02:00
saveSettingsDebounced ( ) ;
2023-07-20 19:32:15 +02:00
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#prefer_character_prompt' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . prefer _character _prompt = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#prefer_character_jailbreak' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . prefer _character _jailbreak = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#continue_on_send' ) . on ( 'input' , function ( ) {
2023-08-24 14:13:04 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . continue _on _send = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#quick_continue' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
2023-08-24 00:37:44 +02:00
power _user . quick _continue = value ;
2023-12-02 19:04:51 +01:00
$ ( '#mes_continue' ) . css ( 'display' , value ? '' : 'none' ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2024-08-02 14:17:29 +02:00
$ ( '#quick_impersonate' ) . on ( 'input' , function ( ) {
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . quick _impersonate = value ;
$ ( '#mes_impersonate' ) . css ( 'display' , value ? '' : 'none' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#trim_spaces' ) . on ( 'input' , function ( ) {
2023-07-20 19:32:15 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . trim _spaces = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#relaxed_api_urls' ) . on ( 'input' , function ( ) {
2023-08-04 22:49:55 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . relaxed _api _urls = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#world_import_dialog' ) . on ( 'input' , function ( ) {
2023-10-10 17:08:08 +02:00
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . world _import _dialog = value ;
saveSettingsDebounced ( ) ;
} ) ;
2024-08-18 03:38:07 +02:00
$ ( '#enable_auto_select_input' ) . on ( 'input' , function ( ) {
const value = ! ! $ ( this ) . prop ( 'checked' ) ;
power _user . enable _auto _select _input = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-07-20 19:32:15 +02:00
$ ( '#spoiler_free_mode' ) . on ( 'input' , function ( ) {
power _user . spoiler _free _mode = ! ! $ ( this ) . prop ( 'checked' ) ;
switchSpoilerMode ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#spoiler_free_desc_button' ) . on ( 'click' , function ( ) {
peekSpoilerMode ( ) ;
$ ( this ) . toggleClass ( 'fa-eye fa-eye-slash' ) ;
} ) ;
$ ( '#custom_stopping_strings' ) . on ( 'input' , function ( ) {
2024-09-05 18:48:21 +02:00
power _user . custom _stopping _strings = String ( $ ( this ) . val ) . trim ( ) ;
2023-07-20 19:32:15 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-12-02 19:04:51 +01:00
$ ( '#custom_stopping_strings_macro' ) . change ( function ( ) {
power _user . custom _stopping _strings _macro = ! ! $ ( this ) . prop ( 'checked' ) ;
2023-08-04 16:53:49 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2023-07-27 23:38:43 +02:00
$ ( '#fuzzy_search_checkbox' ) . on ( 'input' , function ( ) {
power _user . fuzzy _search = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-08-03 13:24:45 +02:00
$ ( '#persona_show_notifications' ) . on ( 'input' , function ( ) {
power _user . persona _show _notifications = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-08-10 10:47:17 +02:00
$ ( '#encode_tags' ) . on ( 'input' , async function ( ) {
power _user . encode _tags = ! ! $ ( this ) . prop ( 'checked' ) ;
await reloadCurrentChat ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-08-30 15:31:53 +02:00
$ ( '#disable_group_trimming' ) . on ( 'input' , function ( ) {
power _user . disable _group _trimming = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-08-27 22:20:43 +02:00
$ ( '#debug_menu' ) . on ( 'click' , function ( ) {
showDebugMenu ( ) ;
} ) ;
2023-11-12 09:23:29 +01:00
$ ( '#bogus_folders' ) . on ( 'input' , function ( ) {
2024-04-14 16:59:51 +02:00
power _user . bogus _folders = ! ! $ ( this ) . prop ( 'checked' ) ;
printCharactersDebounced ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#zoomed_avatar_magnification' ) . on ( 'input' , function ( ) {
power _user . zoomed _avatar _magnification = ! ! $ ( this ) . prop ( 'checked' ) ;
2024-03-30 03:06:40 +01:00
printCharactersDebounced ( ) ;
2023-11-10 20:56:25 +01:00
saveSettingsDebounced ( ) ;
} ) ;
2023-11-12 10:22:21 +01:00
$ ( '#aux_field' ) . on ( 'change' , function ( ) {
2023-11-11 17:25:43 +01:00
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . aux _field = String ( value ) ;
2024-03-30 03:06:40 +01:00
printCharactersDebounced ( ) ;
2023-11-11 17:25:43 +01:00
saveSettingsDebounced ( ) ;
} ) ;
2024-06-22 05:03:05 +02:00
$ ( '#tag_import_setting' ) . on ( 'change' , function ( ) {
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . tag _import _setting = Number ( value ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-05-13 20:56:36 +02:00
$ ( '#stscript_autocomplete_autoHide' ) . on ( 'input' , function ( ) {
power _user . stscript . autocomplete . autoHide = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-05-12 21:15:05 +02:00
$ ( '#stscript_matching' ) . on ( 'change' , function ( ) {
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . stscript . matching = String ( value ) ;
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#stscript_autocomplete_style' ) . on ( 'change' , function ( ) {
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
2024-06-24 21:35:09 +02:00
power _user . stscript . autocomplete . style = String ( value ) ;
document . body . setAttribute ( 'data-stscript-style' , power _user . stscript . autocomplete . style ) ;
2024-05-12 21:15:05 +02:00
saveSettingsDebounced ( ) ;
} ) ;
2024-07-19 13:41:57 +02:00
$ ( '#stscript_autocomplete_select' ) . on ( 'change' , function ( ) {
const value = $ ( this ) . find ( ':selected' ) . val ( ) ;
power _user . stscript . autocomplete . select = parseInt ( String ( value ) ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-05-12 21:15:05 +02:00
$ ( '#stscript_autocomplete_font_scale' ) . on ( 'input' , function ( ) {
const value = $ ( this ) . val ( ) ;
$ ( '#stscript_autocomplete_font_scale_counter' ) . val ( value ) ;
power _user . stscript . autocomplete . font . scale = Number ( value ) ;
document . body . style . setProperty ( '--ac-font-scale' , value . toString ( ) ) ;
2024-05-20 05:56:48 +02:00
window . dispatchEvent ( new Event ( 'resize' , { bubbles : true } ) ) ;
2024-05-12 21:15:05 +02:00
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#stscript_autocomplete_font_scale_counter' ) . on ( 'input' , function ( ) {
const value = $ ( this ) . val ( ) ;
$ ( '#stscript_autocomplete_font_scale' ) . val ( value ) ;
power _user . stscript . autocomplete . font . scale = Number ( value ) ;
document . body . style . setProperty ( '--ac-font-scale' , value . toString ( ) ) ;
2024-05-20 05:56:48 +02:00
window . dispatchEvent ( new Event ( 'resize' , { bubbles : true } ) ) ;
2024-05-12 21:15:05 +02:00
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#stscript_autocomplete_width_left' ) . on ( 'input' , function ( ) {
const value = $ ( this ) . val ( ) ;
power _user . stscript . autocomplete . width . left = Number ( value ) ;
/**@type {HTMLElement}*/ ( this . closest ( '.doubleRangeInputContainer' ) ) . style . setProperty ( '--value' , value . toString ( ) ) ;
2024-05-20 05:56:48 +02:00
window . dispatchEvent ( new Event ( 'resize' , { bubbles : true } ) ) ;
2024-05-12 21:15:05 +02:00
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#stscript_autocomplete_width_right' ) . on ( 'input' , function ( ) {
const value = $ ( this ) . val ( ) ;
power _user . stscript . autocomplete . width . right = Number ( value ) ;
/**@type {HTMLElement}*/ ( this . closest ( '.doubleRangeInputContainer' ) ) . style . setProperty ( '--value' , value . toString ( ) ) ;
2024-05-20 05:56:48 +02:00
window . dispatchEvent ( new Event ( 'resize' , { bubbles : true } ) ) ;
2024-05-12 21:15:05 +02:00
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#stscript_parser_flag_strict_escaping' ) . on ( 'click' , function ( ) {
const value = $ ( this ) . prop ( 'checked' ) ;
power _user . stscript . parser . flags [ PARSER _FLAG . STRICT _ESCAPING ] = value ;
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#stscript_parser_flag_replace_getvar' ) . on ( 'click' , function ( ) {
const value = $ ( this ) . prop ( 'checked' ) ;
power _user . stscript . parser . flags [ PARSER _FLAG . REPLACE _GETVAR ] = value ;
saveSettingsDebounced ( ) ;
} ) ;
2023-11-27 23:29:34 +01:00
$ ( '#restore_user_input' ) . on ( 'input' , function ( ) {
power _user . restore _user _input = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-12 21:11:23 +01:00
$ ( '#reduced_motion' ) . on ( 'input' , function ( ) {
2023-12-10 19:02:25 +01:00
power _user . reduced _motion = ! ! $ ( this ) . prop ( 'checked' ) ;
switchReducedMotion ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
2023-12-16 00:35:28 +01:00
$ ( '#compact_input_area' ) . on ( 'input' , function ( ) {
power _user . compact _input _area = ! ! $ ( this ) . prop ( 'checked' ) ;
switchCompactInputArea ( ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-01-05 19:27:19 +01:00
$ ( '#auto-connect-checkbox' ) . on ( 'input' , function ( ) {
power _user . auto _connect = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
$ ( '#auto-load-chat-checkbox' ) . on ( 'input' , function ( ) {
power _user . auto _load _chat = ! ! $ ( this ) . prop ( 'checked' ) ;
saveSettingsDebounced ( ) ;
} ) ;
2024-04-20 00:11:37 +02:00
$ ( '#forbid_external_media' ) . on ( 'input' , function ( ) {
power _user . forbid _external _media = ! ! $ ( this ) . prop ( 'checked' ) ;
2024-01-24 14:47:54 +01:00
saveSettingsDebounced ( ) ;
reloadCurrentChat ( ) ;
} ) ;
2024-02-10 22:12:16 +01:00
$ ( '#ui_preset_import_button' ) . on ( 'click' , function ( ) {
$ ( '#ui_preset_import_file' ) . trigger ( 'click' ) ;
} ) ;
2024-03-03 10:55:16 +01:00
$ ( '#ui_preset_import_file' ) . on ( 'change' , async function ( ) {
2024-02-10 22:12:16 +01:00
const inputElement = this instanceof HTMLInputElement && this ;
try {
const file = inputElement ? . files ? . [ 0 ] ;
await importTheme ( file ) ;
} catch ( error ) {
console . error ( 'Error importing UI theme' , error ) ;
toastr . error ( String ( error ) , 'Failed to import UI theme' ) ;
} finally {
if ( inputElement ) {
inputElement . value = null ;
}
}
} ) ;
$ ( '#ui_preset_export_button' ) . on ( 'click' , async function ( ) {
await exportTheme ( ) ;
} ) ;
2023-08-27 22:20:43 +02:00
$ ( document ) . on ( 'click' , '#debug_table [data-debug-function]' , function ( ) {
const functionId = $ ( this ) . data ( 'debug-function' ) ;
const functionRecord = debug _functions . find ( f => f . functionId === functionId ) ;
if ( functionRecord ) {
functionRecord . func ( ) ;
} else {
console . warn ( ` Debug function ${ functionId } not found ` ) ;
}
} ) ;
2023-07-20 19:32:15 +02:00
$ ( window ) . on ( 'focus' , function ( ) {
browser _has _focus = true ;
} ) ;
$ ( window ) . on ( 'blur' , function ( ) {
browser _has _focus = false ;
} ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'vn' ,
2024-05-12 21:15:05 +02:00
callback : toggleWaifu ,
helpString : 'Swaps Visual Novel Mode On/Off' ,
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'newchat' ,
2024-06-27 01:39:05 +02:00
/** @type {(args: { delete: string?}, string) => Promise<''>} */
callback : async ( args , _ ) => {
await doNewChat ( { deleteCurrentChat : isTrueBoolean ( args . delete ) } ) ;
return '' ;
} ,
namedArgumentList : [
SlashCommandNamedArgument . fromProps ( {
name : 'delete' ,
description : 'delete the current chat' ,
typeList : [ ARGUMENT _TYPE . BOOLEAN ] ,
defaultValue : 'false' ,
enumList : commonEnumProviders . boolean ( 'trueFalse' ) ( ) ,
} ) ,
] ,
2024-05-12 21:15:05 +02:00
helpString : 'Start a new chat with the current character' ,
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'random' ,
2024-05-12 21:15:05 +02:00
callback : doRandomChat ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'optional tag name' ,
typeList : [ ARGUMENT _TYPE . STRING ] ,
2024-06-20 20:33:45 +02:00
enumProvider : ( ) => tags . filter ( tag => Object . values ( tag _map ) . some ( x => x . includes ( tag . id ) ) ) . map ( tag => new SlashCommandEnumValue ( tag . name , null , enumTypes . enum , enumIcons . tag ) ) ,
2024-06-17 03:30:52 +02:00
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : 'Start a new chat with a random character. If an argument is provided, only considers characters that have the specified tag.' ,
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'delmode' ,
2024-05-12 21:15:05 +02:00
callback : doDelMode ,
aliases : [ 'del' ] ,
unnamedArgumentList : [
new SlashCommandArgument (
'optional number' , [ ARGUMENT _TYPE . NUMBER ] , false ,
) ,
] ,
helpString : 'Enter message deletion mode, and auto-deletes last N messages if numeric argument is provided.' ,
2024-07-28 21:25:35 +02:00
returns : 'The text of the deleted messages.' ,
2024-05-12 21:15:05 +02:00
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'cut' ,
2024-05-12 21:15:05 +02:00
callback : doMesCut ,
returns : 'the text of cut messages separated by a newline' ,
unnamedArgumentList : [
2024-06-21 20:04:55 +02:00
SlashCommandArgument . fromProps ( {
description : 'number or range' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . RANGE ] ,
isRequired : true ,
acceptsMultiple : true ,
enumProvider : commonEnumProviders . messages ( ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Cuts the specified message or continuous chunk from the chat .
< / d i v >
< div >
Ranges are inclusive !
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code > / c u t 0 - 1 0 < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
aliases : [ ] ,
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'resetpanels' ,
2024-05-12 21:15:05 +02:00
callback : doResetPanels ,
helpString : 'resets UI panels to original state' ,
aliases : [ 'resetui' ] ,
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'bgcol' ,
2024-05-12 21:15:05 +02:00
callback : setAvgBG ,
helpString : '– WIP test of auto-bg avg coloring' ,
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'theme' ,
2024-05-12 21:15:05 +02:00
callback : setThemeCallback ,
unnamedArgumentList : [
2024-06-15 21:35:38 +02:00
SlashCommandArgument . fromProps ( {
2024-07-28 01:15:55 +02:00
description : 'theme name' ,
2024-06-15 21:35:38 +02:00
typeList : [ ARGUMENT _TYPE . STRING ] ,
enumProvider : ( ) => themes . map ( theme => new SlashCommandEnumValue ( theme . name ) ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-07-28 01:15:55 +02:00
helpString : `
< div >
Sets a UI theme by name .
< / d i v >
< div >
If no theme name is is provided , this will return the currently active theme .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code > / t h e m e C a p p u c c i n o < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code > / t h e m e < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
2024-05-12 21:15:05 +02:00
} ) ) ;
2024-05-20 05:56:48 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'movingui' ,
2024-05-12 21:15:05 +02:00
callback : setmovingUIPreset ,
unnamedArgumentList : [
2024-06-15 21:35:38 +02:00
SlashCommandArgument . fromProps ( {
description : 'name' ,
typeList : [ ARGUMENT _TYPE . STRING ] ,
isRequired : true ,
enumProvider : ( ) => movingUIPresets . map ( preset => new SlashCommandEnumValue ( preset . name ) ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : 'activates a movingUI preset by name' ,
} ) ) ;
2023-07-20 19:32:15 +02:00
} ) ;