11import { useEffect , useRef , useState } from 'react'
2+ import posthog from 'posthog-js'
3+ import * as Sentry from '@sentry/react'
24
35import { FlashManager , StepCode , ErrorCode , DeviceType } from '../utils/manager'
46import { useImageManager } from '../utils/image'
@@ -38,9 +40,9 @@ function ImagePreloader() {
3840 )
3941}
4042
41- // Capture console logs for debug reports
43+ // Capture console logs for debug reports and telemetry
4244const consoleLogs = [ ]
43- const MAX_LOGS = 100
45+ const MAX_LOGS = 500
4446const originalConsole = { log : console . log , warn : console . warn , error : console . error , info : console . info , debug : console . debug }
4547; [ 'log' , 'warn' , 'error' , 'info' , 'debug' ] . forEach ( level => {
4648 console [ level ] = ( ...args ) => {
@@ -622,6 +624,7 @@ export default function Flash() {
622624 const [ serial , setSerial ] = useState ( null )
623625 const [ selectedDevice , setSelectedDevice ] = useState ( null )
624626 const [ wizardScreen , setWizardScreen ] = useState ( 'landing' ) // 'landing', 'device', 'zadig', 'connect', 'unbind', 'webusb', 'flash'
627+ const reportSentRef = useRef ( false )
625628
626629 const qdlManager = useRef ( null )
627630 const imageManager = useImageManager ( )
@@ -643,7 +646,7 @@ export default function Flash() {
643646 onProgressChange : setProgress ,
644647 onErrorChange : setError ,
645648 onConnectionChange : setConnected ,
646- onSerialChange : setSerial
649+ onSerialChange : setSerial ,
647650 } )
648651
649652 // Initialize the manager
@@ -655,6 +658,45 @@ export default function Flash() {
655658 } )
656659 } , [ config , imageManager . current ] )
657660
661+ // Helper to send a single pass/fail summary
662+ function sendSessionSummary ( result ) {
663+ if ( reportSentRef . current ) return
664+ reportSentRef . current = true
665+
666+ const errorName = Object . keys ( ErrorCode ) . find ( k => ErrorCode [ k ] === error ) || 'NONE'
667+ const stepName = Object . keys ( StepCode ) . find ( k => StepCode [ k ] === step ) || 'UNKNOWN'
668+
669+ // PostHog
670+ posthog . capture ( 'flash_session' , {
671+ result,
672+ serial,
673+ device_type : selectedDevice ,
674+ error_code : errorName ,
675+ step : stepName ,
676+ } )
677+
678+ // Sentry
679+ Sentry . captureMessage ( 'flash_session' , {
680+ level : result === 'pass' ? 'info' : 'error' ,
681+ tags : { result, serial, device_type : selectedDevice , error_code : errorName , step : stepName } ,
682+ extra : { console_tail : consoleLogs . slice ( - 200 ) } ,
683+ } )
684+ }
685+
686+ // Send report on failure
687+ useEffect ( ( ) => {
688+ if ( error !== ErrorCode . NONE && ! reportSentRef . current ) {
689+ sendSessionSummary ( 'fail' )
690+ }
691+ } , [ error ] )
692+
693+ // Send report on success
694+ useEffect ( ( ) => {
695+ if ( step === StepCode . DONE && error === ErrorCode . NONE && ! reportSentRef . current ) {
696+ sendSessionSummary ( 'pass' )
697+ }
698+ } , [ step , error ] )
699+
658700 // Transition to flash screen when connected
659701 useEffect ( ( ) => {
660702 if ( connected && wizardScreen === 'webusb' ) {
0 commit comments