mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
(BETA) Add alternate greetings
This commit is contained in:
427
public/script.js
427
public/script.js
@ -563,6 +563,7 @@ let create_save_avatar = "";
|
||||
let create_save_scenario = "";
|
||||
let create_save_mes_example = "";
|
||||
let create_save_talkativeness = talkativeness_default;
|
||||
let create_save_alternate_greetings = [];
|
||||
|
||||
//animation right menu
|
||||
let animation_duration = 250;
|
||||
@ -3647,13 +3648,26 @@ async function getChatResult() {
|
||||
name2 = characters[this_chid].name;
|
||||
if (chat.length === 0) {
|
||||
const firstMes = characters[this_chid].first_mes || default_ch_mes;
|
||||
const alternateGreetings = characters[this_chid]?.data?.alternate_greetings;
|
||||
|
||||
chat[0] = {
|
||||
name: name2,
|
||||
is_user: false,
|
||||
is_name: true,
|
||||
send_date: humanizedDateTime(),
|
||||
mes: firstMes
|
||||
mes: firstMes,
|
||||
};
|
||||
|
||||
if (Array.isArray(alternateGreetings) && alternateGreetings.length > 0) {
|
||||
chat[0]['swipe_id'] = 0;
|
||||
chat[0]['swipes'] = [];
|
||||
chat[0]['swipes'][0] = chat[0]['mes'];
|
||||
|
||||
for (let i = 0; i < alternateGreetings.length; i++) {
|
||||
const alternateGreeting = alternateGreetings[i];
|
||||
chat[0]['swipes'].push(substituteParams(alternateGreeting));
|
||||
}
|
||||
}
|
||||
}
|
||||
printMessages();
|
||||
select_selected_character(this_chid);
|
||||
@ -4431,6 +4445,7 @@ export function select_selected_character(chid) {
|
||||
$("#name_div").removeClass('displayBlock');
|
||||
$("#name_div").addClass('displayNone');
|
||||
$("#renameCharButton").css("display", "");
|
||||
$('.open_alternate_greetings').data('chid', chid);
|
||||
|
||||
$("#form_create").attr("actiontype", "editcharacter");
|
||||
saveSettingsDebounced();
|
||||
@ -4479,6 +4494,7 @@ function select_rm_create() {
|
||||
$("#renameCharButton").css('display', 'none');
|
||||
$("#name_div").removeClass('displayNone');
|
||||
$("#name_div").addClass('displayBlock');
|
||||
$('.open_alternate_greetings').data('chid', undefined);
|
||||
updateFavButtonState(false);
|
||||
|
||||
$("#form_create").attr("actiontype", "createcharacter");
|
||||
@ -4517,6 +4533,7 @@ function callPopup(text, type, inputValue = '') {
|
||||
$("#dialogue_popup_ok").text("Ok");
|
||||
$("#dialogue_popup_cancel").css("display", "none");
|
||||
case "text":
|
||||
case "alternate_greeting":
|
||||
case "char_not_selected":
|
||||
$("#dialogue_popup_ok").text("Ok");
|
||||
$("#dialogue_popup_cancel").css("display", "none");
|
||||
@ -4628,13 +4645,18 @@ function showSwipeButtons() {
|
||||
if (
|
||||
chat[chat.length - 1].is_system ||
|
||||
!swipes ||
|
||||
$('.mes:last').attr('mesid') <= 0 ||
|
||||
$('.mes:last').attr('mesid') < 0 ||
|
||||
chat[chat.length - 1].is_user ||
|
||||
chat[chat.length - 1].extra?.image ||
|
||||
count_view_mes <= 1 ||
|
||||
count_view_mes < 1 ||
|
||||
(selected_group && is_group_generating)
|
||||
) { return; }
|
||||
|
||||
// swipe_id should be set if alternate greetings are added
|
||||
if (chat.length == 1 && chat[0].swipe_id === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
//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..)
|
||||
@ -4813,6 +4835,241 @@ function enlargeMessageImage() {
|
||||
callPopup(img.outerHTML, 'text');
|
||||
}
|
||||
|
||||
function updateAlternateGreetingsHintVisibility(root) {
|
||||
const numberOfGreetings = root.find('.alternate_greetings_list .alternate_greeting').length;
|
||||
$(root).find('.alternate_grettings_hint').toggle(numberOfGreetings == 0);
|
||||
}
|
||||
|
||||
function openAlternateGreetings() {
|
||||
const chid = $('.open_alternate_greetings').data('chid');
|
||||
|
||||
if (menu_type != 'create' && chid === undefined) {
|
||||
toastr.error('Does not have an Id for this character in editor menu.');
|
||||
return;
|
||||
} else {
|
||||
// If the character does not have alternate greetings, create an empty array
|
||||
if (Array.isArray(characters[chid].data.alternate_greetings) == false) {
|
||||
characters[chid].data.alternate_greetings = [];
|
||||
}
|
||||
}
|
||||
|
||||
const template = $('#alternate_greetings_template .alternate_grettings').clone();
|
||||
const getArray = () => menu_type == 'create' ? create_save_alternate_greetings : characters[chid].data.alternate_greetings;
|
||||
|
||||
for (let index = 0; index < getArray().length; index++) {
|
||||
addAlternateGreeting(template, getArray()[index], index, getArray);
|
||||
}
|
||||
|
||||
template.find('.add_alternate_greeting').on('click', function () {
|
||||
const array = getArray();
|
||||
const index = array.length;
|
||||
array.push(default_ch_mes);
|
||||
addAlternateGreeting(template, default_ch_mes, index, getArray);
|
||||
updateAlternateGreetingsHintVisibility(template);
|
||||
});
|
||||
|
||||
updateAlternateGreetingsHintVisibility(template);
|
||||
callPopup(template, 'alternate_greeting');
|
||||
}
|
||||
|
||||
function addAlternateGreeting(template, greeting, index, getArray) {
|
||||
const greetingBlock = $('#alternate_greeting_form_template .alternate_greeting').clone();
|
||||
greetingBlock.find('.alternate_greeting_text').on('input', async function() {
|
||||
const value = $(this).val();
|
||||
const array = getArray();
|
||||
array[index] = value;
|
||||
}).val(greeting);
|
||||
greetingBlock.find('.greeting_index').text(index + 1);
|
||||
greetingBlock.find('.delete_alternate_greeting').on('click', async function () {
|
||||
if (confirm('Are you sure you want to delete this alternate greeting?')) {
|
||||
const array = getArray();
|
||||
array.splice(index, 1);
|
||||
// We need to reopen the popup to update the index numbers
|
||||
openAlternateGreetings();
|
||||
}
|
||||
});
|
||||
template.find('.alternate_greetings_list').append(greetingBlock);
|
||||
}
|
||||
|
||||
async function createOrEditCharacter(e) {
|
||||
$("#rm_info_avatar").html("");
|
||||
let save_name = create_save_name;
|
||||
var formData = new FormData($("#form_create").get(0));
|
||||
formData.set('fav', fav_ch_checked);
|
||||
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)
|
||||
let url = "/createcharacter";
|
||||
|
||||
if (crop_data != undefined) {
|
||||
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
|
||||
}
|
||||
|
||||
formData.delete('alternate_greetings');
|
||||
for (const value of create_save_alternate_greetings) {
|
||||
formData.append('alternate_greetings', value);
|
||||
}
|
||||
|
||||
await jQuery.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
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").trigger('click'); //closes the advanced character editing popup
|
||||
const fields = [
|
||||
{ id: '#character_name_pole', callback: value => create_save_name = value },
|
||||
{ id: '#description_textarea', callback: value => create_save_description = value },
|
||||
{ id: '#creator_notes_textarea', callback: value => create_save_creator_notes = value },
|
||||
{ id: '#character_version_textarea', callback: value => create_save_character_version = value },
|
||||
{ id: '#post_history_instructions_textarea', callback: value => create_save_post_history_instructions = value },
|
||||
{ id: '#system_prompt_textarea', callback: value => create_save_system_prompt = value },
|
||||
{ id: '#tags_textarea', callback: value => create_save_tags = value },
|
||||
{ id: '#creator_textarea', callback: value => create_save_creator = value },
|
||||
{ id: '#personality_textarea', callback: value => create_save_personality = value },
|
||||
{ id: '#firstmessage_textarea', callback: value => create_save_first_message = value },
|
||||
{ id: '#talkativeness_slider', callback: value => create_save_talkativeness = value, defaultValue: talkativeness_default },
|
||||
{ id: '#scenario_pole', callback: value => create_save_scenario = value },
|
||||
{ id: '#mes_example_textarea', callback: value => create_save_mes_example = value },
|
||||
{ id: '#character_json_data', callback: () => { } },
|
||||
{ id: '#alternate_greetings_template', callback: value => create_save_alternate_greetings = value, defaultValue: [] },
|
||||
];
|
||||
|
||||
fields.forEach(field => {
|
||||
const fieldValue = field.defaultValue !== undefined ? field.defaultValue : '';
|
||||
$(field.id).val(fieldValue);
|
||||
field.callback && field.callback(fieldValue);
|
||||
});
|
||||
|
||||
$("#character_popup_text_h3").text("Create character");
|
||||
|
||||
create_save_avatar = "";
|
||||
|
||||
$("#create_button").removeAttr("disabled");
|
||||
$("#add_avatar_button").replaceWith(
|
||||
$("#add_avatar_button").val("").clone(true)
|
||||
);
|
||||
|
||||
$("#create_button").attr("value", "✅");
|
||||
let oldSelectedChar = null;
|
||||
if (this_chid != undefined && this_chid != "invalid-safety-id") {
|
||||
oldSelectedChar = characters[this_chid].avatar;
|
||||
}
|
||||
|
||||
console.log(`new avatar id: ${html}`);
|
||||
createTagMapFromList("#tagList", html);
|
||||
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(`char_create`, html, oldSelectedChar);
|
||||
|
||||
$("#rm_info_block").transition({ opacity: 1.0, duration: 2000 });
|
||||
crop_data = undefined;
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
$("#create_button").removeAttr("disabled");
|
||||
},
|
||||
});
|
||||
} else {
|
||||
$("#result_info").html("Name not entered");
|
||||
}
|
||||
} else {
|
||||
let url = '/editcharacter';
|
||||
|
||||
if (crop_data != undefined) {
|
||||
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
|
||||
}
|
||||
|
||||
formData.delete('alternate_greetings');
|
||||
const chid = $('.open_alternate_greetings').data('chid');
|
||||
if (Array.isArray(characters[chid]?.data?.alternate_greetings)) {
|
||||
for (const value of characters[chid].data.alternate_greetings) {
|
||||
formData.append('alternate_greetings', value);
|
||||
}
|
||||
}
|
||||
|
||||
await jQuery.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: formData,
|
||||
beforeSend: function () {
|
||||
$("#create_button").attr("disabled", true);
|
||||
$("#create_button").attr("value", "Save");
|
||||
},
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: async function (html) {
|
||||
if (chat.length === 1 && !selected_group) {
|
||||
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;
|
||||
chat[0]["extra"] = {};
|
||||
|
||||
const alternateGreetings = characters[this_chid]?.data?.alternate_greetings;
|
||||
|
||||
if (Array.isArray(alternateGreetings) && alternateGreetings.length > 0) {
|
||||
chat[0]['swipe_id'] = 0;
|
||||
chat[0]['swipes'] = [];
|
||||
chat[0]['swipes'][0] = chat[0]['mes'];
|
||||
|
||||
for (let i = 0; i < alternateGreetings.length; i++) {
|
||||
const alternateGreeting = alternateGreetings[i];
|
||||
chat[0]['swipes'].push(substituteParams(alternateGreeting));
|
||||
}
|
||||
}
|
||||
|
||||
add_mes_without_animation = true;
|
||||
//console.log('form create submission calling addOneMessage');
|
||||
addOneMessage(chat[0]);
|
||||
await eventSource.emit(event_types.MESSAGE_RECEIVED, (chat.length - 1));
|
||||
}
|
||||
}
|
||||
$("#create_button").removeAttr("disabled");
|
||||
await getCharacters();
|
||||
|
||||
$("#add_avatar_button").replaceWith(
|
||||
$("#add_avatar_button").val("").clone(true)
|
||||
);
|
||||
$("#create_button").attr("value", "Save");
|
||||
crop_data = undefined;
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
$("#create_button").removeAttr("disabled");
|
||||
$("#result_info").html("<font color=red>Error: no connection</font>");
|
||||
console.log('Error! Either a file with the same name already existed, or the image file provided was in an invalid format. Double check that the image is not a webp.');
|
||||
toastr.error('Something went wrong while saving the character, or the image file provided was in an invalid format. Double check that the image is not a webp.');
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window["SillyTavern"].getContext = function () {
|
||||
return {
|
||||
chat: chat,
|
||||
@ -4968,6 +5225,13 @@ const swipe_right = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chat.length == 1) {
|
||||
if (chat[0]['swipe_id'] !== undefined && chat[0]['swipe_id'] == chat[0]['swipes'].length - 1) {
|
||||
toastr.info('Add more alternative greetings to swipe through', 'That\'s all for now');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const swipe_duration = 200;
|
||||
const swipe_range = 700;
|
||||
//console.log(swipe_range);
|
||||
@ -5330,7 +5594,7 @@ $(document).ready(function () {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this_chid !== $(this).attr("chid")) {
|
||||
if (selected_group || this_chid !== $(this).attr("chid")) {
|
||||
//if clicked on a different character from what was currently selected
|
||||
if (!is_send_press) {
|
||||
cancelTtsPlay();
|
||||
@ -5605,6 +5869,9 @@ $(document).ready(function () {
|
||||
if (popup_type === "world_imported") {
|
||||
selectImportedWorldInfo();
|
||||
}
|
||||
if (popup_type == "alternate_greeting" && menu_type !== "create") {
|
||||
createOrEditCharacter();
|
||||
}
|
||||
if (popup_type === "del_world" && world_info) {
|
||||
deleteWorldInfo(world_info);
|
||||
}
|
||||
@ -5654,7 +5921,6 @@ $(document).ready(function () {
|
||||
|
||||
dialogueResolve = null;
|
||||
}
|
||||
|
||||
});
|
||||
$("#dialogue_popup_cancel").click(function (e) {
|
||||
$("#shadow_popup").transition({
|
||||
@ -5686,155 +5952,7 @@ $(document).ready(function () {
|
||||
read_avatar_load(this);
|
||||
});
|
||||
|
||||
$("#form_create").submit(function (e) {
|
||||
$("#rm_info_avatar").html("");
|
||||
let save_name = create_save_name;
|
||||
var formData = new FormData($("#form_create").get(0));
|
||||
formData.set('fav', fav_ch_checked);
|
||||
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)
|
||||
let url = "/createcharacter";
|
||||
|
||||
if (crop_data != undefined) {
|
||||
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
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").trigger('click'); //closes the advanced character editing popup
|
||||
const fields = [
|
||||
{ id: '#character_name_pole', callback: value => create_save_name = value },
|
||||
{ id: '#description_textarea', callback: value => create_save_description = value },
|
||||
{ id: '#creator_notes_textarea', callback: value => create_save_creator_notes = value },
|
||||
{ id: '#character_version_textarea', callback: value => create_save_character_version = value },
|
||||
{ id: '#post_history_instructions_textarea', callback: value => create_save_post_history_instructions = value },
|
||||
{ id: '#system_prompt_textarea', callback: value => create_save_system_prompt = value },
|
||||
{ id: '#tags_textarea', callback: value => create_save_tags = value },
|
||||
{ id: '#creator_textarea', callback: value => create_save_creator = value },
|
||||
{ id: '#personality_textarea', callback: value => create_save_personality = value },
|
||||
{ id: '#firstmessage_textarea', callback: value => create_save_first_message = value },
|
||||
{ id: '#talkativeness_slider', callback: value => create_save_talkativeness = value, defaultValue: talkativeness_default },
|
||||
{ id: '#scenario_pole', callback: value => create_save_scenario = value },
|
||||
{ id: '#mes_example_textarea', callback: value => create_save_mes_example = value },
|
||||
{ id: '#character_json_data', callback: () => { } },
|
||||
];
|
||||
|
||||
fields.forEach(field => {
|
||||
const fieldValue = field.defaultValue !== undefined ? field.defaultValue : '';
|
||||
$(field.id).val(fieldValue);
|
||||
field.callback && field.callback(fieldValue);
|
||||
});
|
||||
|
||||
$("#character_popup_text_h3").text("Create character");
|
||||
|
||||
create_save_avatar = "";
|
||||
|
||||
$("#create_button").removeAttr("disabled");
|
||||
$("#add_avatar_button").replaceWith(
|
||||
$("#add_avatar_button").val("").clone(true)
|
||||
);
|
||||
|
||||
$("#create_button").attr("value", "✅");
|
||||
let oldSelectedChar = null;
|
||||
if (this_chid != undefined && this_chid != "invalid-safety-id") {
|
||||
oldSelectedChar = characters[this_chid].avatar;
|
||||
}
|
||||
|
||||
console.log(`new avatar id: ${html}`);
|
||||
createTagMapFromList("#tagList", html);
|
||||
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(`char_create`, html, oldSelectedChar);
|
||||
|
||||
$("#rm_info_block").transition({ opacity: 1.0, duration: 2000 });
|
||||
crop_data = undefined;
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
$("#create_button").removeAttr("disabled");
|
||||
},
|
||||
});
|
||||
} else {
|
||||
$("#result_info").html("Name not entered");
|
||||
}
|
||||
} else {
|
||||
let url = '/editcharacter';
|
||||
|
||||
if (crop_data != undefined) {
|
||||
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: formData,
|
||||
beforeSend: function () {
|
||||
$("#create_button").attr("disabled", true);
|
||||
$("#create_button").attr("value", "Save");
|
||||
},
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: async function (html) {
|
||||
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]);
|
||||
await eventSource.emit(event_types.MESSAGE_RECEIVED, (chat.length - 1));
|
||||
}
|
||||
}
|
||||
$("#create_button").removeAttr("disabled");
|
||||
await getCharacters();
|
||||
|
||||
$("#add_avatar_button").replaceWith(
|
||||
$("#add_avatar_button").val("").clone(true)
|
||||
);
|
||||
$("#create_button").attr("value", "Save");
|
||||
crop_data = undefined;
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
$("#create_button").removeAttr("disabled");
|
||||
$("#result_info").html("<font color=red>Error: no connection</font>");
|
||||
console.log('Error! Either a file with the same name already existed, or the image file provided was in an invalid format. Double check that the image is not a webp.');
|
||||
toastr.error('Something went wrong while saving the character, or the image file provided was in an invalid format. Double check that the image is not a webp.');
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
$("#form_create").submit(createOrEditCharacter);
|
||||
|
||||
$("#delete_button").click(function () {
|
||||
popup_type = "del_ch";
|
||||
@ -6918,6 +7036,7 @@ $(document).ready(function () {
|
||||
$(document).on('click', '#CloseAllWIEntries', function () {
|
||||
$("#world_popup_entries_list").children().find('.up').click()
|
||||
});
|
||||
$(document).on('click', '.open_alternate_greetings', openAlternateGreetings);
|
||||
|
||||
$(document).keyup(function (e) {
|
||||
if (e.key === "Escape") {
|
||||
|
Reference in New Issue
Block a user