@@ -848,16 +848,17 @@ export class JsonUiManager {
848
848
/** @type {UIRecorder|null } UI recording functionality */
849
849
this . uiRecorder = null ;
850
850
851
- // Listen for layout changes to potentially optimize UI element rendering
852
- if ( this . layoutManager . breakpoints ) {
853
- Object . values ( this . layoutManager . breakpoints ) . forEach ( ( mq ) => {
854
- mq . addEventListener ( 'change' , ( ) => {
855
- this . onLayoutChange ( this . layoutManager . currentLayout ) ;
856
- } ) ;
857
- } ) ;
858
- }
851
+ /** @type { ReturnType<typeof setTimeout>|null } Timeout for debounced element redistribution */
852
+ this . redistributionTimeout = null ;
853
+
854
+ // Timing constants
855
+ this . LAYOUT_OPTIMIZATION_DELAY = 150 ; // ms
856
+
857
+ // REMOVED legacy media query listeners to prevent duplicate event handling
858
+ // The UILayoutPlacementManager now handles all layout detection and changes
859
859
860
860
// Listen for custom layout events from the enhanced layout manager
861
+ // This is the single source of truth for layout changes
861
862
globalThis . addEventListener ( 'layoutChanged' , ( e ) => {
862
863
this . onAdvancedLayoutChange ( e . detail ) ;
863
864
} ) ;
@@ -1768,34 +1769,47 @@ export class JsonUiManager {
1768
1769
return JSON . parse ( JSON . stringify ( this . spilloverConfig ) ) ;
1769
1770
}
1770
1771
1771
- // Handle layout changes (enhanced for new system)
1772
+ // Handle layout changes (LEGACY - now deprecated)
1773
+ // This method is kept for backward compatibility but should not be actively used
1772
1774
onLayoutChange ( layoutMode ) {
1773
1775
if ( this . debugMode ) {
1774
- console . log ( `🎵 UI Manager: Layout changed to ${ layoutMode } ` ) ;
1776
+ console . log ( `🎵 UI Manager: LEGACY layout change to ${ layoutMode } (consider using onAdvancedLayoutChange instead) ` ) ;
1775
1777
}
1776
1778
1777
- // CRITICAL FIX: Redistribute UI elements if second container becomes hidden
1778
- this . redistributeElementsIfNeeded ( ) ;
1779
+ // The new onAdvancedLayoutChange method handles all layout changes
1780
+ // This method now just serves as a fallback to avoid breaking existing code
1779
1781
1780
- // Force layout update in case UI elements were added before layout was ready
1781
- if ( this . layoutManager ) {
1782
- this . layoutManager . forceLayoutUpdate ( ) ;
1783
- }
1784
-
1785
- // Re-optimize layout for new mode
1786
- setTimeout ( ( ) => {
1787
- this . optimizeCurrentLayout ( ) ;
1788
- } , 100 ) ;
1782
+ // NOTE: Do not duplicate redistribution logic here since onAdvancedLayoutChange
1783
+ // will be called by the UILayoutPlacementManager for the same resize event
1789
1784
}
1790
1785
1791
1786
/**
1792
1787
* Redistribute UI elements from hidden containers to visible ones
1793
1788
* This fixes the bug where elements disappear when the layout changes
1794
1789
*/
1795
1790
redistributeElementsIfNeeded ( ) {
1791
+ // Clear any pending redistribution to avoid multiple rapid calls
1792
+ if ( this . redistributionTimeout ) {
1793
+ clearTimeout ( this . redistributionTimeout ) ;
1794
+ }
1795
+
1796
+ // Debounce redistribution to allow CSS transitions to complete
1797
+ this . redistributionTimeout = setTimeout ( ( ) => {
1798
+ this . performElementRedistribution ( ) ;
1799
+ } , 100 ) ; // Wait for CSS transitions to complete
1800
+ }
1801
+
1802
+ /**
1803
+ * Actually perform the element redistribution after debouncing
1804
+ * @private
1805
+ */
1806
+ performElementRedistribution ( ) {
1796
1807
const uiControls2Container = document . getElementById ( this . uiControls2Id ) ;
1797
1808
if ( ! uiControls2Container ) return ;
1798
1809
1810
+ // Force a reflow to ensure CSS changes are applied
1811
+ void uiControls2Container . offsetHeight ;
1812
+
1799
1813
// Check if the second container is hidden by CSS
1800
1814
const containerStyle = window . getComputedStyle ( uiControls2Container ) ;
1801
1815
const isSecondContainerVisible = containerStyle . display !== 'none'
@@ -1845,8 +1859,17 @@ export class JsonUiManager {
1845
1859
console . log ( `🎵 UI Manager: Advanced layout change to ${ layout } :` , data ) ;
1846
1860
}
1847
1861
1862
+ // CRITICAL FIX: Redistribute UI elements if second container becomes hidden
1863
+ // This is now the primary method for handling layout changes
1864
+ this . redistributeElementsIfNeeded ( ) ;
1865
+
1848
1866
// Adjust UI elements based on new layout data
1849
1867
this . adaptToLayoutData ( data ) ;
1868
+
1869
+ // Re-optimize layout for new mode
1870
+ setTimeout ( ( ) => {
1871
+ this . optimizeCurrentLayout ( ) ;
1872
+ } , this . LAYOUT_OPTIMIZATION_DELAY ) ; // Slightly longer delay to ensure redistribution completes first
1850
1873
}
1851
1874
1852
1875
/**
@@ -1930,6 +1953,12 @@ export class JsonUiManager {
1930
1953
this . layoutManager = null ;
1931
1954
}
1932
1955
1956
+ // Clear any pending redistribution timeout
1957
+ if ( this . redistributionTimeout ) {
1958
+ clearTimeout ( this . redistributionTimeout ) ;
1959
+ this . redistributionTimeout = null ;
1960
+ }
1961
+
1933
1962
globalThis . removeEventListener ( 'layoutChanged' , this . onAdvancedLayoutChange ) ;
1934
1963
}
1935
1964
0 commit comments