fixed avatar images appearing in rpg

This commit is contained in:
munimunigamer
2025-12-25 20:39:01 -08:00
parent 7802479670
commit b7e52046bc
2 changed files with 69 additions and 3 deletions
+57 -3
View File
@@ -10,6 +10,12 @@ import { saveSettings } from '../../core/persistence.js';
// Track pending avatar generations to avoid duplicate requests // Track pending avatar generations to avoid duplicate requests
const pendingGenerations = new Set(); const pendingGenerations = new Set();
/**
* Callback for when all avatar generations complete
* Used to trigger UI updates
*/
let onGenerationCompleteCallback = null;
/** /**
* Style presets for avatar generation prompts * Style presets for avatar generation prompts
*/ */
@@ -32,6 +38,24 @@ function buildGenerationPrompt(characterName) {
return `${style}, ${characterName}, ${custom}`.trim(); return `${style}, ${characterName}, ${custom}`.trim();
} }
/**
* Sets a callback to be called when all avatar generations complete
* @param {Function} callback - Function to call when all generations are done
*/
export function setOnGenerationComplete(callback) {
onGenerationCompleteCallback = callback;
}
/**
* Triggers the completion callback if all generations are done
*/
function checkAndTriggerCompletionCallback() {
if (pendingGenerations.size === 0 && onGenerationCompleteCallback) {
onGenerationCompleteCallback();
onGenerationCompleteCallback = null;
}
}
/** /**
* Generates an avatar for a character using /sd command * Generates an avatar for a character using /sd command
* @param {string} characterName - Name of the character to generate avatar for * @param {string} characterName - Name of the character to generate avatar for
@@ -61,10 +85,11 @@ export async function generateAvatar(characterName) {
const prompt = buildGenerationPrompt(characterName); const prompt = buildGenerationPrompt(characterName);
// Execute /sd command with quiet=true // Execute /sd command with quiet=true
// This saves to gallery without posting to chat // IMPORTANT: quiet=true must come BEFORE the prompt
// This suppresses chat output and returns the image URL via pipe
const result = await executeSlashCommandsOnChatInput( const result = await executeSlashCommandsOnChatInput(
`/sd ${prompt} quiet=true`, `/sd quiet=true ${prompt}`,
{ clearChatInput: false } { clearChatInput: true }
); );
// The result might be an object with various properties // The result might be an object with various properties
@@ -102,6 +127,8 @@ export async function generateAvatar(characterName) {
return null; return null;
} finally { } finally {
pendingGenerations.delete(characterName); pendingGenerations.delete(characterName);
// Check if all generations are complete and trigger callback
checkAndTriggerCompletionCallback();
} }
} }
@@ -134,3 +161,30 @@ export function checkAndGenerateAvatar(characterName, hasAvatar) {
export function isGenerating(characterName) { export function isGenerating(characterName) {
return pendingGenerations.has(characterName); return pendingGenerations.has(characterName);
} }
/**
* Checks if ANY avatars are currently being generated
* @returns {boolean} True if any generation is in progress
*/
export function isAnyGenerating() {
return pendingGenerations.size > 0;
}
/**
* Waits for all pending avatar generations to complete
* @returns {Promise<void>}
*/
export function waitForAllGenerations() {
if (pendingGenerations.size === 0) {
return Promise.resolve();
}
return new Promise((resolve) => {
const checkInterval = setInterval(() => {
if (pendingGenerations.size === 0) {
clearInterval(checkInterval);
resolve();
}
}, 100);
});
}
+12
View File
@@ -23,6 +23,7 @@ import { renderThoughts } from '../rendering/thoughts.js';
import { renderInventory } from '../rendering/inventory.js'; import { renderInventory } from '../rendering/inventory.js';
import { renderQuests } from '../rendering/quests.js'; import { renderQuests } from '../rendering/quests.js';
import { i18n } from '../../core/i18n.js'; import { i18n } from '../../core/i18n.js';
import { setOnGenerationComplete, waitForAllGenerations } from '../features/avatarGenerator.js';
// Store the original preset name to restore after tracker generation // Store the original preset name to restore after tracker generation
let originalPresetName = null; let originalPresetName = null;
@@ -214,6 +215,12 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
renderInventory(); renderInventory();
renderQuests(); renderQuests();
// Set up callback to re-render thoughts when avatars finish generating
setOnGenerationComplete(() => {
console.log('[RPG Companion] Avatar generation complete, re-rendering thoughts...');
renderThoughts();
});
// Save to chat metadata // Save to chat metadata
saveChatData(); saveChatData();
} }
@@ -221,6 +228,11 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
} catch (error) { } catch (error) {
console.error('[RPG Companion] Error updating RPG data:', error); console.error('[RPG Companion] Error updating RPG data:', error);
} finally { } finally {
// Wait for all avatar generations to complete before finishing
console.log('[RPG Companion] Waiting for avatar generations to complete...');
await waitForAllGenerations();
console.log('[RPG Companion] All avatar generations complete.');
// Restore original preset if we switched to a separate one // Restore original preset if we switched to a separate one
if (originalPresetName && extensionSettings.useSeparatePreset) { if (originalPresetName && extensionSettings.useSeparatePreset) {
console.log(`[RPG Companion] Restoring original preset: "${originalPresetName}"`); console.log(`[RPG Companion] Restoring original preset: "${originalPresetName}"`);