diff --git a/src/client/src/App.tsx b/src/client/src/App.tsx index c660e65..b8fc2eb 100644 --- a/src/client/src/App.tsx +++ b/src/client/src/App.tsx @@ -39,15 +39,28 @@ export const App: React.FC = () => { React.useEffect(() => { try { - localStorage.setItem('generatedPacks', JSON.stringify(generatedPacks)); + // Optimiziation: Strip 'definition' (ScryfallCard) from cards to save huge amount of space + // We only need the properties mapped to DraftCard for the UI and Game + const optimizedPacks = generatedPacks.map(p => ({ + ...p, + cards: p.cards.map(c => { + const { definition, ...rest } = c; + return rest; + }) + })); + localStorage.setItem('generatedPacks', JSON.stringify(optimizedPacks)); } catch (e) { - console.error("Failed to save packs to storage", e); + console.error("Failed to save packs to storage (Quota likely exceeded)", e); } }, [generatedPacks]); React.useEffect(() => { try { - localStorage.setItem('availableLands', JSON.stringify(availableLands)); + const optimizedLands = availableLands.map(l => { + const { definition, ...rest } = l; + return rest; + }); + localStorage.setItem('availableLands', JSON.stringify(optimizedLands)); } catch (e) { console.error("Failed to save lands to storage", e); } diff --git a/src/client/src/modules/cube/CubeManager.tsx b/src/client/src/modules/cube/CubeManager.tsx index 47fc118..c70410b 100644 --- a/src/client/src/modules/cube/CubeManager.tsx +++ b/src/client/src/modules/cube/CubeManager.tsx @@ -72,7 +72,9 @@ export const CubeManager: React.FC = ({ packs, setPacks, avail }); // UI State - const [viewMode, setViewMode] = useState<'list' | 'grid' | 'stack'>('list'); + const [viewMode, setViewMode] = useState<'list' | 'grid' | 'stack'>(() => { + return (localStorage.getItem('cube_viewMode') as 'list' | 'grid' | 'stack') || 'list'; + }); // Generation Settings const [genSettings, setGenSettings] = useState(() => { @@ -100,7 +102,9 @@ export const CubeManager: React.FC = ({ packs, setPacks, avail }); const [searchTerm, setSearchTerm] = useState(''); - const [gameTypeFilter, setGameTypeFilter] = useState<'all' | 'paper' | 'digital'>('all'); // Filter state + const [gameTypeFilter, setGameTypeFilter] = useState<'all' | 'paper' | 'digital'>(() => { + return (localStorage.getItem('cube_gameTypeFilter') as 'all' | 'paper' | 'digital') || 'all'; + }); const [numBoxes, setNumBoxes] = useState(() => { const saved = localStorage.getItem('cube_numBoxes'); return saved ? parseInt(saved) : 3; @@ -119,6 +123,8 @@ export const CubeManager: React.FC = ({ packs, setPacks, avail useEffect(() => localStorage.setItem('cube_selectedSets', JSON.stringify(selectedSets)), [selectedSets]); useEffect(() => localStorage.setItem('cube_numBoxes', numBoxes.toString()), [numBoxes]); useEffect(() => localStorage.setItem('cube_cardWidth', cardWidth.toString()), [cardWidth]); + useEffect(() => localStorage.setItem('cube_viewMode', viewMode), [viewMode]); + useEffect(() => localStorage.setItem('cube_gameTypeFilter', gameTypeFilter), [gameTypeFilter]); const fileInputRef = useRef(null); @@ -183,6 +189,11 @@ export const CubeManager: React.FC = ({ packs, setPacks, avail if (sourceMode === 'set' && selectedSets.length === 0) return; if (sourceMode === 'upload' && !inputText) return; + if (sourceMode === 'set' && numBoxes > 10) { + showToast("Maximum limit is 10 Boxes (360 Packs) to avoid instability.", "error"); + return; + } + setLoading(true); setPacks([]); // Clear old packs to avoid confusion @@ -427,11 +438,15 @@ export const CubeManager: React.FC = ({ packs, setPacks, avail setInputText(''); setRawScryfallData(null); setProcessedData(null); - setProcessedData(null); + setAvailableLands([]); setSelectedSets([]); localStorage.removeItem('cube_inputText'); localStorage.removeItem('cube_rawScryfallData'); localStorage.removeItem('cube_selectedSets'); + localStorage.removeItem('cube_viewMode'); + localStorage.removeItem('cube_gameTypeFilter'); + setViewMode('list'); + setGameTypeFilter('all'); // We keep filters and settings as they are user preferences } }; @@ -686,7 +701,7 @@ export const CubeManager: React.FC = ({ packs, setPacks, avail setNumBoxes(parseInt(e.target.value))} className="w-16 bg-slate-700 border-none rounded p-1 text-center text-white font-mono"