From 6128d801a993e92a5073de8c9f002c7aac71e7f8 Mon Sep 17 00:00:00 2001 From: Maxim Date: Thu, 9 May 2024 03:24:06 +0300 Subject: [PATCH] Virtualize events list --- package.json | 3 +- pnpm-lock.yaml | 24 ++++++++++++++++ src/App.module.scss | 25 ++++++++++------- src/App.tsx | 35 ++++++++++++++++-------- src/visualizers/turing-machine/start.tsx | 5 ++-- 5 files changed, 67 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 5eb1306..e16e78a 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "monaco-editor": "^0.46.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "use-immer": "^0.9.0" + "use-immer": "^0.9.0", + "virtua": "^0.30.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7cae33..fd68e60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: use-immer: specifier: ^0.9.0 version: 0.9.0(immer@10.0.3)(react@18.2.0) + virtua: + specifier: ^0.30.5 + version: 0.30.5(react-dom@18.2.0)(react@18.2.0) devDependencies: '@types/lodash': @@ -3337,6 +3340,27 @@ packages: react: 18.2.0 dev: false + /virtua@0.30.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-rLx19CVwHHf+ombzwUPNVoRVUEd8nJNCzFi000X7ALy/J9hLvftoltiqBSJ/9DxQwv6tZ4B+NZoPDee10mpT+A==} + peerDependencies: + react: '>=16.14.0' + react-dom: '>=16.14.0' + solid-js: '>=1.0' + vue: '>=3.2' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + solid-js: + optional: true + vue: + optional: true + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /vite-plugin-inspect@0.8.1(rollup@4.9.2)(vite@5.0.10): resolution: {integrity: sha512-oPBPVGp6tBd5KdY/qY6lrbLXqrbHRG0hZLvEaJfiZ/GQfDB+szRuLHblQh1oi1Hhh8GeLit/50l4xfs2SA+TCA==} engines: {node: '>=14'} diff --git a/src/App.module.scss b/src/App.module.scss index f599cd8..caee52c 100644 --- a/src/App.module.scss +++ b/src/App.module.scss @@ -67,18 +67,23 @@ html, body { margin-bottom: 20px; } .events { + flex-grow: 1; overflow-y: auto; - display: grid; - .event { - cursor: pointer; - box-sizing: border-box; - border-top: 1px #c3c3c3 solid; - &:last-child { - border-bottom: 1px #c3c3c3 solid; - } - &.selected { - background-color: #eee; + display: flex; + flex-direction: column; + .eventsContainer{ + flex-grow: 1; + .event { + cursor: pointer; + box-sizing: border-box; border-top: 1px #c3c3c3 solid; + &:last-child { + border-bottom: 1px #c3c3c3 solid; + } + &.selected { + background-color: #eee; + border-top: 1px #c3c3c3 solid; + } } } } diff --git a/src/App.tsx b/src/App.tsx index cce3bff..abec58a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,12 @@ /* @refresh reload */ -import { useEffect, useState } from "react" +import { useEffect, useRef, useState } from "react" import { RuntimeStore } from "./core/store" import { IAlgorithmManifest } from "./core/manifest" import { useVisualizer } from "./core/react" import "@fontsource-variable/arimo" import styles from "./App.module.scss" import classNames from "classnames" +import { VList, VListHandle } from "virtua" type AppProps = { manifest: IAlgorithmManifest, @@ -20,7 +21,6 @@ const App = ({ manifest, store }: AppProps) => { const vis = useVisualizer(store) const {curState, curEvent, events, currentStep, start, next} = vis const [eventOverride, setEventOverride] = useState(undefined) - const [skipCounter, setSkipCounter] = useState(undefined) const curEventOverride = eventOverride !== undefined && events !== undefined ? events[eventOverride] : curEvent const curStateOverride = eventOverride !== undefined && events !== undefined ? events[eventOverride].state : curState const isRunning = curEventOverride !== undefined && curStateOverride !== undefined @@ -46,11 +46,17 @@ const App = ({ manifest, store }: AppProps) => { setEventOverride(eventOverride - 1) } } + const eventsHandle = useRef(null) const doStart: typeof start = (...args) => { setCurTab(Tab.Render) setEventOverride(undefined) start(...args) } + useEffect(() => { + if(eventsHandle.current !== null) { + eventsHandle.current.scrollToIndex(eventOverride ?? currentStep ?? 0, {align: "nearest"}) + } + }, [eventOverride, currentStep]) useEffect(() => { const keyListener = (e: KeyboardEvent) => { if (e.key === "ArrowRight") { @@ -108,16 +114,21 @@ const App = ({ manifest, store }: AppProps) => {
Events: -
- {events ? events.map((x, i) => { - const isSelected = i === eventOverride || (eventOverride === undefined && i === currentStep! - 1) - return
setEventOverride(i)}> - - {i + 1} {x.name} -
- }) : "Nothing yet.."} +
+ {events ? + + {events.map((event, index) => { + const isSelected = index === eventOverride || (eventOverride === undefined && index === currentStep! - 1) + return
setEventOverride(index)}> + + {index + 1} {event.name} +
+ })} +
+ : "Nothing yet.." + }
diff --git a/src/visualizers/turing-machine/start.tsx b/src/visualizers/turing-machine/start.tsx index e8fa9be..4f34480 100644 --- a/src/visualizers/turing-machine/start.tsx +++ b/src/visualizers/turing-machine/start.tsx @@ -61,9 +61,9 @@ export const TuringMachineStart = ({ doStart }: StartProps ) } - const onStart = useCallback(() => { + const onStart = useCallback((full: boolean) => () => { if (editorRef.current !== null) { - doStart([editorRef.current.getValue(), tape, 10_000], false) + doStart([editorRef.current.getValue(), tape, 10_000], full) } }, [tape]) useEffect(() => { // https://github.com/Microsoft/monaco-editor/issues/28 @@ -96,5 +96,6 @@ s 0 -> n _ > n 0 -> s _ > n _ -> rj _ >"/> + }