From 19922efd80ca481aef0702a8ac508591bba3204a Mon Sep 17 00:00:00 2001 From: root Date: Sat, 7 Mar 2026 16:12:37 +0000 Subject: [PATCH] fix: persist expanded state across relationship tab re-renders The updateRelationships method rebuilds DOM every broadcast tick, which reset expand/collapse state. Now tracks expanded tiers in a Set that persists across re-renders. Co-Authored-By: Claude Opus 4.6 --- client/src/ui/NpcInfoPanel.ts | 38 ++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/client/src/ui/NpcInfoPanel.ts b/client/src/ui/NpcInfoPanel.ts index d466371..1d98cbf 100644 --- a/client/src/ui/NpcInfoPanel.ts +++ b/client/src/ui/NpcInfoPanel.ts @@ -42,6 +42,7 @@ export class NpcInfoPanel { private statusContent!: HTMLDivElement; private relationshipsContent!: HTMLDivElement; private activeTab: 'status' | 'relationships' = 'status'; + private expandedTiers: Set = new Set(); private visible = false; constructor() { @@ -528,8 +529,9 @@ export class NpcInfoPanel { } if (hidden.length > 0) { + const isExpanded = this.expandedTiers.has(tier); const overflow = document.createElement('div'); - overflow.style.cssText = 'display: none;'; + overflow.style.cssText = isExpanded ? '' : 'display: none;'; for (const rel of hidden) { overflow.appendChild(this.createRelSlider(rel.name, rel.value, tier)); } @@ -544,11 +546,18 @@ export class NpcInfoPanel { padding: 2px 0; text-align: center; `; - toggle.textContent = `\u25BC ${hidden.length} more...`; + toggle.textContent = isExpanded + ? '\u25B2 show less' + : `\u25BC ${hidden.length} more...`; toggle.addEventListener('click', () => { - const expanded = overflow.style.display !== 'none'; - overflow.style.display = expanded ? 'none' : ''; - toggle.textContent = expanded + const wasExpanded = this.expandedTiers.has(tier); + if (wasExpanded) { + this.expandedTiers.delete(tier); + } else { + this.expandedTiers.add(tier); + } + overflow.style.display = wasExpanded ? 'none' : ''; + toggle.textContent = wasExpanded ? `\u25BC ${hidden.length} more...` : '\u25B2 show less'; }); @@ -574,8 +583,10 @@ export class NpcInfoPanel { } if (memHidden.length > 0) { + const memKey = '__memories__'; + const isExpanded = this.expandedTiers.has(memKey); const overflow = document.createElement('div'); - overflow.style.cssText = 'display: none;'; + overflow.style.cssText = isExpanded ? '' : 'display: none;'; for (const rel of memHidden) { overflow.appendChild(this.createRelSlider(rel.name + ' \u2020', rel.value, 'memory')); } @@ -590,11 +601,18 @@ export class NpcInfoPanel { padding: 2px 0; text-align: center; `; - toggle.textContent = `\u25BC ${memHidden.length} more...`; + toggle.textContent = isExpanded + ? '\u25B2 show less' + : `\u25BC ${memHidden.length} more...`; toggle.addEventListener('click', () => { - const expanded = overflow.style.display !== 'none'; - overflow.style.display = expanded ? 'none' : ''; - toggle.textContent = expanded + const wasExpanded = this.expandedTiers.has(memKey); + if (wasExpanded) { + this.expandedTiers.delete(memKey); + } else { + this.expandedTiers.add(memKey); + } + overflow.style.display = wasExpanded ? 'none' : ''; + toggle.textContent = wasExpanded ? `\u25BC ${memHidden.length} more...` : '\u25B2 show less'; });