Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update timestamp #2599

Merged
merged 1 commit into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Paragraph } from './Paragraph'

type Props = {
transcriptString: string
isFirst: boolean
}

type Word = {
Expand All @@ -29,7 +30,7 @@ type TranscriptData = {
words: Word[]
}

export const Viewer = ({ transcriptString }: Props) => {
export const Viewer = ({ transcriptString, isFirst }: Props) => {
const [currentTime, setCurrentTime] = useState(0)
const [userScrolling, setUserScrolling] = useState(false)
const { playerRef } = usePlayerStore((s) => s)
Expand Down Expand Up @@ -90,27 +91,55 @@ export const Viewer = ({ transcriptString }: Props) => {

return (
<Wrapper ref={wrapperRef}>
{transcriptData[0].start > currentTime ? (
<Paragraph active={false} start={secondsToMediaTime(transcriptData[0].start)} text={transcriptData[0].text} />
) : (
<>
{transcriptData.map((i) => {
const start = secondsToMediaTime(i.start)

const isActive = i.start < currentTime && currentTime < i.end

return i.start <= currentTime + 5 ? (
<>
{isFirst ? (
<>
{transcriptData[0].start > currentTime ? (
<Paragraph
key={`${i.start}-${i.end}`}
ref={isActive ? activeRef : null}
active={isActive}
start={start}
text={i.text}
active={false}
start={secondsToMediaTime(transcriptData[0].start)}
text={transcriptData[0].text}
/>
) : null
})}
</>
)}
) : (
<>
{transcriptData.map((i) => {
const start = secondsToMediaTime(i.start)

const isActive = i.start < currentTime && currentTime < i.end

return !isFirst || i.start <= currentTime + 5 ? (
<Paragraph
key={`${i.start}-${i.end}`}
ref={isActive ? activeRef : null}
active={isActive}
start={start}
text={i.text}
/>
) : null
})}
</>
)}
</>
) : (
<>
{transcriptData.map((i) => {
const start = secondsToMediaTime(i.start)

const isActive = i.start < currentTime && currentTime < i.end

return (
<Paragraph
key={`${i.start}-${i.end}`}
ref={isActive ? activeRef : null}
active={isActive}
start={start}
text={i.text}
/>
)
})}
</>
)}
</>
</Wrapper>
)
}
Expand Down
84 changes: 50 additions & 34 deletions src/components/mindset/components/Sidebar/Transcript/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,34 @@ export const Transcript = ({ name }: Props) => {
const { selectedEpisodeId } = useMindsetStore((s) => s)
const { playerRef } = usePlayerStore((s) => s)
const [currentTime, setCurrentTime] = useState(0)
const [activeClip, setActiveClip] = useState<NodeExtended | null>(null)
const [isFirst, setIsFirst] = useState(true)

const [setActiveNode, activeNode, simulation] = useGraphStore((s) => [s.setActiveNode, s.activeNode, s.simulation])

const [clips, setClips] = useState<NodeExtended[]>([])

useEffect(() => {
const init = async () => {
const fetchClips = async () => {
try {
const res = await fetchNodeEdges(selectedEpisodeId, 0, 50, { nodeType: ['Clip'], useSubGraph: false })

if (res?.nodes) {
setClips(res.nodes)
const sortedClips = res.nodes.sort((a, b) => {
const startA = parseTimestamp(a.properties?.timestamp)[0]
const startB = parseTimestamp(b.properties?.timestamp)[0]

return startA - startB // Ascending order
})

setClips(sortedClips)
}
} catch (error) {
console.error(error)
console.error('Failed to fetch clips:', error)
}
}

if (selectedEpisodeId) {
init()
fetchClips()
}
}, [selectedEpisodeId])

Expand All @@ -53,46 +61,55 @@ export const Transcript = ({ name }: Props) => {
}, [playerRef, setCurrentTime])

useEffect(() => {
const activeClip = clips.find((clip) => {
const timestamp: string | undefined = clip?.properties?.timestamp
const calculateActiveClip = () => {
const clip = clips.find((clipNode) => {
const [start, end] = parseTimestamp(clipNode?.properties?.timestamp)

const [start, end] = timestamp
? (timestamp as string).split('-').map(Number) // Directly convert to numbers
: [0, 0]
return start <= currentTime && currentTime < end
})

return start <= currentTime && currentTime < end
})
if ((activeClip && clip?.ref_id === activeClip?.ref_id) || !clip) {
return
}

if (!activeNode || activeClip?.ref_id !== activeNode.ref_id) {
const candidateNode = (simulation?.nodes() || []).find((n: NodeExtended) => n.ref_id === activeClip?.ref_id)
setIsFirst(clip?.ref_id === clips[0]?.ref_id)

setActiveClip(clip || null)
}

if (currentTime) {
calculateActiveClip()
}
}, [currentTime, clips, activeClip])

useEffect(() => {
if (activeClip && (!activeNode || activeClip.ref_id !== activeNode.ref_id)) {
const candidateNode = simulation?.nodes().find((n: NodeExtended) => n.ref_id === activeClip.ref_id)

if (candidateNode?.fx !== undefined) {
setActiveNode(candidateNode)
}
}
}, [activeNode, clips, currentTime, setActiveNode, simulation])
}, [activeClip, activeNode, setActiveNode, simulation])

const parseTimestamp = (timestamp?: string) => {
if (!timestamp) {
return [0, 0]
}

return timestamp.split('-').map(Number)
}

return (
<Wrapper>
<Flex className="heading">{name}</Flex>
{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, 0]

if (start <= currentTime && currentTime < end) {
// Multiply playingTime by 1000 to match millisecond format
return (
<TranscriptWrapper key={clip.ref_id} direction="row">
{clip.properties?.transcript && <Viewer transcriptString={clip.properties?.transcript} />}
</TranscriptWrapper>
)
}

return null
})}
{activeClip ? (
<TranscriptWrapper direction="row">
{activeClip.properties?.transcript && (
<Viewer isFirst={isFirst} transcriptString={activeClip.properties.transcript} />
)}
</TranscriptWrapper>
) : null}
</Wrapper>
)
}
Expand All @@ -103,7 +120,6 @@ const Wrapper = styled(Flex)`
font-size: 16px;
margin-bottom: 16px;
}

color: ${colors.white};
background: ${colors.BG1};
border-radius: 8px;
Expand Down
Loading