diff --git a/static/app/components/replays/preferences/replayPreferenceDropdown.tsx b/static/app/components/replays/preferences/replayPreferenceDropdown.tsx index ff68b87f371e8c..c5f6299ea755dd 100644 --- a/static/app/components/replays/preferences/replayPreferenceDropdown.tsx +++ b/static/app/components/replays/preferences/replayPreferenceDropdown.tsx @@ -1,7 +1,12 @@ +import styled from '@emotion/styled'; + import {Button} from 'sentry/components/core/button'; import {CompositeSelect} from 'sentry/components/core/compactSelect/composite'; +import {Flex} from 'sentry/components/core/layout'; +import {useReplayContext} from 'sentry/components/replays/replayContext'; import {IconSettings} from 'sentry/icons'; import {t} from 'sentry/locale'; +import formatDuration from 'sentry/utils/duration/formatDuration'; import {useReplayPrefs} from 'sentry/utils/replays/playback/providers/replayPreferencesContext'; import {toTitleCase} from 'sentry/utils/string/toTitleCase'; @@ -17,9 +22,24 @@ export default function ReplayPreferenceDropdown({ isLoading?: boolean; }) { const [prefs, setPrefs] = useReplayPrefs(); + const {isFetching, replay} = useReplayContext(); const SKIP_OPTION_VALUE = 'skip'; + // Calculate adjusted duration for each speed, rounded up to the nearest second. + // Returns in seconds + const calculateAdjustedDuration = (originalDurationMs: number, speed: number) => { + if (speed === 1) { + return originalDurationMs / 1000; + } + + return Math.ceil(originalDurationMs / speed / 1000); + }; + + // Check if we should show duration (data is loaded and duration is available) + const shouldShowDuration = + !isLoading && !isFetching && replay && replay.getDurationMs() > 0; + return ( setPrefs({playbackSpeed: opt.value})} - options={speedOptions.map(option => ({ - label: `${option}x`, - value: option, - }))} + options={speedOptions.map(option => { + const baseLabel = `${option}x`; + + if (shouldShowDuration) { + const adjustedDurationMs = calculateAdjustedDuration( + replay.getDurationMs(), + option + ); + const durationDisplay = formatDuration({ + duration: [adjustedDurationMs, 'sec'], + precision: 'sec', + style: 'h:mm:ss', + }); + return { + label: ( + + {baseLabel} + {durationDisplay} + + ), + value: option, + }; + } + + return { + label: baseLabel, + value: option, + }; + })} /> ); } + +const DurationDisplay = styled('span')` + color: ${p => p.theme.subText}; +`;