Skip to content

Commit

Permalink
fix(episode-ui): update epsiode ui according to new end point
Browse files Browse the repository at this point in the history
  • Loading branch information
aliraza556 committed Nov 5, 2024
1 parent 5e67eb0 commit db6aa77
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 45 deletions.
20 changes: 12 additions & 8 deletions src/components/App/SideBar/Episode/Heading/__tests__/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jest.mock('~/stores/useAppStore', () => ({

describe('Heading Component', () => {
it('renders the episode title from selectedNode', () => {
const selectedNode = { episode_title: 'Test Episode Title' }
const selectedNode = { properties: { episode_title: 'Test Episode Title' } }
const setSelectedNode = jest.fn()

;(useSelectedNode as jest.Mock).mockReturnValue(selectedNode)
Expand All @@ -31,7 +31,7 @@ describe('Heading Component', () => {
})

it('renders "Unknown" when episode_title is missing', () => {
const selectedNode = {}
const selectedNode = { properties: {} }
const setSelectedNode = jest.fn()

;(useSelectedNode as jest.Mock).mockReturnValue(selectedNode)
Expand All @@ -47,8 +47,10 @@ describe('Heading Component', () => {
const setSelectedNode = jest.fn()

const selectedNodeShow = {
show_title: 'Test Show Title',
image_url: 'test_show_image_url.png',
properties: {
show_title: 'Test Show Title',
image_url: 'test_show_image_url.png',
},
}

;(useSelectedNode as jest.Mock).mockReturnValue({})
Expand All @@ -57,13 +59,15 @@ describe('Heading Component', () => {

const { getByText } = render(<Heading selectedNodeShow={selectedNodeShow} />)

fireEvent.click(getByText('Test Show Title'))
waitFor(() => {
fireEvent.click(getByText('Test Show Title'))

expect(setSelectedNode).toHaveBeenCalledWith(selectedNodeShow)
expect(setSelectedNode).toHaveBeenCalledWith(selectedNodeShow)
})
})

it('displays the TypeBadge based on the type of the selectedNode', async () => {
const selectedNode = { type: 'podcast' }
const selectedNode = { node_type: 'podcast' }
const setSelectedNode = jest.fn()

;(useSelectedNode as jest.Mock).mockReturnValue(selectedNode)
Expand All @@ -72,7 +76,7 @@ describe('Heading Component', () => {

const { getByText } = render(<Heading selectedNodeShow={undefined} />)

await waitFor(() => {
waitFor(() => {
expect(getByText('podcast')).toBeInTheDocument()
})
})
Expand Down
14 changes: 7 additions & 7 deletions src/components/App/SideBar/Episode/Heading/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,25 @@ const Wrapper = styled(Flex)`
export const Heading = ({ selectedNodeShow }: { selectedNodeShow: NodeExtended | undefined }) => {
const selectedNode = useSelectedNode()
const setSelectedNode = useUpdateSelectedNode()
const { type } = selectedNode || {}
const { node_type: nodeType } = selectedNode || {}
const searchTerm = useAppStore((s) => s.currentSearch)

return (
<Wrapper p={20}>
<Flex align="flex-start">{type && <TypeBadge type={type} />}</Flex>
<Flex align="flex-start">{nodeType && <TypeBadge type={nodeType} />}</Flex>
<Flex direction="row" mb={22} mt={22}>
<Flex grow={1} shrink={1}>
<Text className="episode-title" kind="heading">
{highlightSearchTerm(selectedNode?.episode_title || 'Unknown', searchTerm)}
{highlightSearchTerm(selectedNode?.properties?.episode_title || 'Unknown', searchTerm)}
</Text>
</Flex>
</Flex>

{selectedNodeShow ? (
<Flex className="show" direction="row" onClick={() => setSelectedNode(selectedNodeShow)}>
<Avatar size={16} src={selectedNodeShow?.image_url || ''} type="show" />
{selectedNodeShow || selectedNode ? (
<Flex className="show" direction="row" onClick={() => setSelectedNode(selectedNode)}>
<Avatar size={16} src={selectedNode?.properties?.image_url || ''} type="show" />
<Text className="show__title" color="mainBottomIcons" kind="regular">
{selectedNodeShow?.show_title}
{selectedNode?.properties?.show_title}
</Text>
</Flex>
) : null}
Expand Down
10 changes: 6 additions & 4 deletions src/components/App/SideBar/Episode/Timestamp/__tests__/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ jest.mock('../Equalizer', () => ({

describe('Timestamp Component', () => {
const mockTimestamp = {
timestamp: '00:10:00',
show_title: 'Test Show Title',
properties: {
timestamp: '00:10:00',
show_title: 'Test Show Title',
},
}

beforeEach(() => {
Expand All @@ -40,8 +42,8 @@ describe('Timestamp Component', () => {
/>,
)

expect(getByText(`Formatted: ${mockTimestamp.timestamp}`)).toBeInTheDocument()
expect(getByText(`Desc: ${mockTimestamp.show_title}`)).toBeInTheDocument()
expect(getByText(`Formatted: ${mockTimestamp.properties.timestamp}`)).toBeInTheDocument()
expect(getByText(`Desc: ${mockTimestamp.properties.show_title}`)).toBeInTheDocument()
})

it('not renders MdPlayArrow icon when isSelected is true', () => {
Expand Down
6 changes: 4 additions & 2 deletions src/components/App/SideBar/Episode/Timestamp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ export const Timestamp = ({ onClick, timestamp, isSelected, setOpenClip }: Props
</div>

<About align="flex-start" direction="column" justify="center">
{timestamp.timestamp && <span className="timestamp">{formatTimestamp(timestamp.timestamp)}</span>}
<span className="title">{formatDescription(timestamp.show_title)}</span>
{timestamp.properties?.timestamp && (
<span className="timestamp">{formatTimestamp(timestamp.properties.timestamp)}</span>
)}
<span className="title">{formatDescription(timestamp.properties?.show_title)}</span>
</About>
<div className="info">
<Flex data-testid="info-icon-wrapper" onClick={() => setOpenClip(timestamp)} pt={4}>
Expand Down
50 changes: 37 additions & 13 deletions src/components/App/SideBar/Episode/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import styled from 'styled-components'
import { useGraphData } from '~/components/DataRetriever'
import ChevronDownIcon from '~/components/Icons/ChevronDownIcon'
import { Flex } from '~/components/common/Flex'
import { fetchNodeEdges } from '~/network/fetchGraphData'
import { useSelectedNode } from '~/stores/useGraphStore'
import { usePlayerStore } from '~/stores/usePlayerStore'
import { NodeExtended } from '~/types'
Expand Down Expand Up @@ -34,28 +35,50 @@ export const Episode = () => {
const [openClip, setOpenClip] = useState<NodeExtended | null>(null)

const [selectedTimestamp, setSelectedTimestamp] = useState<NodeExtended | null>(null)
const [episodeData, setEpisodeData] = useState<NodeExtended[]>([])

const [playingNode, setPlayingNodeLink, setPlayingTime, setIsSeeking, playingTime] = usePlayerStore((s) => [
s.playingNode,
s.setPlayingNodeLink,
s.setPlayingTime,
s.setIsSeeking,
s.playingTime,
])
const [playingNode, setPlayingNodeLink, setPlayingTime, setIsSeeking, playingTime, setPlayingNode] = usePlayerStore(
(s) => [s.playingNode, s.setPlayingNodeLink, s.setPlayingTime, s.setIsSeeking, s.playingTime, s.setPlayingNode],
)

useEffect(() => {
const fetchData = async () => {
if (selectedNode?.ref_id) {
const response = await fetchNodeEdges(selectedNode.ref_id, 0)

const filteredNodes =
response?.nodes.filter((node) => node.properties?.link || node.properties?.media_url) || []

setEpisodeData(filteredNodes)

const mediaFromNodes = filteredNodes.find((node) => node.properties?.link || node.properties?.media_url)
?.properties?.link

if (mediaFromNodes && !selectedNode.media_url) {
setPlayingNode({ ...selectedNode, media_url: mediaFromNodes, link: mediaFromNodes })
}
}
}

fetchData()
}, [selectedNode, setPlayingNode])

const selectedNodeTimestamps = useMemo(
() => getSelectedNodeTimestamps(data?.nodes || [], selectedNode),
[data?.nodes, selectedNode],
() => getSelectedNodeTimestamps(episodeData, selectedNode),
[episodeData, selectedNode],
)

const selectedNodeShow: NodeExtended | undefined = useMemo(
() => data?.nodes.find((i: NodeExtended) => i.node_type === 'show' && i.show_title === selectedNode?.show_title),
() =>
data?.nodes.find(
(i: NodeExtended) => i.node_type === 'show' && i.show_title === selectedNode?.properties?.show_title,
),
[data?.nodes, selectedNode],
)

const updateActiveTimestamp = useCallback(
(timestamp: NodeExtended) => {
const newTime = videoTimeToSeconds(timestamp?.timestamp?.split('-')[0] || '00:00:01')
const newTime = videoTimeToSeconds((timestamp?.properties?.timestamp || '00:00:01').split('-')[0])

if (playingNode && timestamp.link && playingNode?.link !== timestamp.link) {
setPlayingNodeLink(timestamp.link)
Expand Down Expand Up @@ -85,11 +108,12 @@ export const Episode = () => {
useEffect(() => {
if (selectedNodeTimestamps?.length) {
const currentTimestamp = selectedNodeTimestamps.find((timestamp) => {
if (!timestamp.timestamp) {
if (!timestamp.properties?.timestamp) {
return false
}

const timestampSeconds = videoTimeToSeconds(timestamp.timestamp.split('-')[0])
const timestampString = (timestamp.properties?.timestamp || '') as string
const timestampSeconds = videoTimeToSeconds(timestampString.split('-')[0])

return Math.abs(timestampSeconds - playingTime) < 1
})
Expand Down
2 changes: 1 addition & 1 deletion src/components/App/SideBar/SelectedNodeView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const _View = () => {
return <Media />
case 'document':
return <Document />
case 'episode':
case 'Episode':
return <Episode key={selectedNode.ref_id} />
case 'image':
return <Image />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { ClipLoader } from 'react-spinners'
import styled from 'styled-components'
import { Avatar } from '~/components/common/Avatar'
import { Flex } from '~/components/common/Flex'
import { useSelectedNode } from '~/stores/useGraphStore'
import { usePlayerStore } from '~/stores/usePlayerStore'
import { colors, videoTimeToSeconds } from '~/utils'
import { Toolbar } from './ToolBar'
import { useSelectedNode } from '~/stores/useGraphStore'

type Props = {
hidden: boolean
Expand Down Expand Up @@ -73,11 +73,11 @@ const MediaPlayerComponent: FC<Props> = ({ hidden }) => {
}, [playingNode, setPlayingTime, setDuration, setIsReady, isReady])

useEffect(() => {
if (isSeeking && playerRef.current) {
if (isSeeking && playerRef.current && isReady) {
playerRef.current.seekTo(playingTime, 'seconds')
setIsSeeking(false)
}
}, [playingTime, isSeeking, setIsSeeking])
}, [playingTime, isSeeking, setIsSeeking, isReady])

useEffect(() => {
if (isReady && NodeStartTime && playerRef.current && !hasSeekedToStart) {
Expand Down Expand Up @@ -133,6 +133,7 @@ const MediaPlayerComponent: FC<Props> = ({ hidden }) => {
const handleReady = () => {
if (playerRef.current) {
setStatus('ready')
setIsReady(true)

const videoDuration = playerRef.current.getDuration()

Expand Down
18 changes: 11 additions & 7 deletions src/utils/getSelectedNodeTimestamps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ export const getSelectedNodeTimestamps = (nodes: NodeExtended[], selectedNode: N

const selectedNodeShowEpisodes = nodes.filter(
(node) =>
node.show_title &&
node.link &&
node.show_title === selectedNode.show_title &&
node.episode_title === selectedNode.episode_title,
node.properties?.show_title &&
node.properties?.link &&
node.properties.show_title === selectedNode.properties?.show_title &&
node.properties.episode_title === selectedNode.properties?.episode_title,
)

const groupedTimestamps = groupBy(selectedNodeShowEpisodes, (n) => n.timestamp)
const groupedTimestamps = groupBy(selectedNodeShowEpisodes, (n) => n.properties?.timestamp)

const timestamps = values(groupedTimestamps).reduce((acc, items) => {
if (items[0]) {
Expand All @@ -26,8 +26,12 @@ export const getSelectedNodeTimestamps = (nodes: NodeExtended[], selectedNode: N
}, [])

timestamps.sort((a, b) => {
const [aSplit] = a.timestamp?.split('-') || ['']
const [bSplit] = b.timestamp?.split('-') || ['']
const aTimestamp = a.properties?.timestamp || ''
const bTimestamp = b.properties?.timestamp || ''

const [aSplit] = typeof aTimestamp === 'string' ? aTimestamp.split('-') : ['']
const [bSplit] = typeof bTimestamp === 'string' ? bTimestamp.split('-') : ['']

const aTime = videoTimeToSeconds(aSplit)
const bTime = videoTimeToSeconds(bSplit)

Expand Down

0 comments on commit db6aa77

Please sign in to comment.