v3.1.0: Add parser error detection and recommended models section

This commit is contained in:
Spicy_Marinara
2026-01-07 22:56:26 +01:00
parent dbf5c2d17a
commit a3063aff4f
33 changed files with 599 additions and 459 deletions
+32 -9
View File
@@ -75,23 +75,23 @@ function separateEmojiFromText(str) {
* Includes event listeners for editable fields.
*/
export function renderInfoBox() {
console.log('[RPG InfoBox Render] ==================== RENDERING INFO BOX ====================');
console.log('[RPG InfoBox Render] showInfoBox setting:', extensionSettings.showInfoBox);
console.log('[RPG InfoBox Render] Container exists:', !!$infoBoxContainer);
// console.log('[RPG InfoBox Render] ==================== RENDERING INFO BOX ====================');
// console.log('[RPG InfoBox Render] showInfoBox setting:', extensionSettings.showInfoBox);
// console.log('[RPG InfoBox Render] Container exists:', !!$infoBoxContainer);
if (!extensionSettings.showInfoBox || !$infoBoxContainer) {
console.log('[RPG InfoBox Render] Exiting: showInfoBox or container is false');
// console.log('[RPG InfoBox Render] Exiting: showInfoBox or container is false');
return;
}
// Use committedTrackerData as fallback if lastGeneratedData is empty (e.g., after page refresh)
const infoBoxData = lastGeneratedData.infoBox || committedTrackerData.infoBox;
console.log('[RPG InfoBox Render] infoBoxData length:', infoBoxData ? infoBoxData.length : 'null');
console.log('[RPG InfoBox Render] infoBoxData preview:', infoBoxData ? infoBoxData.substring(0, 200) : 'null');
// console.log('[RPG InfoBox Render] infoBoxData length:', infoBoxData ? infoBoxData.length : 'null');
// console.log('[RPG InfoBox Render] infoBoxData preview:', infoBoxData ? infoBoxData.substring(0, 200) : 'null');
// If no data yet, hide the container (e.g., after cache clear)
if (!infoBoxData) {
console.log('[RPG InfoBox Render] No data, hiding container');
// console.log('[RPG InfoBox Render] No data, hiding container');
$infoBoxContainer.empty().hide();
return;
}
@@ -574,6 +574,19 @@ export function renderInfoBox() {
$infoBoxContainer.html(html);
// Add dynamic text scaling for location field
const updateLocationTextSize = ($element) => {
const text = $element.text();
const charCount = text.length;
$element.css('--char-count', Math.min(charCount, 100));
};
// Initial size update for location
const $locationText = $infoBoxContainer.find('[data-field="location"]');
if ($locationText.length) {
updateLocationTextSize($locationText);
}
// Add event handlers for editable Info Box fields
$infoBoxContainer.find('.rpg-editable').on('blur', function() {
const $this = $(this);
@@ -591,6 +604,11 @@ export function renderInfoBox() {
}
}
// Update location text size dynamically
if (field === 'location') {
updateLocationTextSize($this);
}
// Handle recent events separately
if (field === 'event1' || field === 'event2' || field === 'event3') {
updateRecentEvent(field, value);
@@ -599,6 +617,11 @@ export function renderInfoBox() {
}
});
// Update location size on input as well (real-time)
$infoBoxContainer.find('[data-field="location"]').on('input', function() {
updateLocationTextSize($(this));
});
// For date fields, show full value on focus
$infoBoxContainer.find('[data-field="month"], [data-field="weekday"], [data-field="year"]').on('focus', function() {
const fullValue = $(this).data('full-value');
@@ -707,7 +730,7 @@ export function updateInfoBoxField(field, value) {
committedTrackerData.infoBox = lastGeneratedData.infoBox;
saveChatData();
renderInfoBox();
console.log('[RPG Companion] Updated info box field (v3 JSON):', { field, value });
// console.log('[RPG Companion] Updated info box field (v3 JSON):', { field, value });
return;
}
}
@@ -1061,6 +1084,6 @@ function updateRecentEvent(field, value) {
window.RPGCompanion.updateWeatherEffect();
}
console.log(`[RPG Companion] Updated recent event ${field}:`, value);
// console.log(`[RPG Companion] Updated recent event ${field}:`, value);
}
}
+8 -8
View File
@@ -100,7 +100,7 @@ export function renderMusicPlayer(container) {
// Find the chat form container and insert widget before (above) it
const $chatForm = $('#send_form');
console.log('[RPG Companion] Music Player: Found #send_form:', $chatForm.length > 0);
// console.log('[RPG Companion] Music Player: Found #send_form:', $chatForm.length > 0);
if ($chatForm.length === 0) {
console.error('[RPG Companion] Music Player: Could not find #send_form - cannot render widget!');
@@ -108,17 +108,17 @@ export function renderMusicPlayer(container) {
}
// Insert widget inside (at top of) the chat form
console.log('[RPG Companion] Music Player: Prepending widget to #send_form');
// console.log('[RPG Companion] Music Player: Prepending widget to #send_form');
$chatForm.prepend(musicPlayerHtml);
console.log('[RPG Companion] Music Player: Widget inserted, checking if visible...');
// console.log('[RPG Companion] Music Player: Widget inserted, checking if visible...');
const $widget = $('#rpg-chat-music-player');
console.log('[RPG Companion] Music Player: Widget exists:', $widget.length > 0);
// console.log('[RPG Companion] Music Player: Widget exists:', $widget.length > 0);
if ($widget.length > 0) {
console.log('[RPG Companion] Music Player: Widget position:', $widget.offset());
console.log('[RPG Companion] Music Player: Widget dimensions:', { width: $widget.width(), height: $widget.height() });
console.log('[RPG Companion] Music Player: Widget CSS display:', $widget.css('display'));
console.log('[RPG Companion] Music Player: Widget CSS visibility:', $widget.css('visibility'));
// console.log('[RPG Companion] Music Player: Widget position:', $widget.offset());
// console.log('[RPG Companion] Music Player: Widget dimensions:', { width: $widget.width(), height: $widget.height() });
// console.log('[RPG Companion] Music Player: Widget CSS display:', $widget.css('display'));
// console.log('[RPG Companion] Music Player: Widget CSS visibility:', $widget.css('visibility'));
}
// Bind play button click
+96 -36
View File
@@ -39,7 +39,7 @@ function getLockIconHtml(tracker, path) {
* Helper to log to both console and debug logs array
*/
function debugLog(message, data = null) {
console.log(message, data || '');
// console.log(message, data || '');
if (extensionSettings.debugMode) {
addDebugLog(message, data);
}
@@ -592,7 +592,7 @@ export function renderThoughts() {
const character = $(this).data('character');
const field = $(this).data('field');
const value = $(this).text().trim();
console.log('[RPG Companion] Character stat edit:', { character, field, value });
// console.log('[RPG Companion] Character stat edit:', { character, field, value });
updateCharacterField(character, field, value);
});
@@ -723,7 +723,7 @@ export function updateCharacterField(characterName, field, value) {
else if (isThoughtsField && line.startsWith(thoughtsFieldName + ':')) {
// Update thoughts field
lines[i] = `${thoughtsFieldName}: ${value}`;
console.log('[RPG Companion] Updated thoughts:', lines[i]);
// console.log('[RPG Companion] Updated thoughts:', lines[i]);
}
}
@@ -737,7 +737,7 @@ export function updateCharacterField(characterName, field, value) {
}
numValue = Math.max(0, Math.min(100, numValue));
console.log('[RPG Companion] Updating stat:', { field, rawValue: value, cleanValue, numValue });
// console.log('[RPG Companion] Updating stat:', { field, rawValue: value, cleanValue, numValue });
if (statsLineExists) {
// Update existing Stats line
@@ -750,7 +750,7 @@ export function updateCharacterField(characterName, field, value) {
if (statParts[j].startsWith(field + ':')) {
statParts[j] = `${field}: ${numValue}%`;
statFound = true;
console.log('[RPG Companion] Updated stat part:', statParts[j]);
// console.log('[RPG Companion] Updated stat part:', statParts[j]);
break;
}
}
@@ -758,11 +758,11 @@ export function updateCharacterField(characterName, field, value) {
// If stat wasn't found in existing parts, add it
if (!statFound) {
statParts.push(`${field}: ${numValue}%`);
console.log('[RPG Companion] Added new stat to existing line:', `${field}: ${numValue}%`);
// console.log('[RPG Companion] Added new stat to existing line:', `${field}: ${numValue}%`);
}
lines[statsLineIndex] = `Stats: ${statParts.join(' | ')}`;
console.log('[RPG Companion] Updated stats line:', lines[statsLineIndex]);
// console.log('[RPG Companion] Updated stats line:', lines[statsLineIndex]);
} else {
// Create new Stats line with all enabled stats (defaulting to 0% except the one being edited)
const statsParts = enabledCharStats.map(s => {
@@ -785,7 +785,7 @@ export function updateCharacterField(characterName, field, value) {
}
lines.splice(insertIndex, 0, newStatsLine);
console.log('[RPG Companion] Created new stats line:', newStatsLine);
// console.log('[RPG Companion] Created new stats line:', newStatsLine);
characterEndIndex++; // Adjust end index since we inserted a line
}
}
@@ -831,7 +831,7 @@ export function updateCharacterField(characterName, field, value) {
lastGeneratedData.characterThoughts = lines.join('\n');
committedTrackerData.characterThoughts = lines.join('\n');
console.log('[RPG Companion] Updated characterThoughts data:', lastGeneratedData.characterThoughts);
// console.log('[RPG Companion] Updated characterThoughts data:', lastGeneratedData.characterThoughts);
const chat = getContext().chat;
if (chat && chat.length > 0) {
@@ -1075,12 +1075,12 @@ function initThoughtIconDragHandlers() {
if (thoughtIconDragHandlersInitialized) return;
thoughtIconDragHandlersInitialized = true;
console.log('[Thought Icon] Initializing drag handlers ONCE - will attach to icon when created');
// console.log('[Thought Icon] Initializing drag handlers ONCE - will attach to icon when created');
}
// Function to attach drag handlers to a specific icon element
function attachDragHandlersToIcon($icon) {
console.log('[Thought Icon] Attaching handlers to icon element');
// console.log('[Thought Icon] Attaching handlers to icon element');
// Remove any existing handlers
$icon.off('.thoughtIconDrag');
@@ -1089,20 +1089,20 @@ function attachDragHandlersToIcon($icon) {
$icon.on('click.thoughtIconDrag', function(e) {
// Check global flag set immediately after drag completes
if (justFinishedDragging) {
console.log('[Thought Icon] CLICK blocked - just finished dragging');
// console.log('[Thought Icon] CLICK blocked - just finished dragging');
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return false;
}
console.log('[Thought Icon] CLICK detected on icon!');
// console.log('[Thought Icon] CLICK detected on icon!');
});
// Touch drag support - mobile only
$icon.on('touchstart.thoughtIconDrag', function(e) {
if (window.innerWidth > 1000) return;
console.log('[Thought Icon] touchstart');
// console.log('[Thought Icon] touchstart');
touchMoved = false;
dragStartTime = Date.now();
const touch = e.originalEvent.touches[0];
@@ -1120,7 +1120,7 @@ function attachDragHandlersToIcon($icon) {
if (window.innerWidth > 1000) return;
if (!touchMoved) {
console.log('[Thought Icon] touchmove - first movement');
// console.log('[Thought Icon] touchmove - first movement');
}
touchMoved = true;
const touch = e.originalEvent.touches[0];
@@ -1160,7 +1160,7 @@ function attachDragHandlersToIcon($icon) {
});
$icon.on('touchend.thoughtIconDrag', function(e) {
console.log('[Thought Icon] touchend - isDragging:', isDragging, 'touchMoved:', touchMoved);
// console.log('[Thought Icon] touchend - isDragging:', isDragging, 'touchMoved:', touchMoved);
if (isDragging) {
const offset = $(this).offset();
@@ -1193,7 +1193,7 @@ function attachDragHandlersToIcon($icon) {
e.preventDefault();
e.stopPropagation();
} else if (!touchMoved) {
console.log('[Thought Icon] Opening panel - was a tap');
// console.log('[Thought Icon] Opening panel - was a tap');
const $panel = $('#rpg-thought-panel');
const iconOffset = $(this).offset();
if (iconOffset) {
@@ -1207,7 +1207,7 @@ function attachDragHandlersToIcon($icon) {
$(this).addClass('rpg-hidden');
$panel.fadeIn(200);
} else {
console.log('[Thought Icon] Did nothing - touchMoved but not isDragging');
// console.log('[Thought Icon] Did nothing - touchMoved but not isDragging');
}
});
@@ -1217,7 +1217,7 @@ function attachDragHandlersToIcon($icon) {
$icon.on('mousedown.thoughtIconDrag', function(e) {
if (window.innerWidth > 1000) return;
console.log('[Thought Icon] mousedown');
// console.log('[Thought Icon] mousedown');
e.preventDefault();
mouseDown = true;
@@ -1237,7 +1237,7 @@ function attachDragHandlersToIcon($icon) {
if (!mouseDown || window.innerWidth > 1000) return;
if (!touchMoved) {
console.log('[Thought Icon] mousemove - first movement');
// console.log('[Thought Icon] mousemove - first movement');
}
touchMoved = true;
@@ -1280,7 +1280,7 @@ function attachDragHandlersToIcon($icon) {
$(document).on('mouseup.thoughtIconDrag', function(e) {
if (!mouseDown) return;
console.log('[Thought Icon] mouseup - isDragging:', isDragging, 'touchMoved:', touchMoved);
// console.log('[Thought Icon] mouseup - isDragging:', isDragging, 'touchMoved:', touchMoved);
mouseDown = false;
@@ -1568,22 +1568,82 @@ export function createThoughtPanel($message, thoughtsArray) {
// Load saved icon position in mobile, or default to center of viewport
if (extensionSettings.thoughtIconPosition && extensionSettings.thoughtIconPosition.top && extensionSettings.thoughtIconPosition.left) {
const pos = extensionSettings.thoughtIconPosition;
$thoughtIcon.css({
top: pos.top,
left: pos.left,
transform: 'none',
right: 'auto',
bottom: 'auto'
});
// Validate saved position - check if it's not at the very top (likely invalid)
const savedTop = parseInt(pos.top);
const topBar = $('#top-settings-holder');
const topBarHeight = topBar.length ? topBar.outerHeight() : 60;
// If saved position is above or too close to top bar, recalculate default
if (savedTop < topBarHeight + 50) {
// console.log('[Thought Icon] Saved position invalid (too close to top), recalculating default');
// Clear invalid saved position
delete extensionSettings.thoughtIconPosition;
saveSettings();
// Calculate new default position
setTimeout(() => {
const viewportHeight = window.innerHeight;
const viewportWidth = window.innerWidth;
const defaultTop = topBarHeight + ((viewportHeight - topBarHeight) / 2) - 22;
const defaultLeft = (viewportWidth * 0.75) - 22;
// console.log('[Thought Icon] Setting new default position:', {
// topBarHeight,
// viewportHeight,
// viewportWidth,
// calculatedTop: defaultTop,
// calculatedLeft: defaultLeft
// });
$thoughtIcon.css({
top: `${defaultTop}px`,
left: `${defaultLeft}px`,
transform: 'none',
right: 'auto',
bottom: 'auto'
});
}, 100);
} else {
// Position is valid, use it
$thoughtIcon.css({
top: pos.top,
left: pos.left,
transform: 'none',
right: 'auto',
bottom: 'auto'
});
}
} else {
// Default position: center of viewport
$thoughtIcon.css({
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
right: 'auto',
bottom: 'auto'
});
// Default position: center-right of viewport, accounting for top bar
// Use setTimeout to ensure DOM is fully rendered before calculating positions
setTimeout(() => {
const topBar = $('#top-settings-holder');
const topBarHeight = topBar.length ? topBar.outerHeight() : 60;
const viewportHeight = window.innerHeight;
const viewportWidth = window.innerWidth;
// Position in the center vertically (accounting for top bar) and slightly right
const defaultTop = topBarHeight + ((viewportHeight - topBarHeight) / 2) - 22; // 22 = half of icon height
const defaultLeft = (viewportWidth * 0.75) - 22; // 75% from left, minus half icon width
// console.log('[Thought Icon] Setting default position:', {
// topBarHeight,
// viewportHeight,
// viewportWidth,
// calculatedTop: defaultTop,
// calculatedLeft: defaultLeft
// });
$thoughtIcon.css({
top: `${defaultTop}px`,
left: `${defaultLeft}px`,
transform: 'none',
right: 'auto',
bottom: 'auto'
});
}, 100);
}
} else {
// Desktop: show panel, hide icon with class
+19 -19
View File
@@ -181,12 +181,12 @@ export function renderUserStats() {
// Don't render if no data exists (e.g., after cache clear)
// Check both lastGeneratedData and committedTrackerData
console.log('[RPG UserStats Render] Checking data:', {
hasLastGenerated: !!lastGeneratedData.userStats,
hasCommitted: !!committedTrackerData.userStats,
lastGeneratedPreview: lastGeneratedData.userStats ? lastGeneratedData.userStats.substring(0, 100) : 'null',
committedPreview: committedTrackerData.userStats ? committedTrackerData.userStats.substring(0, 100) : 'null'
});
// console.log('[RPG UserStats Render] Checking data:', {
// hasLastGenerated: !!lastGeneratedData.userStats,
// hasCommitted: !!committedTrackerData.userStats,
// lastGeneratedPreview: lastGeneratedData.userStats ? lastGeneratedData.userStats.substring(0, 100) : 'null',
// committedPreview: committedTrackerData.userStats ? committedTrackerData.userStats.substring(0, 100) : 'null'
// });
if (!lastGeneratedData.userStats && !committedTrackerData.userStats) {
// Always render to the #rpg-user-stats container (mobile layout just moves it around in DOM)
@@ -200,15 +200,15 @@ export function renderUserStats() {
}
const stats = extensionSettings.userStats;
console.log('[RPG UserStats Render] Current extensionSettings.userStats:', {
health: stats.health,
satiety: stats.satiety,
energy: stats.energy,
hygiene: stats.hygiene,
arousal: stats.arousal,
mood: stats.mood,
conditions: stats.conditions
});
// console.log('[RPG UserStats Render] Current extensionSettings.userStats:', {
// health: stats.health,
// satiety: stats.satiety,
// energy: stats.energy,
// hygiene: stats.hygiene,
// arousal: stats.arousal,
// mood: stats.mood,
// conditions: stats.conditions
// });
const config = extensionSettings.trackerConfig?.userStats || {
customStats: [
{ id: 'health', name: 'Health', enabled: true },
@@ -394,13 +394,13 @@ export function renderUserStats() {
html += '</div>'; // Close rpg-stats-content
console.log('[RPG UserStats Render] Generated HTML length:', html.length);
console.log('[RPG UserStats Render] HTML preview:', html.substring(0, 300));
console.log('[RPG UserStats Render] Container exists:', !!$userStatsContainer, '$userStatsContainer length:', $userStatsContainer?.length);
// console.log('[RPG UserStats Render] Generated HTML length:', html.length);
// console.log('[RPG UserStats Render] HTML preview:', html.substring(0, 300));
// console.log('[RPG UserStats Render] Container exists:', !!$userStatsContainer, '$userStatsContainer length:', $userStatsContainer?.length);
// Always render to the #rpg-user-stats container (mobile layout just moves it around in DOM)
$userStatsContainer.html(html);
console.log('[RPG UserStats Render] ✓ HTML rendered to #rpg-user-stats container');
// console.log('[RPG UserStats Render] ✓ HTML rendered to #rpg-user-stats container');
// Add event listeners for editable stat values
$('.rpg-editable-stat').on('blur', function() {