import React, { createContext, useContext, useEffect, useCallback, type PropsWithChildren, } from 'react'; import { type SessionRecorderOptions, SessionState } from '../types'; import sessionRecorder from '../session-recorder'; import { ScreenRecorderView } from '../components/ScreenRecorderView'; import SessionRecorderWidget from '../components/SessionRecorderWidget'; import { SessionType } from '@multiplayer-app/session-recorder-common'; import { sessionRecorderStore, type SessionRecorderState, } from './SessionRecorderStore'; import { useStoreSelector } from './useStoreSelector'; interface SessionRecorderContextType { instance: typeof sessionRecorder; openWidgetModal: () => void; closeWidgetModal: () => void; startSession: (sessionType?: SessionType) => Promise; stopSession: (comment?: string) => Promise; pauseSession: () => Promise; resumeSession: () => Promise; cancelSession: () => Promise; saveSession: () => Promise; } const SessionRecorderContext = createContext( null ); export interface SessionRecorderProviderProps extends PropsWithChildren { options?: SessionRecorderOptions; } export const SessionRecorderProvider: React.FC< SessionRecorderProviderProps > = ({ children, options }) => { const isInitialized = useStoreSelector( sessionRecorderStore, (s) => s.isInitialized ); useEffect(() => { if (options) { sessionRecorder.init(options); } sessionRecorderStore.setState({ isInitialized: sessionRecorder.isInitialized, }); }, []); useEffect(() => { sessionRecorderStore.setState({ sessionState: sessionRecorder.sessionState, sessionType: sessionRecorder.sessionType, }); const onStateChange = ( sessionState: SessionState, sessionType: SessionType ) => { sessionRecorderStore.setState({ sessionState, sessionType }); }; const onInit = () => { sessionRecorderStore.setState({ isInitialized: true }); }; sessionRecorder.on('state-change', onStateChange); sessionRecorder.on('init', onInit); return () => { sessionRecorder.off('state-change', onStateChange); sessionRecorder.off('init', onInit); }; }, []); const startSession = useCallback( (sessionType: SessionType = SessionType.MANUAL) => { return sessionRecorder.start(sessionType); }, [] ); const stopSession = useCallback((comment?: string) => { return sessionRecorder.stop(comment); }, []); const pauseSession = useCallback(() => { return sessionRecorder.pause(); }, []); const resumeSession = useCallback(() => { return sessionRecorder.resume(); }, []); const cancelSession = useCallback(() => { return sessionRecorder.cancel(); }, []); const saveSession = useCallback(() => { return sessionRecorder.save(); }, []); const openWidgetModal = useCallback(() => { sessionRecorderStore.setState({ isWidgetModalVisible: true }); }, []); const closeWidgetModal = useCallback(() => { sessionRecorderStore.setState({ isWidgetModalVisible: false }); }, []); return ( {children} {isInitialized && !!sessionRecorder.config.widget.enabled && ( )} ); }; export const useSessionRecorder = (): SessionRecorderContextType => { const context = useContext(SessionRecorderContext); if (!context) { throw new Error( 'useSessionRecorder must be used within a SessionRecorderProvider' ); } return context; };