mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2025-03-11 04:42:34 +01:00
UI: Remember last position of documentation pages (#1434)
This commit is contained in:
@ -1,12 +1,15 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useLayoutEffect, useState } from "react";
|
||||
|
||||
import Button from "@mui/material/Button";
|
||||
import { MD } from "../../ui/MD/MD";
|
||||
|
||||
import { getPage } from "../root";
|
||||
import { Navigator, useHistory } from "../../ui/React/Documentation";
|
||||
import { Navigator, windowTopPositionOfPages, useHistory } from "../../ui/React/Documentation";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { asFilePath, resolveFilePath } from "../../Paths/FilePath";
|
||||
import Box from "@mui/material/Box";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Page } from "../../ui/Router";
|
||||
|
||||
export function DocumentationRoot({ docPage }: { docPage?: string }): React.ReactElement {
|
||||
const history = useHistory();
|
||||
@ -15,7 +18,6 @@ export function DocumentationRoot({ docPage }: { docPage?: string }): React.Reac
|
||||
history.push(asFilePath(deepLink));
|
||||
setDeepLink(undefined);
|
||||
}
|
||||
const page = getPage(history.page);
|
||||
const navigator = {
|
||||
navigate(relPath: string, external: boolean) {
|
||||
const newPath = resolveFilePath("./" + relPath, history.page);
|
||||
@ -30,19 +32,30 @@ export function DocumentationRoot({ docPage }: { docPage?: string }): React.Reac
|
||||
return;
|
||||
}
|
||||
history.push(newPath);
|
||||
|
||||
// Reset scroll to the top of the page.
|
||||
window.scrollTo(0, 0);
|
||||
},
|
||||
};
|
||||
|
||||
// We need to use "useLayoutEffect" instead of "useEffect". "useLayoutEffect" is fired before the browser repaints the
|
||||
// screen.
|
||||
useLayoutEffect(() => {
|
||||
return () => {
|
||||
if (Router.page() !== Page.Documentation) {
|
||||
windowTopPositionOfPages.set(history.page, window.scrollY);
|
||||
}
|
||||
};
|
||||
}, [history]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={() => history.pop()}>Back</Button>
|
||||
<Button onClick={() => history.home()}>Home</Button>
|
||||
<Navigator.Provider value={navigator}>
|
||||
<MD md={page + ""} />
|
||||
</Navigator.Provider>
|
||||
<Box position="fixed" top={0} zIndex={1} width="100%" paddingTop="8px" bgcolor={Settings.theme.backgroundprimary}>
|
||||
<Button onClick={() => history.pop()}>Back</Button>
|
||||
<Button onClick={() => history.home()}>Home</Button>
|
||||
</Box>
|
||||
<Box paddingTop="50px">
|
||||
<Navigator.Provider value={navigator}>
|
||||
<MD pageFilePath={history.page} top={windowTopPositionOfPages.get(history.page) ?? 0} />
|
||||
</Navigator.Provider>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { TableHead } from "@mui/material";
|
||||
import remarkGfm from "remark-gfm";
|
||||
@ -7,8 +7,20 @@ import { code, Pre } from "./code";
|
||||
import { A } from "./a";
|
||||
import remarkMath from "remark-math";
|
||||
import rehypeMathjax from "rehype-mathjax/svg";
|
||||
import { FilePath } from "../../Paths/FilePath";
|
||||
import { getPage } from "../../Documentation/root";
|
||||
|
||||
export function MD(props: { pageFilePath: FilePath; top: number }): React.ReactElement {
|
||||
const pageContent = getPage(props.pageFilePath);
|
||||
|
||||
useEffect(() => {
|
||||
// This is a workaround. window.scrollTo does not work when we switch from Documentation tab to another tab, then
|
||||
// switch back.
|
||||
setTimeout(() => {
|
||||
window.scrollTo({ top: props.top, behavior: "instant" });
|
||||
}, 0);
|
||||
});
|
||||
|
||||
export function MD(props: { md: string }): React.ReactElement {
|
||||
return (
|
||||
<ReactMarkdown
|
||||
components={{
|
||||
@ -34,7 +46,7 @@ export function MD(props: { md: string }): React.ReactElement {
|
||||
remarkPlugins={[remarkGfm, remarkMath]}
|
||||
rehypePlugins={[rehypeMathjax]}
|
||||
>
|
||||
{props.md}
|
||||
{String(pageContent)}
|
||||
</ReactMarkdown>
|
||||
);
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ export const Navigator = React.createContext<Navigator>({ navigate: () => undefi
|
||||
|
||||
export const useNavigator = (): Navigator => useContext(Navigator);
|
||||
|
||||
export const windowTopPositionOfPages = new Map<FilePath, number>();
|
||||
|
||||
interface History {
|
||||
pages: FilePath[];
|
||||
page: FilePath;
|
||||
@ -59,13 +61,22 @@ export const HistoryProvider = (props: React.PropsWithChildren<object>): React.R
|
||||
page: defaultPage,
|
||||
pages: [],
|
||||
push(p: FilePath) {
|
||||
setHistory((h) => onPush(h, p));
|
||||
setHistory((h) => {
|
||||
windowTopPositionOfPages.set(h.page, window.scrollY);
|
||||
return onPush(h, p);
|
||||
});
|
||||
},
|
||||
pop() {
|
||||
setHistory((h) => onPop(h));
|
||||
setHistory((h) => {
|
||||
windowTopPositionOfPages.set(h.page, window.scrollY);
|
||||
return onPop(h);
|
||||
});
|
||||
},
|
||||
home() {
|
||||
setHistory((h) => onHome(h));
|
||||
setHistory((h) => {
|
||||
windowTopPositionOfPages.set(h.page, window.scrollY);
|
||||
return onHome(h);
|
||||
});
|
||||
},
|
||||
});
|
||||
return <Provider value={history}>{props.children}</Provider>;
|
||||
|
Reference in New Issue
Block a user