Skip to content

Commit

Permalink
fix: seekbar rendering (#26484)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
pauldambra and github-actions[bot] authored Nov 27, 2024
1 parent f6de867 commit 2f03369
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './Seekbar.scss'
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { useEffect, useRef } from 'react'
import React from 'react'

import { RecordingSegment } from '~/types'

Expand All @@ -14,6 +15,45 @@ import { PlayerSeekbarPreview } from './PlayerSeekbarPreview'
import { PlayerSeekbarTicks } from './PlayerSeekbarTicks'
import { seekbarLogic } from './seekbarLogic'

// the seekbar and its children can be accidentally re-rendered as the player ticks
const SeekbarSegment = React.memo(function SeekbarSegmentRaw({
segment,
durationMs,
}: {
segment: RecordingSegment
durationMs: number
}): JSX.Element {
return (
<div
className={clsx(
'PlayerSeekbar__segments__item',
segment.isActive && 'PlayerSeekbar__segments__item--active'
)}
title={!segment.isActive ? 'Inactive period' : 'Active period'}
// eslint-disable-next-line react/forbid-dom-props
style={{
width: `${(100 * segment.durationMs) / durationMs}%`,
}}
/>
)
})

function SeekbarSegments(): JSX.Element {
const { logicProps } = useValues(sessionRecordingPlayerLogic)
const { segments, durationMs } = useValues(sessionRecordingDataLogic(logicProps))
return (
<div className="PlayerSeekbar__segments">
{segments?.map((segment: RecordingSegment) => (
<SeekbarSegment
segment={segment}
durationMs={durationMs}
key={`${segment.startTimestamp}-${segment.endTimestamp}-${segment.windowId}-${segment.kind}`}
/>
))}
</div>
)
}

export function Seekbar(): JSX.Element {
const { sessionRecordingId, logicProps } = useValues(sessionRecordingPlayerLogic)
const { seekToTime } = useActions(sessionRecordingPlayerLogic)
Expand Down Expand Up @@ -48,22 +88,7 @@ export function Seekbar(): JSX.Element {
onMouseDown={handleDown}
onTouchStart={handleDown}
>
<div className="PlayerSeekbar__segments">
{sessionPlayerData.segments?.map((segment: RecordingSegment) => (
<div
key={`${segment.startTimestamp}-${segment.endTimestamp}`}
className={clsx(
'PlayerSeekbar__segments__item',
segment.isActive && 'PlayerSeekbar__segments__item--active'
)}
title={!segment.isActive ? 'Inactive period' : 'Active period'}
// eslint-disable-next-line react/forbid-dom-props
style={{
width: `${(100 * segment.durationMs) / sessionPlayerData.durationMs}%`,
}}
/>
))}
</div>
<SeekbarSegments />

<div
className="PlayerSeekbar__currentbar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ export const seekbarLogic = kea<seekbarLogicType>([
thumbLeftPos: [
-THUMB_OFFSET,
{
setThumbLeftPos: (_, { thumbLeftPos }) => thumbLeftPos,
setThumbLeftPos: (_, { thumbLeftPos }) => {
// we receive this number to many decimal places, so we round it to 1 decimal place
// since otherwise we render dependent components
// thousands of times more than we need to
return parseFloat(thumbLeftPos.toFixed(1))
},
},
],
cursorDiff: [
Expand Down Expand Up @@ -82,7 +87,12 @@ export const seekbarLogic = kea<seekbarLogicType>([
(selectors) => [selectors.sessionPlayerData],
(sessionPlayerData) => {
if (sessionPlayerData?.bufferedToTime && sessionPlayerData?.segments && sessionPlayerData?.durationMs) {
return 100 * (sessionPlayerData?.bufferedToTime / sessionPlayerData.durationMs)
// we calculate this number to many decimal places, so we round it to 1 decimal place
// since otherwise we render dependent components
// thousands of times more than we need to
return parseFloat(
(100 * (sessionPlayerData?.bufferedToTime / sessionPlayerData.durationMs)).toFixed(1)
)
}
return 0
},
Expand Down

0 comments on commit 2f03369

Please sign in to comment.