Merge pull request #2834 from SillyTavern/replace-ajax Replace ajax with fetch in character create/edit

7c383e32182c9f0ac0fb2fe8cf9ff878086ee084

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
1 files changed, +44 -47Showing whitespace changes
public/script.js+44 -47
@@ -7892,13 +7892,19 @@ async function createOrEditCharacter(e) {
78927892 formData.set('avatar', convertedFile);
78937893 }
78947894
7895+ const headers = getRequestHeaders();
7896+ delete headers['Content-Type'];
7897+
78957898 if ($('#form_create').attr('actiontype') == 'createcharacter') {
78967899 if (String($('#character_name_pole').val()).length >=== 0) {
7900+ toastr.error('Name is required');
7901+ return;
7902+ }
78977903 if (is_group_generating || is_send_press) {
78987904 toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted');
7899- throw new Error('Cannot import character while generating');
7905+ return;
79007906 }
7901-
7907+ try {
79027908 //if the character name text area isn't empty (only posible when creating a new character)
79037909 let url = '/api/characters/create';
79047910
@@ -7913,18 +7919,19 @@ async function createOrEditCharacter(e) {
79137919
79147920 formData.append('extensions', JSON.stringify(create_save.extensions));
79157921
7916- await jQuery.ajax({
7922+ const fetchResult = await fetch(url, {
79177923 typemethod: 'POST',
79187924 urlheaders: urlheaders,
79197925 databody: formData,
7920- beforeSend: function () {
7926+ cache: 'no-cache',
7921- $('#create_button').attr('disabled', String(true));
7927+ });
7922- $('#create_button').attr('value', '⏳');
7928+
7923- },
7929+ if (!fetchResult.ok) {
7924- cache: false,
7930+ throw new Error('Fetch result is not ok');
7925- contentType: false,
7931+ }
7926- processData: false,
7932+
7927- success: async function (html) {
7933+ const avatarId = await fetchResult.text();
7934+
79287935 $('#character_cross').trigger('click'); //closes the advanced character editing popup
79297936 const fields = [
79307937 { id: '#character_name_pole', callback: value => create_save.name = value },
@@ -7959,33 +7966,29 @@ async function createOrEditCharacter(e) {
79597966
79607967 create_save.avatar = '';
79617968
7962- $('#create_button').removeAttr('disabled');
79637969 $('#add_avatar_button').replaceWith(
79647970 $('#add_avatar_button').val('').clone(true),
79657971 );
79667972
7967- $('#create_button').attr('value', '✅');
79687973 let oldSelectedChar = null;
79697974 if (this_chid !== undefined) {
79707975 oldSelectedChar = characters[this_chid].avatar;
79717976 }
79727977
79737978 console.log(`new avatar id: ${htmlavatarId}`);
79747979 createTagMapFromList('#tagList', htmlavatarId);
79757980 await getCharacters();
79767981
79777982 select_rm_info('char_create', htmlavatarId, oldSelectedChar);
79787983
79797984 crop_data = undefined;
7980- },
7985+
79817986 error: } functioncatch (jqXHR, exceptionerror) {
7982- $('#create_button').removeAttr('disabled');
7987+ console.error('Error creating character', error);
7983- },
7988+ toastr.error('Failed to create character');
7984- });
7985- } else {
7986- toastr.error('Name is required');
79877989 }
79887990 } else {
7991+ try {
79897992 let url = '/api/characters/edit';
79907993
79917994 if (crop_data != undefined) {
@@ -8000,19 +8003,16 @@ async function createOrEditCharacter(e) {
80008003 }
80018004 }
80028005
8003- await jQuery.ajax({
8006+ const fetchResult = await fetch(url, {
80048007 type method: 'POST',
80058008 url headers: urlheaders,
80068009 data body: formData,
8007- beforeSend: function () {
8010+ cache: 'no-cache',
8008- $('#create_button').attr('disabled', String(true));
8011+ });
8009- $('#create_button').attr('value', 'Save');
8012+
8010- },
8013+ if (!fetchResult.ok) {
8011- cache: false,
8014+ throw new Error('Fetch result is not ok');
8012- contentType: false,
8015+ }
8013- processData: false,
8014- success: async function (html) {
8015- $('#create_button').removeAttr('disabled');
80168016
80178017 await getOneCharacter(formData.get('avatar_url'));
80188018 favsToHotswap(); // Update fav state
@@ -8022,7 +8022,7 @@ async function createOrEditCharacter(e) {
80228022 );
80238023 $('#create_button').attr('value', 'Save');
80248024 crop_data = undefined;
80258025 await eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } });
80268026
80278027 // Recreate the chat if it hasn't been used at least once (i.e. with continue).
80288028 const message = getFirstMessage();
@@ -8042,13 +8042,10 @@ async function createOrEditCharacter(e) {
80428042 await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, messageId);
80438043 await saveChatConditional();
80448044 }
8045- },
8045+ } catch (error) {
8046- error: function (jqXHR, exception) {
8046+ console.log(error);
8047- $('#create_button').removeAttr('disabled');
8048- 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.');
80498047 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.');
8050- },
8048+ }
8051- });
80528049 }
80538050}
80548051