-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(replay): Let the a11y analysis run at any point as long as replay (
#61012) This deserves a video, but for now here's some screen shots Related to: #55501 https://github.com/getsentry/sentry/assets/187460/a80c6e93-6904-427c-8949-93a41abf6fa6
- Loading branch information
Showing
5 changed files
with
124 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<RawA11yResponse>( | ||
[ | ||
const unixTimestamp = ((startTimestampMs || 0) + currentTime) / 1000; | ||
const {data, ...rest} = useQuery<RawA11yResponse>({ | ||
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}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
static/app/views/replays/detail/accessibility/accessibilityRefetchBanner.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ( | ||
<StyledWell> | ||
<Flex | ||
gap={space(1)} | ||
justify="space-between" | ||
align="center" | ||
wrap="nowrap" | ||
style={{overflow: 'auto'}} | ||
> | ||
<Flex gap={space(1)} wrap="nowrap" style={{whiteSpace: 'nowrap'}}> | ||
{tct('Results as of [lastRuntime]', { | ||
lastRuntime: ( | ||
<StyledTimestampButton | ||
aria-label={t('See in replay')} | ||
onClick={handleClickTimestamp} | ||
startTimestampMs={startTimestampMs} | ||
timestampMs={startTimestampMs + lastOffsetMs} | ||
/> | ||
), | ||
})} | ||
</Flex> | ||
<Button | ||
size="xs" | ||
priority="primary" | ||
onClick={handleClickRefetch} | ||
disabled={currentTime === lastOffsetMs} | ||
> | ||
{isPlaying | ||
? tct('Pause and Run validation for [now]', {now}) | ||
: tct('Run validation for [now]', {now})} | ||
</Button> | ||
</Flex> | ||
</StyledWell> | ||
); | ||
} | ||
|
||
const StyledWell = styled(Well)` | ||
margin-bottom: 0; | ||
border-radius: ${p => p.theme.borderRadiusTop}; | ||
`; | ||
|
||
const StyledTimestampButton = styled(TimestampButton)` | ||
align-self: center; | ||
align-items: center; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters