summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas F. K. Jorna <[email protected]>2021-10-09 22:20:34 +0200
committerThomas F. K. Jorna <[email protected]>2021-10-09 22:20:34 +0200
commit31d7477b376501bd80fe635b91412bc7f6ae7ea7 (patch)
treeb0fcc9b289cef86385805fe606b70d1ee14f1b25
parent9d1692fbcf322db2d95586b1ab6768ba9328e5df (diff)
feat(preview): node history
-rw-r--r--components/Sidebar/OrgImage.tsx9
-rw-r--r--components/Sidebar/Toolbar.tsx36
-rw-r--r--components/Sidebar/index.tsx27
-rw-r--r--components/Sidebar/noteStyle.ts15
-rw-r--r--package-lock.json73
-rw-r--r--package.json2
-rw-r--r--pages/index.tsx42
-rw-r--r--util/processOrg.tsx1
8 files changed, 181 insertions, 24 deletions
diff --git a/components/Sidebar/OrgImage.tsx b/components/Sidebar/OrgImage.tsx
index a87fc4c..f9f508a 100644
--- a/components/Sidebar/OrgImage.tsx
+++ b/components/Sidebar/OrgImage.tsx
@@ -30,6 +30,13 @@ export const OrgImage = (props: OrgImageProps) => {
}
return (
- <Image layout="responsive" loader={dumbLoader} src={fullPath} alt="" width="70%" height="70%" />
+ <Image
+ layout="responsive"
+ loader={dumbLoader}
+ src={fullPath}
+ alt=""
+ width="100%"
+ height="100%"
+ />
)
}
diff --git a/components/Sidebar/Toolbar.tsx b/components/Sidebar/Toolbar.tsx
index 458361f..f6f1e39 100644
--- a/components/Sidebar/Toolbar.tsx
+++ b/components/Sidebar/Toolbar.tsx
@@ -9,21 +9,51 @@ import {
BiRightIndent,
} from 'react-icons/bi'
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons'
+import { NodeObject } from 'force-graph'
export interface ToolbarProps {
setJustification: any
justification: number
setIndent: any
setFont: any
+ setPreviewNode: any
+ canUndo: any
+ canRedo: any
+ resetPreviewNode: any
+ previousPreviewNode: any
+ nextPreviewNode: any
}
export const Toolbar = (props: ToolbarProps) => {
- const { setJustification, setIndent, setFont, justification } = props
+ const {
+ setJustification,
+ setIndent,
+ setFont,
+ justification,
+ setPreviewNode,
+ canUndo,
+ canRedo,
+ resetPreviewNode,
+ previousPreviewNode,
+ nextPreviewNode,
+ } = props
return (
<Flex py={3} alignItems="center" justifyContent="space-between" pr={4}>
<Flex>
- <IconButton variant="ghost" icon={<ChevronLeftIcon />} aria-label="Previous node" />
- <IconButton variant="ghost" icon={<ChevronRightIcon />} aria-label="Previous node" />
+ <IconButton
+ variant="ghost"
+ icon={<ChevronLeftIcon />}
+ aria-label="Previous node"
+ disabled={!canUndo}
+ onClick={() => previousPreviewNode()}
+ />
+ <IconButton
+ variant="ghost"
+ icon={<ChevronRightIcon />}
+ aria-label="Next node"
+ disabled={!canRedo}
+ onClick={() => nextPreviewNode()}
+ />
</Flex>
<Flex>
<IconButton
diff --git a/components/Sidebar/index.tsx b/components/Sidebar/index.tsx
index 4d807ef..2e32f4f 100644
--- a/components/Sidebar/index.tsx
+++ b/components/Sidebar/index.tsx
@@ -1,4 +1,4 @@
-import React, { useContext, useEffect, useState } from 'react'
+import React, { useContext, useEffect, useRef, useState } from 'react'
import { Toolbar } from './Toolbar'
import { Note } from './Note'
@@ -23,6 +23,11 @@ export interface SidebarProps {
linksByNodeId: LinksByNodeId
nodeByCite: NodeByCite
setSidebarHighlightedNode: any
+ canUndo: any
+ canRedo: any
+ resetPreviewNode: any
+ previousPreviewNode: any
+ nextPreviewNode: any
}
const Sidebar = (props: SidebarProps) => {
@@ -36,6 +41,11 @@ const Sidebar = (props: SidebarProps) => {
linksByNodeId,
nodeByCite,
setSidebarHighlightedNode,
+ canUndo,
+ canRedo,
+ resetPreviewNode,
+ previousPreviewNode,
+ nextPreviewNode,
} = props
const { highlightColor } = useContext(ThemeContext)
@@ -97,7 +107,20 @@ const Sidebar = (props: SidebarProps) => {
onClick={onClose}
/>
</Flex>
- <Toolbar {...{ setJustification, setIndent, setFont, justification }} />
+ <Toolbar
+ {...{
+ setJustification,
+ setIndent,
+ setFont,
+ justification,
+ setPreviewNode,
+ canUndo,
+ canRedo,
+ resetPreviewNode,
+ previousPreviewNode,
+ nextPreviewNode,
+ }}
+ />
<Scrollbars
//autoHeight
//autoHeightMax={600}
diff --git a/components/Sidebar/noteStyle.ts b/components/Sidebar/noteStyle.ts
index adf715d..42ecaf6 100644
--- a/components/Sidebar/noteStyle.ts
+++ b/components/Sidebar/noteStyle.ts
@@ -44,7 +44,7 @@ export const noteStyle = {
fontWeight: 'bold',
marginTop: 0,
},
- '.todo': { fontFamily: 'monospace', color: 'red' },
+ '.TODO': { color: 'red.500' },
'.equationContainer': {
display: 'table',
textAlign: 'center',
@@ -71,7 +71,6 @@ export const noteStyle = {
},
textarea: { overflowX: 'auto' },
'.linenr': { fontSize: 'smaller' },
- '.code-highlighted': { backgroundColor: '#ffff00' },
'.org-info-js_info-navigation': { borderStyle: 'none' },
'#org-info-js_console-label': {
fontSize: '10px',
@@ -84,10 +83,10 @@ export const noteStyle = {
fontWeight: 'bold',
},
'.org-svg': { width: '90%' },
- '.done': { fontFamily: 'monospace', color: 'green' },
+ '.DONE': { color: 'green' },
'.priority': { fontFamily: 'monospace', color: 'orange' },
'.tag': {
- backgroundColor: '#eee',
+ backgroundColor: 'white',
fontFamily: 'monospace',
padding: '2px',
fontSize: '80%',
@@ -103,9 +102,9 @@ export const noteStyle = {
'#preamble p': { fontSize: '90%', margin: '.2em' },
'p.verse': { marginLeft: '3%' },
pre: {
- border: '1px solid #e6e6e6',
+ //border: '1px solid #e6e6e6',
borderRadius: '3px',
- backgroundColor: '#f2f2f2',
+ backgroundColor: 'white',
padding: '8pt',
fontFamily: 'monospace',
overflow: 'auto',
@@ -121,8 +120,8 @@ export const noteStyle = {
top: '-8px',
right: '12px',
padding: '3px',
- color: '#555',
- backgroundColor: '#f2f2f299',
+ //color: '#555',
+ backgroundColor: 'white',
},
'caption.t-above': { captionSide: 'top' },
'caption.t-bottom': { captionSide: 'bottom' },
diff --git a/package-lock.json b/package-lock.json
index fe40c45..1a6f57f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -30,6 +30,7 @@
"react-dom": "17.0.2",
"react-force-graph": "^1.41.7",
"react-icons": "^4.3.1",
+ "react-resizable": "^3.0.4",
"react-spring": "^9.2.4",
"reconnecting-websocket": "^4.4.0",
"rehype": "^11.0.0",
@@ -47,6 +48,7 @@
"uniorg-rehype": "^0.4.0",
"uniorg-slug": "^0.4.0",
"use-constant": "^1.1.0",
+ "use-undo": "^1.0.5",
"vfile": "^4.2.1",
"word-wrap": "^1.2.3"
},
@@ -3180,6 +3182,14 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
+ "node_modules/clsx": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
+ "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -7579,6 +7589,19 @@
"react": "17.0.2"
}
},
+ "node_modules/react-draggable": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.4.tgz",
+ "integrity": "sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA==",
+ "dependencies": {
+ "clsx": "^1.1.1",
+ "prop-types": "^15.6.0"
+ },
+ "peerDependencies": {
+ "react": ">= 16.3.0",
+ "react-dom": ">= 16.3.0"
+ }
+ },
"node_modules/react-fast-compare": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
@@ -7707,6 +7730,18 @@
}
}
},
+ "node_modules/react-resizable": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.4.tgz",
+ "integrity": "sha512-StnwmiESiamNzdRHbSSvA65b0ZQJ7eVQpPusrSmcpyGKzC0gojhtO62xxH6YOBmepk9dQTBi9yxidL3W4s3EBA==",
+ "dependencies": {
+ "prop-types": "15.x",
+ "react-draggable": "^4.0.3"
+ },
+ "peerDependencies": {
+ "react": ">= 16.3"
+ }
+ },
"node_modules/react-spring": {
"version": "9.2.4",
"resolved": "https://registry.npmjs.org/react-spring/-/react-spring-9.2.4.tgz",
@@ -9411,6 +9446,15 @@
"react": "^16.8.0 || ^17.0.0"
}
},
+ "node_modules/use-undo": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/use-undo/-/use-undo-1.0.5.tgz",
+ "integrity": "sha512-rLlwvcrioEqZ0t/M4hpgCsrCMgCpbodUXMRskK98g3ftdGFi7wr9DzxPY93vKHK17mMgxBY2ar7bgZ5cNFSiNQ==",
+ "peerDependencies": {
+ "react": "^16.8.6",
+ "react-dom": "^16.8.6"
+ }
+ },
"node_modules/util": {
"version": "0.12.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz",
@@ -12087,6 +12131,11 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
+ "clsx": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
+ "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
+ },
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -15560,6 +15609,15 @@
"scheduler": "^0.20.2"
}
},
+ "react-draggable": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.4.tgz",
+ "integrity": "sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA==",
+ "requires": {
+ "clsx": "^1.1.1",
+ "prop-types": "^15.6.0"
+ }
+ },
"react-fast-compare": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
@@ -15647,6 +15705,15 @@
"tslib": "^1.0.0"
}
},
+ "react-resizable": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.4.tgz",
+ "integrity": "sha512-StnwmiESiamNzdRHbSSvA65b0ZQJ7eVQpPusrSmcpyGKzC0gojhtO62xxH6YOBmepk9dQTBi9yxidL3W4s3EBA==",
+ "requires": {
+ "prop-types": "15.x",
+ "react-draggable": "^4.0.3"
+ }
+ },
"react-spring": {
"version": "9.2.4",
"resolved": "https://registry.npmjs.org/react-spring/-/react-spring-9.2.4.tgz",
@@ -16941,6 +17008,12 @@
"object-assign": "^4.1.1"
}
},
+ "use-undo": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/use-undo/-/use-undo-1.0.5.tgz",
+ "integrity": "sha512-rLlwvcrioEqZ0t/M4hpgCsrCMgCpbodUXMRskK98g3ftdGFi7wr9DzxPY93vKHK17mMgxBY2ar7bgZ5cNFSiNQ==",
+ "requires": {}
+ },
"util": {
"version": "0.12.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz",
diff --git a/package.json b/package.json
index 66aab66..a0b4777 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
"react-dom": "17.0.2",
"react-force-graph": "^1.41.7",
"react-icons": "^4.3.1",
+ "react-resizable": "^3.0.4",
"react-spring": "^9.2.4",
"reconnecting-websocket": "^4.4.0",
"rehype": "^11.0.0",
@@ -50,6 +51,7 @@
"uniorg-rehype": "^0.4.0",
"uniorg-slug": "^0.4.0",
"use-constant": "^1.1.0",
+ "use-undo": "^1.0.5",
"vfile": "^4.2.1",
"word-wrap": "^1.2.3"
},
diff --git a/pages/index.tsx b/pages/index.tsx
index 59fae1a..a1df7e7 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -46,6 +46,7 @@ import ReconnectingWebSocket from 'reconnecting-websocket'
import { deleteNodeInEmacs, openNodeInEmacs, createNodeInEmacs } from '../util/webSocketFunctions'
import { ChevronLeftIcon, HamburgerIcon } from '@chakra-ui/icons'
+import useUndo from 'use-undo'
// react-force-graph fails on import when server-rendered
// https://github.com/vasturiano/react-force-graph/issues/155
const ForceGraph2D = (
@@ -97,7 +98,22 @@ export function GraphPage() {
const [emacsNodeId, setEmacsNodeId] = useState<string | null>(null)
const [behavior, setBehavior] = usePersistantState('behavior', initialBehavior)
const [mouse, setMouse] = usePersistantState('mouse', initialMouse)
- const [previewNode, setPreviewNode] = useState<NodeObject>({})
+ const [
+ previewNodeState,
+ {
+ set: setPreviewNode,
+ reset: resetPreviewNode,
+ undo: previousPreviewNode,
+ redo: nextPreviewNode,
+ canUndo,
+ canRedo,
+ },
+ ] = useUndo<NodeObject>({})
+ const {
+ past: pastPreviewNodes,
+ present: previewNode,
+ future: futurePreviewNodes,
+ } = previewNodeState
const [sidebarHighlightedNode, setSidebarHighlightedNode] = useState<OrgRoamNode | null>(null)
const { isOpen, onOpen, onClose } = useDisclosure()
@@ -509,6 +525,10 @@ export function GraphPage() {
onClose,
previewNode,
setPreviewNode,
+ canUndo,
+ canRedo,
+ previousPreviewNode,
+ nextPreviewNode,
setSidebarHighlightedNode,
}}
nodeById={nodeByIdRef.current!}
@@ -843,14 +863,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
algorithm: algos[visuals.algorithmName],
},
)
- useEffect(() => {
- console.log('aaa')
- if (sidebarHighlightedNode?.id) {
- setHoverNode(sidebarHighlightedNode)
- } else {
- setHoverNode(null)
- }
- }, [sidebarHighlightedNode])
+
const highlightedNodes = useMemo(() => {
if (!centralHighlightedNode.current) {
return {}
@@ -862,7 +875,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
}
return Object.fromEntries(
[
- centralHighlightedNode.current.id! as string,
+ centralHighlightedNode.current?.id! as string,
...links.flatMap((link) => [link.source, link.target]),
].map((nodeId) => [nodeId, {}]),
)
@@ -870,6 +883,15 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
JSON.stringify(centralHighlightedNode.current),
JSON.stringify(filteredLinksByNodeIdRef.current),
])
+
+ useEffect(() => {
+ if (sidebarHighlightedNode?.id) {
+ setHoverNode(sidebarHighlightedNode)
+ } else {
+ setHoverNode(null)
+ }
+ }, [sidebarHighlightedNode])
+
const lastHoverNode = useRef<OrgRoamNode | null>(null)
useEffect(() => {
centralHighlightedNode.current = hoverNode
diff --git a/util/processOrg.tsx b/util/processOrg.tsx
index 3f32d30..1bab2cd 100644
--- a/util/processOrg.tsx
+++ b/util/processOrg.tsx
@@ -42,6 +42,7 @@ export const ProcessedOrg = (props: ProcessedOrgProps) => {
.use(attachments)
.use(uniorgSlug)
.use(uniorg2rehype)
+ .use(highlight)
.use(katex)
.use(rehype2react, {
createElement: React.createElement,