v3.6.0 - Bug fixes and number display mode for stats

- Fixed custom status fields not being sent to prompts or parsed
- Fixed date format selection not working beyond default format
- Fixed widget text overflow issues with minimal scrollbars
- Added ability to display stats as numbers with custom max values instead of percentages
- Enabled desktop strip widgets by default
- Removed icon from Desktop Collapsed Strip Widgets heading
This commit is contained in:
Spicy_Marinara
2026-01-13 13:52:18 +01:00
parent ce668c4793
commit e8edc42164
12 changed files with 340 additions and 64 deletions
+26 -4
View File
@@ -28,6 +28,7 @@ export function buildUserStatsJSONInstruction() {
const trackerConfig = extensionSettings.trackerConfig;
const userStatsConfig = trackerConfig?.userStats;
const enabledStats = userStatsConfig?.customStats?.filter(s => s && s.enabled && s.name) || [];
const displayMode = userStatsConfig?.statsDisplayMode || 'percentage';
let instruction = '{\n';
instruction += ' "stats": [\n';
@@ -36,7 +37,12 @@ export function buildUserStatsJSONInstruction() {
for (let i = 0; i < enabledStats.length; i++) {
const stat = enabledStats[i];
const comma = i < enabledStats.length - 1 ? ',' : '';
instruction += ` {"id": "${stat.id}", "name": "${stat.name}", "value": X}${comma}\n`;
if (displayMode === 'number') {
const maxValue = stat.maxValue || 100;
instruction += ` {"id": "${stat.id}", "name": "${stat.name}", "value": X}${comma} // 0 to ${maxValue}\n`;
} else {
instruction += ` {"id": "${stat.id}", "name": "${stat.name}", "value": X}${comma} // 0 to 100 (percentage)\n`;
}
}
instruction += ' ],\n';
@@ -45,9 +51,24 @@ export function buildUserStatsJSONInstruction() {
if (userStatsConfig?.statusSection?.enabled) {
instruction += ' "status": {\n';
if (userStatsConfig.statusSection.showMoodEmoji) {
instruction += ' "mood": "Mood Emoji",\n';
instruction += ' "mood": "Mood Emoji"';
}
// Add all custom status fields
const customFields = userStatsConfig.statusSection.customFields || [];
if (customFields.length > 0) {
for (let i = 0; i < customFields.length; i++) {
const fieldName = customFields[i].toLowerCase();
const fieldKey = toSnakeCase(fieldName);
const comma = (i === customFields.length - 1 && !userStatsConfig.statusSection.showMoodEmoji) ? '' : (userStatsConfig.statusSection.showMoodEmoji || i < customFields.length - 1 ? ',\n' : '\n');
if (i === 0 && userStatsConfig.statusSection.showMoodEmoji) {
instruction += ',\n';
}
instruction += ` "${fieldKey}": "[${fieldName}1, ${fieldName}2]"${comma}`;
}
}
if (!userStatsConfig.statusSection.showMoodEmoji && customFields.length > 0) {
instruction += '\n';
}
instruction += ' "conditions": "[Condition1, Condition2]"\n';
instruction += ' },\n';
}
@@ -105,7 +126,8 @@ export function buildInfoBoxJSONInstruction() {
let hasFields = false;
if (widgets.date?.enabled) {
instruction += ' "date": {"value": "Weekday, Month, Year"}';
const dateFormat = widgets.date.format || 'Weekday, Month, Year';
instruction += ` "date": {"value": "${dateFormat}"}`;
hasFields = true;
}
+34 -8
View File
@@ -547,9 +547,15 @@ export function parseUserStats(statsText) {
extensionSettings.userStats.mood = statsData.status.mood;
// console.log('[RPG Parser] ✓ Set mood =', statsData.status.mood);
}
if (statsData.status.conditions) {
extensionSettings.userStats.conditions = statsData.status.conditions;
// console.log('[RPG Parser] ✓ Set conditions =', statsData.status.conditions);
// Extract all custom status fields
const trackerConfig = extensionSettings.trackerConfig;
const customFields = trackerConfig?.userStats?.statusSection?.customFields || [];
for (const fieldName of customFields) {
const fieldKey = fieldName.toLowerCase();
if (statsData.status[fieldKey]) {
extensionSettings.userStats[fieldKey] = statsData.status[fieldKey];
// console.log(`[RPG Parser] ✓ Set ${fieldKey} =`, statsData.status[fieldKey]);
}
}
}
@@ -679,6 +685,7 @@ export function parseUserStats(statsText) {
const statusConfig = trackerConfig?.userStats?.statusSection;
if (statusConfig?.enabled) {
let moodMatch = null;
const customFields = statusConfig.customFields || [];
// Try Status: format
const statusMatch = statsText.match(/Status:\s*(.+)/i);
@@ -691,14 +698,30 @@ export function parseUserStats(statsText) {
if (emoji) {
extensionSettings.userStats.mood = emoji;
// Remaining text contains custom status fields
if (text) {
extensionSettings.userStats.conditions = text;
if (text && customFields.length > 0) {
// For first custom field, use the remaining text
const firstFieldKey = customFields[0].toLowerCase();
extensionSettings.userStats[firstFieldKey] = text;
}
moodMatch = true;
}
} else {
// No mood emoji, whole status is conditions
extensionSettings.userStats.conditions = statusContent;
// No mood emoji, whole status goes to first custom field
if (customFields.length > 0) {
const firstFieldKey = customFields[0].toLowerCase();
extensionSettings.userStats[firstFieldKey] = statusContent;
}
moodMatch = true;
}
}
// Try to extract individual custom status fields by name
for (const fieldName of customFields) {
const fieldKey = fieldName.toLowerCase();
const fieldRegex = new RegExp(`${fieldName}:\\s*(.+?)(?:,|$)`, 'i');
const fieldMatch = statsText.match(fieldRegex);
if (fieldMatch) {
extensionSettings.userStats[fieldKey] = fieldMatch[1].trim();
moodMatch = true;
}
}
@@ -706,7 +729,10 @@ export function parseUserStats(statsText) {
debugLog('[RPG Parser] Status match:', {
found: !!moodMatch,
mood: extensionSettings.userStats.mood,
conditions: extensionSettings.userStats.conditions
customFields: customFields.map(f => ({
name: f,
value: extensionSettings.userStats[f.toLowerCase()]
}))
});
}
+26 -7
View File
@@ -485,11 +485,22 @@ function formatTrackerDataForContext(jsonData, trackerType, userName) {
// Handle common object formats
if (field && typeof field === 'object') {
// Status object: {mood, conditions}
if ('mood' in field && 'conditions' in field) {
// Status object: {mood, [customFields...]}
if ('mood' in field) {
const statusParts = [];
const mood = getValue(field.mood);
const conditions = getValue(field.conditions);
return `${mood} - ${conditions}`;
if (mood) statusParts.push(mood);
// Add all other status fields (custom fields)
for (const [key, value] of Object.entries(field)) {
if (key !== 'mood') {
const fieldValue = getValue(value);
if (fieldValue && fieldValue !== 'None') {
statusParts.push(fieldValue);
}
}
}
return statusParts.join(' - ');
}
// Skill/item/quest objects: {name}, {title}, {name, quantity}
@@ -830,9 +841,17 @@ export function formatHistoricalTrackerData(trackerData, trackerConfig, userName
// Status section
if (shouldInclude(userStatsConfig.statusSection) && userStatsData.status) {
const mood = getValue(userStatsData.status.mood || userStatsData.status);
const conditions = getValue(userStatsData.status.conditions);
if (mood) statsFormatted += `Mood: ${mood}, `;
if (conditions && conditions !== 'None') statsFormatted += `Conditions: ${conditions}, `;
if (mood && userStatsConfig.statusSection.showMoodEmoji) statsFormatted += `Mood: ${mood}, `;
// Add all custom status fields
const customFields = userStatsConfig.statusSection.customFields || [];
for (const fieldName of customFields) {
const fieldKey = fieldName.toLowerCase();
const fieldValue = getValue(userStatsData.status[fieldKey]);
if (fieldValue && fieldValue !== 'None') {
statsFormatted += `${fieldName}: ${fieldValue}, `;
}
}
}
// Skills section