import { humanizedDateTime } from "./scripts/RossAscends-mods.js";
import { encode, decode } from "../scripts/gpt-2-3-tokenizer/mod.js";
import {
world_info_budget,
world_info_data,
world_info_depth,
world_info,
checkWorldInfo,
selectImportedWorldInfo,
setWorldInfoSettings,
deleteWorldInfo,
} from "./scripts/world-info.js";
import {
groups,
selected_group,
saveGroupChat,
getGroups,
generateGroupWrapper,
deleteGroup,
is_group_generating,
printGroups,
resetSelectedGroup,
select_group_chats,
} from "./scripts/group-chats.js";
import {
force_pygmalion_formatting,
collapse_newlines,
} from "./scripts/power-user.js";
import { debounce, delay } from "./scripts/utils.js";
//exporting functions and vars for mods
export {
Generate,
getSettings,
saveSettings,
printMessages,
clearChat,
getChat,
getCharacters,
callPopup,
substituteParams,
sendSystemMessage,
addOneMessage,
resetChatState,
select_rm_info,
setCharacterId,
setCharacterName,
setEditedMessageId,
setSendButtonState,
selectRightMenuWithAnimation,
setRightTabSelectedClass,
chat,
this_chid,
settings,
characters,
online_status,
main_api,
api_server,
api_key_novel,
token,
is_send_press,
default_avatar,
system_message_types,
talkativeness_default,
default_ch_mes,
}
// API OBJECT FOR EXTERNAL WIRING
window["TavernAI"] = {};
const VERSION = "1.2.8";
let converter = new showdown.Converter({ emoji: "true" });
let bg_menu_toggle = false;
const systemUserName = "TavernAI";
let default_user_name = "You";
let name1 = default_user_name;
let name2 = "TavernAI";
let chat = [];
let safetychat = [
{
name: systemUserName,
is_user: false,
is_name: true,
create_date: 0,
mes: "\n*You deleted a character/chat and arrived back here for safety reasons! Pick another character!*\n\n",
},
];
let chat_create_date = 0;
let prev_selected_char = null;
const default_ch_mes = "Hello";
let count_view_mes = 0;
let mesStr = "";
let generatedPromtCache = "";
let characters = [];
let this_chid;
let active_character;
let backgrounds = [];
const default_avatar = "img/fluffy.png";
const system_avatar = "img/five.png";
let is_colab = false;
let is_checked_colab = false;
let is_mes_reload_avatar = false;
const durationSaveEdit = 200;
const saveSettingsDebounced = debounce(() => saveSettings(), durationSaveEdit);
const saveCharacterDebounced = debounce(() => $("#create_button").click(), durationSaveEdit);
const system_message_types = {
HELP: "help",
WELCOME: "welcome",
GROUP: "group",
EMPTY: "empty",
GENERIC: "generic",
};
const system_messages = {
help: {
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_system: true,
is_name: true,
mes: [
'Hi there! The following chat formatting commands are supported:',
'
',
'
*text* – format the actions that your character does
',
'
{*text*} – set the behavioral bias for your character
',
'',
'Need more help? Visit our wiki – TavernAI Wiki!'
].join('')
},
welcome:
{
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_name: true,
mes: [
'Welcome to TavernAI! In order to begin chatting:',
'
',
'
Connect to one of the supported generation APIs
',
'
Create or pick a character from the list
',
'
',
'Still have questions left?\n',
'Check out built-in help by typing /? in any chat or visit our ',
'TavernAI Wiki!'
].join('')
},
group: {
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_system: true,
is_name: true,
is_group: true,
mes: "Group chat created. Say 'Hi' to lovely people!",
},
empty: {
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_system: true,
is_name: true,
mes: "No one hears you. **Hint:** add more members to the group!",
},
generic: {
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_system: true,
is_name: true,
mes: "Generic system message. User `text` parameter to override the contents",
},
};
const talkativeness_default = 0.5;
var is_advanced_char_open = false;
var menu_type = ""; //what is selected in the menu
var selected_button = ""; //which button pressed
//create pole save
var create_save_name = "";
var create_save_description = "";
var create_save_personality = "";
var create_save_first_message = "";
var create_save_avatar = "";
var create_save_scenario = "";
var create_save_mes_example = "";
var create_save_talkativeness = talkativeness_default;
//animation right menu
var animation_rm_duration = 500;
var animation_rm_easing = "";
var popup_type = "";
var bg_file_for_del = "";
var online_status = "no_connection";
var api_server = "";
var api_server_textgenerationwebui = "";
//var interval_timer = setInterval(getStatus, 2000);
var interval_timer_novel = setInterval(getStatusNovel, 3000);
var is_get_status = false;
var is_get_status_novel = false;
var is_api_button_press = false;
var is_api_button_press_novel = false;
var is_send_press = false; //Send generation
var add_mes_without_animation = false;
var this_del_mes = 0;
//message editing and chat scroll posistion persistence
var this_edit_mes_text = "";
var this_edit_mes_chname = "";
var this_edit_mes_id;
var scroll_holder = 0;
var is_use_scroll_holder = false;
//settings
var settings;
var koboldai_settings;
var koboldai_setting_names;
var preset_settings = "gui";
var user_avatar = "you.png";
var temp = 0.5;
var amount_gen = 80; //default max length of AI generated responses
var max_context = 2048;
var rep_pen = 1;
var rep_pen_size = 100;
var textgenerationwebui_settings = {
temp: 0.5,
top_p: 0.9,
top_k: 0,
typical_p: 1,
rep_pen: 1.1,
rep_pen_size: 0,
penalty_alpha: 0,
};
var is_pygmalion = false;
var tokens_already_generated = 0;
var message_already_generated = "";
var if_typing_text = false;
const tokens_cycle_count = 30;
var cycle_count_generation = 0;
var swipes = false;
var anchor_order = 0;
var style_anchor = true;
var character_anchor = true;
let extension_prompts = {};
var main_api = "kobold";
//novel settings
var temp_novel = 0.5;
var rep_pen_novel = 1;
var rep_pen_size_novel = 100;
var api_key_novel = "";
var novel_tier;
var model_novel = "euterpe-v2";
var novelai_settings;
var novelai_setting_names;
var preset_settings_novel = "Classic-Krake";
//css
var bg1_toggle = true; // inits the BG as BG1
var css_mes_bg = $('').css("background");
var css_send_form_display = $("").css("display");
var colab_ini_step = 1;
var token;
//////////// Is this needed?
setInterval(function () {
switch (colab_ini_step) {
case 0:
$("#colab_popup_text").html("
Initialization
");
colab_ini_step = 1;
break;
case 1:
$("#colab_popup_text").html("
Initialization.
");
colab_ini_step = 2;
break;
case 2:
$("#colab_popup_text").html("
Initialization..
");
colab_ini_step = 3;
break;
case 3:
$("#colab_popup_text").html("
Initialization...
");
colab_ini_step = 0;
break;
}
}, 500);
/////////////
$.ajaxPrefilter((options, originalOptions, xhr) => {
xhr.setRequestHeader("X-CSRF-Token", token);
});
///// initialization protocol ////////
$.get("/csrf-token").then((data) => {
token = data.token;
getCharacters();
getSettings("def");
getLastVersion();
sendSystemMessage(system_message_types.WELCOME);
getBackgrounds();
getUserAvatars();
});
///////////// UNUSED FUNCTIONS MOVED TO TOP ///////////////
function cleanGroupMessage(getMessage) {
const group = groups.find((x) => x.id == selected_group);
if (group && Array.isArray(group.members) && group.members) {
for (let member of group.members) {
// Skip current speaker.
if (member === name2) {
continue;
}
const indexOfMember = getMessage.indexOf(member + ":");
if (indexOfMember != -1) {
getMessage = getMessage.substr(0, indexOfMember);
}
}
}
return getMessage;
}
function getExtensionPrompt() {
let extension_prompt = Object.keys(extension_prompts)
.sort()
.map((x) => extension_prompts[x])
.filter(x => x)
.join("\n");
if (extension_prompt.length && !extension_prompt.endsWith("\n")) {
extension_prompt += "\n";
}
return extension_prompt;
}
function getWorldInfoPrompt(chat2) {
let worldInfoString = "", worldInfoBefore = "", worldInfoAfter = "";
if (world_info && world_info_data) {
const activatedWorldInfo = checkWorldInfo(chat2);
worldInfoBefore = activatedWorldInfo.worldInfoBefore;
worldInfoAfter = activatedWorldInfo.worldInfoAfter;
worldInfoString = worldInfoBefore + worldInfoAfter;
}
return { worldInfoString, worldInfoBefore, worldInfoAfter };
}
function newMesPattern(name) {
//Patern which denotes a new message
name = name + ":";
return name;
}
//////////////////////////////////////////
function checkOnlineStatus() {
///////// REMOVED LINES THAT DUPLICATE RA_CHeckOnlineStatus FEATURES
if (online_status == "no_connection") {
$("#online_status_indicator2").css("background-color", "red"); //Kobold
$("#online_status_text2").html("No connection...");
$("#online_status_indicator3").css("background-color", "red"); //Novel
$("#online_status_text3").html("No connection...");
is_get_status = false;
is_get_status_novel = false;
} else {
$("#online_status_indicator2").css("background-color", "green"); //kobold
$("#online_status_text2").html(online_status);
$("#online_status_indicator3").css("background-color", "green"); //novel
$("#online_status_text3").html(online_status);
$("#online_status_indicator4").css("background-color", "green"); //extensions api
$("#online_status_text4").html(online_status);
}
}
///// DO WE STILL NEED THIS?
async function getLastVersion() {
jQuery.ajax({
type: "POST", //
url: "/getlastversion", //
data: JSON.stringify({
"": "",
}),
beforeSend: function () { },
cache: false,
dataType: "json",
contentType: "application/json",
//processData: false,
success: function (data) {
var getVersion = data.version;
if (getVersion !== "error" && getVersion != undefined) {
if (compareVersions(getVersion, VERSION) === 1) {
$("#verson").append(" (v." + getVersion + ")");
}
}
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
},
});
}
async function getStatus() {
if (is_get_status) {
jQuery.ajax({
type: "POST", //
url: "/getstatus", //
data: JSON.stringify({
api_server:
main_api == "kobold" ? api_server : api_server_textgenerationwebui,
main_api: main_api,
}),
beforeSend: function () {
if (is_api_button_press) {
//$("#api_loading").css("display", 'inline-block');
//$("#api_button").css("display", 'none');
}
//$('#create_button').attr('value','Creating...'); //
},
cache: false,
dataType: "json",
crossDomain: true,
contentType: "application/json",
//processData: false,
success: function (data) {
online_status = data.result;
if (online_status == undefined) {
online_status = "no_connection";
}
if (online_status.toLowerCase().indexOf("pygmalion") != -1 || (online_status !== "no_connection" && force_pygmalion_formatting)) {
is_pygmalion = true;
online_status += " (Pyg. formatting on)";
} else {
is_pygmalion = false;
}
//console.log(online_status);
resultCheckStatus();
if (online_status !== "no_connection") {
var checkStatusNow = setTimeout(getStatus, 3000); //getStatus();
}
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
online_status = "no_connection";
resultCheckStatus();
},
});
} else {
if (is_get_status_novel != true) {
online_status = "no_connection";
}
}
}
function resultCheckStatus() {
is_api_button_press = false;
checkOnlineStatus();
$("#api_loading").css("display", "none");
$("#api_button").css("display", "inline-block");
$("#api_loading_textgenerationwebui").css("display", "none");
$("#api_button_textgenerationwebui").css("display", "inline-block");
}
async function getSoftPromptsList() {
if (!api_server) {
return;
}
const response = await fetch("/getsoftprompts", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({ api_server: api_server }),
});
if (response.ok) {
const data = await response.json();
updateSoftPromptsList(data.soft_prompts);
}
}
function clearSoftPromptsList() {
$('#softprompt option[value!=""]').each(function () {
$(this).remove();
});
}
function updateSoftPromptsList(soft_prompts) {
// Delete SPs removed from Kobold
$("#softprompt option").each(function () {
const value = $(this).attr("value");
if (value == "") {
return;
}
const prompt = soft_prompts.find((x) => x.name === value);
if (!prompt) {
$(this).remove();
}
});
// Add SPs added to Kobold
soft_prompts.forEach((prompt) => {
if ($(`#softprompt option[value="${prompt.name}"]`).length === 0) {
$("#softprompt").append(
``
);
if (prompt.selected) {
$("#softprompt").val(prompt.name);
}
}
});
// No SP selected or no SPs
if (soft_prompts.length === 0 || !soft_prompts.some((x) => x.selected)) {
$("#softprompt").val("");
}
}
function printCharacters() {
//console.log('printCharacters() entered');
$("#rm_print_characters_block").empty();
//console.log('printCharacters() -- sees '+characters.length+' characters.');
characters.forEach(function (item, i, arr) {
var this_avatar = default_avatar;
if (item.avatar != "none") {
this_avatar = "characters/" + item.avatar + "?" + Date.now();
} //RossAscends: changed 'prepend' to 'append' to make alphabetical sorting display correctly.
$("#rm_print_characters_block").append(
`
${item.name}
`
);
//console.log('printcharacters() -- printing -- ChID '+i+' ('+item.name+')');
});
printGroups();
}
async function getCharacters() {
await getGroups();
//console.log('getCharacters() -- entered');
//console.log(characters);
var response = await fetch("/getcharacters", {
//RossAscends: changed from const
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({
"": "",
}),
});
if (response.ok === true) {
var getData = ""; //RossAscends: reset to force array to update to account for deleted character.
var getData = await response.json(); //RossAscends: changed from const
//console.log(getData);
//var aa = JSON.parse(getData[0]);
var load_ch_count = Object.getOwnPropertyNames(getData); //RossAscends: change from const to create dynamic character load amounts.
var charCount = load_ch_count.length;
//console.log('/getcharacters -- expecting to load '+charCount+' characters.')
for (var i = 0; i < load_ch_count.length; i++) {
characters[i] = [];
characters[i] = getData[i];
//console.log('/getcharacters -- loaded character #'+(i+1)+' ('+characters[i].name+')');
}
//RossAscends: updated character sorting to be alphabetical
characters.sort(function (a, b) {
//console.log('sorting characters: '+a.name+' vs '+b.name);
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
//console.log(characters);
//characters.reverse();
//console.log('/getcharacters -- this_chid -- '+this_chid);
if (this_chid != undefined && this_chid != "invalid-safety-id") {
$("#avatar_url_pole").val(characters[this_chid].avatar);
}
//console.log('/getcharacters -- sending '+i+' characters to /printcharacters');
printCharacters();
//console.log(propOwn.length);
//return JSON.parse(getData[0]);
//const getData = await response.json();
//var getMessage = getData.results[0].text;
}
}
async function getBackgrounds() {
const response = await fetch("/getbackgrounds", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({
"": "",
}),
});
if (response.ok === true) {
const getData = await response.json();
//background = getData;
//console.log(getData.length);
for (var i = 0; i < getData.length; i++) {
//console.log(1);
$("#bg_menu_content").append(
"
");
selectRightMenuWithAnimation('rm_info_block');
setRightTabSelectedClass();
prev_selected_char = charId;
}
function select_selected_character(chid) {
//character select
//console.log('select_selected_character() -- starting with input of -- '+chid+' (name:'+characters[chid].name+')');
select_rm_create();
menu_type = "character_edit";
$("#delete_button").css("display", "block");
$("#export_button").css("display", "block");
setRightTabSelectedClass('rm_button_selected_ch');
var display_name = characters[chid].name;
$("#rm_button_selected_ch").children("h2").text(display_name);
//create text poles
$("#rm_button_back").css("display", "none");
//$("#character_import_button").css("display", "none");
$("#create_button").attr("value", "Save"); // what is the use case for this?
$("#create_button_label").css("display", "none");
$("#rm_button_selected_ch").children("h2").text(display_name);
$("#add_avatar_button").val("");
$("#character_popup_text_h3").text(characters[chid].name);
$("#character_name_pole").val(characters[chid].name);
$("#description_textarea").val(characters[chid].description);
$("#personality_textarea").val(characters[chid].personality);
$("#firstmessage_textarea").val(characters[chid].first_mes);
$("#scenario_pole").val(characters[chid].scenario);
$("#talkativeness_slider").val(
characters[chid].talkativeness ?? talkativeness_default
);
$("#mes_example_textarea").val(characters[chid].mes_example);
$("#selected_chat_pole").val(characters[chid].chat);
$("#create_date_pole").val(characters[chid].create_date);
$("#avatar_url_pole").val(characters[chid].avatar);
$("#chat_import_avatar_url").val(characters[chid].avatar);
$("#chat_import_character_name").val(characters[chid].name);
//$("#avatar_div").css("display", "none");
var this_avatar = default_avatar;
if (characters[chid].avatar != "none") {
this_avatar = "characters/" + characters[chid].avatar;
}
$("#avatar_load_preview").attr("src", this_avatar + "?" + Date.now());
$("#name_div").css("display", "none");
$("#form_create").attr("actiontype", "editcharacter");
active_character = chid;
//console.log('select_selected_character() -- active_character -- '+chid+'(ChID of '+display_name+')');
saveSettingsDebounced();
//console.log('select_selected_character() -- called saveSettings() to save -- active_character -- '+active_character+'(ChID of '+display_name+')');
}
function select_rm_create() {
menu_type = "create";
//console.log('select_rm_Create() -- selected button: '+selected_button);
if (selected_button == "create") {
if (create_save_avatar != "") {
$("#add_avatar_button").get(0).files = create_save_avatar;
read_avatar_load($("#add_avatar_button").get(0));
}
}
selectRightMenuWithAnimation('rm_ch_create_block');
setRightTabSelectedClass();
$("#delete_button_div").css("display", "none");
$("#delete_button").css("display", "none");
$("#export_button").css("display", "none");
$("#create_button_label").css("display", "block");
$("#create_button").attr("value", "Create");
//RossAscends: commented this out as part of the auto-loading token counter
//$('#result_info').html(' ');
//create text poles
$("#rm_button_back").css("display", "inline-block");
$("#character_import_button").css("display", "inline-block");
$("#character_popup_text_h3").text("Create character");
$("#character_name_pole").val(create_save_name);
$("#description_textarea").val(create_save_description);
$("#personality_textarea").val(create_save_personality);
$("#firstmessage_textarea").val(create_save_first_message);
$("#talkativeness_slider").val(create_save_talkativeness);
$("#scenario_pole").val(create_save_scenario);
if ($.trim(create_save_mes_example).length == 0) {
$("#mes_example_textarea").val("");
} else {
$("#mes_example_textarea").val(create_save_mes_example);
}
$("#avatar_div").css("display", "flex");
$("#avatar_load_preview").attr("src", default_avatar);
$("#name_div").css("display", "block");
$("#form_create").attr("actiontype", "createcharacter");
}
function select_rm_characters() {
if (prev_selected_char) {
let newChId = characters.findIndex((x) => x.name == prev_selected_char);
$(`.character_select[chid="${newChId}"]`).trigger("click");
prev_selected_char = null;
}
menu_type = "characters";
selectRightMenuWithAnimation('rm_characters_block');
setRightTabSelectedClass('rm_button_characters');
}
function setExtensionPrompt(key, value) {
extension_prompts[key] = value;
}
function callPopup(text, type) {
if (type) {
popup_type = type;
}
$("#dialogue_popup_cancel").css("display", "inline-block");
switch (popup_type) {
case "text":
case "char_not_selected":
$("#dialogue_popup_ok").text("Ok");
$("#dialogue_popup_cancel").css("display", "none");
break;
case "world_imported":
case "new_chat":
$("#dialogue_popup_ok").text("Yes");
break;
case "del_world":
case "del_group":
default:
$("#dialogue_popup_ok").text("Delete");
}
$("#dialogue_popup_text").html(text);
$("#shadow_popup").css("display", "block");
$("#shadow_popup").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
});
}
function read_bg_load(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#bg_load_preview")
.attr("src", e.target.result)
.width(103)
.height(83);
var formData = new FormData($("#form_bg_download").get(0));
//console.log(formData);
jQuery.ajax({
type: "POST",
url: "/downloadbackground",
data: formData,
beforeSend: function () {
//$('#create_button').attr('value','Creating...');
},
cache: false,
contentType: false,
processData: false,
success: function (html) {
setBackground(html);
if (bg1_toggle == true) {
// this is a repeat of the background setting function for when user uploads a new BG image
bg1_toggle = false; // should make the Bg setting a modular function to be called in both cases
var number_bg = 2;
var target_opacity = 1.0;
} else {
bg1_toggle = true;
var number_bg = 1;
var target_opacity = 0.0;
}
$("#bg2").transition({
opacity: target_opacity,
duration: 1300, //animation_rm_duration,
easing: "linear",
complete: function () {
$("#options").css("display", "none");
},
});
$("#bg" + number_bg).css(
"background-image",
"url(" + e.target.result + ")"
);
$("#form_bg_download").after(
"
"
);
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
},
});
};
reader.readAsDataURL(input.files[0]);
}
}
function showSwipeButtons() {
if (
chat[chat.length - 1].name === 'TavernAI' ||
!swipes ||
$('.mes:last').attr('mesid') <= 0 ||
chat[chat.length - 1].is_user ||
count_view_mes <= 1
) { return; }
const currentMessage = $("#chat").children().filter(`[mesid="${count_view_mes - 1}"]`);
const swipeId = chat[chat.length - 1].swipe_id;
var swipesCounterHTML = (`${(swipeId + 1)}/${(chat[chat.length - 1].swipes.length)}`);
if (swipeId !== undefined && swipeId != 0) {
currentMessage.children('.swipe_left').css('display', 'flex');
}
if (is_send_press === false || chat[chat.length - 1].swipes.length >= swipeId) { //only show right when generate is off, or when next right swipe would not make a generate happen
currentMessage.children('.swipe_right').css('display', 'flex');
currentMessage.children('.swipe_right').css('opacity', '0.3');
}
//had to add this to make the swipe counter work
//(copied from the onclick functions for swipe buttons..
//don't know why the array isn't set for non-swipe messsages in Generate or addOneMessage..)
if (chat[chat.length - 1]['swipe_id'] === undefined) { // if there is no swipe-message in the last spot of the chat array
chat[chat.length - 1]['swipe_id'] = 0; // set it to id 0
chat[chat.length - 1]['swipes'] = []; // empty the array
chat[chat.length - 1]['swipes'][0] = chat[chat.length - 1]['mes']; //assign swipe array with last message from chat
}
//console.log((chat[chat.length - 1]));
if (is_send_press === false && (chat[chat.length - 1].swipes.length - swipeId) === 1) {
console.log('highlighting R swipe');
currentMessage.children('.swipe_right').css('opacity', '0.7');
}
console.log(swipesCounterHTML);
$(".swipes-counter").html(swipesCounterHTML);
//console.log(swipeId);
//console.log(chat[chat.length - 1].swipes.length);
}
function hideSwipeButtons() {
//console.log('hideswipebuttons entered');
$("#chat").children().filter('[mesid="' + (count_view_mes - 1) + '"]').children('.swipe_right').css('display', 'none');
$("#chat").children().filter('[mesid="' + (count_view_mes - 1) + '"]').children('.swipe_left').css('display', 'none');
}
window["TavernAI"].getContext = function () {
return {
chat: chat,
characters: characters,
groups: groups,
worldInfo: world_info_data,
name1: name1,
name2: name2,
characterId: this_chid,
groupId: selected_group,
chatId: this_chid && characters[this_chid] && characters[this_chid].chat,
onlineStatus: online_status,
addOneMessage: addOneMessage,
generate: Generate,
encode: encode,
extensionPrompts: extension_prompts,
setExtensionPrompt: setExtensionPrompt,
saveChat: saveChat,
sendSystemMessage: sendSystemMessage,
};
};
$(document).ready(function () {
$('#swipes-checkbox').change(function () {
console.log('detected swipes-checkbox changed values')
swipes = !!$('#swipes-checkbox').prop('checked');
if (swipes) {
//console.log('toggle change calling showswipebtns');
showSwipeButtons();
} else {
hideSwipeButtons();
}
});
///// SWIPE BUTTON CLICKS ///////
$(document).on('click', '.swipe_right', function () { //when we click swipe right button
const swipe_duration = 120;
const swipe_range = 700;
//console.log(swipe_range);
let run_generate = false;
let run_swipe_right = false;
if (chat[chat.length - 1]['swipe_id'] === undefined) { // if there is no swipe-message in the last spot of the chat array
chat[chat.length - 1]['swipe_id'] = 0; // set it to id 0
chat[chat.length - 1]['swipes'] = []; // empty the array
chat[chat.length - 1]['swipes'][0] = chat[chat.length - 1]['mes']; //assign swipe array with last message from chat
}
chat[chat.length - 1]['swipe_id']++; //make new slot in array
//console.log(chat[chat.length-1]['swipes']);
if (parseInt(chat[chat.length - 1]['swipe_id']) === chat[chat.length - 1]['swipes'].length) { //if swipe id of last message is the same as the length of the 'swipes' array
run_generate = true;
} else if (parseInt(chat[chat.length - 1]['swipe_id']) < chat[chat.length - 1]['swipes'].length) { //otherwise, if the id is less than the number of swipes
chat[chat.length - 1]['mes'] = chat[chat.length - 1]['swipes'][chat[chat.length - 1]['swipe_id']]; //load the last mes box with the latest generation
run_swipe_right = true; //then prepare to do normal right swipe to show next message
}
if (chat[chat.length - 1]['swipe_id'] > chat[chat.length - 1]['swipes'].length) { //if we swipe right while generating (the swipe ID is greater than what we are viewing now)
chat[chat.length - 1]['swipe_id'] = chat[chat.length - 1]['swipes'].length; //show that message slot (will be '...' while generating)
}
if (run_generate) { //hide swipe arrows while generating
$(this).css('display', 'none');
}
if (run_generate || run_swipe_right) { // handles animated transitions when swipe right, specifically height transitions between messages
let this_mes_div = $(this).parent();
let this_mes_block = $(this).parent().children('.mes_block').children('.mes_text');
const this_mes_div_height = this_mes_div[0].scrollHeight;
const this_mes_block_height = this_mes_block[0].scrollHeight;
this_mes_div.children('.swipe_left').css('display', 'flex');
this_mes_div.children('.mes_block').transition({ // this moves the div back and forth
x: '-' + swipe_range,
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
const is_animation_scroll = ($('#chat').scrollTop() >= ($('#chat').prop("scrollHeight") - $('#chat').outerHeight()) - 10);
//console.log(parseInt(chat[chat.length-1]['swipe_id']));
//console.log(chat[chat.length-1]['swipes'].length);
if (run_generate && parseInt(chat[chat.length - 1]['swipe_id']) === chat[chat.length - 1]['swipes'].length) {
//console.log('showing ""..."');
$("#chat").children().filter('[mesid="' + (count_view_mes - 1) + '"]').children('.mes_block').children('.mes_text').html('...'); //shows "..." while generating
} else {
//console.log('showing previously generated swipe candidate, or "..."');
//console.log('onclick right swipe calling addOneMessage');
addOneMessage(chat[chat.length - 1], 'swipe');
}
let new_height = this_mes_div_height - (this_mes_block_height - this_mes_block[0].scrollHeight);
if (new_height < 103) new_height = 103;
this_mes_div.animate({ height: new_height + 'px' }, {
duration: 100,
queue: false,
progress: function () {
// Scroll the chat down as the message expands
if (is_animation_scroll) $("#chat").scrollTop($("#chat")[0].scrollHeight);
},
complete: function () {
this_mes_div.css('height', 'auto');
// Scroll the chat down to the bottom once the animation is complete
if (is_animation_scroll) $("#chat").scrollTop($("#chat")[0].scrollHeight);
}
});
this_mes_div.children('.mes_block').transition({
x: swipe_range,
duration: 0,
easing: animation_rm_easing,
queue: false,
complete: function () {
this_mes_div.children('.mes_block').transition({
x: '0px',
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
if (run_generate && !is_send_press && parseInt(chat[chat.length - 1]['swipe_id']) === chat[chat.length - 1]['swipes'].length) {
console.log('caught here 2');
is_send_press = true;
Generate('swipe');
} else {
if (parseInt(chat[chat.length - 1]['swipe_id']) !== chat[chat.length - 1]['swipes'].length) {
saveChat();
}
}
}
});
}
});
}
});
$(this).parent().children('.avatar').transition({ // moves avatar aong with swipe
x: '-' + swipe_range,
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
$(this).parent().children('.avatar').transition({
x: swipe_range,
duration: 0,
easing: animation_rm_easing,
queue: false,
complete: function () {
$(this).parent().children('.avatar').transition({
x: '0px',
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
}
});
}
});
}
});
}
});
$(document).on('click', '.swipe_left', function () { // when we swipe left..but no generation.
const swipe_duration = 120;
const swipe_range = '700px';
chat[chat.length - 1]['swipe_id']--;
if (chat[chat.length - 1]['swipe_id'] >= 0) { // hide the left arrow if we are viewing the first candidate of the last message block
$(this).parent().children('swipe_right_button').css('display', 'flex');
if (chat[chat.length - 1]['swipe_id'] === 0) {
$(this).css('display', 'none');
}
let this_mes_div = $(this).parent();
let this_mes_block = $(this).parent().children('.mes_block').children('.mes_text');
const this_mes_div_height = this_mes_div[0].scrollHeight;
this_mes_div.css('height', this_mes_div_height);
const this_mes_block_height = this_mes_block[0].scrollHeight;
chat[chat.length - 1]['mes'] = chat[chat.length - 1]['swipes'][chat[chat.length - 1]['swipe_id']];
$(this).parent().children('.mes_block').transition({
x: swipe_range,
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
const is_animation_scroll = ($('#chat').scrollTop() >= ($('#chat').prop("scrollHeight") - $('#chat').outerHeight()) - 10);
//console.log('on left swipe click calling addOneMessage');
addOneMessage(chat[chat.length - 1], 'swipe');
let new_height = this_mes_div_height - (this_mes_block_height - this_mes_block[0].scrollHeight);
if (new_height < 103) new_height = 103;
this_mes_div.animate({ height: new_height + 'px' }, {
duration: 100,
queue: false,
progress: function () {
// Scroll the chat down as the message expands
if (is_animation_scroll) $("#chat").scrollTop($("#chat")[0].scrollHeight);
},
complete: function () {
this_mes_div.css('height', 'auto');
// Scroll the chat down to the bottom once the animation is complete
if (is_animation_scroll) $("#chat").scrollTop($("#chat")[0].scrollHeight);
}
});
$(this).parent().children('.mes_block').transition({
x: '-' + swipe_range,
duration: 0,
easing: animation_rm_easing,
queue: false,
complete: function () {
$(this).parent().children('.mes_block').transition({
x: '0px',
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
saveChat();
}
});
}
});
}
});
$(this).parent().children('.avatar').transition({
x: swipe_range,
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
$(this).parent().children('.avatar').transition({
x: '-' + swipe_range,
duration: 0,
easing: animation_rm_easing,
queue: false,
complete: function () {
$(this).parent().children('.avatar').transition({
x: '0px',
duration: swipe_duration,
easing: animation_rm_easing,
queue: false,
complete: function () {
}
});
}
});
}
});
}
if (chat[chat.length - 1]['swipe_id'] < 0) {
chat[chat.length - 1]['swipe_id'] = 0;
}
});
$("#character_search_bar").on("input", function () {
const selector = ['#rm_print_characters_block .character_select', '#rm_print_characters_block .group_select'].join(',');
const searchValue = $(this).val().trim().toLowerCase();
if (!searchValue) {
$(selector).show();
} else {
$(selector).each(function () {
$(this).children(".ch_name").text().toLowerCase().includes(searchValue)
? $(this).show()
: $(this).hide();
});
}
});
$("#characloud_url").click(function () {
window.open("https://boosty.to/tavernai", "_blank");
});
$("#send_but").click(function () {
if (is_send_press == false) {
//hideSwipeButtons();
is_send_press = true;
Generate();
}
});
//hotkey to send input with enter (shift+enter generates a new line in the chat input box)
//this is not ideal for touch device users with virtual keyboards.
//ideally we would detect if the user is using a virtual keyboard, and disable this shortcut for them.
//because mobile users' hands are always near the screen, tapping the send button is better for them, and enter should always make a new line.
//note: CAI seems to have this handled. PC: shift+enter = new line, enter = send. iOS: shift+enter AND enter both make new lines, and only the send button sends.
//maybe a way to simulate this would be to disable the eventListener for people iOS.
$("#send_textarea").keydown(function (e) {
if (!e.shiftKey && !e.ctrlKey && e.key == "Enter" && is_send_press == false) {
//hideSwipeButtons();
is_send_press = true;
e.preventDefault();
Generate();
}
});
//menu buttons setup
$("#rm_button_settings").click(function () {
selected_button = "settings";
menu_type = "settings";
selectRightMenuWithAnimation('rm_api_block');
setRightTabSelectedClass('rm_button_settings');
});
$("#rm_button_characters").click(function () {
selected_button = "characters";
select_rm_characters();
});
$("#rm_button_back").click(function () {
selected_button = "characters";
select_rm_characters();
});
$("#rm_button_create").click(function () {
selected_button = "create";
select_rm_create();
});
$("#rm_button_selected_ch").click(function () {
selected_button = "character_edit";
select_selected_character(this_chid);
});
$(document).on("click", ".character_select", function () {
if (selected_group && is_group_generating) {
return;
}
if (this_chid !== $(this).attr("chid")) {
//if clicked on a different character from what was currently selected
if (!is_send_press) {
resetSelectedGroup();
this_edit_mes_id = undefined;
selected_button = "character_edit";
this_chid = $(this).attr("chid");
active_character = this_chid;
clearChat();
chat.length = 0;
getChat();
//console.log('Clicked on '+characters[this_chid].name+' Active_Character set to: '+active_character+' (ChID:'+this_chid+')');
}
} else {
//if clicked on character that was already selected
selected_button = "character_edit";
select_selected_character(this_chid);
}
$("#character_search_bar").val("").trigger("input");
});
$(document).on("input", ".edit_textarea", function () {
scroll_holder = $("#chat").scrollTop();
$(this).height(0).height(this.scrollHeight);
is_use_scroll_holder = true;
});
$("#chat").on("scroll", function () {
if (is_use_scroll_holder) {
$("#chat").scrollTop(scroll_holder);
is_use_scroll_holder = false;
}
});
$(document).on("click", ".del_checkbox", function () {
//when a 'delete message' checkbox is clicked
$(".del_checkbox").each(function () {
$(this).prop("checked", false);
$(this).parent().css("background", css_mes_bg);
});
$(this).parent().css("background", "#600"); //sets the bg of the mes selected for deletion
var i = $(this).parent().attr("mesid"); //checks the message ID in the chat
this_del_mes = i;
while (i < chat.length) {
//as long as the current message ID is less than the total chat length
$(".mes[mesid='" + i + "']").css("background", "#600"); //sets the bg of the all msgs BELOW the selected .mes
$(".mes[mesid='" + i + "']")
.children(".del_checkbox")
.prop("checked", true);
i++;
//console.log(i);
}
});
$(document).on("click", "#user_avatar_block .avatar", function () {
user_avatar = $(this).attr("imgfile");
$(".mes").each(function () {
if ($(this).attr("ch_name") == name1) {
$(this)
.children(".avatar")
.children("img")
.attr("src", "User Avatars/" + user_avatar);
}
});
saveSettingsDebounced();
highlightSelectedAvatar();
});
$(document).on("click", "#user_avatar_block .avatar_upload", function () {
$("#avatar_upload_file").click();
});
$("#avatar_upload_file").on("change", function (e) {
const file = e.target.files[0];
if (!file) {
return;
}
const formData = new FormData($("#form_upload_avatar").get(0));
jQuery.ajax({
type: "POST",
url: "/uploaduseravatar",
data: formData,
beforeSend: () => { },
cache: false,
contentType: false,
processData: false,
success: function (data) {
if (data.path) {
appendUserAvatar(data.path);
}
},
error: (jqXHR, exception) => { },
});
// Will allow to select the same file twice in a row
$("#form_upload_avatar").trigger("reset");
});
$("#logo_block").click(function (event) {
if (!bg_menu_toggle) {
$("#bg_menu_button").transition({
perspective: "100px",
rotate3d: "1,1,0,180deg",
});
$("#bg_menu_content").transition({
opacity: 1.0,
height: "90vh",
duration: 340,
easing: "in",
complete: function () {
bg_menu_toggle = true;
$("#bg_menu_content").css("overflow-y", "auto");
},
});
} else {
$("#bg_menu_button").transition({
perspective: "100px",
rotate3d: "1,1,0,360deg",
});
$("#bg_menu_content").css("overflow-y", "hidden");
$("#bg_menu_content").transition({
opacity: 0.0,
height: "0px",
duration: 340,
easing: "in",
complete: function () {
bg_menu_toggle = false;
},
});
}
});
$(document).on("click", ".bg_example_img", function () {
//when user clicks on a BG thumbnail...
var this_bgfile = $(this).attr("bgfile"); // this_bgfile = whatever they clicked
if (bg1_toggle == true) {
//if bg1 is toggled true (initially set as true in first JS vars)
bg1_toggle = false; // then toggle it false
var number_bg = 2; // sets a variable for bg2
var target_opacity = 1.0; // target opacity is 100%
} else {
//if bg1 is FALSE
bg1_toggle = true; // make it true
var number_bg = 1; // set variable to bg1..
var target_opacity = 0.0; // set target opacity to 0
}
$("#bg2").stop(); // first, stop whatever BG transition was happening before
$("#bg2").transition({
// start a new BG transition routine
opacity: target_opacity, // set opacity to previously set variable
duration: 1300, //animation_rm_duration,
easing: "linear",
complete: function () {
// why does the BG transition completion make the #options (right nav) invisible?
$("#options").css("display", "none");
},
});
$("#bg" + number_bg).css(
"background-image",
'url("backgrounds/' + this_bgfile + '")'
);
setBackground(this_bgfile);
});
$(document).on("click", ".bg_example_cross", function () {
bg_file_for_del = $(this);
//$(this).parent().remove();
//delBackground(this_bgfile);
popup_type = "del_bg";
callPopup("
Delete the background?
");
});
$("#advanced_div").click(function () {
if (!is_advanced_char_open) {
is_advanced_char_open = true;
$("#character_popup").css("display", "grid");
$("#character_popup").css("opacity", 0.0);
$("#character_popup").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
});
} else {
is_advanced_char_open = false;
$("#character_popup").css("display", "none");
}
});
$("#character_cross").click(function () {
is_advanced_char_open = false;
$("#character_popup").css("display", "none");
});
$("#character_popup_ok").click(function () {
is_advanced_char_open = false;
$("#character_popup").css("display", "none");
});
$("#dialogue_popup_ok").click(function () {
$("#shadow_popup").css("display", "none");
$("#shadow_popup").css("opacity:", 0.0);
if (popup_type == "del_bg") {
delBackground(bg_file_for_del.attr("bgfile"));
bg_file_for_del.parent().remove();
}
if (popup_type == "del_ch") {
console.log(
"Deleting character -- ChID: " +
this_chid +
" -- Name: " +
characters[this_chid].name
);
var msg = jQuery("#form_create").serialize(); // ID form
jQuery.ajax({
method: "POST",
url: "/deletecharacter",
beforeSend: function () {
select_rm_info("Character deleted");
//$('#create_button').attr('value','Deleting...');
},
data: msg,
cache: false,
success: function (html) {
//RossAscends: New handling of character deletion that avoids page refreshes and should have fixed char corruption due to cache problems.
//due to how it is handled with 'popup_type', i couldn't find a way to make my method completely modular, so keeping it in TAI-main.js as a new default.
//this allows for dynamic refresh of character list after deleting a character.
$("#character_cross").click(); // closes advanced editing popup
this_chid = "invalid-safety-id"; // unsets expected chid before reloading (related to getCharacters/printCharacters from using old arrays)
characters.length = 0; // resets the characters array, forcing getcharacters to reset
name2 = systemUserName; // replaces deleted charcter name with system user since she will be displayed next.
chat = [...safetychat]; // sets up system user to tell user about having deleted a character
setRightTabSelectedClass() // 'deselects' character's tab panel
$(document.getElementById("rm_button_selected_ch"))
.children("h2")
.text(""); // removes character name from nav tabs
clearChat(); // removes deleted char's chat
this_chid = undefined; // prevents getCharacters from trying to load an invalid char.
getCharacters(); // gets the new list of characters (that doesn't include the deleted one)
printMessages(); // prints out system user's 'deleted character' message
//console.log("#dialogue_popup_ok(del-char) >>>> saving");
saveSettingsDebounced(); // saving settings to keep changes to variables
//getCharacters();
//$('#create_button_div').html(html);
},
});
}
if (popup_type === "world_imported") {
selectImportedWorldInfo();
}
if (popup_type === "del_world" && world_info) {
deleteWorldInfo(world_info);
}
if (popup_type === "del_group") {
const groupId = $("#dialogue_popup").data("group_id");
if (groupId) {
deleteGroup(groupId);
}
}
//Make a new chat for selected character
if (
popup_type == "new_chat" &&
this_chid != undefined &&
menu_type != "create"
) {
//Fix it; New chat doesn't create while open create character menu
clearChat();
chat.length = 0;
characters[this_chid].chat = name2 + " - " + humanizedDateTime(); //RossAscends: added character name to new chat filenames and replaced Date.now() with humanizedDateTime;
$("#selected_chat_pole").val(characters[this_chid].chat);
saveCharacterDebounced();
getChat();
}
});
$("#dialogue_popup_cancel").click(function () {
$("#shadow_popup").css("display", "none");
$("#shadow_popup").css("opacity:", 0.0);
popup_type = "";
});
$("#add_bg_button").change(function () {
read_bg_load(this);
});
$("#add_avatar_button").change(function () {
is_mes_reload_avatar = Date.now();
read_avatar_load(this);
});
$("#form_create").submit(function (e) {
$("#rm_info_avatar").html("");
var formData = new FormData($("#form_create").get(0));
if ($("#form_create").attr("actiontype") == "createcharacter") {
if ($("#character_name_pole").val().length > 0) {
//if the character name text area isn't empty (only posible when creating a new character)
//console.log('/createcharacter entered');
jQuery.ajax({
type: "POST",
url: "/createcharacter",
data: formData,
beforeSend: function () {
$("#create_button").attr("disabled", true);
$("#create_button").attr("value", "⏳");
},
cache: false,
contentType: false,
processData: false,
success: async function (html) {
$("#character_cross").click(); //closes the advanced character editing popup
$("#character_name_pole").val("");
create_save_name = "";
$("#description_textarea").val("");
create_save_description = "";
$("#personality_textarea").val("");
create_save_personality = "";
$("#firstmessage_textarea").val("");
create_save_first_message = "";
$("#talkativeness_slider").val(talkativeness_default);
create_save_talkativeness = talkativeness_default;
$("#character_popup_text_h3").text("Create character");
$("#scenario_pole").val("");
create_save_scenario = "";
$("#mes_example_textarea").val("");
create_save_mes_example = "";
create_save_avatar = "";
$("#create_button").removeAttr("disabled");
$("#add_avatar_button").replaceWith(
$("#add_avatar_button").val("").clone(true)
);
$("#create_button").attr("value", "✅");
if (true) {
let oldSelectedChar = null;
if (this_chid != undefined && this_chid != "invalid-safety-id") {
oldSelectedChar = characters[this_chid].name;
}
await getCharacters();
$("#rm_info_block").transition({ opacity: 0, duration: 0 });
var $prev_img = $("#avatar_div_div").clone();
$("#rm_info_avatar").append($prev_img);
select_rm_info("Character created", oldSelectedChar);
$("#rm_info_block").transition({ opacity: 1.0, duration: 2000 });
} else {
$("#result_info").html(html);
}
},
error: function (jqXHR, exception) {
//alert('ERROR: '+xhr.status+ ' Status Text: '+xhr.statusText+' '+xhr.responseText);
$("#create_button").removeAttr("disabled");
},
});
} else {
$("#result_info").html("Name not entered");
}
} else {
//console.log('/editcharacter -- entered.');
//console.log('Avatar Button Value:'+$("#add_avatar_button").val());
jQuery.ajax({
type: "POST",
url: "/editcharacter",
data: formData,
beforeSend: function () {
$("#create_button").attr("disabled", true);
$("#create_button").attr("value", "Save");
},
cache: false,
contentType: false,
processData: false,
success: function (html) {
$(".mes").each(function () {
if ($(this).attr("ch_name") != name1) {
$(this)
.children(".avatar")
.children("img")
.attr("src", $("#avatar_load_preview").attr("src"));
}
});
if (chat.length === 1) {
var this_ch_mes = default_ch_mes;
if ($("#firstmessage_textarea").val() != "") {
this_ch_mes = $("#firstmessage_textarea").val();
}
if (
this_ch_mes !=
$.trim(
$("#chat")
.children(".mes")
.children(".mes_block")
.children(".mes_text")
.text()
)
) {
clearChat();
chat.length = 0;
chat[0] = {};
chat[0]["name"] = name2;
chat[0]["is_user"] = false;
chat[0]["is_name"] = true;
chat[0]["mes"] = this_ch_mes;
add_mes_without_animation = true;
//console.log('form create submission calling addOneMessage');
addOneMessage(chat[0]);
}
}
$("#create_button").removeAttr("disabled");
getCharacters();
$("#add_avatar_button").replaceWith(
$("#add_avatar_button").val("").clone(true)
);
$("#create_button").attr("value", "Save");
},
error: function (jqXHR, exception) {
$("#create_button").removeAttr("disabled");
$("#result_info").html("Error: no connection");
},
});
}
});
$("#delete_button").click(function () {
popup_type = "del_ch";
callPopup(
"
Delete the character?
Your chat will be closed."
);
});
$("#rm_info_button").click(function () {
$("#rm_info_avatar").html("");
select_rm_characters();
});
//////// OPTIMIZED ALL CHAR CREATION/EDITING TEXTAREA LISTENERS ///////////////
$("#character_name_pole").on("change keyup paste", function () {
if (menu_type == "create") {
create_save_name = $("#character_name_pole").val();
}
});
$("#description_textarea, #personality_textarea, #scenario_pole" +
"#mes_example_textarea, #firstmessage_textarea")
.on("keyup paste cut", function () {
if (menu_type == "create") {
create_save_description = $("#description_textarea").val();
create_save_personality = $("#personality_textarea").val();
create_save_scenario = $("#scenario_pole").val();
create_save_mes_example = $("#mes_example_textarea").val();
create_save_first_message = $("#firstmessage_textarea").val();
} else {
saveCharacterDebounced();
}
});
$("#talkativeness_slider").on("input", function () {
if (menu_type == "create") {
create_save_talkativeness = $("#talkativeness_slider").val();
} else {
saveCharacterDebounced();
}
});
///////////////////////////////////////////////////////////////////////////////////
$("#api_button").click(function () {
if ($("#api_url_text").val() != "") {
$("#api_loading").css("display", "inline-block");
$("#api_button").css("display", "none");
api_server = $("#api_url_text").val();
api_server = $.trim(api_server);
//console.log("1: "+api_server);
if (api_server.substr(api_server.length - 1, 1) == "/") {
api_server = api_server.substr(0, api_server.length - 1);
}
if (
!(
api_server.substr(api_server.length - 3, 3) == "api" ||
api_server.substr(api_server.length - 4, 4) == "api/"
)
) {
api_server = api_server + "/api";
}
//console.log("2: "+api_server);
main_api = "kobold";
saveSettingsDebounced();
is_get_status = true;
is_api_button_press = true;
getStatus();
clearSoftPromptsList();
getSoftPromptsList();
}
});
$("#api_button_textgenerationwebui").click(function () {
if ($("#textgenerationwebui_api_url_text").val() != "") {
$("#api_loading_textgenerationwebui").css("display", "inline-block");
$("#api_button_textgenerationwebui").css("display", "none");
api_server_textgenerationwebui = $(
"#textgenerationwebui_api_url_text"
).val();
api_server_textgenerationwebui = $.trim(api_server_textgenerationwebui);
if (
api_server_textgenerationwebui.substr(
api_server_textgenerationwebui.length - 1,
1
) == "/"
) {
api_server_textgenerationwebui = api_server_textgenerationwebui.substr(
0,
api_server_textgenerationwebui.length - 1
);
}
//console.log("2: "+api_server_textgenerationwebui);
main_api = "textgenerationwebui";
saveSettingsDebounced();
is_get_status = true;
is_api_button_press = true;
getStatus();
}
});
$("body").click(function () {
if ($("#options").css("opacity") == 1.0) {
$("#options").transition({
opacity: 0.0,
duration: 100, //animation_rm_duration,
easing: animation_rm_easing,
complete: function () {
$("#options").css("display", "none");
},
});
}
});
$("#options_button").click(function () {
// this is the options button click function, shows the options menu if closed
if (
$("#options").css("display") === "none" &&
$("#options").css("opacity") == 0.0
) {
$("#options").css("display", "block");
$("#options").transition({
opacity: 1.0, // the manual setting of CSS via JS is what allows the click-away feature to work
duration: 100,
easing: animation_rm_easing,
complete: function () { },
});
}
});
///////////// OPTIMIZED LISTENERS FOR LEFT SIDE OPTIONS POPUP MENU //////////////////////
$("#options_button [id]").on("click", function () {
var id = $(this).attr("id");
if (id == "option_select_chat") {
if (selected_group) {
// will open a chat selection screen
openNavToggle();
$("#rm_button_characters").trigger("click");
return;
}
if (this_chid != undefined && !is_send_press) {
getAllCharaChats();
$("#shadow_select_chat_popup").css("display", "block");
$("#shadow_select_chat_popup").css("opacity", 0.0);
$("#shadow_select_chat_popup").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
});
}
}
else if (id == "option_start_new_chat") {
if (selected_group) {
// will open a group creation screen
openNavToggle();
$("#rm_button_group_chats").trigger("click");
return;
}
if (this_chid != undefined && !is_send_press) {
popup_type = "new_chat";
callPopup("