Skip to content

Commit 1d04b42

Browse files
authored
feat(replay): Refetch the viewed-by data after an update to it (#69357)
This follows #69232 which removed some optimistic updated that would cause crazy re-rendering. Instead we'll just invalidate (and re-fetch if needed) the `/viewed-by/` endpoint data. This is related to the viewed-by replay project: getsentry/team-replay#19 #64924
1 parent 6965eb0 commit 1d04b42

File tree

7 files changed

+51
-52
lines changed

7 files changed

+51
-52
lines changed

static/app/components/events/eventReplay/replayPreviewPlayer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function ReplayPreviewPlayer({
7979

8080
const {mutate: markAsViewed} = useMarkReplayViewed();
8181
useEffect(() => {
82-
if (replayRecord && !replayRecord.has_viewed && !isFetching && isPlaying) {
82+
if (replayRecord?.id && !replayRecord.has_viewed && !isFetching && isPlaying) {
8383
markAsViewed({projectSlug: replayRecord.project_id, replayId: replayRecord.id});
8484
}
8585
}, [isFetching, isPlaying, markAsViewed, organization, replayRecord]);

static/app/components/replays/header/replayMetaData.tsx

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
import {Fragment, useEffect} from 'react';
1+
import {Fragment} from 'react';
22
import styled from '@emotion/styled';
3-
import * as Sentry from '@sentry/react';
43

5-
import AvatarList from 'sentry/components/avatar/avatarList';
64
import Link from 'sentry/components/links/link';
75
import ErrorCounts from 'sentry/components/replays/header/errorCounts';
86
import HeaderPlaceholder from 'sentry/components/replays/header/headerPlaceholder';
7+
import ReplayViewers from 'sentry/components/replays/header/replayViewers';
98
import {IconCursorArrow} from 'sentry/icons';
109
import {t} from 'sentry/locale';
1110
import {space} from 'sentry/styles/space';
1211
import EventView from 'sentry/utils/discover/eventView';
1312
import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes';
1413
import {TabKey} from 'sentry/utils/replays/hooks/useActiveReplayTab';
15-
import useReplayViewedByData from 'sentry/utils/replays/hooks/useReplayViewedByData';
1614
import {useLocation} from 'sentry/utils/useLocation';
1715
import {useRoutes} from 'sentry/utils/useRoutes';
1816
import type {ReplayError, ReplayRecord} from 'sentry/views/replays/types';
@@ -28,16 +26,6 @@ function ReplayMetaData({replayErrors, replayRecord, showDeadRageClicks = true}:
2826
const routes = useRoutes();
2927
const referrer = getRouteStringFromRoutes(routes);
3028
const eventView = EventView.fromLocation(location);
31-
const viewersResult = useReplayViewedByData({
32-
projectSlug: replayRecord?.project_id,
33-
replayId: replayRecord?.id,
34-
});
35-
36-
useEffect(() => {
37-
if (viewersResult.isError) {
38-
Sentry.captureException(viewersResult.error);
39-
}
40-
});
4129

4230
const breadcrumbTab = {
4331
...location,
@@ -97,10 +85,10 @@ function ReplayMetaData({replayErrors, replayRecord, showDeadRageClicks = true}:
9785
</KeyMetricData>
9886
<KeyMetricLabel>{t('Seen By')}</KeyMetricLabel>
9987
<KeyMetricData>
100-
{viewersResult.isLoading ? (
101-
<HeaderPlaceholder width="55px" height="27px" />
88+
{replayRecord ? (
89+
<ReplayViewers projectId={replayRecord.project_id} replayId={replayRecord.id} />
10290
) : (
103-
<AvatarList avatarSize={25} users={viewersResult.data?.data.viewed_by} />
91+
<HeaderPlaceholder width="55px" height="27px" />
10492
)}
10593
</KeyMetricData>
10694
</KeyMetrics>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import AvatarList from 'sentry/components/avatar/avatarList';
2+
import HeaderPlaceholder from 'sentry/components/replays/header/headerPlaceholder';
3+
import type {User} from 'sentry/types/user';
4+
import {useApiQuery} from 'sentry/utils/queryClient';
5+
import useOrganization from 'sentry/utils/useOrganization';
6+
import useProjects from 'sentry/utils/useProjects';
7+
8+
type TResponseData = {
9+
data: {
10+
viewed_by: User[];
11+
};
12+
};
13+
14+
interface Props {
15+
projectId: string;
16+
replayId: string;
17+
}
18+
19+
export default function ReplayViewers({projectId, replayId}: Props) {
20+
const organization = useOrganization();
21+
22+
const {projects} = useProjects();
23+
const project = projects.find(p => p.id === projectId);
24+
const projectSlug = project?.slug;
25+
const url = `/projects/${organization.slug}/${projectSlug}/replays/${replayId}/viewed-by/`;
26+
27+
const {data, isError, isLoading} = useApiQuery<TResponseData>([url], {
28+
staleTime: 0,
29+
});
30+
31+
return isLoading || isError ? (
32+
<HeaderPlaceholder width="55px" height="27px" />
33+
) : (
34+
<AvatarList avatarSize={25} users={data?.data.viewed_by} />
35+
);
36+
}

static/app/utils/replays/hooks/useFetchReplayList.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export default function useFetchReplayList({
7676
}, [options, organization.slug, queryReferrer]);
7777

7878
const {data, ...result} = useApiQuery<{data: any[]}>(fixedQueryKey, {
79-
staleTime: Infinity,
79+
staleTime: 0,
8080
enabled: true,
8181
});
8282

static/app/utils/replays/hooks/useMarkReplayViewed.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {fetchMutation, useMutation} from 'sentry/utils/queryClient';
1+
import {fetchMutation, useMutation, useQueryClient} from 'sentry/utils/queryClient';
22
import useApi from 'sentry/utils/useApi';
33

44
type TData = unknown;
@@ -13,13 +13,17 @@ export default function useMarkReplayViewed() {
1313
const api = useApi({
1414
persistInFlight: false,
1515
});
16+
const queryClient = useQueryClient();
1617

1718
return useMutation<TData, TError, TVariables, TContext>({
1819
mutationFn: ({projectSlug, replayId}) => {
1920
const url = `/projects/${organization.slug}/${projectSlug}/replays/${replayId}/viewed-by/`;
2021
return fetchMutation(api)(['POST', url]);
2122
},
22-
cacheTime: 0,
23+
onSuccess(_data, {projectSlug, replayId}) {
24+
const url = `/projects/${organization.slug}/${projectSlug}/replays/${replayId}/viewed-by/`;
25+
queryClient.refetchQueries({queryKey: [url]});
26+
},
2327
retry: false,
2428
});
2529
}

static/app/utils/replays/hooks/useReplayViewedByData.tsx

Lines changed: 0 additions & 30 deletions
This file was deleted.

static/app/views/replays/details.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ function ReplayDetails({params: {replaySlug}}: Props) {
7979
replayRecord &&
8080
!replayRecord.has_viewed &&
8181
projectSlug &&
82-
!fetching
82+
!fetching &&
83+
replayId
8384
) {
8485
markAsViewed({projectSlug, replayId});
8586
}

0 commit comments

Comments
 (0)