Browse Source

ref(replay): add placeholder for os/browser area (#72901)

add placeholder for the browser/os icon area near the url bar (the
browser one goes away for mobile replays)

before: 



https://github.com/getsentry/sentry/assets/56095982/0f708aab-3d42-4015-86b6-882eb56e7ca8

after (web):


https://github.com/getsentry/sentry/assets/56095982/b24af686-4093-4cd5-808e-2ce9350d7a00

after (mobile):


https://github.com/getsentry/sentry/assets/56095982/439c269b-1501-4b3f-be91-7cc0bd2c87b1


relates to https://github.com/getsentry/sentry/issues/68109
Michelle Zhang 8 months ago
parent
commit
d79b7bd0b6

+ 4 - 3
static/app/components/replays/replayView.tsx

@@ -17,10 +17,11 @@ import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
 import {CanvasSupportNotice} from './canvasSupportNotice';
 import {CanvasSupportNotice} from './canvasSupportNotice';
 
 
 type Props = {
 type Props = {
+  isLoading: boolean;
   toggleFullscreen: () => void;
   toggleFullscreen: () => void;
 };
 };
 
 
-function ReplayView({toggleFullscreen}: Props) {
+function ReplayView({toggleFullscreen, isLoading}: Props) {
   const isFullscreen = useIsFullscreen();
   const isFullscreen = useIsFullscreen();
   const [isSidebarOpen, setIsSidebarOpen] = useState(true);
   const [isSidebarOpen, setIsSidebarOpen] = useState(true);
   const {isFetching, replay} = useReplayContext();
   const {isFetching, replay} = useReplayContext();
@@ -32,7 +33,7 @@ function ReplayView({toggleFullscreen}: Props) {
         <PlayerContainer>
         <PlayerContainer>
           <ContextContainer>
           <ContextContainer>
             {isVideoReplay ? <ReplayCurrentScreen /> : <ReplayCurrentUrl />}
             {isVideoReplay ? <ReplayCurrentScreen /> : <ReplayCurrentUrl />}
-            <BrowserOSIcons showBrowser={!isVideoReplay} />
+            <BrowserOSIcons showBrowser={!isVideoReplay} isLoading={isLoading} />
             {isFullscreen ? (
             {isFullscreen ? (
               <ReplaySidebarToggleButton
               <ReplaySidebarToggleButton
                 isOpen={isSidebarOpen}
                 isOpen={isSidebarOpen}
@@ -77,7 +78,7 @@ const Panel = styled(FluidHeight)`
 const ContextContainer = styled('div')`
 const ContextContainer = styled('div')`
   display: grid;
   display: grid;
   grid-auto-flow: column;
   grid-auto-flow: column;
-  grid-template-columns: 1fr max-content max-content;
+  grid-template-columns: 1fr max-content;
   align-items: center;
   align-items: center;
   gap: ${space(1)};
   gap: ${space(1)};
 `;
 `;

+ 11 - 2
static/app/views/replays/detail/browserOSIcons.tsx

@@ -1,14 +1,23 @@
 import {Fragment} from 'react';
 import {Fragment} from 'react';
 
 
+import Placeholder from 'sentry/components/placeholder';
 import ContextIcon from 'sentry/components/replays/contextIcon';
 import ContextIcon from 'sentry/components/replays/contextIcon';
 import {useReplayContext} from 'sentry/components/replays/replayContext';
 import {useReplayContext} from 'sentry/components/replays/replayContext';
 import {Tooltip} from 'sentry/components/tooltip';
 import {Tooltip} from 'sentry/components/tooltip';
 
 
-export default function BrowserOSIcons({showBrowser = true}: {showBrowser?: boolean}) {
+export default function BrowserOSIcons({
+  showBrowser = true,
+  isLoading,
+}: {
+  isLoading?: boolean;
+  showBrowser?: boolean;
+}) {
   const {replay} = useReplayContext();
   const {replay} = useReplayContext();
   const replayRecord = replay?.getReplay();
   const replayRecord = replay?.getReplay();
 
 
-  return (
+  return isLoading ? (
+    <Placeholder width="50px" height="32px" />
+  ) : (
     <Fragment>
     <Fragment>
       <Tooltip title={`${replayRecord?.os.name ?? ''} ${replayRecord?.os.version ?? ''}`}>
       <Tooltip title={`${replayRecord?.os.name ?? ''} ${replayRecord?.os.version ?? ''}`}>
         <ContextIcon
         <ContextIcon

+ 3 - 1
static/app/views/replays/detail/layout/index.tsx

@@ -26,7 +26,9 @@ const DIVIDER_SIZE = 16;
 function ReplayLayout({
 function ReplayLayout({
   isVideoReplay = false,
   isVideoReplay = false,
   replayRecord,
   replayRecord,
+  isLoading,
 }: {
 }: {
+  isLoading: boolean;
   replayRecord: ReplayRecord | undefined;
   replayRecord: ReplayRecord | undefined;
   isVideoReplay?: boolean;
   isVideoReplay?: boolean;
 }) {
 }) {
@@ -44,7 +46,7 @@ function ReplayLayout({
   const video = (
   const video = (
     <VideoSection ref={fullscreenRef}>
     <VideoSection ref={fullscreenRef}>
       <ErrorBoundary mini>
       <ErrorBoundary mini>
-        <ReplayView toggleFullscreen={toggleFullscreen} />
+        <ReplayView toggleFullscreen={toggleFullscreen} isLoading={isLoading} />
       </ErrorBoundary>
       </ErrorBoundary>
     </VideoSection>
     </VideoSection>
   );
   );

+ 6 - 2
static/app/views/replays/details.tsx

@@ -102,7 +102,7 @@ function ReplayDetails({params: {replaySlug}}: Props) {
   });
   });
 
 
   const rrwebFrames = replay?.getRRWebFrames();
   const rrwebFrames = replay?.getRRWebFrames();
-  // The replay data takes a while to load in, which causes our `isVideoReplay`
+  // The replay data takes a while to load in, which causes `isVideoReplay`
   // to return an early `false`, which used to cause UI jumping.
   // to return an early `false`, which used to cause UI jumping.
   // One way to check whether it's finished loading is by checking the length
   // One way to check whether it's finished loading is by checking the length
   // of the rrweb frames, which should always be > 2 for any given replay.
   // of the rrweb frames, which should always be > 2 for any given replay.
@@ -199,7 +199,11 @@ function ReplayDetails({params: {replaySlug}}: Props) {
           replayErrors={replayErrors}
           replayErrors={replayErrors}
           isLoading={isLoading}
           isLoading={isLoading}
         >
         >
-          <ReplaysLayout isVideoReplay={isVideoReplay} replayRecord={replayRecord} />
+          <ReplaysLayout
+            isVideoReplay={isVideoReplay}
+            replayRecord={replayRecord}
+            isLoading={isLoading}
+          />
         </Page>
         </Page>
       </ReplayTransactionContext>
       </ReplayTransactionContext>
     </ReplayContextProvider>
     </ReplayContextProvider>