Skip to content

Commit

Permalink
ref(replay): Refactor replayer override styles into its own file (#76712
Browse files Browse the repository at this point in the history
)

Moves some sentry-specific replayer styles out into their own file.
Separate the styles from the logic so we can refactor replayer logic
easier.
  • Loading branch information
ryan953 committed Aug 29, 2024
1 parent 9d79685 commit ec36348
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 117 deletions.
126 changes: 126 additions & 0 deletions static/app/components/replays/player/styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {css, type Theme} from '@emotion/react';

// Base styles, to make the Replayer instance work
export const baseReplayerCss = css`
.replayer-wrapper {
user-select: none;
}
.replayer-wrapper > .replayer-mouse {
pointer-events: none;
}
.replayer-wrapper > .replayer-mouse-tail {
position: absolute;
pointer-events: none;
}
/* Override default user-agent styles */
.replayer-wrapper > iframe {
border: none;
background: white;
/* Set pointer-events to make it easier to right-click & inspect */
pointer-events: initial !important;
}
`;

// Sentry-specific styles for the player.
// The elements we have to work with are:
// ```css
// div.replayer-wrapper {}
// div.replayer-wrapper > div.replayer-mouse {}
// div.replayer-wrapper > canvas.replayer-mouse-tail {}
// div.replayer-wrapper > iframe {}
// ```
// The mouse-tail is also configured for color/size in `app/components/replays/replayContext.tsx`
export const sentryReplayerCss = (theme: Theme) => css`
.replayer-mouse {
position: absolute;
width: 32px;
height: 32px;
transition:
left 0.05s linear,
top 0.05s linear;
background-size: contain;
background-repeat: no-repeat;
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTkiIHZpZXdCb3g9IjAgMCAxMiAxOSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTZWMEwxMS42IDExLjZINC44TDQuNCAxMS43TDAgMTZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOS4xIDE2LjdMNS41IDE4LjJMMC43OTk5OTkgNy4xTDQuNSA1LjZMOS4xIDE2LjdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNC42NzQ1MSA4LjYxODUxTDIuODMwMzEgOS4zOTI3MUw1LjkyNzExIDE2Ljc2OTVMNy43NzEzMSAxNS45OTUzTDQuNjc0NTEgOC42MTg1MVoiIGZpbGw9ImJsYWNrIi8+CjxwYXRoIGQ9Ik0xIDIuNFYxMy42TDQgMTAuN0w0LjQgMTAuNkg5LjJMMSAyLjRaIiBmaWxsPSJibGFjayIvPgo8L3N2Zz4K');
border-color: transparent;
}
.replayer-mouse:after {
content: '';
display: inline-block;
width: 32px;
height: 32px;
background: ${theme.purple300};
border-radius: 100%;
transform: translate(-50%, -50%);
opacity: 0.3;
}
.replayer-mouse.active:after {
animation: click 0.2s ease-in-out 1;
}
.replayer-mouse.touch-device {
background-image: none;
width: 70px;
height: 70px;
border-radius: 100%;
margin-left: -37px;
margin-top: -37px;
border: 4px solid rgba(73, 80, 246, 0);
transition:
left 0s linear,
top 0s linear,
border-color 0.2s ease-in-out;
}
.replayer-mouse.touch-device.touch-active {
border-color: ${theme.purple200};
transition:
left 0.25s linear,
top 0.25s linear,
border-color 0.2s ease-in-out;
}
.replayer-mouse.touch-device:after {
opacity: 0;
}
.replayer-mouse.touch-device.active:after {
animation: touch-click 0.2s ease-in-out 1;
}
@keyframes click {
0% {
opacity: 0.3;
width: 20px;
height: 20px;
}
50% {
opacity: 0.5;
width: 10px;
height: 10px;
}
}
@keyframes touch-click {
0% {
opacity: 0;
width: 20px;
height: 20px;
}
50% {
opacity: 0.5;
width: 10px;
height: 10px;
}
}
/* Correctly positions the canvas for video replays and shows the purple "mousetails" */
&.video-replayer {
.replayer-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.replayer-wrapper > iframe {
opacity: 0;
}
}
`;
123 changes: 6 additions & 117 deletions static/app/components/replays/replayPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import NegativeSpaceContainer from 'sentry/components/container/negativeSpaceCon
import LoadingIndicator from 'sentry/components/loadingIndicator';
import BufferingOverlay from 'sentry/components/replays/player/bufferingOverlay';
import FastForwardBadge from 'sentry/components/replays/player/fastForwardBadge';
import {
baseReplayerCss,
sentryReplayerCss,
} from 'sentry/components/replays/player/styles';
import {useReplayContext} from 'sentry/components/replays/replayContext';
import {trackAnalytics} from 'sentry/utils/analytics';
import useOrganization from 'sentry/utils/useOrganization';
Expand Down Expand Up @@ -177,127 +181,12 @@ const PositionedLoadingIndicator = styled(LoadingIndicator)`

// Base styles, to make the Replayer instance work
const PlayerRoot = styled(BasePlayerRoot)`
.replayer-wrapper {
user-select: none;
}
.replayer-wrapper > .replayer-mouse {
pointer-events: none;
}
.replayer-wrapper > .replayer-mouse-tail {
position: absolute;
pointer-events: none;
}
/* Override default user-agent styles */
.replayer-wrapper > iframe {
border: none;
background: white;
/* Set pointer-events to make it easier to right-click & inspect */
pointer-events: initial !important;
}
${baseReplayerCss}
`;

// Sentry-specific styles for the player.
// The elements we have to work with are:
// ```css
// div.replayer-wrapper {}
// div.replayer-wrapper > div.replayer-mouse {}
// div.replayer-wrapper > canvas.replayer-mouse-tail {}
// div.replayer-wrapper > iframe {}
// ```
// The mouse-tail is also configured for color/size in `app/components/replays/replayContext.tsx`
const SentryPlayerRoot = styled(PlayerRoot)`
.replayer-mouse {
position: absolute;
width: 32px;
height: 32px;
transition:
left 0.05s linear,
top 0.05s linear;
background-size: contain;
background-repeat: no-repeat;
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iMTkiIHZpZXdCb3g9IjAgMCAxMiAxOSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTZWMEwxMS42IDExLjZINC44TDQuNCAxMS43TDAgMTZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOS4xIDE2LjdMNS41IDE4LjJMMC43OTk5OTkgNy4xTDQuNSA1LjZMOS4xIDE2LjdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNC42NzQ1MSA4LjYxODUxTDIuODMwMzEgOS4zOTI3MUw1LjkyNzExIDE2Ljc2OTVMNy43NzEzMSAxNS45OTUzTDQuNjc0NTEgOC42MTg1MVoiIGZpbGw9ImJsYWNrIi8+CjxwYXRoIGQ9Ik0xIDIuNFYxMy42TDQgMTAuN0w0LjQgMTAuNkg5LjJMMSAyLjRaIiBmaWxsPSJibGFjayIvPgo8L3N2Zz4K');
border-color: transparent;
}
.replayer-mouse:after {
content: '';
display: inline-block;
width: 32px;
height: 32px;
background: ${p => p.theme.purple300};
border-radius: 100%;
transform: translate(-50%, -50%);
opacity: 0.3;
}
.replayer-mouse.active:after {
animation: click 0.2s ease-in-out 1;
}
.replayer-mouse.touch-device {
background-image: none;
width: 70px;
height: 70px;
border-radius: 100%;
margin-left: -37px;
margin-top: -37px;
border: 4px solid rgba(73, 80, 246, 0);
transition:
left 0s linear,
top 0s linear,
border-color 0.2s ease-in-out;
}
.replayer-mouse.touch-device.touch-active {
border-color: ${p => p.theme.purple200};
transition:
left 0.25s linear,
top 0.25s linear,
border-color 0.2s ease-in-out;
}
.replayer-mouse.touch-device:after {
opacity: 0;
}
.replayer-mouse.touch-device.active:after {
animation: touch-click 0.2s ease-in-out 1;
}
@keyframes click {
0% {
opacity: 0.3;
width: 20px;
height: 20px;
}
50% {
opacity: 0.5;
width: 10px;
height: 10px;
}
}
@keyframes touch-click {
0% {
opacity: 0;
width: 20px;
height: 20px;
}
50% {
opacity: 0.5;
width: 10px;
height: 10px;
}
}
/* Correctly positions the canvas for video replays and shows the purple "mousetails" */
&.video-replayer {
.replayer-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.replayer-wrapper > iframe {
opacity: 0;
}
}
${p => sentryReplayerCss(p.theme)}
`;

const Overlay = styled('div')`
Expand Down

0 comments on commit ec36348

Please sign in to comment.