feat: remove character button

This commit is contained in:
Subarashimo
2025-12-04 21:04:56 +01:00
parent 9f6c44745b
commit 271c69ec49
3 changed files with 149 additions and 0 deletions
+1
View File
@@ -401,6 +401,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ
} }
instructions += '- Empty arrays [] for sections with no items\n'; instructions += '- Empty arrays [] for sections with no items\n';
instructions += '- Items may be added or removed from all sections\n';
instructions += '- null for main quest if none active\n'; instructions += '- null for main quest if none active\n';
// Add stat descriptions if any have descriptions // Add stat descriptions if any have descriptions
+116
View File
@@ -478,6 +478,7 @@ export function renderThoughts() {
<div class="rpg-character-header"> <div class="rpg-character-header">
<span class="rpg-character-emoji rpg-editable" contenteditable="true" data-character="${escapedName}" data-field="emoji" title="Click to edit emoji">${char.emoji}</span> <span class="rpg-character-emoji rpg-editable" contenteditable="true" data-character="${escapedName}" data-field="emoji" title="Click to edit emoji">${char.emoji}</span>
<span class="rpg-character-name rpg-editable" contenteditable="true" data-character="${escapedName}" data-field="name" title="Click to edit name">${char.name}</span> <span class="rpg-character-name rpg-editable" contenteditable="true" data-character="${escapedName}" data-field="name" title="Click to edit name">${char.name}</span>
<button class="rpg-character-remove" data-character="${escapedName}" title="Remove character">×</button>
</div> </div>
`; `;
@@ -541,6 +542,15 @@ export function renderThoughts() {
updateCharacterField(character, field, value); updateCharacterField(character, field, value);
}); });
// Add event handlers for remove character buttons
$thoughtsContainer.find('.rpg-character-remove').on('click', function(e) {
e.stopPropagation();
const characterName = $(this).data('character');
if (characterName && confirm(`Remove ${characterName} from present characters?`)) {
removeCharacter(characterName);
}
});
// Remove updating class after animation // Remove updating class after animation
if (extensionSettings.enableAnimations) { if (extensionSettings.enableAnimations) {
setTimeout(() => $thoughtsContainer.removeClass('rpg-content-updating'), 600); setTimeout(() => $thoughtsContainer.removeClass('rpg-content-updating'), 600);
@@ -780,6 +790,112 @@ export function updateCharacterField(characterName, field, value) {
} }
} }
/**
* Removes a character from Present Characters data and re-renders.
* Works with both structured (charactersData) and text (characterThoughts) formats.
*
* @param {string} characterName - Name of the character to remove
*/
export function removeCharacter(characterName) {
console.log('[RPG Companion] Removing character:', characterName);
// Remove from structured data if it exists
if (extensionSettings.charactersData && Array.isArray(extensionSettings.charactersData)) {
const initialLength = extensionSettings.charactersData.length;
extensionSettings.charactersData = extensionSettings.charactersData.filter(
char => char.name && char.name.toLowerCase() !== characterName.toLowerCase()
);
if (extensionSettings.charactersData.length < initialLength) {
console.log('[RPG Companion] Removed character from structured data');
}
}
// Remove from text format
if (!lastGeneratedData.characterThoughts) {
console.log('[RPG Companion] No characterThoughts data to remove from');
return;
}
const lines = lastGeneratedData.characterThoughts.split('\n');
const presentCharsConfig = extensionSettings.trackerConfig?.presentCharacters;
let characterFound = false;
let inTargetCharacter = false;
let characterStartIndex = -1;
let characterEndIndex = -1;
const linesToRemove = [];
// Find the character block
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith('- ')) {
const name = line.substring(2).trim();
if (name.toLowerCase() === characterName.toLowerCase()) {
characterFound = true;
inTargetCharacter = true;
characterStartIndex = i;
linesToRemove.push(i);
} else if (inTargetCharacter) {
characterEndIndex = i;
break;
}
} else if (inTargetCharacter) {
// Include all lines until the next character or end of file
linesToRemove.push(i);
// Check if this is a character name line (next character)
if (line.startsWith('- ')) {
characterEndIndex = i;
break;
}
}
}
if (characterFound && characterEndIndex === -1) {
characterEndIndex = lines.length;
}
if (characterFound && linesToRemove.length > 0) {
// Remove lines in reverse order to maintain indices
for (let i = linesToRemove.length - 1; i >= 0; i--) {
lines.splice(linesToRemove[i], 1);
}
// Clean up any trailing empty lines after removal
while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
lines.pop();
}
lastGeneratedData.characterThoughts = lines.join('\n');
committedTrackerData.characterThoughts = lines.join('\n');
console.log('[RPG Companion] Removed character from text format');
// Update chat swipe data
const chat = getContext().chat;
if (chat && chat.length > 0) {
for (let i = chat.length - 1; i >= 0; i--) {
const message = chat[i];
if (!message.is_user) {
if (message.extra && message.extra.rpg_companion_swipes) {
const swipeId = message.swipe_id || 0;
if (message.extra.rpg_companion_swipes[swipeId]) {
message.extra.rpg_companion_swipes[swipeId].characterThoughts = lines.join('\n');
}
}
break;
}
}
}
saveChatData();
renderThoughts();
updateChatThoughts();
} else {
console.log('[RPG Companion] Character not found in text format:', characterName);
}
}
/** /**
* Updates or removes thought overlays in the chat. * Updates or removes thought overlays in the chat.
* Creates floating thought bubbles positioned near character avatars. * Creates floating thought bubbles positioned near character avatars.
+32
View File
@@ -1957,6 +1957,38 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
white-space: nowrap; /* Prevent name from wrapping */ white-space: nowrap; /* Prevent name from wrapping */
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
/* Character remove button */
.rpg-character-remove {
flex-shrink: 0;
background: rgba(255, 0, 0, 0.2);
border: 1px solid rgba(255, 0, 0, 0.4);
border-radius: 50%;
width: clamp(18px, 2.5vh, 22px);
height: clamp(18px, 2.5vh, 22px);
display: flex;
align-items: center;
justify-content: center;
font-size: clamp(14px, 2vw, 18px);
color: var(--rpg-highlight);
cursor: pointer;
transition: all 0.2s ease;
padding: 0;
line-height: 1;
margin-left: auto;
}
.rpg-character-remove:hover {
background: rgba(255, 0, 0, 0.4);
border-color: rgba(255, 0, 0, 0.6);
transform: scale(1.1);
}
.rpg-character-remove:active {
transform: scale(0.95);
} }
/* Character traits/status line and custom fields */ /* Character traits/status line and custom fields */