Add trendingTopic:seen metric (#11309)
This commit is contained in:
@@ -750,6 +750,10 @@ export type Events = {
|
|||||||
'trendingTopics:hide': {
|
'trendingTopics:hide': {
|
||||||
context: 'settings' | 'sidebar' | 'interstitial' | 'explore:trending'
|
context: 'settings' | 'sidebar' | 'interstitial' | 'explore:trending'
|
||||||
}
|
}
|
||||||
|
'trendingTopic:seen': {
|
||||||
|
context: 'sidebar' | 'interstitial' | 'explore'
|
||||||
|
recId?: string
|
||||||
|
}
|
||||||
'trendingTopic:click': {
|
'trendingTopic:click': {
|
||||||
context: 'sidebar' | 'interstitial' | 'explore'
|
context: 'sidebar' | 'interstitial' | 'explore'
|
||||||
recId?: string
|
recId?: string
|
||||||
|
|||||||
@@ -1,22 +1,28 @@
|
|||||||
import {useMemo} from 'react'
|
import {useEffect, useMemo} from 'react'
|
||||||
import {type AppBskyUnspeccedDefs, type AtUri} from '@atproto/api'
|
import {type AppBskyUnspeccedDefs, type AtUri} from '@atproto/api'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
|
||||||
|
|
||||||
import {PressableScale} from '#/lib/custom-animations/PressableScale'
|
import {PressableScale} from '#/lib/custom-animations/PressableScale'
|
||||||
|
import {useCallOnce} from '#/lib/once'
|
||||||
// import {makeProfileLink} from '#/lib/routes/links'
|
// import {makeProfileLink} from '#/lib/routes/links'
|
||||||
// import {feedUriToHref} from '#/lib/strings/url-helpers'
|
// import {feedUriToHref} from '#/lib/strings/url-helpers'
|
||||||
import {native} from '#/alf'
|
import {native} from '#/alf'
|
||||||
import {Link as InternalLink, type LinkProps} from '#/components/Link'
|
import {Link as InternalLink, type LinkProps} from '#/components/Link'
|
||||||
|
import {type Metrics, useAnalytics} from '#/analytics'
|
||||||
|
|
||||||
export function TrendingTopicLink({
|
export function TrendingTopicLink({
|
||||||
topic: raw,
|
topic: raw,
|
||||||
|
metricContext,
|
||||||
|
recId,
|
||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
}: {
|
}: {
|
||||||
topic: AppBskyUnspeccedDefs.TrendView
|
topic: AppBskyUnspeccedDefs.TrendView
|
||||||
|
metricContext: Metrics['trendingTopic:seen']['context']
|
||||||
|
recId?: string
|
||||||
} & Omit<LinkProps, 'to' | 'label'>) {
|
} & Omit<LinkProps, 'to' | 'label'>) {
|
||||||
const topic = useTopic(raw)
|
const topic = useTopic(raw)
|
||||||
|
useTrendingTopicSeen(metricContext, recId)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InternalLink
|
<InternalLink
|
||||||
@@ -29,6 +35,20 @@ export function TrendingTopicLink({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useTrendingTopicSeen(
|
||||||
|
context: Metrics['trendingTopic:seen']['context'],
|
||||||
|
recId?: string,
|
||||||
|
) {
|
||||||
|
const ax = useAnalytics()
|
||||||
|
const trackSeen = useCallOnce(() => {
|
||||||
|
ax.metric('trendingTopic:seen', {context, recId})
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
trackSeen()
|
||||||
|
}, [trackSeen])
|
||||||
|
}
|
||||||
|
|
||||||
type ParsedTrendingTopic =
|
type ParsedTrendingTopic =
|
||||||
| {
|
| {
|
||||||
type: 'topic' | 'tag' | 'starter-pack' | 'unknown'
|
type: 'topic' | 'tag' | 'starter-pack' | 'unknown'
|
||||||
@@ -48,14 +68,14 @@ type ParsedTrendingTopic =
|
|||||||
export function useTopic(
|
export function useTopic(
|
||||||
raw: AppBskyUnspeccedDefs.TrendView,
|
raw: AppBskyUnspeccedDefs.TrendView,
|
||||||
): ParsedTrendingTopic {
|
): ParsedTrendingTopic {
|
||||||
const {_} = useLingui()
|
const {t: l} = useLingui()
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const {topic: displayName, link} = raw
|
const {topic: displayName, link} = raw
|
||||||
|
|
||||||
if (link.startsWith('/search')) {
|
if (link.startsWith('/search')) {
|
||||||
return {
|
return {
|
||||||
type: 'topic',
|
type: 'topic',
|
||||||
label: _(msg`Browse posts about ${displayName}`),
|
label: l`Browse posts about ${displayName}`,
|
||||||
displayName,
|
displayName,
|
||||||
uri: undefined,
|
uri: undefined,
|
||||||
url: link,
|
url: link,
|
||||||
@@ -63,7 +83,7 @@ export function useTopic(
|
|||||||
} else if (link.startsWith('/hashtag')) {
|
} else if (link.startsWith('/hashtag')) {
|
||||||
return {
|
return {
|
||||||
type: 'tag',
|
type: 'tag',
|
||||||
label: _(msg`Browse posts tagged with ${displayName}`),
|
label: l`Browse posts tagged with ${displayName}`,
|
||||||
displayName,
|
displayName,
|
||||||
// displayName: displayName.replace(/^#/, ''),
|
// displayName: displayName.replace(/^#/, ''),
|
||||||
uri: undefined,
|
uri: undefined,
|
||||||
@@ -72,7 +92,7 @@ export function useTopic(
|
|||||||
} else if (link.startsWith('/starter-pack')) {
|
} else if (link.startsWith('/starter-pack')) {
|
||||||
return {
|
return {
|
||||||
type: 'starter-pack',
|
type: 'starter-pack',
|
||||||
label: _(msg`Browse starter pack ${displayName}`),
|
label: l`Browse starter pack ${displayName}`,
|
||||||
displayName,
|
displayName,
|
||||||
uri: undefined,
|
uri: undefined,
|
||||||
url: link,
|
url: link,
|
||||||
@@ -109,10 +129,10 @@ export function useTopic(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'unknown',
|
type: 'unknown',
|
||||||
label: _(msg`Browse topic ${displayName}`),
|
label: l`Browse topic ${displayName}`,
|
||||||
displayName,
|
displayName,
|
||||||
uri: undefined,
|
uri: undefined,
|
||||||
url: link,
|
url: link,
|
||||||
}
|
}
|
||||||
}, [_, raw])
|
}, [l, raw])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {Trending3_Stroke2_Corner1_Rounded as TrendingIcon} from '#/components/ic
|
|||||||
import {Link} from '#/components/Link'
|
import {Link} from '#/components/Link'
|
||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import {SubtleHover} from '#/components/SubtleHover'
|
import {SubtleHover} from '#/components/SubtleHover'
|
||||||
|
import {useTrendingTopicSeen} from '#/components/TrendingTopics'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
|
|
||||||
@@ -136,9 +137,11 @@ function Inner() {
|
|||||||
key={trend.link}
|
key={trend.link}
|
||||||
trend={trend}
|
trend={trend}
|
||||||
rank={index + 1}
|
rank={index + 1}
|
||||||
|
recId={trending.recId}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
ax.metric('trendingTopic:click', {
|
ax.metric('trendingTopic:click', {
|
||||||
context: 'interstitial',
|
context: 'interstitial',
|
||||||
|
recId: trending.recId,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -163,10 +166,12 @@ function Inner() {
|
|||||||
function TrendRow({
|
function TrendRow({
|
||||||
trend,
|
trend,
|
||||||
rank,
|
rank,
|
||||||
|
recId,
|
||||||
onPress,
|
onPress,
|
||||||
}: ViewStyleProp & {
|
}: ViewStyleProp & {
|
||||||
trend: AppBskyUnspeccedDefs.TrendView
|
trend: AppBskyUnspeccedDefs.TrendView
|
||||||
rank: number
|
rank: number
|
||||||
|
recId?: string
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
onPress?: () => void
|
onPress?: () => void
|
||||||
}) {
|
}) {
|
||||||
@@ -175,6 +180,7 @@ function TrendRow({
|
|||||||
|
|
||||||
const actors = useModerateTrendingActors(trend.actors)
|
const actors = useModerateTrendingActors(trend.actors)
|
||||||
const formattedPostCount = formatCount(i18n, trend.postCount)
|
const formattedPostCount = formatCount(i18n, trend.postCount)
|
||||||
|
useTrendingTopicSeen('interstitial', recId)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {useCallback} from 'react'
|
import {useCallback} from 'react'
|
||||||
import {ScrollView, View} from 'react-native'
|
import {ScrollView, View} from 'react-native'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useTrendingSettings,
|
useTrendingSettings,
|
||||||
@@ -30,7 +29,7 @@ export function TrendingInterstitial() {
|
|||||||
|
|
||||||
export function Inner() {
|
export function Inner() {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
const gutters = useGutters([0, 'base', 0, 'base'])
|
const gutters = useGutters([0, 'base', 0, 'base'])
|
||||||
const trendingPrompt = Prompt.usePromptControl()
|
const trendingPrompt = Prompt.usePromptControl()
|
||||||
@@ -103,6 +102,8 @@ export function Inner() {
|
|||||||
<TrendingTopicLink
|
<TrendingTopicLink
|
||||||
key={topic.link}
|
key={topic.link}
|
||||||
topic={topic}
|
topic={topic}
|
||||||
|
metricContext="interstitial"
|
||||||
|
recId={trending.recId}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
ax.metric('trendingTopic:click', {
|
ax.metric('trendingTopic:click', {
|
||||||
context: 'interstitial',
|
context: 'interstitial',
|
||||||
@@ -122,7 +123,7 @@ export function Inner() {
|
|||||||
</TrendingTopicLink>
|
</TrendingTopicLink>
|
||||||
))}
|
))}
|
||||||
<Button
|
<Button
|
||||||
label={_(msg`Hide trending topics`)}
|
label={l`Hide trending topics`}
|
||||||
size="tiny"
|
size="tiny"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
@@ -138,9 +139,9 @@ export function Inner() {
|
|||||||
|
|
||||||
<Prompt.Basic
|
<Prompt.Basic
|
||||||
control={trendingPrompt}
|
control={trendingPrompt}
|
||||||
title={_(msg`Hide trending topics?`)}
|
title={l`Hide trending topics?`}
|
||||||
description={_(msg`You can update this later from your settings.`)}
|
description={l`You can update this later from your settings.`}
|
||||||
confirmButtonCta={_(msg`Hide`)}
|
confirmButtonCta={l`Hide`}
|
||||||
onConfirm={onConfirmHide}
|
onConfirm={onConfirmHide}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {Link} from '#/components/Link'
|
|||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import {RichText} from '#/components/RichText'
|
import {RichText} from '#/components/RichText'
|
||||||
import {SubtleHover} from '#/components/SubtleHover'
|
import {SubtleHover} from '#/components/SubtleHover'
|
||||||
|
import {useTrendingTopicSeen} from '#/components/TrendingTopics'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import * as ModuleHeader from '../components/ModuleHeader'
|
import * as ModuleHeader from '../components/ModuleHeader'
|
||||||
@@ -71,6 +72,7 @@ function Inner() {
|
|||||||
key={trend.link}
|
key={trend.link}
|
||||||
trend={trend}
|
trend={trend}
|
||||||
rank={index + 1}
|
rank={index + 1}
|
||||||
|
recId={trending.recId}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
ax.metric('trendingTopic:click', {
|
ax.metric('trendingTopic:click', {
|
||||||
context: 'explore',
|
context: 'explore',
|
||||||
@@ -98,11 +100,13 @@ function Inner() {
|
|||||||
export function TrendRow({
|
export function TrendRow({
|
||||||
trend,
|
trend,
|
||||||
rank,
|
rank,
|
||||||
|
recId,
|
||||||
children,
|
children,
|
||||||
onPress,
|
onPress,
|
||||||
}: ViewStyleProp & {
|
}: ViewStyleProp & {
|
||||||
trend: AppBskyUnspeccedDefs.TrendView
|
trend: AppBskyUnspeccedDefs.TrendView
|
||||||
rank: number
|
rank: number
|
||||||
|
recId?: string
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
onPress?: () => void
|
onPress?: () => void
|
||||||
}) {
|
}) {
|
||||||
@@ -112,6 +116,7 @@ export function TrendRow({
|
|||||||
|
|
||||||
const actors = useModerateTrendingActors(trend.actors)
|
const actors = useModerateTrendingActors(trend.actors)
|
||||||
const formattedPostCount = formatCount(i18n, trend.postCount)
|
const formattedPostCount = formatCount(i18n, trend.postCount)
|
||||||
|
useTrendingTopicSeen('explore', recId)
|
||||||
|
|
||||||
const description = useMemo(() => {
|
const description = useMemo(() => {
|
||||||
if (!trend.description) return
|
if (!trend.description) return
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ function Inner() {
|
|||||||
<TrendingTopicLink
|
<TrendingTopicLink
|
||||||
key={topic.link}
|
key={topic.link}
|
||||||
topic={topic}
|
topic={topic}
|
||||||
|
metricContext="sidebar"
|
||||||
|
recId={trending.recId}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
ax.metric('trendingTopic:click', {
|
ax.metric('trendingTopic:click', {
|
||||||
context: 'sidebar',
|
context: 'sidebar',
|
||||||
|
|||||||
Reference in New Issue
Block a user