summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/config.ts1
-rw-r--r--org-roam-ui.el63
-rw-r--r--pages/index.tsx61
3 files changed, 73 insertions, 52 deletions
diff --git a/components/config.ts b/components/config.ts
index 4de0e2d..9c49068 100644
--- a/components/config.ts
+++ b/components/config.ts
@@ -93,4 +93,5 @@ export const initialVisuals = {
export const initialBehavior = {
follow: 'Zoom',
+ followLocalOrZoom: true,
}
diff --git a/org-roam-ui.el b/org-roam-ui.el
index fe8881c..877a4d6 100644
--- a/org-roam-ui.el
+++ b/org-roam-ui.el
@@ -108,28 +108,23 @@ This serves the web-build and API over HTTP."
35903
:host 'local
:on-open (lambda (ws) (progn (setq oru-ws
- ws) (org-roam-ui--send-graphdata) (org-roam-ui-sync-theme--advice) (message "Connection
- established with org-roam-ui")
- (add-hook 'post-command-hook
- #'org-roam-ui--update-current-node)
- ))
+ ws) (org-roam-ui--send-graphdata) (message "Connection established with org-roam-ui")
+ (add-hook 'post-command-hook #'org-roam-ui--update-current-node)))
:on-close (lambda (_websocket) (setq oru-ws
- nil) (message "Connection with org-roam-ui closed
- succesfully."))))
+ nil) (message "Connection with org-roam-ui closed succesfully."))))
(if (boundp 'counsel-load-theme)
-(advice-add 'counsel-load-theme :around #'org-roam-ui-sync-theme--advice)
+(advice-add 'counsel-load-theme :after #'org-roam-ui-sync-theme--advice)
(advice-add 'load-theme :around #'org-roam-ui-sync-theme--advice))
(add-hook 'post-command-hook #'org-roam-ui--update-current-node))
;(add-hook 'post-command-hook #'org-roam-ui-update))
(t
(progn
+ (websocket-server-close org-roam-ui-ws)
(remove-hook 'post-command-hook #'org-roam-ui-update)
(remove-hook 'post-command-hook #'org-roam-ui--update-current-node)
(if (boundp 'counsel-load-theme)
(advice-remove 'counsel-load-theme #'org-roam-ui-sync-theme--advice)
(advice-remove 'load-theme #'org-roam-ui-sync-theme--advice))
- (websocket-server-close org-roam-ui-ws)
- (delete-process org-roam-ui-ws)
(httpd-stop)))))
@@ -144,13 +139,13 @@ This serves the web-build and API over HTTP."
(websocket-send-text oru-ws (json-encode `((type . "graphdata") (data . ,response))))))
(defun org-roam-ui--update-current-node ()
- (when (and (boundp 'org-roam-ui-websocket) (websocket-openp org-roam-ui-websocket))
+ (when (websocket-openp oru-ws)
(let* ((node (org-roam-id-at-point)))
(unless (string-match-p (regexp-quote "Minibuf") (buffer-name (current-buffer)))
(unless (string= org-roam-ui--ws-current-node node)
(setq org-roam-ui--ws-current-node node)
- (websocket-send-text org-roam-ui-websocket (json-encode `((type . "command") (data . ((commandName . "follow") (id . ,node))))))))))
-)
+ (websocket-send-text oru-ws (json-encode `((type . "command") (data
+. ((commandName . "follow") (id . ,node)))))))))))
(defun org-roam-ui-show-node ()
"Open the current org-roam node in org-roam-ui."
@@ -257,19 +252,35 @@ This function is added to `post-command-hook'."
))
-;; (defservlet* theme text/stream ()
-;; (progn)
-;; (if org-roam-ui-sync-theme
-;; (if (boundp 'doom-themes--colors)
-;; (let*
-;; ((colors (butlast doom-themes--colors (- (length doom-themes--colors) 25))) ui-theme (list nil))
-;; (progn
-;; (dolist (color colors) (push (cons (car color) (car (cdr color))) ui-theme))
-;; ui-theme))
-;; (insert (format "data: %s\n\n" (json-encode (org-roam-ui-get-theme)))))
-;; (when org-roam-ui-custom-theme
-;; (insert (format "data %s\n\n" (json-encode org-roam-ui-custom-theme)))))
-;; (httpd-send-header t "text/event-stream" 200 :Access-Control-Allow-Origin "*"))
+;;;; commands
+(defun orui-zoom-to-node (&optional id speed padding)
+ "Move the view of the graph to the node at points, or optionally a node of your choosing.
+Optionally takes three arguments:
+The id of the node you want to travel to.
+The time in ms it takes to make the transition.
+The padding around the nodes in the viewport."
+ (interactive)
+ (if-let ((node (or id (org-roam-id-at-point))))
+ (websocket-send-text oru-ws (json-encode `((type . "command") (data .
+ ((commandName . "zoom") (id . ,node) (speed . ,speed) (padding . ,padding)))))))
+ (message "No node found."))
+
+(defun orui-toggle-following ()
+ "Set whether ORUI should follow your every move in emacs. Default yes."
+ (interactive)
+ (if (member #'org-roam-ui--update-current-node post-command-hook)
+ (progn
+ (remove-hook 'post-command-hook #'org-roam-ui--update-current-node)
+ (message "Org-Roam-UI will now leave you alone.")
+ (add-hook 'post-command-hook #'org-roam-ui--update-current-node)
+ (message "Org-Roam-UI will now follow you around."))
+ ))
+
+(defun orui-toggle-local-zoom ()
+ "Toggles whether org-roam-ui should go to the local view of a given node or zoom to it.
+Defaults to local."
+ (interactive)
+ (org-roam-ui--send-command "toggle" `(id . yes)))
(provide 'org-roam-ui)
;;; org-roam-ui.el ends here
diff --git a/pages/index.tsx b/pages/index.tsx
index 56e287a..ae1b4ef 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -132,8 +132,16 @@ export function GraphPage() {
const orgRoamGraphDataClone = JSON.parse(JSON.stringify(orgRoamGraphDataWithFileLinks))
setGraphData(orgRoamGraphDataClone)
}
+
const { setEmacsTheme } = useContext(ThemeContext)
+
+ const [threeDim, setThreeDim] = useState(false)
+
+ const graph2dRef = useRef<any>(null)
+ const graph3dRef = useRef<any>(null)
+
useEffect(() => {
+ const fg = threeDim ? graph3dRef.current : graph2dRef.current
const socket = new ReconnectingWebSocket('ws://localhost:35903')
socket.addEventListener('open', (event) => {
console.log('Connection with Emacs established')
@@ -156,14 +164,18 @@ export function GraphPage() {
setEmacsNodeId(message.data.id)
break
case 'zoom': {
+ console.log(message)
const links = linksByNodeIdRef.current[message.data.id!] ?? []
const nodes = Object.fromEntries(
[
- message.commandData.id! as string,
+ message.data.id! as string,
...links.flatMap((link) => [link.source, link.target]),
].map((nodeId) => [nodeId, {}]),
)
- /* zoomToFit(500, 200, (node: OrgRoamNode)=>nodes[node.id!]) */
+ fg.zoomToFit(2000, 200, (node: OrgRoamNode) => nodes[node.id!])
+ }
+ case 'toggle': {
+ /* setBehavior({ ...behavior, followLocalorZoom: !behavior.followLocalOrZoom }) */
}
default:
console.log('oopsie whoopsie')
@@ -180,8 +192,6 @@ export function GraphPage() {
//fetchGraphData()
}, [emacsNodeId])
- const [threeDim, setThreeDim] = useState(false)
-
if (!graphData) {
return null
}
@@ -212,6 +222,8 @@ export function GraphPage() {
filter,
visuals,
behavior,
+ graph2dRef,
+ graph3dRef,
}}
/>
</Box>
@@ -229,6 +241,8 @@ export interface GraphProps {
emacsNodeId: string | null
visuals: typeof initialVisuals
behavior: typeof initialBehavior
+ graph2dRef: any
+ graph3dRef: any
}
export const Graph = function (props: GraphProps) {
@@ -242,11 +256,10 @@ export const Graph = function (props: GraphProps) {
nodeById,
visuals,
behavior,
+ graph2dRef,
+ graph3dRef,
} = props
- const graph2dRef = useRef<any>(null)
- const graph3dRef = useRef<any>(null)
-
// react-force-graph does not track window size
// https://github.com/vasturiano/react-force-graph/issues/233
// does not work below a certain width
@@ -260,15 +273,11 @@ export const Graph = function (props: GraphProps) {
return
}
const fg = threeDim ? graph3dRef.current : graph2dRef.current
- switch (behavior.follow) {
- case 'Local':
- setScope({ nodeIds: [emacsNodeId] })
- break
- case 'Zoom':
- fg?.zoomToFit(1000, 200, (node: NodeObject) => getNeighborNodes(emacsNodeId)[node.id!])
- setHoverNode(nodeById[emacsNodeId] as NodeObject)
- break
- default:
+ if (behavior.followLocalOrZoom) {
+ setScope({ nodeIds: [emacsNodeId] })
+ } else {
+ fg?.zoomToFit(1000, 200, (node: NodeObject) => getNeighborNodes(emacsNodeId)[node.id!])
+ setHoverNode(nodeById[emacsNodeId] as NodeObject)
}
}, [emacsNodeId])
@@ -281,24 +290,25 @@ export const Graph = function (props: GraphProps) {
]),
)
}
- const centralHighlightedNode = hoverNode
+ const centralHighlightedNode = useRef<NodeObject | null>(null)
+ centralHighlightedNode.current = hoverNode
const highlightedNodes = useMemo(() => {
- if (!centralHighlightedNode) {
+ if (!centralHighlightedNode.current) {
return {}
}
- const links = linksByNodeId[centralHighlightedNode.id!]
+ const links = linksByNodeId[centralHighlightedNode.current.id!]
if (!links) {
return {}
}
return Object.fromEntries(
[
- centralHighlightedNode.id! as string,
+ centralHighlightedNode.current.id! as string,
...links.flatMap((link) => [link.source, link.target]),
].map((nodeId) => [nodeId, {}]),
)
- }, [centralHighlightedNode, linksByNodeId])
+ }, [centralHighlightedNode.current, linksByNodeId])
const filteredNodes = useMemo(() => {
return graphData.nodes.filter((node) => {
@@ -658,13 +668,13 @@ export const Graph = function (props: GraphProps) {
* } */
const sourceId = typeof link.source === 'object' ? link.source.id! : (link.source as string)
const targetId = typeof link.target === 'object' ? link.target.id! : (link.target as string)
- const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode)
+ const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode.current)
const linkWasHighlighted = isLinkRelatedToNode(link, lastHoverNode.current)
const needsHighlighting = linkIsHighlighted || linkWasHighlighted
return getLinkColor(sourceId as string, targetId as string, needsHighlighting)
},
linkWidth: (link) => {
- const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode)
+ const linkIsHighlighted = isLinkRelatedToNode(link, centralHighlightedNode.current)
const linkWasHighlighted = isLinkRelatedToNode(link, lastHoverNode.current)
return linkIsHighlighted || linkWasHighlighted
@@ -735,10 +745,9 @@ export const Graph = function (props: GraphProps) {
)
}
-function isLinkRelatedToNode(link: LinkObject, centralHighlightedNode: NodeObject | null) {
+function isLinkRelatedToNode(link: LinkObject, node: NodeObject | null) {
return (
- (link.source as NodeObject).id! === centralHighlightedNode?.id! ||
- (link.target as NodeObject).id! === centralHighlightedNode?.id!
+ (link.source as NodeObject).id! === node?.id! || (link.target as NodeObject).id! === node?.id!
)
}