diff options
Diffstat (limited to 'components/Sidebar/Link.tsx')
-rw-r--r-- | components/Sidebar/Link.tsx | 208 |
1 files changed, 168 insertions, 40 deletions
diff --git a/components/Sidebar/Link.tsx b/components/Sidebar/Link.tsx index ff812ef..9515b6d 100644 --- a/components/Sidebar/Link.tsx +++ b/components/Sidebar/Link.tsx @@ -1,6 +1,7 @@ import { Box, Button, + Link, Popover, PopoverArrow, PopoverBody, @@ -10,9 +11,9 @@ import { PopoverTrigger, Portal, Text, + useTheme, } from '@chakra-ui/react' -import React, { useState } from 'react' -import UniOrg from '../../util/uniorg' +import React, { ReactElement, useContext, useEffect, useMemo, useState } from 'react' import unified from 'unified' //import createStream from 'unified-stream' @@ -22,57 +23,184 @@ import uniorg2rehype from 'uniorg-rehype' import katex from 'rehype-katex' import 'katex/dist/katex.css' import rehype2react from 'rehype-react' +import { ThemeContext } from '../../util/themecontext' +import { NodeByCite, NodeById } from '../../pages' export interface LinkProps { - href: string + href: any children: any - testProp: string - getText: any previewNode?: any setPreviewNode: any + setSidebarHighlightedNode: any + nodeByCite: NodeByCite + nodeById: NodeById } -export const PreviewLink = (props: any) => { - const { href, children, nodeById, getText, previewNode, setPreviewNode } = props - const [previewText, setPreviewText] = useState('') - const [whatever, type, uri] = [...href.matchAll(/(.*?)\:(.*)/g)][0] +export interface NormalLinkProps { + setPreviewNode: any + nodeById: NodeById + nodeByCite: NodeByCite + href: any + children: any + setSidebarHighlightedNode: any +} - const processor = unified().use(uniorgParse).use(uniorg2rehype).use(katex).use(rehype2react, { - createElement: React.createElement, - // eslint-disable-next-line react/display-name - }) +import { hexToRGBA, getThemeColor } from '../../pages/index' +import noteStyle from './noteStyle' - type === 'id' && getText(uri, setPreviewText) +export const NormalLink = (props: NormalLinkProps) => { + const { setSidebarHighlightedNode, setPreviewNode, nodeById, href, children } = props + const { highlightColor } = useContext(ThemeContext) + const theme = useTheme() + const coolHighlightColor = getThemeColor(highlightColor, theme) + const [whatever, type, uri] = [...href.matchAll(/(.*?)\:(.*)/g)][0] return ( - <> - <Popover trigger="hover" isLazy position="relative" zIndex="tooltip"> - <PopoverTrigger> - <Button size="sm" onClick={() => setPreviewNode(nodeById[uri])} variant="link"> - {children} - </Button> - </PopoverTrigger> - <Portal zIndex={100000} position="relative"> - <PopoverContent boxShadow="xl" position="relative" zIndex="tooltip"> - <PopoverHeader pl={5} fontSize="sm" zIndex="tooltip" fontWeight="semibold"> - {children} - </PopoverHeader> - <PopoverArrow zIndex={10000} /> - <PopoverCloseButton zIndex={10000} /> - <PopoverBody - pb={5} - fontSize="xs" - px={5} + <Text + onMouseEnter={() => setSidebarHighlightedNode(nodeById[uri])} + onMouseLeave={() => setSidebarHighlightedNode({})} + tabIndex={0} + display="inline" + overflow="hidden" + fontWeight={500} + color={highlightColor} + textDecoration="underline" + onClick={() => setPreviewNode(nodeById[uri])} + _hover={{ textDecoration: 'none', cursor: 'pointer', bgColor: coolHighlightColor + '22' }} + _focus={{ outlineColor: highlightColor }} + > + {children} + </Text> + ) +} + +export const PreviewLink = (props: LinkProps) => { + const { + href, + children, + nodeById, + setSidebarHighlightedNode, + previewNode, + setPreviewNode, + nodeByCite, + } = props + // TODO figure out how to properly type this + // see https://github.com/rehypejs/rehype-react/issues/25 + const [orgText, setOrgText] = useState<any>() + const [whatever, type, uri] = [...href.matchAll(/(.*?)\:(.*)/g)][0] + + const getId = (type: string, uri: string) => { + if (type === 'id') { + return uri + } + + if (type.includes('cite')) { + const node = nodeByCite[uri] ?? false + if (!node) { + return '' + } + if (node?.properties.FILELESS) { + return '' + } + return node?.id + } + return '' + } + + const id = getId(type, uri) + + const processor = unified() + .use(uniorgParse) + .use(uniorg2rehype) + .use(katex) + .use(rehype2react, { + createElement: React.createElement, + components: { + // eslint-disable-next-line react/display-name + a: ({ children, href }) => ( + <NormalLink + setSidebarHighlightedNode={setSidebarHighlightedNode} + nodeById={nodeById} + nodeByCite={nodeByCite} + setPreviewNode={setPreviewNode} + {...{ children, href }} + /> + ), + }, + }) + + const file = encodeURIComponent(nodeById[id]?.file as string) + const getText = () => { + console.log(nodeById[id]?.title) + fetch(`api/notes/${file}`) + .then((res) => { + return res.text() + }) + .then((res) => { + if (res !== 'error') { + const text = processor.processSync(res).result + setOrgText(text) + return + } + }) + .catch((e) => { + console.log(e) + return 'Could not fetch the text for some reason, sorry!\n\n This can happen because you have an id with forward slashes (/) in it.' + }) + } + + useMemo(() => { + getText() + }, [id]) + if (id) { + return ( + <> + <Popover gutter={12} trigger="hover" placement="top-start"> + <PopoverTrigger> + <Box display="inline"> + <NormalLink + key={nodeById[id]?.title ?? id} + {...{ + setSidebarHighlightedNode, + setPreviewNode, + nodeById, + href, + children, + nodeByCite, + }} + /> + </Box> + </PopoverTrigger> + <Portal> + <PopoverContent + key={nodeById[id]?.title ?? id} + boxShadow="xl" position="relative" zIndex="tooltip" - maxHeight={300} - overflow="scroll" + onMouseEnter={() => setSidebarHighlightedNode(nodeById[id] ?? {})} + onMouseLeave={() => setSidebarHighlightedNode({})} > - {uri && <Box>{processor.processSync(previewText).result}</Box>} - </PopoverBody> - </PopoverContent> - </Portal> - </Popover> - </> + <PopoverArrow /> + <PopoverBody + pb={5} + fontSize="xs" + px={5} + position="relative" + zIndex="tooltip" + maxHeight={300} + overflow="scroll" + > + <Box sx={noteStyle}>{orgText}</Box> + </PopoverBody> + </PopoverContent> + </Portal> + </Popover> + </> + ) + } + return ( + <Text display="inline" color="base.700" cursor="not-allowed"> + {children} + </Text> ) } |