diff --git a/src/app/exercise/[id]/ExercisePageClient.tsx b/src/app/exercise/[id]/ExercisePageClient.tsx index d80c3bf..cbef560 100644 --- a/src/app/exercise/[id]/ExercisePageClient.tsx +++ b/src/app/exercise/[id]/ExercisePageClient.tsx @@ -150,10 +150,6 @@ export default function ExercisePageClient({ params }: { params: Promise<{ id: s const pathname = usePathname(); const [isMobile, setIsMobile] = useState(false); const [activeMobileTab, setActiveMobileTab] = useState<'source' | 'viz' | 'log' | 'misc'>('source'); - const mobileShellRef = useRef(null); - const mobileWorkspacePanelRef = useRef(null); - const mobileDirectionsRef = useRef(null); - const mobileBottomDockRef = useRef(null); useEffect(() => { if (typeof window === 'undefined') return; @@ -209,67 +205,6 @@ export default function ExercisePageClient({ params }: { params: Promise<{ id: s setActiveMobileTab('source'); }, [id]); - useEffect(() => { - if (!isMobile) { - mobileShellRef.current?.style.removeProperty('--mobile-workspace-panel-height'); - return; - } - - const shellElement = mobileShellRef.current; - const panelElement = mobileWorkspacePanelRef.current; - const directionsElement = mobileDirectionsRef.current; - const bottomDockElement = mobileBottomDockRef.current; - - if (!shellElement || !panelElement || !directionsElement || !bottomDockElement) { - return; - } - - let frameId = 0; - - const syncPanelHeight = () => { - frameId = 0; - const shellRect = shellElement.getBoundingClientRect(); - const panelRect = panelElement.getBoundingClientRect(); - const bottomDockRect = bottomDockElement.getBoundingClientRect(); - const shellStyles = window.getComputedStyle(shellElement); - const shellGap = parseFloat(shellStyles.rowGap || shellStyles.gap || '0') || 0; - const availableHeight = Math.floor(bottomDockRect.top - panelRect.top - shellGap); - const maxAvailableHeight = Math.floor(shellRect.bottom - panelRect.top); - const nextHeight = Math.max(0, Math.min(availableHeight, maxAvailableHeight)); - shellElement.style.setProperty('--mobile-workspace-panel-height', `${nextHeight}px`); - }; - - const queueSyncPanelHeight = () => { - if (frameId !== 0) return; - frameId = window.requestAnimationFrame(syncPanelHeight); - }; - - queueSyncPanelHeight(); - - const observer = new ResizeObserver(() => { - queueSyncPanelHeight(); - }); - - observer.observe(shellElement); - observer.observe(directionsElement); - observer.observe(bottomDockElement); - - window.addEventListener('resize', queueSyncPanelHeight); - window.visualViewport?.addEventListener('resize', queueSyncPanelHeight); - window.visualViewport?.addEventListener('scroll', queueSyncPanelHeight); - - return () => { - observer.disconnect(); - window.removeEventListener('resize', queueSyncPanelHeight); - window.visualViewport?.removeEventListener('resize', queueSyncPanelHeight); - window.visualViewport?.removeEventListener('scroll', queueSyncPanelHeight); - if (frameId !== 0) { - window.cancelAnimationFrame(frameId); - } - shellElement.style.removeProperty('--mobile-workspace-panel-height'); - }; - }, [activeMobileTab, isMobile]); - useEffect(() => { const mainElement = document.querySelector('#app-body > main'); const appElement = document.getElementById('app'); @@ -512,8 +447,8 @@ export default function ExercisePageClient({ params }: { params: Promise<{ id: s if (isMobile) { return ( -
-
+
+
@@ -557,7 +492,7 @@ export default function ExercisePageClient({ params }: { params: Promise<{ id: s
-
+
{activeMobileTab === 'source' && } {activeMobileTab === 'viz' && ( @@ -576,7 +511,7 @@ export default function ExercisePageClient({ params }: { params: Promise<{ id: s
-
+
diff --git a/src/app/globals.css b/src/app/globals.css index 90d9d76..bb56925 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1021,10 +1021,8 @@ button.link-button:focus-visible, .mobile-workspace-panel { display: flex; - flex: 0 0 auto; + flex: 1 1 0%; flex-direction: column; - height: var(--mobile-workspace-panel-height, auto); - max-height: var(--mobile-workspace-panel-height, none); min-height: 0; overflow: hidden; }