handle hash urls with 'view more'

This commit is contained in:
keyan 2023-12-20 18:16:34 -06:00
parent 1e03f3b63f
commit 633c96d619
2 changed files with 21 additions and 3 deletions

View File

@ -6,8 +6,10 @@ import { fromMarkdown } from 'mdast-util-from-markdown'
import { visit } from 'unist-util-visit' import { visit } from 'unist-util-visit'
import { toString } from 'mdast-util-to-string' import { toString } from 'mdast-util-to-string'
import GithubSlugger from 'github-slugger' import GithubSlugger from 'github-slugger'
import { useRouter } from 'next/router'
export default function Toc ({ text }) { export default function Toc ({ text }) {
const router = useRouter()
if (!text || text.length === 0) { if (!text || text.length === 0) {
return null return null
} }
@ -42,6 +44,8 @@ export default function Toc ({ text }) {
marginLeft: `${(v.depth - 1) * 5}px` marginLeft: `${(v.depth - 1) * 5}px`
}} }}
href={`#${v.slug}`} key={v.slug} href={`#${v.slug}`} key={v.slug}
// nextjs router doesn't emit hashChangeStart events
onClick={() => router.events.emit('hashChangeStart', `#${v.slug}`, { shallow: true })}
>{v.heading} >{v.heading}
</Dropdown.Item> </Dropdown.Item>
) )

View File

@ -17,6 +17,7 @@ import { IMGPROXY_URL_REGEXP } from '../lib/url'
import reactStringReplace from 'react-string-replace' import reactStringReplace from 'react-string-replace'
import { rehypeInlineCodeProperty } from '../lib/md' import { rehypeInlineCodeProperty } from '../lib/md'
import { Button } from 'react-bootstrap' import { Button } from 'react-bootstrap'
import { useRouter } from 'next/router'
export function SearchText ({ text }) { export function SearchText ({ text }) {
return ( return (
@ -33,9 +34,23 @@ export function SearchText ({ text }) {
// this is one of the slowest components to render // this is one of the slowest components to render
export default memo(function Text ({ nofollow, imgproxyUrls, children, tab, ...outerProps }) { export default memo(function Text ({ nofollow, imgproxyUrls, children, tab, ...outerProps }) {
const [overflowing, setOverflowing] = useState(false) const [overflowing, setOverflowing] = useState(false)
const router = useRouter()
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const containerRef = useRef(null) const containerRef = useRef(null)
useEffect(() => {
setShow(router.asPath.includes('#'))
const handleRouteChange = (url, { shallow }) => {
setShow(url.includes('#'))
}
router.events.on('hashChangeStart', handleRouteChange)
return () => {
router.events.off('hashChangeStart', handleRouteChange)
}
}, [router])
useEffect(() => { useEffect(() => {
const container = containerRef.current const container = containerRef.current
if (!container || overflowing) return if (!container || overflowing) return
@ -58,14 +73,13 @@ export default memo(function Text ({ nofollow, imgproxyUrls, children, tab, ...o
} }
}, [containerRef.current, setOverflowing]) }, [containerRef.current, setOverflowing])
// all the reactStringReplace calls are to facilitate search highlighting const slugger = new GithubSlugger()
const slugger = useRef(new GithubSlugger())
const Heading = useCallback(({ children, node, ...props }) => { const Heading = useCallback(({ children, node, ...props }) => {
const [copied, setCopied] = useState(false) const [copied, setCopied] = useState(false)
const { noFragments, topLevel } = outerProps const { noFragments, topLevel } = outerProps
const id = useMemo(() => const id = useMemo(() =>
noFragments ? undefined : slugger?.current?.slug(toString(node).replace(/[^\w\-\s]+/gi, '')), [node, noFragments, slugger]) noFragments ? undefined : slugger?.slug(toString(node).replace(/[^\w\-\s]+/gi, '')), [node, noFragments, slugger])
const h = useMemo(() => { const h = useMemo(() => {
if (topLevel) { if (topLevel) {
return node?.TagName return node?.TagName