@alauda/doom
Version:
Doctor Doom making docs.
119 lines (118 loc) • 4.76 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { isProduction, NoSSR, useSite, withBase } from '@rspress/core/runtime';
import {} from '@rspress/shared';
import virtual from 'doom-@global-virtual';
import { noop } from 'es-toolkit';
import { useEffect, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';
import { base } from 'virtual-runtime-config';
import { parse } from 'yaml';
import { ACP_BASE, getPdfName, getUnversionedVersion, isExplicitlyUnversioned, } from '../../shared/index.js';
import { NavMenuGroup } from './NavMenuGroup.js';
import { NavMenuSingleItem } from './NavMenuSingleItem.js';
import { useLang, useTranslation } from '@alauda/doom/runtime';
const getNavMenu = () => {
if (typeof document === 'undefined') {
return null;
}
return document.querySelector('.rspress-nav-menu');
};
const LEGACY_VERSIONS = ['v3.18.1', 'v3.18.0', 'v3.16', 'v3.14'];
const LEGACY_NAV_ITEMS = LEGACY_VERSIONS.map((v) => ({
text: v,
link: `https://docs.alauda.io/document/release-notes?version=${v}`,
}));
const ALLOWED_LEGACY_DOMAINS = new Set(['docs.alauda.cn', 'docs.alauda.io']);
if (!isProduction()) {
ALLOWED_LEGACY_DOMAINS.add('localhost');
}
const VersionsNav_ = () => {
const { site } = useSite();
const lang = useLang();
const t = useTranslation();
const siteTitle = site.originalTitle ?? site.title;
const downloadLink = useMemo(() => {
if (!virtual.download) {
return;
}
return withBase(getPdfName(lang, virtual.userBase, siteTitle));
}, [lang, siteTitle]);
const [versionsBase, version] = useMemo(() => {
const unversionedVersion = getUnversionedVersion(virtual.version);
if (!unversionedVersion) {
return [];
}
return [
isExplicitlyUnversioned(virtual.version)
? undefined
: base.slice(0, -unversionedVersion.length - 1),
unversionedVersion,
];
}, []);
const [navMenu, setNavMenu] = useState(getNavMenu);
const [versions, setVersions] = useState(version ? [version] : []);
useEffect(() => {
const fetchVersions = async () => {
if (versionsBase == null) {
if (!version) {
return;
}
}
else {
const res = await fetch(`${isProduction() ? versionsBase : base}/versions.yaml`);
if (!res.ok) {
return;
}
const text = await res.text();
const versions = parse(text);
if (version && !versions.includes(version)) {
versions.unshift(version);
}
setVersions(versions);
}
setNavMenu(getNavMenu);
};
void fetchVersions().catch(noop);
}, [version, versionsBase]);
// hack way to detect nav menu recreation on theme change
useEffect(() => {
if (!navMenu) {
return;
}
const observer = new MutationObserver((mutations) => {
if (mutations.some((m) => m.removedNodes.length)) {
setNavMenu(getNavMenu);
}
});
const newNavMenu = getNavMenu();
if (newNavMenu !== navMenu) {
// eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
setNavMenu(newNavMenu);
}
else if (navMenu.parentNode) {
observer.observe(navMenu.parentNode, { childList: true });
}
return () => {
observer.disconnect();
};
}, [navMenu]);
const navItems = useMemo(() => {
const versionItems = versions.map((v) => versionsBase == null
? { text: v, items: [] }
: { text: v, link: `${versionsBase}/${v}/`, activeMatch: v });
if (versionsBase != null &&
ALLOWED_LEGACY_DOMAINS.has(location.hostname) &&
virtual.userBase === ACP_BASE) {
versionItems.push(...LEGACY_NAV_ITEMS);
}
return versionItems;
}, [versionsBase, versions]);
let finalNavMenu;
if ((!navItems.length && !virtual.download) ||
!(finalNavMenu = getNavMenu())) {
return;
}
return createPortal(_jsxs(_Fragment, { children: [downloadLink && (_jsx(NavMenuSingleItem, { text: t('download_pdf'), link: downloadLink, download: true })), !navItems.length || (_jsx(NavMenuGroup, { text: version, base: versionsBase, items: navItems, pathname: base }))] }), finalNavMenu);
};
export const VersionsNav = () => (_jsx(NoSSR, { children: _jsx(VersionsNav_, {}) }));
export default VersionsNav;