UI: Improve navigation system of in-game documentation viewer (#2499)

* UI: Improve navigation system of in-game documentation viewer

* Update based on feedback

* Update based on feedback
This commit is contained in:
catloversg
2026-02-17 00:00:58 +07:00
committed by GitHub
parent dd78a2cb44
commit 9a6e80129f
5 changed files with 172 additions and 74 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ export const getPage = (title: string): string => {
return resolvePage(title).pageContent;
};
export const DocumentationPopUpEvents = new EventEmitter<[string | undefined]>();
export const DocumentationPopUpEvents = new EventEmitter<[string]>();
export function openDocumentationPopUp(path: string): void {
DocumentationPopUpEvents.emit(path);
+25 -34
View File
@@ -1,8 +1,8 @@
import React, { useEffect, useRef, useState } from "react";
import { Modal } from "../../ui/React/Modal";
import { defaultNsApiPage, Navigator, openDocExternally } from "../../ui/React/Documentation";
import { convertNavigatorHref, Navigator, openDocExternally } from "../../ui/React/Documentation";
import { MD } from "../../ui/MD/MD";
import { asFilePath, type FilePath, isFilePath, resolveFilePath } from "../../Paths/FilePath";
import { asFilePath, type FilePath } from "../../Paths/FilePath";
import { DocumentationPopUpEvents } from "../root";
export function DocumentationPopUp({ hidden }: { hidden: boolean }) {
@@ -11,8 +11,8 @@ export function DocumentationPopUp({ hidden }: { hidden: boolean }) {
useEffect(
() =>
DocumentationPopUpEvents.subscribe((path?: string) => {
setPath(path ? asFilePath(path) : undefined);
DocumentationPopUpEvents.subscribe((path: string) => {
setPath(asFilePath(path));
}),
[],
);
@@ -24,39 +24,30 @@ export function DocumentationPopUp({ hidden }: { hidden: boolean }) {
modalWrapperRef.current.scrollTo({ top: 0, behavior: "instant" });
});
const navigator = {
navigate(href: string, openExternally: boolean) {
/**
* This function is used for navigating inside the documentation popup.
*
* Href can be:
* - Internal NS docs. The "markdown" folder does not have any subfolders. All files are at the top-level. "Href"
* is always "./<filename>". E.g., "./bitburner.ns.md".
* - HTTP URL (e.g., ns.printf has a link to https://github.com/alexei/sprintf.js).
*/
let path;
if (href.startsWith("https://") || href.startsWith("http://")) {
openExternally = true;
path = href;
} else {
path = resolveFilePath(href, defaultNsApiPage);
}
if (!path) {
console.error(`Bad path ${href} while navigating docs.`);
return;
}
if (openExternally) {
openDocExternally(path);
return;
}
if (isFilePath(path)) {
setPath(path);
}
},
};
if (!path) {
return <></>;
}
const navigator = {
/**
* This function is used for navigating inside the documentation popup.
*/
navigate(href: string, openExternally: boolean) {
if (!path) {
return;
}
const { path: newPath, forceOpenExternally } = convertNavigatorHref(href, path);
if (!newPath) {
console.error(`Bad path ${href} while navigating docs.`);
return;
}
if (openExternally || forceOpenExternally) {
openDocExternally(newPath);
return;
}
setPath(newPath);
},
};
return (
<Modal
open={!hidden}
+8 -36
View File
@@ -9,9 +9,9 @@ import {
windowTopPositionOfPages,
useHistory,
openDocExternally,
prefixOfHttpUrlOfNsDocs,
convertNavigatorHref,
} from "../../ui/React/Documentation";
import { asFilePath, isFilePath, resolveFilePath } from "../../Paths/FilePath";
import { asFilePath } from "../../Paths/FilePath";
import { Settings } from "../../Settings/Settings";
import { Router } from "../../ui/GameRoot";
import { Page } from "../../ui/Router";
@@ -21,48 +21,20 @@ export function DocumentationRoot({ docPage }: { docPage?: string }): React.Reac
const history = useHistory();
const [deepLink, setDeepLink] = useState(docPage);
const navigator = {
/**
* This function is used for navigating inside the documentation tab.
*/
navigate(href: string, openExternally: boolean) {
let path;
/**
* Href can be:
* - Internal NS docs: nsDoc/bitburner.ns.md
* - Internal non-NS docs: help/getting_started.md
* - HTTP URL:
* - Point to NS docs. Some non-NS docs pages include links to NS docs. For example: basic/scripts.md has a
* link to https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.ns.flags.md. In
* these cases, the link always points to a file at https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/
* - Point to other places.
*/
if (href.startsWith("nsDoc/")) {
// Internal NS docs
path = asFilePath(href);
} else if (href.startsWith("https://") || href.startsWith("http://")) {
/**
* HTTP URL pointing to NS docs.
* Convert https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/page.md to nsDoc/page.md
*/
if (href.startsWith(prefixOfHttpUrlOfNsDocs)) {
path = asFilePath(`nsDoc/${href.replace(prefixOfHttpUrlOfNsDocs, "")}`);
} else {
// HTTP URL pointing to other places.
openExternally = true;
path = href;
}
} else {
// Internal non-NS docs
path = resolveFilePath("./" + href, history.page);
}
const { path, forceOpenExternally } = convertNavigatorHref(href, history.page);
if (!path) {
console.error(`Bad path ${href} from ${history.page} while navigating docs.`);
return;
}
if (openExternally) {
if (openExternally || forceOpenExternally) {
openDocExternally(path);
return;
}
if (isFilePath(path)) {
history.push(path);
}
history.push(path);
},
};