-
Notifications
You must be signed in to change notification settings - Fork 591
chore(release): v9.14.0 RC #13822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(release): v9.14.0 RC #13822
Changes from all commits
10fdffe
153457a
242cc96
9fa3fa1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,7 @@ import { NoFallback, withSuspense } from "app/utils/hooks/withSuspense" | |
| import { isDislikeArtworksEnabledFor } from "app/utils/isDislikeArtworksEnabledFor" | ||
| import { useMemoizedRandom } from "app/utils/placeholders" | ||
| import { times } from "lodash" | ||
| import { memo, useEffect, useRef } from "react" | ||
| import { memo, useEffect, useState } from "react" | ||
| import { fetchQuery, graphql, useFragment, useLazyLoadQuery } from "react-relay" | ||
|
|
||
| interface HomeViewSectionArtworksProps extends FlexProps { | ||
|
|
@@ -64,49 +64,59 @@ export const HomeViewSectionArtworks: React.FC<HomeViewSectionArtworksProps> = ( | |
|
|
||
| const isRailInViewport = viewableSections.includes(section.internalID) | ||
|
|
||
| // Ref so the async `complete` callback reads current visibility, not the value at kick-off. | ||
| const isRailInViewportRef = useRef(isRailInViewport) | ||
| isRailInViewportRef.current = isRailInViewport | ||
| // Set when a live refresh completes; cleared once we've re-fired railViewed for it. Lets us fire | ||
| // when the rail is on screen — now, or later when it's scrolled into view. | ||
| const [hasPendingRailViewed, setHasPendingRailViewed] = useState(false) | ||
|
|
||
| const { onViewableItemsChanged, viewabilityConfig, resetTracking } = useItemsImpressionsTracking({ | ||
| // It is important here to tell if the rail is visible or not, because the viewability config | ||
| // default behavior, doesn't take into account the fact that the rail could be not visible | ||
| // on the screen because it's within a scrollable container. | ||
| isInViewport: isRailInViewport && section.trackItemImpressions, | ||
| contextModule, | ||
| }) | ||
| const { onViewableItemsChanged, viewabilityConfig, resetTracking, trackingKey } = | ||
| useItemsImpressionsTracking({ | ||
| // It is important here to tell if the rail is visible or not, because the viewability config | ||
| // default behavior, doesn't take into account the fact that the rail could be not visible | ||
| // on the screen because it's within a scrollable container. | ||
| isInViewport: isRailInViewport && section.trackItemImpressions, | ||
| contextModule, | ||
| }) | ||
|
|
||
| // On a refetch bump, force-fetch this rail. This effect runs per-section, so every live rail | ||
| // (recommended, new works for you, and any future ones in liveSectionIDs) refetches — in view | ||
| // or not — so no live rail goes stale. On complete, reset the impression guard and re-fire | ||
| // railViewed only if the rail is on screen. | ||
| // On a refetch bump, flag that railViewed should re-fire for this refresh (the effect below | ||
| // fires it once the rail is on screen — now or when scrolled to), and force-fetch this rail. This | ||
| // effect runs per-section, so every live rail (recommended, new works for you, and any future | ||
| // ones in liveSectionIDs) refetches — in view or not — so no live rail goes stale. On complete we | ||
| // reset the per-item impression guard so items re-track against the fresh data. | ||
| useEffect(() => { | ||
| if (!isLiveRefreshRail || liveRefetchKey === 0) { | ||
| return | ||
| } | ||
| if (isLiveRefreshRail && liveRefetchKey > 0) { | ||
| setHasPendingRailViewed(true) | ||
|
|
||
| const subscription = fetchQuery<HomeViewSectionArtworksQuery>( | ||
| getRelayEnvironment(), | ||
| homeViewSectionArtworksQuery, | ||
| { id: section.internalID, enableHidingDislikedArtworks }, | ||
| { networkCacheConfig: { force: true } } | ||
| ).subscribe({ | ||
| complete: () => { | ||
| resetTracking() | ||
|
|
||
| if (isRailInViewportRef.current) { | ||
| tracking.viewedSection(contextModule, index) | ||
| } | ||
| }, | ||
| error: (error: Error) => { | ||
| console.error("Failed to refresh live artworks rail", error) | ||
| }, | ||
| }) | ||
| const subscription = fetchQuery<HomeViewSectionArtworksQuery>( | ||
| getRelayEnvironment(), | ||
| homeViewSectionArtworksQuery, | ||
| { id: section.internalID, enableHidingDislikedArtworks }, | ||
| { networkCacheConfig: { force: true } } | ||
| ).subscribe({ | ||
| complete: () => { | ||
| resetTracking() | ||
| }, | ||
| error: (error: Error) => { | ||
| console.error("Failed to refresh live artworks rail", error) | ||
| }, | ||
| }) | ||
|
|
||
| return () => subscription.unsubscribe() | ||
| } | ||
|
|
||
| return () => subscription.unsubscribe() | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, [liveRefetchKey]) | ||
|
|
||
| // Re-fire railViewed after a live refresh, once the rail is on screen. Driven by the reactive | ||
| // `isRailInViewport` (from viewableSections, which updates on scroll), so a rail that was off | ||
| // screen at refresh time still re-fires when it's later scrolled into view. | ||
| useEffect(() => { | ||
| if (hasPendingRailViewed && isRailInViewport) { | ||
| tracking.viewedSection(contextModule, index) | ||
| setHasPendingRailViewed(false) | ||
| } | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, [hasPendingRailViewed, isRailInViewport]) | ||
|
Comment on lines
+112
to
+118
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two things about this effect: 1. Duplicate
Both paths now call 2. |
||
|
|
||
| let artworks = extractNodes(section.artworksConnection) | ||
|
|
||
| if (isDislikeArtworksEnabledFor(contextModule)) { | ||
|
|
@@ -182,6 +192,8 @@ export const HomeViewSectionArtworks: React.FC<HomeViewSectionArtworksProps> = ( | |
| onArtworkPress={handleOnGridArtworkPress} | ||
| trackItemImpressions={section.trackItemImpressions} | ||
| contextModule={contextModule} | ||
| // We are using this key to force a re-render to track item impressions again | ||
| key={trackingKey} | ||
|
Comment on lines
+195
to
+196
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment says "force a re-render", but a changing The useEffect(() => {
trackedGridItems.clear()
}, [trackingKey]) |
||
| /> | ||
| ) : ( | ||
| <ArtworkRail | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,6 +24,7 @@ export const useItemsImpressionsTracking = ({ | |||||||||||||||||||
| // Use different state management for test vs production | ||||||||||||||||||||
| const renderedItems = useSharedValue<Array<TrackableItem>>([]) | ||||||||||||||||||||
| const [testRenderedItems, setTestRenderedItems] = useState<Array<TrackableItem>>([]) | ||||||||||||||||||||
| const [key, setKey] = useState<number>(0) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const trackedItems = useRef<Set<string>>(new Set()).current | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -106,18 +107,20 @@ export const useItemsImpressionsTracking = ({ | |||||||||||||||||||
| runOnJS(trackItems)(currentItems) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| }, | ||||||||||||||||||||
| [enableItemsViewsTracking, isInViewport, contextScreenOwnerType, contextModule] | ||||||||||||||||||||
| [enableItemsViewsTracking, isInViewport, contextScreenOwnerType, contextModule, key] | ||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That means the behaviour this dep buys is untested: |
||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Clears the per-item "already tracked" guard so itemViewed events become | ||||||||||||||||||||
| // eligible to fire again, e.g. after a forced data refresh of the rail. | ||||||||||||||||||||
| const resetTracking = useCallback(() => { | ||||||||||||||||||||
| trackedItems.clear() | ||||||||||||||||||||
| }, [trackedItems]) | ||||||||||||||||||||
| setKey(key + 1) | ||||||||||||||||||||
| }, [trackedItems, key]) | ||||||||||||||||||||
|
Comment on lines
115
to
+118
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| return { | ||||||||||||||||||||
| onViewableItemsChanged, | ||||||||||||||||||||
| viewabilityConfig, | ||||||||||||||||||||
| resetTracking, | ||||||||||||||||||||
| trackingKey: key, | ||||||||||||||||||||
| viewabilityConfig, | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.