@@ -188,35 +188,10 @@ function App() {
188188 const [ showIons , setShowIons ] = useState ( false ) ;
189189
190190 const [ showSurface , setShowSurface ] = useState ( initialUrlState . showSurface || false ) ;
191+ const [ measurements , setMeasurements ] = useState < Measurement [ ] > ( [ ] ) ;
192+ const [ proteinTitle , setProteinTitle ] = useState < string | null > ( null ) ;
191193
192- // Undo/Redo Stack
193- const visualState : VisualState = useMemo ( ( ) => ( {
194- representation,
195- coloring,
196- colorPalette,
197- showLigands,
198- showIons,
199- showSurface,
200- customBackgroundColor : customBackgroundColor || '' ,
201- customColors
202- } ) , [ representation , coloring , colorPalette , showLigands , showIons , showSurface , customBackgroundColor , customColors ] ) ;
203194
204- const handleVisualStateChange = useCallback ( ( newState : VisualState ) => {
205- setRepresentation ( newState . representation ) ;
206- setColoring ( newState . coloring ) ;
207- setColorPalette ( newState . colorPalette ) ;
208- setShowLigands ( newState . showLigands ) ;
209- setShowIons ( newState . showIons ) ;
210- setShowSurface ( newState . showSurface ) ;
211- setCustomBackgroundColor ( newState . customBackgroundColor || null ) ;
212- setCustomColors ( newState . customColors ) ;
213- } , [ ] ) ;
214-
215- const { undo, redo, canUndo, canRedo } = useVisualStack ( {
216- state : visualState ,
217- onChange : handleVisualStateChange ,
218- resetTrigger : pdbId // Reset stack when PDB ID changes to avoid cross-structure confusing undos
219- } ) ;
220195
221196 // ... (lines 53-343) ...
222197
@@ -319,29 +294,75 @@ function App() {
319294 // Store previous theme to restore after exiting Publication Mode
320295 const previousThemeRef = useRef ( isLightMode ) ;
321296
322- // Effect to apply Publication Mode settings
323- useEffect ( ( ) => {
324- if ( isPublicationMode ) {
325- // Save current theme before overriding
326- previousThemeRef . current = isLightMode ;
297+ const togglePublicationMode = useCallback ( ( shouldBeEnabled ?: boolean ) => {
298+ const nextState = shouldBeEnabled !== undefined ? shouldBeEnabled : ! isPublicationMode ;
299+
300+ if ( nextState === isPublicationMode ) return ;
327301
328- // Auto-set High Quality Defaults
302+ setIsPublicationMode ( nextState ) ;
303+
304+ if ( nextState ) {
305+ // Enable
306+ previousThemeRef . current = isLightMode ;
329307 setRepresentation ( 'cartoon' ) ;
330308 setIsCleanMode ( true ) ;
331309 setColoring ( 'chainid' ) ;
332310 setCustomBackgroundColor ( '#ffffff' ) ; // White background
333311 setIsLightMode ( true ) ; // Ensure light mode for paper look
334312 } else {
335- // Restore previous configuration
313+ // Disable
336314 setIsCleanMode ( false ) ;
337315 setCustomBackgroundColor ( null ) ; // Revert to theme
338316 setIsLightMode ( previousThemeRef . current ) ; // Restore original theme
339317 }
340- // eslint-disable-next-line react-hooks/exhaustive-deps
341- } , [ isPublicationMode ] ) ;
318+ } , [ isPublicationMode , isLightMode ] ) ;
319+
320+
321+
342322
343323 // ... (fetchTitle logic) ...
344324
325+ // Undo/Redo Stack (Moved here to access all state variables)
326+ const visualState : VisualState = useMemo ( ( ) => ( {
327+ representation,
328+ coloring,
329+ colorPalette,
330+ showLigands,
331+ showIons,
332+ showSurface,
333+ customBackgroundColor : customBackgroundColor || '' ,
334+ customColors,
335+ isSpinning,
336+ isCleanMode,
337+ showContactMap,
338+ isPublicationMode,
339+ highlightedResidue,
340+ measurements
341+ } ) , [ representation , coloring , colorPalette , showLigands , showIons , showSurface , customBackgroundColor , customColors , isSpinning , isCleanMode , showContactMap , isPublicationMode , highlightedResidue , measurements ] ) ;
342+
343+ const handleVisualStateChange = useCallback ( ( newState : VisualState ) => {
344+ setRepresentation ( newState . representation ) ;
345+ setColoring ( newState . coloring ) ;
346+ setColorPalette ( newState . colorPalette ) ;
347+ setShowLigands ( newState . showLigands ) ;
348+ setShowIons ( newState . showIons ) ;
349+ setShowSurface ( newState . showSurface ) ;
350+ setCustomBackgroundColor ( newState . customBackgroundColor || null ) ;
351+ setCustomColors ( newState . customColors ) ;
352+ setIsSpinning ( newState . isSpinning ) ;
353+ setIsCleanMode ( newState . isCleanMode ) ;
354+ setShowContactMap ( newState . showContactMap ) ;
355+ setIsPublicationMode ( newState . isPublicationMode ) ;
356+ setHighlightedResidue ( newState . highlightedResidue ) ;
357+ setMeasurements ( newState . measurements ) ;
358+ } , [ ] ) ;
359+
360+ const { undo, redo, canUndo, canRedo } = useVisualStack ( {
361+ state : visualState ,
362+ onChange : handleVisualStateChange ,
363+ resetTrigger : pdbId
364+ } ) ;
365+
345366 // --- DERIVED STATE (Dr. AI V4) ---
346367 const structureStats = useMemo ( ( ) => {
347368 const chainCount = chains . length ;
@@ -430,7 +451,7 @@ function App() {
430451 }
431452 } , [ showLigands , initialUrlState . showLigands , pdbId , dataSource , addToHistory ] ) ;
432453
433- const [ proteinTitle , setProteinTitle ] = useState < string | null > ( null ) ;
454+
434455
435456 // Consolidate Title & Metadata Fetching
436457 // 1. Remove separate 'fetchTitle' effect that was specific to RCSB PDB
@@ -815,7 +836,7 @@ function App() {
815836 const [ hoveredResidue , setHoveredResidue ] = useState < ResidueInfo | null > ( null ) ;
816837
817838 // --- MEASUREMENT STATE ---
818- const [ measurements , setMeasurements ] = useState < Measurement [ ] > ( [ ] ) ;
839+
819840 const [ isMeasurementPanelOpen , setIsMeasurementPanelOpen ] = useState ( false ) ;
820841 const [ measurementTextColorMode , setMeasurementTextColorMode ] = useState < MeasurementTextColor > ( 'auto' ) ;
821842
@@ -968,7 +989,7 @@ function App() {
968989 label : isPublicationMode ? 'Exit Publication Mode' : 'Enter Publication Mode' ,
969990 icon : Camera ,
970991 category : 'View' ,
971- perform : ( ) => setIsPublicationMode ( prev => ! prev )
992+ perform : ( ) => togglePublicationMode ( )
972993 } ,
973994 {
974995 id : 'take-snapshot' ,
@@ -1344,7 +1365,7 @@ function App() {
13441365 isMeasurementMode = { isMeasurementMode }
13451366 setIsMeasurementMode = { setIsMeasurementMode }
13461367 isPublicationMode = { isPublicationMode }
1347- setIsPublicationMode = { setIsPublicationMode }
1368+ onTogglePublicationMode = { togglePublicationMode }
13481369 onClearMeasurements = { ( ) => {
13491370 setMeasurements ( [ ] ) ;
13501371 viewerRef . current ?. clearMeasurements ( ) ;
0 commit comments