Merge pull request #2834 from SillyTavern/replace-ajax
Replace ajax with fetch in character create/edit
This commit is contained in:
commit
7c383e3218
267
public/script.js
267
public/script.js
|
@ -7892,13 +7892,19 @@ async function createOrEditCharacter(e) {
|
||||||
formData.set('avatar', convertedFile);
|
formData.set('avatar', convertedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('#form_create').attr('actiontype') == 'createcharacter') {
|
const headers = getRequestHeaders();
|
||||||
if (String($('#character_name_pole').val()).length > 0) {
|
delete headers['Content-Type'];
|
||||||
if (is_group_generating || is_send_press) {
|
|
||||||
toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted');
|
|
||||||
throw new Error('Cannot import character while generating');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ($('#form_create').attr('actiontype') == 'createcharacter') {
|
||||||
|
if (String($('#character_name_pole').val()).length === 0) {
|
||||||
|
toastr.error('Name is required');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (is_group_generating || is_send_press) {
|
||||||
|
toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
//if the character name text area isn't empty (only posible when creating a new character)
|
//if the character name text area isn't empty (only posible when creating a new character)
|
||||||
let url = '/api/characters/create';
|
let url = '/api/characters/create';
|
||||||
|
|
||||||
|
@ -7913,142 +7919,133 @@ async function createOrEditCharacter(e) {
|
||||||
|
|
||||||
formData.append('extensions', JSON.stringify(create_save.extensions));
|
formData.append('extensions', JSON.stringify(create_save.extensions));
|
||||||
|
|
||||||
await jQuery.ajax({
|
const fetchResult = await fetch(url, {
|
||||||
type: 'POST',
|
method: 'POST',
|
||||||
url: url,
|
headers: headers,
|
||||||
data: formData,
|
body: formData,
|
||||||
beforeSend: function () {
|
cache: 'no-cache',
|
||||||
$('#create_button').attr('disabled', String(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: '#depth_prompt_prompt', callback: value => create_save.depth_prompt_prompt = value },
|
|
||||||
{ id: '#depth_prompt_depth', callback: value => create_save.depth_prompt_depth = value, defaultValue: depth_prompt_depth_default },
|
|
||||||
{ id: '#depth_prompt_role', callback: value => create_save.depth_prompt_role = value, defaultValue: depth_prompt_role_default },
|
|
||||||
{ 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: [] },
|
|
||||||
{ id: '#character_world', callback: value => create_save.world = value },
|
|
||||||
{ id: '#_character_extensions_fake', callback: value => create_save.extensions = {} },
|
|
||||||
];
|
|
||||||
|
|
||||||
fields.forEach(field => {
|
|
||||||
const fieldValue = field.defaultValue !== undefined ? field.defaultValue : '';
|
|
||||||
$(field.id).val(fieldValue);
|
|
||||||
field.callback && field.callback(fieldValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#character_popup-button-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) {
|
|
||||||
oldSelectedChar = characters[this_chid].avatar;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`new avatar id: ${html}`);
|
|
||||||
createTagMapFromList('#tagList', html);
|
|
||||||
await getCharacters();
|
|
||||||
|
|
||||||
select_rm_info('char_create', html, oldSelectedChar);
|
|
||||||
|
|
||||||
crop_data = undefined;
|
|
||||||
},
|
|
||||||
error: function (jqXHR, exception) {
|
|
||||||
$('#create_button').removeAttr('disabled');
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
toastr.error('Name is required');
|
if (!fetchResult.ok) {
|
||||||
|
throw new Error('Fetch result is not ok');
|
||||||
|
}
|
||||||
|
|
||||||
|
const avatarId = await fetchResult.text();
|
||||||
|
|
||||||
|
$('#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: '#depth_prompt_prompt', callback: value => create_save.depth_prompt_prompt = value },
|
||||||
|
{ id: '#depth_prompt_depth', callback: value => create_save.depth_prompt_depth = value, defaultValue: depth_prompt_depth_default },
|
||||||
|
{ id: '#depth_prompt_role', callback: value => create_save.depth_prompt_role = value, defaultValue: depth_prompt_role_default },
|
||||||
|
{ 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: [] },
|
||||||
|
{ id: '#character_world', callback: value => create_save.world = value },
|
||||||
|
{ id: '#_character_extensions_fake', callback: value => create_save.extensions = {} },
|
||||||
|
];
|
||||||
|
|
||||||
|
fields.forEach(field => {
|
||||||
|
const fieldValue = field.defaultValue !== undefined ? field.defaultValue : '';
|
||||||
|
$(field.id).val(fieldValue);
|
||||||
|
field.callback && field.callback(fieldValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#character_popup-button-h3').text('Create character');
|
||||||
|
|
||||||
|
create_save.avatar = '';
|
||||||
|
|
||||||
|
$('#add_avatar_button').replaceWith(
|
||||||
|
$('#add_avatar_button').val('').clone(true),
|
||||||
|
);
|
||||||
|
|
||||||
|
let oldSelectedChar = null;
|
||||||
|
if (this_chid !== undefined) {
|
||||||
|
oldSelectedChar = characters[this_chid].avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`new avatar id: ${avatarId}`);
|
||||||
|
createTagMapFromList('#tagList', avatarId);
|
||||||
|
await getCharacters();
|
||||||
|
|
||||||
|
select_rm_info('char_create', avatarId, oldSelectedChar);
|
||||||
|
|
||||||
|
crop_data = undefined;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating character', error);
|
||||||
|
toastr.error('Failed to create character');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let url = '/api/characters/edit';
|
try {
|
||||||
|
let url = '/api/characters/edit';
|
||||||
|
|
||||||
if (crop_data != undefined) {
|
if (crop_data != undefined) {
|
||||||
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
|
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
|
||||||
}
|
|
||||||
|
|
||||||
formData.delete('alternate_greetings');
|
|
||||||
const chid = $('.open_alternate_greetings').data('chid');
|
|
||||||
if (chid && Array.isArray(characters[chid]?.data?.alternate_greetings)) {
|
|
||||||
for (const value of characters[chid].data.alternate_greetings) {
|
|
||||||
formData.append('alternate_greetings', value);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await jQuery.ajax({
|
formData.delete('alternate_greetings');
|
||||||
type: 'POST',
|
const chid = $('.open_alternate_greetings').data('chid');
|
||||||
url: url,
|
if (chid && Array.isArray(characters[chid]?.data?.alternate_greetings)) {
|
||||||
data: formData,
|
for (const value of characters[chid].data.alternate_greetings) {
|
||||||
beforeSend: function () {
|
formData.append('alternate_greetings', value);
|
||||||
$('#create_button').attr('disabled', String(true));
|
|
||||||
$('#create_button').attr('value', 'Save');
|
|
||||||
},
|
|
||||||
cache: false,
|
|
||||||
contentType: false,
|
|
||||||
processData: false,
|
|
||||||
success: async function (html) {
|
|
||||||
$('#create_button').removeAttr('disabled');
|
|
||||||
|
|
||||||
await getOneCharacter(formData.get('avatar_url'));
|
|
||||||
favsToHotswap(); // Update fav state
|
|
||||||
|
|
||||||
$('#add_avatar_button').replaceWith(
|
|
||||||
$('#add_avatar_button').val('').clone(true),
|
|
||||||
);
|
|
||||||
$('#create_button').attr('value', 'Save');
|
|
||||||
crop_data = undefined;
|
|
||||||
eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } });
|
|
||||||
|
|
||||||
// Recreate the chat if it hasn't been used at least once (i.e. with continue).
|
|
||||||
const message = getFirstMessage();
|
|
||||||
const shouldRegenerateMessage =
|
|
||||||
!isNewChat &&
|
|
||||||
message.mes &&
|
|
||||||
!selected_group &&
|
|
||||||
!chat_metadata['tainted'] &&
|
|
||||||
(chat.length === 0 || (chat.length === 1 && !chat[0].is_user && !chat[0].is_system));
|
|
||||||
|
|
||||||
if (shouldRegenerateMessage) {
|
|
||||||
chat.splice(0, chat.length, message);
|
|
||||||
const messageId = (chat.length - 1);
|
|
||||||
await eventSource.emit(event_types.MESSAGE_RECEIVED, messageId);
|
|
||||||
await clearChat();
|
|
||||||
await printMessages();
|
|
||||||
await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, messageId);
|
|
||||||
await saveChatConditional();
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
error: function (jqXHR, exception) {
|
|
||||||
$('#create_button').removeAttr('disabled');
|
const fetchResult = await fetch(url, {
|
||||||
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.');
|
method: 'POST',
|
||||||
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.');
|
headers: headers,
|
||||||
},
|
body: formData,
|
||||||
});
|
cache: 'no-cache',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!fetchResult.ok) {
|
||||||
|
throw new Error('Fetch result is not ok');
|
||||||
|
}
|
||||||
|
|
||||||
|
await getOneCharacter(formData.get('avatar_url'));
|
||||||
|
favsToHotswap(); // Update fav state
|
||||||
|
|
||||||
|
$('#add_avatar_button').replaceWith(
|
||||||
|
$('#add_avatar_button').val('').clone(true),
|
||||||
|
);
|
||||||
|
$('#create_button').attr('value', 'Save');
|
||||||
|
crop_data = undefined;
|
||||||
|
await eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } });
|
||||||
|
|
||||||
|
// Recreate the chat if it hasn't been used at least once (i.e. with continue).
|
||||||
|
const message = getFirstMessage();
|
||||||
|
const shouldRegenerateMessage =
|
||||||
|
!isNewChat &&
|
||||||
|
message.mes &&
|
||||||
|
!selected_group &&
|
||||||
|
!chat_metadata['tainted'] &&
|
||||||
|
(chat.length === 0 || (chat.length === 1 && !chat[0].is_user && !chat[0].is_system));
|
||||||
|
|
||||||
|
if (shouldRegenerateMessage) {
|
||||||
|
chat.splice(0, chat.length, message);
|
||||||
|
const messageId = (chat.length - 1);
|
||||||
|
await eventSource.emit(event_types.MESSAGE_RECEIVED, messageId);
|
||||||
|
await clearChat();
|
||||||
|
await printMessages();
|
||||||
|
await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, messageId);
|
||||||
|
await saveChatConditional();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
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.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue