summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/config.ts7
-rw-r--r--components/tweaks.tsx53
-rw-r--r--org-roam-ui.el14
-rw-r--r--pages/index.tsx41
4 files changed, 101 insertions, 14 deletions
diff --git a/components/config.ts b/components/config.ts
index 6c73921..db450d7 100644
--- a/components/config.ts
+++ b/components/config.ts
@@ -34,6 +34,7 @@ export const initialPhysics = {
export const initialFilter = {
orphans: false,
parents: true,
+ fileless_cites: false,
tagsBlacklist: [],
tagsWhitelist: [],
nodes: [],
@@ -88,6 +89,12 @@ export const initialVisuals = {
citeLinkColor: 'gray.600',
citeLinkHighlightColor: '',
citeNodeColor: 'black',
+ refDashes: true,
+ refDashLength: 35,
+ refGapLength: 15,
+ refLinkColor: 'gray.400',
+ refLinkHighlightColor: ''.
+ refNodeColor: 'black',
}
export interface TagColors {
diff --git a/components/tweaks.tsx b/components/tweaks.tsx
index 39a8a35..8456766 100644
--- a/components/tweaks.tsx
+++ b/components/tweaks.tsx
@@ -233,6 +233,15 @@ export const Tweaks = (props: TweakProps) => {
isChecked={filter.parents}
></Switch>
</Flex>
+ <Flex justifyContent="space-between">
+ <Text>Citations without note files</Text>
+ <Switch
+ onChange={() => {
+ setFilter({ ...filter, fileless_cites: !filter.fileless_cites })
+ }}
+ isChecked={filter.fileless_cites}
+ ></Switch>
+ </Flex>
</VStack>
<Accordion padding={0} allowToggle allowMultiple paddingLeft={3}>
<AccordionItem>
@@ -772,12 +781,54 @@ export const Tweaks = (props: TweakProps) => {
/>
<ColorMenu
colorList={colorList}
- label="Citation link highlight"
+ label="Reference link highlight"
visuals={visuals}
setVisuals={setVisuals}
value={'citeLinkHighlightColor'}
visValue={visuals.citeLinkHighlightColor}
/>
+ <EnableSection
+ label="Dash ref links"
+ infoText="Add dashes to citation links, whose target has a note, made with org-roam-bibtex"
+ value={visuals.refDashes}
+ onChange={() => setVisuals({ ...visuals, refDashes: !visuals.refDashes })}
+ >
+ <SliderWithInfo
+ label="Dash length"
+ value={visuals.refDashLength / 10}
+ onChange={(value) =>
+ setVisuals({ ...visuals, refDashLength: value * 10 })
+ }
+ />
+ <SliderWithInfo
+ label="Gap length"
+ value={visuals.refGapLength / 5}
+ onChange={(value) => setVisuals({ ...visuals, refGapLength: value * 5 })}
+ />
+ </EnableSection>
+ <ColorMenu
+ colorList={colorList}
+ label="Reference node color"
+ visuals={visuals}
+ setVisuals={setVisuals}
+ value={'refNodeColor'}
+ visValue={visuals.refNodeColor}
+ />
+ <ColorMenu
+ colorList={colorList}
+ label="Reference link color"
+ visuals={visuals}
+ setVisuals={setVisuals}
+ value={'refLinkColor'}
+ visValue={visuals.refLinkColor}
+ <ColorMenu
+ colorList={colorList}
+ label="Reference link highlight"
+ visuals={visuals}
+ setVisuals={setVisuals}
+ value={'refLinkHighlightColor'}
+ visValue={visuals.refLinkHighlightColor}
+ />
<Box>
<Flex alignItems="center" justifyContent="space-between">
<Text>Labels</Text>
diff --git a/org-roam-ui.el b/org-roam-ui.el
index 5ac7eac..368d788 100644
--- a/org-roam-ui.el
+++ b/org-roam-ui.el
@@ -157,6 +157,9 @@ This serves the web-build and API over HTTP."
(org-roam-ui--send-graphdata))
)
+(defun org-roam-ui--create-fake-node (ref)
+ (list ref ref ref 0 `(("ROAM_REFS" . ,(format "cite:%s" ref)) ("FILELESS" . t)) 'nil))
+
(defun org-roam-ui--send-graphdata ()
"Get roam data, make JSON, send through websocket to org-roam-ui."
(let* ((nodes-columns [id file title level properties ,(funcall group-concat tag (emacsql-escape-raw \, ))])
@@ -174,14 +177,17 @@ This serves the web-build and API over HTTP."
:from links
:left :outer :join refs :on (= links:dest refs:ref)
:where (or (= links:type "id") (= links:type "cite"))]))
- ;; Convert any cite links that have nodes with associated refs to a
- ;; standard id link while removing the 'nil `refs:node-id' from all
- ;; other links
+ ;; Convert any cite links that have nodes with associated refs to an
+ ;; id based link of type `ref' while removing the 'nil `refs:node-id'
+ ;; from all other links
(links-db-rows (seq-map (lambda (l)
(pcase-let ((`(,source ,dest ,type ,node-id) l))
(if node-id
- (list source node-id "cite")
+ (list source node-id "ref")
(list source dest type)))) links-db-rows))
+ (links-with-empty-refs (seq-filter (lambda (l) (equal (nth 2 l) "cite")) links-db-rows))
+ (fake-nodes (delete-dups (seq-map (lambda (l) (org-roam-ui--create-fake-node (nth 1 l))) links-with-empty-refs)))
+ (nodes-db-rows (append nodes-db-rows fake-nodes))
(response `((nodes . ,(mapcar (apply-partially #'org-roam-ui-sql-to-alist (append nodes-names nil)) nodes-db-rows))
(links . ,(mapcar (apply-partially #'org-roam-ui-sql-to-alist '(source target type)) links-db-rows))
(tags . ,(seq-mapcat #'seq-reverse (org-roam-db-query [:select :distinct tag :from tags]))))))
diff --git a/pages/index.tsx b/pages/index.tsx
index 02be883..c829fef 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -70,6 +70,14 @@ 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)
@@ -429,6 +437,10 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
hiddenNodeIdsRef.current = { ...hiddenNodeIdsRef.current, [node.id]: node }
return false
}
+ if (filter.fileless_cites && node.properties.FILELESS) {
+ hiddenNodeIdsRef.current = { ...hiddenNodeIdsRef.current, [node.id]: node }
+ return false
+ }
return true
})
.filter((nodeArg) => {
@@ -456,9 +468,8 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
const filteredNodeIds = filteredNodes.map((node) => node.id as string)
const filteredLinks = graphData.links.filter((link) => {
- if (filter.tagsBlacklist.length || filter.tagsWhitelist.length) {
- 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 [sourceId, targetId] = normalizeLinkEnds(link)
+ if (filter.tagsBlacklist.length || filter.tagsWhitelist.length){
return (
filteredNodeIds.includes(sourceId as string) &&
filteredNodeIds.includes(targetId as string)
@@ -486,8 +497,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
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 = 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 [sourceId, targetId] = normalizeLinkEnds(link)
return (
scopedNodeIds.includes(sourceId as string) && scopedNodeIds.includes(targetId as string)
)
@@ -674,9 +684,12 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
const tagColor = tagColors[node.tags.filter((tag) => tagColors[tag])[0]]
return getThemeColor(tagColor)
}
- if (visuals.citeNodeColor && node.properties.ROAM_REFS) {
+ if (visuals.citeNodeColor && node.properties.ROAM_REFS && node.properties.FILELESS) {
return getThemeColor(visuals.citeNodeColor)
}
+ if (visuals.refNodeColor && node.properties.ROAM_REFS) {
+ return getThemeColor(visuals.refNodeColor)
+ }
if (!needsHighlighting) {
return getThemeColor(getNodeColorById(node.id as string))
}
@@ -806,6 +819,13 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
const linkWasHighlighted = isLinkRelatedToNode(link, lastHoverNode.current)
const needsHighlighting = linkIsHighlighted || linkWasHighlighted
const roamLink = link as OrgRoamLink
+ if (visuals.refLinkColor && roamLink.type === 'ref') {
+ return needsHighlighting && (visuals.refLinkHighlightColor || visuals.linkHighlight)
+ ? highlightColors[visuals.refLinkColor][
+ visuals.refLinkHighlightColor || visuals.linkHighlight
+ ](opacity)
+ : getThemeColor(visuals.refLinkColor)
+ }
if (visuals.citeLinkColor && roamLink.type === 'cite') {
return needsHighlighting && (visuals.citeLinkHighlightColor || visuals.linkHighlight)
? highlightColors[visuals.citeLinkColor][
@@ -897,10 +917,13 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) {
{...graphCommonProps}
linkLineDash={(link) => {
const linkArg = link as OrgRoamLink
- if (!visuals.citeDashes || linkArg.type !== 'cite') {
- return null
+ if (visuals.citeDashes && linkArg.type === 'cite') {
+ return [visuals.citeDashLength, visuals.citeGapLength]
+ }
+ if (visuals.refDashes && linkArg.type == 'ref') {
+ return [visuals.refDashLength, visuals.refGapLength]
}
- return [visuals.citeDashLength, visuals.citeGapLength]
+ return null
}}
/>
)}