Fix parser to support both text and emoji formats for Info Box and Present Characters trackers
This commit is contained in:
@@ -66,35 +66,42 @@ export function renderInfoBox() {
|
||||
for (const line of lines) {
|
||||
// console.log('[RPG Companion] Processing line:', line);
|
||||
|
||||
if (line.includes('🗓️:')) {
|
||||
// Support both new text format (Date:) and legacy emoji format (🗓️:)
|
||||
if (line.startsWith('Date:') || line.includes('🗓️:')) {
|
||||
// console.log('[RPG Companion] → Matched DATE');
|
||||
const dateStr = line.replace('🗓️:', '').trim();
|
||||
const dateStr = line.replace('Date:', '').replace('🗓️:', '').trim();
|
||||
// Parse format: "Weekday, Month Day, Year" or "Weekday, Month, Year"
|
||||
const dateParts = dateStr.split(',').map(p => p.trim());
|
||||
data.weekday = dateParts[0] || '';
|
||||
data.month = dateParts[1] || '';
|
||||
data.year = dateParts[2] || '';
|
||||
data.date = dateStr;
|
||||
} else if (line.includes('🌡️:')) {
|
||||
} else if (line.startsWith('Temperature:') || line.includes('🌡️:')) {
|
||||
// console.log('[RPG Companion] → Matched TEMPERATURE');
|
||||
const tempStr = line.replace('🌡️:', '').trim();
|
||||
const tempStr = line.replace('Temperature:', '').replace('🌡️:', '').trim();
|
||||
data.temperature = tempStr;
|
||||
// Extract numeric value
|
||||
const tempMatch = tempStr.match(/(-?\d+)/);
|
||||
if (tempMatch) {
|
||||
data.tempValue = parseInt(tempMatch[1]);
|
||||
}
|
||||
} else if (line.includes('🕒:')) {
|
||||
} else if (line.startsWith('Time:') || line.includes('🕒:')) {
|
||||
// console.log('[RPG Companion] → Matched TIME');
|
||||
const timeStr = line.replace('🕒:', '').trim();
|
||||
const timeStr = line.replace('Time:', '').replace('🕒:', '').trim();
|
||||
data.time = timeStr;
|
||||
// Parse "HH:MM → HH:MM" format
|
||||
const timeParts = timeStr.split('→').map(t => t.trim());
|
||||
data.timeStart = timeParts[0] || '';
|
||||
data.timeEnd = timeParts[1] || '';
|
||||
} else if (line.includes('🗺️:')) {
|
||||
} else if (line.startsWith('Location:') || line.includes('🗺️:')) {
|
||||
// console.log('[RPG Companion] → Matched LOCATION');
|
||||
data.location = line.replace('🗺️:', '').trim();
|
||||
data.location = line.replace('Location:', '').replace('🗺️:', '').trim();
|
||||
} else if (line.startsWith('Weather:')) {
|
||||
// New text format: Weather: [Emoji], [Forecast]
|
||||
const weatherStr = line.replace('Weather:', '').trim();
|
||||
const weatherParts = weatherStr.split(',').map(p => p.trim());
|
||||
data.weatherEmoji = weatherParts[0] || '';
|
||||
data.weatherForecast = weatherParts[1] || '';
|
||||
} else {
|
||||
// Check if it's a weather line
|
||||
// Since \p{Emoji} doesn't work reliably, use a simpler approach
|
||||
|
||||
@@ -71,6 +71,7 @@ export function renderThoughts() {
|
||||
// console.log('[RPG Companion] Split into lines:', lines);
|
||||
|
||||
// Parse format: [Emoji]: [Name, Status, Demeanor] | [Relationship] | [Thoughts]
|
||||
// Also supports 4-part format: [Emoji]: [Name, Status] | [Demeanor] | [Relationship] | [Thoughts]
|
||||
for (const line of lines) {
|
||||
// Skip empty lines, headers, dividers, and code fences
|
||||
if (line.trim() &&
|
||||
@@ -89,17 +90,40 @@ export function renderThoughts() {
|
||||
if (emojiMatch) {
|
||||
const emoji = emojiMatch[1].trim();
|
||||
const info = emojiMatch[2].trim();
|
||||
const relationship = parts[1].trim(); // Enemy/Neutral/Friend/Lover
|
||||
const thoughts = parts[2] ? parts[2].trim() : '';
|
||||
|
||||
// Handle both 3-part and 4-part formats
|
||||
let relationship, thoughts, traits;
|
||||
|
||||
if (parts.length === 3) {
|
||||
// 3-part format: Emoji:Name,traits | Relationship | Thoughts
|
||||
relationship = parts[1].trim();
|
||||
thoughts = parts[2].trim();
|
||||
const infoParts = info.split(',').map(p => p.trim());
|
||||
traits = infoParts.slice(1).join(', ');
|
||||
} else if (parts.length >= 4) {
|
||||
// 4-part format: Emoji:Name,traits | Demeanor | Relationship | Thoughts
|
||||
// Add the demeanor to traits and use last two parts for relationship/thoughts
|
||||
const demeanor = parts[1].trim();
|
||||
relationship = parts[2].trim();
|
||||
thoughts = parts[3].trim();
|
||||
const infoParts = info.split(',').map(p => p.trim());
|
||||
const baseTraits = infoParts.slice(1).join(', ');
|
||||
traits = baseTraits ? `${baseTraits}, ${demeanor}` : demeanor;
|
||||
} else {
|
||||
// Fallback for 2-part format
|
||||
relationship = parts[1].trim();
|
||||
thoughts = '';
|
||||
const infoParts = info.split(',').map(p => p.trim());
|
||||
traits = infoParts.slice(1).join(', ');
|
||||
}
|
||||
|
||||
// Parse name from info (first part before comma)
|
||||
const infoParts = info.split(',').map(p => p.trim());
|
||||
const name = infoParts[0] || '';
|
||||
const traits = infoParts.slice(1).join(', ');
|
||||
|
||||
if (name && name.toLowerCase() !== 'unavailable') {
|
||||
presentCharacters.push({ emoji, name, traits, relationship, thoughts });
|
||||
// console.log('[RPG Companion] Parsed character:', { name, relationship });
|
||||
// console.log('[RPG Companion] Parsed character:', { name, relationship, thoughts });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,6 +453,7 @@ export function updateChatThoughts() {
|
||||
const parts = line.split('|').map(p => p.trim());
|
||||
// console.log('[RPG Companion] Line parts:', parts);
|
||||
|
||||
// Handle both 3-part and 4-part formats
|
||||
if (parts.length >= 3) {
|
||||
const firstPart = parts[0].trim();
|
||||
const emojiMatch = firstPart.match(/^(.+?):\s*(.+)$/);
|
||||
@@ -436,7 +461,15 @@ export function updateChatThoughts() {
|
||||
if (emojiMatch) {
|
||||
const emoji = emojiMatch[1].trim();
|
||||
const info = emojiMatch[2].trim();
|
||||
const thoughts = parts[2] ? parts[2].trim() : '';
|
||||
|
||||
let thoughts;
|
||||
if (parts.length === 3) {
|
||||
// 3-part format: Emoji:Name,traits | Relationship | Thoughts
|
||||
thoughts = parts[2].trim();
|
||||
} else if (parts.length >= 4) {
|
||||
// 4-part format: Emoji:Name,traits | Demeanor | Relationship | Thoughts
|
||||
thoughts = parts[3].trim();
|
||||
}
|
||||
|
||||
const infoParts = info.split(',').map(p => p.trim());
|
||||
const name = infoParts[0] || '';
|
||||
|
||||
@@ -55,8 +55,12 @@ export function renderUserStats() {
|
||||
const html = `
|
||||
<div class="rpg-stats-content">
|
||||
<div class="rpg-stats-left">
|
||||
<div style="display: flex; gap: clamp(4px, 0.8vh, 8px); align-items: center; justify-content: center; flex-shrink: 0;">
|
||||
<div class="rpg-user-info-row">
|
||||
<img src="${userPortrait}" alt="${userName}" class="rpg-user-portrait" onerror="this.style.opacity='0.5';this.onerror=null;" />
|
||||
<span class="rpg-user-name">${userName}</span>
|
||||
<span style="opacity: 0.5;">|</span>
|
||||
<span class="rpg-level-label">LVL</span>
|
||||
<span class="rpg-level-value rpg-editable" contenteditable="true" data-field="level" title="Click to edit level">${extensionSettings.level}</span>
|
||||
</div>
|
||||
<div class="rpg-stats-grid">
|
||||
<div class="rpg-stat-row">
|
||||
@@ -236,4 +240,30 @@ export function renderUserStats() {
|
||||
saveChatData();
|
||||
updateMessageSwipeData();
|
||||
});
|
||||
|
||||
// Add event listener for level editing
|
||||
$('.rpg-level-value.rpg-editable').on('blur', function() {
|
||||
let value = parseInt($(this).text().trim());
|
||||
if (isNaN(value) || value < 1) {
|
||||
value = 1;
|
||||
}
|
||||
// Set reasonable max level
|
||||
value = Math.min(100, value);
|
||||
|
||||
extensionSettings.level = value;
|
||||
saveSettings();
|
||||
saveChatData();
|
||||
updateMessageSwipeData();
|
||||
|
||||
// Re-render to update the display
|
||||
renderUserStats();
|
||||
});
|
||||
|
||||
// Prevent line breaks in level field
|
||||
$('.rpg-level-value.rpg-editable').on('keydown', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
$(this).blur();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user