import React, { useState, useCallback, memo } from 'react'; import { View, StyleSheet } from 'react-native'; import { SessionState } from '../../types'; import { SessionType } from '@multiplayer-app/session-recorder-common'; import { useSessionRecorder } from '../../context/SessionRecorderContext'; import FinalPopover from './FinalPopover'; import ModalContainer from './ModalContainer'; import InitialPopover from './InitialPopover'; import FloatingButton from './FloatingButton'; import ErrorBanner from './ErrorBanner'; import { logger } from '../../utils'; import { useSessionRecorderStore } from '../../context/useSessionRecorderStore'; import { sessionRecorderStore } from '../../context/SessionRecorderStore'; interface SessionRecorderWidgetProps {} const SessionRecorderWidget: React.FC = memo(() => { const { instance, openWidgetModal, closeWidgetModal } = useSessionRecorder(); const isOnline = useSessionRecorderStore((s) => s.isOnline); const sessionType = useSessionRecorderStore( (s) => s.sessionType ); const isModalVisible = useSessionRecorderStore( (s) => s.isWidgetModalVisible ); const sessionState = useSessionRecorderStore( (s) => s.sessionState ); const error = useSessionRecorderStore((s) => s.error); const [isSubmitting, setIsSubmitting] = useState(false); // Get configuration from instance const { widget, showContinuousRecording } = instance.config; const dismissError = useCallback(() => { sessionRecorderStore.setState({ error: null }); }, []); const handleError = useCallback((error: any, message: string) => { const errorMessage = error instanceof Error ? error.message : message; logger.error('SessionRecorderWidget', message, error); sessionRecorderStore.setState({ error: errorMessage }); }, []); const onStartRecording = useCallback( async (sessionType: SessionType) => { if (!isOnline) { handleError( new Error('Cannot start recording while offline'), 'Cannot start recording while offline' ); return; } try { await instance.start(sessionType); closeWidgetModal(); } catch (error) { handleError(error, 'Failed to start recording'); } }, [isOnline, handleError] ); const onStopRecording = useCallback( async (comment?: string) => { try { setIsSubmitting(true); await instance.stop(comment); closeWidgetModal(); } catch (error) { handleError(error, 'Failed to stop recording'); } finally { setIsSubmitting(false); } }, [handleError] ); const onCancelSession = useCallback(async () => { try { await instance.cancel(); closeWidgetModal(); } catch (error) { handleError(error, 'Failed to cancel session'); } }, [handleError]); const onSaveContinuousSession = useCallback(async () => { try { await instance.save(); } catch (error) { handleError(error, 'Failed to save continuous session'); } }, [handleError]); const isStarted = sessionState === SessionState.started || sessionState === SessionState.paused; const isContinuous = sessionType === SessionType.CONTINUOUS; return ( <> {widget.button?.visible && ( )} {isStarted && !isContinuous ? ( {error && } ) : ( {error && } )} ); }); export default SessionRecorderWidget; const styles = StyleSheet.create({ overlayContainer: { ...StyleSheet.absoluteFillObject, }, });