123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- import styled from '@emotion/styled';
- import RangeSlider from 'sentry/components/forms/controls/rangeSlider';
- import SliderAndInputWrapper from 'sentry/components/forms/controls/rangeSlider/sliderAndInputWrapper';
- import * as Progress from 'sentry/components/replays/progress';
- import {useReplayContext} from 'sentry/components/replays/replayContext';
- import {divide} from 'sentry/components/replays/utils';
- import space from 'sentry/styles/space';
- type Props = {
- className?: string;
- };
- function Scrubber({className}: Props) {
- const {currentHoverTime, currentTime, replay, setCurrentTime} = useReplayContext();
- const durationMs = replay?.getDurationMs();
- const percentComplete = divide(currentTime, durationMs);
- const hoverPlace = divide(currentHoverTime || 0, durationMs);
- return (
- <Wrapper className={className}>
- <Meter>
- {currentHoverTime ? <MouseTrackingValue percent={hoverPlace} /> : null}
- <PlaybackTimeValue percent={percentComplete} />
- </Meter>
- <RangeWrapper>
- <Range
- name="replay-timeline"
- min={0}
- max={durationMs}
- value={Math.round(currentTime)}
- onChange={value => setCurrentTime(value || 0)}
- showLabel={false}
- />
- </RangeWrapper>
- </Wrapper>
- );
- }
- const Meter = styled(Progress.Meter)`
- background: ${p => p.theme.gray200};
- `;
- const RangeWrapper = styled('div')`
- overflow: hidden;
- width: 100%;
- `;
- const Range = styled(RangeSlider)`
- input {
- cursor: pointer;
- opacity: 0;
- height: 100%;
- &::-webkit-slider-thumb {
- height: 0px;
- width: 0px;
- }
- &::-moz-range-thumb {
- height: 0px;
- width: 0px;
- }
- &::-ms-thumb {
- height: 0px;
- width: 0px;
- }
- }
- `;
- // Need the named value so we can target it separatly from PlaybackTimeValue
- const PlaybackTimeValue = styled(Progress.Value)``;
- const MouseTrackingValue = styled(Progress.Value)``;
- const Wrapper = styled('div')`
- position: relative;
- width: 100%;
- & > * {
- position: absolute;
- top: 0;
- left: 0;
- }
- `;
- export const TimelineScrubber = styled(Scrubber)`
- height: 100%;
- ${Meter} {
- background: transparent;
- }
- ${RangeWrapper},
- ${Range},
- ${SliderAndInputWrapper} {
- height: 100%;
- }
- ${PlaybackTimeValue} {
- background: ${p => p.theme.purple100};
- border-top-left-radius: 3px;
- border-bottom-left-radius: 3px;
- }
- /**
- * Draw lines so users can see the currenTime & their mouse position
- * "----|----|--------------------- duration = 1:00"
- * ^ ^
- * | PlaybackTimeValue @ 20s
- * MouseTrackingValue @ 10s
- */
- ${PlaybackTimeValue},
- ${MouseTrackingValue} {
- border-right: ${space(0.25)} solid ${p => p.theme.purple300};
- }
- `;
- export const PlayerScrubber = styled(Scrubber)`
- height: ${space(0.5)};
- :hover {
- margin-block: -${space(0.25)};
- height: ${space(1)};
- }
- ${Meter} {
- border-radius: ${p => p.theme.borderRadiusBottom};
- }
- ${RangeWrapper} {
- height: ${space(0.5)};
- }
- :hover ${RangeWrapper} {
- height: ${space(0.75)};
- }
- ${PlaybackTimeValue} {
- background: ${p => p.theme.purple200};
- border-bottom-left-radius: ${p => p.theme.borderRadius};
- }
- /**
- * Draw the circle (appears on hover) to mark the currentTime of the video
- * "---------o-------------------- duration = 1:00"
- * ^
- * PlaybackTimeValue @ 20s
- */
- ${PlaybackTimeValue}:after {
- content: '';
- display: block;
- width: ${space(2)};
- height: ${space(2)}; /* equal to width */
- z-index: ${p => p.theme.zIndex.initial};
- pointer-events: none;
- background: ${p => p.theme.purple300};
- box-sizing: content-box;
- border-radius: ${space(2)}; /* greater than or equal to width */
- border: solid ${p => p.theme.white};
- border-width: ${space(0.5)};
- position: absolute;
- top: -${space(1)}; /* Half the width */
- right: -${space(1.5)}; /* Half of (width + borderWidth) */
- opacity: 0;
- transition: opacity 0.1s ease;
- }
- :hover ${PlaybackTimeValue}:after {
- opacity: 1;
- }
- /*
- * Draw a square so users can see their mouse position when it is left or right of the currentTime
- * "----□----o--------------------- duration = 1:00"
- * ^ ^
- * | PlaybackTimeValue @ 20s
- * MouseTrackingValue @ 10s
- */
- ${MouseTrackingValue}:after {
- content: '';
- display: block;
- width: ${space(0.5)};
- height: ${space(1.5)};
- pointer-events: none;
- background: ${p => p.theme.purple200};
- box-sizing: content-box;
- position: absolute;
- top: -${space(0.5)};
- right: -1px;
- }
- :hover ${MouseTrackingValue}:after {
- height: ${space(2)};
- top: -${space(0.5)};
- }
- `;
|