diff --git a/public/script.js b/public/script.js index 53e89cc6e..a2557028a 100644 --- a/public/script.js +++ b/public/script.js @@ -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(); }, diff --git a/public/scripts/personas.js b/public/scripts/personas.js index 8a3f0341d..86cbc7826 100644 --- a/public/scripts/personas.js +++ b/public/scripts/personas.js @@ -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('