Merge pull request #75 from munimunigamer/avatar-gen-fixes
fixed right click regen and clearing chat
This commit is contained in:
@@ -537,6 +537,9 @@ async function initUI() {
|
|||||||
} else {
|
} else {
|
||||||
$options.slideUp(200);
|
$options.slideUp(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-render thoughts to update tooltips (regenerate vs delete)
|
||||||
|
renderThoughts();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#rpg-avatar-llm-instruction').on('input', function() {
|
$('#rpg-avatar-llm-instruction').on('input', function() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Avatar Generator Module
|
* Avatar Generator Module
|
||||||
* Handles automatic and manual avatar generation for NPC characters
|
* Handles automatic and manual avatar generation for NPC characters
|
||||||
*
|
*
|
||||||
* Features:
|
* Features:
|
||||||
* - Batch generation with awaitable completion
|
* - Batch generation with awaitable completion
|
||||||
* - Batch prompt generation via LLM
|
* - Batch prompt generation via LLM
|
||||||
@@ -119,7 +119,7 @@ export function hasExistingAvatar(characterName) {
|
|||||||
/**
|
/**
|
||||||
* Generates avatars for multiple characters and waits for all to complete.
|
* Generates avatars for multiple characters and waits for all to complete.
|
||||||
* This is the main entry point for auto-generation within a workflow.
|
* This is the main entry point for auto-generation within a workflow.
|
||||||
*
|
*
|
||||||
* @param {string[]} characterNames - Array of character names to generate avatars for
|
* @param {string[]} characterNames - Array of character names to generate avatars for
|
||||||
* @param {Function} onStarted - Optional callback when generation starts (to update UI)
|
* @param {Function} onStarted - Optional callback when generation starts (to update UI)
|
||||||
* @returns {Promise<void>} Resolves when all generations complete
|
* @returns {Promise<void>} Resolves when all generations complete
|
||||||
@@ -199,7 +199,7 @@ export async function generateAvatarsForCharacters(characterNames, onStarted = n
|
|||||||
* Regenerates avatar for a specific character
|
* Regenerates avatar for a specific character
|
||||||
* Clears existing avatar and prompt, then generates new ones
|
* Clears existing avatar and prompt, then generates new ones
|
||||||
* Handles preset switching if useSeparatePreset is enabled
|
* Handles preset switching if useSeparatePreset is enabled
|
||||||
*
|
*
|
||||||
* @param {string} characterName - Name of character to regenerate
|
* @param {string} characterName - Name of character to regenerate
|
||||||
* @returns {Promise<string|null>} New avatar URL or null if failed
|
* @returns {Promise<string|null>} New avatar URL or null if failed
|
||||||
*/
|
*/
|
||||||
@@ -250,7 +250,7 @@ export async function regenerateAvatar(characterName) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates LLM prompts for multiple characters in a single API call
|
* Generates LLM prompts for multiple characters in a single API call
|
||||||
*
|
*
|
||||||
* @param {string[]} characterNames - Names of characters needing prompts
|
* @param {string[]} characterNames - Names of characters needing prompts
|
||||||
*/
|
*/
|
||||||
async function generateLLMPrompts(characterNames) {
|
async function generateLLMPrompts(characterNames) {
|
||||||
@@ -282,7 +282,7 @@ async function generateLLMPrompts(characterNames) {
|
|||||||
/**
|
/**
|
||||||
* Builds a fallback prompt when LLM prompt generation fails or isn't available
|
* Builds a fallback prompt when LLM prompt generation fails or isn't available
|
||||||
* Uses information embedded in the character name if present (e.g., from malformed tracker output)
|
* Uses information embedded in the character name if present (e.g., from malformed tracker output)
|
||||||
*
|
*
|
||||||
* @param {string} characterName - Character name (may contain additional details)
|
* @param {string} characterName - Character name (may contain additional details)
|
||||||
* @returns {string} A basic prompt for image generation
|
* @returns {string} A basic prompt for image generation
|
||||||
*/
|
*/
|
||||||
@@ -299,14 +299,14 @@ function buildFallbackPrompt(characterName) {
|
|||||||
return `portrait of ${name}, ${descriptions}, fantasy art style, detailed`;
|
return `portrait of ${name}, ${descriptions}, fantasy art style, detailed`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple fallback - just use the name
|
// Simple fallback - just use the name
|
||||||
return `portrait of ${characterName}, character portrait, fantasy art style, detailed face, high quality`;
|
return `portrait of ${characterName}, character portrait, fantasy art style, detailed face, high quality`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a single avatar using the /sd command
|
* Generates a single avatar using the /sd command
|
||||||
*
|
*
|
||||||
* @param {string} characterName - Name of character to generate avatar for
|
* @param {string} characterName - Name of character to generate avatar for
|
||||||
* @returns {Promise<string|null>} Avatar URL or null if failed
|
* @returns {Promise<string|null>} Avatar URL or null if failed
|
||||||
*/
|
*/
|
||||||
@@ -324,7 +324,7 @@ async function generateSingleAvatar(characterName) {
|
|||||||
// Execute /sd command with quiet=true to suppress chat output
|
// Execute /sd command with quiet=true to suppress chat output
|
||||||
const result = await executeSlashCommandsOnChatInput(
|
const result = await executeSlashCommandsOnChatInput(
|
||||||
`/sd quiet=true ${prompt}`,
|
`/sd quiet=true ${prompt}`,
|
||||||
{ clearChatInput: true }
|
{ clearChatInput: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
// Extract image URL from result
|
// Extract image URL from result
|
||||||
@@ -353,7 +353,7 @@ async function generateSingleAvatar(characterName) {
|
|||||||
/**
|
/**
|
||||||
* Extracts image URL from /sd command result
|
* Extracts image URL from /sd command result
|
||||||
* Handles various result formats
|
* Handles various result formats
|
||||||
*
|
*
|
||||||
* @param {any} result - Result from executeSlashCommandsOnChatInput
|
* @param {any} result - Result from executeSlashCommandsOnChatInput
|
||||||
* @returns {string|null} Image URL or null
|
* @returns {string|null} Image URL or null
|
||||||
*/
|
*/
|
||||||
@@ -373,7 +373,7 @@ function extractImageUrl(result) {
|
|||||||
if (typeof result === 'object') {
|
if (typeof result === 'object') {
|
||||||
// Try common properties
|
// Try common properties
|
||||||
const url = result.pipe || result.output || result.image || result.url || result.result;
|
const url = result.pipe || result.output || result.image || result.url || result.result;
|
||||||
|
|
||||||
if (url && typeof url === 'string') {
|
if (url && typeof url === 'string') {
|
||||||
if (url.startsWith('http') || url.startsWith('data:') || url.startsWith('/')) {
|
if (url.startsWith('http') || url.startsWith('data:') || url.startsWith('/')) {
|
||||||
return url;
|
return url;
|
||||||
|
|||||||
@@ -473,10 +473,15 @@ export function renderThoughts() {
|
|||||||
|
|
||||||
const escapedDefaultName = escapeHtmlAttr(defaultName);
|
const escapedDefaultName = escapeHtmlAttr(defaultName);
|
||||||
|
|
||||||
|
// Determine right-click action text based on auto-generate setting
|
||||||
|
const defaultAvatarRightClickAction = extensionSettings.autoGenerateAvatars
|
||||||
|
? 'Right-click to regenerate avatar'
|
||||||
|
: 'Right-click to delete avatar';
|
||||||
|
|
||||||
html += '<div class="rpg-thoughts-content">';
|
html += '<div class="rpg-thoughts-content">';
|
||||||
html += `
|
html += `
|
||||||
<div class="rpg-character-card" data-character-name="${escapedDefaultName}">
|
<div class="rpg-character-card" data-character-name="${escapedDefaultName}">
|
||||||
<div class="rpg-character-avatar rpg-avatar-upload" data-character="${escapedDefaultName}" title="Click to upload custom avatar Right-click to regenerate avatar">
|
<div class="rpg-character-avatar rpg-avatar-upload" data-character="${escapedDefaultName}" title="Click to upload custom avatar ${defaultAvatarRightClickAction}">
|
||||||
<img src="${defaultPortrait}" alt="${escapedDefaultName}" onerror="this.style.opacity='0.5';this.onerror=null;" />
|
<img src="${defaultPortrait}" alt="${escapedDefaultName}" onerror="this.style.opacity='0.5';this.onerror=null;" />
|
||||||
<div class="rpg-relationship-badge rpg-editable" contenteditable="true" data-character="${escapedDefaultName}" data-field="relationship" title="Click to edit (use emoji: ⚔️ ⚖️ ⭐ ❤️)">⚖️</div>
|
<div class="rpg-relationship-badge rpg-editable" contenteditable="true" data-character="${escapedDefaultName}" data-field="relationship" title="Click to edit (use emoji: ⚔️ ⚖️ ⭐ ❤️)">⚖️</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -535,9 +540,14 @@ export function renderThoughts() {
|
|||||||
// Check if avatar is being generated
|
// Check if avatar is being generated
|
||||||
const isCurrentlyGenerating = isGenerating(char.name);
|
const isCurrentlyGenerating = isGenerating(char.name);
|
||||||
|
|
||||||
|
// Determine right-click action text based on auto-generate setting
|
||||||
|
const avatarRightClickAction = extensionSettings.autoGenerateAvatars
|
||||||
|
? 'Right-click to regenerate avatar'
|
||||||
|
: 'Right-click to delete avatar';
|
||||||
|
|
||||||
html += `
|
html += `
|
||||||
<div class="rpg-character-card" data-character-name="${escapedName}">
|
<div class="rpg-character-card" data-character-name="${escapedName}">
|
||||||
<div class="rpg-character-avatar rpg-avatar-upload ${isCurrentlyGenerating ? 'rpg-avatar-generating' : ''}" data-character="${escapedName}" title="Click to upload custom avatar Right-click to regenerate avatar">
|
<div class="rpg-character-avatar rpg-avatar-upload ${isCurrentlyGenerating ? 'rpg-avatar-generating' : ''}" data-character="${escapedName}" title="Click to upload custom avatar ${avatarRightClickAction}">
|
||||||
<img src="${characterPortrait}" alt="${escapedName}" onerror="this.style.opacity='0.5';this.onerror=null;" />
|
<img src="${characterPortrait}" alt="${escapedName}" onerror="this.style.opacity='0.5';this.onerror=null;" />
|
||||||
${isCurrentlyGenerating ? '<div class="rpg-generating-overlay"><i class="fa-solid fa-spinner fa-spin"></i></div>' : ''}
|
${isCurrentlyGenerating ? '<div class="rpg-generating-overlay"><i class="fa-solid fa-spinner fa-spin"></i></div>' : ''}
|
||||||
${hasRelationshipEnabled ? `<div class="rpg-relationship-badge rpg-editable" contenteditable="true" data-character="${escapedName}" data-field="${relationshipFieldName}" title="Click to edit (use emoji: ⚔️ ⚖️ ⭐ ❤️)">${relationshipBadge}</div>` : ''}
|
${hasRelationshipEnabled ? `<div class="rpg-relationship-badge rpg-editable" contenteditable="true" data-character="${escapedName}" data-field="${relationshipFieldName}" title="Click to edit (use emoji: ⚔️ ⚖️ ⭐ ❤️)">${relationshipBadge}</div>` : ''}
|
||||||
|
|||||||
Reference in New Issue
Block a user