Refactor inventory lock logic to use item names

Updated inventory lock management and rendering to match items by name instead of index, improving reliability and consistency. Also adjusted quest rendering and parsing to handle locked quest objects with a value property.
This commit is contained in:
Spicy_Marinara
2026-01-23 09:17:40 +01:00
parent e82918004e
commit 6fc35e50a1
4 changed files with 29 additions and 21 deletions
+14 -11
View File
@@ -98,16 +98,19 @@ function applyUserStatsLocks(data, lockedItems) {
}
}
// Lock inventory items - handle bracket notation paths like "inventory.onPerson[0]"
// Lock inventory items - match by item name instead of index
if (data.inventory && lockedItems.inventory) {
// Helper function to parse bracket notation and apply lock
// Helper function to apply locks based on item name
const applyInventoryLocks = (items, category) => {
if (!Array.isArray(items)) return items;
if (!lockedItems.inventory[category]) return items;
return items.map((item, index) => {
// Check if this specific item is locked using bracket notation with inventory prefix
const bracketPath = `${category}[${index}]`;
if (lockedItems.inventory[bracketPath]) {
return items.map((item) => {
// Get item name (handle both string and object formats)
const itemName = typeof item === 'string' ? item : (item.item || item.name || '');
// Check if this specific item name is locked
if (lockedItems.inventory[category][itemName]) {
return typeof item === 'string'
? { item, locked: true }
: { ...item, locked: true };
@@ -131,13 +134,13 @@ function applyUserStatsLocks(data, lockedItems) {
data.inventory.assets = applyInventoryLocks(data.inventory.assets, 'assets');
}
// Apply locks to stored items (nested structure with inventory.stored.location[index])
// Apply locks to stored items - match by item name
if (data.inventory.stored && lockedItems.inventory.stored) {
for (const location in data.inventory.stored) {
if (Array.isArray(data.inventory.stored[location])) {
data.inventory.stored[location] = data.inventory.stored[location].map((item, index) => {
const bracketPath = `${location}[${index}]`;
if (lockedItems.inventory.stored[bracketPath]) {
if (Array.isArray(data.inventory.stored[location]) && lockedItems.inventory.stored[location]) {
data.inventory.stored[location] = data.inventory.stored[location].map((item) => {
const itemName = typeof item === 'string' ? item : (item.item || item.name || '');
if (lockedItems.inventory.stored[location][itemName]) {
return typeof item === 'string'
? { item, locked: true }
: { ...item, locked: true };
+2
View File
@@ -617,6 +617,8 @@ export function parseUserStats(statsText) {
if (!quest) return '';
if (typeof quest === 'string') return quest;
if (typeof quest === 'object') {
// Check for locked format: {value, locked}
if (quest.value !== undefined) return String(quest.value);
// v3 format: {title, description, status}
return quest.title || quest.description || JSON.stringify(quest);
}
+8 -8
View File
@@ -81,7 +81,7 @@ export function renderOnPersonView(onPersonItems, viewMode = 'list') {
if (viewMode === 'grid') {
// Grid view: card-style items
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.onPerson[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.onPerson.${item}`);
return `
<div class="rpg-item-card" data-field="onPerson" data-index="${index}">
${lockIconHtml}
@@ -94,7 +94,7 @@ export function renderOnPersonView(onPersonItems, viewMode = 'list') {
} else {
// List view: full-width rows
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.onPerson[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.onPerson.${item}`);
return `
<div class="rpg-item-row" data-field="onPerson" data-index="${index}">
${lockIconHtml}
@@ -163,7 +163,7 @@ export function renderClothingView(clothingItems, viewMode = 'list') {
if (viewMode === 'grid') {
// Grid view: card-style items
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.clothing[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.clothing.${item}`);
return `
<div class="rpg-item-card" data-field="clothing" data-index="${index}">
${lockIconHtml}
@@ -176,7 +176,7 @@ export function renderClothingView(clothingItems, viewMode = 'list') {
} else {
// List view: full-width rows
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.clothing[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.clothing.${item}`);
return `
<div class="rpg-item-row" data-field="clothing" data-index="${index}">
${lockIconHtml}
@@ -291,7 +291,7 @@ export function renderStoredView(stored, collapsedLocations = [], viewMode = 'li
if (viewMode === 'grid') {
// Grid view: card-style items
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.stored.${location}[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.stored.${location}.${item}`);
return `
<div class="rpg-item-card" data-field="stored" data-location="${escapeHtml(location)}" data-index="${index}">
${lockIconHtml}
@@ -304,7 +304,7 @@ export function renderStoredView(stored, collapsedLocations = [], viewMode = 'li
} else {
// List view: full-width rows
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.stored.${location}[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.stored.${location}.${item}`);
return `
<div class="rpg-item-row" data-field="stored" data-location="${escapeHtml(location)}" data-index="${index}">
${lockIconHtml}
@@ -393,7 +393,7 @@ export function renderAssetsView(assets, viewMode = 'list') {
if (viewMode === 'grid') {
// Grid view: card-style items
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.assets[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.assets.${item}`);
return `
<div class="rpg-item-card" data-field="assets" data-index="${index}">
${lockIconHtml}
@@ -406,7 +406,7 @@ export function renderAssetsView(assets, viewMode = 'list') {
} else {
// List view: full-width rows
itemsHtml = items.map((item, index) => {
const lockIconHtml = getLockIconHtml('userStats', `inventory.assets[${index}]`);
const lockIconHtml = getLockIconHtml('userStats', `inventory.assets.${item}`);
return `
<div class="rpg-item-row" data-field="assets" data-index="${index}">
${lockIconHtml}
+5 -2
View File
@@ -212,8 +212,11 @@ export function renderQuests() {
// Get current sub-tab from container or default to 'main'
const activeSubTab = $questsContainer.data('active-subtab') || 'main';
// Get quests data
const mainQuest = extensionSettings.quests.main || 'None';
// Get quests data - extract value if it's a locked object
let mainQuest = extensionSettings.quests.main || 'None';
if (typeof mainQuest === 'object' && mainQuest.value !== undefined) {
mainQuest = mainQuest.value;
}
const optionalQuests = extensionSettings.quests.optional || [];
// Build HTML