From b92b006e2c22302e708672de97b9a05081ecca1c Mon Sep 17 00:00:00 2001 From: "Thomas F. K. Jorna" Date: Fri, 6 Aug 2021 02:31:59 +0200 Subject: features!: context menu, better ui, and smoother updates --- components/config.ts | 46 +- components/contextmenu.tsx | 6 +- components/tweaks.tsx | 2004 ++++++++++++++++++++++---------------------- 3 files changed, 1026 insertions(+), 1030 deletions(-) (limited to 'components') diff --git a/components/config.ts b/components/config.ts index 2487168..ef48973 100644 --- a/components/config.ts +++ b/components/config.ts @@ -21,9 +21,9 @@ export const initialPhysics = { collisionStrength: 20, centering: true, centeringStrength: 0.05, - linkStrength: 0.1, + linkStrength: 0.3, linkIts: 1, - alphaDecay: 0.02, + alphaDecay: 0.1, alphaTarget: 0, alphaMin: 0, velocityDecay: 0.25, @@ -34,9 +34,10 @@ export const initialPhysics = { export const initialFilter = { orphans: false, parents: true, - fileless_cites: false, + filelessCites: false, tagsBlacklist: [], tagsWhitelist: [], + bad: true, nodes: [], links: [], date: [], @@ -60,10 +61,11 @@ export const initialVisuals = { highlight: true, highlightNodeSize: 2, highlightLinkSize: 2, + highlightFade: 0.8, highlightAnim: true, - animationSpeed: 700, + animationSpeed: 420, algorithmOptions: options, - algorithmName: 'BackOut', + algorithmName: 'SinusoidalOut', linkColorScheme: 'gray.500', nodeColorScheme: [ 'red.500', @@ -76,26 +78,26 @@ export const initialVisuals = { 'purple.500', 'orange.500', ], - nodeHighlight: '', + nodeHighlight: 'purple.500', linkHighlight: 'purple.500', backgroundColor: 'white', emacsNodeColor: 'gray.800', - labelTextColor: 'black', - labelBackgroundColor: 'white', + labelTextColor: 'gray.900', + labelBackgroundColor: '', labelBackgroundOpacity: 0.7, citeDashes: true, citeDashLength: 35, citeGapLength: 15, - citeLinkColor: 'gray.600', + citeLinkColor: 'gray.700', citeLinkHighlightColor: '', citeNodeColor: 'black', refDashes: true, refDashLength: 35, refGapLength: 15, - refLinkColor: 'gray.400', + refLinkColor: 'gray.700', refLinkHighlightColor: '', refNodeColor: 'black', - nodeSizeLinks: 2, + nodeSizeLinks: 0.5, } export interface TagColors { @@ -114,3 +116,25 @@ export const initialMouse = { local: 'click', follow: 'double', } + +export const colorList = [ + 'red.500', + 'orange.500', + 'yellow.500', + 'green.500', + 'cyan.500', + 'blue.500', + 'pink.500', + 'purple.500', + 'white', + 'gray.100', + 'gray.200', + 'gray.300', + 'gray.400', + 'gray.500', + 'gray.600', + 'gray.700', + 'gray.800', + 'gray.900', + 'black', +] diff --git a/components/contextmenu.tsx b/components/contextmenu.tsx index 228a780..755bd9d 100644 --- a/components/contextmenu.tsx +++ b/components/contextmenu.tsx @@ -54,6 +54,7 @@ export default interface ContextMenuProps { menuClose: () => void scope: { nodeIds: string[] } deleteNodeInEmacs: (node: OrgRoamNode) => void + createNodeInEmacs: (node: OrgRoamNode) => void } export const ContextMenu = (props: ContextMenuProps) => { @@ -67,6 +68,7 @@ export const ContextMenu = (props: ContextMenuProps) => { scope, openNodeInEmacs, deleteNodeInEmacs, + createNodeInEmacs, } = props const { isOpen, onOpen, onClose } = useDisclosure() const copyRef = useRef() @@ -104,7 +106,9 @@ export const ContextMenu = (props: ContextMenuProps) => { Open in Emacs ) : ( - }>Create node + } onClick={() => createNodeInEmacs(node)}> + Create node + )} {node?.properties.ROAM_REFS && ( }>Open in Zotero diff --git a/components/tweaks.tsx b/components/tweaks.tsx index bed075f..c62cbd0 100644 --- a/components/tweaks.tsx +++ b/components/tweaks.tsx @@ -45,7 +45,7 @@ import { } from '@chakra-ui/react' import { CUIAutoComplete } from 'chakra-ui-autocomplete' -import React, { useState, useContext } from 'react' +import React, { useState, useContext, useEffect } from 'react' import Scrollbars from 'react-custom-scrollbars-2' import { initialPhysics, @@ -54,6 +54,7 @@ import { initialMouse, initialBehavior, TagColors, + colorList, } from './config' import { ThemeContext } from '../util/themecontext' @@ -96,381 +97,434 @@ export const Tweaks = (props: TweakProps) => { } = props const [showTweaks, setShowTweaks] = useState(true) const { highlightColor, setHighlightColor } = useContext(ThemeContext) - const colorList = [ - 'red.500', - 'orange.500', - 'yellow.500', - 'green.500', - 'cyan.500', - 'blue.500', - 'pink.500', - 'purple.500', - 'white', - 'gray.100', - 'gray.200', - 'gray.300', - 'gray.400', - 'gray.500', - 'gray.600', - 'gray.700', - 'gray.800', - 'gray.900', - 'black', - ] - return ( - <> - - + return !showTweaks ? ( + + } + onClick={() => setShowTweaks(true)} + /> + + ) : ( + + + + + + + + } + onClick={() => { + setVisuals(initialVisuals) + setFilter(initialFilter) + setMouse(initialMouse) + setPhysics(initialPhysics) + setBehavior(initialBehavior) + }} + variant="none" + size="sm" + /> + } - onClick={() => setShowTweaks(true)} + size="sm" + icon={} + aria-label="Close Tweak Panel" + variant="ghost" + onClick={() => setShowTweaks(false)} /> - - - + + ( - - - - - - } - onClick={() => { - setVisuals(initialVisuals) - setFilter(initialFilter) - setMouse(initialMouse) - setPhysics(initialPhysics) - setBehavior(initialBehavior) - }} - variant="none" - size="sm" - /> - - } - aria-label="Close Tweak Panel" - variant="ghost" - onClick={() => setShowTweaks(false)} - /> - - - ( - - )} - > - - - - - Filter - - - } - align="stretch" - paddingLeft={7} - color="gray.800" - > - - Orphans - { - setFilter({ ...filter, orphans: !filter.orphans }) - }} - isChecked={filter.orphans} - > - - - Link nodes with parent file - { - setFilter({ ...filter, parents: !filter.parents }) - }} - isChecked={filter.parents} - > - - - Citations without note files - { - setFilter({ ...filter, fileless_cites: !filter.fileless_cites }) - }} - isChecked={filter.fileless_cites} - > - - - - - - Tag filters - - - - - - - - - - Tag Colors - - - - - - - - - - - - - - Physics - - {/* + )} + > + + + + + Filter + + + } + align="stretch" + paddingLeft={7} + color="gray.800" + > + + Orphans + { + setFilter({ ...filter, orphans: !filter.orphans }) + }} + isChecked={filter.orphans} + > + + + Link nodes with parent file + { + setFilter({ ...filter, parents: !filter.parents }) + }} + isChecked={filter.parents} + > + + + Citations without note files + { + setFilter({ ...filter, filelessCites: !filter.filelessCites }) + }} + isChecked={filter.filelessCites} + > + + + Non-existant nodes + { + setTagColors({ ...tagColors, bad: 'white' }) + setFilter({ ...filter, bad: !filter.bad }) + }} + isChecked={filter.bad} + > + + + + + + Tag filters + + + + + + + + + + Tag Colors + + + + + + + + + + + + + + Physics + + {/* setPhysics({ ...physics, enabled: !physics.enabled })} isChecked={physics.enabled} /> */} - - - } - align="stretch" - paddingLeft={7} - color="gray.800" - > - setPhysics({ ...physics, gravityOn: !physics.gravityOn })} - > - setPhysics({ ...physics, gravity: v / 10 })} - /> - - setPhysics({ ...physics, charge: -100 * value })} - label="Repulsive Force" - /> - setPhysics({ ...physics, collision: !physics.collision })} - > - - setPhysics({ ...physics, collisionStrength: value * 5 }) - } - label="Collision Radius" - infoText="Easy with this one, high values can lead to a real jiggly mess" - /> - - setPhysics({ ...physics, linkStrength: value / 5 })} - label="Link Force" - /> - setPhysics({ ...physics, linkIts: value })} - min={0} - max={6} - step={1} - infoText="How many links down the line the physics of a single node affects (Slow)" - /> - setPhysics({ ...physics, velocityDecay: value / 10 })} - /> - - - - - - Advanced - - - - } - align="stretch" - paddingLeft={3} - color="gray.800" - > - - setPhysics({ ...physics, alphaDecay: value / 50 }) - } - /> - - setPhysics({ ...physics, centering: !physics.centering }) - } - infoText="Keeps the nodes in the center of the viewport. If disabled you can drag the nodes anywhere you want." - > - setPhysics({ ...physics, centeringStrength: v })} + + + } + align="stretch" + paddingLeft={7} + color="gray.800" + > + setPhysics({ ...physics, gravityOn: !physics.gravityOn })} + > + setPhysics({ ...physics, gravity: v / 10 })} + /> + + setPhysics({ ...physics, charge: -100 * value })} + label="Repulsive Force" + /> + setPhysics({ ...physics, collision: !physics.collision })} + > + setPhysics({ ...physics, collisionStrength: value * 5 })} + label="Collision Radius" + infoText="Easy with this one, high values can lead to a real jiggly mess" + /> + + setPhysics({ ...physics, linkStrength: value / 5 })} + label="Link Force" + /> + setPhysics({ ...physics, linkIts: value })} + min={0} + max={6} + step={1} + infoText="How many links down the line the physics of a single node affects (Slow)" + /> + setPhysics({ ...physics, velocityDecay: value / 10 })} + /> + + + + + + Advanced + + + + } + align="stretch" + paddingLeft={3} + color="gray.800" + > + setPhysics({ ...physics, alphaDecay: value / 50 })} + /> + setPhysics({ ...physics, centering: !physics.centering })} + infoText="Keeps the nodes in the center of the viewport. If disabled you can drag the nodes anywhere you want." + > + setPhysics({ ...physics, centeringStrength: v })} + /> + + + + + + + + + + + + Visual + + + + + + + + Colors + + + + + } + align="stretch" + color="gray.800" + > + + + Nodes + + } + variant="ghost" + onClick={() => { + const arr = visuals.nodeColorScheme ?? [] + setVisuals({ + ...visuals, + //shuffle that guy + //definitely thought of this myself + nodeColorScheme: arr + .map((x: any) => [Math.random(), x]) + .sort(([a], [b]) => a - b) + .map(([_, x]) => x), + }) + }} /> - - - - - - - - - - - - Visual - - - - - - - - Colors - - - - - } - align="stretch" - color="gray.800" - > - - - Nodes - - } - variant="ghost" - onClick={() => { - const arr = visuals.nodeColorScheme ?? [] - setVisuals({ - ...visuals, - //shuffle that guy - //definitely thought of this myself - nodeColorScheme: arr - .map((x: any) => [Math.random(), x]) - .sort(([a], [b]) => a - b) - .map(([_, x]) => x), - }) - }} - /> - - - } - size="sm" - variant="ghost" - onClick={() => { - const arr = visuals.nodeColorScheme ?? [] - setVisuals({ - ...visuals, - nodeColorScheme: [...arr.slice(1, arr.length), arr[0]], - }) + + + } + size="sm" + variant="ghost" + onClick={() => { + const arr = visuals.nodeColorScheme ?? [] + setVisuals({ + ...visuals, + nodeColorScheme: [...arr.slice(1, arr.length), arr[0]], + }) + }} + /> + + + } + > + + {visuals.nodeColorScheme.map((color) => ( + + ))} + + + + {' '} + + { + if (!colors.length) { + return + } + setVisuals({ ...visuals, nodeColorScheme: colors }) }} - /> - - - } > + {colorList.map((color) => ( + c === color)} + value={color} + isDisabled={ + visuals.nodeColorScheme.length === 1 && + visuals.nodeColorScheme[0] === color + } + > + + + + + ))} + + + + + + + Links + + } + > + + {visuals.linkColorScheme ? ( + + ) : ( { > ))} - - - {' '} - - { - if (!colors.length) { - return - } - setVisuals({ ...visuals, nodeColorScheme: colors }) - }} - > - {colorList.map((color) => ( - c === color, - )} - value={color} - isDisabled={ - visuals.nodeColorScheme.length === 1 && - visuals.nodeColorScheme[0] === color - } - > - - - - - ))} - - - - - - - Links - - } + )} + + + + {' '} + + setVisuals({ ...visuals, linkColorScheme: '' })} + justifyContent="space-between" + alignItems="center" + display="flex" > - - {visuals.linkColorScheme ? ( + + {visuals.nodeColorScheme.map((color) => ( - ) : ( - - {visuals.nodeColorScheme.map((color) => ( - - ))} - - )} - - - - {' '} - - - setVisuals({ ...visuals, linkColorScheme: '' }) - } - justifyContent="space-between" - alignItems="center" - display="flex" - > - - {visuals.nodeColorScheme.map((color) => ( - - ))} - - - {colorList.map((color) => ( - - setVisuals({ - ...visuals, - linkColorScheme: color, - }) - } - justifyContent="space-between" - alignItems="center" - display="flex" - > - - + bgColor={color} + flex="1 1 8px" + borderRadius="2xl" + > ))} - - - - - - Accent - - } - > - { + + + {colorList.map((color) => ( + + setVisuals({ + ...visuals, + linkColorScheme: color, + }) + } + justifyContent="space-between" + alignItems="center" + display="flex" + > - } - - - {' '} - - {colorList.map((color) => ( - setHighlightColor(color)} - justifyContent="space-between" - alignItems="center" - display="flex" - > - - - ))} - - - - - - - - - - - - - - } - align="stretch" - paddingLeft={7} - color="gray.800" - > - setVisuals({ ...visuals, nodeRel: value })} - /> - setVisuals({ ...visuals, nodeSizeLinks: value })} - /> - {threeDim && ( - <> - setVisuals({ ...visuals, nodeOpacity: value })} + + ))} + + + + + + Accent + + } + > + { + + } + + + {' '} + + {colorList.map((color) => ( + setHighlightColor(color)} + justifyContent="space-between" + alignItems="center" + display="flex" + > + + + ))} + + + + + - setVisuals({ ...visuals, nodeResolution: value })} + - - )} + + + + + + + + } + align="stretch" + paddingLeft={7} + color="gray.800" + > + setVisuals({ ...visuals, nodeRel: value })} + /> + setVisuals({ ...visuals, nodeSizeLinks: value })} + /> + {threeDim && ( + <> setVisuals({ ...visuals, linkWidth: value })} - /> - {threeDim && ( - setVisuals({ ...visuals, linkOpacity: value })} - /> - )} - setVisuals({ ...visuals, citeDashes: !visuals.citeDashes })} - > - - setVisuals({ ...visuals, citeDashLength: value * 10 }) - } - /> - setVisuals({ ...visuals, citeGapLength: value * 5 })} - /> - - - - - setVisuals({ ...visuals, refDashes: !visuals.refDashes })} - > - - setVisuals({ ...visuals, refDashLength: value * 10 }) - } - /> - setVisuals({ ...visuals, refGapLength: value * 5 })} - /> - - - setVisuals({ ...visuals, nodeOpacity: value })} /> - setVisuals({ ...visuals, nodeResolution: value })} /> - - - Labels - - } - > - {!visuals.labels - ? 'Never' - : visuals.labels < 2 - ? 'On Highlight' - : 'Always'} - - - {' '} - - setVisuals({ ...visuals, labels: 0 })}> - Never - - setVisuals({ ...visuals, labels: 1 })}> - On Highlight - - setVisuals({ ...visuals, labels: 2 })}> - Always - - setVisuals({ ...visuals, labels: 3 })}> - Always (even in 3D) - - - - - - 0} animateOpacity> - } - align="stretch" - paddingLeft={2} - color="gray.800" - > - - - - - { - console.log(visuals.labelBackgroundOpacity) - setVisuals({ ...visuals, labelBackgroundOpacity: value }) - }} - min={0} - max={1} - step={0.01} - /> - - - 1} animateOpacity> - - - setVisuals({ ...visuals, labelScale: value / 5 }) - } - /> - - - - - - setVisuals({ ...visuals, arrows: !visuals.arrows })} - > - setVisuals({ ...visuals, arrowsLength: 10 * value })} - /> - setVisuals({ ...visuals, arrowsPos: value })} - /> - - - setVisuals({ ...visuals, particles: !visuals.particles })} - > - setVisuals({ ...visuals, particlesNumber: value })} - /> - setVisuals({ ...visuals, particlesWidth: value })} - /> - - setVisuals({ ...visuals, highlight: !visuals.highlight })} - value={visuals.highlight} - > - } - align="stretch" - paddingLeft={0} - > - - setVisuals({ ...visuals, highlightLinkSize: value }) - } - /> - - setVisuals({ ...visuals, highlightNodeSize: value }) - } - /> - {/* - Highlight node color - - - Highlight link color - */} - { - setVisuals({ ...visuals, highlightAnim: !visuals.highlightAnim }) - }} - value={visuals.highlightAnim} - > - setVisuals({ ...visuals, animationSpeed: v })} - value={visuals.animationSpeed} - infoText="Slower speed has a chance of being buggy" - min={50} - max={1000} - step={10} - /> - - - - - - - - - - - - Behavior - - - } - align="stretch" - paddingLeft={7} - color="gray.800" + + )} + setVisuals({ ...visuals, linkWidth: value })} + /> + {threeDim && ( + setVisuals({ ...visuals, linkOpacity: value })} + /> + )} + setVisuals({ ...visuals, citeDashes: !visuals.citeDashes })} + > + setVisuals({ ...visuals, citeDashLength: value * 10 })} + /> + setVisuals({ ...visuals, citeGapLength: value * 5 })} + /> + + + + + setVisuals({ ...visuals, refDashes: !visuals.refDashes })} > + setVisuals({ ...visuals, refDashLength: value * 10 })} + /> + setVisuals({ ...visuals, refGapLength: value * 5 })} + /> + + + + + - - Expand Node - - + Labels } colorScheme="" color="black" - > - - {mouse.local - ? mouse.local[0]!.toUpperCase() + mouse.local!.slice(1) - : 'Never'} - - - - {' '} - - setMouse({ ...mouse, local: '' })}> - Never - - setMouse({ ...mouse, local: 'click' })}> - Click - - setMouse({ ...mouse, local: 'double' })}> - Double Click - - setMouse({ ...mouse, local: 'right' })}> - Right Click - - - - - - - Open in Emacs - - } - colorScheme="" - color="black" > - - {mouse.follow - ? mouse.follow[0]!.toUpperCase() + mouse.follow!.slice(1) - : 'Never'} - + {!visuals.labels + ? 'Never' + : visuals.labels < 2 + ? 'On Highlight' + : 'Always'} {' '} - - setMouse({ ...mouse, follow: '' })}> + + setVisuals({ ...visuals, labels: 0 })}> Never - setMouse({ ...mouse, follow: 'click' })}> - Click + setVisuals({ ...visuals, labels: 1 })}> + On Highlight - setMouse({ ...mouse, follow: 'double' })}> - Double Click + setVisuals({ ...visuals, labels: 2 })}> + Always - setMouse({ ...mouse, follow: 'right' })}> - Right Click + setVisuals({ ...visuals, labels: 3 })}> + Always (even in 3D) - - Follow Emacs by... - - } - colorScheme="" - color="black" + 0} animateOpacity> + } + align="stretch" + paddingLeft={2} + color="gray.800" + > + + + + + { + console.log(visuals.labelBackgroundOpacity) + setVisuals({ ...visuals, labelBackgroundOpacity: value }) + }} + min={0} + max={1} + step={0.01} + /> + + + 1} animateOpacity> + + + setVisuals({ ...visuals, labelScale: value / 5 }) + } + /> + + + + + + setVisuals({ ...visuals, arrows: !visuals.arrows })} + > + setVisuals({ ...visuals, arrowsLength: 10 * value })} + /> + setVisuals({ ...visuals, arrowsPos: value })} + /> + + + setVisuals({ ...visuals, particles: !visuals.particles })} + > + setVisuals({ ...visuals, particlesNumber: value })} + /> + setVisuals({ ...visuals, particlesWidth: value })} + /> + + setVisuals({ ...visuals, highlight: !visuals.highlight })} + value={visuals.highlight} + > + } + align="stretch" + paddingLeft={0} + > + setVisuals({ ...visuals, highlightLinkSize: value })} + /> + setVisuals({ ...visuals, highlightNodeSize: value })} + /> + setVisuals({ ...visuals, highlightFade: value })} + /> + {/* + Highlight node color + + + Highlight link color + */} + { + setVisuals({ ...visuals, highlightAnim: !visuals.highlightAnim }) + }} + value={visuals.highlightAnim} + > + setVisuals({ ...visuals, animationSpeed: v })} + value={visuals.animationSpeed} + infoText="Slower speed has a chance of being buggy" + min={50} + max={1000} + step={10} + /> + + + + + + + + + + + + Behavior + + + } + align="stretch" + paddingLeft={7} + color="gray.800" + > + + + Expand Node + + + + } + colorScheme="" + color="black" + > + + {mouse.local + ? mouse.local[0]!.toUpperCase() + mouse.local!.slice(1) + : 'Never'} + + + + {' '} + + setMouse({ ...mouse, local: '' })}>Never + setMouse({ ...mouse, local: 'click' })}> + Click + + setMouse({ ...mouse, local: 'double' })}> + Double Click + + setMouse({ ...mouse, local: 'right' })}> + Right Click + + + + + + + Open in Emacs + + } + colorScheme="" + color="black" + > + + {mouse.follow + ? mouse.follow[0]!.toUpperCase() + mouse.follow!.slice(1) + : 'Never'} + + + + {' '} + + setMouse({ ...mouse, follow: '' })}> + Never + + setMouse({ ...mouse, follow: 'click' })}> + Click + + setMouse({ ...mouse, follow: 'double' })}> + Double Click + + setMouse({ ...mouse, follow: 'right' })}> + Right Click + + + + + + + Follow Emacs by... + + } + colorScheme="" + color="black" + > + {behavior.follow[0].toUpperCase() + behavior.follow.slice(1)} + + + {' '} + + setBehavior({ ...behavior, follow: 'color' })}> + Just coloring the currently opened node + + setBehavior({ ...behavior, follow: 'local' })}> + Opening the local graph + + setBehavior({ ...behavior, follow: 'zoom' })}> + Zooming to the current node + + + + + + {/* Follow local graph @@ -1181,31 +1151,29 @@ export const Tweaks = (props: TweakProps) => { */} - setBehavior({ ...behavior, zoomSpeed: value })} - /> - setBehavior({ ...behavior, zoomPadding: value })} - infoText="How much to zoom out to accomodate all nodes when changing the view." - /> - - - - - - - - + setBehavior({ ...behavior, zoomSpeed: value })} + /> + setBehavior({ ...behavior, zoomPadding: value })} + infoText="How much to zoom out to accomodate all nodes when changing the view." + /> + + + + + + ) } -- cgit v1.2.3