fix(avatars): use proper getThumbnailUrl API to eliminate 404 errors
Root cause: Widgets were using getUserAvatar() which returns bare
filenames like 'user-default.png'. These were being used directly as
image src URLs, causing 404 errors like /user-default.png.
Solution: Use getAvatarUrl() dependency which calls getThumbnailUrl()
to convert filenames to proper URLs like /thumbnail?type=persona&file=...
Changes:
- userInfoWidget.js: Use getAvatarUrl('persona', rawAvatar) instead of
raw avatar validation
- sillytavern.js: Simplify updatePersonaAvatar() to trust
getSafeThumbnailUrl() which already calls getThumbnailUrl()
This eliminates 404 errors on initial render and when switching tabs.
This commit is contained in:
@@ -26,6 +26,7 @@ export function registerUserInfoWidget(registry, dependencies) {
|
|||||||
const {
|
const {
|
||||||
getContext,
|
getContext,
|
||||||
getUserAvatar,
|
getUserAvatar,
|
||||||
|
getAvatarUrl,
|
||||||
getFallbackAvatar,
|
getFallbackAvatar,
|
||||||
getExtensionSettings,
|
getExtensionSettings,
|
||||||
onStatsChange
|
onStatsChange
|
||||||
@@ -50,7 +51,16 @@ export function registerUserInfoWidget(registry, dependencies) {
|
|||||||
const settings = getExtensionSettings();
|
const settings = getExtensionSettings();
|
||||||
const context = getContext();
|
const context = getContext();
|
||||||
const userName = context.name1;
|
const userName = context.name1;
|
||||||
const userPortrait = getUserAvatar() || getFallbackAvatar();
|
|
||||||
|
// Get user avatar - use getAvatarUrl to convert filename to proper thumbnail URL
|
||||||
|
let userPortrait = getFallbackAvatar();
|
||||||
|
const rawAvatar = getUserAvatar();
|
||||||
|
|
||||||
|
// Convert raw avatar filename to proper thumbnail URL
|
||||||
|
// getAvatarUrl calls getThumbnailUrl which generates URLs like /thumbnail?type=persona&file=...
|
||||||
|
if (rawAvatar) {
|
||||||
|
userPortrait = getAvatarUrl('persona', rawAvatar);
|
||||||
|
}
|
||||||
|
|
||||||
// Merge default config
|
// Merge default config
|
||||||
const finalConfig = {
|
const finalConfig = {
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import {
|
|||||||
setLastActionWasSwipe,
|
setLastActionWasSwipe,
|
||||||
setIsPlotProgression,
|
setIsPlotProgression,
|
||||||
updateLastGeneratedData,
|
updateLastGeneratedData,
|
||||||
updateCommittedTrackerData
|
updateCommittedTrackerData,
|
||||||
|
FALLBACK_AVATAR_DATA_URI
|
||||||
} from '../../core/state.js';
|
} from '../../core/state.js';
|
||||||
import { saveChatData, loadChatData } from '../../core/persistence.js';
|
import { saveChatData, loadChatData } from '../../core/persistence.js';
|
||||||
|
|
||||||
@@ -291,11 +292,12 @@ export function onMessageSwiped(messageIndex) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the persona avatar image when user switches personas
|
* Update the persona avatar image when user switches personas
|
||||||
|
* Updates ALL .rpg-user-portrait elements with proper fallback handling
|
||||||
*/
|
*/
|
||||||
export function updatePersonaAvatar() {
|
export function updatePersonaAvatar() {
|
||||||
const portraitImg = document.querySelector('.rpg-user-portrait');
|
const portraitImgs = document.querySelectorAll('.rpg-user-portrait');
|
||||||
if (!portraitImg) {
|
if (portraitImgs.length === 0) {
|
||||||
// console.log('[RPG Companion] Portrait image element not found in DOM');
|
// console.log('[RPG Companion] No portrait image elements found in DOM');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,24 +305,27 @@ export function updatePersonaAvatar() {
|
|||||||
const context = getContext();
|
const context = getContext();
|
||||||
const currentUserAvatar = context.user_avatar || user_avatar;
|
const currentUserAvatar = context.user_avatar || user_avatar;
|
||||||
|
|
||||||
// console.log('[RPG Companion] Attempting to update persona avatar:', currentUserAvatar);
|
// console.log('[RPG Companion] Updating', portraitImgs.length, 'avatar(s) for:', currentUserAvatar);
|
||||||
|
|
||||||
// Try to get a valid thumbnail URL using our safe helper
|
// Update each avatar instance
|
||||||
if (currentUserAvatar) {
|
portraitImgs.forEach(portraitImg => {
|
||||||
const thumbnailUrl = getSafeThumbnailUrl('persona', currentUserAvatar);
|
// getSafeThumbnailUrl already calls getThumbnailUrl and handles errors
|
||||||
|
// It returns proper URLs like /thumbnail?type=persona&file=... or null
|
||||||
|
const thumbnailUrl = currentUserAvatar ? getSafeThumbnailUrl('persona', currentUserAvatar) : null;
|
||||||
|
const finalUrl = thumbnailUrl || FALLBACK_AVATAR_DATA_URI;
|
||||||
|
|
||||||
if (thumbnailUrl) {
|
// Set the avatar URL
|
||||||
// Only update the src if we got a valid URL
|
portraitImg.src = finalUrl;
|
||||||
portraitImg.src = thumbnailUrl;
|
|
||||||
// console.log('[RPG Companion] Persona avatar updated successfully');
|
// Add onerror handler to use fallback if load fails (404, etc.)
|
||||||
} else {
|
portraitImg.onerror = () => {
|
||||||
// Don't update the src if we couldn't get a valid URL
|
if (portraitImg.src !== FALLBACK_AVATAR_DATA_URI) {
|
||||||
// This prevents 400 errors and keeps the existing image
|
// console.warn('[RPG Companion] Avatar failed to load, using fallback');
|
||||||
// console.warn('[RPG Companion] Could not get valid thumbnail URL for persona avatar, keeping existing image');
|
portraitImg.src = FALLBACK_AVATAR_DATA_URI;
|
||||||
}
|
portraitImg.onerror = null; // Prevent infinite loop
|
||||||
} else {
|
}
|
||||||
// console.log('[RPG Companion] No user avatar configured, keeping existing image');
|
};
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user