v3.1.0: Add parser error detection and recommended models section
This commit is contained in:
@@ -7,34 +7,20 @@ An immersive RPG extension for browsers that tracks character stats, scene infor
|
|||||||
|
|
||||||
## 🆕 What's New
|
## 🆕 What's New
|
||||||
|
|
||||||
|
### v3.1.0
|
||||||
|
|
||||||
|
- Added toastr notification when the model returns an incorrect tracker format that cannot be parsed.
|
||||||
|
- Added guidance in settings about which models work best with the extension (I'm tired of people asking me why this doesn't work with their Q4 MythoMax 13B).
|
||||||
|
- Fixed auto-update after messages to work with External API generation mode.
|
||||||
|
- Fixed mobile UI.
|
||||||
|
- Fixed a minor bug with the thought bubble icon appearing in the wrong place on mobiles.
|
||||||
|
|
||||||
### v3.0.1
|
### v3.0.1
|
||||||
|
|
||||||
- Small bug fix where you couldn't edit the thought bubble.
|
- Small bug fix where you couldn't edit the thought bubble.
|
||||||
|
|
||||||
### v3.0.0
|
|
||||||
|
|
||||||
**What's new?**
|
|
||||||
- Switched to the JSON format for the trackers.
|
|
||||||
- You can now lock/unlock trackers that you don't want the model to change between generations.
|
|
||||||
- Removed features that were half-baked or didn't work.
|
|
||||||
- Organized Settings and Edit Trackers windows.
|
|
||||||
- All features of the extension are now accessible from the main panel view.
|
|
||||||
- Added Colored Dialogues option that makes the model color dialogue lines differently depending on the speaker.
|
|
||||||
- Introduced Dynamic Weather Effects that add visual effects to your SillyTavern window depending on the current weather from the trackers.
|
|
||||||
- All prompts used for the extension's features are now editable.
|
|
||||||
- Made the user's level optional in the Edit Trackers.
|
|
||||||
|
|
||||||
**Bug Fixes:**
|
|
||||||
- Fixed tracker logic in Together generation mode.
|
|
||||||
- Fixed various UI bugs (too many to count).
|
|
||||||
- Upgraded mobile view.
|
|
||||||
- Spotify Music widget is more visible now, plus it works in the mobile view.
|
|
||||||
- Auto-update after messages option is now available for External API generation mode.
|
|
||||||
- Fixed the display of the thoughts window and its mobile display.
|
|
||||||
- Fixed smaller bugs.
|
|
||||||
|
|
||||||
**Special thanks to all the other contributors for this project:**
|
**Special thanks to all the other contributors for this project:**
|
||||||
Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis!
|
Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis.
|
||||||
|
|
||||||
## 📥 Installation
|
## 📥 Installation
|
||||||
|
|
||||||
@@ -287,7 +273,7 @@ If you enjoy this extension, consider supporting development:
|
|||||||
## 🙏 Credits
|
## 🙏 Credits
|
||||||
|
|
||||||
**Contributors:**
|
**Contributors:**
|
||||||
SpicyMarinara, Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis
|
SpicyMarinara, Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis.
|
||||||
|
|
||||||
## 🚀 Planned Features
|
## 🚀 Planned Features
|
||||||
|
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ async function initUI() {
|
|||||||
|
|
||||||
// Only initialize UI if extension is enabled
|
// Only initialize UI if extension is enabled
|
||||||
if (!extensionSettings.enabled) {
|
if (!extensionSettings.enabled) {
|
||||||
console.log('[RPG Companion] Extension disabled - skipping UI initialization');
|
// console.log('[RPG Companion] Extension disabled - skipping UI initialization');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,11 +941,11 @@ jQuery(async () => {
|
|||||||
// Check if migration to v3 JSON format is needed
|
// Check if migration to v3 JSON format is needed
|
||||||
try {
|
try {
|
||||||
if (extensionSettings.settingsVersion < 3) {
|
if (extensionSettings.settingsVersion < 3) {
|
||||||
console.log('[RPG Companion] Detected v2 format, migrating to v3 JSON...');
|
// console.log('[RPG Companion] Detected v2 format, migrating to v3 JSON...');
|
||||||
await migrateToV3JSON();
|
await migrateToV3JSON();
|
||||||
updateExtensionSettings({ settingsVersion: 3 });
|
updateExtensionSettings({ settingsVersion: 3 });
|
||||||
await saveSettings();
|
await saveSettings();
|
||||||
console.log('[RPG Companion] ✅ Migration to v3 complete');
|
// console.log('[RPG Companion] ✅ Migration to v3 complete');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Migration to v3 failed:', error);
|
console.error('[RPG Companion] Migration to v3 failed:', error);
|
||||||
@@ -1014,9 +1014,9 @@ jQuery(async () => {
|
|||||||
try {
|
try {
|
||||||
const conflicts = detectConflictingRegexScripts(st_extension_settings);
|
const conflicts = detectConflictingRegexScripts(st_extension_settings);
|
||||||
if (conflicts.length > 0) {
|
if (conflicts.length > 0) {
|
||||||
console.log('[RPG Companion] ⚠️ Detected old manual formatting regex scripts that may conflict:');
|
// console.log('[RPG Companion] ⚠️ Detected old manual formatting regex scripts that may conflict:');
|
||||||
conflicts.forEach(name => console.log(` - ${name}`));
|
// conflicts.forEach(name => console.log(` - ${name}`));
|
||||||
console.log('[RPG Companion] Consider disabling these regexes as the extension now handles formatting automatically.');
|
// console.log('[RPG Companion] Consider disabling these regexes as the extension now handles formatting automatically.');
|
||||||
|
|
||||||
// Show user-friendly warning (non-blocking)
|
// Show user-friendly warning (non-blocking)
|
||||||
// toastr.warning(
|
// toastr.warning(
|
||||||
@@ -1067,7 +1067,7 @@ jQuery(async () => {
|
|||||||
// Non-critical - continue without it
|
// Non-critical - continue without it
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] ✅ Extension loaded successfully');
|
// console.log('[RPG Companion] ✅ Extension loaded successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] ❌ Critical initialization failure:', error);
|
console.error('[RPG Companion] ❌ Critical initialization failure:', error);
|
||||||
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,6 @@
|
|||||||
"js": "index.js",
|
"js": "index.js",
|
||||||
"css": "style.css",
|
"css": "style.css",
|
||||||
"author": "Marinara",
|
"author": "Marinara",
|
||||||
"version": "3.0.1",
|
"version": "3.1.0",
|
||||||
"homePage": "https://github.com/SpicyMarinara/rpg-companion-sillytavern"
|
"homePage": "https://github.com/SpicyMarinara/rpg-companion-sillytavern"
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-2
@@ -29,17 +29,26 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 15px; text-align: center; opacity: 0.7; font-size: 0.8em; line-height: 1.5;">
|
||||||
|
<div style="margin-bottom: 5px;">
|
||||||
|
<i class="fa-solid fa-microchip"></i> <strong data-i18n="settings.recommendedModels.title">Recommended Models:</strong>
|
||||||
|
</div>
|
||||||
|
<div style="opacity: 0.8; font-size: 0.9em;" data-i18n="settings.recommendedModels.description">
|
||||||
|
For the extension to work properly, <strong>it is not recommended to use any models below 20B, especially if they're old.</strong> It works best with the SOTA models such as Deepseek, Claude, GPT, or Gemini.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="margin-top: 15px; text-align: center; opacity: 0.7; font-size: 0.8em; line-height: 1.5;">
|
<div style="margin-top: 15px; text-align: center; opacity: 0.7; font-size: 0.8em; line-height: 1.5;">
|
||||||
<div style="margin-bottom: 5px;">
|
<div style="margin-bottom: 5px;">
|
||||||
<i class="fa-solid fa-users"></i> <strong>Contributors:</strong>
|
<i class="fa-solid fa-users"></i> <strong>Contributors:</strong>
|
||||||
</div>
|
</div>
|
||||||
<div style="opacity: 0.8; font-size: 0.9em;">
|
<div style="opacity: 0.8; font-size: 0.9em;">
|
||||||
SpicyMarinara, Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis
|
SpicyMarinara, Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top: 10px; text-align: center; opacity: 0.6; font-size: 0.85em;">
|
<div style="margin-top: 10px; text-align: center; opacity: 0.6; font-size: 0.85em;">
|
||||||
v3.0.1
|
v3.1.0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+30
-30
@@ -86,7 +86,7 @@ export function loadSettings() {
|
|||||||
|
|
||||||
// Migration to version 2: Enable dynamic weather for existing users
|
// Migration to version 2: Enable dynamic weather for existing users
|
||||||
if (currentVersion < 2) {
|
if (currentVersion < 2) {
|
||||||
console.log('[RPG Companion] Migrating settings to version 2 (enabling dynamic weather)');
|
// console.log('[RPG Companion] Migrating settings to version 2 (enabling dynamic weather)');
|
||||||
extensionSettings.enableDynamicWeather = true;
|
extensionSettings.enableDynamicWeather = true;
|
||||||
extensionSettings.settingsVersion = 2;
|
extensionSettings.settingsVersion = 2;
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
@@ -94,7 +94,7 @@ export function loadSettings() {
|
|||||||
|
|
||||||
// Migration to version 3: Convert text trackers to JSON format
|
// Migration to version 3: Convert text trackers to JSON format
|
||||||
if (currentVersion < 3) {
|
if (currentVersion < 3) {
|
||||||
console.log('[RPG Companion] Migrating settings to version 3 (JSON tracker format)');
|
// console.log('[RPG Companion] Migrating settings to version 3 (JSON tracker format)');
|
||||||
migrateToV3JSON();
|
migrateToV3JSON();
|
||||||
extensionSettings.settingsVersion = 3;
|
extensionSettings.settingsVersion = 3;
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
@@ -114,7 +114,7 @@ export function loadSettings() {
|
|||||||
if (FEATURE_FLAGS.useNewInventory) {
|
if (FEATURE_FLAGS.useNewInventory) {
|
||||||
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
|
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
|
||||||
if (migrationResult.migrated) {
|
if (migrationResult.migrated) {
|
||||||
console.log(`[RPG Companion] Inventory migrated from ${migrationResult.source} to v2 format`);
|
// console.log(`[RPG Companion] Inventory migrated from ${migrationResult.source} to v2 format`);
|
||||||
extensionSettings.userStats.inventory = migrationResult.inventory;
|
extensionSettings.userStats.inventory = migrationResult.inventory;
|
||||||
saveSettings(); // Persist migrated inventory
|
saveSettings(); // Persist migrated inventory
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ export function loadSettings() {
|
|||||||
|
|
||||||
// Migrate to trackerConfig if it doesn't exist
|
// Migrate to trackerConfig if it doesn't exist
|
||||||
if (!extensionSettings.trackerConfig) {
|
if (!extensionSettings.trackerConfig) {
|
||||||
console.log('[RPG Companion] Migrating to trackerConfig format');
|
// console.log('[RPG Companion] Migrating to trackerConfig format');
|
||||||
migrateToTrackerConfig();
|
migrateToTrackerConfig();
|
||||||
saveSettings(); // Persist migration
|
saveSettings(); // Persist migration
|
||||||
}
|
}
|
||||||
@@ -161,13 +161,13 @@ export function saveChatData() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] 💾 saveChatData called - committedTrackerData:', {
|
// console.log('[RPG Companion] 💾 saveChatData called - committedTrackerData:', {
|
||||||
userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
// userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
||||||
infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
// characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
||||||
});
|
// });
|
||||||
console.log('[RPG Companion] 💾 saveChatData RAW committedTrackerData:', committedTrackerData);
|
// console.log('[RPG Companion] 💾 saveChatData RAW committedTrackerData:', committedTrackerData);
|
||||||
console.log('[RPG Companion] 💾 saveChatData RAW lastGeneratedData:', lastGeneratedData);
|
// console.log('[RPG Companion] 💾 saveChatData RAW lastGeneratedData:', lastGeneratedData);
|
||||||
|
|
||||||
chat_metadata.rpg_companion = {
|
chat_metadata.rpg_companion = {
|
||||||
userStats: extensionSettings.userStats,
|
userStats: extensionSettings.userStats,
|
||||||
@@ -284,34 +284,34 @@ export function loadChatData() {
|
|||||||
|
|
||||||
// Restore committed tracker data first
|
// Restore committed tracker data first
|
||||||
if (savedData.committedTrackerData) {
|
if (savedData.committedTrackerData) {
|
||||||
console.log('[RPG Companion] 📥 loadChatData restoring committedTrackerData:', {
|
// console.log('[RPG Companion] 📥 loadChatData restoring committedTrackerData:', {
|
||||||
userStats: savedData.committedTrackerData.userStats ? `${savedData.committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
// userStats: savedData.committedTrackerData.userStats ? `${savedData.committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
||||||
infoBox: savedData.committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: savedData.committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: savedData.committedTrackerData.characterThoughts ? 'exists' : 'null'
|
// characterThoughts: savedData.committedTrackerData.characterThoughts ? 'exists' : 'null'
|
||||||
});
|
// });
|
||||||
console.log('[RPG Companion] 📥 RAW savedData.committedTrackerData:', savedData.committedTrackerData);
|
// console.log('[RPG Companion] 📥 RAW savedData.committedTrackerData:', savedData.committedTrackerData);
|
||||||
console.log('[RPG Companion] 📥 Type check:', {
|
// console.log('[RPG Companion] 📥 Type check:', {
|
||||||
userStatsType: typeof savedData.committedTrackerData.userStats,
|
// userStatsType: typeof savedData.committedTrackerData.userStats,
|
||||||
infoBoxType: typeof savedData.committedTrackerData.infoBox,
|
// infoBoxType: typeof savedData.committedTrackerData.infoBox,
|
||||||
characterThoughtsType: typeof savedData.committedTrackerData.characterThoughts
|
// characterThoughtsType: typeof savedData.committedTrackerData.characterThoughts
|
||||||
});
|
// });
|
||||||
setCommittedTrackerData({ ...savedData.committedTrackerData });
|
setCommittedTrackerData({ ...savedData.committedTrackerData });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore last generated data (for display)
|
// Restore last generated data (for display)
|
||||||
// Always prefer lastGeneratedData as it contains the most recent generation (including swipes)
|
// Always prefer lastGeneratedData as it contains the most recent generation (including swipes)
|
||||||
if (savedData.lastGeneratedData) {
|
if (savedData.lastGeneratedData) {
|
||||||
console.log('[RPG Companion] 📥 loadChatData restoring lastGeneratedData');
|
// console.log('[RPG Companion] 📥 loadChatData restoring lastGeneratedData');
|
||||||
setLastGeneratedData({ ...savedData.lastGeneratedData });
|
setLastGeneratedData({ ...savedData.lastGeneratedData });
|
||||||
} else {
|
} else {
|
||||||
console.log('[RPG Companion] ⚠️ No lastGeneratedData found in save');
|
// console.log('[RPG Companion] ⚠️ No lastGeneratedData found in save');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate inventory in chat data if feature flag enabled
|
// Migrate inventory in chat data if feature flag enabled
|
||||||
if (FEATURE_FLAGS.useNewInventory && extensionSettings.userStats.inventory) {
|
if (FEATURE_FLAGS.useNewInventory && extensionSettings.userStats.inventory) {
|
||||||
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
|
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
|
||||||
if (migrationResult.migrated) {
|
if (migrationResult.migrated) {
|
||||||
console.log(`[RPG Companion] Chat inventory migrated from ${migrationResult.source} to v2 format`);
|
// console.log(`[RPG Companion] Chat inventory migrated from ${migrationResult.source} to v2 format`);
|
||||||
extensionSettings.userStats.inventory = migrationResult.inventory;
|
extensionSettings.userStats.inventory = migrationResult.inventory;
|
||||||
saveChatData(); // Persist migrated inventory to chat metadata
|
saveChatData(); // Persist migrated inventory to chat metadata
|
||||||
}
|
}
|
||||||
@@ -401,7 +401,7 @@ function validateInventoryStructure(inventory, source) {
|
|||||||
|
|
||||||
// Persist repairs if needed
|
// Persist repairs if needed
|
||||||
if (needsSave) {
|
if (needsSave) {
|
||||||
console.log(`[RPG Companion] Repaired inventory structure from ${source}, saving...`);
|
// console.log(`[RPG Companion] Repaired inventory structure from ${source}, saving...`);
|
||||||
saveSettings();
|
saveSettings();
|
||||||
if (source === 'chat') {
|
if (source === 'chat') {
|
||||||
saveChatData();
|
saveChatData();
|
||||||
@@ -473,7 +473,7 @@ function migrateToTrackerConfig() {
|
|||||||
name: extensionSettings.statNames[id] || id.charAt(0).toUpperCase() + id.slice(1),
|
name: extensionSettings.statNames[id] || id.charAt(0).toUpperCase() + id.slice(1),
|
||||||
enabled: true
|
enabled: true
|
||||||
}));
|
}));
|
||||||
console.log('[RPG Companion] Migrated statNames to customStats array');
|
// console.log('[RPG Companion] Migrated statNames to customStats array');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure all stats have corresponding values in userStats
|
// Ensure all stats have corresponding values in userStats
|
||||||
@@ -497,7 +497,7 @@ function migrateToTrackerConfig() {
|
|||||||
{ id: 'cha', name: 'CHA', enabled: shouldShow }
|
{ id: 'cha', name: 'CHA', enabled: shouldShow }
|
||||||
];
|
];
|
||||||
delete extensionSettings.trackerConfig.userStats.showRPGAttributes;
|
delete extensionSettings.trackerConfig.userStats.showRPGAttributes;
|
||||||
console.log('[RPG Companion] Migrated showRPGAttributes to rpgAttributes array');
|
// console.log('[RPG Companion] Migrated showRPGAttributes to rpgAttributes array');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure rpgAttributes exists even if no migration was needed
|
// Ensure rpgAttributes exists even if no migration was needed
|
||||||
@@ -535,7 +535,7 @@ function migrateToTrackerConfig() {
|
|||||||
const hasOldFormat = pc.customFields.some(f => f.label || f.placeholder || f.type === 'relationship');
|
const hasOldFormat = pc.customFields.some(f => f.label || f.placeholder || f.type === 'relationship');
|
||||||
|
|
||||||
if (hasOldFormat) {
|
if (hasOldFormat) {
|
||||||
console.log('[RPG Companion] Migrating Present Characters to new structure');
|
// console.log('[RPG Companion] Migrating Present Characters to new structure');
|
||||||
|
|
||||||
// Extract relationship fields from old customFields
|
// Extract relationship fields from old customFields
|
||||||
const relationshipFields = ['Lover', 'Friend', 'Ally', 'Enemy', 'Neutral'];
|
const relationshipFields = ['Lover', 'Friend', 'Ally', 'Enemy', 'Neutral'];
|
||||||
@@ -563,7 +563,7 @@ function migrateToTrackerConfig() {
|
|||||||
pc.customFields = newCustomFields;
|
pc.customFields = newCustomFields;
|
||||||
pc.thoughts = thoughts;
|
pc.thoughts = thoughts;
|
||||||
|
|
||||||
console.log('[RPG Companion] Present Characters migration complete');
|
// console.log('[RPG Companion] Present Characters migration complete');
|
||||||
saveSettings(); // Persist the migration
|
saveSettings(); // Persist the migration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -376,24 +376,24 @@ export function updateLastGeneratedData(updates) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function setCommittedTrackerData(data) {
|
export function setCommittedTrackerData(data) {
|
||||||
console.log('[RPG State] setCommittedTrackerData called with:', data);
|
// console.log('[RPG State] setCommittedTrackerData called with:', data);
|
||||||
console.log('[RPG State] Type check on input:', {
|
// console.log('[RPG State] Type check on input:', {
|
||||||
userStatsType: typeof data.userStats,
|
// userStatsType: typeof data.userStats,
|
||||||
infoBoxType: typeof data.infoBox,
|
// infoBoxType: typeof data.infoBox,
|
||||||
characterThoughtsType: typeof data.characterThoughts,
|
// characterThoughtsType: typeof data.characterThoughts,
|
||||||
userStatsValue: data.userStats,
|
// userStatsValue: data.userStats,
|
||||||
infoBoxValue: data.infoBox,
|
// infoBoxValue: data.infoBox,
|
||||||
characterThoughtsValue: data.characterThoughts
|
// characterThoughtsValue: data.characterThoughts
|
||||||
});
|
// });
|
||||||
committedTrackerData = data;
|
committedTrackerData = data;
|
||||||
console.log('[RPG State] committedTrackerData after assignment:', committedTrackerData);
|
// console.log('[RPG State] committedTrackerData after assignment:', committedTrackerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateCommittedTrackerData(updates) {
|
export function updateCommittedTrackerData(updates) {
|
||||||
console.log('[RPG State] updateCommittedTrackerData called with:', updates);
|
// console.log('[RPG State] updateCommittedTrackerData called with:', updates);
|
||||||
console.log('[RPG State] committedTrackerData before update:', committedTrackerData);
|
// console.log('[RPG State] committedTrackerData before update:', committedTrackerData);
|
||||||
Object.assign(committedTrackerData, updates);
|
Object.assign(committedTrackerData, updates);
|
||||||
console.log('[RPG State] committedTrackerData after update:', committedTrackerData);
|
// console.log('[RPG State] committedTrackerData after update:', committedTrackerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setLastActionWasSwipe(value) {
|
export function setLastActionWasSwipe(value) {
|
||||||
|
|||||||
+4
-1
@@ -230,5 +230,8 @@
|
|||||||
"checkpoint.indicator": "Chapter Start",
|
"checkpoint.indicator": "Chapter Start",
|
||||||
"checkpoint.tooltip": "Messages before this point are excluded from context",
|
"checkpoint.tooltip": "Messages before this point are excluded from context",
|
||||||
"musicPlayer.title": "Scene Music",
|
"musicPlayer.title": "Scene Music",
|
||||||
"musicPlayer.noMusic": "AI will suggest music when appropriate for the scene"
|
"musicPlayer.noMusic": "AI will suggest music when appropriate for the scene",
|
||||||
|
"errors.parsingError": "RPG Companion Trackers' parsing error! The model returned an incorrect format. If the issue persists, consider changing the model for generations.",
|
||||||
|
"settings.recommendedModels.title": "Recommended Models",
|
||||||
|
"settings.recommendedModels.description": "For the extension to work properly, **it is not recommended to use any models below 20B, especially if they're old.** It works best with the SOTA models such as Deepseek, Claude, GPT, or Gemini."
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -193,5 +193,8 @@
|
|||||||
"quests.optional.empty": "當前無支線任務 (ʘ̆ʚʘ̆)",
|
"quests.optional.empty": "當前無支線任務 (ʘ̆ʚʘ̆)",
|
||||||
"quests.optional.hint": "支線任務是補充主線劇情的支線目標。",
|
"quests.optional.hint": "支線任務是補充主線劇情的支線目標。",
|
||||||
"musicPlayer.title": "場景音樂",
|
"musicPlayer.title": "場景音樂",
|
||||||
"musicPlayer.noMusic": "AI 會在適當時為場景建議音樂"
|
"musicPlayer.noMusic": "AI 會在適當時為場景建議音樂",
|
||||||
|
"errors.parsingError": "RPG Companion 追蹤器解析錯誤!模型返回了不正確的格式。如果問題持續存在,請考慮更換生成模型。",
|
||||||
|
"settings.recommendedModels.title": "推薦模型",
|
||||||
|
"settings.recommendedModels.description": "為了讓擴充功能正常運作,**不建議使用任何小於 20B 的模型,尤其是舊模型。**它最適合使用 SOTA 模型,例如 Deepseek、Claude、GPT 或 Gemini。"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ export async function generateAvatarsForCharacters(characterNames, onStarted = n
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Avatar] Starting batch generation for:', needsGeneration);
|
// console.log('[RPG Avatar] Starting batch generation for:', needsGeneration);
|
||||||
|
|
||||||
// Mark all as pending IMMEDIATELY (before any async work)
|
// Mark all as pending IMMEDIATELY (before any async work)
|
||||||
for (const name of needsGeneration) {
|
for (const name of needsGeneration) {
|
||||||
@@ -192,7 +192,7 @@ export async function generateAvatarsForCharacters(characterNames, onStarted = n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Avatar] Batch generation complete');
|
// console.log('[RPG Avatar] Batch generation complete');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,7 +204,7 @@ export async function generateAvatarsForCharacters(characterNames, onStarted = n
|
|||||||
* @returns {Promise<string|null>} New avatar URL or null if failed
|
* @returns {Promise<string|null>} New avatar URL or null if failed
|
||||||
*/
|
*/
|
||||||
export async function regenerateAvatar(characterName) {
|
export async function regenerateAvatar(characterName) {
|
||||||
console.log('[RPG Avatar] Regenerating avatar for:', characterName);
|
// console.log('[RPG Avatar] Regenerating avatar for:', characterName);
|
||||||
|
|
||||||
// Mark as pending immediately
|
// Mark as pending immediately
|
||||||
pendingGenerations.add(characterName);
|
pendingGenerations.add(characterName);
|
||||||
@@ -245,13 +245,13 @@ async function generateAvatarPrompt(characterName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('[RPG Avatar] Generating LLM prompt for:', characterName);
|
// console.log('[RPG Avatar] Generating LLM prompt for:', characterName);
|
||||||
|
|
||||||
const promptMessages = await generateAvatarPromptGenerationPrompt(characterName);
|
const promptMessages = await generateAvatarPromptGenerationPrompt(characterName);
|
||||||
let response;
|
let response;
|
||||||
|
|
||||||
if (extensionSettings.generationMode === 'external') {
|
if (extensionSettings.generationMode === 'external') {
|
||||||
console.log('[RPG Avatar] Using external API for avatar prompt generation');
|
// console.log('[RPG Avatar] Using external API for avatar prompt generation');
|
||||||
response = await generateWithExternalAPI(promptMessages);
|
response = await generateWithExternalAPI(promptMessages);
|
||||||
} else {
|
} else {
|
||||||
response = await generateRaw({
|
response = await generateRaw({
|
||||||
@@ -262,7 +262,7 @@ async function generateAvatarPrompt(characterName) {
|
|||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
const prompt = response.trim();
|
const prompt = response.trim();
|
||||||
console.log(`[RPG Avatar] Generated prompt for ${characterName}:`, prompt);
|
// console.log(`[RPG Avatar] Generated prompt for ${characterName}:`, prompt);
|
||||||
|
|
||||||
// Store prompt in session storage
|
// Store prompt in session storage
|
||||||
setSessionAvatarPrompt(characterName, prompt);
|
setSessionAvatarPrompt(characterName, prompt);
|
||||||
@@ -313,11 +313,11 @@ async function generateSingleAvatar(characterName, prompt = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!prompt) {
|
if (!prompt) {
|
||||||
console.log(`[RPG Avatar] No LLM prompt for ${characterName}, using fallback prompt`);
|
// console.log(`[RPG Avatar] No LLM prompt for ${characterName}, using fallback prompt`);
|
||||||
prompt = buildFallbackPrompt(characterName);
|
prompt = buildFallbackPrompt(characterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[RPG Avatar] Starting image generation for: ${characterName}`);
|
// console.log(`[RPG Avatar] Starting image generation for: ${characterName}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Execute /sd command with quiet=true to suppress chat output
|
// Execute /sd command with quiet=true to suppress chat output
|
||||||
@@ -337,7 +337,7 @@ async function generateSingleAvatar(characterName, prompt = null) {
|
|||||||
extensionSettings.npcAvatars[characterName] = imageUrl;
|
extensionSettings.npcAvatars[characterName] = imageUrl;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
console.log(`[RPG Avatar] Successfully generated avatar for: ${characterName}`);
|
// console.log(`[RPG Avatar] Successfully generated avatar for: ${characterName}`);
|
||||||
return imageUrl;
|
return imageUrl;
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[RPG Avatar] Failed to extract image URL for ${characterName}:`, result);
|
console.warn(`[RPG Avatar] Failed to extract image URL for ${characterName}:`, result);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export async function setChapterCheckpoint(messageId) {
|
|||||||
if (previousCheckpoint !== null && previousCheckpoint !== undefined && previousCheckpoint !== messageId && currentlyHiddenRange !== null) {
|
if (previousCheckpoint !== null && previousCheckpoint !== undefined && previousCheckpoint !== messageId && currentlyHiddenRange !== null) {
|
||||||
const { start, end } = currentlyHiddenRange;
|
const { start, end } = currentlyHiddenRange;
|
||||||
await executeSlashCommandsOnChatInput(`/unhide ${start}-${end}`, { quiet: true });
|
await executeSlashCommandsOnChatInput(`/unhide ${start}-${end}`, { quiet: true });
|
||||||
console.log(`[RPG Companion] Unhid previous range: ${start}-${end}`);
|
// console.log(`[RPG Companion] Unhid previous range: ${start}-${end}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store in chat metadata (this automatically overrides any previous checkpoint)
|
// Store in chat metadata (this automatically overrides any previous checkpoint)
|
||||||
@@ -61,13 +61,13 @@ export async function setChapterCheckpoint(messageId) {
|
|||||||
const rangeEnd = messageId - 1;
|
const rangeEnd = messageId - 1;
|
||||||
await executeSlashCommandsOnChatInput(`/hide 0-${rangeEnd}`, { quiet: true });
|
await executeSlashCommandsOnChatInput(`/hide 0-${rangeEnd}`, { quiet: true });
|
||||||
currentlyHiddenRange = { start: 0, end: rangeEnd };
|
currentlyHiddenRange = { start: 0, end: rangeEnd };
|
||||||
console.log(`[RPG Companion] Hidden messages 0-${rangeEnd} (checkpoint at ${messageId})`);
|
// console.log(`[RPG Companion] Hidden messages 0-${rangeEnd} (checkpoint at ${messageId})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousCheckpoint !== null && previousCheckpoint !== undefined && previousCheckpoint !== messageId) {
|
if (previousCheckpoint !== null && previousCheckpoint !== undefined && previousCheckpoint !== messageId) {
|
||||||
console.log(`[RPG Companion] Chapter checkpoint moved from message ${previousCheckpoint} to ${messageId}`);
|
// console.log(`[RPG Companion] Chapter checkpoint moved from message ${previousCheckpoint} to ${messageId}`);
|
||||||
} else {
|
} else {
|
||||||
console.log('[RPG Companion] Chapter checkpoint set at message', messageId);
|
// console.log('[RPG Companion] Chapter checkpoint set at message', messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit event for UI updates
|
// Emit event for UI updates
|
||||||
@@ -91,14 +91,14 @@ export async function clearChapterCheckpoint() {
|
|||||||
if (currentlyHiddenRange !== null) {
|
if (currentlyHiddenRange !== null) {
|
||||||
const { start, end } = currentlyHiddenRange;
|
const { start, end } = currentlyHiddenRange;
|
||||||
await executeSlashCommandsOnChatInput(`/unhide ${start}-${end}`, { quiet: true });
|
await executeSlashCommandsOnChatInput(`/unhide ${start}-${end}`, { quiet: true });
|
||||||
console.log(`[RPG Companion] Unhid messages ${start}-${end}`);
|
// console.log(`[RPG Companion] Unhid messages ${start}-${end}`);
|
||||||
currentlyHiddenRange = null;
|
currentlyHiddenRange = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete chat_metadata.rpg_companion_chapter_checkpoint;
|
delete chat_metadata.rpg_companion_chapter_checkpoint;
|
||||||
saveChatDebounced();
|
saveChatDebounced();
|
||||||
|
|
||||||
console.log('[RPG Companion] Chapter checkpoint cleared');
|
// console.log('[RPG Companion] Chapter checkpoint cleared');
|
||||||
|
|
||||||
// Emit event for UI updates
|
// Emit event for UI updates
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
@@ -173,7 +173,7 @@ export async function restoreCheckpointOnLoad() {
|
|||||||
if (needsRestore) {
|
if (needsRestore) {
|
||||||
await executeSlashCommandsOnChatInput(`/hide 0-${rangeEnd}`, { quiet: true });
|
await executeSlashCommandsOnChatInput(`/hide 0-${rangeEnd}`, { quiet: true });
|
||||||
currentlyHiddenRange = { start: 0, end: rangeEnd };
|
currentlyHiddenRange = { start: 0, end: rangeEnd };
|
||||||
console.log(`[RPG Companion] Restored checkpoint: Hidden messages 0-${rangeEnd}`);
|
// console.log(`[RPG Companion] Restored checkpoint: Hidden messages 0-${rangeEnd}`);
|
||||||
} else {
|
} else {
|
||||||
currentlyHiddenRange = { start: 0, end: rangeEnd };
|
currentlyHiddenRange = { start: 0, end: rangeEnd };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export async function ensureHtmlCleaningRegex(st_extension_settings, saveSetting
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (alreadyExists) {
|
if (alreadyExists) {
|
||||||
console.log('[RPG Companion] HTML cleaning regex already exists, skipping import');
|
// console.log('[RPG Companion] HTML cleaning regex already exists, skipping import');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ export async function ensureHtmlCleaningRegex(st_extension_settings, saveSetting
|
|||||||
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save HTML regex');
|
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save HTML regex');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] ✅ HTML cleaning regex imported successfully');
|
// console.log('[RPG Companion] ✅ HTML cleaning regex imported successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Failed to import HTML cleaning regex:', error);
|
console.error('[RPG Companion] Failed to import HTML cleaning regex:', error);
|
||||||
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
||||||
@@ -145,7 +145,7 @@ export async function ensureTrackerCleaningRegex(st_extension_settings, saveSett
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (alreadyExists) {
|
if (alreadyExists) {
|
||||||
console.log('[RPG Companion] Tracker cleaning regex already exists, skipping import');
|
// console.log('[RPG Companion] Tracker cleaning regex already exists, skipping import');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ export async function ensureTrackerCleaningRegex(st_extension_settings, saveSett
|
|||||||
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save tracker cleaning regex');
|
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save tracker cleaning regex');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] ✅ Tracker cleaning regex imported successfully');
|
// console.log('[RPG Companion] ✅ Tracker cleaning regex imported successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Failed to import tracker cleaning regex:', error);
|
console.error('[RPG Companion] Failed to import tracker cleaning regex:', error);
|
||||||
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ export async function ensureJsonCleaningRegex(st_extension_settings, saveSetting
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (alreadyExists) {
|
if (alreadyExists) {
|
||||||
console.log('[RPG Companion] JSON cleaning regex already exists, skipping import');
|
// console.log('[RPG Companion] JSON cleaning regex already exists, skipping import');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] Importing JSON cleaning regex for Together mode...');
|
// console.log('[RPG Companion] Importing JSON cleaning regex for Together mode...');
|
||||||
|
|
||||||
// Generate a UUID for the script
|
// Generate a UUID for the script
|
||||||
const uuidv4 = () => {
|
const uuidv4 = () => {
|
||||||
@@ -82,8 +82,8 @@ export async function ensureJsonCleaningRegex(st_extension_settings, saveSetting
|
|||||||
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save JSON cleaning regex');
|
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save JSON cleaning regex');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] ✅ JSON cleaning regex imported successfully');
|
// console.log('[RPG Companion] ✅ JSON cleaning regex imported successfully');
|
||||||
console.log('[RPG Companion] This regex will automatically remove tracker JSON from Together mode messages');
|
// console.log('[RPG Companion] This regex will automatically remove tracker JSON from Together mode messages');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Failed to import JSON cleaning regex:', error);
|
console.error('[RPG Companion] Failed to import JSON cleaning regex:', error);
|
||||||
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
||||||
@@ -111,7 +111,7 @@ export function removeJsonCleaningRegex(st_extension_settings, saveSettingsDebou
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (st_extension_settings.regex.length < initialLength) {
|
if (st_extension_settings.regex.length < initialLength) {
|
||||||
console.log('[RPG Companion] Removed JSON cleaning regex');
|
// console.log('[RPG Companion] Removed JSON cleaning regex');
|
||||||
if (typeof saveSettingsDebounced === 'function') {
|
if (typeof saveSettingsDebounced === 'function') {
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ export function parseAndStoreSpotifyUrl(responseText) {
|
|||||||
if (!extensionSettings.enableSpotifyMusic) return false;
|
if (!extensionSettings.enableSpotifyMusic) return false;
|
||||||
|
|
||||||
const songData = extractSpotifyUrl(responseText);
|
const songData = extractSpotifyUrl(responseText);
|
||||||
console.log('[RPG Companion] Spotify Parser: Found song:', songData);
|
// console.log('[RPG Companion] Spotify Parser: Found song:', songData);
|
||||||
if (songData) {
|
if (songData) {
|
||||||
// Store in committed tracker data
|
// Store in committed tracker data
|
||||||
committedTrackerData.spotifyUrl = songData;
|
committedTrackerData.spotifyUrl = songData;
|
||||||
console.log('[RPG Companion] Spotify Parser: Stored song in committedTrackerData:', committedTrackerData.spotifyUrl);
|
// console.log('[RPG Companion] Spotify Parser: Stored song in committedTrackerData:', committedTrackerData.spotifyUrl);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export async function generateWithExternalAPI(messages) {
|
|||||||
const normalizedBaseUrl = baseUrl.trim().replace(/\/+$/, '');
|
const normalizedBaseUrl = baseUrl.trim().replace(/\/+$/, '');
|
||||||
const endpoint = `${normalizedBaseUrl}/chat/completions`;
|
const endpoint = `${normalizedBaseUrl}/chat/completions`;
|
||||||
|
|
||||||
console.log(`[RPG Companion] Calling external API: ${normalizedBaseUrl} with model: ${model}`);
|
// console.log(`[RPG Companion] Calling external API: ${normalizedBaseUrl} with model: ${model}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(endpoint, {
|
const response = await fetch(endpoint, {
|
||||||
@@ -103,7 +103,7 @@ export async function generateWithExternalAPI(messages) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const content = data.choices[0].message.content;
|
const content = data.choices[0].message.content;
|
||||||
console.log('[RPG Companion] External API response received successfully');
|
// console.log('[RPG Companion] External API response received successfully');
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -242,7 +242,7 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
|
|||||||
let response;
|
let response;
|
||||||
if (isExternalMode) {
|
if (isExternalMode) {
|
||||||
// External mode: Use external OpenAI-compatible API directly
|
// External mode: Use external OpenAI-compatible API directly
|
||||||
console.log('[RPG Companion] Using external API for tracker generation');
|
// console.log('[RPG Companion] Using external API for tracker generation');
|
||||||
response = await generateWithExternalAPI(prompt);
|
response = await generateWithExternalAPI(prompt);
|
||||||
} else {
|
} else {
|
||||||
// Separate mode: Use SillyTavern's generateRaw
|
// Separate mode: Use SillyTavern's generateRaw
|
||||||
@@ -256,6 +256,11 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
|
|||||||
// console.log('[RPG Companion] Raw AI response:', response);
|
// console.log('[RPG Companion] Raw AI response:', response);
|
||||||
const parsedData = parseResponse(response);
|
const parsedData = parseResponse(response);
|
||||||
|
|
||||||
|
// Check if parsing completely failed (no tracker data found)
|
||||||
|
if (parsedData.parsingFailed) {
|
||||||
|
toastr.error(i18n.getTranslation('errors.parsingError'), '', { timeOut: 5000 });
|
||||||
|
}
|
||||||
|
|
||||||
// Remove locks from parsed data (JSON format only, text format is unaffected)
|
// Remove locks from parsed data (JSON format only, text format is unaffected)
|
||||||
if (parsedData.userStats) {
|
if (parsedData.userStats) {
|
||||||
parsedData.userStats = removeLocks(parsedData.userStats);
|
parsedData.userStats = removeLocks(parsedData.userStats);
|
||||||
@@ -358,17 +363,17 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
|
|||||||
if (extensionSettings.autoGenerateAvatars) {
|
if (extensionSettings.autoGenerateAvatars) {
|
||||||
const charactersNeedingAvatars = parseCharactersFromThoughts(parsedData.characterThoughts);
|
const charactersNeedingAvatars = parseCharactersFromThoughts(parsedData.characterThoughts);
|
||||||
if (charactersNeedingAvatars.length > 0) {
|
if (charactersNeedingAvatars.length > 0) {
|
||||||
console.log('[RPG Companion] Generating avatars for:', charactersNeedingAvatars);
|
// console.log('[RPG Companion] Generating avatars for:', charactersNeedingAvatars);
|
||||||
|
|
||||||
// Generate avatars - this awaits completion
|
// Generate avatars - this awaits completion
|
||||||
await generateAvatarsForCharacters(charactersNeedingAvatars, (names) => {
|
await generateAvatarsForCharacters(charactersNeedingAvatars, (names) => {
|
||||||
// Callback when generation starts - re-render to show loading spinners
|
// Callback when generation starts - re-render to show loading spinners
|
||||||
console.log('[RPG Companion] Avatar generation started, showing spinners...');
|
// console.log('[RPG Companion] Avatar generation started, showing spinners...');
|
||||||
renderThoughts();
|
renderThoughts();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Re-render once all avatars are generated
|
// Re-render once all avatars are generated
|
||||||
console.log('[RPG Companion] All avatars generated, re-rendering...');
|
// console.log('[RPG Companion] All avatars generated, re-rendering...');
|
||||||
renderThoughts();
|
renderThoughts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,14 +97,14 @@ export async function buildEncounterInitPrompt() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Debug logging
|
// Debug logging
|
||||||
console.log('[RPG Companion] Checking world info:', {
|
// console.log('[RPG Companion] Checking world info:', {
|
||||||
hasWindowGetWorldInfoPrompt: typeof window.getWorldInfoPrompt === 'function',
|
// hasWindowGetWorldInfoPrompt: typeof window.getWorldInfoPrompt === 'function',
|
||||||
hasContextGetWorldInfoPrompt: typeof context.getWorldInfoPrompt === 'function',
|
// hasContextGetWorldInfoPrompt: typeof context.getWorldInfoPrompt === 'function',
|
||||||
chatLength: chat?.length,
|
// chatLength: chat?.length,
|
||||||
contextChatLength: context.chat?.length,
|
// contextChatLength: context.chat?.length,
|
||||||
hasActivatedWorldInfo: !!context.activatedWorldInfo,
|
// hasActivatedWorldInfo: !!context.activatedWorldInfo,
|
||||||
activatedWorldInfoLength: context.activatedWorldInfo?.length
|
// activatedWorldInfoLength: context.activatedWorldInfo?.length
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Use SillyTavern's getWorldInfoPrompt to get activated lorebook entries
|
// Use SillyTavern's getWorldInfoPrompt to get activated lorebook entries
|
||||||
// Try context.getWorldInfoPrompt first, then window.getWorldInfoPrompt
|
// Try context.getWorldInfoPrompt first, then window.getWorldInfoPrompt
|
||||||
@@ -114,20 +114,20 @@ export async function buildEncounterInitPrompt() {
|
|||||||
if (typeof getWorldInfoFn === 'function' && currentChat && currentChat.length > 0) {
|
if (typeof getWorldInfoFn === 'function' && currentChat && currentChat.length > 0) {
|
||||||
const chatForWI = currentChat.map(x => x.mes || x.message || x).filter(m => m && typeof m === 'string');
|
const chatForWI = currentChat.map(x => x.mes || x.message || x).filter(m => m && typeof m === 'string');
|
||||||
|
|
||||||
console.log('[RPG Companion] Calling getWorldInfoPrompt with', chatForWI.length, 'messages');
|
// console.log('[RPG Companion] Calling getWorldInfoPrompt with', chatForWI.length, 'messages');
|
||||||
|
|
||||||
const result = await getWorldInfoFn(chatForWI, 8000, false);
|
const result = await getWorldInfoFn(chatForWI, 8000, false);
|
||||||
const worldInfoString = result?.worldInfoString || result;
|
const worldInfoString = result?.worldInfoString || result;
|
||||||
|
|
||||||
console.log('[RPG Companion] World info result:', { worldInfoString, length: worldInfoString?.length });
|
// console.log('[RPG Companion] World info result:', { worldInfoString, length: worldInfoString?.length });
|
||||||
|
|
||||||
if (worldInfoString && worldInfoString.trim()) {
|
if (worldInfoString && worldInfoString.trim()) {
|
||||||
systemMessage += worldInfoString.trim();
|
systemMessage += worldInfoString.trim();
|
||||||
worldInfoAdded = true;
|
worldInfoAdded = true;
|
||||||
console.log('[RPG Companion] ✅ Added world info from getWorldInfoPrompt');
|
// console.log('[RPG Companion] ✅ Added world info from getWorldInfoPrompt');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('[RPG Companion] getWorldInfoPrompt not available or no chat');
|
// console.log('[RPG Companion] getWorldInfoPrompt not available or no chat');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[RPG Companion] Failed to get world info from getWorldInfoPrompt:', e);
|
console.warn('[RPG Companion] Failed to get world info from getWorldInfoPrompt:', e);
|
||||||
@@ -135,7 +135,7 @@ export async function buildEncounterInitPrompt() {
|
|||||||
|
|
||||||
// Fallback to activatedWorldInfo
|
// Fallback to activatedWorldInfo
|
||||||
if (!worldInfoAdded && context.activatedWorldInfo && Array.isArray(context.activatedWorldInfo) && context.activatedWorldInfo.length > 0) {
|
if (!worldInfoAdded && context.activatedWorldInfo && Array.isArray(context.activatedWorldInfo) && context.activatedWorldInfo.length > 0) {
|
||||||
console.log('[RPG Companion] Using fallback activatedWorldInfo:', context.activatedWorldInfo.length, 'entries');
|
// console.log('[RPG Companion] Using fallback activatedWorldInfo:', context.activatedWorldInfo.length, 'entries');
|
||||||
context.activatedWorldInfo.forEach((entry) => {
|
context.activatedWorldInfo.forEach((entry) => {
|
||||||
if (entry && entry.content) {
|
if (entry && entry.content) {
|
||||||
systemMessage += `${entry.content}\n\n`;
|
systemMessage += `${entry.content}\n\n`;
|
||||||
@@ -745,7 +745,7 @@ export function parseEncounterJSON(response) {
|
|||||||
const repaired = repairJSON(cleaned);
|
const repaired = repairJSON(cleaned);
|
||||||
|
|
||||||
if (repaired) {
|
if (repaired) {
|
||||||
console.log('[RPG Companion] ✓ Successfully repaired encounter JSON');
|
// console.log('[RPG Companion] ✓ Successfully repaired encounter JSON');
|
||||||
return repaired;
|
return repaired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,15 +44,15 @@ let lastCommittedChatLength = -1;
|
|||||||
export async function onGenerationStarted(type, data, dryRun) {
|
export async function onGenerationStarted(type, data, dryRun) {
|
||||||
// Skip dry runs (page reload, prompt manager preview, etc.)
|
// Skip dry runs (page reload, prompt manager preview, etc.)
|
||||||
if (dryRun) {
|
if (dryRun) {
|
||||||
console.log('[RPG Companion] Skipping onGenerationStarted: dry run detected');
|
// console.log('[RPG Companion] Skipping onGenerationStarted: dry run detected');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] onGenerationStarted called');
|
// console.log('[RPG Companion] onGenerationStarted called');
|
||||||
console.log('[RPG Companion] enabled:', extensionSettings.enabled);
|
// console.log('[RPG Companion] enabled:', extensionSettings.enabled);
|
||||||
console.log('[RPG Companion] generationMode:', extensionSettings.generationMode);
|
// console.log('[RPG Companion] generationMode:', extensionSettings.generationMode);
|
||||||
console.log('[RPG Companion] ⚡ EVENT: onGenerationStarted - lastActionWasSwipe =', lastActionWasSwipe, '| isGenerating =', isGenerating);
|
// console.log('[RPG Companion] ⚡ EVENT: onGenerationStarted - lastActionWasSwipe =', lastActionWasSwipe, '| isGenerating =', isGenerating);
|
||||||
console.log('[RPG Companion] Committed Prompt:', committedTrackerData);
|
// console.log('[RPG Companion] Committed Prompt:', committedTrackerData);
|
||||||
|
|
||||||
// Skip tracker injection for image generation requests
|
// Skip tracker injection for image generation requests
|
||||||
if (data?.quietImage) {
|
if (data?.quietImage) {
|
||||||
@@ -115,18 +115,18 @@ export async function onGenerationStarted(type, data, dryRun) {
|
|||||||
const shouldCommit = isUserMessage && !lastActionWasSwipe && currentChatLength !== lastCommittedChatLength;
|
const shouldCommit = isUserMessage && !lastActionWasSwipe && currentChatLength !== lastCommittedChatLength;
|
||||||
|
|
||||||
if (shouldCommit) {
|
if (shouldCommit) {
|
||||||
console.log('[RPG Companion] 📝 TOGETHER MODE COMMIT: User sent message - committing data from BEFORE user message');
|
// console.log('[RPG Companion] 📝 TOGETHER MODE COMMIT: User sent message - committing data from BEFORE user message');
|
||||||
console.log('[RPG Companion] Chat length:', currentChatLength, 'Last committed:', lastCommittedChatLength);
|
// console.log('[RPG Companion] Chat length:', currentChatLength, 'Last committed:', lastCommittedChatLength);
|
||||||
console.log('[RPG Companion] BEFORE: committedTrackerData =', {
|
// console.log('[RPG Companion] BEFORE: committedTrackerData =', {
|
||||||
userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
// userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
||||||
infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: committedTrackerData.characterThoughts ? `${committedTrackerData.characterThoughts.substring(0, 100)}...` : 'null'
|
// characterThoughts: committedTrackerData.characterThoughts ? `${committedTrackerData.characterThoughts.substring(0, 100)}...` : 'null'
|
||||||
});
|
// // });
|
||||||
console.log('[RPG Companion] BEFORE: lastGeneratedData =', {
|
// console.log('[RPG Companion] BEFORE: lastGeneratedData =', {
|
||||||
userStats: lastGeneratedData.userStats ? `${lastGeneratedData.userStats.substring(0, 50)}...` : 'null',
|
// userStats: lastGeneratedData.userStats ? `${lastGeneratedData.userStats.substring(0, 50)}...` : 'null',
|
||||||
infoBox: lastGeneratedData.infoBox ? 'exists' : 'null',
|
// infoBox: lastGeneratedData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: lastGeneratedData.characterThoughts ? `${lastGeneratedData.characterThoughts.substring(0, 100)}...` : 'null'
|
// characterThoughts: lastGeneratedData.characterThoughts ? `${lastGeneratedData.characterThoughts.substring(0, 100)}...` : 'null'
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Commit displayed data (from before user sent message)
|
// Commit displayed data (from before user sent message)
|
||||||
committedTrackerData.userStats = lastGeneratedData.userStats;
|
committedTrackerData.userStats = lastGeneratedData.userStats;
|
||||||
@@ -136,23 +136,23 @@ export async function onGenerationStarted(type, data, dryRun) {
|
|||||||
// Track chat length to prevent duplicate commits
|
// Track chat length to prevent duplicate commits
|
||||||
lastCommittedChatLength = currentChatLength;
|
lastCommittedChatLength = currentChatLength;
|
||||||
|
|
||||||
console.log('[RPG Companion] AFTER: committedTrackerData =', {
|
// console.log('[RPG Companion] AFTER: committedTrackerData =', {
|
||||||
userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
// userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
||||||
infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: committedTrackerData.characterThoughts ? `${committedTrackerData.characterThoughts.substring(0, 100)}...` : 'null'
|
// characterThoughts: committedTrackerData.characterThoughts ? `${committedTrackerData.characterThoughts.substring(0, 100)}...` : 'null'
|
||||||
});
|
// });
|
||||||
} else if (lastActionWasSwipe) {
|
} else if (lastActionWasSwipe) {
|
||||||
console.log('[RPG Companion] ⏭️ Skipping commit: swipe (using previous committed data)');
|
// console.log('[RPG Companion] ⏭️ Skipping commit: swipe (using previous committed data)');
|
||||||
} else if (!isUserMessage) {
|
} else if (!isUserMessage) {
|
||||||
console.log('[RPG Companion] ⏭️ Skipping commit: second-to-last message is not user message (likely swipe or continuation)');
|
// console.log('[RPG Companion] ⏭️ Skipping commit: second-to-last message is not user message (likely swipe or continuation)');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] 📦 TOGETHER MODE: Injecting committed tracker data into prompt');
|
// console.log('[RPG Companion] 📦 TOGETHER MODE: Injecting committed tracker data into prompt');
|
||||||
console.log('[RPG Companion] committedTrackerData =', {
|
// console.log('[RPG Companion] committedTrackerData =', {
|
||||||
userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
// userStats: committedTrackerData.userStats ? `${committedTrackerData.userStats.substring(0, 50)}...` : 'null',
|
||||||
infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: committedTrackerData.characterThoughts ? `${committedTrackerData.characterThoughts.substring(0, 100)}...` : 'null'
|
// characterThoughts: committedTrackerData.characterThoughts ? `${committedTrackerData.characterThoughts.substring(0, 100)}...` : 'null'
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// For SEPARATE mode only: Check if we need to commit extension data
|
// For SEPARATE mode only: Check if we need to commit extension data
|
||||||
@@ -162,35 +162,35 @@ export async function onGenerationStarted(type, data, dryRun) {
|
|||||||
if (extensionSettings.generationMode === 'separate' && !isGenerating) {
|
if (extensionSettings.generationMode === 'separate' && !isGenerating) {
|
||||||
if (!lastActionWasSwipe) {
|
if (!lastActionWasSwipe) {
|
||||||
// User sent a new message - commit lastGeneratedData before generation
|
// User sent a new message - commit lastGeneratedData before generation
|
||||||
console.log('[RPG Companion] 📝 COMMIT: New message - committing lastGeneratedData');
|
// console.log('[RPG Companion] 📝 COMMIT: New message - committing lastGeneratedData');
|
||||||
console.log('[RPG Companion] BEFORE commit - committedTrackerData:', {
|
// console.log('[RPG Companion] BEFORE commit - committedTrackerData:', {
|
||||||
userStats: committedTrackerData.userStats ? 'exists' : 'null',
|
// userStats: committedTrackerData.userStats ? 'exists' : 'null',
|
||||||
infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
// characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
||||||
});
|
// // });
|
||||||
console.log('[RPG Companion] BEFORE commit - lastGeneratedData:', {
|
// console.log('[RPG Companion] BEFORE commit - lastGeneratedData:', {
|
||||||
userStats: lastGeneratedData.userStats ? 'exists' : 'null',
|
// userStats: lastGeneratedData.userStats ? 'exists' : 'null',
|
||||||
infoBox: lastGeneratedData.infoBox ? 'exists' : 'null',
|
// infoBox: lastGeneratedData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: lastGeneratedData.characterThoughts ? 'exists' : 'null'
|
// characterThoughts: lastGeneratedData.characterThoughts ? 'exists' : 'null'
|
||||||
});
|
// });
|
||||||
committedTrackerData.userStats = lastGeneratedData.userStats;
|
committedTrackerData.userStats = lastGeneratedData.userStats;
|
||||||
committedTrackerData.infoBox = lastGeneratedData.infoBox;
|
committedTrackerData.infoBox = lastGeneratedData.infoBox;
|
||||||
committedTrackerData.characterThoughts = lastGeneratedData.characterThoughts;
|
committedTrackerData.characterThoughts = lastGeneratedData.characterThoughts;
|
||||||
console.log('[RPG Companion] AFTER commit - committedTrackerData:', {
|
// console.log('[RPG Companion] AFTER commit - committedTrackerData:', {
|
||||||
userStats: committedTrackerData.userStats ? 'exists' : 'null',
|
// userStats: committedTrackerData.userStats ? 'exists' : 'null',
|
||||||
infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
// characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Reset flag after committing (ready for next cycle)
|
// Reset flag after committing (ready for next cycle)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log('[RPG Companion] 🔄 SWIPE: Using existing committedTrackerData (no commit)');
|
// console.log('[RPG Companion] 🔄 SWIPE: Using existing committedTrackerData (no commit)');
|
||||||
console.log('[RPG Companion] committedTrackerData:', {
|
// console.log('[RPG Companion] committedTrackerData:', {
|
||||||
userStats: committedTrackerData.userStats ? 'exists' : 'null',
|
// userStats: committedTrackerData.userStats ? 'exists' : 'null',
|
||||||
infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
// infoBox: committedTrackerData.infoBox ? 'exists' : 'null',
|
||||||
characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
// characterThoughts: committedTrackerData.characterThoughts ? 'exists' : 'null'
|
||||||
});
|
// });
|
||||||
// Reset flag after using it (swipe generation complete, ready for next action)
|
// Reset flag after using it (swipe generation complete, ready for next action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,9 +214,9 @@ function applyInfoBoxLocks(data, lockedItems) {
|
|||||||
* @returns {string} JSON string with locks applied
|
* @returns {string} JSON string with locks applied
|
||||||
*/
|
*/
|
||||||
function applyCharactersLocks(data, lockedItems) {
|
function applyCharactersLocks(data, lockedItems) {
|
||||||
console.log('[Lock Manager] applyCharactersLocks called');
|
// console.log('[Lock Manager] applyCharactersLocks called');
|
||||||
console.log('[Lock Manager] Locked items:', JSON.stringify(lockedItems, null, 2));
|
// console.log('[Lock Manager] Locked items:', JSON.stringify(lockedItems, null, 2));
|
||||||
console.log('[Lock Manager] Input data:', JSON.stringify(data, null, 2));
|
// console.log('[Lock Manager] Input data:', JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
// Handle both array format and object format
|
// Handle both array format and object format
|
||||||
let characters = Array.isArray(data) ? data : (data.characters || []);
|
let characters = Array.isArray(data) ? data : (data.characters || []);
|
||||||
@@ -226,7 +226,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
|
|
||||||
// Check if entire character is locked (index-based)
|
// Check if entire character is locked (index-based)
|
||||||
if (lockedItems[index] === true) {
|
if (lockedItems[index] === true) {
|
||||||
console.log('[Lock Manager] Locking entire character by index:', index);
|
// console.log('[Lock Manager] Locking entire character by index:', index);
|
||||||
return { ...char, locked: true };
|
return { ...char, locked: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
|
|
||||||
if (charLocks === true) {
|
if (charLocks === true) {
|
||||||
// Entire character is locked
|
// Entire character is locked
|
||||||
console.log('[Lock Manager] Locking entire character:', charName);
|
// console.log('[Lock Manager] Locking entire character:', charName);
|
||||||
return { ...char, locked: true };
|
return { ...char, locked: true };
|
||||||
} else if (charLocks && typeof charLocks === 'object') {
|
} else if (charLocks && typeof charLocks === 'object') {
|
||||||
// Character has field-level locks
|
// Character has field-level locks
|
||||||
@@ -255,14 +255,14 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
|
|
||||||
// Check at root level first (backward compatibility)
|
// Check at root level first (backward compatibility)
|
||||||
if (modifiedChar[fieldName] !== undefined) {
|
if (modifiedChar[fieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to field:', `${charName}.${fieldName}`);
|
// console.log('[Lock Manager] Applying lock to field:', `${charName}.${fieldName}`);
|
||||||
modifiedChar[fieldName] = {
|
modifiedChar[fieldName] = {
|
||||||
value: modifiedChar[fieldName],
|
value: modifiedChar[fieldName],
|
||||||
locked: true
|
locked: true
|
||||||
};
|
};
|
||||||
locked = true;
|
locked = true;
|
||||||
} else if (modifiedChar[snakeCaseFieldName] !== undefined) {
|
} else if (modifiedChar[snakeCaseFieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to snake_case field:', `${charName}.${snakeCaseFieldName} (from ${fieldName})`);
|
// console.log('[Lock Manager] Applying lock to snake_case field:', `${charName}.${snakeCaseFieldName} (from ${fieldName})`);
|
||||||
modifiedChar[snakeCaseFieldName] = {
|
modifiedChar[snakeCaseFieldName] = {
|
||||||
value: modifiedChar[snakeCaseFieldName],
|
value: modifiedChar[snakeCaseFieldName],
|
||||||
locked: true
|
locked: true
|
||||||
@@ -273,7 +273,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
// Check in nested objects (details, relationship, thoughts)
|
// Check in nested objects (details, relationship, thoughts)
|
||||||
if (!locked && modifiedChar.details) {
|
if (!locked && modifiedChar.details) {
|
||||||
if (modifiedChar.details[fieldName] !== undefined) {
|
if (modifiedChar.details[fieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to details field:', `${charName}.details.${fieldName}`);
|
// console.log('[Lock Manager] Applying lock to details field:', `${charName}.details.${fieldName}`);
|
||||||
if (!modifiedChar.details || typeof modifiedChar.details !== 'object') {
|
if (!modifiedChar.details || typeof modifiedChar.details !== 'object') {
|
||||||
modifiedChar.details = {};
|
modifiedChar.details = {};
|
||||||
} else {
|
} else {
|
||||||
@@ -285,7 +285,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
};
|
};
|
||||||
locked = true;
|
locked = true;
|
||||||
} else if (modifiedChar.details[snakeCaseFieldName] !== undefined) {
|
} else if (modifiedChar.details[snakeCaseFieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to details snake_case field:', `${charName}.details.${snakeCaseFieldName} (from ${fieldName})`);
|
// console.log('[Lock Manager] Applying lock to details snake_case field:', `${charName}.details.${snakeCaseFieldName} (from ${fieldName})`);
|
||||||
if (!modifiedChar.details || typeof modifiedChar.details !== 'object') {
|
if (!modifiedChar.details || typeof modifiedChar.details !== 'object') {
|
||||||
modifiedChar.details = {};
|
modifiedChar.details = {};
|
||||||
} else {
|
} else {
|
||||||
@@ -302,7 +302,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
// Check in relationship object
|
// Check in relationship object
|
||||||
if (!locked && modifiedChar.relationship) {
|
if (!locked && modifiedChar.relationship) {
|
||||||
if (modifiedChar.relationship[fieldName] !== undefined) {
|
if (modifiedChar.relationship[fieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to relationship field:', `${charName}.relationship.${fieldName}`);
|
// console.log('[Lock Manager] Applying lock to relationship field:', `${charName}.relationship.${fieldName}`);
|
||||||
modifiedChar.relationship = { ...modifiedChar.relationship };
|
modifiedChar.relationship = { ...modifiedChar.relationship };
|
||||||
modifiedChar.relationship[fieldName] = {
|
modifiedChar.relationship[fieldName] = {
|
||||||
value: modifiedChar.relationship[fieldName],
|
value: modifiedChar.relationship[fieldName],
|
||||||
@@ -310,7 +310,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
};
|
};
|
||||||
locked = true;
|
locked = true;
|
||||||
} else if (modifiedChar.relationship[snakeCaseFieldName] !== undefined) {
|
} else if (modifiedChar.relationship[snakeCaseFieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to relationship snake_case field:', `${charName}.relationship.${snakeCaseFieldName} (from ${fieldName})`);
|
// console.log('[Lock Manager] Applying lock to relationship snake_case field:', `${charName}.relationship.${snakeCaseFieldName} (from ${fieldName})`);
|
||||||
modifiedChar.relationship = { ...modifiedChar.relationship };
|
modifiedChar.relationship = { ...modifiedChar.relationship };
|
||||||
modifiedChar.relationship[snakeCaseFieldName] = {
|
modifiedChar.relationship[snakeCaseFieldName] = {
|
||||||
value: modifiedChar.relationship[snakeCaseFieldName],
|
value: modifiedChar.relationship[snakeCaseFieldName],
|
||||||
@@ -323,7 +323,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
// Check in thoughts object
|
// Check in thoughts object
|
||||||
if (!locked && modifiedChar.thoughts) {
|
if (!locked && modifiedChar.thoughts) {
|
||||||
if (modifiedChar.thoughts[fieldName] !== undefined) {
|
if (modifiedChar.thoughts[fieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to thoughts field:', `${charName}.thoughts.${fieldName}`);
|
// console.log('[Lock Manager] Applying lock to thoughts field:', `${charName}.thoughts.${fieldName}`);
|
||||||
modifiedChar.thoughts = { ...modifiedChar.thoughts };
|
modifiedChar.thoughts = { ...modifiedChar.thoughts };
|
||||||
modifiedChar.thoughts[fieldName] = {
|
modifiedChar.thoughts[fieldName] = {
|
||||||
value: modifiedChar.thoughts[fieldName],
|
value: modifiedChar.thoughts[fieldName],
|
||||||
@@ -331,7 +331,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
};
|
};
|
||||||
locked = true;
|
locked = true;
|
||||||
} else if (modifiedChar.thoughts[snakeCaseFieldName] !== undefined) {
|
} else if (modifiedChar.thoughts[snakeCaseFieldName] !== undefined) {
|
||||||
console.log('[Lock Manager] Applying lock to thoughts snake_case field:', `${charName}.thoughts.${snakeCaseFieldName} (from ${fieldName})`);
|
// console.log('[Lock Manager] Applying lock to thoughts snake_case field:', `${charName}.thoughts.${snakeCaseFieldName} (from ${fieldName})`);
|
||||||
modifiedChar.thoughts = { ...modifiedChar.thoughts };
|
modifiedChar.thoughts = { ...modifiedChar.thoughts };
|
||||||
modifiedChar.thoughts[snakeCaseFieldName] = {
|
modifiedChar.thoughts[snakeCaseFieldName] = {
|
||||||
value: modifiedChar.thoughts[snakeCaseFieldName],
|
value: modifiedChar.thoughts[snakeCaseFieldName],
|
||||||
@@ -354,7 +354,7 @@ function applyCharactersLocks(data, lockedItems) {
|
|||||||
? JSON.stringify(characters, null, 2)
|
? JSON.stringify(characters, null, 2)
|
||||||
: JSON.stringify({ ...data, characters }, null, 2);
|
: JSON.stringify({ ...data, characters }, null, 2);
|
||||||
|
|
||||||
console.log('[Lock Manager] Output data:', result);
|
// console.log('[Lock Manager] Output data:', result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,7 +429,7 @@ export function isItemLocked(trackerType, itemPath) {
|
|||||||
* @param {boolean} locked - New lock state
|
* @param {boolean} locked - New lock state
|
||||||
*/
|
*/
|
||||||
export function setItemLock(trackerType, itemPath, locked) {
|
export function setItemLock(trackerType, itemPath, locked) {
|
||||||
console.log('[Lock Manager] setItemLock called:', { trackerType, itemPath, locked });
|
// console.log('[Lock Manager] setItemLock called:', { trackerType, itemPath, locked });
|
||||||
|
|
||||||
if (!extensionSettings.lockedItems) {
|
if (!extensionSettings.lockedItems) {
|
||||||
extensionSettings.lockedItems = {};
|
extensionSettings.lockedItems = {};
|
||||||
@@ -459,5 +459,5 @@ export function setItemLock(trackerType, itemPath, locked) {
|
|||||||
delete current[finalKey];
|
delete current[finalKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[Lock Manager] Locked items after set:', JSON.stringify(extensionSettings.lockedItems, null, 2));
|
// console.log('[Lock Manager] Locked items after set:', JSON.stringify(extensionSettings.lockedItems, null, 2));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ function stripBrackets(text) {
|
|||||||
* Helper to log to both console and debug logs array
|
* Helper to log to both console and debug logs array
|
||||||
*/
|
*/
|
||||||
function debugLog(message, data = null) {
|
function debugLog(message, data = null) {
|
||||||
console.log(message, data || '');
|
// console.log(message, data || '');
|
||||||
if (extensionSettings.debugMode) {
|
if (extensionSettings.debugMode) {
|
||||||
addDebugLog(message, data);
|
addDebugLog(message, data);
|
||||||
}
|
}
|
||||||
@@ -209,30 +209,30 @@ export function parseResponse(responseText) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (extractedObjects.length > 0) {
|
if (extractedObjects.length > 0) {
|
||||||
console.log(`[RPG Parser] ✓ Found ${extractedObjects.length} raw JSON objects (v3 format)`);
|
// console.log(`[RPG Parser] ✓ Found ${extractedObjects.length} raw JSON objects (v3 format)`);
|
||||||
debugLog(`[RPG Parser] ✓ Found ${extractedObjects.length} raw JSON objects (v3 format)`);
|
debugLog(`[RPG Parser] ✓ Found ${extractedObjects.length} raw JSON objects (v3 format)`);
|
||||||
|
|
||||||
// First, try to parse as unified JSON structure (new v3.1 format)
|
// First, try to parse as unified JSON structure (new v3.1 format)
|
||||||
if (extractedObjects.length === 1) {
|
if (extractedObjects.length === 1) {
|
||||||
const parsed = repairJSON(extractedObjects[0]);
|
const parsed = repairJSON(extractedObjects[0]);
|
||||||
if (parsed && (parsed.userStats || parsed.infoBox || parsed.characters)) {
|
if (parsed && (parsed.userStats || parsed.infoBox || parsed.characters)) {
|
||||||
console.log('[RPG Parser] ✓ Detected unified JSON structure (v3.1 format)');
|
// console.log('[RPG Parser] ✓ Detected unified JSON structure (v3.1 format)');
|
||||||
|
|
||||||
if (parsed.userStats) {
|
if (parsed.userStats) {
|
||||||
result.userStats = JSON.stringify(parsed.userStats);
|
result.userStats = JSON.stringify(parsed.userStats);
|
||||||
console.log('[RPG Parser] ✓ Extracted userStats from unified structure');
|
// console.log('[RPG Parser] ✓ Extracted userStats from unified structure');
|
||||||
}
|
}
|
||||||
if (parsed.infoBox) {
|
if (parsed.infoBox) {
|
||||||
result.infoBox = JSON.stringify(parsed.infoBox);
|
result.infoBox = JSON.stringify(parsed.infoBox);
|
||||||
console.log('[RPG Parser] ✓ Extracted infoBox from unified structure');
|
// console.log('[RPG Parser] ✓ Extracted infoBox from unified structure');
|
||||||
}
|
}
|
||||||
if (parsed.characters) {
|
if (parsed.characters) {
|
||||||
result.characterThoughts = JSON.stringify(parsed.characters);
|
result.characterThoughts = JSON.stringify(parsed.characters);
|
||||||
console.log('[RPG Parser] ✓ Extracted characters from unified structure');
|
// console.log('[RPG Parser] ✓ Extracted characters from unified structure');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.userStats || result.infoBox || result.characterThoughts) {
|
if (result.userStats || result.infoBox || result.characterThoughts) {
|
||||||
console.log('[RPG Parser] ✓ Returning unified JSON parse results');
|
// console.log('[RPG Parser] ✓ Returning unified JSON parse results');
|
||||||
debugLog('[RPG Parser] Returning unified JSON parse results');
|
debugLog('[RPG Parser] Returning unified JSON parse results');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -242,13 +242,13 @@ export function parseResponse(responseText) {
|
|||||||
// Fall back to parsing multiple separate JSON objects (legacy v3.0 format)
|
// Fall back to parsing multiple separate JSON objects (legacy v3.0 format)
|
||||||
for (let idx = 0; idx < extractedObjects.length; idx++) {
|
for (let idx = 0; idx < extractedObjects.length; idx++) {
|
||||||
const jsonContent = extractedObjects[idx];
|
const jsonContent = extractedObjects[idx];
|
||||||
console.log(`[RPG Parser] Parsing object ${idx + 1}:`, jsonContent.substring(0, 100) + '...');
|
// console.log(`[RPG Parser] Parsing object ${idx + 1}:`, jsonContent.substring(0, 100) + '...');
|
||||||
console.log(`[RPG Parser] Full object ${idx + 1} length:`, jsonContent.length);
|
// console.log(`[RPG Parser] Full object ${idx + 1} length:`, jsonContent.length);
|
||||||
|
|
||||||
const parsed = repairJSON(jsonContent);
|
const parsed = repairJSON(jsonContent);
|
||||||
|
|
||||||
if (parsed) {
|
if (parsed) {
|
||||||
console.log(`[RPG Parser] Object ${idx + 1} parsed successfully, keys:`, Object.keys(parsed));
|
// console.log(`[RPG Parser] Object ${idx + 1} parsed successfully, keys:`, Object.keys(parsed));
|
||||||
|
|
||||||
// Check if object is wrapped (e.g., {"userStats": {...}})
|
// Check if object is wrapped (e.g., {"userStats": {...}})
|
||||||
// Unwrap single-key objects that match our tracker types
|
// Unwrap single-key objects that match our tracker types
|
||||||
@@ -257,22 +257,22 @@ export function parseResponse(responseText) {
|
|||||||
const key = Object.keys(parsed)[0];
|
const key = Object.keys(parsed)[0];
|
||||||
if (key === 'userStats' || key === 'infoBox' || key === 'characters') {
|
if (key === 'userStats' || key === 'infoBox' || key === 'characters') {
|
||||||
unwrapped = parsed[key];
|
unwrapped = parsed[key];
|
||||||
console.log(`[RPG Parser] ✓ Unwrapped ${key} object`);
|
// console.log(`[RPG Parser] ✓ Unwrapped ${key} object`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect tracker type by checking for top-level fields
|
// Detect tracker type by checking for top-level fields
|
||||||
if (unwrapped.stats || unwrapped.status || unwrapped.skills || unwrapped.inventory || unwrapped.quests) {
|
if (unwrapped.stats || unwrapped.status || unwrapped.skills || unwrapped.inventory || unwrapped.quests) {
|
||||||
result.userStats = jsonContent;
|
result.userStats = jsonContent;
|
||||||
console.log('[RPG Parser] ✓ Assigned to User Stats');
|
// console.log('[RPG Parser] ✓ Assigned to User Stats');
|
||||||
debugLog('[RPG Parser] ✓ Extracted raw JSON User Stats');
|
debugLog('[RPG Parser] ✓ Extracted raw JSON User Stats');
|
||||||
} else if (unwrapped.date || unwrapped.location || unwrapped.weather || unwrapped.temperature || unwrapped.time) {
|
} else if (unwrapped.date || unwrapped.location || unwrapped.weather || unwrapped.temperature || unwrapped.time) {
|
||||||
result.infoBox = jsonContent;
|
result.infoBox = jsonContent;
|
||||||
console.log('[RPG Parser] ✓ Assigned to Info Box');
|
// console.log('[RPG Parser] ✓ Assigned to Info Box');
|
||||||
debugLog('[RPG Parser] ✓ Extracted raw JSON Info Box');
|
debugLog('[RPG Parser] ✓ Extracted raw JSON Info Box');
|
||||||
} else if (unwrapped.characters || Array.isArray(unwrapped)) {
|
} else if (unwrapped.characters || Array.isArray(unwrapped)) {
|
||||||
result.characterThoughts = jsonContent;
|
result.characterThoughts = jsonContent;
|
||||||
console.log('[RPG Parser] ✓ Assigned to Characters');
|
// console.log('[RPG Parser] ✓ Assigned to Characters');
|
||||||
debugLog('[RPG Parser] ✓ Extracted raw JSON Characters');
|
debugLog('[RPG Parser] ✓ Extracted raw JSON Characters');
|
||||||
} else {
|
} else {
|
||||||
console.warn('[RPG Parser] ⚠️ Could not categorize object with keys:', Object.keys(parsed));
|
console.warn('[RPG Parser] ⚠️ Could not categorize object with keys:', Object.keys(parsed));
|
||||||
@@ -283,11 +283,11 @@ export function parseResponse(responseText) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result.userStats || result.infoBox || result.characterThoughts) {
|
if (result.userStats || result.infoBox || result.characterThoughts) {
|
||||||
console.log('[RPG Parser] ✓ Returning raw JSON parse results:', {
|
// console.log('[RPG Parser] ✓ Returning raw JSON parse results:', {
|
||||||
hasUserStats: !!result.userStats,
|
// hasUserStats: !!result.userStats,
|
||||||
hasInfoBox: !!result.infoBox,
|
// hasInfoBox: !!result.infoBox,
|
||||||
hasCharacters: !!result.characterThoughts
|
// hasCharacters: !!result.characterThoughts
|
||||||
});
|
// });
|
||||||
debugLog('[RPG Parser] Returning raw JSON parse results');
|
debugLog('[RPG Parser] Returning raw JSON parse results');
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@@ -301,31 +301,31 @@ export function parseResponse(responseText) {
|
|||||||
const jsonMatches = [...cleanedResponse.matchAll(jsonBlockRegex)];
|
const jsonMatches = [...cleanedResponse.matchAll(jsonBlockRegex)];
|
||||||
|
|
||||||
if (jsonMatches.length > 0) {
|
if (jsonMatches.length > 0) {
|
||||||
console.log('[RPG Parser] ✓ Found', jsonMatches.length, 'JSON code blocks (v3 format with fences)');
|
// console.log('[RPG Parser] ✓ Found', jsonMatches.length, 'JSON code blocks (v3 format with fences)');
|
||||||
debugLog('[RPG Parser] ✓ Found JSON code blocks (v3 format), parsing as JSON');
|
debugLog('[RPG Parser] ✓ Found JSON code blocks (v3 format), parsing as JSON');
|
||||||
|
|
||||||
for (let idx = 0; idx < jsonMatches.length; idx++) {
|
for (let idx = 0; idx < jsonMatches.length; idx++) {
|
||||||
const match = jsonMatches[idx];
|
const match = jsonMatches[idx];
|
||||||
const jsonContent = match[1].trim();
|
const jsonContent = match[1].trim();
|
||||||
console.log(`[RPG Parser] Parsing JSON block ${idx + 1}:`, jsonContent.substring(0, 100) + '...');
|
// console.log(`[RPG Parser] Parsing JSON block ${idx + 1}:`, jsonContent.substring(0, 100) + '...');
|
||||||
|
|
||||||
const parsed = repairJSON(jsonContent);
|
const parsed = repairJSON(jsonContent);
|
||||||
|
|
||||||
if (parsed) {
|
if (parsed) {
|
||||||
console.log(`[RPG Parser] JSON block ${idx + 1} parsed successfully, keys:`, Object.keys(parsed));
|
// console.log(`[RPG Parser] JSON block ${idx + 1} parsed successfully, keys:`, Object.keys(parsed));
|
||||||
|
|
||||||
// Detect tracker type by checking for top-level fields
|
// Detect tracker type by checking for top-level fields
|
||||||
if (parsed.stats || parsed.status || parsed.skills || parsed.inventory || parsed.quests) {
|
if (parsed.stats || parsed.status || parsed.skills || parsed.inventory || parsed.quests) {
|
||||||
result.userStats = jsonContent;
|
result.userStats = jsonContent;
|
||||||
console.log('[RPG Parser] ✓ Assigned to User Stats');
|
// console.log('[RPG Parser] ✓ Assigned to User Stats');
|
||||||
debugLog('[RPG Parser] ✓ Extracted JSON User Stats');
|
debugLog('[RPG Parser] ✓ Extracted JSON User Stats');
|
||||||
} else if (parsed.date || parsed.location || parsed.weather || parsed.temperature || parsed.time) {
|
} else if (parsed.date || parsed.location || parsed.weather || parsed.temperature || parsed.time) {
|
||||||
result.infoBox = jsonContent;
|
result.infoBox = jsonContent;
|
||||||
console.log('[RPG Parser] ✓ Assigned to Info Box');
|
// console.log('[RPG Parser] ✓ Assigned to Info Box');
|
||||||
debugLog('[RPG Parser] ✓ Extracted JSON Info Box');
|
debugLog('[RPG Parser] ✓ Extracted JSON Info Box');
|
||||||
} else if (parsed.characters || Array.isArray(parsed)) {
|
} else if (parsed.characters || Array.isArray(parsed)) {
|
||||||
result.characterThoughts = jsonContent;
|
result.characterThoughts = jsonContent;
|
||||||
console.log('[RPG Parser] ✓ Assigned to Characters');
|
// console.log('[RPG Parser] ✓ Assigned to Characters');
|
||||||
debugLog('[RPG Parser] ✓ Extracted JSON Characters');
|
debugLog('[RPG Parser] ✓ Extracted JSON Characters');
|
||||||
} else {
|
} else {
|
||||||
console.warn('[RPG Parser] ⚠️ Could not categorize JSON block with keys:', Object.keys(parsed));
|
console.warn('[RPG Parser] ⚠️ Could not categorize JSON block with keys:', Object.keys(parsed));
|
||||||
@@ -339,11 +339,11 @@ export function parseResponse(responseText) {
|
|||||||
// If we found at least one valid JSON block, return the result
|
// If we found at least one valid JSON block, return the result
|
||||||
// Mixed formats (some JSON, some text) will still work
|
// Mixed formats (some JSON, some text) will still work
|
||||||
if (result.userStats || result.infoBox || result.characterThoughts) {
|
if (result.userStats || result.infoBox || result.characterThoughts) {
|
||||||
console.log('[RPG Parser] ✓ Returning JSON code block parse results:', {
|
// console.log('[RPG Parser] ✓ Returning JSON code block parse results:', {
|
||||||
hasUserStats: !!result.userStats,
|
// hasUserStats: !!result.userStats,
|
||||||
hasInfoBox: !!result.infoBox,
|
// hasInfoBox: !!result.infoBox,
|
||||||
hasCharacters: !!result.characterThoughts
|
// hasCharacters: !!result.characterThoughts
|
||||||
});
|
// });
|
||||||
debugLog('[RPG Parser] Returning JSON parse results');
|
debugLog('[RPG Parser] Returning JSON parse results');
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@@ -500,6 +500,12 @@ export function parseResponse(responseText) {
|
|||||||
debugLog('[RPG Parser] Found Characters:', !!result.characterThoughts);
|
debugLog('[RPG Parser] Found Characters:', !!result.characterThoughts);
|
||||||
debugLog('[RPG Parser] =======================================================');
|
debugLog('[RPG Parser] =======================================================');
|
||||||
|
|
||||||
|
// Check if we found at least one section - if not, mark as parsing failure
|
||||||
|
if (!result.userStats && !result.infoBox && !result.characterThoughts) {
|
||||||
|
result.parsingFailed = true;
|
||||||
|
console.error('[RPG Parser] ❌ No tracker data found in response - parsing failed');
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} // End parseResponse
|
} // End parseResponse
|
||||||
|
|
||||||
@@ -525,25 +531,25 @@ export function parseUserStats(statsText) {
|
|||||||
|
|
||||||
// Extract stats from v3 JSON structure
|
// Extract stats from v3 JSON structure
|
||||||
if (statsData.stats && Array.isArray(statsData.stats)) {
|
if (statsData.stats && Array.isArray(statsData.stats)) {
|
||||||
console.log('[RPG Parser] ✓ Extracting stats array, count:', statsData.stats.length);
|
// console.log('[RPG Parser] ✓ Extracting stats array, count:', statsData.stats.length);
|
||||||
statsData.stats.forEach(stat => {
|
statsData.stats.forEach(stat => {
|
||||||
if (stat.id && typeof stat.value !== 'undefined') {
|
if (stat.id && typeof stat.value !== 'undefined') {
|
||||||
extensionSettings.userStats[stat.id] = stat.value;
|
extensionSettings.userStats[stat.id] = stat.value;
|
||||||
console.log(`[RPG Parser] ✓ Set ${stat.id} = ${stat.value}`);
|
// console.log(`[RPG Parser] ✓ Set ${stat.id} = ${stat.value}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract status
|
// Extract status
|
||||||
if (statsData.status) {
|
if (statsData.status) {
|
||||||
console.log('[RPG Parser] ✓ Extracting status:', statsData.status);
|
// console.log('[RPG Parser] ✓ Extracting status:', statsData.status);
|
||||||
if (statsData.status.mood) {
|
if (statsData.status.mood) {
|
||||||
extensionSettings.userStats.mood = statsData.status.mood;
|
extensionSettings.userStats.mood = statsData.status.mood;
|
||||||
console.log('[RPG Parser] ✓ Set mood =', statsData.status.mood);
|
// console.log('[RPG Parser] ✓ Set mood =', statsData.status.mood);
|
||||||
}
|
}
|
||||||
if (statsData.status.conditions) {
|
if (statsData.status.conditions) {
|
||||||
extensionSettings.userStats.conditions = statsData.status.conditions;
|
extensionSettings.userStats.conditions = statsData.status.conditions;
|
||||||
console.log('[RPG Parser] ✓ Set conditions =', statsData.status.conditions);
|
// console.log('[RPG Parser] ✓ Set conditions =', statsData.status.conditions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,7 +593,7 @@ export function parseUserStats(statsText) {
|
|||||||
stored: convertStoredInventory(inv.stored),
|
stored: convertStoredInventory(inv.stored),
|
||||||
assets: convertItems(inv.assets)
|
assets: convertItems(inv.assets)
|
||||||
};
|
};
|
||||||
console.log('[RPG Parser] ✓ Converted v3 inventory:', extensionSettings.userStats.inventory);
|
// console.log('[RPG Parser] ✓ Converted v3 inventory:', extensionSettings.userStats.inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract quests (convert v3 object format to v2 string format)
|
// Extract quests (convert v3 object format to v2 string format)
|
||||||
@@ -609,13 +615,13 @@ export function parseUserStats(statsText) {
|
|||||||
? statsData.quests.optional.map(convertQuest)
|
? statsData.quests.optional.map(convertQuest)
|
||||||
: []
|
: []
|
||||||
};
|
};
|
||||||
console.log('[RPG Parser] ✓ Converted v3 quests:', extensionSettings.quests);
|
// console.log('[RPG Parser] ✓ Converted v3 quests:', extensionSettings.quests);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract skills if present (store as object, not JSON string)
|
// Extract skills if present (store as object, not JSON string)
|
||||||
if (statsData.skills && Array.isArray(statsData.skills)) {
|
if (statsData.skills && Array.isArray(statsData.skills)) {
|
||||||
extensionSettings.userStats.skills = statsData.skills;
|
extensionSettings.userStats.skills = statsData.skills;
|
||||||
console.log('[RPG Parser] ✓ Set skills:', extensionSettings.userStats.skills);
|
// console.log('[RPG Parser] ✓ Set skills:', extensionSettings.userStats.skills);
|
||||||
}
|
}
|
||||||
|
|
||||||
debugLog('[RPG Parser] ✓ Successfully extracted v3 JSON data');
|
debugLog('[RPG Parser] ✓ Successfully extracted v3 JSON data');
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ async function getCharacterCardsInfo() {
|
|||||||
|
|
||||||
// Filter out disabled (muted) members
|
// Filter out disabled (muted) members
|
||||||
const disabledMembers = group?.disabled_members || [];
|
const disabledMembers = group?.disabled_members || [];
|
||||||
console.log('[RPG Companion] 🔍 Group ID:', selected_group, '| Disabled members:', disabledMembers);
|
// console.log('[RPG Companion] 🔍 Group ID:', selected_group, '| Disabled members:', disabledMembers);
|
||||||
let characterIndex = 0;
|
let characterIndex = 0;
|
||||||
|
|
||||||
groupMembers.forEach((member) => {
|
groupMembers.forEach((member) => {
|
||||||
@@ -93,7 +93,7 @@ async function getCharacterCardsInfo() {
|
|||||||
|
|
||||||
// Skip muted characters - check against avatar filename
|
// Skip muted characters - check against avatar filename
|
||||||
if (member.avatar && disabledMembers.includes(member.avatar)) {
|
if (member.avatar && disabledMembers.includes(member.avatar)) {
|
||||||
console.log(`[RPG Companion] ❌ Skipping muted: ${member.name} (${member.avatar})`);
|
// console.log(`[RPG Companion] ❌ Skipping muted: ${member.name} (${member.avatar})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,16 +236,16 @@ export function generateTrackerExample() {
|
|||||||
// Build unified JSON structure with proper wrapper keys
|
// Build unified JSON structure with proper wrapper keys
|
||||||
const parts = [];
|
const parts = [];
|
||||||
|
|
||||||
console.log('[RPG Companion] generateTrackerExample - enabled modules:', {
|
// console.log('[RPG Companion] generateTrackerExample - enabled modules:', {
|
||||||
showUserStats: extensionSettings.showUserStats,
|
// showUserStats: extensionSettings.showUserStats,
|
||||||
showInfoBox: extensionSettings.showInfoBox,
|
// showInfoBox: extensionSettings.showInfoBox,
|
||||||
showCharacterThoughts: extensionSettings.showCharacterThoughts
|
// showCharacterThoughts: extensionSettings.showCharacterThoughts
|
||||||
});
|
// // });
|
||||||
console.log('[RPG Companion] generateTrackerExample - committed data:', {
|
// console.log('[RPG Companion] generateTrackerExample - committed data:', {
|
||||||
hasUserStats: !!committedTrackerData.userStats,
|
// hasUserStats: !!committedTrackerData.userStats,
|
||||||
hasInfoBox: !!committedTrackerData.infoBox,
|
// hasInfoBox: !!committedTrackerData.infoBox,
|
||||||
hasCharacterThoughts: !!committedTrackerData.characterThoughts
|
// hasCharacterThoughts: !!committedTrackerData.characterThoughts
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (extensionSettings.showUserStats && committedTrackerData.userStats) {
|
if (extensionSettings.showUserStats && committedTrackerData.userStats) {
|
||||||
// Try to parse as JSON first, otherwise treat as text
|
// Try to parse as JSON first, otherwise treat as text
|
||||||
@@ -285,7 +285,7 @@ export function generateTrackerExample() {
|
|||||||
example = '{\n' + parts.join(',\n') + '\n}';
|
example = '{\n' + parts.join(',\n') + '\n}';
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] generateTrackerExample - result length:', example.length, 'parts:', parts.length);
|
// console.log('[RPG Companion] generateTrackerExample - result length:', example.length, 'parts:', parts.length);
|
||||||
|
|
||||||
return example.trim();
|
return example.trim();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
$musicPlayerContainer
|
$musicPlayerContainer
|
||||||
} from '../../core/state.js';
|
} from '../../core/state.js';
|
||||||
import { saveChatData, loadChatData } from '../../core/persistence.js';
|
import { saveChatData, loadChatData } from '../../core/persistence.js';
|
||||||
|
import { i18n } from '../../core/i18n.js';
|
||||||
|
|
||||||
// Generation & Parsing
|
// Generation & Parsing
|
||||||
import { parseResponse, parseUserStats } from '../generation/parser.js';
|
import { parseResponse, parseUserStats } from '../generation/parser.js';
|
||||||
@@ -88,7 +89,7 @@ export function commitTrackerData() {
|
|||||||
export function onMessageSent() {
|
export function onMessageSent() {
|
||||||
if (!extensionSettings.enabled) return;
|
if (!extensionSettings.enabled) return;
|
||||||
|
|
||||||
console.log('[RPG Companion] 🟢 EVENT: onMessageSent - lastActionWasSwipe =', lastActionWasSwipe);
|
// console.log('[RPG Companion] 🟢 EVENT: onMessageSent - lastActionWasSwipe =', lastActionWasSwipe);
|
||||||
|
|
||||||
// Check if this is a streaming placeholder message (content = "...")
|
// Check if this is a streaming placeholder message (content = "...")
|
||||||
// When streaming is on, ST sends a "..." placeholder before generation starts
|
// When streaming is on, ST sends a "..." placeholder before generation starts
|
||||||
@@ -97,12 +98,12 @@ export function onMessageSent() {
|
|||||||
const lastMessage = chat && chat.length > 0 ? chat[chat.length - 1] : null;
|
const lastMessage = chat && chat.length > 0 ? chat[chat.length - 1] : null;
|
||||||
|
|
||||||
if (lastMessage && lastMessage.mes === '...') {
|
if (lastMessage && lastMessage.mes === '...') {
|
||||||
console.log('[RPG Companion] 🟢 Ignoring onMessageSent: streaming placeholder message');
|
// console.log('[RPG Companion] 🟢 Ignoring onMessageSent: streaming placeholder message');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] 🟢 EVENT: onMessageSent (after placeholder check)');
|
// console.log('[RPG Companion] 🟢 EVENT: onMessageSent (after placeholder check)');
|
||||||
console.log('[RPG Companion] 🟢 NOTE: lastActionWasSwipe will be reset in onMessageReceived after generation completes');
|
// console.log('[RPG Companion] 🟢 NOTE: lastActionWasSwipe will be reset in onMessageReceived after generation completes');
|
||||||
|
|
||||||
// For separate mode with auto-update disabled, commit displayed tracker
|
// For separate mode with auto-update disabled, commit displayed tracker
|
||||||
if (extensionSettings.generationMode === 'separate' && !extensionSettings.autoUpdate) {
|
if (extensionSettings.generationMode === 'separate' && !extensionSettings.autoUpdate) {
|
||||||
@@ -111,7 +112,7 @@ export function onMessageSent() {
|
|||||||
committedTrackerData.infoBox = lastGeneratedData.infoBox;
|
committedTrackerData.infoBox = lastGeneratedData.infoBox;
|
||||||
committedTrackerData.characterThoughts = lastGeneratedData.characterThoughts;
|
committedTrackerData.characterThoughts = lastGeneratedData.characterThoughts;
|
||||||
|
|
||||||
console.log('[RPG Companion] 💾 SEPARATE MODE: Committed displayed tracker (auto-update disabled)');
|
// console.log('[RPG Companion] 💾 SEPARATE MODE: Committed displayed tracker (auto-update disabled)');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +121,7 @@ export function onMessageSent() {
|
|||||||
* Event handler for when a message is generated.
|
* Event handler for when a message is generated.
|
||||||
*/
|
*/
|
||||||
export async function onMessageReceived(data) {
|
export async function onMessageReceived(data) {
|
||||||
console.log('[RPG Companion] onMessageReceived called, lastActionWasSwipe:', lastActionWasSwipe);
|
// console.log('[RPG Companion] onMessageReceived called, lastActionWasSwipe:', lastActionWasSwipe);
|
||||||
|
|
||||||
if (!extensionSettings.enabled) {
|
if (!extensionSettings.enabled) {
|
||||||
return;
|
return;
|
||||||
@@ -129,7 +130,7 @@ export async function onMessageReceived(data) {
|
|||||||
// Reset swipe flag after generation completes
|
// Reset swipe flag after generation completes
|
||||||
// This ensures next user message (whether from original or swipe) triggers commit
|
// This ensures next user message (whether from original or swipe) triggers commit
|
||||||
setLastActionWasSwipe(false);
|
setLastActionWasSwipe(false);
|
||||||
console.log('[RPG Companion] 🟢 Reset lastActionWasSwipe = false (generation completed)');
|
// console.log('[RPG Companion] 🟢 Reset lastActionWasSwipe = false (generation completed)');
|
||||||
|
|
||||||
if (extensionSettings.generationMode === 'together') {
|
if (extensionSettings.generationMode === 'together') {
|
||||||
// In together mode, parse the response to extract RPG data
|
// In together mode, parse the response to extract RPG data
|
||||||
@@ -139,6 +140,11 @@ export async function onMessageReceived(data) {
|
|||||||
const responseText = lastMessage.mes;
|
const responseText = lastMessage.mes;
|
||||||
const parsedData = parseResponse(responseText);
|
const parsedData = parseResponse(responseText);
|
||||||
|
|
||||||
|
// Check if parsing completely failed (no tracker data found)
|
||||||
|
if (parsedData.parsingFailed) {
|
||||||
|
toastr.error(i18n.getTranslation('errors.parsingError'), '', { timeOut: 5000 });
|
||||||
|
}
|
||||||
|
|
||||||
// Remove locks from parsed data (JSON format only, text format is unaffected)
|
// Remove locks from parsed data (JSON format only, text format is unaffected)
|
||||||
if (parsedData.userStats) {
|
if (parsedData.userStats) {
|
||||||
parsedData.userStats = removeLocks(parsedData.userStats);
|
parsedData.userStats = removeLocks(parsedData.userStats);
|
||||||
@@ -154,7 +160,7 @@ export async function onMessageReceived(data) {
|
|||||||
parseAndStoreSpotifyUrl(responseText);
|
parseAndStoreSpotifyUrl(responseText);
|
||||||
|
|
||||||
// Update display data with newly parsed response
|
// Update display data with newly parsed response
|
||||||
console.log('[RPG Companion] 📝 TOGETHER MODE: Updating lastGeneratedData with parsed response');
|
// console.log('[RPG Companion] 📝 TOGETHER MODE: Updating lastGeneratedData with parsed response');
|
||||||
if (parsedData.userStats) {
|
if (parsedData.userStats) {
|
||||||
lastGeneratedData.userStats = parsedData.userStats;
|
lastGeneratedData.userStats = parsedData.userStats;
|
||||||
parseUserStats(parsedData.userStats);
|
parseUserStats(parsedData.userStats);
|
||||||
@@ -227,8 +233,8 @@ export async function onMessageReceived(data) {
|
|||||||
// Save to chat metadata
|
// Save to chat metadata
|
||||||
saveChatData();
|
saveChatData();
|
||||||
}
|
}
|
||||||
} else if (extensionSettings.generationMode === 'separate') {
|
} else if (extensionSettings.generationMode === 'separate' || extensionSettings.generationMode === 'external') {
|
||||||
// In separate mode, also parse Spotify URLs from the main roleplay response
|
// In separate/external mode, also parse Spotify URLs from the main roleplay response
|
||||||
const lastMessage = chat[chat.length - 1];
|
const lastMessage = chat[chat.length - 1];
|
||||||
if (lastMessage && !lastMessage.is_user) {
|
if (lastMessage && !lastMessage.is_user) {
|
||||||
const responseText = lastMessage.mes;
|
const responseText = lastMessage.mes;
|
||||||
@@ -243,7 +249,7 @@ export async function onMessageReceived(data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger auto-update if enabled
|
// Trigger auto-update if enabled (for both separate and external modes)
|
||||||
if (extensionSettings.autoUpdate) {
|
if (extensionSettings.autoUpdate) {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await updateRPGData(renderUserStats, renderInfoBox, renderThoughts, renderInventory);
|
await updateRPGData(renderUserStats, renderInfoBox, renderThoughts, renderInventory);
|
||||||
@@ -313,12 +319,12 @@ export function onMessageSwiped(messageIndex) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] 🔵 EVENT: onMessageSwiped at index:', messageIndex);
|
// console.log('[RPG Companion] 🔵 EVENT: onMessageSwiped at index:', messageIndex);
|
||||||
|
|
||||||
// Get the message that was swiped
|
// Get the message that was swiped
|
||||||
const message = chat[messageIndex];
|
const message = chat[messageIndex];
|
||||||
if (!message || message.is_user) {
|
if (!message || message.is_user) {
|
||||||
console.log('[RPG Companion] 🔵 Ignoring swipe - message is user or undefined');
|
// console.log('[RPG Companion] 🔵 Ignoring swipe - message is user or undefined');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,10 +340,10 @@ export function onMessageSwiped(messageIndex) {
|
|||||||
if (!isExistingSwipe) {
|
if (!isExistingSwipe) {
|
||||||
// This is a NEW swipe that will trigger generation
|
// This is a NEW swipe that will trigger generation
|
||||||
setLastActionWasSwipe(true);
|
setLastActionWasSwipe(true);
|
||||||
console.log('[RPG Companion] 🔵 NEW swipe detected - Set lastActionWasSwipe = true');
|
// console.log('[RPG Companion] 🔵 NEW swipe detected - Set lastActionWasSwipe = true');
|
||||||
} else {
|
} else {
|
||||||
// This is navigating to an EXISTING swipe - don't change the flag
|
// This is navigating to an EXISTING swipe - don't change the flag
|
||||||
console.log('[RPG Companion] 🔵 EXISTING swipe navigation - lastActionWasSwipe unchanged =', lastActionWasSwipe);
|
// console.log('[RPG Companion] 🔵 EXISTING swipe navigation - lastActionWasSwipe unchanged =', lastActionWasSwipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('[RPG Companion] Loading data for swipe', currentSwipeId);
|
// console.log('[RPG Companion] Loading data for swipe', currentSwipeId);
|
||||||
@@ -358,9 +364,9 @@ export function onMessageSwiped(messageIndex) {
|
|||||||
parseUserStats(swipeData.userStats);
|
parseUserStats(swipeData.userStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] 🔄 Loaded swipe data into lastGeneratedData for display:', currentSwipeId);
|
// console.log('[RPG Companion] 🔄 Loaded swipe data into lastGeneratedData for display:', currentSwipeId);
|
||||||
} else {
|
} else {
|
||||||
console.log('[RPG Companion] ℹ️ No stored data for swipe:', currentSwipeId);
|
// console.log('[RPG Companion] ℹ️ No stored data for swipe:', currentSwipeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-render the panels
|
// Re-render the panels
|
||||||
@@ -428,7 +434,7 @@ export function clearExtensionPrompts() {
|
|||||||
* Re-applies checkpoint if SillyTavern unhid messages
|
* Re-applies checkpoint if SillyTavern unhid messages
|
||||||
*/
|
*/
|
||||||
export async function onGenerationEnded() {
|
export async function onGenerationEnded() {
|
||||||
console.log('[RPG Companion] 🏁 onGenerationEnded called');
|
// console.log('[RPG Companion] 🏁 onGenerationEnded called');
|
||||||
|
|
||||||
// Note: isGenerating flag is cleared in onMessageReceived after parsing (together mode)
|
// Note: isGenerating flag is cleared in onMessageReceived after parsing (together mode)
|
||||||
// or in apiClient.js after separate generation completes (separate mode)
|
// or in apiClient.js after separate generation completes (separate mode)
|
||||||
|
|||||||
@@ -75,23 +75,23 @@ function separateEmojiFromText(str) {
|
|||||||
* Includes event listeners for editable fields.
|
* Includes event listeners for editable fields.
|
||||||
*/
|
*/
|
||||||
export function renderInfoBox() {
|
export function renderInfoBox() {
|
||||||
console.log('[RPG InfoBox Render] ==================== RENDERING INFO BOX ====================');
|
// console.log('[RPG InfoBox Render] ==================== RENDERING INFO BOX ====================');
|
||||||
console.log('[RPG InfoBox Render] showInfoBox setting:', extensionSettings.showInfoBox);
|
// console.log('[RPG InfoBox Render] showInfoBox setting:', extensionSettings.showInfoBox);
|
||||||
console.log('[RPG InfoBox Render] Container exists:', !!$infoBoxContainer);
|
// console.log('[RPG InfoBox Render] Container exists:', !!$infoBoxContainer);
|
||||||
|
|
||||||
if (!extensionSettings.showInfoBox || !$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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use committedTrackerData as fallback if lastGeneratedData is empty (e.g., after page refresh)
|
// Use committedTrackerData as fallback if lastGeneratedData is empty (e.g., after page refresh)
|
||||||
const infoBoxData = lastGeneratedData.infoBox || committedTrackerData.infoBox;
|
const infoBoxData = lastGeneratedData.infoBox || committedTrackerData.infoBox;
|
||||||
console.log('[RPG InfoBox Render] infoBoxData length:', infoBoxData ? infoBoxData.length : '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');
|
// 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 no data yet, hide the container (e.g., after cache clear)
|
||||||
if (!infoBoxData) {
|
if (!infoBoxData) {
|
||||||
console.log('[RPG InfoBox Render] No data, hiding container');
|
// console.log('[RPG InfoBox Render] No data, hiding container');
|
||||||
$infoBoxContainer.empty().hide();
|
$infoBoxContainer.empty().hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -574,6 +574,19 @@ export function renderInfoBox() {
|
|||||||
|
|
||||||
$infoBoxContainer.html(html);
|
$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
|
// Add event handlers for editable Info Box fields
|
||||||
$infoBoxContainer.find('.rpg-editable').on('blur', function() {
|
$infoBoxContainer.find('.rpg-editable').on('blur', function() {
|
||||||
const $this = $(this);
|
const $this = $(this);
|
||||||
@@ -591,6 +604,11 @@ export function renderInfoBox() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update location text size dynamically
|
||||||
|
if (field === 'location') {
|
||||||
|
updateLocationTextSize($this);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle recent events separately
|
// Handle recent events separately
|
||||||
if (field === 'event1' || field === 'event2' || field === 'event3') {
|
if (field === 'event1' || field === 'event2' || field === 'event3') {
|
||||||
updateRecentEvent(field, value);
|
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
|
// For date fields, show full value on focus
|
||||||
$infoBoxContainer.find('[data-field="month"], [data-field="weekday"], [data-field="year"]').on('focus', function() {
|
$infoBoxContainer.find('[data-field="month"], [data-field="weekday"], [data-field="year"]').on('focus', function() {
|
||||||
const fullValue = $(this).data('full-value');
|
const fullValue = $(this).data('full-value');
|
||||||
@@ -707,7 +730,7 @@ export function updateInfoBoxField(field, value) {
|
|||||||
committedTrackerData.infoBox = lastGeneratedData.infoBox;
|
committedTrackerData.infoBox = lastGeneratedData.infoBox;
|
||||||
saveChatData();
|
saveChatData();
|
||||||
renderInfoBox();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1061,6 +1084,6 @@ function updateRecentEvent(field, value) {
|
|||||||
window.RPGCompanion.updateWeatherEffect();
|
window.RPGCompanion.updateWeatherEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[RPG Companion] Updated recent event ${field}:`, value);
|
// console.log(`[RPG Companion] Updated recent event ${field}:`, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ export function renderMusicPlayer(container) {
|
|||||||
// Find the chat form container and insert widget before (above) it
|
// Find the chat form container and insert widget before (above) it
|
||||||
const $chatForm = $('#send_form');
|
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) {
|
if ($chatForm.length === 0) {
|
||||||
console.error('[RPG Companion] Music Player: Could not find #send_form - cannot render widget!');
|
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
|
// 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);
|
$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');
|
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) {
|
if ($widget.length > 0) {
|
||||||
console.log('[RPG Companion] Music Player: Widget position:', $widget.offset());
|
// 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 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 display:', $widget.css('display'));
|
||||||
console.log('[RPG Companion] Music Player: Widget CSS visibility:', $widget.css('visibility'));
|
// console.log('[RPG Companion] Music Player: Widget CSS visibility:', $widget.css('visibility'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind play button click
|
// Bind play button click
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ function getLockIconHtml(tracker, path) {
|
|||||||
* Helper to log to both console and debug logs array
|
* Helper to log to both console and debug logs array
|
||||||
*/
|
*/
|
||||||
function debugLog(message, data = null) {
|
function debugLog(message, data = null) {
|
||||||
console.log(message, data || '');
|
// console.log(message, data || '');
|
||||||
if (extensionSettings.debugMode) {
|
if (extensionSettings.debugMode) {
|
||||||
addDebugLog(message, data);
|
addDebugLog(message, data);
|
||||||
}
|
}
|
||||||
@@ -592,7 +592,7 @@ export function renderThoughts() {
|
|||||||
const character = $(this).data('character');
|
const character = $(this).data('character');
|
||||||
const field = $(this).data('field');
|
const field = $(this).data('field');
|
||||||
const value = $(this).text().trim();
|
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);
|
updateCharacterField(character, field, value);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -723,7 +723,7 @@ export function updateCharacterField(characterName, field, value) {
|
|||||||
else if (isThoughtsField && line.startsWith(thoughtsFieldName + ':')) {
|
else if (isThoughtsField && line.startsWith(thoughtsFieldName + ':')) {
|
||||||
// Update thoughts field
|
// Update thoughts field
|
||||||
lines[i] = `${thoughtsFieldName}: ${value}`;
|
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));
|
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) {
|
if (statsLineExists) {
|
||||||
// Update existing Stats line
|
// Update existing Stats line
|
||||||
@@ -750,7 +750,7 @@ export function updateCharacterField(characterName, field, value) {
|
|||||||
if (statParts[j].startsWith(field + ':')) {
|
if (statParts[j].startsWith(field + ':')) {
|
||||||
statParts[j] = `${field}: ${numValue}%`;
|
statParts[j] = `${field}: ${numValue}%`;
|
||||||
statFound = true;
|
statFound = true;
|
||||||
console.log('[RPG Companion] Updated stat part:', statParts[j]);
|
// console.log('[RPG Companion] Updated stat part:', statParts[j]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -758,11 +758,11 @@ export function updateCharacterField(characterName, field, value) {
|
|||||||
// If stat wasn't found in existing parts, add it
|
// If stat wasn't found in existing parts, add it
|
||||||
if (!statFound) {
|
if (!statFound) {
|
||||||
statParts.push(`${field}: ${numValue}%`);
|
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(' | ')}`;
|
lines[statsLineIndex] = `Stats: ${statParts.join(' | ')}`;
|
||||||
console.log('[RPG Companion] Updated stats line:', lines[statsLineIndex]);
|
// console.log('[RPG Companion] Updated stats line:', lines[statsLineIndex]);
|
||||||
} else {
|
} else {
|
||||||
// Create new Stats line with all enabled stats (defaulting to 0% except the one being edited)
|
// Create new Stats line with all enabled stats (defaulting to 0% except the one being edited)
|
||||||
const statsParts = enabledCharStats.map(s => {
|
const statsParts = enabledCharStats.map(s => {
|
||||||
@@ -785,7 +785,7 @@ export function updateCharacterField(characterName, field, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lines.splice(insertIndex, 0, newStatsLine);
|
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
|
characterEndIndex++; // Adjust end index since we inserted a line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -831,7 +831,7 @@ export function updateCharacterField(characterName, field, value) {
|
|||||||
lastGeneratedData.characterThoughts = lines.join('\n');
|
lastGeneratedData.characterThoughts = lines.join('\n');
|
||||||
committedTrackerData.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;
|
const chat = getContext().chat;
|
||||||
if (chat && chat.length > 0) {
|
if (chat && chat.length > 0) {
|
||||||
@@ -1075,12 +1075,12 @@ function initThoughtIconDragHandlers() {
|
|||||||
if (thoughtIconDragHandlersInitialized) return;
|
if (thoughtIconDragHandlersInitialized) return;
|
||||||
thoughtIconDragHandlersInitialized = true;
|
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 to attach drag handlers to a specific icon element
|
||||||
function attachDragHandlersToIcon($icon) {
|
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
|
// Remove any existing handlers
|
||||||
$icon.off('.thoughtIconDrag');
|
$icon.off('.thoughtIconDrag');
|
||||||
@@ -1089,20 +1089,20 @@ function attachDragHandlersToIcon($icon) {
|
|||||||
$icon.on('click.thoughtIconDrag', function(e) {
|
$icon.on('click.thoughtIconDrag', function(e) {
|
||||||
// Check global flag set immediately after drag completes
|
// Check global flag set immediately after drag completes
|
||||||
if (justFinishedDragging) {
|
if (justFinishedDragging) {
|
||||||
console.log('[Thought Icon] CLICK blocked - just finished dragging');
|
// console.log('[Thought Icon] CLICK blocked - just finished dragging');
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
console.log('[Thought Icon] CLICK detected on icon!');
|
// console.log('[Thought Icon] CLICK detected on icon!');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Touch drag support - mobile only
|
// Touch drag support - mobile only
|
||||||
$icon.on('touchstart.thoughtIconDrag', function(e) {
|
$icon.on('touchstart.thoughtIconDrag', function(e) {
|
||||||
if (window.innerWidth > 1000) return;
|
if (window.innerWidth > 1000) return;
|
||||||
|
|
||||||
console.log('[Thought Icon] touchstart');
|
// console.log('[Thought Icon] touchstart');
|
||||||
touchMoved = false;
|
touchMoved = false;
|
||||||
dragStartTime = Date.now();
|
dragStartTime = Date.now();
|
||||||
const touch = e.originalEvent.touches[0];
|
const touch = e.originalEvent.touches[0];
|
||||||
@@ -1120,7 +1120,7 @@ function attachDragHandlersToIcon($icon) {
|
|||||||
if (window.innerWidth > 1000) return;
|
if (window.innerWidth > 1000) return;
|
||||||
|
|
||||||
if (!touchMoved) {
|
if (!touchMoved) {
|
||||||
console.log('[Thought Icon] touchmove - first movement');
|
// console.log('[Thought Icon] touchmove - first movement');
|
||||||
}
|
}
|
||||||
touchMoved = true;
|
touchMoved = true;
|
||||||
const touch = e.originalEvent.touches[0];
|
const touch = e.originalEvent.touches[0];
|
||||||
@@ -1160,7 +1160,7 @@ function attachDragHandlersToIcon($icon) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$icon.on('touchend.thoughtIconDrag', function(e) {
|
$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) {
|
if (isDragging) {
|
||||||
const offset = $(this).offset();
|
const offset = $(this).offset();
|
||||||
@@ -1193,7 +1193,7 @@ function attachDragHandlersToIcon($icon) {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
} else if (!touchMoved) {
|
} 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 $panel = $('#rpg-thought-panel');
|
||||||
const iconOffset = $(this).offset();
|
const iconOffset = $(this).offset();
|
||||||
if (iconOffset) {
|
if (iconOffset) {
|
||||||
@@ -1207,7 +1207,7 @@ function attachDragHandlersToIcon($icon) {
|
|||||||
$(this).addClass('rpg-hidden');
|
$(this).addClass('rpg-hidden');
|
||||||
$panel.fadeIn(200);
|
$panel.fadeIn(200);
|
||||||
} else {
|
} 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) {
|
$icon.on('mousedown.thoughtIconDrag', function(e) {
|
||||||
if (window.innerWidth > 1000) return;
|
if (window.innerWidth > 1000) return;
|
||||||
|
|
||||||
console.log('[Thought Icon] mousedown');
|
// console.log('[Thought Icon] mousedown');
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
mouseDown = true;
|
mouseDown = true;
|
||||||
@@ -1237,7 +1237,7 @@ function attachDragHandlersToIcon($icon) {
|
|||||||
if (!mouseDown || window.innerWidth > 1000) return;
|
if (!mouseDown || window.innerWidth > 1000) return;
|
||||||
|
|
||||||
if (!touchMoved) {
|
if (!touchMoved) {
|
||||||
console.log('[Thought Icon] mousemove - first movement');
|
// console.log('[Thought Icon] mousemove - first movement');
|
||||||
}
|
}
|
||||||
touchMoved = true;
|
touchMoved = true;
|
||||||
|
|
||||||
@@ -1280,7 +1280,7 @@ function attachDragHandlersToIcon($icon) {
|
|||||||
$(document).on('mouseup.thoughtIconDrag', function(e) {
|
$(document).on('mouseup.thoughtIconDrag', function(e) {
|
||||||
if (!mouseDown) return;
|
if (!mouseDown) return;
|
||||||
|
|
||||||
console.log('[Thought Icon] mouseup - isDragging:', isDragging, 'touchMoved:', touchMoved);
|
// console.log('[Thought Icon] mouseup - isDragging:', isDragging, 'touchMoved:', touchMoved);
|
||||||
|
|
||||||
mouseDown = false;
|
mouseDown = false;
|
||||||
|
|
||||||
@@ -1568,22 +1568,82 @@ export function createThoughtPanel($message, thoughtsArray) {
|
|||||||
// Load saved icon position in mobile, or default to center of viewport
|
// Load saved icon position in mobile, or default to center of viewport
|
||||||
if (extensionSettings.thoughtIconPosition && extensionSettings.thoughtIconPosition.top && extensionSettings.thoughtIconPosition.left) {
|
if (extensionSettings.thoughtIconPosition && extensionSettings.thoughtIconPosition.top && extensionSettings.thoughtIconPosition.left) {
|
||||||
const pos = extensionSettings.thoughtIconPosition;
|
const pos = extensionSettings.thoughtIconPosition;
|
||||||
$thoughtIcon.css({
|
|
||||||
top: pos.top,
|
// Validate saved position - check if it's not at the very top (likely invalid)
|
||||||
left: pos.left,
|
const savedTop = parseInt(pos.top);
|
||||||
transform: 'none',
|
const topBar = $('#top-settings-holder');
|
||||||
right: 'auto',
|
const topBarHeight = topBar.length ? topBar.outerHeight() : 60;
|
||||||
bottom: 'auto'
|
|
||||||
});
|
// 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 {
|
} else {
|
||||||
// Default position: center of viewport
|
// Default position: center-right of viewport, accounting for top bar
|
||||||
$thoughtIcon.css({
|
// Use setTimeout to ensure DOM is fully rendered before calculating positions
|
||||||
top: '50%',
|
setTimeout(() => {
|
||||||
left: '50%',
|
const topBar = $('#top-settings-holder');
|
||||||
transform: 'translate(-50%, -50%)',
|
const topBarHeight = topBar.length ? topBar.outerHeight() : 60;
|
||||||
right: 'auto',
|
const viewportHeight = window.innerHeight;
|
||||||
bottom: 'auto'
|
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 {
|
} else {
|
||||||
// Desktop: show panel, hide icon with class
|
// Desktop: show panel, hide icon with class
|
||||||
|
|||||||
@@ -181,12 +181,12 @@ export function renderUserStats() {
|
|||||||
|
|
||||||
// Don't render if no data exists (e.g., after cache clear)
|
// Don't render if no data exists (e.g., after cache clear)
|
||||||
// Check both lastGeneratedData and committedTrackerData
|
// Check both lastGeneratedData and committedTrackerData
|
||||||
console.log('[RPG UserStats Render] Checking data:', {
|
// console.log('[RPG UserStats Render] Checking data:', {
|
||||||
hasLastGenerated: !!lastGeneratedData.userStats,
|
// hasLastGenerated: !!lastGeneratedData.userStats,
|
||||||
hasCommitted: !!committedTrackerData.userStats,
|
// hasCommitted: !!committedTrackerData.userStats,
|
||||||
lastGeneratedPreview: lastGeneratedData.userStats ? lastGeneratedData.userStats.substring(0, 100) : 'null',
|
// lastGeneratedPreview: lastGeneratedData.userStats ? lastGeneratedData.userStats.substring(0, 100) : 'null',
|
||||||
committedPreview: committedTrackerData.userStats ? committedTrackerData.userStats.substring(0, 100) : 'null'
|
// committedPreview: committedTrackerData.userStats ? committedTrackerData.userStats.substring(0, 100) : 'null'
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (!lastGeneratedData.userStats && !committedTrackerData.userStats) {
|
if (!lastGeneratedData.userStats && !committedTrackerData.userStats) {
|
||||||
// Always render to the #rpg-user-stats container (mobile layout just moves it around in DOM)
|
// 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;
|
const stats = extensionSettings.userStats;
|
||||||
console.log('[RPG UserStats Render] Current extensionSettings.userStats:', {
|
// console.log('[RPG UserStats Render] Current extensionSettings.userStats:', {
|
||||||
health: stats.health,
|
// health: stats.health,
|
||||||
satiety: stats.satiety,
|
// satiety: stats.satiety,
|
||||||
energy: stats.energy,
|
// energy: stats.energy,
|
||||||
hygiene: stats.hygiene,
|
// hygiene: stats.hygiene,
|
||||||
arousal: stats.arousal,
|
// arousal: stats.arousal,
|
||||||
mood: stats.mood,
|
// mood: stats.mood,
|
||||||
conditions: stats.conditions
|
// conditions: stats.conditions
|
||||||
});
|
// });
|
||||||
const config = extensionSettings.trackerConfig?.userStats || {
|
const config = extensionSettings.trackerConfig?.userStats || {
|
||||||
customStats: [
|
customStats: [
|
||||||
{ id: 'health', name: 'Health', enabled: true },
|
{ id: 'health', name: 'Health', enabled: true },
|
||||||
@@ -394,13 +394,13 @@ export function renderUserStats() {
|
|||||||
|
|
||||||
html += '</div>'; // Close rpg-stats-content
|
html += '</div>'; // Close rpg-stats-content
|
||||||
|
|
||||||
console.log('[RPG UserStats Render] Generated HTML length:', html.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] HTML preview:', html.substring(0, 300));
|
||||||
console.log('[RPG UserStats Render] Container exists:', !!$userStatsContainer, '$userStatsContainer length:', $userStatsContainer?.length);
|
// 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)
|
// Always render to the #rpg-user-stats container (mobile layout just moves it around in DOM)
|
||||||
$userStatsContainer.html(html);
|
$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
|
// Add event listeners for editable stat values
|
||||||
$('.rpg-editable-stat').on('blur', function() {
|
$('.rpg-editable-stat').on('blur', function() {
|
||||||
|
|||||||
@@ -1001,7 +1001,7 @@ export class EncounterModal {
|
|||||||
{ clearChatInput: false }
|
{ clearChatInput: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`[RPG Companion] Added combat summary to chat as "${speakerName}"`);
|
// console.log(`[RPG Companion] Added combat summary to chat as "${speakerName}"`);
|
||||||
|
|
||||||
// Update combat over screen
|
// Update combat over screen
|
||||||
this.updateCombatOverScreen(true, speakerName);
|
this.updateCombatOverScreen(true, speakerName);
|
||||||
@@ -1259,7 +1259,7 @@ export class EncounterModal {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] Regenerating request:', this.lastRequest.type);
|
// console.log('[RPG Companion] Regenerating request:', this.lastRequest.type);
|
||||||
|
|
||||||
if (this.lastRequest.type === 'init') {
|
if (this.lastRequest.type === 'init') {
|
||||||
// Retry initialization
|
// Retry initialization
|
||||||
@@ -1327,7 +1327,7 @@ export class EncounterModal {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] Regenerating request:', this.lastRequest.type);
|
// console.log('[RPG Companion] Regenerating request:', this.lastRequest.type);
|
||||||
|
|
||||||
if (this.lastRequest.type === 'init') {
|
if (this.lastRequest.type === 'init') {
|
||||||
// Retry initialization
|
// Retry initialization
|
||||||
@@ -1369,7 +1369,7 @@ export class EncounterModal {
|
|||||||
this.modal.setAttribute('data-weather', weather.toLowerCase());
|
this.modal.setAttribute('data-weather', weather.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Companion] Applied environment styling:', styleNotes);
|
// console.log('[RPG Companion] Applied environment styling:', styleNotes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+42
-42
@@ -92,12 +92,12 @@ export function updateCollapseToggleIcon() {
|
|||||||
const isOpen = $panel.hasClass('rpg-mobile-open');
|
const isOpen = $panel.hasClass('rpg-mobile-open');
|
||||||
const isLeftPanel = $panel.hasClass('rpg-position-left');
|
const isLeftPanel = $panel.hasClass('rpg-position-left');
|
||||||
|
|
||||||
console.log('[RPG Mobile] updateCollapseToggleIcon:', {
|
// console.log('[RPG Mobile] updateCollapseToggleIcon:', {
|
||||||
isMobile: true,
|
// isMobile: true,
|
||||||
isOpen,
|
// isOpen,
|
||||||
isLeftPanel,
|
// isLeftPanel,
|
||||||
settingIcon: isOpen ? (isLeftPanel ? 'chevron-left' : 'chevron-right') : (isLeftPanel ? 'chevron-right' : 'chevron-left')
|
// settingIcon: isOpen ? (isLeftPanel ? 'chevron-left' : 'chevron-right') : (isLeftPanel ? 'chevron-right' : 'chevron-left')
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (isLeftPanel) {
|
if (isLeftPanel) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
@@ -157,44 +157,44 @@ export function setupCollapseToggle() {
|
|||||||
// On mobile: button toggles panel open/closed (same as desktop behavior)
|
// On mobile: button toggles panel open/closed (same as desktop behavior)
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const isOpen = $panel.hasClass('rpg-mobile-open');
|
const isOpen = $panel.hasClass('rpg-mobile-open');
|
||||||
console.log('[RPG Mobile] Collapse toggle clicked. Current state:', {
|
// console.log('[RPG Mobile] Collapse toggle clicked. Current state:', {
|
||||||
isOpen,
|
// isOpen,
|
||||||
panelClasses: $panel.attr('class'),
|
// panelClasses: $panel.attr('class'),
|
||||||
inlineStyles: $panel.attr('style'),
|
// inlineStyles: $panel.attr('style'),
|
||||||
panelPosition: {
|
// panelPosition: {
|
||||||
top: $panel.css('top'),
|
// top: $panel.css('top'),
|
||||||
bottom: $panel.css('bottom'),
|
// bottom: $panel.css('bottom'),
|
||||||
transform: $panel.css('transform'),
|
// transform: $panel.css('transform'),
|
||||||
visibility: $panel.css('visibility')
|
// visibility: $panel.css('visibility')
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
// Close panel with animation
|
// Close panel with animation
|
||||||
console.log('[RPG Mobile] Closing panel');
|
// console.log('[RPG Mobile] Closing panel');
|
||||||
closeMobilePanelWithAnimation();
|
closeMobilePanelWithAnimation();
|
||||||
} else {
|
} else {
|
||||||
// Open panel
|
// Open panel
|
||||||
console.log('[RPG Mobile] Opening panel');
|
// console.log('[RPG Mobile] Opening panel');
|
||||||
$panel.addClass('rpg-mobile-open');
|
$panel.addClass('rpg-mobile-open');
|
||||||
const $overlay = $('<div class="rpg-mobile-overlay"></div>');
|
const $overlay = $('<div class="rpg-mobile-overlay"></div>');
|
||||||
$('body').append($overlay);
|
$('body').append($overlay);
|
||||||
|
|
||||||
// Debug: Check state after animation should complete
|
// Debug: Check state after animation should complete
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('[RPG Mobile] 500ms after opening:', {
|
// console.log('[RPG Mobile] 500ms after opening:', {
|
||||||
panelClasses: $panel.attr('class'),
|
// panelClasses: $panel.attr('class'),
|
||||||
hasOpenClass: $panel.hasClass('rpg-mobile-open'),
|
// hasOpenClass: $panel.hasClass('rpg-mobile-open'),
|
||||||
visibility: $panel.css('visibility'),
|
// visibility: $panel.css('visibility'),
|
||||||
transform: $panel.css('transform'),
|
// transform: $panel.css('transform'),
|
||||||
display: $panel.css('display'),
|
// display: $panel.css('display'),
|
||||||
opacity: $panel.css('opacity')
|
// opacity: $panel.css('opacity')
|
||||||
});
|
// });
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
// Close when clicking overlay
|
// Close when clicking overlay
|
||||||
$overlay.on('click', function() {
|
$overlay.on('click', function() {
|
||||||
console.log('[RPG Mobile] Overlay clicked - closing panel');
|
// console.log('[RPG Mobile] Overlay clicked - closing panel');
|
||||||
closeMobilePanelWithAnimation();
|
closeMobilePanelWithAnimation();
|
||||||
updateCollapseToggleIcon();
|
updateCollapseToggleIcon();
|
||||||
});
|
});
|
||||||
@@ -203,20 +203,20 @@ export function setupCollapseToggle() {
|
|||||||
// Update icon to reflect new state
|
// Update icon to reflect new state
|
||||||
updateCollapseToggleIcon();
|
updateCollapseToggleIcon();
|
||||||
|
|
||||||
console.log('[RPG Mobile] After toggle:', {
|
// console.log('[RPG Mobile] After toggle:', {
|
||||||
panelClasses: $panel.attr('class'),
|
// panelClasses: $panel.attr('class'),
|
||||||
inlineStyles: $panel.attr('style'),
|
// inlineStyles: $panel.attr('style'),
|
||||||
panelPosition: {
|
// panelPosition: {
|
||||||
top: $panel.css('top'),
|
// top: $panel.css('top'),
|
||||||
bottom: $panel.css('bottom'),
|
// bottom: $panel.css('bottom'),
|
||||||
transform: $panel.css('transform'),
|
// transform: $panel.css('transform'),
|
||||||
visibility: $panel.css('visibility')
|
// visibility: $panel.css('visibility')
|
||||||
},
|
// },
|
||||||
gameContainer: {
|
// gameContainer: {
|
||||||
opacity: $('.rpg-game-container').css('opacity'),
|
// opacity: $('.rpg-game-container').css('opacity'),
|
||||||
visibility: $('.rpg-game-container').css('visibility')
|
// visibility: $('.rpg-game-container').css('visibility')
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+51
-54
@@ -55,13 +55,13 @@ export function setupMobileToggle() {
|
|||||||
const $overlay = $('<div class="rpg-mobile-overlay"></div>');
|
const $overlay = $('<div class="rpg-mobile-overlay"></div>');
|
||||||
|
|
||||||
// DIAGNOSTIC: Check if elements exist and log setup state
|
// DIAGNOSTIC: Check if elements exist and log setup state
|
||||||
console.log('[RPG Mobile] ========================================');
|
// console.log('[RPG Mobile] ========================================');
|
||||||
console.log('[RPG Mobile] setupMobileToggle called');
|
// console.log('[RPG Mobile] setupMobileToggle called');
|
||||||
console.log('[RPG Mobile] Button exists:', $mobileToggle.length > 0, 'jQuery object:', $mobileToggle);
|
// console.log('[RPG Mobile] Button exists:', $mobileToggle.length > 0, 'jQuery object:', $mobileToggle);
|
||||||
console.log('[RPG Mobile] Panel exists:', $panel.length > 0);
|
// console.log('[RPG Mobile] Panel exists:', $panel.length > 0);
|
||||||
console.log('[RPG Mobile] Window width:', window.innerWidth);
|
// console.log('[RPG Mobile] Window width:', window.innerWidth);
|
||||||
console.log('[RPG Mobile] Is mobile viewport (<=1000):', window.innerWidth <= 1000);
|
// console.log('[RPG Mobile] Is mobile viewport (<=1000):', window.innerWidth <= 1000);
|
||||||
console.log('[RPG Mobile] ========================================');
|
// console.log('[RPG Mobile] ========================================');
|
||||||
|
|
||||||
if ($mobileToggle.length === 0) {
|
if ($mobileToggle.length === 0) {
|
||||||
console.error('[RPG Mobile] ERROR: Mobile toggle button not found in DOM!');
|
console.error('[RPG Mobile] ERROR: Mobile toggle button not found in DOM!');
|
||||||
@@ -72,7 +72,7 @@ export function setupMobileToggle() {
|
|||||||
// Load and apply saved FAB position
|
// Load and apply saved FAB position
|
||||||
if (extensionSettings.mobileFabPosition) {
|
if (extensionSettings.mobileFabPosition) {
|
||||||
const pos = extensionSettings.mobileFabPosition;
|
const pos = extensionSettings.mobileFabPosition;
|
||||||
console.log('[RPG Mobile] Loading saved FAB position:', pos);
|
// console.log('[RPG Mobile] Loading saved FAB position:', pos);
|
||||||
|
|
||||||
// Apply saved position
|
// Apply saved position
|
||||||
if (pos.top) $mobileToggle.css('top', pos.top);
|
if (pos.top) $mobileToggle.css('top', pos.top);
|
||||||
@@ -250,7 +250,7 @@ export function setupMobileToggle() {
|
|||||||
extensionSettings.mobileFabPosition = newPosition;
|
extensionSettings.mobileFabPosition = newPosition;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
console.log('[RPG Mobile] Saved new FAB position (mouse):', newPosition);
|
// console.log('[RPG Mobile] Saved new FAB position (mouse):', newPosition);
|
||||||
|
|
||||||
// Constrain to viewport bounds (now that position is saved)
|
// Constrain to viewport bounds (now that position is saved)
|
||||||
setTimeout(() => constrainFabToViewport(), 10);
|
setTimeout(() => constrainFabToViewport(), 10);
|
||||||
@@ -291,7 +291,7 @@ export function setupMobileToggle() {
|
|||||||
extensionSettings.mobileFabPosition = newPosition;
|
extensionSettings.mobileFabPosition = newPosition;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
console.log('[RPG Mobile] Saved new FAB position:', newPosition);
|
// console.log('[RPG Mobile] Saved new FAB position:', newPosition);
|
||||||
|
|
||||||
// Constrain to viewport bounds (now that position is saved)
|
// Constrain to viewport bounds (now that position is saved)
|
||||||
setTimeout(() => constrainFabToViewport(), 10);
|
setTimeout(() => constrainFabToViewport(), 10);
|
||||||
@@ -304,7 +304,7 @@ export function setupMobileToggle() {
|
|||||||
isDragging = false;
|
isDragging = false;
|
||||||
} else {
|
} else {
|
||||||
// Was a tap - toggle panel
|
// Was a tap - toggle panel
|
||||||
console.log('[RPG Mobile] Quick tap detected - toggling panel');
|
// console.log('[RPG Mobile] Quick tap detected - toggling panel');
|
||||||
|
|
||||||
if ($panel.hasClass('rpg-mobile-open')) {
|
if ($panel.hasClass('rpg-mobile-open')) {
|
||||||
// Close panel with animation
|
// Close panel with animation
|
||||||
@@ -327,28 +327,28 @@ export function setupMobileToggle() {
|
|||||||
$mobileToggle.on('click', function(e) {
|
$mobileToggle.on('click', function(e) {
|
||||||
// Skip if we just finished dragging
|
// Skip if we just finished dragging
|
||||||
if ($mobileToggle.data('just-dragged')) {
|
if ($mobileToggle.data('just-dragged')) {
|
||||||
console.log('[RPG Mobile] Click blocked - just finished dragging');
|
// console.log('[RPG Mobile] Click blocked - just finished dragging');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Mobile] >>> CLICK EVENT FIRED <<<', {
|
// console.log('[RPG Mobile] >>> CLICK EVENT FIRED <<<', {
|
||||||
windowWidth: window.innerWidth,
|
// windowWidth: window.innerWidth,
|
||||||
isMobileViewport: window.innerWidth <= 1000,
|
// isMobileViewport: window.innerWidth <= 1000,
|
||||||
panelOpen: $panel.hasClass('rpg-mobile-open')
|
// panelOpen: $panel.hasClass('rpg-mobile-open')
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Work on both mobile and desktop (removed viewport check)
|
// Work on both mobile and desktop (removed viewport check)
|
||||||
if ($panel.hasClass('rpg-mobile-open')) {
|
if ($panel.hasClass('rpg-mobile-open')) {
|
||||||
console.log('[RPG Mobile] Click: Closing panel');
|
// console.log('[RPG Mobile] Click: Closing panel');
|
||||||
closeMobilePanelWithAnimation();
|
closeMobilePanelWithAnimation();
|
||||||
} else {
|
} else {
|
||||||
console.log('[RPG Mobile] Click: Opening panel');
|
// console.log('[RPG Mobile] Click: Opening panel');
|
||||||
$panel.addClass('rpg-mobile-open');
|
$panel.addClass('rpg-mobile-open');
|
||||||
$('body').append($overlay);
|
$('body').append($overlay);
|
||||||
$mobileToggle.addClass('active');
|
$mobileToggle.addClass('active');
|
||||||
|
|
||||||
$overlay.on('click', function() {
|
$overlay.on('click', function() {
|
||||||
console.log('[RPG Mobile] Overlay clicked - closing panel');
|
// console.log('[RPG Mobile] Overlay clicked - closing panel');
|
||||||
closeMobilePanelWithAnimation();
|
closeMobilePanelWithAnimation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -367,7 +367,7 @@ export function setupMobileToggle() {
|
|||||||
|
|
||||||
// Transitioning from desktop to mobile - handle immediately for smooth transition
|
// Transitioning from desktop to mobile - handle immediately for smooth transition
|
||||||
if (!wasMobile && isMobile) {
|
if (!wasMobile && isMobile) {
|
||||||
console.log('[RPG Mobile] Transitioning desktop -> mobile');
|
// console.log('[RPG Mobile] Transitioning desktop -> mobile');
|
||||||
|
|
||||||
// Show mobile toggle button
|
// Show mobile toggle button
|
||||||
$mobileToggle.show();
|
$mobileToggle.show();
|
||||||
@@ -391,16 +391,16 @@ export function setupMobileToggle() {
|
|||||||
// Clear any inline styles that might be overriding CSS
|
// Clear any inline styles that might be overriding CSS
|
||||||
$panel.attr('style', '');
|
$panel.attr('style', '');
|
||||||
|
|
||||||
console.log('[RPG Mobile] After cleanup:', {
|
// console.log('[RPG Mobile] After cleanup:', {
|
||||||
panelClasses: $panel.attr('class'),
|
// panelClasses: $panel.attr('class'),
|
||||||
inlineStyles: $panel.attr('style'),
|
// inlineStyles: $panel.attr('style'),
|
||||||
panelPosition: {
|
// panelPosition: {
|
||||||
top: $panel.css('top'),
|
// top: $panel.css('top'),
|
||||||
bottom: $panel.css('bottom'),
|
// bottom: $panel.css('bottom'),
|
||||||
transform: $panel.css('transform'),
|
// transform: $panel.css('transform'),
|
||||||
visibility: $panel.css('visibility')
|
// visibility: $panel.css('visibility')
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Set up mobile tabs IMMEDIATELY (no debounce delay)
|
// Set up mobile tabs IMMEDIATELY (no debounce delay)
|
||||||
setupMobileTabs();
|
setupMobileTabs();
|
||||||
@@ -462,17 +462,14 @@ export function setupMobileToggle() {
|
|||||||
// Clear any inline styles
|
// Clear any inline styles
|
||||||
$panel.attr('style', '');
|
$panel.attr('style', '');
|
||||||
|
|
||||||
console.log('[RPG Mobile] Initial load on mobile viewport:', {
|
// console.log('[RPG Mobile] Initial load on mobile viewport:', {
|
||||||
panelClasses: $panel.attr('class'),
|
// panelClasses: $panel.attr('class'),
|
||||||
inlineStyles: $panel.attr('style'),
|
// inlineStyles: $panel.attr('style'),
|
||||||
panelPosition: {
|
// panelPosition: {
|
||||||
top: $panel.css('top'),
|
// top: $panel.css('top'),
|
||||||
bottom: $panel.css('top'),
|
// bottom: $panel.css('top'),
|
||||||
transform: $panel.css('transform'),
|
// transform: $panel.css('transform'),
|
||||||
visibility: $panel.css('visibility')
|
// visibility: $panel.css('visibility')\n // }\n // });\n setupMobileTabs();
|
||||||
}
|
|
||||||
});
|
|
||||||
setupMobileTabs();
|
|
||||||
// Set initial icon for mobile
|
// Set initial icon for mobile
|
||||||
updateCollapseToggleIcon();
|
updateCollapseToggleIcon();
|
||||||
// Show mobile toggle on mobile viewport
|
// Show mobile toggle on mobile viewport
|
||||||
@@ -491,7 +488,7 @@ export function setupMobileToggle() {
|
|||||||
export function constrainFabToViewport() {
|
export function constrainFabToViewport() {
|
||||||
// Only constrain if user has set a custom position
|
// Only constrain if user has set a custom position
|
||||||
if (!extensionSettings.mobileFabPosition) {
|
if (!extensionSettings.mobileFabPosition) {
|
||||||
console.log('[RPG Mobile] Skipping viewport constraint - using CSS defaults');
|
// console.log('[RPG Mobile] Skipping viewport constraint - using CSS defaults');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,7 +497,7 @@ export function constrainFabToViewport() {
|
|||||||
|
|
||||||
// Skip if button is not visible
|
// Skip if button is not visible
|
||||||
if (!$mobileToggle.is(':visible')) {
|
if (!$mobileToggle.is(':visible')) {
|
||||||
console.log('[RPG Mobile] Skipping viewport constraint - button not visible');
|
// console.log('[RPG Mobile] Skipping viewport constraint - button not visible');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,12 +527,12 @@ export function constrainFabToViewport() {
|
|||||||
|
|
||||||
// Only update if position changed
|
// Only update if position changed
|
||||||
if (newX !== currentX || newY !== currentY) {
|
if (newX !== currentX || newY !== currentY) {
|
||||||
console.log('[RPG Mobile] Constraining FAB to viewport:', {
|
// console.log('[RPG Mobile] Constraining FAB to viewport:', {
|
||||||
old: { x: currentX, y: currentY },
|
// old: { x: currentX, y: currentY },
|
||||||
new: { x: newX, y: newY },
|
// new: { x: newX, y: newY },
|
||||||
viewport: { width: window.innerWidth, height: window.innerHeight },
|
// viewport: { width: window.innerWidth, height: window.innerHeight },
|
||||||
topBarHeight
|
// topBarHeight
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Apply new position
|
// Apply new position
|
||||||
$mobileToggle.css({
|
$mobileToggle.css({
|
||||||
@@ -816,12 +813,12 @@ export function setupRefreshButtonDrag() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Mobile] setupRefreshButtonDrag called');
|
// console.log('[RPG Mobile] setupRefreshButtonDrag called');
|
||||||
|
|
||||||
// Load and apply saved position
|
// Load and apply saved position
|
||||||
if (extensionSettings.mobileRefreshPosition) {
|
if (extensionSettings.mobileRefreshPosition) {
|
||||||
const pos = extensionSettings.mobileRefreshPosition;
|
const pos = extensionSettings.mobileRefreshPosition;
|
||||||
console.log('[RPG Mobile] Loading saved refresh button position:', pos);
|
// console.log('[RPG Mobile] Loading saved refresh button position:', pos);
|
||||||
|
|
||||||
// Apply saved position
|
// Apply saved position
|
||||||
if (pos.top) $refreshBtn.css('top', pos.top);
|
if (pos.top) $refreshBtn.css('top', pos.top);
|
||||||
@@ -1031,12 +1028,12 @@ export function setupDebugButtonDrag() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[RPG Mobile] setupDebugButtonDrag called');
|
// console.log('[RPG Mobile] setupDebugButtonDrag called');
|
||||||
|
|
||||||
// Load and apply saved position
|
// Load and apply saved position
|
||||||
if (extensionSettings.debugFabPosition) {
|
if (extensionSettings.debugFabPosition) {
|
||||||
const pos = extensionSettings.debugFabPosition;
|
const pos = extensionSettings.debugFabPosition;
|
||||||
console.log('[RPG Mobile] Loading saved debug button position:', pos);
|
// console.log('[RPG Mobile] Loading saved debug button position:', pos);
|
||||||
|
|
||||||
// Apply saved position
|
// Apply saved position
|
||||||
if (pos.top) $debugBtn.css('top', pos.top);
|
if (pos.top) $debugBtn.css('top', pos.top);
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ export function setupSettingsPopup() {
|
|||||||
|
|
||||||
// Clear cache button
|
// Clear cache button
|
||||||
$('#rpg-clear-cache').on('click', function() {
|
$('#rpg-clear-cache').on('click', function() {
|
||||||
console.log('[RPG Companion] Clear Cache button clicked');
|
// console.log('[RPG Companion] Clear Cache button clicked');
|
||||||
|
|
||||||
// Clear the data (set to null so panels show "not generated yet")
|
// Clear the data (set to null so panels show "not generated yet")
|
||||||
lastGeneratedData.userStats = null;
|
lastGeneratedData.userStats = null;
|
||||||
@@ -375,7 +375,7 @@ export function setupSettingsPopup() {
|
|||||||
const context = getContext();
|
const context = getContext();
|
||||||
if (context.chat_metadata && context.chat_metadata.rpg_companion) {
|
if (context.chat_metadata && context.chat_metadata.rpg_companion) {
|
||||||
delete context.chat_metadata.rpg_companion;
|
delete context.chat_metadata.rpg_companion;
|
||||||
console.log('[RPG Companion] Cleared chat_metadata.rpg_companion for current chat');
|
// console.log('[RPG Companion] Cleared chat_metadata.rpg_companion for current chat');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all message swipe data
|
// Clear all message swipe data
|
||||||
@@ -495,7 +495,7 @@ export function setupSettingsPopup() {
|
|||||||
renderInventory();
|
renderInventory();
|
||||||
renderQuests();
|
renderQuests();
|
||||||
|
|
||||||
console.log('[RPG Companion] Cache cleared successfully');
|
// console.log('[RPG Companion] Cache cleared successfully');
|
||||||
});
|
});
|
||||||
|
|
||||||
return settingsModal;
|
return settingsModal;
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ function exportTrackerPreset() {
|
|||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
|
|
||||||
console.log('[RPG Companion] Tracker preset exported successfully');
|
// console.log('[RPG Companion] Tracker preset exported successfully');
|
||||||
toastr.success(i18n.getTranslation('template.trackerEditorModal.messages.exportSuccess') || 'Tracker preset exported successfully!');
|
toastr.success(i18n.getTranslation('template.trackerEditorModal.messages.exportSuccess') || 'Tracker preset exported successfully!');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Error exporting tracker preset:', error);
|
console.error('[RPG Companion] Error exporting tracker preset:', error);
|
||||||
@@ -292,7 +292,7 @@ function importTrackerPreset() {
|
|||||||
// Re-render the editor UI
|
// Re-render the editor UI
|
||||||
renderEditorUI();
|
renderEditorUI();
|
||||||
|
|
||||||
console.log('[RPG Companion] Tracker preset imported successfully');
|
// console.log('[RPG Companion] Tracker preset imported successfully');
|
||||||
toastr.success(i18n.getTranslation('template.trackerEditorModal.messages.importSuccess') || 'Tracker preset imported successfully!');
|
toastr.success(i18n.getTranslation('template.trackerEditorModal.messages.importSuccess') || 'Tracker preset imported successfully!');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Error importing tracker preset:', error);
|
console.error('[RPG Companion] Error importing tracker preset:', error);
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ export function migrateCharactersToJSON(textData) {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
export async function migrateToV3JSON() {
|
export async function migrateToV3JSON() {
|
||||||
console.log('[RPG Migration] Starting migration to v3 JSON format...');
|
// console.log('[RPG Migration] Starting migration to v3 JSON format...');
|
||||||
|
|
||||||
const migrated = {
|
const migrated = {
|
||||||
userStats: null,
|
userStats: null,
|
||||||
@@ -367,28 +367,28 @@ export async function migrateToV3JSON() {
|
|||||||
|
|
||||||
// Migrate User Stats
|
// Migrate User Stats
|
||||||
if (committedTrackerData.userStats && typeof committedTrackerData.userStats === 'string') {
|
if (committedTrackerData.userStats && typeof committedTrackerData.userStats === 'string') {
|
||||||
console.log('[RPG Migration] Migrating User Stats...');
|
// console.log('[RPG Migration] Migrating User Stats...');
|
||||||
migrated.userStats = migrateUserStatsToJSON(committedTrackerData.userStats);
|
migrated.userStats = migrateUserStatsToJSON(committedTrackerData.userStats);
|
||||||
if (migrated.userStats) {
|
if (migrated.userStats) {
|
||||||
console.log('[RPG Migration] ✓ User Stats migrated');
|
// console.log('[RPG Migration] ✓ User Stats migrated');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate Info Box
|
// Migrate Info Box
|
||||||
if (committedTrackerData.infoBox && typeof committedTrackerData.infoBox === 'string') {
|
if (committedTrackerData.infoBox && typeof committedTrackerData.infoBox === 'string') {
|
||||||
console.log('[RPG Migration] Migrating Info Box...');
|
// console.log('[RPG Migration] Migrating Info Box...');
|
||||||
migrated.infoBox = migrateInfoBoxToJSON(committedTrackerData.infoBox);
|
migrated.infoBox = migrateInfoBoxToJSON(committedTrackerData.infoBox);
|
||||||
if (migrated.infoBox) {
|
if (migrated.infoBox) {
|
||||||
console.log('[RPG Migration] ✓ Info Box migrated');
|
// console.log('[RPG Migration] ✓ Info Box migrated');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate Present Characters
|
// Migrate Present Characters
|
||||||
if (committedTrackerData.characterThoughts && typeof committedTrackerData.characterThoughts === 'string') {
|
if (committedTrackerData.characterThoughts && typeof committedTrackerData.characterThoughts === 'string') {
|
||||||
console.log('[RPG Migration] Migrating Present Characters...');
|
// console.log('[RPG Migration] Migrating Present Characters...');
|
||||||
migrated.characterThoughts = migrateCharactersToJSON(committedTrackerData.characterThoughts);
|
migrated.characterThoughts = migrateCharactersToJSON(committedTrackerData.characterThoughts);
|
||||||
if (migrated.characterThoughts) {
|
if (migrated.characterThoughts) {
|
||||||
console.log('[RPG Migration] ✓ Present Characters migrated');
|
// console.log('[RPG Migration] ✓ Present Characters migrated');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ export async function migrateToV3JSON() {
|
|||||||
|
|
||||||
// Initialize lockedItems if not present
|
// Initialize lockedItems if not present
|
||||||
if (!extensionSettings.lockedItems) {
|
if (!extensionSettings.lockedItems) {
|
||||||
console.log('[RPG Migration] Initializing lockedItems structure...');
|
// console.log('[RPG Migration] Initializing lockedItems structure...');
|
||||||
updateExtensionSettings({
|
updateExtensionSettings({
|
||||||
lockedItems: {
|
lockedItems: {
|
||||||
stats: [],
|
stats: [],
|
||||||
@@ -429,5 +429,5 @@ export async function migrateToV3JSON() {
|
|||||||
await saveChatData();
|
await saveChatData();
|
||||||
await saveSettings();
|
await saveSettings();
|
||||||
|
|
||||||
console.log('[RPG Migration] ✅ Migration to v3 JSON format complete');
|
// console.log('[RPG Migration] ✅ Migration to v3 JSON format complete');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export function repairJSON(jsonString) {
|
|||||||
const result = fn();
|
const result = fn();
|
||||||
// Validate it's actually an object or array
|
// Validate it's actually an object or array
|
||||||
if (result && (typeof result === 'object')) {
|
if (result && (typeof result === 'object')) {
|
||||||
console.log('[RPG JSON Repair] ✓ Repaired using Function constructor');
|
// console.log('[RPG JSON Repair] ✓ Repaired using Function constructor');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -1616,22 +1616,43 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rpg-location-text {
|
.rpg-location-text {
|
||||||
font-size: clamp(0.625rem, 0.6vw, 0.75rem);
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--rpg-text);
|
color: var(--rpg-text);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
padding: 0;
|
padding: 0.25em 0.5em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow: hidden;
|
max-height: 4em;
|
||||||
display: -webkit-box;
|
width: 100%;
|
||||||
-webkit-line-clamp: 2;
|
display: block;
|
||||||
-webkit-box-orient: vertical;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
/* Dynamic text scaling based on content length */
|
||||||
|
font-size: clamp(0.45rem, calc(0.75rem - 0.005rem * var(--char-count, 0)), 0.75rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom scrollbar for location text */
|
||||||
|
.rpg-location-text::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-location-text::-webkit-scrollbar-track {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-location-text::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--rpg-border);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-location-text::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--rpg-highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Row 3: Recent Events */
|
/* Row 3: Recent Events */
|
||||||
@@ -5122,9 +5143,13 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
left: auto !important;
|
left: auto !important;
|
||||||
|
|
||||||
/* Mobile panel sizing */
|
/* Mobile panel sizing */
|
||||||
|
width: 85vw !important;
|
||||||
width: 85dvw !important;
|
width: 85dvw !important;
|
||||||
max-width: 400px !important;
|
max-width: 400px !important;
|
||||||
|
height: calc(100vh - var(--topBarBlockSize)) !important;
|
||||||
height: calc(100dvh - var(--topBarBlockSize)) !important;
|
height: calc(100dvh - var(--topBarBlockSize)) !important;
|
||||||
|
max-height: calc(100vh - var(--topBarBlockSize)) !important;
|
||||||
|
max-height: calc(100dvh - var(--topBarBlockSize)) !important;
|
||||||
|
|
||||||
/* Hidden by default - completely removed from layout */
|
/* Hidden by default - completely removed from layout */
|
||||||
display: none !important;
|
display: none !important;
|
||||||
@@ -5143,12 +5168,18 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
/* Allow collapse button to show outside panel */
|
/* Allow collapse button to show outside panel */
|
||||||
.rpg-game-container {
|
.rpg-game-container {
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
|
height: 100% !important;
|
||||||
|
max-height: 100% !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
padding: 0.75em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* But keep content scrollable */
|
/* But keep content scrollable */
|
||||||
#rpg-panel-content {
|
#rpg-panel-content {
|
||||||
overflow-y: auto !important;
|
overflow-y: auto !important;
|
||||||
overflow-x: hidden !important;
|
overflow-x: hidden !important;
|
||||||
|
max-height: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show panel when opened with slide-in animation */
|
/* Show panel when opened with slide-in animation */
|
||||||
@@ -5317,10 +5348,12 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
margin: -12px -12px 16px -12px;
|
margin: -12px -12px 16px -12px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tab container at top of panel */
|
/* Tab container at top of panel */
|
||||||
@@ -5501,7 +5534,11 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rpg-location-text {
|
.rpg-location-text {
|
||||||
font-size: min(2.8vw, 0.875rem) !important;
|
/* Dynamic text scaling based on content length - mobile override */
|
||||||
|
font-size: clamp(0.45rem, calc(0.875rem - 0.005rem * var(--char-count, 0)), 0.875rem) !important;
|
||||||
|
max-height: 4.5em !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
overflow-x: hidden !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rpg-map-marker {
|
.rpg-map-marker {
|
||||||
|
|||||||
+6
-1
@@ -935,9 +935,14 @@
|
|||||||
<li>Fixed smaller bugs.</li>
|
<li>Fixed smaller bugs.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h4 style="margin-top: 20px; margin-bottom: 10px;"><strong data-i18n="settings.recommendedModels.title">Recommended Models:</strong></h4>
|
||||||
|
<p style="margin-left: 20px; line-height: 1.6;" data-i18n="settings.recommendedModels.description">
|
||||||
|
For the extension to work properly, **it is not recommended to use any models below 20B, especially if they're old.** It works best with the SOTA models such as Deepseek, Claude, GPT, or Gemini.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h4 style="margin-top: 20px; margin-bottom: 10px;"><strong>Special thanks to all the other contributors for this project:</strong></h4>
|
<h4 style="margin-top: 20px; margin-bottom: 10px;"><strong>Special thanks to all the other contributors for this project:</strong></h4>
|
||||||
<p style="margin-left: 20px; line-height: 1.6;">
|
<p style="margin-left: 20px; line-height: 1.6;">
|
||||||
Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude (???), IDeathByte, Chungchandev, Joenunezb, and Amauragis!
|
Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude (???), IDeathByte, Chungchandev, Joenunezb, and Amauragis.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div style="margin-top: 20px; text-align: center;">
|
<div style="margin-top: 20px; text-align: center;">
|
||||||
|
|||||||
Reference in New Issue
Block a user