From e6e452b030017fc8b91c8597b17776c05b7f835e Mon Sep 17 00:00:00 2001 From: dnviti Date: Thu, 18 Dec 2025 02:09:44 +0100 Subject: [PATCH] feat: Implement `localStorage` persistence for UI panel resize states in Draft and Deck views. --- docs/development/CENTRAL.md | 1 + .../2025-12-18-050000_resize_persistence.md | 18 ++++++++++++++++ .../src/modules/draft/DeckBuilderView.tsx | 21 ++++++++++++++++--- src/client/src/modules/draft/DraftView.tsx | 9 +++++++- 4 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 docs/development/devlog/2025-12-18-050000_resize_persistence.md diff --git a/docs/development/CENTRAL.md b/docs/development/CENTRAL.md index eea4d0c..160d40e 100644 --- a/docs/development/CENTRAL.md +++ b/docs/development/CENTRAL.md @@ -108,3 +108,4 @@ - [Pool Card Sizing](./devlog/2025-12-18-042500_pool_card_sizing.md): Completed. Fixed "enormous" card bug in horizontal pool by enforcing percentage-based height constraint. - [Final Pool Layout Fix](./devlog/2025-12-18-043500_pool_sizing_final.md): Completed. Overhauled flex layout for Horizontal Pool to ensure card images scale 1:1 with panel height during resize, removing layout-blocking transitions. - [Pool Overflow Constraint](./devlog/2025-12-18-044500_pool_overflow_fix.md): Completed. Enforce flex shrinkage with `min-h-0` and `overflow-hidden` to strictly bind card height to resizeable panel. +- [Resize Persistence](./devlog/2025-12-18-050000_resize_persistence.md): Completed. Implemented `localStorage` persistence for Sidebars and Pool Panels in both Draft and Deck Views. diff --git a/docs/development/devlog/2025-12-18-050000_resize_persistence.md b/docs/development/devlog/2025-12-18-050000_resize_persistence.md new file mode 100644 index 0000000..4c1b470 --- /dev/null +++ b/docs/development/devlog/2025-12-18-050000_resize_persistence.md @@ -0,0 +1,18 @@ +# Work Plan - Persist Resize State + +## Request +The user wants resized areas (sidebar and pool) to be remembered (persisted) so they reopen with the same sizes. + +## Changes +- **DraftView.tsx**: + - Updated initialization of `sidebarWidth` state to read from `localStorage.getItem('draft_sidebarWidth')`. + - Added `useEffect` to save `sidebarWidth` to `localStorage` whenever it changes. + - Verified `poolHeight` persistence logic already exists. + +- **DeckBuilderView.tsx**: + - Updated initialization of `sidebarWidth` and `poolHeightPercent` to read from `localStorage` keys `deck_sidebarWidth` and `deck_poolHeightPercent`. + - Added `useEffect` hooks to persist both values to `localStorage`. + - Added `useEffect` to imports (fixed lint error). + +## Verification +- **Test**: Refreshing the page after resizing the sidebar or pool panel should restore the previous dimensions exactly. diff --git a/src/client/src/modules/draft/DeckBuilderView.tsx b/src/client/src/modules/draft/DeckBuilderView.tsx index d381e97..eabe227 100644 --- a/src/client/src/modules/draft/DeckBuilderView.tsx +++ b/src/client/src/modules/draft/DeckBuilderView.tsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo } from 'react'; +import React, { useState, useMemo, useEffect } from 'react'; import { socketService } from '../../services/SocketService'; import { Save, Layers, Clock, Columns, LayoutTemplate, List, LayoutGrid, ChevronDown, Check, GripVertical } from 'lucide-react'; import { StackView } from '../../components/StackView'; @@ -239,8 +239,14 @@ export const DeckBuilderView: React.FC = ({ initialPool, a const [sortDropdownOpen, setSortDropdownOpen] = useState(false); // --- Resize State --- - const [sidebarWidth, setSidebarWidth] = useState(320); // Initial 320px - const [poolHeightPercent, setPoolHeightPercent] = useState(60); // Initial 60% for pool (horizontal layout) + const [sidebarWidth, setSidebarWidth] = useState(() => { + const saved = localStorage.getItem('deck_sidebarWidth'); + return saved ? parseInt(saved, 10) : 320; + }); + const [poolHeightPercent, setPoolHeightPercent] = useState(() => { + const saved = localStorage.getItem('deck_poolHeightPercent'); + return saved ? parseFloat(saved) : 60; + }); const sidebarRef = React.useRef(null); const poolRef = React.useRef(null); @@ -258,6 +264,15 @@ export const DeckBuilderView: React.FC = ({ initialPool, a if (poolRef.current) poolRef.current.style.height = `${poolHeightPercent}%`; }, []); + // Persist Resize + useEffect(() => { + localStorage.setItem('deck_sidebarWidth', sidebarWidth.toString()); + }, [sidebarWidth]); + + useEffect(() => { + localStorage.setItem('deck_poolHeightPercent', poolHeightPercent.toString()); + }, [poolHeightPercent]); + const [pool, setPool] = useState(initialPool); const [deck, setDeck] = useState([]); const [lands, setLands] = useState({ Plains: 0, Island: 0, Swamp: 0, Mountain: 0, Forest: 0 }); diff --git a/src/client/src/modules/draft/DraftView.tsx b/src/client/src/modules/draft/DraftView.tsx index c749a72..5f02d03 100644 --- a/src/client/src/modules/draft/DraftView.tsx +++ b/src/client/src/modules/draft/DraftView.tsx @@ -61,7 +61,10 @@ export const DraftView: React.FC = ({ draftState, currentPlayerI // --- UI State & Persistence --- - const [sidebarWidth, setSidebarWidth] = useState(320); + const [sidebarWidth, setSidebarWidth] = useState(() => { + const saved = localStorage.getItem('draft_sidebarWidth'); + return saved ? parseInt(saved, 10) : 320; + }); const [poolHeight, setPoolHeight] = useState(() => { const saved = localStorage.getItem('draft_poolHeight'); return saved ? parseInt(saved, 10) : 220; @@ -107,6 +110,10 @@ export const DraftView: React.FC = ({ draftState, currentPlayerI localStorage.setItem('draft_poolHeight', poolHeight.toString()); }, [poolHeight]); + useEffect(() => { + localStorage.setItem('draft_sidebarWidth', sidebarWidth.toString()); + }, [sidebarWidth]); + useEffect(() => { localStorage.setItem('draft_cardScale', cardScale.toString()); }, [cardScale]);