From cddd8dfc0c2d0bdfdf3891a15df2922a681149c0 Mon Sep 17 00:00:00 2001 From: gumillie222 <121700352+gumillie222@users.noreply.github.com> Date: Fri, 21 Feb 2025 13:19:20 -0500 Subject: [PATCH 1/3] no error in build --- cypress/e2e/retainLayout.cy.ts | 127 ++++++++++++++++++++ src/app/components/DraggableSplitter.tsx | 2 + src/app/editor/components/TimelineTools.tsx | 9 +- 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 cypress/e2e/retainLayout.cy.ts diff --git a/cypress/e2e/retainLayout.cy.ts b/cypress/e2e/retainLayout.cy.ts new file mode 100644 index 0000000..b8c845a --- /dev/null +++ b/cypress/e2e/retainLayout.cy.ts @@ -0,0 +1,127 @@ + +describe('editor layout persistence', () => { + beforeEach(() => { + cy.viewport(2000, 1000, { log: false }); + cy.clearLocalStorage(); + cy.visit('http://localhost:3000/editor'); + cy.wait(500); + cy.get('[data-cy="yaml-save"]').realClick() + cy.wait(500); + }); + + it('remembers the left column width after a reload', () => { + let oldWidth: number; + cy.get('#leftColumn') + .then(($el) => { + oldWidth = $el[0].getBoundingClientRect().width; + cy.log('Initial width: ' + oldWidth); + }); + + cy.get('[data-cy="splitter-vertical"]') + .realMouseDown({ position: 'center' }) + .realMouseMove(200, 0) + .realMouseUp(); + + // Verify the left column width changed + cy.get('#leftColumn') + .then(($el) => { + const newWidth = $el[0].getBoundingClientRect().width; + cy.log('New width: ' + newWidth); + expect(newWidth).to.be.gt(oldWidth); + }); + + cy.reload(); + cy.wait(500); + + // After reload, check that the left column width is still > oldWidth + cy.get('#leftColumn') + .then(($el) => { + const newWidth = $el[0].getBoundingClientRect().width; + expect(newWidth).to.be.gt(oldWidth); + }); + }); + + it('remembers the upper-left panel height after a reload', () => { + let oldHeight : number; + + cy.get('#upperLeft') + .then(($el) => { + oldHeight = $el[0].getBoundingClientRect().height; + cy.log('Initial width: ' + oldHeight); + }); + + cy.get('[data-cy="splitter-horizontal"]') + .realMouseDown({ position: 'center' }) + .realMouseMove(0, 100) + .realMouseUp(); + + // Verify the new height is different + cy.get('#upperLeft') + .then(($el) => { + const newHeight = $el[0].getBoundingClientRect().height; + cy.log('New height: ' + newHeight); + expect(newHeight).to.be.gt(oldHeight); + }); + + cy.reload(); + cy.wait(500); + + // After reload, check the panel has the updated height + cy.get('#upperLeft') + .then(($el) => { + const newHeight = $el[0].getBoundingClientRect().height; + expect(newHeight).to.be.gt(oldHeight); + }); + }); + + it('remembers slider position and scale after a page reload', () => { + + cy.get('#scaleSlider') + .invoke('val') + .should('equal', '0'); + + let oldWidth: number; + cy.get('[data-cy="stage-0"]') + .then(($el) => { + oldWidth = $el[0].getBoundingClientRect().width; + cy.log('Initial stage width: ' + oldWidth); + }); + + cy.get('#scaleSlider') + .invoke("val", 75) + .trigger("input"); + + cy.wait(500); + + cy.get('#scaleSlider') + .invoke('val') + .should('equal', '75'); + + let newWidth : number; + cy.get('[data-cy="stage-0"]') + .then(($el) => { + newWidth = $el[0].getBoundingClientRect().width; + cy.log('After dragging, new width: ' + newWidth); + expect(newWidth).to.be.greaterThan(oldWidth); + }); + + + cy.reload(); + cy.wait(500) + + // After reload, check the slider position + cy.get('#scaleSlider') + .invoke('val') + .should('equal', '75'); + + // Check that the stage block is still the new size + cy.get('[data-cy="stage-0"]') + .then(($el) => { + const reloadedWidth = $el[0].getBoundingClientRect().width; + cy.log('Reloaded stage width: ' + reloadedWidth); + expect(reloadedWidth).to.be.closeTo(newWidth, 2); + + }); + }); + }); + \ No newline at end of file diff --git a/src/app/components/DraggableSplitter.tsx b/src/app/components/DraggableSplitter.tsx index f2a9d71..e4de6a6 100644 --- a/src/app/components/DraggableSplitter.tsx +++ b/src/app/components/DraggableSplitter.tsx @@ -7,10 +7,12 @@ export default function DraggableSplitter({ isDragging, ...props }: any) { + const dataCy = dir === 'horizontal' ? 'splitter-horizontal' : 'splitter-vertical' return (
) => { + const scaleValue = 10 ** (Number(e.target.value) / 100); + setScale(scaleValue); + localStorage.setItem('timelineScale', e.target.value); // Store the slider value + }; return (
@@ -10,9 +15,9 @@ export default function TimelineTools({ setScale }: { setScale: any }) { type="range" min="-100" max="100" - defaultValue="0" + defaultValue={localStorage.getItem('timelineScale') || "0"} // Retrieve the slider value id="scaleSlider" - onChange={(e) => setScale(10 ** (Number(e.target.value) / 100))} + onInput={handleScaleChange} />
From f528965150efa16e3de0268d4a47bd1b81878459 Mon Sep 17 00:00:00 2001 From: gumillie222 <121700352+gumillie222@users.noreply.github.com> Date: Fri, 21 Feb 2025 13:39:11 -0500 Subject: [PATCH 2/3] fix page, no build error --- src/app/editor/page.tsx | 66 ++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/src/app/editor/page.tsx b/src/app/editor/page.tsx index 1b05d6d..e01458f 100644 --- a/src/app/editor/page.tsx +++ b/src/app/editor/page.tsx @@ -1,5 +1,6 @@ 'use client' -import React, { useState } from 'react' +import React, { useState, useEffect } from 'react' +import dynamic from 'next/dynamic' import { useResizable } from 'react-resizable-layout' import DraggableSplitter from '../components/DraggableSplitter' import CodeEditor from './components/CodeEditor' @@ -13,22 +14,59 @@ const defaultStageContext = { elapsed: 0, } -export default function EditorPage({}) { - const { position: leftWidth, separatorProps: codeSeparatorProps } = +function EditorPageContent() { + + const [leftWidth, setLeftWidth] = useState(() => { + if (typeof window !== 'undefined') { + const stored = localStorage.getItem('editor.leftWidth') + return stored ? Number(stored) : 1000 + } + return 1000 + }) + + const [upperLeftHeight, setUpperLeftHeight] = useState(() => { + if (typeof window !== 'undefined') { + const stored = localStorage.getItem('editor.upperLeftHeight') + return stored ? Number(stored) : 500 + } + return 500 + }) + + const { position: leftWidthPosition, separatorProps: codeSeparatorProps } = useResizable({ axis: 'x', - initial: 1000, + initial: leftWidth, min: 100, + onResizeEnd: ({ position }) => { + setLeftWidth(position) + localStorage.setItem('editor.leftWidth', String(position)) + }, }) - console.log('page.tsx, context', defaultStageContext) - - const { position: upperLeftHeight, separatorProps: timelineSeparatorProps } = + const { position: upperLeftHeightPosition, separatorProps: timelineSeparatorProps } = useResizable({ axis: 'y', - initial: 500, + initial: upperLeftHeight, + min: 100, + // Called after every drag + onResizeEnd: ({position}) => { + setUpperLeftHeight(position) + localStorage.setItem('editor.upperLeftHeight', String(position)) + }, }) + useEffect(() => { + if (leftWidth !== leftWidthPosition) { + setLeftWidth(leftWidthPosition) + } + }, [leftWidth, leftWidthPosition]) + + useEffect(() => { + if (upperLeftHeight !== upperLeftHeightPosition) { + setUpperLeftHeight(upperLeftHeightPosition) + } + }, [upperLeftHeight, upperLeftHeightPosition]) + const [renderElements, setRenderElements] = useState([]) const [renderPanelStage, setRenderPanelStage] = useState({}) @@ -38,12 +76,12 @@ export default function EditorPage({}) {
@@ -64,3 +102,11 @@ export default function EditorPage({}) { ) } + + +const DynamicEditorPage = dynamic( + () => Promise.resolve(EditorPageContent), + { ssr: false } +) + +export default DynamicEditorPage \ No newline at end of file From 1e76df8b2a160cafb47a874b437503431aa0cfd4 Mon Sep 17 00:00:00 2001 From: gumillie222 <121700352+gumillie222@users.noreply.github.com> Date: Fri, 21 Feb 2025 13:42:58 -0500 Subject: [PATCH 3/3] timeline fixed --- src/app/editor/components/Timeline.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/editor/components/Timeline.tsx b/src/app/editor/components/Timeline.tsx index e203253..4e42b4c 100644 --- a/src/app/editor/components/Timeline.tsx +++ b/src/app/editor/components/Timeline.tsx @@ -14,7 +14,12 @@ export default function Timeline({ }: { setRenderPanelStage: any }) { - const [scale, setScale] = useState(1) // pixels per second + const [scale, setScale] = useState(() => { + // Retrieve the scale value from localStorage on initial render + const storedScale = localStorage.getItem('timelineScale'); + return storedScale ? 10 ** (Number(storedScale) / 100) : 1; + }); + const [stageOptions, setStageOptions] = useState([]) const [treatmentOptions, setTreatmentOptions] = useState([]) const [introSequenceOptions, setIntroSequenceOptions] = useState([])