diff --git a/src/components/Universe/Graph/Cubes/Text/index.tsx b/src/components/Universe/Graph/Cubes/Text/index.tsx index ede72b2d8..31518e065 100644 --- a/src/components/Universe/Graph/Cubes/Text/index.tsx +++ b/src/components/Universe/Graph/Cubes/Text/index.tsx @@ -77,7 +77,7 @@ export const TextNode = memo(({ node, hide, ignoreDistance }: Props) => { const { texture } = useTexture(node.properties?.image_url || '') - const { normalizedSchemasByType } = useSchemaStore((s) => s) + const { normalizedSchemasByType, getNodeKeysByType } = useSchemaStore((s) => s) useFrame(({ camera, clock }) => { const { selectedNode, hoveredNode, activeEdge } = useGraphStore.getState() @@ -148,7 +148,10 @@ export const TextNode = memo(({ node, hide, ignoreDistance }: Props) => { const Icon = primaryIcon ? Icons[primaryIcon] : null const iconName = Icon ? primaryIcon : 'NodesIcon' - const sanitizedNodeName = removeEmojis(String(node?.properties?.name || '')) + const keyProperty = getNodeKeysByType(node.node_type) || '' + + const sanitizedNodeName = + keyProperty && node?.properties ? removeEmojis(String(node?.properties[keyProperty] || '')) : '' const uniforms = { u_texture: { value: texture }, diff --git a/src/components/mindset/components/Header/index.tsx b/src/components/mindset/components/Header/index.tsx index 280530014..43565241e 100644 --- a/src/components/mindset/components/Header/index.tsx +++ b/src/components/mindset/components/Header/index.tsx @@ -22,6 +22,7 @@ const Head = styled(Flex).attrs({ justify: 'flex-start', })` height: 64px; + box-sizing: border-box; padding: 20px 23px; gap: 0px; z-index: 50; diff --git a/src/components/mindset/components/LandingPage/index.tsx b/src/components/mindset/components/LandingPage/index.tsx index 7c33fbcbd..6980905e5 100644 --- a/src/components/mindset/components/LandingPage/index.tsx +++ b/src/components/mindset/components/LandingPage/index.tsx @@ -8,11 +8,11 @@ import { getNodes, getSchemaAll } from '~/network/fetchSourcesData' import { useDataStore } from '~/stores/useDataStore' import { useMindsetStore } from '~/stores/useMindsetStore' import { useSchemaStore } from '~/stores/useSchemaStore' -import { SubmitErrRes } from '~/types' +import { FetchDataResponse, Node, SubmitErrRes } from '~/types' import { colors } from '~/utils/colors' import { ChevronRight } from '../Icon/ChevronRight' -import { isValidMediaUrl } from './utils' import { VideoCard } from '../VideoCard' +import { isValidMediaUrl } from './utils' export type FormData = { input: string @@ -22,26 +22,6 @@ export type FormData = { latitude: string } -interface EpisodeProperties { - date: number - episode_title: string - image_url: string - media_url: string - pubkey: string - source_link: string - status: string -} - -interface Node { - node_type: string - properties?: EpisodeProperties -} - -export interface ApiResponse { - edges: never[] - nodes: Node[] -} - const handleSubmitForm = async (data: FieldValues): Promise => { const endPoint = 'add_node' @@ -65,22 +45,18 @@ export const LandingPage = () => { const [inputValue, setInputValue] = useState('') const [error, setError] = useState(false) const [requestError, setRequestError] = useState('') - const [episodes, setEpisodes] = useState([]) + const [episodes, setEpisodes] = useState([]) const { setRunningProjectId } = useDataStore((s) => s) const { setSelectedEpisodeId, setSelectedEpisodeLink } = useMindsetStore((s) => s) const { setSchemas } = useSchemaStore((s) => s) - const filterAndSortEpisodes = (data: ApiResponse): EpisodeProperties[] => - data.nodes - .filter((node) => node.node_type.toLowerCase() === 'episode' && node.properties?.date) - .map((node) => node.properties!) - .sort((a, b) => b.date - a.date) - .slice(0, 3) + const filterAndSortEpisodes = (data: FetchDataResponse): Node[] => + data.nodes.filter((node) => node.node_type.toLowerCase() === 'episode' && node.properties?.date).slice(0, 3) useEffect(() => { const fetchSchemaData = async () => { try { - const res: ApiResponse = await getNodes() + const res: FetchDataResponse = await getNodes() const topEpisodes = filterAndSortEpisodes(res) @@ -161,11 +137,11 @@ export const LandingPage = () => { {episodes.map((episode) => ( handleSubmit(episode?.source_link)} - subtitle="Subtitle for episode seed" - title={(episode?.episode_title as string) || ''} + key={episode?.ref_id} + imageUrl={episode?.properties?.image_url || ''} + onClick={() => handleSubmit(episode?.properties?.source_link)} + subtitle="" + title={episode?.properties?.episode_title || ''} /> ))} diff --git a/src/components/mindset/components/MediaPlayer/index.tsx b/src/components/mindset/components/MediaPlayer/index.tsx index a073e4c97..b7b106db2 100644 --- a/src/components/mindset/components/MediaPlayer/index.tsx +++ b/src/components/mindset/components/MediaPlayer/index.tsx @@ -89,13 +89,13 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => { setIsPlaying(!isPlaying) } - const handlePlay = () => { + const handlePlay = useCallback(() => { setIsPlaying(true) - } + }, [setIsPlaying]) - const handlePause = () => { + const handlePause = useCallback(() => { setIsPlaying(false) - } + }, [setIsPlaying]) const handleError = () => { setHasError(true) @@ -123,8 +123,6 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => { } else { setActiveEdge(null) } - - // find playing link and set it to state } } diff --git a/src/components/mindset/components/PlayerContols/Controls/index.tsx b/src/components/mindset/components/PlayerContols/Controls/index.tsx new file mode 100644 index 000000000..8abd7e388 --- /dev/null +++ b/src/components/mindset/components/PlayerContols/Controls/index.tsx @@ -0,0 +1,104 @@ +import { IconButton } from '@mui/material' +import { memo } from 'react' +import styled from 'styled-components' +import PauseIcon from '~/components/Icons/PauseIcon' +import PlayIcon from '~/components/Icons/PlayIcon' +import { Flex } from '~/components/common/Flex' +import { usePlayerStore } from '~/stores/usePlayerStore' +import { colors } from '~/utils/colors' + +export const Controls = memo(() => { + const { isPlaying, playerRef } = usePlayerStore((s) => s) + + const handleRewind = () => { + if (playerRef) { + const newTime = playerRef.getCurrentTime() - 15 + + playerRef.seekTo(newTime, 'seconds') + } + } + + const handleFastForward = () => { + if (playerRef) { + const newTime = playerRef.getCurrentTime() + 15 + + playerRef.seekTo(newTime, 'seconds') + } + } + + const togglePlay = () => { + if (playerRef) { + if (isPlaying) { + playerRef.getInternalPlayer().pauseVideo() + + return + } + + playerRef.getInternalPlayer().playVideo() + } + } + + return ( + + + + + + {isPlaying ? : } + + + + + + ) +}) + +Controls.displayName = 'Controls' + +const Wrapper = styled(Flex).attrs({ + direction: 'row', + align: 'center', + justify: 'flex-start', +})` + width: 142px; + height: 54px; + background: ${colors.BG1}; + border-radius: 40px; + margin-right: 54px; + color: ${colors.white}; + font-size: 20px; + padding: 12px; + justify-content: space-between; + box-sizing: border-box; +` + +const Action = styled(IconButton)` + && { + font-size: 36px; + padding: 2px; + overflow: hidden; + } +` + +const RewindIconWrapper = styled.div` + display: flex; + align-items: center; + justify-content: center; + margin: 1px 0 0 1px; + cursor: pointer; + img { + width: 20px; + height: auto; + } +` + +const ForwardIconWrapper = styled.div` + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + img { + width: 24px; + height: auto; + } +` diff --git a/src/components/mindset/components/Marker/index.tsx b/src/components/mindset/components/PlayerContols/ProgressBar/Markers/Marker/index.tsx similarity index 100% rename from src/components/mindset/components/Marker/index.tsx rename to src/components/mindset/components/PlayerContols/ProgressBar/Markers/Marker/index.tsx diff --git a/src/components/mindset/components/PlayerContols/ProgressBar/Markers/index.tsx b/src/components/mindset/components/PlayerContols/ProgressBar/Markers/index.tsx new file mode 100644 index 000000000..8f7e3f868 --- /dev/null +++ b/src/components/mindset/components/PlayerContols/ProgressBar/Markers/index.tsx @@ -0,0 +1,22 @@ +import { memo } from 'react' +import { NodeExtended } from '~/types' +import { Marker } from './Marker' + +type Props = { + markers: NodeExtended[] + duration: number +} + +export const Markers = memo(({ markers, duration }: Props) => ( + <> + {markers.map((node) => { + const position = ((node?.start || 0) / duration) * 100 + const type = node?.node_type || '' + const img = node?.properties?.image_url || '' + + return + })} + +)) + +Markers.displayName = 'Markers' diff --git a/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx b/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx index 557cb22da..c7b57145a 100644 --- a/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx +++ b/src/components/mindset/components/PlayerContols/ProgressBar/index.tsx @@ -3,7 +3,7 @@ import styled from 'styled-components' import { Flex } from '~/components/common/Flex' import { NodeExtended } from '~/types' import { colors } from '~/utils' -import { Marker } from '../../Marker' +import { Markers } from './Markers' type Props = { duration: number @@ -18,13 +18,7 @@ export const ProgressBar = ({ duration, markers, handleProgressChange, playingTI return ( - {markers.map((node) => { - const position = ((node?.start || 0) / duration) * 100 - const type = node?.node_type || '' - const img = node?.properties?.image_url || '' - - return - })} + ) } diff --git a/src/components/mindset/components/PlayerContols/index.tsx b/src/components/mindset/components/PlayerContols/index.tsx index b14bc3b7f..8a15165e1 100644 --- a/src/components/mindset/components/PlayerContols/index.tsx +++ b/src/components/mindset/components/PlayerContols/index.tsx @@ -1,12 +1,10 @@ -import { IconButton } from '@mui/material' import { useCallback, useEffect, useState } from 'react' import styled from 'styled-components' -import PauseIcon from '~/components/Icons/PauseIcon' -import PlayIcon from '~/components/Icons/PlayIcon' import { Flex } from '~/components/common/Flex' import { usePlayerStore } from '~/stores/usePlayerStore' import { NodeExtended } from '~/types' import { colors } from '~/utils/colors' +import { Controls } from './Controls' import { ProgressBar } from './ProgressBar' type Props = { @@ -14,7 +12,7 @@ type Props = { } export const PlayerControl = ({ markers }: Props) => { - const { isPlaying, setIsPlaying, playingNode, playerRef } = usePlayerStore((s) => s) + const { playingNode, playerRef } = usePlayerStore((s) => s) const [currentTime, setCurrentTime] = useState(0) const showPlayer = playingNode @@ -42,45 +40,11 @@ export const PlayerControl = ({ markers }: Props) => { return () => clearInterval(interval) }, [playerRef, setCurrentTime]) - const handleRewind = () => { - if (playerRef) { - const newTime = playerRef.getCurrentTime() - 15 - - playerRef.seekTo(newTime, 'seconds') - } - } - - const handleFastForward = () => { - if (playerRef) { - const newTime = playerRef.getCurrentTime() + 15 - - playerRef.seekTo(newTime, 'seconds') - } - } - const duration = playerRef?.getDuration() || 0 return showPlayer ? ( - - - - - { - setIsPlaying(!isPlaying) - e.stopPropagation() - }} - size="small" - > - {isPlaying ? : } - - - - - - + (({ active, start, text }, ref) => ( + + {start} + + {text} + + +)) + +ParagraphComponent.displayName = 'ParagraphComponent' + +export const Paragraph = memo(ParagraphComponent, (prevProps, nextProps) => prevProps.active === nextProps.active) + +const StyledParagraph = styled(Flex)` + flex-direction: row; + align-items: flex-start; + font-size: 14px; + padding: 8px 24px; + &.active { + background: ${colors.AI_HIGHLIGHT}; + } +` + +const Start = styled.span` + background: ${colors.lightBlue100}; + color: ${colors.lightBlue500}; + padding: 2px; + margin-right: 8px; + border-radius: 4px; +` + +const Words = styled.div` + margin: 0 2px; + word-break: break-word; + + &.active { + background: ${colors.AI_HIGHLIGHT}; + } +` diff --git a/src/components/mindset/components/Sidebar/Transcript/Viewer/index.tsx b/src/components/mindset/components/Sidebar/Transcript/Viewer/index.tsx index 39abaafd6..a1c91fe68 100644 --- a/src/components/mindset/components/Sidebar/Transcript/Viewer/index.tsx +++ b/src/components/mindset/components/Sidebar/Transcript/Viewer/index.tsx @@ -1,10 +1,8 @@ -import clsx from 'clsx' import { useEffect, useRef, useState } from 'react' import styled from 'styled-components' -import { Flex } from '~/components/common/Flex' import { usePlayerStore } from '~/stores/usePlayerStore' -import { colors } from '~/utils' import { secondsToMediaTime } from '~/utils/secondsToMediaTime' +import { Paragraph } from './Paragraph' type Props = { transcriptString: string @@ -101,49 +99,19 @@ export const Viewer = ({ transcriptString }: Props) => { - {start} - - {i.text} - - + active={isActive} + start={start} + text={i.text} + /> ) })} ) } -const Paragraph = styled(Flex)` - flex-direction: row; - align-items: flex-start; - font-size: 14px; - padding: 8px 24px; - &.active { - background: ${colors.AI_HIGHLIGHT}; - } -` - const Wrapper = styled.div` width: 100%; height: 100%; overflow: scroll; padding-right: 4px; ` - -const Start = styled.span` - background: ${colors.lightBlue100}; - color: ${colors.lightBlue500}; - padding: 2px; - margin-right: 8px; - border-radius: 4px; -` - -const Words = styled.div` - margin: 0 2px; - word-break: break-word; - - &.active { - background: ${colors.AI_HIGHLIGHT}; - } -` diff --git a/src/components/mindset/components/Sidebar/Transcript/index.tsx b/src/components/mindset/components/Sidebar/Transcript/index.tsx index 568d5b23f..c2245e2dd 100644 --- a/src/components/mindset/components/Sidebar/Transcript/index.tsx +++ b/src/components/mindset/components/Sidebar/Transcript/index.tsx @@ -45,7 +45,7 @@ export const Transcript = () => { return () => clearInterval(interval) }, [playerRef, setCurrentTime]) - return ( + return currentTime ? ( Transcript {clips.map((clip) => { @@ -59,7 +59,6 @@ export const Transcript = () => { // Multiply playingTime by 1000 to match millisecond format return ( - {!clip.properties?.transcript && clip?.properties?.text && {clip?.properties?.text}} {clip.properties?.transcript && } ) @@ -68,7 +67,7 @@ export const Transcript = () => { return null })} - ) + ) : null } const Wrapper = styled(Flex)` diff --git a/src/components/mindset/components/Sidebar/index.tsx b/src/components/mindset/components/Sidebar/index.tsx index ea894294d..60af49b0b 100644 --- a/src/components/mindset/components/Sidebar/index.tsx +++ b/src/components/mindset/components/Sidebar/index.tsx @@ -24,7 +24,7 @@ export const SideBar = () => { const Wrapper = styled(Flex)(({ theme }) => ({ position: 'relative', display: 'flex', - padding: '20px', + padding: '33px 20px 20px 20px', background: 'transparent', width: '100%', @@ -45,16 +45,15 @@ const Summary = styled(Text)` ` const EpisodeTitle = styled(Text)` - margin-top: 20px; font-size: 14px; font-weight: 700; line-height: 16.94px; + margin-bottom: 12px; ` const MediaWrapper = styled(Flex)(({ theme }) => ({ width: '100%', - margin: '16px auto', - zIndex: 29, + margin: '0 auto 16px', [theme.breakpoints.up('sm')]: { width: '390px', }, diff --git a/src/components/mindset/components/VideoCard/index.tsx b/src/components/mindset/components/VideoCard/index.tsx index d40c096d6..69c4f4378 100644 --- a/src/components/mindset/components/VideoCard/index.tsx +++ b/src/components/mindset/components/VideoCard/index.tsx @@ -69,7 +69,6 @@ const TextWrapper = styled(Flex)` ` const CardTitle = styled.p` - font-family: Inter; font-size: 16px; font-weight: 500; line-height: 19px; diff --git a/src/network/fetchSourcesData/index.ts b/src/network/fetchSourcesData/index.ts index 9b0b4bb94..1a41c5d0f 100644 --- a/src/network/fetchSourcesData/index.ts +++ b/src/network/fetchSourcesData/index.ts @@ -1,5 +1,6 @@ import { SchemaExtended } from '~/components/ModalsContainer/BlueprintModal/types' import { + FetchDataResponse, FetchEdgesResponse, FetchEdgeTypesResponse, FetchRadarResponse, @@ -10,7 +11,6 @@ import { SubmitErrRes, } from '~/types' import { api } from '../api' -import { ApiResponse } from '~/components/mindset/components/LandingPage' type TradarParams = { skip?: string @@ -180,10 +180,10 @@ export interface UpdateSchemaParams { } } -export const getNodes = async (): Promise => { - const url = `/prediction/graph/search?node_type=['Episode']&&include_properties=true&&includecontent=true` +export const getNodes = async (): Promise => { + const url = `/prediction/graph/search?node_type=['Episode']&include_properties=true&includeContent=true&sort_by=date` - const response = await api.get(url) + const response = await api.get(url) return response }