replayContent.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import styled from '@emotion/styled';
  2. import DateTime from 'sentry/components/dateTime';
  3. import Duration from 'sentry/components/duration';
  4. import Placeholder from 'sentry/components/placeholder';
  5. import {Provider as ReplayContextProvider} from 'sentry/components/replays/replayContext';
  6. import ReplayView from 'sentry/components/replays/replayView';
  7. import {t} from 'sentry/locale';
  8. import space from 'sentry/styles/space';
  9. import useFullscreen from 'sentry/utils/replays/hooks/useFullscreen';
  10. import useReplayData from 'sentry/utils/replays/hooks/useReplayData';
  11. import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
  12. type Props = {
  13. orgSlug: string;
  14. replaySlug: string;
  15. };
  16. function ReplayContent({orgSlug, replaySlug}: Props) {
  17. const {fetching, replay, fetchError} = useReplayData({
  18. orgSlug,
  19. replaySlug,
  20. });
  21. const {ref: fullscreenRef, toggle: toggleFullscreen} = useFullscreen();
  22. if (fetchError) {
  23. throw new Error('Failed to load Replay');
  24. }
  25. const replayRecord = replay?.getReplay();
  26. if (fetching || !replayRecord) {
  27. return (
  28. <StyledPlaceholder
  29. testId="replay-loading-placeholder"
  30. height="400px"
  31. width="100%"
  32. />
  33. );
  34. }
  35. return (
  36. <table className="table key-value">
  37. <tbody>
  38. <tr key="replay">
  39. <td className="key">{t('Replay')}</td>
  40. <td className="value">
  41. <ReplayContextProvider replay={replay} initialTimeOffset={0}>
  42. <PlayerContainer ref={fullscreenRef} data-test-id="player-container">
  43. <ReplayView toggleFullscreen={toggleFullscreen} showAddressBar={false} />
  44. </PlayerContainer>
  45. </ReplayContextProvider>
  46. </td>
  47. </tr>
  48. <tr key="id">
  49. <td className="key">{t('Id')}</td>
  50. <td className="value">
  51. <pre className="val-string" data-test-id="replay-id">
  52. {replayRecord.id}
  53. </pre>
  54. </td>
  55. </tr>
  56. <tr key="url">
  57. <td className="key">{t('URL')}</td>
  58. <td className="value">
  59. <pre className="val-string" data-test-id="replay-url">
  60. {replayRecord.urls[0]}
  61. </pre>
  62. </td>
  63. </tr>
  64. <tr key="timestamp">
  65. <td className="key">{t('Timestamp')}</td>
  66. <td className="value">
  67. <pre className="val-string" data-test-id="replay-timestamp">
  68. <DateTime year seconds utc date={replayRecord.startedAt} />
  69. </pre>
  70. </td>
  71. </tr>
  72. <tr key="duration">
  73. <td className="key">{t('Duration')}</td>
  74. <td className="value">
  75. <pre className="val-string" data-test-id="replay-duration">
  76. <Duration seconds={replayRecord.duration} fixedDigits={0} />
  77. </pre>
  78. </td>
  79. </tr>
  80. </tbody>
  81. </table>
  82. );
  83. }
  84. const PlayerContainer = styled(FluidHeight)`
  85. margin-bottom: ${space(2)};
  86. background: ${p => p.theme.background};
  87. gap: ${space(1)};
  88. `;
  89. const StyledPlaceholder = styled(Placeholder)`
  90. margin-top: ${space(2)};
  91. `;
  92. export default ReplayContent;