diff --git a/src/components/App/SideBar/SelectedNodeView/Default/index.tsx b/src/components/App/SideBar/SelectedNodeView/Default/index.tsx index 5949eb134..c043388f5 100644 --- a/src/components/App/SideBar/SelectedNodeView/Default/index.tsx +++ b/src/components/App/SideBar/SelectedNodeView/Default/index.tsx @@ -1,7 +1,7 @@ import Button from '@mui/material/Button' import clsx from 'clsx' import moment from 'moment' -import { useEffect, useRef, useState } from 'react' +import React, { useEffect, useRef, useState } from 'react' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { okaidia } from 'react-syntax-highlighter/dist/esm/styles/prism' import styled from 'styled-components' @@ -14,25 +14,74 @@ import { TypeBadge } from '~/components/common/TypeBadge' import AiPauseIcon from '~/components/Icons/AiPauseIcon' import AiPlayIcon from '~/components/Icons/AiPlayIcon' import LinkIcon from '~/components/Icons/LinkIcon' +import { fetchNodeEdges } from '~/network/fetchGraphData' import { useAppStore } from '~/stores/useAppStore' import { useSelectedNode } from '~/stores/useGraphStore' +import { usePlayerStore } from '~/stores/usePlayerStore' +import { useSchemaStore } from '~/stores/useSchemaStore' +import { Link, Node } from '~/types' import { colors } from '~/utils/colors' import { BoostAmt } from '../../../Helper/BoostAmt' -import { usePlayerStore } from '~/stores/usePlayerStore' + +interface SequencedNode { + node: Node + sequence: number +} + +interface EdgeWithTargetNode extends Link { + target_node?: Node + properties?: { + sequence?: number + [key: string]: unknown + } +} export const Default = () => { const selectedNode = useSelectedNode() const audioRef = useRef(null) const { currentPlayingAudio, setCurrentPlayingAudio } = useAppStore((s) => s) const [isPlaying, setIsPlaying] = useState(false) + const [sequencedNodes, setSequencedNodes] = useState([]) const [boostAmount, setBoostAmount] = useState(selectedNode?.properties?.boost || 0) + const getIndexByType = useSchemaStore((s) => s.getIndexByType) const { playingNode } = usePlayerStore((s) => s) useEffect(() => { setBoostAmount(selectedNode?.properties?.boost || 0) }, [selectedNode]) + useEffect(() => { + const fetchSequencedNodes = async () => { + if (selectedNode?.ref_id) { + const response = await fetchNodeEdges(selectedNode.ref_id, 0, 100, { + sortBy: 'sequence', + includeProperties: true, + includeContent: true, + depth: 1, + useSubGraph: true, + }) + + if (response) { + const nodesWithSequence = + response.edges + ?.filter( + (edge: EdgeWithTargetNode) => edge.properties?.sequence !== undefined && edge.target_node !== undefined, + ) + .map((edge: EdgeWithTargetNode) => ({ + node: edge.target_node as Node, + sequence: edge.properties?.sequence as number, + })) + .sort((a, b) => a.sequence - b.sequence) || [] + + setSequencedNodes(nodesWithSequence) + } + } + } + + fetchSequencedNodes() + }, [selectedNode?.ref_id]) + useEffect(() => { const audioElement = audioRef.current @@ -85,9 +134,15 @@ export const Default = () => { const sourceLink = selectedNode.properties?.source_link const pubkey = selectedNode.properties?.pubkey + const getNodeContent = (node: Node) => { + const keyProp = getIndexByType(node.node_type) + + return keyProp ? node.properties?.[keyProp] : node.label + } + return ( - {hasImage ? ( + {hasImage && ( img_a11y { src={selectedNode.properties?.image_url} /> - ) : null} + )} @@ -128,6 +183,17 @@ export const Default = () => { ))} + {sequencedNodes.length > 0 && ( + + {sequencedNodes.map((item, idx) => ( + + {getNodeContent(item.node)} + {idx < sequencedNodes.length - 1 && } + + ))} + + )} + {pubkey && ( @@ -296,3 +362,17 @@ const StyledLinkIcon = styled.a` height: 1.3em; } ` + +const StyledSequenceWrapper = styled(Flex)` + padding: 16px 24px; + flex-direction: column; + gap: 8px; + overflow-y: auto; +` + +const StyledLineBreak = styled.div` + width: 100%; + height: 1px; + background-color: ${colors.GRAY3}; + margin: 8px 0; +`