From 4c3205e3f22c756ad499351fc7e00ac076a71366 Mon Sep 17 00:00:00 2001 From: Ryan Albrecht Date: Wed, 28 Aug 2024 16:03:43 -0700 Subject: [PATCH 1/3] ref(replay): Refactor replayer override styles into its own file --- .../app/components/replays/player/styles.tsx | 126 ++++++++++++++++++ .../app/components/replays/replayPlayer.tsx | 22 +-- 2 files changed, 128 insertions(+), 20 deletions(-) create mode 100644 static/app/components/replays/player/styles.tsx diff --git a/static/app/components/replays/player/styles.tsx b/static/app/components/replays/player/styles.tsx new file mode 100644 index 00000000000000..a19bb907758972 --- /dev/null +++ b/static/app/components/replays/player/styles.tsx @@ -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; + } + } +`; diff --git a/static/app/components/replays/replayPlayer.tsx b/static/app/components/replays/replayPlayer.tsx index b62a9f5e106861..9042a902eaf964 100644 --- a/static/app/components/replays/replayPlayer.tsx +++ b/static/app/components/replays/replayPlayer.tsx @@ -6,6 +6,7 @@ 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} 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'; @@ -177,26 +178,7 @@ 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. From 545a500c219e268253dadabcf8afbc8e64e5fe32 Mon Sep 17 00:00:00 2001 From: Ryan Albrecht Date: Wed, 28 Aug 2024 16:05:41 -0700 Subject: [PATCH 2/3] fix code comment --- .../app/components/replays/replayPlayer.tsx | 103 +----------------- 1 file changed, 5 insertions(+), 98 deletions(-) diff --git a/static/app/components/replays/replayPlayer.tsx b/static/app/components/replays/replayPlayer.tsx index 9042a902eaf964..2a57f018ba5ec6 100644 --- a/static/app/components/replays/replayPlayer.tsx +++ b/static/app/components/replays/replayPlayer.tsx @@ -6,7 +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} from 'sentry/components/replays/player/styles'; +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'; @@ -182,104 +185,8 @@ const PlayerRoot = styled(BasePlayerRoot)` `; // 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; - } - } + ${sentryReplayerCss} `; const Overlay = styled('div')` From 25ff7163709d0b402e74c63d80321bd8a8d590d4 Mon Sep 17 00:00:00 2001 From: Ryan Albrecht Date: Thu, 29 Aug 2024 09:59:52 -0700 Subject: [PATCH 3/3] fix tsc --- static/app/components/replays/replayPlayer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/app/components/replays/replayPlayer.tsx b/static/app/components/replays/replayPlayer.tsx index 2a57f018ba5ec6..28a2d79f034719 100644 --- a/static/app/components/replays/replayPlayer.tsx +++ b/static/app/components/replays/replayPlayer.tsx @@ -186,7 +186,7 @@ const PlayerRoot = styled(BasePlayerRoot)` // Sentry-specific styles for the player. const SentryPlayerRoot = styled(PlayerRoot)` - ${sentryReplayerCss} + ${p => sentryReplayerCss(p.theme)} `; const Overlay = styled('div')`