Force persona creation on avatar uploads. Don't show cropper for images if never resize is enabled.

This commit is contained in:
Cohee 2023-11-12 15:47:52 +02:00
parent adc533070d
commit 822d9d72ea
2 changed files with 66 additions and 37 deletions

View File

@ -143,6 +143,7 @@ import {
escapeRegex,
resetScrollHeight,
onlyUnique,
getBase64Async,
} from "./scripts/utils.js";
import { ModuleWorkerWrapper, doDailyExtensionUpdatesCheck, extension_settings, getContext, loadExtensionSettings, processExtensionHelpers, registerExtensionHelper, renderExtensionTemplate, runGenerationInterceptors, saveMetadataDebounced } from "./scripts/extensions.js";
@ -184,7 +185,7 @@ import {
} from "./scripts/instruct-mode.js";
import { applyLocale } from "./scripts/i18n.js";
import { getFriendlyTokenizerName, getTokenCount, getTokenizerModel, initTokenizers, saveTokenCache } from "./scripts/tokenizers.js";
import { initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
import { createPersona, initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
import { getBackgrounds, initBackgrounds } from "./scripts/backgrounds.js";
import { hideLoader, showLoader } from "./scripts/loader.js";
import { CharacterContextMenu, BulkEditOverlay } from "./scripts/BulkEditOverlay.js";
@ -4785,22 +4786,21 @@ async function read_avatar_load(input) {
create_save.avatar = input.files;
}
const e = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = resolve;
reader.onerror = reject;
reader.readAsDataURL(input.files[0]);
})
const file = input.files[0];
const fileData = await getBase64Async(file);
$('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup');
if (!power_user.never_resize_avatars) {
$('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup');
const croppedImage = await callPopup(getCropPopup(fileData), 'avatarToCrop');
if (!croppedImage) {
return;
}
const croppedImage = await callPopup(getCropPopup(e.target.result), 'avatarToCrop');
if (!croppedImage) {
return;
$("#avatar_load_preview").attr("src", croppedImage);
} else {
$("#avatar_load_preview").attr("src", fileData);
}
$("#avatar_load_preview").attr("src", croppedImage || e.target.result);
if (menu_type == "create") {
return;
}
@ -5162,24 +5162,19 @@ async function uploadUserAvatar(e) {
}
const formData = new FormData($("#form_upload_avatar").get(0));
const dataUrl = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = resolve;
reader.onerror = reject;
reader.readAsDataURL(file);
});
$('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup');
const confirmation = await callPopup(getCropPopup(dataUrl.target.result), 'avatarToCrop');
if (!confirmation) {
return;
}
const dataUrl = await getBase64Async(file);
let url = "/uploaduseravatar";
if (crop_data !== undefined) {
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
if (!power_user.never_resize_avatars) {
$('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup');
const confirmation = await callPopup(getCropPopup(dataUrl), 'avatarToCrop');
if (!confirmation) {
return;
}
if (crop_data !== undefined) {
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
}
}
jQuery.ajax({
@ -5190,7 +5185,7 @@ async function uploadUserAvatar(e) {
cache: false,
contentType: false,
processData: false,
success: async function () {
success: async function (data) {
// If the user uploaded a new avatar, we want to make sure it's not cached
const name = formData.get("overwrite_name");
if (name) {
@ -5198,6 +5193,12 @@ async function uploadUserAvatar(e) {
reloadUserAvatar(true);
}
if (data.path) {
await getUserAvatars();
await delay(500);
await createPersona(data.path);
}
crop_data = undefined;
await getUserAvatars();
},

View File

@ -1,7 +1,3 @@
/**
* This is a placeholder file for all the Persona Management code. Will be refactored into a separate file soon.
*/
import { callPopup, characters, chat_metadata, default_avatar, eventSource, event_types, getRequestHeaders, getThumbnailUrl, getUserAvatars, name1, saveMetadata, saveSettingsDebounced, setUserName, this_chid, user_avatar } from "../script.js";
import { persona_description_positions, power_user } from "./power-user.js";
import { getTokenCount } from "./tokenizers.js";
@ -38,6 +34,28 @@ async function uploadUserAvatar(url, name) {
});
}
/**
* Prompts the user to create a persona for the uploaded avatar.
* @param {string} avatarId User avatar id
* @returns {Promise} Promise that resolves when the persona is set
*/
export async function createPersona(avatarId) {
const personaName = await callPopup('<h3>Enter a name for this persona:</h3>Cancel if you\'re just uploading an avatar.', 'input', '');
if (!personaName) {
console.debug('User cancelled creating a persona');
return;
}
await delay(500);
const personaDescription = await callPopup('<h3>Enter a description for this persona:</h3>You can always add or change it later.', 'input', '', { rows: 4 });
initPersona(avatarId, personaName, personaDescription);
if (power_user.persona_show_notifications) {
toastr.success(`You can now pick ${personaName} as a persona in the Persona Management menu.`, 'Persona Created');
}
}
async function createDummyPersona() {
const personaName = await callPopup('<h3>Enter a name for this persona:</h3>', 'input', '');
@ -48,18 +66,28 @@ async function createDummyPersona() {
// Date + name (only ASCII) to make it unique
const avatarId = `${Date.now()}-${personaName.replace(/[^a-zA-Z0-9]/g, '')}.png`;
initPersona(avatarId, personaName, '');
await uploadUserAvatar(default_avatar, avatarId);
}
/**
* Initializes a persona for the given avatar id.
* @param {string} avatarId User avatar id
* @param {string} personaName Name for the persona
* @param {string} personaDescription Optional description for the persona
* @returns {void}
*/
export function initPersona(avatarId, personaName, personaDescription) {
power_user.personas[avatarId] = personaName;
power_user.persona_descriptions[avatarId] = {
description: '',
description: personaDescription || '',
position: persona_description_positions.IN_PROMPT,
};
await uploadUserAvatar(default_avatar, avatarId);
saveSettingsDebounced();
}
export async function convertCharacterToPersona(characterId = null) {
if (null === characterId) characterId = this_chid;
const avatarUrl = characters[characterId]?.avatar;