diff --git a/frontend/src/components/Scratch/Scratch.tsx b/frontend/src/components/Scratch/Scratch.tsx index 568db33..91b1b7b 100644 --- a/frontend/src/components/Scratch/Scratch.tsx +++ b/frontend/src/components/Scratch/Scratch.tsx @@ -40,6 +40,7 @@ import ScratchToolbar from "./ScratchToolbar"; import { StreamLanguage } from "@codemirror/language"; import { pascal } from "@/lib/codemirror/pascal"; import ObjdiffPanel from "../Diff/ObjdiffPanel"; +import ScrollRestorer from "../ScrollRestorer"; enum TabId { ABOUT = "scratch_about", @@ -164,6 +165,8 @@ export default function Scratch({ const contextEditor = useRef(null); const [valueVersion, incrementValueVersion] = useReducer((x) => x + 1, 0); + const compilerOptsScrollPosition = useRef(0); + const [isModified, setIsModified] = useState(false); const setScratch = (scratch: Partial) => { onChange(scratch); @@ -263,19 +266,17 @@ export default function Scratch({ saveContext(); }} > - {() => ( - { - setScratch({ source_code: value }); - }} - onSelectedLineChange={setSelectedSourceLine} - extensions={cmExtensionsSource} - /> - )} + { + setScratch({ source_code: value }); + }} + onSelectedLineChange={setSelectedSourceLine} + extensions={cmExtensionsSource} + /> ); case TabId.CONTEXT: @@ -290,18 +291,16 @@ export default function Scratch({ saveSource(); }} > - {() => ( - { - setScratch({ context: value }); - }} - extensions={cmExtensionsContext} - /> - )} + { + setScratch({ context: value }); + }} + extensions={cmExtensionsContext} + /> ); case TabId.OPTIONS: @@ -313,7 +312,10 @@ export default function Scratch({ className={styles.compilerOptsTab} > {() => ( -
+ -
+ )} ); diff --git a/frontend/src/components/ScrollRestorer.tsx b/frontend/src/components/ScrollRestorer.tsx new file mode 100644 index 0000000..d4f1597 --- /dev/null +++ b/frontend/src/components/ScrollRestorer.tsx @@ -0,0 +1,42 @@ +import type React from "react"; +import { useEffect, useRef } from "react"; + +interface ScrollRestorerProps { + scrollPositionRef: React.RefObject; + children: React.ReactNode; + className?: string; +} + +const ScrollRestorer: React.FC = ({ + scrollPositionRef, + children, + className, +}) => { + const containerRef = useRef(null); + + useEffect(() => { + const el = containerRef.current; + if (!el) return; + + // Restore scroll position on initial mount + el.scrollTop = scrollPositionRef.current; + + // Save scroll position on scroll + const handleScroll = () => { + scrollPositionRef.current = el.scrollTop; + }; + + el.addEventListener("scroll", handleScroll); + return () => { + el.removeEventListener("scroll", handleScroll); + }; + }, []); + + return ( +
+ {children} +
+ ); +}; + +export default ScrollRestorer;