summaryrefslogtreecommitdiff
path: root/pages/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'pages/index.tsx')
-rw-r--r--pages/index.tsx164
1 files changed, 46 insertions, 118 deletions
diff --git a/pages/index.tsx b/pages/index.tsx
index d3d6a44..b22e678 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -40,7 +40,6 @@ import { ThemeContext, ThemeContextProps } from '../util/themecontext'
import SpriteText from 'three-spritetext'
import ReconnectingWebSocket from 'reconnecting-websocket'
-import { sendJson } from 'next/dist/next-server/server/api-utils'
// react-force-graph fails on import when server-rendered
// https://github.com/vasturiano/react-force-graph/issues/155
@@ -73,16 +72,6 @@ export default function Home() {
return <GraphPage />
}
-function normalizeLinkEnds(link: OrgRoamLink | LinkObject): [string, string] {
- // we need to cover both because force-graph modifies the original data
- // but if we supply the original data on each render, the graph will re-render sporadically
- const sourceId =
- typeof link.source === 'object' ? (link.source.id! as string) : (link.source as string)
- const targetId =
- typeof link.target === 'object' ? (link.target.id! as string) : (link.target as string)
- return [sourceId, targetId]
-}
-
export function GraphPage() {
const [physics, setPhysics] = usePersistantState('physics', initialPhysics)
const [filter, setFilter] = usePersistantState('filter', initialFilter)
@@ -100,9 +89,7 @@ export function GraphPage() {
const currentGraphDataRef = useRef<GraphData>({ nodes: [], links: [] })
const updateGraphData = (orgRoamGraphData: OrgRoamGraphReponse) => {
- const currentGraphData = currentGraphDataRef.current
const oldNodeById = nodeByIdRef.current
- const oldLinksByNodeId = linksByNodeIdRef.current
tagsRef.current = orgRoamGraphData.tags ?? []
const nodesByFile = orgRoamGraphData.nodes.reduce<NodesByFile>((acc, node) => {
return {
@@ -174,36 +161,33 @@ export function GraphPage() {
}, {})
const nodes = [...orgRoamGraphData.nodes, ...nonExistantNodes]
- const orgRoamGraphDataWithFileLinksAndBadNdes = {
+ const orgRoamGraphDataProcessed = {
nodes,
links,
}
- if (!currentGraphData.nodes.length) {
+ const currentGraphData = currentGraphDataRef.current
+ if (currentGraphData.nodes.length === 0) {
// react-force-graph modifies the graph data implicitly,
// so we make sure there's no overlap between the objects we pass it and
// nodeByIdRef, linksByNodeIdRef
- const orgRoamGraphDataClone = JSON.parse(
- JSON.stringify(orgRoamGraphDataWithFileLinksAndBadNdes),
- )
- console.log(orgRoamGraphDataClone)
+ const orgRoamGraphDataClone = JSON.parse(JSON.stringify(orgRoamGraphDataProcessed))
currentGraphDataRef.current = orgRoamGraphDataClone
setGraphData(orgRoamGraphDataClone)
return
}
const newNodes = [
- ...currentGraphData.nodes.map((node: NodeObject) => {
+ ...currentGraphData.nodes.flatMap((node: NodeObject) => {
const newNode = nodeByIdRef.current[node?.id!] ?? false
if (!newNode) {
- return
+ return []
}
- return { ...node, ...newNode }
+ return [{ ...node, ...newNode }]
}),
...Object.keys(nodeByIdRef.current)
.filter((id) => !oldNodeById[id])
.map((id) => {
- console.log(id)
return nodeByIdRef.current[id] as NodeObject
}),
]
@@ -215,49 +199,7 @@ export function GraphPage() {
[id]: index,
}
}, {})
- console.log(newNodes)
- console.log(nodeIndex)
- /* const currentGraphIndexByLink = currentGraphData.links.reduce<{[key: string]: number}>((acc, link, index) => {
-* const [source, target] = normalizeLinkEnds(link)
-* const sourceTarget=source+target
-* return {
-* ...acc,
-* [sourceTarget]: index
-* }
-},{}) */
- /* const newLinks = [
- * ...currentGraphData!.links.filter((link) => {
- * const [source, target] = normalizeLinkEnds(link)
- * if (!nodeByIdRef.current[source] || !nodeByIdRef.current[target]) {
- * return false
- * }
- * if (
- * !linksByNodeIdRef.current[source]!.some(
- * (link) => link.target === target || link.source === target,
- * ) &&
- * !linksByNodeIdRef.current[target]!.some(
- * (link) => link.target === source || link.source === source,
- * )
- * ) {
- * return false
- * }
- * return true
- * }),
- * ...Object.keys(linksByNodeIdRef.current).flatMap((id) => {
- * if (!oldLinksByNodeId[id]!) {
- * return linksByNodeIdRef.current![id!]!
- * }
- * return (
- * linksByNodeIdRef.current![id]!.filter((link) => {
- * const [source, target] = normalizeLinkEnds(link)
- * return !oldLinksByNodeId[id]!.some(
- * (oldLink) => oldLink.source === source && oldLink.target === target,
- * )!
- * }) ?? []
- * )
- * }),
- * ]
- */
+
const newerLinks = links.map((link) => {
const [source, target] = normalizeLinkEnds(link)
return {
@@ -266,7 +208,7 @@ export function GraphPage() {
target: newNodes[nodeIndex![target]],
}
})
- const fg = graphRef.current
+
setGraphData({ nodes: newNodes as NodeObject[], links: newerLinks })
}
useEffect(() => {
@@ -284,7 +226,7 @@ export function GraphPage() {
const scopeRef = useRef<Scope>({ nodeIds: [] })
const behaviorRef = useRef(initialBehavior)
behaviorRef.current = behavior
- const WebSocketRef = useRef<any>(null)
+ const WebSocketRef = useRef<ReconnectingWebSocket | null>(null)
scopeRef.current = scope
const followBehavior = (
@@ -318,7 +260,6 @@ export function GraphPage() {
if (!sr.nodeIds.length) {
setScope({ nodeIds: [emacsNode] })
setTimeout(() => {
- /* fg.zoomToFit(speed, padding, (node: OrgRoamNode) => nodes[node.id!]) */
fg.centerAt(0, 0, speed)
}, 50)
return
@@ -326,13 +267,12 @@ export function GraphPage() {
if (bh.localSame !== 'add') {
setScope({ nodeIds: [emacsNode] })
setTimeout(() => {
- /* fg.zoomToFit(speed, padding, (node: OrgRoamNode) => nodes[node.id!]) */
fg.centerAt(0, 0, speed)
}, 50)
return
}
- // if the node is in the scopednodes, add it to scope instead of replacing it
+ // if the node is in the scoped nodes, add it to scope instead of replacing it
if (
!sr.nodeIds.includes(emacsNode) ||
!sr.nodeIds.some((scopeId: string) => {
@@ -341,7 +281,6 @@ export function GraphPage() {
) {
setScope({ nodeIds: [emacsNode] })
setTimeout(() => {
- /* fg.zoomToFit(speed, padding, (node: OrgRoamNode) => nodes[node.id!]) */
fg.centerAt(0, 0, speed)
}, 50)
return
@@ -355,11 +294,10 @@ export function GraphPage() {
useEffect(() => {
WebSocketRef.current = new ReconnectingWebSocket('ws://localhost:35903')
- WebSocketRef.current.addEventListener('open', (event: any) => {
+ WebSocketRef.current.addEventListener('open', () => {
console.log('Connection with Emacs established')
})
WebSocketRef.current.addEventListener('message', (event: any) => {
- const fg = graphRef.current
const bh = behaviorRef.current
const message = JSON.parse(event.data)
switch (message.type) {
@@ -525,7 +463,6 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
const handleClick = (click: string, node: OrgRoamNode) => {
switch (click) {
- //mouse.highlight:
case mouse.local: {
handleLocal(node, behavior.localSame)
break
@@ -538,15 +475,6 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
break
}
}
- const getNeighborNodes = (id: string) => {
- const links = linksByNodeId[id]! ?? []
- return Object.fromEntries(
- [id as string, ...links.flatMap((link) => [link.source, link.target])].map((nodeId) => [
- nodeId,
- {},
- ]),
- )
- }
const centralHighlightedNode = useRef<NodeObject | null>(null)
@@ -577,16 +505,10 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
}, [centralHighlightedNode.current, linksByNodeId])
const hiddenNodeIdsRef = useRef<NodeById>({})
- const filteredLinksByNodeId = useRef<LinksByNodeId>({})
const filteredGraphData = useMemo(() => {
hiddenNodeIdsRef.current = {}
const filteredNodes = graphData?.nodes
?.filter((nodeArg) => {
- //sometimes there will be some undefined nodes in the mix
- // should probably fix the actual issue, but this is a fix
- if (!nodeArg) {
- return
- }
const node = nodeArg as OrgRoamNode
if (
filter.tagsBlacklist.length &&
@@ -668,8 +590,6 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
const scopedNodeIds = scopedNodes.map((node) => node.id as string)
const scopedLinks = filteredGraphData.filteredLinks.filter((link) => {
- // we need to cover both because force-graph modifies the original data
- // but if we supply the original data on each render, the graph will re-render sporadically
const [sourceId, targetId] = normalizeLinkEnds(link)
return (
scopedNodeIds.includes(sourceId as string) && scopedNodeIds.includes(targetId as string)
@@ -716,7 +636,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
graphRef.current?.d3ReheatSimulation()
}, [physics])
- //shitty handler to check for doubleClicks
+ // shitty handler to check for doubleClicks
const lastNodeClickRef = useRef(0)
const [opacity, setOpacity] = useState<number>(1)
@@ -798,9 +718,6 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
}
const getLinkColor = (sourceId: string, targetId: string, needsHighlighting: boolean) => {
- // I'm so sorry
- // if we are matching the node color and don't have a highlight color
- // or we don't have our own scheme and we're not being highlighted
if (!visuals.linkHighlight && !visuals.linkColorScheme && !needsHighlighting) {
const nodeColor = getLinkNodeColor(sourceId, targetId)
return getThemeColor(nodeColor)
@@ -834,7 +751,6 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
}
const getNodeColor = (node: OrgRoamNode) => {
- const isHighlightingHappening = !!highlightedNodes.length
const needsHighlighting = highlightedNodes[node.id!] || previouslyHighlightedNodes[node.id!]
// if we are matching the node color and don't have a highlight color
// or we don't have our own scheme and we're not being highlighted
@@ -870,17 +786,6 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
return highlightColors[getNodeColorById(node.id as string)][visuals.nodeHighlight](opacity)
}
- const hexToRGBA = (hex: string, opacity: number) =>
- 'rgba(' +
- (hex = hex.replace('#', ''))
- .match(new RegExp('(.{' + hex.length / 3 + '})', 'g'))!
- .map(function (l) {
- return parseInt(hex.length % 2 ? l + l : l, 16)
- })
- .concat(isFinite(opacity) ? opacity : 1)
- .join(',') +
- ')'
-
const labelTextColor = useMemo(
() => getThemeColor(visuals.labelTextColor),
[visuals.labelTextColor, emacsTheme],
@@ -906,13 +811,13 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
}
const [dragging, setDragging] = useState(false)
- const { isOpen, onOpen, onClose } = useDisclosure()
+ const contextMenu = useDisclosure()
const [rightClickedNode, setRightClickedNode] = useState<OrgRoamNode | null>(null)
const [contextPos, setContextPos] = useState([0, 0])
const openContextMenu = (node: OrgRoamNode, event: any) => {
setContextPos([event.pageX, event.pageY])
setRightClickedNode(node)
- onOpen()
+ contextMenu.onOpen()
}
const graphCommonProps: ComponentPropsWithoutRef<typeof TForceGraph2D> = {
@@ -954,7 +859,6 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
nodeTitle.length > visuals.labelLength
? nodeTitle.substring(0, visuals.labelLength) + '...'
: nodeTitle
- // const label = 'label'
const fontSize = visuals.labelFontSize / (0.75 * Math.min(Math.max(0.5, globalScale), 3))
const textWidth = ctx.measureText(label).width
const bckgDimensions = [textWidth * 1.1, fontSize].map((n) => n + fontSize * 0.5) as [
@@ -1003,7 +907,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
linkDirectionalArrowLength: visuals.arrows ? visuals.arrowsLength : undefined,
linkDirectionalArrowRelPos: visuals.arrowsPos,
linkDirectionalArrowColor: visuals.arrowsColor
- ? (link) => getThemeColor(visuals.arrowsColor)
+ ? () => getThemeColor(visuals.arrowsColor)
: undefined,
linkColor: (link) => {
const sourceId = typeof link.source === 'object' ? link.source.id! : (link.source as string)
@@ -1053,7 +957,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
onNodeClick: (nodeArg: NodeObject, event: any) => {
const node = nodeArg as OrgRoamNode
- onClose()
+ contextMenu.onClose()
const isDoubleClick = event.timeStamp - lastNodeClickRef.current < 400
lastNodeClickRef.current = event.timeStamp
if (isDoubleClick) {
@@ -1062,7 +966,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
return handleClick('click', node)
},
onBackgroundClick: () => {
- onClose()
+ contextMenu.onClose()
setHoverNode(null)
if (scope.nodeIds.length === 0) {
return
@@ -1090,11 +994,11 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
//handleClick('right', node)
},
onNodeDrag: (node) => {
- onClose()
+ contextMenu.onClose()
setHoverNode(node)
setDragging(true)
},
- onNodeDragEnd: (node) => {
+ onNodeDragEnd: () => {
setHoverNode(null)
setDragging(false)
},
@@ -1102,7 +1006,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
return (
<Box overflow="hidden">
- {isOpen && (
+ {contextMenu.isOpen && (
<ContextMenu
scope={scope}
node={rightClickedNode!}
@@ -1110,7 +1014,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
background={false}
coordinates={contextPos}
handleLocal={handleLocal}
- menuClose={onClose}
+ menuClose={contextMenu.onClose.bind(contextMenu)}
openNodeInEmacs={openNodeInEmacs}
deleteNodeInEmacs={deleteNodeInEmacs}
createNodeInEmacs={createNodeInEmacs}
@@ -1170,3 +1074,27 @@ function isLinkRelatedToNode(link: LinkObject, node: NodeObject | null) {
function numberWithinRange(num: number, min: number, max: number) {
return Math.min(Math.max(num, min), max)
}
+
+function normalizeLinkEnds(link: OrgRoamLink | LinkObject): [string, string] {
+ // we need to cover both because force-graph modifies the original data
+ // but if we supply the original data on each render, the graph will re-render sporadically
+ const sourceId =
+ typeof link.source === 'object' ? (link.source.id! as string) : (link.source as string)
+ const targetId =
+ typeof link.target === 'object' ? (link.target.id! as string) : (link.target as string)
+ return [sourceId, targetId]
+}
+
+function hexToRGBA(hex: string, opacity: number) {
+ return (
+ 'rgba(' +
+ (hex = hex.replace('#', ''))
+ .match(new RegExp('(.{' + hex.length / 3 + '})', 'g'))!
+ .map(function (l) {
+ return parseInt(hex.length % 2 ? l + l : l, 16)
+ })
+ .concat(isFinite(opacity) ? opacity : 1)
+ .join(',') +
+ ')'
+ )
+}