|
@@ -1,21 +1,14 @@
|
|
|
import {useCallback, useEffect, useRef, useState} from 'react';
|
|
|
-import {ClassNames} from '@emotion/react';
|
|
|
import styled from '@emotion/styled';
|
|
|
import {useResizeObserver} from '@react-aria/utils';
|
|
|
|
|
|
-import {Button, LinkButton} from 'sentry/components/button';
|
|
|
import NegativeSpaceContainer from 'sentry/components/container/negativeSpaceContainer';
|
|
|
-import {Hovercard} from 'sentry/components/hovercard';
|
|
|
import LoadingIndicator from 'sentry/components/loadingIndicator';
|
|
|
import BufferingOverlay from 'sentry/components/replays/player/bufferingOverlay';
|
|
|
import FastForwardBadge from 'sentry/components/replays/player/fastForwardBadge';
|
|
|
import {useReplayContext} from 'sentry/components/replays/replayContext';
|
|
|
-import {IconOpen, IconQuestion} from 'sentry/icons';
|
|
|
-import {t} from 'sentry/locale';
|
|
|
-import {space} from 'sentry/styles/space';
|
|
|
import {trackAnalytics} from 'sentry/utils/analytics';
|
|
|
import useOrganization from 'sentry/utils/useOrganization';
|
|
|
-import useIsFullscreen from 'sentry/utils/window/useIsFullscreen';
|
|
|
|
|
|
import PlayerDOMAlert from './playerDOMAlert';
|
|
|
|
|
@@ -79,7 +72,6 @@ function BasePlayerRoot({className, isPreview = false}: Props) {
|
|
|
});
|
|
|
|
|
|
useVideoSizeLogger({videoDimensions, windowDimensions});
|
|
|
- const isFullscreen = useIsFullscreen();
|
|
|
|
|
|
// Create the `rrweb` instance which creates an iframe inside `viewEl`
|
|
|
useEffect(() => initRoot(viewEl.current), [initRoot]);
|
|
@@ -121,80 +113,6 @@ function BasePlayerRoot({className, isPreview = false}: Props) {
|
|
|
}
|
|
|
}, [windowDimensions, videoDimensions]);
|
|
|
|
|
|
- function Resource({
|
|
|
- title,
|
|
|
- subtitle,
|
|
|
- link,
|
|
|
- }: {
|
|
|
- link: string;
|
|
|
- subtitle: string;
|
|
|
- title: string;
|
|
|
- }) {
|
|
|
- const organization = useOrganization();
|
|
|
- return (
|
|
|
- <StyledLinkButton
|
|
|
- icon={<IconOpen />}
|
|
|
- borderless
|
|
|
- external
|
|
|
- href={link}
|
|
|
- onClick={() => {
|
|
|
- trackAnalytics('replay.details-resource-docs-clicked', {
|
|
|
- organization,
|
|
|
- title,
|
|
|
- });
|
|
|
- }}
|
|
|
- >
|
|
|
- <ButtonContent>
|
|
|
- <ButtonTitle>{title}</ButtonTitle>
|
|
|
- <ButtonSubtitle>{subtitle}</ButtonSubtitle>
|
|
|
- </ButtonContent>
|
|
|
- </StyledLinkButton>
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- function ResourceButtons() {
|
|
|
- return (
|
|
|
- <ButtonContainer>
|
|
|
- <Resource
|
|
|
- title={t('General')}
|
|
|
- subtitle={t('Configure sampling rates and recording thresholds')}
|
|
|
- link="https://docs.sentry.io/platforms/javascript/session-replay/configuration/#general-integration-configuration"
|
|
|
- />
|
|
|
- <Resource
|
|
|
- title={t('Element Masking/Blocking')}
|
|
|
- subtitle={t('Unmask text (****) and unblock media (img, svg, video, etc.)')}
|
|
|
- link="https://docs.sentry.io/platforms/javascript/session-replay/privacy/"
|
|
|
- />
|
|
|
- <Resource
|
|
|
- title={t('Network Details')}
|
|
|
- subtitle={t('Capture request and response headers or bodies')}
|
|
|
- link="https://docs.sentry.io/platforms/javascript/session-replay/configuration/#network-details"
|
|
|
- />
|
|
|
- </ButtonContainer>
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- function ResourceCard() {
|
|
|
- return (
|
|
|
- <ResourceCardContainer>
|
|
|
- <ClassNames>
|
|
|
- {({css}) => (
|
|
|
- <Hovercard
|
|
|
- body={<ResourceButtons />}
|
|
|
- bodyClassName={css`
|
|
|
- padding: ${space(1)};
|
|
|
- `}
|
|
|
- header={t('Documentation Resources')}
|
|
|
- position="top-end"
|
|
|
- >
|
|
|
- <Button icon={<IconQuestion />} aria-label={t('replay resources')} />
|
|
|
- </Hovercard>
|
|
|
- )}
|
|
|
- </ClassNames>
|
|
|
- </ResourceCardContainer>
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
return (
|
|
|
<NegativeSpaceContainer ref={windowEl} className="sentry-block">
|
|
|
<div ref={viewEl} className={className} />
|
|
@@ -202,7 +120,6 @@ function BasePlayerRoot({className, isPreview = false}: Props) {
|
|
|
{isBuffering ? <PositionedBuffering /> : null}
|
|
|
{isPreview ? null : <PlayerDOMAlert />}
|
|
|
{isFetching ? <PositionedLoadingIndicator /> : null}
|
|
|
- {!(isFullscreen || isPreview) && <ResourceCard />}
|
|
|
</NegativeSpaceContainer>
|
|
|
);
|
|
|
}
|
|
@@ -336,40 +253,4 @@ const SentryPlayerRoot = styled(PlayerRoot)`
|
|
|
}
|
|
|
`;
|
|
|
|
|
|
-const ResourceCardContainer = styled('div')`
|
|
|
- position: absolute;
|
|
|
- bottom: ${space(1)};
|
|
|
- right: 8px;
|
|
|
-`;
|
|
|
-
|
|
|
-const ButtonContainer = styled('div')`
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- gap: ${space(1)};
|
|
|
- align-items: flex-start;
|
|
|
-`;
|
|
|
-
|
|
|
-const ButtonContent = styled('div')`
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- text-align: left;
|
|
|
- white-space: pre-line;
|
|
|
- gap: ${space(0.25)};
|
|
|
-`;
|
|
|
-
|
|
|
-const ButtonTitle = styled('div')`
|
|
|
- font-weight: normal;
|
|
|
-`;
|
|
|
-
|
|
|
-const ButtonSubtitle = styled('div')`
|
|
|
- color: ${p => p.theme.gray300};
|
|
|
- font-weight: normal;
|
|
|
- font-size: ${p => p.theme.fontSizeSmall};
|
|
|
-`;
|
|
|
-
|
|
|
-const StyledLinkButton = styled(LinkButton)`
|
|
|
- padding: ${space(1)};
|
|
|
- height: auto;
|
|
|
-`;
|
|
|
-
|
|
|
export default SentryPlayerRoot;
|