fix(inventory): ensure stored locations always initialized properly
Fixes Bug #3: Locations disappearing when switching tabs or on reload. Root cause: inventory.stored could become corrupted (null, array, or undefined) due to incomplete validation during load/save operations. Solution - Defense in Depth: 1. **Persistence Layer** (src/core/persistence.js): - New validateInventoryStructure() function - Validates on loadSettings() and loadChatData() - Checks all v2 fields (onPerson, stored, assets, version) - Ensures stored is always a plain object - Validates stored keys/values using validateStoredInventory() - Auto-repairs corrupted data with console warnings - Persists repairs immediately 2. **Form State Management** (src/systems/interaction/inventoryActions.js): - Enhanced restoreFormStates() to detect deleted locations - Cleans up orphaned form states automatically - Prevents errors from forms referencing non-existent locations Validation checks: - ✓ inventory.stored is object (not null/array/undefined) - ✓ All stored keys are safe (no __proto__, constructor, etc.) - ✓ All stored values are strings - ✓ onPerson and assets are strings - ✓ version field exists Auto-repair scenarios: - Corrupted stored → reset to {} - Invalid onPerson/assets → reset to "None" - Missing version → set to 2 - Dangerous keys → removed with warning Result: - Locations persist across tab switches ✓ - Empty locations persist ✓ - Data corruption auto-repaired on load ✓ - Orphaned form states cleaned up ✓ - No crashes from invalid data ✓ Fixes: Location disappears when switching tabs or reloading
This commit is contained in:
@@ -539,6 +539,7 @@ export function getInventoryRenderOptions() {
|
||||
/**
|
||||
* Restores the state of inline forms after re-rendering.
|
||||
* This ensures forms that were open before re-render are shown again.
|
||||
* Also cleans up orphaned form states for deleted locations (Bug #3 fix).
|
||||
*/
|
||||
export function restoreFormStates() {
|
||||
// Restore add location form
|
||||
@@ -570,15 +571,31 @@ export function restoreFormStates() {
|
||||
}
|
||||
|
||||
// Restore add item stored forms (for each location)
|
||||
// Clean up orphaned states for deleted locations (Bug #3 fix)
|
||||
if (openForms.addItemStored && typeof openForms.addItemStored === 'object') {
|
||||
const inventory = extensionSettings.userStats.inventory;
|
||||
const locationsToDelete = [];
|
||||
|
||||
for (const location in openForms.addItemStored) {
|
||||
if (openForms.addItemStored[location]) {
|
||||
const locationId = location.replace(/\s+/g, '-');
|
||||
const form = $(`#rpg-add-item-form-stored-${locationId}`);
|
||||
if (form.length > 0) {
|
||||
form.show();
|
||||
// Check if location still exists in inventory
|
||||
if (inventory?.stored && inventory.stored.hasOwnProperty(location)) {
|
||||
// Location exists, restore form
|
||||
const locationId = location.replace(/\s+/g, '-');
|
||||
const form = $(`#rpg-add-item-form-stored-${locationId}`);
|
||||
if (form.length > 0) {
|
||||
form.show();
|
||||
}
|
||||
} else {
|
||||
// Location was deleted, mark for cleanup
|
||||
locationsToDelete.push(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up orphaned form states
|
||||
for (const location of locationsToDelete) {
|
||||
delete openForms.addItemStored[location];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user