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:
		| @@ -2459,13 +2459,17 @@ | |||||||
|                             placeholder="Describe your character's physical and mental traits here." |                             placeholder="Describe your character's physical and mental traits here." | ||||||
|                             class="margin-bot-10px" name="description" placeholder=""></textarea> |                             class="margin-bot-10px" name="description" placeholder=""></textarea> | ||||||
|  |  | ||||||
|                         <div id="first_message_div" class="margin-bot-10px"> |                         <div id="first_message_div" class="margin-bot-10px title_restorable"> | ||||||
|  |                             <span> | ||||||
|                                 <span data-i18n="First message">First message</span> |                                 <span data-i18n="First message">First message</span> | ||||||
|                                 <a href="https://docs.sillytavern.app/usage/guidebook/#first-message" class="notes-link" |                                 <a href="https://docs.sillytavern.app/usage/guidebook/#first-message" class="notes-link" | ||||||
|                                     target="_blank"> |                                     target="_blank"> | ||||||
|                                     <span class="note-link-span">?</span> |                                     <span class="note-link-span">?</span> | ||||||
|                                 </a> |                                 </a> | ||||||
|  |                             </span> | ||||||
|  |                             <div class="menu_button open_alternate_greetings" title="Click to set additional greeting messages"> | ||||||
|  |                                 <i class="fa-solid fa-comment-dots"></i> | ||||||
|  |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|                         <textarea id="firstmessage_textarea" |                         <textarea id="firstmessage_textarea" | ||||||
|                             placeholder="This will be the first message from the character that starts every chat." |                             placeholder="This will be the first message from the character that starts every chat." | ||||||
| @@ -3174,6 +3178,36 @@ | |||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|  |     <div id="alternate_greetings_template" class="template_element"> | ||||||
|  |         <div class="alternate_grettings flexFlowColumn flex-container"> | ||||||
|  |             <div class="title_restorable"> | ||||||
|  |                 <h3><span data-i18n="Alternate Greetings">Alternate Greetings</span></h3> | ||||||
|  |                 <div title="Add" class="menu_button fa-solid fa-plus add_alternate_greeting"></div> | ||||||
|  |             </div> | ||||||
|  |             <div class="justifyLeft" data-i18n="Alternate Greetings Subtitle"> | ||||||
|  |                 These will be displayed as swipes on the first message when starting a new chat. | ||||||
|  |                 Group members can select one of them to initiate the conversation. | ||||||
|  |             </div> | ||||||
|  |             <hr> | ||||||
|  |             <div class="alternate_greetings_list flexFlowColumn flex-container wide100p"> | ||||||
|  |                 <strong class="alternate_grettings_hint margin-bot-10px" data-i18n="Alternate Greetings Hint"> | ||||||
|  |                     Click the <i class="fa-solid fa-plus"></i> button to get started! | ||||||
|  |                 </strong> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div id="alternate_greeting_form_template" class="template_element"> | ||||||
|  |         <div class="alternate_greeting"> | ||||||
|  |             <div class="title_restorable"> | ||||||
|  |                 <strong>Alternate Greeting #<span class="greeting_index"></span></strong> | ||||||
|  |                 <div class="menu_button fa-solid fa-trash-alt delete_alternate_greeting"></div> | ||||||
|  |             </div> | ||||||
|  |             <textarea name="alternate_greetings" placeholder="(This will be the first message from the character that starts every chat)" | ||||||
|  |                 class="text_pole textarea_compact alternate_greeting_text" maxlength="20000" value="" autocomplete="off" rows="4"></textarea> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|     <!-- chat and input bar --> |     <!-- chat and input bar --> | ||||||
|     <div id="typing_indicator_template" class="template_element"> |     <div id="typing_indicator_template" class="template_element"> | ||||||
|         <div class="typing_indicator"><span class="typing_indicator_name">CHAR</span> is typing</div> |         <div class="typing_indicator"><span class="typing_indicator_name">CHAR</span> is typing</div> | ||||||
| @@ -3221,7 +3255,7 @@ | |||||||
|                 <span data-i18n="Convert to group">Convert to group</span> |                 <span data-i18n="Convert to group">Convert to group</span> | ||||||
|             </a> |             </a> | ||||||
|             <a id="option_start_new_chat"> |             <a id="option_start_new_chat"> | ||||||
|                 <i class="fa-lg fa-solid fa-comment-dots"></i> |                 <i class="fa-lg fa-solid fa-comments"></i> | ||||||
|                 <span data-i18n="Start new chat">Start new chat</span> |                 <span data-i18n="Start new chat">Start new chat</span> | ||||||
|             </a> |             </a> | ||||||
|             <a id="option_select_chat"> |             <a id="option_select_chat"> | ||||||
|   | |||||||
							
								
								
									
										427
									
								
								public/script.js
									
									
									
									
									
								
							
							
						
						
									
										427
									
								
								public/script.js
									
									
									
									
									
								
							| @@ -563,6 +563,7 @@ let create_save_avatar = ""; | |||||||
| let create_save_scenario = ""; | let create_save_scenario = ""; | ||||||
| let create_save_mes_example = ""; | let create_save_mes_example = ""; | ||||||
| let create_save_talkativeness = talkativeness_default; | let create_save_talkativeness = talkativeness_default; | ||||||
|  | let create_save_alternate_greetings = []; | ||||||
|  |  | ||||||
| //animation right menu | //animation right menu | ||||||
| let animation_duration = 250; | let animation_duration = 250; | ||||||
| @@ -3647,13 +3648,26 @@ async function getChatResult() { | |||||||
|     name2 = characters[this_chid].name; |     name2 = characters[this_chid].name; | ||||||
|     if (chat.length === 0) { |     if (chat.length === 0) { | ||||||
|         const firstMes = characters[this_chid].first_mes || default_ch_mes; |         const firstMes = characters[this_chid].first_mes || default_ch_mes; | ||||||
|  |         const alternateGreetings = characters[this_chid]?.data?.alternate_greetings; | ||||||
|  |  | ||||||
|         chat[0] = { |         chat[0] = { | ||||||
|             name: name2, |             name: name2, | ||||||
|             is_user: false, |             is_user: false, | ||||||
|             is_name: true, |             is_name: true, | ||||||
|             send_date: humanizedDateTime(), |             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(); |     printMessages(); | ||||||
|     select_selected_character(this_chid); |     select_selected_character(this_chid); | ||||||
| @@ -4431,6 +4445,7 @@ export function select_selected_character(chid) { | |||||||
|     $("#name_div").removeClass('displayBlock'); |     $("#name_div").removeClass('displayBlock'); | ||||||
|     $("#name_div").addClass('displayNone'); |     $("#name_div").addClass('displayNone'); | ||||||
|     $("#renameCharButton").css("display", ""); |     $("#renameCharButton").css("display", ""); | ||||||
|  |     $('.open_alternate_greetings').data('chid', chid); | ||||||
|  |  | ||||||
|     $("#form_create").attr("actiontype", "editcharacter"); |     $("#form_create").attr("actiontype", "editcharacter"); | ||||||
|     saveSettingsDebounced(); |     saveSettingsDebounced(); | ||||||
| @@ -4479,6 +4494,7 @@ function select_rm_create() { | |||||||
|     $("#renameCharButton").css('display', 'none'); |     $("#renameCharButton").css('display', 'none'); | ||||||
|     $("#name_div").removeClass('displayNone'); |     $("#name_div").removeClass('displayNone'); | ||||||
|     $("#name_div").addClass('displayBlock'); |     $("#name_div").addClass('displayBlock'); | ||||||
|  |     $('.open_alternate_greetings').data('chid', undefined); | ||||||
|     updateFavButtonState(false); |     updateFavButtonState(false); | ||||||
|  |  | ||||||
|     $("#form_create").attr("actiontype", "createcharacter"); |     $("#form_create").attr("actiontype", "createcharacter"); | ||||||
| @@ -4517,6 +4533,7 @@ function callPopup(text, type, inputValue = '') { | |||||||
|             $("#dialogue_popup_ok").text("Ok"); |             $("#dialogue_popup_ok").text("Ok"); | ||||||
|             $("#dialogue_popup_cancel").css("display", "none"); |             $("#dialogue_popup_cancel").css("display", "none"); | ||||||
|         case "text": |         case "text": | ||||||
|  |         case "alternate_greeting": | ||||||
|         case "char_not_selected": |         case "char_not_selected": | ||||||
|             $("#dialogue_popup_ok").text("Ok"); |             $("#dialogue_popup_ok").text("Ok"); | ||||||
|             $("#dialogue_popup_cancel").css("display", "none"); |             $("#dialogue_popup_cancel").css("display", "none"); | ||||||
| @@ -4628,13 +4645,18 @@ function showSwipeButtons() { | |||||||
|     if ( |     if ( | ||||||
|         chat[chat.length - 1].is_system || |         chat[chat.length - 1].is_system || | ||||||
|         !swipes || |         !swipes || | ||||||
|         $('.mes:last').attr('mesid') <= 0 || |         $('.mes:last').attr('mesid') < 0 || | ||||||
|         chat[chat.length - 1].is_user || |         chat[chat.length - 1].is_user || | ||||||
|         chat[chat.length - 1].extra?.image || |         chat[chat.length - 1].extra?.image || | ||||||
|         count_view_mes <= 1 || |         count_view_mes < 1 || | ||||||
|         (selected_group && is_group_generating) |         (selected_group && is_group_generating) | ||||||
|     ) { return; } |     ) { 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 |     //had to add this to make the swipe counter work | ||||||
|     //(copied from the onclick functions for swipe buttons.. |     //(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..) |     //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'); |     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 () { | window["SillyTavern"].getContext = function () { | ||||||
|     return { |     return { | ||||||
|         chat: chat, |         chat: chat, | ||||||
| @@ -4968,6 +5225,13 @@ const swipe_right = () => { | |||||||
|         return; |         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_duration = 200; | ||||||
|     const swipe_range = 700; |     const swipe_range = 700; | ||||||
|     //console.log(swipe_range); |     //console.log(swipe_range); | ||||||
| @@ -5330,7 +5594,7 @@ $(document).ready(function () { | |||||||
|             return; |             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 clicked on a different character from what was currently selected | ||||||
|             if (!is_send_press) { |             if (!is_send_press) { | ||||||
|                 cancelTtsPlay(); |                 cancelTtsPlay(); | ||||||
| @@ -5605,6 +5869,9 @@ $(document).ready(function () { | |||||||
|         if (popup_type === "world_imported") { |         if (popup_type === "world_imported") { | ||||||
|             selectImportedWorldInfo(); |             selectImportedWorldInfo(); | ||||||
|         } |         } | ||||||
|  |         if (popup_type == "alternate_greeting" && menu_type !== "create") { | ||||||
|  |             createOrEditCharacter(); | ||||||
|  |         } | ||||||
|         if (popup_type === "del_world" && world_info) { |         if (popup_type === "del_world" && world_info) { | ||||||
|             deleteWorldInfo(world_info); |             deleteWorldInfo(world_info); | ||||||
|         } |         } | ||||||
| @@ -5654,7 +5921,6 @@ $(document).ready(function () { | |||||||
|  |  | ||||||
|             dialogueResolve = null; |             dialogueResolve = null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     }); |     }); | ||||||
|     $("#dialogue_popup_cancel").click(function (e) { |     $("#dialogue_popup_cancel").click(function (e) { | ||||||
|         $("#shadow_popup").transition({ |         $("#shadow_popup").transition({ | ||||||
| @@ -5686,155 +5952,7 @@ $(document).ready(function () { | |||||||
|         read_avatar_load(this); |         read_avatar_load(this); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     $("#form_create").submit(function (e) { |     $("#form_create").submit(createOrEditCharacter); | ||||||
|         $("#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.'); |  | ||||||
|                 }, |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     $("#delete_button").click(function () { |     $("#delete_button").click(function () { | ||||||
|         popup_type = "del_ch"; |         popup_type = "del_ch"; | ||||||
| @@ -6918,6 +7036,7 @@ $(document).ready(function () { | |||||||
|     $(document).on('click', '#CloseAllWIEntries', function () { |     $(document).on('click', '#CloseAllWIEntries', function () { | ||||||
|         $("#world_popup_entries_list").children().find('.up').click() |         $("#world_popup_entries_list").children().find('.up').click() | ||||||
|     }); |     }); | ||||||
|  |     $(document).on('click', '.open_alternate_greetings', openAlternateGreetings); | ||||||
|  |  | ||||||
|     $(document).keyup(function (e) { |     $(document).keyup(function (e) { | ||||||
|         if (e.key === "Escape") { |         if (e.key === "Escape") { | ||||||
|   | |||||||
| @@ -179,6 +179,14 @@ export async function getGroupChat(groupId) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function getFirstCharacterMessage(character) { | function getFirstCharacterMessage(character) { | ||||||
|  |     let messageText = character.first_mes; | ||||||
|  |  | ||||||
|  |     // if there are alternate greetings, pick one at random | ||||||
|  |     if (Array.isArray(character.data?.alternate_greetings)) { | ||||||
|  |         const messageTexts = [character.first_mes, ...character.data.alternate_greetings].filter(x => x); | ||||||
|  |         messageText = messageTexts[Math.floor(Math.random() * messageTexts.length)]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const mes = {}; |     const mes = {}; | ||||||
|     mes["is_user"] = false; |     mes["is_user"] = false; | ||||||
|     mes["is_system"] = false; |     mes["is_system"] = false; | ||||||
| @@ -187,8 +195,8 @@ function getFirstCharacterMessage(character) { | |||||||
|     mes["send_date"] = humanizedDateTime(); |     mes["send_date"] = humanizedDateTime(); | ||||||
|     mes["original_avatar"] = character.avatar; |     mes["original_avatar"] = character.avatar; | ||||||
|     mes["extra"] = { "gen_id": Date.now() * Math.random() * 1000000 }; |     mes["extra"] = { "gen_id": Date.now() * Math.random() * 1000000 }; | ||||||
|     mes["mes"] = character.first_mes |     mes["mes"] = messageText | ||||||
|         ? substituteParams(character.first_mes.trim(), name1, character.name) |         ? substituteParams(messageText.trim(), name1, character.name) | ||||||
|         : default_ch_mes; |         : default_ch_mes; | ||||||
|     mes["force_avatar"] = |     mes["force_avatar"] = | ||||||
|         character.avatar != "none" |         character.avatar != "none" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user