mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-13 20:27:01 +00:00
wip try to encapsulate captureEvent calls in telemetry
This commit is contained in:
@@ -1,5 +1,21 @@
|
||||
import { getPosthog } from './utils'
|
||||
|
||||
export const captureEvent = (
|
||||
event: string,
|
||||
props?: Record<string, unknown>
|
||||
) => {
|
||||
void getPosthog()
|
||||
.then((ph) => {
|
||||
ph.capture(event, props)
|
||||
})
|
||||
.catch(() => {
|
||||
/* telemetry must never break the app */
|
||||
})
|
||||
if (import.meta.env.DEV) {
|
||||
console.warn(`[telemetry] ${event}`, props)
|
||||
}
|
||||
}
|
||||
|
||||
export type LogCode =
|
||||
// media
|
||||
| 'join_preview_failure'
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
notifyRecordingSaveInProgress,
|
||||
useNotifyParticipants,
|
||||
} from '@/features/notifications'
|
||||
import posthog from 'posthog-js'
|
||||
import { useConfig } from '@/api/useConfig'
|
||||
import { NoAccessView } from './NoAccessView'
|
||||
import { ControlsButton } from './ControlsButton'
|
||||
@@ -29,7 +28,7 @@ import { useSidePanel } from '@/features/rooms/livekit/hooks/useSidePanel'
|
||||
import { useIsAdminOrOwner } from '@/features/rooms/livekit/hooks/useIsAdminOrOwner'
|
||||
import { FeatureFlags } from '@/features/analytics/enums'
|
||||
import { LimitDescription } from './LimitDescription'
|
||||
import { reportError } from '@/features/analytics/telemetry'
|
||||
import { captureEvent, reportError } from '@/features/analytics/telemetry'
|
||||
|
||||
export const ScreenRecordingSidePanel = () => {
|
||||
const { data } = useConfig()
|
||||
@@ -64,7 +63,7 @@ export const ScreenRecordingSidePanel = () => {
|
||||
await notifyParticipants({
|
||||
type: NotificationType.ScreenRecordingRequested,
|
||||
})
|
||||
posthog.capture('screen-recording-requested', {})
|
||||
captureEvent('screen-recording-requested', {})
|
||||
}
|
||||
|
||||
const handleScreenRecording = async () => {
|
||||
@@ -101,7 +100,7 @@ export const ScreenRecordingSidePanel = () => {
|
||||
await notifyParticipants({
|
||||
type: NotificationType.ScreenRecordingStarted,
|
||||
})
|
||||
posthog.capture('screen-recording-started', {
|
||||
captureEvent('screen-recording-started', {
|
||||
includeTranscript: includeTranscript,
|
||||
language: selectedLanguageKey,
|
||||
})
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
useNotifyParticipants,
|
||||
notifyRecordingSaveInProgress,
|
||||
} from '@/features/notifications'
|
||||
import posthog from 'posthog-js'
|
||||
import { useConfig } from '@/api/useConfig'
|
||||
import { VStack } from '@/styled-system/jsx'
|
||||
import { Checkbox } from '@/primitives/Checkbox.tsx'
|
||||
@@ -35,7 +34,7 @@ import { useSidePanel } from '@/features/rooms/livekit/hooks/useSidePanel'
|
||||
import { useIsAdminOrOwner } from '@/features/rooms/livekit/hooks/useIsAdminOrOwner'
|
||||
import { LimitDescription } from './LimitDescription'
|
||||
import { openSettingsDialog } from '@/stores/settings'
|
||||
import { reportError } from '@/features/analytics/telemetry'
|
||||
import { captureEvent, reportError } from '@/features/analytics/telemetry'
|
||||
|
||||
export const TranscriptSidePanel = () => {
|
||||
const { data } = useConfig()
|
||||
@@ -77,7 +76,7 @@ export const TranscriptSidePanel = () => {
|
||||
await notifyParticipants({
|
||||
type: NotificationType.TranscriptionRequested,
|
||||
})
|
||||
posthog.capture('transcript-requested', {})
|
||||
captureEvent('transcript-requested', {})
|
||||
}
|
||||
|
||||
const handleTranscript = async () => {
|
||||
@@ -122,7 +121,7 @@ export const TranscriptSidePanel = () => {
|
||||
await notifyParticipants({
|
||||
type: NotificationType.TranscriptionStarted,
|
||||
})
|
||||
posthog.capture('transcript-started', {
|
||||
captureEvent('transcript-started', {
|
||||
includeScreenRecording: includeScreenRecording,
|
||||
language: selectedLanguageKey,
|
||||
})
|
||||
|
||||
@@ -26,8 +26,7 @@ import { css } from '@/styled-system/css'
|
||||
import { BackgroundProcessorFactory } from '../livekit/components/blur'
|
||||
import { LocalUserChoices } from '@/stores/userChoices'
|
||||
import { MediaDeviceErrorAlert } from './MediaDeviceErrorAlert'
|
||||
import { reportError } from '@/features/analytics/telemetry'
|
||||
import { usePostHog } from 'posthog-js/react'
|
||||
import { captureEvent, reportError } from '@/features/analytics/telemetry'
|
||||
import { useConfig } from '@/api/useConfig'
|
||||
import { isFireFox } from '@/utils/livekit'
|
||||
import { useIsMobile } from '@/utils/useIsMobile'
|
||||
@@ -48,7 +47,6 @@ export const Conference = ({
|
||||
mode?: 'join' | 'create'
|
||||
initialRoomData?: ApiRoom
|
||||
}) => {
|
||||
const posthog = usePostHog()
|
||||
const { data: apiConfig } = useConfig()
|
||||
|
||||
const { userChoices: userConfig } = usePersistentUserChoices() as {
|
||||
@@ -58,8 +56,8 @@ export const Conference = ({
|
||||
const { username } = useSnapshot(userStore)
|
||||
|
||||
useEffect(() => {
|
||||
posthog.capture('visit-room', { slug: roomId })
|
||||
}, [roomId, posthog])
|
||||
captureEvent('visit-room', { slug: roomId })
|
||||
}, [roomId])
|
||||
const fetchKey = [keys.room, roomId]
|
||||
|
||||
const [isConnectionWarmedUp, setIsConnectionWarmedUp] = useState(false)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { Button, H, Input, Text, TextArea } from '@/primitives'
|
||||
import { Button, H, Text, TextArea } from '@/primitives'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { cva } from '@/styled-system/css'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { styled, VStack } from '@/styled-system/jsx'
|
||||
import { usePostHog } from 'posthog-js/react'
|
||||
import type { PostHog } from 'posthog-js'
|
||||
import { Button as RACButton } from 'react-aria-components'
|
||||
import { useIsAnalyticsEnabled } from '@/features/analytics/hooks/useIsAnalyticsEnabled'
|
||||
import type { CandidateInfo } from '@/stores/connectionObserver'
|
||||
import { captureEvent } from '@/features/analytics/telemetry'
|
||||
|
||||
const Card = styled('div', {
|
||||
base: {
|
||||
@@ -72,11 +71,9 @@ const labelRecipe = cva({
|
||||
})
|
||||
|
||||
const OpenFeedback = ({
|
||||
posthog,
|
||||
onNext,
|
||||
metadata,
|
||||
}: {
|
||||
posthog: PostHog
|
||||
onNext: () => void
|
||||
metadata?: Record<string, unknown>
|
||||
}) => {
|
||||
@@ -90,7 +87,7 @@ const OpenFeedback = ({
|
||||
|
||||
const onSubmit = () => {
|
||||
try {
|
||||
posthog.capture('open-feedback', {
|
||||
captureEvent('open-feedback', {
|
||||
feedback,
|
||||
...metadata,
|
||||
})
|
||||
@@ -141,12 +138,10 @@ const OpenFeedback = ({
|
||||
}
|
||||
|
||||
const RateQuality = ({
|
||||
posthog,
|
||||
onNext,
|
||||
metadata,
|
||||
maxRating = 5,
|
||||
}: {
|
||||
posthog: PostHog
|
||||
onNext: () => void
|
||||
metadata?: Record<string, unknown>
|
||||
maxRating?: number
|
||||
@@ -160,7 +155,7 @@ const RateQuality = ({
|
||||
|
||||
const onSubmit = () => {
|
||||
try {
|
||||
posthog.capture('quality-rating', {
|
||||
captureEvent('quality-rating', {
|
||||
rating: selectedRating,
|
||||
...metadata,
|
||||
})
|
||||
@@ -243,67 +238,6 @@ const ConfirmationMessage = ({ onNext }: { onNext: () => void }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const AuthenticationMessage = ({
|
||||
onNext,
|
||||
posthog,
|
||||
}: {
|
||||
onNext: () => void
|
||||
posthog: PostHog
|
||||
}) => {
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'authenticationMessage' })
|
||||
|
||||
const [email, setEmail] = useState('')
|
||||
|
||||
const onSubmit = () => {
|
||||
posthog.people.set({ unsafe_email: email })
|
||||
onNext()
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
style={{
|
||||
maxWidth: '380px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<H lvl={3}>{t('heading')}</H>
|
||||
<Input
|
||||
id="emailInput"
|
||||
name="email"
|
||||
placeholder={t('placeholder')}
|
||||
required
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
style={{
|
||||
marginBottom: '1rem',
|
||||
}}
|
||||
/>
|
||||
<VStack gap="0.5">
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
fullWidth
|
||||
isDisabled={!email}
|
||||
onPress={onSubmit}
|
||||
>
|
||||
{t('submit')}
|
||||
</Button>
|
||||
<Button
|
||||
invisible
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
fullWidth
|
||||
onPress={onNext}
|
||||
>
|
||||
{t('ignore')}
|
||||
</Button>
|
||||
</VStack>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
type RatingMetadata = {
|
||||
room_id?: string
|
||||
pc_publisher?: CandidateInfo
|
||||
@@ -318,12 +252,6 @@ export const Rating = ({
|
||||
metadata: RatingMetadata
|
||||
}) => {
|
||||
const isAnalyticsEnabled = useIsAnalyticsEnabled()
|
||||
const posthog = usePostHog()
|
||||
|
||||
const isUserAnonymous = useMemo(() => {
|
||||
return posthog.get_property('$user_state') == 'anonymous'
|
||||
}, [posthog])
|
||||
|
||||
const [step, setStep] = useState(0)
|
||||
|
||||
const sessionId = useMemo(() => crypto.randomUUID(), [])
|
||||
@@ -339,37 +267,14 @@ export const Rating = ({
|
||||
if (!isAnalyticsEnabled) return
|
||||
|
||||
if (step == 0) {
|
||||
return (
|
||||
<RateQuality
|
||||
posthog={posthog}
|
||||
onNext={() => setStep(step + 1)}
|
||||
metadata={metadata}
|
||||
/>
|
||||
)
|
||||
return <RateQuality onNext={() => setStep(step + 1)} metadata={metadata} />
|
||||
}
|
||||
|
||||
if (step == 1) {
|
||||
return (
|
||||
<OpenFeedback
|
||||
posthog={posthog}
|
||||
onNext={() => setStep(step + 1)}
|
||||
metadata={metadata}
|
||||
/>
|
||||
)
|
||||
return <OpenFeedback onNext={() => setStep(step + 1)} metadata={metadata} />
|
||||
}
|
||||
|
||||
if (step == 2) {
|
||||
return isUserAnonymous ? (
|
||||
<AuthenticationMessage
|
||||
posthog={posthog}
|
||||
onNext={() => setStep(step + 1)}
|
||||
/>
|
||||
) : (
|
||||
<ConfirmationMessage onNext={() => setStep(0)} />
|
||||
)
|
||||
}
|
||||
|
||||
if (step == 3) {
|
||||
return <ConfirmationMessage onNext={() => setStep(0)} />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import { DisconnectReason, RoomEvent } from 'livekit-client'
|
||||
import { userPreferencesStore } from '@/stores/userPreferences'
|
||||
import { connectionObserverStore } from '@/stores/connectionObserver'
|
||||
|
||||
import posthog from 'posthog-js'
|
||||
import { useFeatureFlagEnabled } from 'posthog-js/react'
|
||||
import { isMobileBrowser } from '@livekit/components-core'
|
||||
import { FeatureFlags } from '@/features/analytics/enums'
|
||||
import { captureEvent } from '@/features/analytics/telemetry'
|
||||
|
||||
const CANDIDATE_POLL_INTERVAL_MS = 5000
|
||||
|
||||
@@ -182,23 +182,23 @@ export const ConnectionObserver = () => {
|
||||
// total session duration from first connect to final disconnect.
|
||||
if (connectionStartTimeRef.current != null) return
|
||||
connectionStartTimeRef.current = Date.now()
|
||||
posthog.capture('connection-event')
|
||||
captureEvent('connection-event')
|
||||
}
|
||||
|
||||
const handleReconnect = () => {
|
||||
posthog.capture('reconnect-event')
|
||||
captureEvent('reconnect-event')
|
||||
}
|
||||
|
||||
const handleReconnected = () => {
|
||||
posthog.capture('reconnected-event')
|
||||
captureEvent('reconnected-event')
|
||||
}
|
||||
|
||||
const handleSignalingConnect = () => {
|
||||
posthog.capture('signaling-connect-event')
|
||||
captureEvent('signaling-connect-event')
|
||||
}
|
||||
|
||||
const handleSignalingReconnect = () => {
|
||||
posthog.capture('signaling-reconnect-event')
|
||||
captureEvent('signaling-reconnect-event')
|
||||
}
|
||||
|
||||
const handleDisconnect = (
|
||||
@@ -206,7 +206,7 @@ export const ConnectionObserver = () => {
|
||||
) => {
|
||||
const connectionEndTime = Date.now()
|
||||
|
||||
posthog.capture('disconnect-event', {
|
||||
captureEvent('disconnect-event', {
|
||||
// Calculate total session duration from first connection to final disconnect
|
||||
// This duration is sensitive to refreshing the page.
|
||||
sessionDuration: connectionStartTimeRef.current
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import type { ProcessorOptions, Track } from 'livekit-client'
|
||||
import posthog from 'posthog-js'
|
||||
import {
|
||||
FilesetResolver,
|
||||
ImageSegmenter,
|
||||
@@ -18,6 +17,7 @@ import {
|
||||
type ProcessorType,
|
||||
MEDIAPIPE_PATH_WASM,
|
||||
} from '.'
|
||||
import { captureEvent } from '@/features/analytics/telemetry.ts'
|
||||
|
||||
const PROCESSING_WIDTH = 256
|
||||
const PROCESSING_HEIGHT = 144
|
||||
@@ -100,7 +100,7 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface {
|
||||
await this.initSegmenter()
|
||||
this._initWorker()
|
||||
|
||||
posthog.capture('firefox-blurring-init')
|
||||
captureEvent('firefox-blurring-init', {})
|
||||
}
|
||||
|
||||
_initVirtualBackgroundImage() {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { ProcessorOptions, Track, TrackProcessor } from 'livekit-client'
|
||||
import posthog from 'posthog-js'
|
||||
import {
|
||||
FilesetResolver,
|
||||
FaceLandmarker,
|
||||
@@ -16,6 +15,7 @@ import {
|
||||
ProcessorType,
|
||||
MEDIAPIPE_PATH_WASM,
|
||||
} from '.'
|
||||
import { captureEvent } from '@/features/analytics/telemetry'
|
||||
|
||||
const PROCESSING_WIDTH = 256 * 3
|
||||
const PROCESSING_HEIGHT = 144 * 3
|
||||
@@ -101,7 +101,7 @@ export class FaceLandmarksProcessor implements TrackProcessor<Track.Kind> {
|
||||
await this.initFaceLandmarker()
|
||||
this._initWorker()
|
||||
|
||||
posthog.capture('face-landmarks-init')
|
||||
captureEvent('face-landmarks-init', {})
|
||||
}
|
||||
|
||||
_initWorker() {
|
||||
|
||||
@@ -11,7 +11,6 @@ import { useTranslation } from 'react-i18next'
|
||||
import { SoundTester } from '@/components/SoundTester'
|
||||
import { ActiveSpeaker } from '@/features/rooms/components/ActiveSpeaker'
|
||||
import { useNoiseReductionAvailable } from '@/features/rooms/livekit/hooks/useNoiseReductionAvailable'
|
||||
import posthog from 'posthog-js'
|
||||
import { RowWrapper } from './layout/RowWrapper'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import {
|
||||
@@ -20,6 +19,7 @@ import {
|
||||
saveNoiseReductionEnabled,
|
||||
userChoicesStore,
|
||||
} from '@/stores/userChoices'
|
||||
import { captureEvent } from '@/features/analytics/telemetry'
|
||||
|
||||
export type AudioTabProps = Pick<DialogProps, 'onOpenChange'> &
|
||||
Pick<TabPanelProps, 'id'>
|
||||
@@ -128,7 +128,7 @@ export const AudioTab = ({ id }: AudioTabProps) => {
|
||||
isSelected={noiseReductionEnabled}
|
||||
onChange={(v) => {
|
||||
saveNoiseReductionEnabled(v)
|
||||
if (v) posthog.capture('noise-reduction-init')
|
||||
if (v) captureEvent('noise-reduction-init')
|
||||
}}
|
||||
>
|
||||
{t('audio.noiseReduction.label')}
|
||||
|
||||
Reference in New Issue
Block a user