From 99a48fe0e976d1b1acd8b956cfdaf23e23d5d758 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 27 May 2026 11:04:42 -0500 Subject: [PATCH] Add metrics, clean up callbacks --- src/analytics/metrics/types.ts | 11 ++ .../StandardSiteEmbed/StandardSiteMetaRow.tsx | 14 +- .../Post/Embed/StandardSiteEmbed/index.tsx | 138 ++++++++++++++---- src/components/Post/Embed/index.tsx | 1 + src/view/com/composer/ExternalEmbed.tsx | 1 + 5 files changed, 139 insertions(+), 26 deletions(-) diff --git a/src/analytics/metrics/types.ts b/src/analytics/metrics/types.ts index 6e35ce317d..7c9f1bffb9 100644 --- a/src/analytics/metrics/types.ts +++ b/src/analytics/metrics/types.ts @@ -987,6 +987,17 @@ export type Events = { 'share:press:recentDm': {} 'share:press:embed': {} + 'embed:standardSite:view': {url: string} + 'embed:standardSite:article:press': {url: string} + 'embed:standardSite:article:longPress': {url: string} + 'embed:standardSite:publication:press': {url: string} + 'embed:standardSite:publication:longPress': {url: string} + 'embed:standardSite:publicationCta:press': {url: string} + 'embed:standardSite:publicationCta:longPress': {url: string} + 'embed:standardSite:subscribe:press': {url: string} + 'embed:standardSite:subscribe:longPress': {url: string} + 'embed:standardSite:authorHandle:press': {handle: string} + 'thread:click:showOtherReplies': {} 'thread:click:hideReplyForMe': {} 'thread:click:hideReplyForEveryone': {} diff --git a/src/components/Post/Embed/StandardSiteEmbed/StandardSiteMetaRow.tsx b/src/components/Post/Embed/StandardSiteEmbed/StandardSiteMetaRow.tsx index 1541acfa0c..a36baf114c 100644 --- a/src/components/Post/Embed/StandardSiteEmbed/StandardSiteMetaRow.tsx +++ b/src/components/Post/Embed/StandardSiteEmbed/StandardSiteMetaRow.tsx @@ -16,14 +16,18 @@ import { isStandardSitePublicationUri, } from '#/components/Post/Embed/StandardSiteEmbed/utils' import {Text} from '#/components/Typography' +import {useAnalytics} from '#/analytics' export function StandardSiteMetaRow({ + preview, type = 'document', view, }: { + preview?: boolean type?: 'document' | 'publication' view: AppBskyEmbedExternal.ViewExternal }) { + const ax = useAnalytics() const t = useTheme() const {t: l} = useLingui() const highlightedPublisher = !!matchStandardSitePublisher(view) @@ -77,7 +81,15 @@ export function StandardSiteMetaRow({ + style={[ + metaTextStyle, + preview ? a.pointer_events_none : a.pointer_events_auto, + ]} + onPress={() => { + ax.metric('embed:standardSite:authorHandle:press', { + handle: authorProfile.handle, + }) + }}> @{authorProfile.handle} diff --git a/src/components/Post/Embed/StandardSiteEmbed/index.tsx b/src/components/Post/Embed/StandardSiteEmbed/index.tsx index e5294ef90b..7c84834536 100644 --- a/src/components/Post/Embed/StandardSiteEmbed/index.tsx +++ b/src/components/Post/Embed/StandardSiteEmbed/index.tsx @@ -5,6 +5,7 @@ import {plural} from '@lingui/core/macro' import {useLingui} from '@lingui/react/macro' import {useHaptics} from '#/lib/haptics' +import {useCallOnce} from '#/lib/once' import {shareUrl} from '#/lib/sharing' import {niceDate} from '#/lib/strings/time' import {toNiceDomain} from '#/lib/strings/url-helpers' @@ -22,6 +23,7 @@ import {StandardSiteMetaRow} from '#/components/Post/Embed/StandardSiteEmbed/Sta import {StandardSiteThemeProvider} from '#/components/Post/Embed/StandardSiteEmbed/StandardSiteThemeProvider' import {isStandardSitePublicationEmbed} from '#/components/Post/Embed/StandardSiteEmbed/utils' import {Text} from '#/components/Typography' +import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' export type ThemeColors = { @@ -35,14 +37,20 @@ const PUBLICATION_AVATAR_STYLE = { } export const StandardSiteEmbed = ({ + preview, view, - onOpen, + onEmbedInteractionCallback, style, }: { + /** + * Indicates the card is showing the composer + */ + preview?: boolean view: AppBskyEmbedExternal.ViewExternal - onOpen?: () => void + onEmbedInteractionCallback?: () => void style?: StyleProp }) => { + const ax = useAnalytics() const {t: l, i18n} = useLingui() const t = useTheme() const playHaptic = useHaptics() @@ -76,27 +84,51 @@ export const StandardSiteEmbed = ({ onIn: onInteract, onOut: onInteractOut, } = useInteractionState() - const onPress = () => { playHaptic('Light') - onOpen?.() + onEmbedInteractionCallback?.() + ax.metric('embed:standardSite:article:press', {url: view.uri}) } - const onLongPress = () => { if (view.uri && IS_NATIVE) { playHaptic('Heavy') shareUrl(view.uri) + ax.metric('embed:standardSite:article:longPress', {url: view.uri}) } } + const onPressPublication = () => { + playHaptic('Light') + onEmbedInteractionCallback?.() + ax.metric('embed:standardSite:publication:press', { + url: view.source?.uri || '', + }) + } + const onLongPressPublication = () => { + if (view.source?.uri && IS_NATIVE) { + playHaptic('Heavy') + shareUrl(view.source.uri) + ax.metric('embed:standardSite:publication:longPress', { + url: view.source.uri, + }) + } + } + + useCallOnce(() => { + if (!preview) { + ax.metric('embed:standardSite:view', {url: view.uri}) + } + })() if (isStandardPublication) { return ( ) } @@ -111,6 +143,7 @@ export const StandardSiteEmbed = ({ a.border, t.atoms.bg, interacted ? t.atoms.border_contrast_high : t.atoms.border_contrast_low, + preview && a.pointer_events_none, style, ]}> - + )} @@ -234,11 +267,13 @@ export const StandardSiteEmbed = ({ )} @@ -247,17 +282,21 @@ export const StandardSiteEmbed = ({ } export function PublicationCard({ + preview, view, onPress, onLongPress, themeColors, style, + onEmbedInteractionCallback, }: { + preview?: boolean view: AppBskyEmbedExternal.ViewExternal onPress?: () => void onLongPress?: () => void themeColors: ThemeColors style?: StyleProp + onEmbedInteractionCallback?: () => void }) { const t = useTheme() const {t: l} = useLingui() @@ -330,16 +369,20 @@ export function PublicationCard({ style={[a.text_md, a.font_semi_bold, t.atoms.text]}> {view.source?.title} - + {gtPhone && ( )} @@ -356,10 +399,10 @@ export function PublicationCard({ {!gtPhone && ( )} @@ -369,17 +412,20 @@ export function PublicationCard({ } export function SubscribeButton({ + preview, view, - onPress, - onLongPress, style, + onEmbedInteractionCallback, }: { + preview?: boolean view: AppBskyEmbedExternal.ViewExternal - onPress?: () => void - onLongPress?: () => void style?: StyleProp + onEmbedInteractionCallback?: () => void }) { + const ax = useAnalytics() const {t: l} = useLingui() + const playHaptic = useHaptics() + const highlightedPublisher = matchStandardSitePublisher(view) const cta = highlightedPublisher ? l`Subscribe on ${highlightedPublisher.name}` @@ -396,6 +442,36 @@ export function SubscribeButton({ ? l`View ${publicationTitle}` : l`View publication` + const onPress = () => { + playHaptic('Light') + onEmbedInteractionCallback?.() + if (highlightedPublisher) { + ax.metric('embed:standardSite:subscribe:press', { + url: view.source?.uri || '', + }) + } else { + ax.metric('embed:standardSite:publicationCta:press', { + url: view.source?.uri || '', + }) + } + } + + const onLongPress = () => { + if (view.source?.uri && IS_NATIVE) { + playHaptic('Heavy') + shareUrl(view.source.uri) + if (highlightedPublisher) { + ax.metric('embed:standardSite:subscribe:longPress', { + url: view.source?.uri || '', + }) + } else { + ax.metric('embed:standardSite:publicationCta:longPress', { + url: view.source?.uri || '', + }) + } + } + } + return ( {highlightedPublisher ? ( @@ -470,17 +550,21 @@ function PublicationIcon({ } export function PublicationFooter({ + preview, view, themeColors, onPress, onLongPress, interactedOuter, + onEmbedInteractionCallback, }: { + preview?: boolean view: AppBskyEmbedExternal.ViewExternal themeColors: ThemeColors onPress?: () => void onLongPress?: () => void interactedOuter?: boolean + onEmbedInteractionCallback?: () => void }) { const t = useTheme() const {t: l} = useLingui() @@ -503,8 +587,8 @@ export function PublicationFooter({ a.gap_md, gtPhone && [a.flex_row, a.gap_sm], interactedOuter && t.atoms.bg_contrast_25, - ]} - testID="publication-embed-footer"> + preview && a.pointer_events_none, + ]}> {view.source?.title} - + ) diff --git a/src/components/Post/Embed/index.tsx b/src/components/Post/Embed/index.tsx index 2114904557..054558ad83 100644 --- a/src/components/Post/Embed/index.tsx +++ b/src/components/Post/Embed/index.tsx @@ -104,6 +104,7 @@ function MediaEmbed({ activeStyle={[a.mt_sm]}> diff --git a/src/view/com/composer/ExternalEmbed.tsx b/src/view/com/composer/ExternalEmbed.tsx index ef58054e07..cc7b983c31 100644 --- a/src/view/com/composer/ExternalEmbed.tsx +++ b/src/view/com/composer/ExternalEmbed.tsx @@ -91,6 +91,7 @@ export const ExternalEmbedLink = ({ if (data.view && isStandardSiteEmbed(data.view.external)) { return (