diff --git a/packages/web_ui/src/components/LogConsole.tsx b/packages/web_ui/src/components/LogConsole.tsx index f422a73c..13332bc7 100644 --- a/packages/web_ui/src/components/LogConsole.tsx +++ b/packages/web_ui/src/components/LogConsole.tsx @@ -4,10 +4,14 @@ import { Select, Typography } from "antd"; import * as lib from "@clusterio/lib"; import { useAccount } from "../model/account"; +import useLocalStorage from "../util/useLocalStorage"; import ControlContext from "./ControlContext"; const { Paragraph } = Typography; +const consoleHeightKey = "instance-console-height"; +const defaultConsoleHeight = 300; + type Parsed = { format: string; type: string; @@ -99,6 +103,28 @@ export default function LogConsole(props: LogConsoleProps) { let anchor = useRef(); let [pastLines, setPastLines] = useState([{"Loading past entries..."}
]); let [lines, setLines] = useState([]); + const [consoleHeight, setConsoleHeight] = useLocalStorage(consoleHeightKey, defaultConsoleHeight); + const consoleHeightRef = useRef(consoleHeight); + consoleHeightRef.current = consoleHeight; + + // Persist the height the user drag-resizes the console to, so it is restored + // on the next visit. The scroll container is the element wrapping the + // anchor. + useEffect(() => { + const element = anchor.current?.parentElement as HTMLElement | undefined; + if (!element || typeof ResizeObserver === "undefined") { + return undefined; + } + const observer = new ResizeObserver(() => { + const next = Math.round(element.offsetHeight); + if (next && next !== consoleHeightRef.current) { + consoleHeightRef.current = next; + setConsoleHeight(next); + } + }); + observer.observe(element); + return () => observer.disconnect(); + }, []); useEffect(() => { let logFilter = { @@ -163,7 +189,11 @@ export default function LogConsole(props: LogConsoleProps) { ]); return <> - + {pastLines} {lines}
diff --git a/packages/web_ui/src/style.css b/packages/web_ui/src/style.css index ef9fcdf4..d04ca110 100644 --- a/packages/web_ui/src/style.css +++ b/packages/web_ui/src/style.css @@ -171,13 +171,19 @@ body { margin: 0; background: #000; border-color: #252525; - height: 300px; + /* Height is driven by --console-height (set from the persisted user choice) + so the console can be drag-resized; the resize handle needs a non-visible + overflow, which overflow-y: scroll provides. */ + height: var(--console-height, 300px); + min-height: 100px; + resize: vertical; overflow-y: scroll; white-space: pre-wrap; /* Make sure there's at least one pixel of scroll space, this */ - /* is necessary for the view to stick on the scroll anchor. */ - padding-top: 300px; + /* is necessary for the view to stick on the scroll anchor. Tracks the */ + /* height so the pin-to-bottom keeps working at any size. */ + padding-top: var(--console-height, 300px); } .instance-console .factorio-time {