Add video playback observability to Sentry (#11111)
This commit is contained in:
@@ -26,12 +26,18 @@ export function VideoEmbedInnerNative({
|
||||
setStatus,
|
||||
setIsLoading,
|
||||
setIsActive,
|
||||
onError,
|
||||
}: {
|
||||
ref: React.Ref<{togglePlayback: () => void}>
|
||||
embed: AppBskyEmbedVideo.View
|
||||
setStatus: (status: 'playing' | 'paused') => void
|
||||
setIsLoading: (isLoading: boolean) => void
|
||||
setIsActive: (isActive: boolean) => void
|
||||
/**
|
||||
* Called with the native error message before the component throws to the
|
||||
* surrounding error boundary.
|
||||
*/
|
||||
onError?: (error: string) => void
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const videoRef = useRef<BlueskyVideoView>(null)
|
||||
@@ -81,6 +87,7 @@ export function VideoEmbedInnerNative({
|
||||
setTimeRemaining(e.nativeEvent.timeRemaining)
|
||||
}}
|
||||
onError={e => {
|
||||
onError?.(e.nativeEvent.error)
|
||||
setError(e.nativeEvent.error)
|
||||
}}
|
||||
ref={videoRef}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {useCallback, useRef, useState} from 'react'
|
||||
import {useCallback, useEffect, useRef, useState} from 'react'
|
||||
import {ActivityIndicator, View} from 'react-native'
|
||||
import {ImageBackground} from 'expo-image'
|
||||
import {type AppBskyEmbedVideo} from '@atproto/api'
|
||||
@@ -6,6 +6,10 @@ import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
|
||||
import {
|
||||
createPlaybackTelemetry,
|
||||
type PlaybackTelemetry,
|
||||
} from '#/lib/media/video/playbackTelemetry'
|
||||
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
|
||||
import {atoms as a, platform} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
@@ -75,6 +79,17 @@ function InnerWrapper({embed}: Props) {
|
||||
const [isActive, setIsActive] = useState(false)
|
||||
const showSpinner = useThrottledValue(isActive && isLoading, 100)
|
||||
|
||||
/*
|
||||
* Created lazily on first activation so videos that are never scrolled into
|
||||
* the active position cost nothing.
|
||||
*/
|
||||
const telemetryRef = useRef<PlaybackTelemetry | null>(null)
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
telemetryRef.current?.deactivated()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const showOverlay =
|
||||
!isActive ||
|
||||
isLoading ||
|
||||
@@ -89,9 +104,33 @@ function InnerWrapper({embed}: Props) {
|
||||
<>
|
||||
<VideoEmbedInnerNative
|
||||
embed={embed}
|
||||
setStatus={setStatus}
|
||||
setIsLoading={setIsLoading}
|
||||
setIsActive={setIsActive}
|
||||
setStatus={s => {
|
||||
setStatus(s)
|
||||
if (s === 'playing') {
|
||||
telemetryRef.current?.playing()
|
||||
}
|
||||
}}
|
||||
setIsLoading={loading => {
|
||||
setIsLoading(loading)
|
||||
if (!loading) {
|
||||
telemetryRef.current?.ready()
|
||||
}
|
||||
}}
|
||||
setIsActive={active => {
|
||||
setIsActive(active)
|
||||
if (active) {
|
||||
telemetryRef.current ??= createPlaybackTelemetry({
|
||||
surface: 'feed',
|
||||
presentation: embed.presentation === 'gif' ? 'gif' : 'video',
|
||||
})
|
||||
telemetryRef.current.activated()
|
||||
} else {
|
||||
telemetryRef.current?.deactivated()
|
||||
}
|
||||
}}
|
||||
onError={error => {
|
||||
telemetryRef.current?.error(error)
|
||||
}}
|
||||
ref={ref}
|
||||
/>
|
||||
<ImageBackground
|
||||
|
||||
Reference in New Issue
Block a user