diff --git a/src/components/App/ActionsToolbar/PlayerControl/index.tsx b/src/components/App/ActionsToolbar/PlayerControl/index.tsx index 5d67c055e..ec9de2600 100644 --- a/src/components/App/ActionsToolbar/PlayerControl/index.tsx +++ b/src/components/App/ActionsToolbar/PlayerControl/index.tsx @@ -54,7 +54,9 @@ export const PlayerControl = () => { const showPlayer = (sidebarIsOpen && selectedNode?.ref_id !== playingNode?.ref_id) || (playingNode && !sidebarIsOpen) - return miniPlayerIsVisible && playingNode && showPlayer ? ( + const isMindset = window.location?.hostname === 'graphmindset.sphinx.chat' + + return miniPlayerIsVisible && playingNode && showPlayer && !isMindset ? ( diff --git a/src/components/Universe/Graph/Cubes/Text/index.tsx b/src/components/Universe/Graph/Cubes/Text/index.tsx index 64f3b8808..5dc6dc0a9 100644 --- a/src/components/Universe/Graph/Cubes/Text/index.tsx +++ b/src/components/Universe/Graph/Cubes/Text/index.tsx @@ -128,7 +128,7 @@ export const TextNode = memo(({ node, hide, ignoreDistance }: Props) => { const Icon = primaryIcon ? Icons[primaryIcon] : null const iconName = Icon ? primaryIcon : 'NodesIcon' - const sanitizedNodeName = removeEmojis(String(node.name)) + const sanitizedNodeName = removeEmojis(String(node?.properties?.name || '')) const uniforms = { u_texture: { value: texture }, @@ -192,7 +192,7 @@ export const TextNode = memo(({ node, hide, ignoreDistance }: Props) => { /> )} - {node.name && ( + {sanitizedNodeName && ( = start && playerProgress <= end) { return edge // Found the corresponding edge @@ -127,9 +127,11 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => { } const edges = useMemo(() => { - const edgesFiltered = dataInitial?.links.filter((link) => link?.start) || [] + const edgesFiltered = dataInitial?.links.filter((link) => link?.properties?.start) || [] - const sortedEdges = edgesFiltered.slice().sort((a, b) => (a?.start as number) - (b?.start as number)) + const sortedEdges = edgesFiltered + .slice() + .sort((a, b) => (a?.properties?.start as number) - (b?.properties?.start as number)) return sortedEdges }, [dataInitial]) diff --git a/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx b/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx index 3d4ef0ab7..b0a3ffa74 100644 --- a/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx +++ b/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx @@ -2,9 +2,9 @@ import { LinearProgress } from '@mui/material' import styled from 'styled-components' import { Flex } from '~/components/common/Flex' import { Tooltip } from '~/components/common/ToolTip' +import { NodeExtended } from '~/types' import { colors } from '~/utils' import { Marker } from '../../Marker' -import { NodeExtended } from '~/types' type Props = { duration: number @@ -12,27 +12,23 @@ type Props = { markers: NodeExtended[] } -export const ProgressBar = ({ duration, progress, markers }: Props) => { - console.log('s') +export const ProgressBar = ({ duration, progress, markers }: Props) => ( + + + {markers.map((node) => { + const position = ((node?.start || 0) / duration) * 100 + const type = node?.node_type || '' - return ( - - - {markers.map((node) => { - const position = ((node?.start || 0) / duration) * 100 - const type = node?.node_type || '' - - return ( - - - - - - ) - })} - - ) -} + return ( + + + + + + ) + })} + +) const Progress = styled(LinearProgress)` && { @@ -62,4 +58,7 @@ const MarkerWrapper = styled.div` transform: translateX(-50%); /* Center the marker horizontally */ transform: translateX(-50%) translateY(-50%); top: 50%; + display: flex; + align-items: center; + justify-content: center; ` diff --git a/src/components/mindset/components/PlayerContols/index.tsx b/src/components/mindset/components/PlayerContols/index.tsx index 060f72367..90d01dd2f 100644 --- a/src/components/mindset/components/PlayerContols/index.tsx +++ b/src/components/mindset/components/PlayerContols/index.tsx @@ -55,9 +55,9 @@ const Wrapper = styled(Flex).attrs({ justify: 'space-between', })` padding: 20px; - margin: 20px; background: ${colors.BG2}; height: 96px; + margin-top: 16px; border-radius: 8px; box-sizing: border-box; ` diff --git a/src/components/mindset/components/Sidebar/Transcript/index.tsx b/src/components/mindset/components/Sidebar/Transcript/index.tsx index 84472cabc..c7b73e9a7 100644 --- a/src/components/mindset/components/Sidebar/Transcript/index.tsx +++ b/src/components/mindset/components/Sidebar/Transcript/index.tsx @@ -1,22 +1,57 @@ +import { useEffect, useState } from 'react' import styled from 'styled-components' import { Flex } from '~/components/common/Flex' -import { transcript } from '~/components/mindset/data/transcript' +import { fetchNodeEdges } from '~/network/fetchGraphData' +import { useMindsetStore } from '~/stores/useMindsetStore' import { usePlayerStore } from '~/stores/usePlayerStore' +import { NodeExtended } from '~/types' import { colors } from '~/utils' export const Transcript = () => { - const data = transcript + const { selectedEpisodeId } = useMindsetStore((s) => s) + const { playingTime, duration } = usePlayerStore((s) => s) - const { playingTime } = usePlayerStore((s) => s) + const [clips, setClips] = useState([]) + + useEffect(() => { + const init = async () => { + try { + const res = await fetchNodeEdges(selectedEpisodeId, 0, 50, { nodeType: ['Clip'], useSubGraph: false }) + + if (res?.nodes) { + setClips(res.nodes) + } + } catch (error) { + console.error(error) + } + } + + if (selectedEpisodeId) { + init() + } + }, [selectedEpisodeId]) return ( - Transcript ({playingTime}) - - {data.map((tr) => ( - {tr.text} - ))} - + Transcript + {clips.map((clip) => { + const timestamp: string | undefined = clip?.properties?.timestamp + + const [start, end] = timestamp + ? (timestamp as string).split('-').map(Number) // Directly convert to numbers + : [0, duration] + + if (start <= playingTime * 1000 && playingTime * 1000 < end) { + // Multiply playingTime by 1000 to match millisecond format + return ( + + {clip?.properties?.text && {clip?.properties?.text}} + + ) + } + + return null + })} ) } @@ -25,12 +60,14 @@ const Wrapper = styled(Flex)` .heading { font-weight: 700; font-size: 12px; + margin-bottom: 16px; } + color: ${colors.white}; background: ${colors.BG1}; border-radius: 8px; padding: 24px; - overflow: scroll; + overflow-y: auto; flex: 1 1 100%; ` diff --git a/src/components/mindset/components/Sidebar/index.tsx b/src/components/mindset/components/Sidebar/index.tsx index 06dc065ff..ea894294d 100644 --- a/src/components/mindset/components/Sidebar/index.tsx +++ b/src/components/mindset/components/Sidebar/index.tsx @@ -12,8 +12,8 @@ export const SideBar = () => { return ( - {selectedEpisode?.node_type && {selectedEpisode?.node_type}} {selectedEpisode?.name && {selectedEpisode?.name}} + {selectedEpisode?.properties?.text && {selectedEpisode?.properties?.text}} {selectedEpisodeLink && } @@ -34,7 +34,6 @@ const Wrapper = styled(Flex)(({ theme }) => ({ })) const Summary = styled(Text)` - font-family: Inter; font-size: 20px; font-weight: Bold; line-height: 24.2px; @@ -42,13 +41,13 @@ const Summary = styled(Text)` white-space: normal; word-break: break-word; margin-right: 10px; + font-weight: 500; ` const EpisodeTitle = styled(Text)` - font-family: Inter; margin-top: 20px; font-size: 14px; - font-weight: 500; + font-weight: 700; line-height: 16.94px; ` diff --git a/src/components/mindset/index.tsx b/src/components/mindset/index.tsx index 60a208275..e4fed860a 100644 --- a/src/components/mindset/index.tsx +++ b/src/components/mindset/index.tsx @@ -73,7 +73,6 @@ export const MindSet = () => { const data = await fetchNodeEdges(selectedEpisodeId, 0, 50) if (data) { - data.nodes = data?.nodes.map((i) => ({ ...i, node_type: 'Topic' })) handleNewNodeCreated(data) } } catch (error) { @@ -130,18 +129,20 @@ export const MindSet = () => { const markers = useMemo(() => { if (dataInitial) { - const edgesMention: Array<{ source: string; start: number }> = dataInitial.links - .filter((e) => e?.start) - .map((edge) => ({ source: edge.source, start: edge?.start as number })) + const edgesMention: Array<{ source: string; target: string; start: number }> = dataInitial.links + .filter((e) => e?.properties?.start) + .map((edge) => ({ source: edge.source, target: edge.target, start: edge.properties?.start as number })) const nodesWithTimestamps = dataInitial.nodes - .filter((node) => dataInitial.links.some((ed) => ed.source === node.ref_id)) + .filter((node) => dataInitial.links.some((ed) => ed.source === node.ref_id || ed.target === node.ref_id)) .map((node) => { - const edge = edgesMention.find((ed) => node.ref_id === ed.source) + const edge = edgesMention.find((ed) => node.ref_id === ed.source || node.ref_id === ed.target) return { ...node, start: edge?.start || 0 } }) - .filter((node) => node) + .filter( + (node) => node && node.node_type !== 'Clip' && node.node_type !== 'Episode' && node.node_type !== 'Show', + ) return nodesWithTimestamps } @@ -159,7 +160,7 @@ export const MindSet = () => { - + {showTwoD ? : } diff --git a/src/network/fetchGraphData/index.ts b/src/network/fetchGraphData/index.ts index 86a1187ed..1c56acf55 100644 --- a/src/network/fetchGraphData/index.ts +++ b/src/network/fetchGraphData/index.ts @@ -52,11 +52,45 @@ const fetchNodes = async ( return fetchWithLSAT() } -export const fetchNodeEdges = async (refId: string, skip: number, limit = 5): Promise => { +interface FetchNodeEdgesParams { + sortBy?: string + includeProperties?: boolean + includeContent?: boolean + depth?: number + useSubGraph?: boolean + nodeType?: string[] // Array of strings for node types +} + +export const fetchNodeEdges = async ( + refId: string, + skip: number, + limit = 5, + params: FetchNodeEdgesParams = {}, // Optional params +): Promise => { try { - const response = await api.get( - `/prediction/graph/edges/${refId}?skip=${skip}&limit=${limit}&sort_by="edge_count&include_properties=true&includeContent=true&depth=1"`, - ) + // Destructure and provide defaults + const { + sortBy = 'edge_count', + includeProperties = true, + includeContent = true, + depth = 1, + useSubGraph = true, + nodeType = [], // Default to an empty array + } = params + + // Construct query string + const query = new URLSearchParams({ + skip: skip.toString(), + limit: limit.toString(), + sort_by: sortBy, + include_properties: includeProperties.toString(), + includeContent: includeContent.toString(), + depth: depth.toString(), + use_sub_graph: useSubGraph.toString(), + ...(nodeType.length > 0 && { node_type: JSON.stringify(nodeType) }), // Add node_type if not empty + }).toString() + + const response = await api.get(`/prediction/graph/edges/${refId}?${query}`) return response } catch (e) { diff --git a/src/types/index.ts b/src/types/index.ts index 01d126700..bf4941d8b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -167,6 +167,7 @@ export type Link = { targetPosition?: Vector3 onlyVisibleOnSelect?: boolean properties?: { [key: string]: unknown } + attributes?: { [key: string]: unknown } } export type GraphData = {