mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	Upload expressions update
This commit is contained in:
		@@ -15,6 +15,8 @@ import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashComm
 | 
			
		||||
import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
 | 
			
		||||
import { slashCommandReturnHelper } from '../../slash-commands/SlashCommandReturnHelper.js';
 | 
			
		||||
import { generateWebLlmChatPrompt, isWebLlmSupported } from '../shared.js';
 | 
			
		||||
import { Popup, POPUP_RESULT } from '../../popup.js';
 | 
			
		||||
import { t } from '../../i18n.js';
 | 
			
		||||
export { MODULE_NAME };
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1852,11 +1854,23 @@ async function handleFileUpload(url, formData) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Removes the file extension from a file name
 | 
			
		||||
 * @param {string} fileName The file name to remove the extension from
 | 
			
		||||
 * @returns {string} The file name without the extension
 | 
			
		||||
 */
 | 
			
		||||
function withoutExtension(fileName) {
 | 
			
		||||
    return fileName.replace(/\.[^/.]+$/, '');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function onClickExpressionUpload(event) {
 | 
			
		||||
    // Prevents the expression from being set
 | 
			
		||||
    event.stopPropagation();
 | 
			
		||||
 | 
			
		||||
    const expression = $(this).closest('.expression_list_item').data('expression');
 | 
			
		||||
    const expressionListItem = $(this).closest('.expression_list_item');
 | 
			
		||||
 | 
			
		||||
    const clickedFileName = expressionListItem.attr('data-expression-type') !== 'failure' ? expressionListItem.attr('data-filename') : null;
 | 
			
		||||
    const expression = expressionListItem.data('expression');
 | 
			
		||||
    const name = $('#image_list').data('name');
 | 
			
		||||
 | 
			
		||||
    const handleExpressionUploadChange = async (e) => {
 | 
			
		||||
@@ -1866,21 +1880,70 @@ async function onClickExpressionUpload(event) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // // If extension_settings.expressions.allowMultiple is false and there's already a main image, ask user:
 | 
			
		||||
        // let hasMainImage = true; // Check from your item data
 | 
			
		||||
        // if (!extension_settings.expressions.allowMultiple && hasMainImage) {
 | 
			
		||||
        //     let userChoice = await callPopup('<h3>Replace existing main image?</h3><p>Press Ok to replace, Cancel to abort.</p>', 'confirm');
 | 
			
		||||
        //     if (!userChoice) {
 | 
			
		||||
        //         return;
 | 
			
		||||
        //     }
 | 
			
		||||
        //     // If user chooses replace, remove the old file, then proceed
 | 
			
		||||
        //     // ...existing code to remove old file...
 | 
			
		||||
        // }
 | 
			
		||||
        const existingFiles = spriteCache[name]?.find(x => x.label === expression)?.files || [];
 | 
			
		||||
 | 
			
		||||
        let spriteName = expression;
 | 
			
		||||
 | 
			
		||||
        if (extension_settings.expressions.allowMultiple) {
 | 
			
		||||
            const matchesExisting = existingFiles.some(x => x.fileName === file.name);
 | 
			
		||||
            const fileNameWithoutExtension = withoutExtension(file.name);
 | 
			
		||||
            const filenameValidationRegex = new RegExp(`^${expression}(?:[-\\.].*?)?$`);
 | 
			
		||||
            const validFileName = filenameValidationRegex.test(fileNameWithoutExtension);
 | 
			
		||||
 | 
			
		||||
            // If there is no expression yet and it's a valid expression, we just take it
 | 
			
		||||
            if (!clickedFileName && validFileName) {
 | 
			
		||||
                spriteName = fileNameWithoutExtension;
 | 
			
		||||
            }
 | 
			
		||||
            // If the filename matches the one that was clicked, we just take it and replace it
 | 
			
		||||
            else if (clickedFileName === file.name) {
 | 
			
		||||
                spriteName = fileNameWithoutExtension;
 | 
			
		||||
            }
 | 
			
		||||
            // If it's a valid filename and there's no existing file with the same name, we just take it
 | 
			
		||||
            else if (!matchesExisting && validFileName) {
 | 
			
		||||
                spriteName = fileNameWithoutExtension;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                /** @type {import('../../popup.js').CustomPopupButton[]} */
 | 
			
		||||
                const customButtons = [];
 | 
			
		||||
                if (clickedFileName) {
 | 
			
		||||
                    customButtons.push({
 | 
			
		||||
                        text: t`Replace Existing`,
 | 
			
		||||
                        result: POPUP_RESULT.NEGATIVE,
 | 
			
		||||
                        action: () => {
 | 
			
		||||
                            console.debug('Replacing existing sprite');
 | 
			
		||||
                            spriteName = withoutExtension(clickedFileName);
 | 
			
		||||
                        },
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const message = await renderExtensionTemplateAsync(MODULE_NAME, 'templates/upload-expression', { expression, clickedFileName });
 | 
			
		||||
 | 
			
		||||
                spriteName = null;
 | 
			
		||||
                const result = await Popup.show.input(t`Upload Expression Sprite`, message,
 | 
			
		||||
                    `${expression}-${existingFiles.length}`, { customButtons: customButtons });
 | 
			
		||||
 | 
			
		||||
                if (result) {
 | 
			
		||||
                    if (!filenameValidationRegex.test(result)) {
 | 
			
		||||
                        toastr.warning(t`The name you entered does not follow the naming schema for the selected expression '${expression}'.`, t`Invalid Expression Sprite Name`);
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    spriteName = result;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            spriteName = withoutExtension(clickedFileName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!spriteName) {
 | 
			
		||||
            toastr.warning(t`Cancelled uploading sprite.`, t`Upload Cancelled`);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const formData = new FormData();
 | 
			
		||||
        formData.append('name', name);
 | 
			
		||||
        formData.append('label', expression);
 | 
			
		||||
        formData.append('avatar', file);
 | 
			
		||||
        formData.append('spriteName', spriteName);
 | 
			
		||||
 | 
			
		||||
        await handleFileUpload('/api/sprites/upload', formData);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user