Skip to content

Commit

Permalink
Merge pull request #2496 from stakwork/feature/timestamps
Browse files Browse the repository at this point in the history
feat: updated timestamps ui
  • Loading branch information
Rassl authored Dec 3, 2024
2 parents b0315fc + 3670a01 commit ebee8b5
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 31 deletions.
9 changes: 3 additions & 6 deletions src/components/mindset/components/MediaPlayer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,18 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => {
if (!isSeeking) {
const currentTime = progress.playedSeconds

setPlayingTime(currentTime)

return

const edge = findCurrentEdge(edges, currentTime)

if (edge) {
setActiveEdge(edge)
} else {
setActiveEdge(null)
}

// find playing link and set it to state
}
}

console.log(handleProgress)

const handleReady = () => {
if (playerRef) {
setStatus('ready')
Expand Down Expand Up @@ -167,6 +163,7 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => {
onError={handleError}
onPause={handlePause}
onPlay={handlePlay}
onProgress={handleProgress}
onReady={handleReady}
playing={isPlaying}
url={mediaUrl || ''}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import clsx from 'clsx'
import { useEffect, useState } from 'react'
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'
Expand Down Expand Up @@ -32,10 +33,14 @@ type TranscriptData = {

export const Viewer = ({ transcriptString }: Props) => {
const [currentTime, setCurrentTime] = useState(0)
const [userScrolling, setUserScrolling] = useState(false)
const { playerRef } = usePlayerStore((s) => s)
const cleaned = transcriptString.replace(/^["']|["']$/g, '')

const transcriptData: TranscriptData[] = JSON.parse(cleaned)
const activeRef = useRef<HTMLDivElement | null>(null)
const wrapperRef = useRef<HTMLDivElement | null>(null)
const scrollTimeout = useRef<NodeJS.Timeout | null>(null)

useEffect(() => {
const interval = setInterval(() => {
Expand All @@ -49,36 +54,74 @@ export const Viewer = ({ transcriptString }: Props) => {
return () => clearInterval(interval)
}, [playerRef, setCurrentTime])

useEffect(() => {
const handleScroll = () => {
setUserScrolling(true)

if (scrollTimeout.current) {
clearTimeout(scrollTimeout.current)
}

// Re-enable automatic scrolling after 1 second of no user scroll
scrollTimeout.current = setTimeout(() => {
setUserScrolling(false)
}, 1000)
}

const wrapper = wrapperRef.current

if (wrapper) {
wrapper.addEventListener('scroll', handleScroll)
}

return () => {
if (wrapper) {
wrapper.removeEventListener('scroll', handleScroll)
}
}
}, [])

useEffect(() => {
if (!userScrolling && activeRef.current) {
activeRef.current.scrollIntoView({
behavior: 'smooth',
block: 'center', // Centers the active paragraph
})
}
}, [currentTime, userScrolling])

return (
<Wrapper>
<Wrapper ref={wrapperRef}>
{transcriptData.map((i) => {
const start = secondsToMediaTime(i.start)
const end = secondsToMediaTime(i.end)

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

return (
<Paragraph key={i.start}>
<Start>
{start}:{end}
</Start>
{i.words.map((word) => {
const isActive = word.start < currentTime && currentTime < word.end

return (
<Word key={`${word.start}`} className={clsx({ active: isActive })}>
{word.word}
</Word>
)
})}
<Paragraph
key={`${i.start}-${i.end}`}
ref={isActive ? activeRef : null}
className={clsx({ active: isActive })}
>
<Start>{start}</Start>
<Words>
<span>{i.text}</span>
</Words>
</Paragraph>
)
})}
</Wrapper>
)
}

const Paragraph = styled.div`
const Paragraph = styled(Flex)`
flex-direction: row;
align-items: flex-start;
font-size: 14px;
word-break: break-word;
padding: 8px 24px;
&.active {
background: ${colors.AI_HIGHLIGHT};
}
`

const Wrapper = styled.div`
Expand All @@ -88,12 +131,19 @@ const Wrapper = styled.div`
padding-right: 4px;
`

const Start = styled.span``
const Start = styled.span`
background: ${colors.lightBlue100};
color: ${colors.lightBlue500};
padding: 2px;
margin-right: 8px;
border-radius: 4px;
`

const Word = styled.span`
const Words = styled.div`
margin: 0 2px;
word-break: break-word;
&.active {
background: ${colors.lightBlue300};
background: ${colors.AI_HIGHLIGHT};
}
`
24 changes: 20 additions & 4 deletions src/components/mindset/components/Sidebar/Transcript/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { Viewer } from './Viewer'

export const Transcript = () => {
const { selectedEpisodeId } = useMindsetStore((s) => s)
const { playingTime, duration } = usePlayerStore((s) => s)
const { playerRef } = usePlayerStore((s) => s)
const [currentTime, setCurrentTime] = useState(0)

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

Expand All @@ -32,6 +33,18 @@ export const Transcript = () => {
}
}, [selectedEpisodeId])

useEffect(() => {
const interval = setInterval(() => {
if (playerRef && setCurrentTime) {
const time = playerRef.getCurrentTime()

setCurrentTime(time)
}
}, 100)

return () => clearInterval(interval)
}, [playerRef, setCurrentTime])

return (
<Wrapper>
<Flex className="heading">Transcript</Flex>
Expand All @@ -40,9 +53,9 @@ export const Transcript = () => {

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

if (start <= playingTime * 1000 && playingTime * 1000 < end) {
if (start <= currentTime * 1000 && currentTime * 1000 < end) {
// Multiply playingTime by 1000 to match millisecond format
return (
<TranscriptWrapper key={clip.ref_id} direction="row">
Expand All @@ -61,7 +74,7 @@ export const Transcript = () => {
const Wrapper = styled(Flex)`
.heading {
font-weight: 700;
font-size: 12px;
font-size: 16px;
margin-bottom: 16px;
}
Expand All @@ -71,9 +84,12 @@ const Wrapper = styled(Flex)`
padding: 24px;
overflow-y: auto;
flex: 1 1 100%;
max-height: 50%;
`

const TranscriptWrapper = styled(Flex)`
flex-wrap: wrap;
flex: 1 1 100%;
margin-left: -24px;
margin-right: -24px;
`

0 comments on commit ebee8b5

Please sign in to comment.