diff --git a/static/app/utils/replays/hooks/useA11yData.tsx b/static/app/utils/replays/hooks/useA11yData.tsx index 21262409d5fc69..9d02e2a38b98f9 100644 --- a/static/app/utils/replays/hooks/useA11yData.tsx +++ b/static/app/utils/replays/hooks/useA11yData.tsx @@ -1,33 +1,37 @@ import {useMemo} from 'react'; import {useReplayContext} from 'sentry/components/replays/replayContext'; -import {useApiQuery} from 'sentry/utils/queryClient'; +import {useQuery} from 'sentry/utils/queryClient'; import hydrateA11yFrame, {RawA11yResponse} from 'sentry/utils/replays/hydrateA11yFrame'; +import useApi from 'sentry/utils/useApi'; import useOrganization from 'sentry/utils/useOrganization'; import useProjects from 'sentry/utils/useProjects'; export default function useA11yData() { + const api = useApi(); const organization = useOrganization(); - const {replay} = useReplayContext(); + const {currentTime, replay} = useReplayContext(); const {projects} = useProjects(); - const replayRecord = replay?.getReplay(); const startTimestampMs = replayRecord?.started_at.getTime(); const project = projects.find(p => p.id === replayRecord?.project_id); - - const {data, ...rest} = useApiQuery( - [ + const unixTimestamp = ((startTimestampMs || 0) + currentTime) / 1000; + const {data, ...rest} = useQuery({ + queryKey: [ `/projects/${organization.slug}/${project?.slug}/replays/${replayRecord?.id}/accessibility-issues/`, ], - { - staleTime: 0, - enabled: Boolean(project) && Boolean(replayRecord), - } - ); + queryFn: ({queryKey: [url]}) => + api.requestPromise(String(url), { + method: 'GET', + query: {timestamp: unixTimestamp}, + }), + staleTime: 0, + enabled: Boolean(project) && Boolean(replayRecord), + }); const hydrated = useMemo( () => data?.data?.flatMap(record => hydrateA11yFrame(record, startTimestampMs ?? 0)), [data?.data, startTimestampMs] ); - return {data: hydrated, ...rest}; + return {data: hydrated, dataOffsetMs: currentTime, ...rest}; } diff --git a/static/app/views/replays/detail/accessibility/accessibilityHeaderCell.tsx b/static/app/views/replays/detail/accessibility/accessibilityHeaderCell.tsx index db77f1a3b06871..8988a10de83132 100644 --- a/static/app/views/replays/detail/accessibility/accessibilityHeaderCell.tsx +++ b/static/app/views/replays/detail/accessibility/accessibilityHeaderCell.tsx @@ -27,7 +27,6 @@ const COLUMNS: { label: t('Type'), }, {field: 'element', label: t('Element')}, - {field: '', label: ''}, ]; export const COLUMN_COUNT = COLUMNS.length; diff --git a/static/app/views/replays/detail/accessibility/accessibilityRefetchBanner.tsx b/static/app/views/replays/detail/accessibility/accessibilityRefetchBanner.tsx new file mode 100644 index 00000000000000..506407d90631a8 --- /dev/null +++ b/static/app/views/replays/detail/accessibility/accessibilityRefetchBanner.tsx @@ -0,0 +1,81 @@ +import {useCallback, useState} from 'react'; +import styled from '@emotion/styled'; + +import {Button} from 'sentry/components/button'; +import {Flex} from 'sentry/components/profiling/flex'; +import {useReplayContext} from 'sentry/components/replays/replayContext'; +import {showPlayerTime} from 'sentry/components/replays/utils'; +import Well from 'sentry/components/well'; +import {t, tct} from 'sentry/locale'; +import {space} from 'sentry/styles/space'; +import TimestampButton from 'sentry/views/replays/detail/timestampButton'; + +interface Props { + initialOffsetMs: number; + refetch: () => void; +} + +export default function AccessibilityRefetchBanner({initialOffsetMs, refetch}: Props) { + const {currentTime, replay, setCurrentTime, isPlaying, togglePlayPause} = + useReplayContext(); + + const startTimestampMs = replay?.getReplay()?.started_at?.getTime() ?? 0; + const [lastOffsetMs, setLastOffsetMs] = useState(initialOffsetMs); + + const handleClickRefetch = useCallback(() => { + togglePlayPause(false); + setLastOffsetMs(currentTime); + refetch(); + }, [currentTime, refetch, togglePlayPause]); + + const handleClickTimestamp = useCallback(() => { + setCurrentTime(lastOffsetMs); + }, [setCurrentTime, lastOffsetMs]); + + const now = showPlayerTime(startTimestampMs + currentTime, startTimestampMs, false); + + return ( + + + + {tct('Results as of [lastRuntime]', { + lastRuntime: ( + + ), + })} + + + + + ); +} + +const StyledWell = styled(Well)` + margin-bottom: 0; + border-radius: ${p => p.theme.borderRadiusTop}; +`; + +const StyledTimestampButton = styled(TimestampButton)` + align-self: center; + align-items: center; +`; diff --git a/static/app/views/replays/detail/accessibility/accessibilityTableCell.tsx b/static/app/views/replays/detail/accessibility/accessibilityTableCell.tsx index 2d54cc2abf839c..e53394fa02badf 100644 --- a/static/app/views/replays/detail/accessibility/accessibilityTableCell.tsx +++ b/static/app/views/replays/detail/accessibility/accessibilityTableCell.tsx @@ -1,15 +1,13 @@ import {ComponentProps, CSSProperties, forwardRef} from 'react'; import classNames from 'classnames'; -import {Button} from 'sentry/components/button'; import { Cell, CodeHighlightCell, Text, } from 'sentry/components/replays/virtualizedGrid/bodyCell'; import {Tooltip} from 'sentry/components/tooltip'; -import {IconFire, IconInfo, IconPlay, IconWarning} from 'sentry/icons'; -import {t} from 'sentry/locale'; +import {IconFire, IconInfo, IconWarning} from 'sentry/icons'; import type useCrumbHandlers from 'sentry/utils/replays/hooks/useCrumbHandlers'; import {HydratedA11yFrame} from 'sentry/utils/replays/hydrateA11yFrame'; import {Color} from 'sentry/utils/theme'; @@ -44,7 +42,6 @@ const AccessibilityTableCell = forwardRef( currentHoverTime, currentTime, onClickCell, - onClickTimestamp, onMouseEnter, onMouseLeave, rowIndex, @@ -125,20 +122,6 @@ const AccessibilityTableCell = forwardRef( ), - () => ( - -