Merge pull request #1386 from yashsinghcodes/1.4.0

Docs performance improvement
This commit is contained in:
Frikky
2024-05-13 14:34:45 +02:00
committed by GitHub
2 changed files with 105 additions and 58 deletions
+2 -1
View File
@@ -24,7 +24,8 @@ function ScrollToTop({ getUserNotifications, curpath, setCurpath, history }) {
// Custom handler for certain scroll mechanics // Custom handler for certain scroll mechanics
// //
//console.log("OLD: ", curpath, "NeW: ", window.location.pathname) //console.log("OLD: ", curpath, "NeW: ", window.location.pathname)
if (curpath === window.location.pathname && curpath === "/usecases") { if (curpath === window.location.pathname && (curpath === "/usecases" ||
(curpath === "/docs" && location.hash.length > 0))) {
} else { } else {
window.scroll({ window.scroll({
+77 -31
View File
@@ -51,7 +51,7 @@ const Body = {
const dividerColor = "rgb(225, 228, 232)"; const dividerColor = "rgb(225, 228, 232)";
const hrefStyle = { const hrefStyle = {
color: "rgba(255, 255, 255, 0.40)", color: "rgba(255, 255, 255, 0.8)",
textDecoration: "none", textDecoration: "none",
}; };
@@ -219,6 +219,7 @@ const Docs = (defaultprops) => {
const [data, setData] = useState(""); const [data, setData] = useState("");
const [firstrequest, setFirstrequest] = useState(true); const [firstrequest, setFirstrequest] = useState(true);
const [list, setList] = useState([]); const [list, setList] = useState([]);
const [lastHeading, setLastHeading] = useState(false);
const [activeId, setActiveId] = useState() const [activeId, setActiveId] = useState()
const [isopen, setOpen] = useState(-1); const [isopen, setOpen] = useState(-1);
const [hover, setHover] = useState(false); const [hover, setHover] = useState(false);
@@ -245,40 +246,32 @@ const Docs = (defaultprops) => {
//} //}
}, []) }, [])
function handleClick(event) { const handleClick = (event) => {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
} }
function handleClickToc(event) { const handleClickToc = (event) => {
setAnchorElToc(event.currentTarget); setAnchorElToc(event.currentTarget);
} }
function handleCollapse(index) { const handleCollapse = (index) => {
setOpen(isopen === index ? -1 : index) setOpen(isopen === index ? -1 : index)
} }
function handleMouseOver() { const handleMouseOver = () => {
setHover(!hover); setHover(!hover);
} }
function handleClose() { const handleClose = () => {
setAnchorEl(null) setAnchorEl(null)
} }
function handleCloseToc() { const handleCloseToc = () => {
setAnchorElToc(null) setAnchorElToc(null)
} }
// Emma Goto
const activeIdsetter = (id) => {
setActiveId(id)
}
const intersectionObserver = () => { const intersectionObserver = () => {
const callback = (headings) => { const callback = (headings) => {
console.log("Headings: ", headings)
headingElementsRef.current = headings.reduce((map, headingElement) => { headingElementsRef.current = headings.reduce((map, headingElement) => {
if (map === undefined) { if (map === undefined) {
return {} return {}
@@ -295,37 +288,49 @@ const Docs = (defaultprops) => {
}, headingElementsRef.current) }, headingElementsRef.current)
const visibleHeadings = [] const visibleHeadings = []
Object.keys(headingElementsRef.current).forEach((key) => { const keys = Object.keys(headingElementsRef.current)
const headingElemet = headingElementsRef.current[key]
if (headingElemet.isIntersecting) { for (var i = 0; i < keys.length; i++) {
visibleHeadings.push(headingElemet) const headingElement = headingElementsRef.current[keys[i]]
if (headingElement.isIntersecting) {
visibleHeadings.push(headingElement)
}
} }
})
if (visibleHeadings.length > 0) { if (visibleHeadings.length > 0) {
//setActiveId(visibleHeadings[0].target.id) const tocs = document.getElementsByClassName('toc')
activeIdsetter(visibleHeadings[0].target.id) for (const t of tocs) {
const currentPoint = t.getElementsByTagName('a')[0]
currentPoint.style.color = "white";
if (`#${visibleHeadings[0].target.id}`
=== currentPoint.hash) {
currentPoint.style.color = "#f86a3e";
}
}
} }
} }
const observer = new IntersectionObserver(callback, { const observer = new IntersectionObserver(callback, {
threshold: [1]
}) })
const headingElements = Array.from(document.querySelectorAll("h2")) const headingElements = Array.from(document.querySelectorAll("h2"))
if (headingElements.length != 0) { if (headingElements.length != 0) {
headingElements.forEach((element) => observer.observe(element)) for (var i = 0; i < headingElements.length; i++) {
var element = headingElements[i]
observer.observe(element)
}
return () => observer.disconnect() return () => observer.disconnect()
} }
} }
console.log("ACTIVEID: ", activeId) if (lastHeading) {
if (hashRendered) {
setTimeout(() => { setTimeout(() => {
intersectionObserver() intersectionObserver()
}, 2000) }, 100)
} }
const scrollToHash = () => { const scrollToHash = () => {
const hash = window.location.hash.replace("#", "") const hash = window.location.hash.replace("#", "")
if (hash) { if (hash) {
@@ -338,6 +343,37 @@ const Docs = (defaultprops) => {
} }
} }
// extract toc from all headings and subheadings
const extractHeadings = (content) => {
const headings = [];
const headingRegex = /^(#{2,3})\s+(.+)$/gm;
let match;
while ((match = headingRegex.exec(content)) !== null) {
const level = match[1].length;
const title = match[2].trim();
if (level === 2) {
headings.push({
id: title.toLowerCase().replace(/\s+/g, '-'),
title: title,
items: []
});
} else if (level === 3 && headings.length > 0) {
const lastHeading = headings[headings.length - 1];
lastHeading.items.push({
id: title.toLowerCase().replace(/\s+/g, '-'),
title: title
});
}
}
return headings
}
// extract TOC from actual markdown
const tocvalue = (markdown) => { const tocvalue = (markdown) => {
const items = []; const items = [];
let currentMainItem = null; let currentMainItem = null;
@@ -346,7 +382,7 @@ const Docs = (defaultprops) => {
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i]; const line = lines[i];
if (line.startsWith('* [')) { if (line.startsWith('* [') && !line.startsWith(" ", 5)) {
const matches = line.match(/^\* \[([^)]+)\]\(#([^)]+)\)/); const matches = line.match(/^\* \[([^)]+)\]\(#([^)]+)\)/);
if (matches) { if (matches) {
currentMainItem = { currentMainItem = {
@@ -403,6 +439,12 @@ const Docs = (defaultprops) => {
}, 500) }, 500)
} }
if (serverside !== true && !lastHeading) {
setTimeout(() => {
setLastHeading(true)
}, 500)
}
var extraInfo = ""; var extraInfo = "";
if (props.level === 1) { if (props.level === 1) {
extraInfo = ( extraInfo = (
@@ -413,7 +455,6 @@ const Docs = (defaultprops) => {
borderRadius: theme.palette.borderRadius, borderRadius: theme.palette.borderRadius,
marginBottom: 30, marginBottom: 30,
display: "flex", display: "flex",
scrollPaddingTop: 20,
}} }}
> >
<div style={{ flex: 3, display: "flex", vAlign: "center", position: "sticky", top: 50, }}> <div style={{ flex: 3, display: "flex", vAlign: "center", position: "sticky", top: 50, }}>
@@ -533,6 +574,7 @@ const Docs = (defaultprops) => {
width: "17%", width: "17%",
position: "sticky", position: "sticky",
top: 50, top: 50,
paddingTop: "0.25em",
minHeight: "93vh", minHeight: "93vh",
maxHeight: "93vh", maxHeight: "93vh",
overflowX: "hidden", overflowX: "hidden",
@@ -587,7 +629,7 @@ const Docs = (defaultprops) => {
if (responseJson.success && responseJson.reason !== undefined) { if (responseJson.success && responseJson.reason !== undefined) {
// Find <img> tags and translate them into ![]() format // Find <img> tags and translate them into ![]() format
const imgRegex = /<img.*?src="(.*?)"/g; const imgRegex = /<img.*?src="(.*?)"/g;
const tocRegex = /^## Table of contents[\s\S]*?(?=^##\s|\Z)|^\* \[[^\]]+\]\([^)]+\)\n?(?![^\n]+\]\([^)]+\))/gm; const tocRegex = /^## Table of contents[\s\S]*?(?=^## )|^## Table of contents[\s\S]*$/gm;
const newdata = responseJson.reason.replace(imgRegex, '![]($1)') const newdata = responseJson.reason.replace(imgRegex, '![]($1)')
.replace(tocRegex, ""); .replace(tocRegex, "");
setData(newdata); setData(newdata);
@@ -611,10 +653,14 @@ const Docs = (defaultprops) => {
responseJson.reason !== undefined && responseJson.reason !== undefined &&
responseJson.reason !== null responseJson.reason !== null
) { ) {
/*
const values = tocvalue(responseJson.reason.match(tocRegex) const values = tocvalue(responseJson.reason.match(tocRegex)
.join() .join()
.toString()); .toString());
setTocLines(values); setTocLines(values);
*/
const values = extractHeadings(newdata)
setTocLines(values)
} }
} else { } else {
setData("# Error\nThis page doesn't exist."); setData("# Error\nThis page doesn't exist.");
@@ -1134,7 +1180,7 @@ const Docs = (defaultprops) => {
// Padding and zIndex etc set because of footer in cloud. // Padding and zIndex etc set because of footer in cloud.
const loadedCheck = ( const loadedCheck = (
<div style={{ minHeight: 1000, paddingBottom: 100, zIndex: 50000, maxWidth: 1920, minWidth: isMobile ? null : 1366, margin: "auto", }}> <div style={{ minHeight: 1000, paddingTop: "60px", zIndex: 50000, maxWidth: 1920, minWidth: isMobile ? null : 1366, margin: "auto", }}>
<BrowserView>{postDataBrowser}</BrowserView> <BrowserView>{postDataBrowser}</BrowserView>
<MobileView>{postDataMobile}</MobileView> <MobileView>{postDataMobile}</MobileView>
</div> </div>