cuoral_flutter 0.0.5 copy "cuoral_flutter: ^0.0.5" to clipboard
cuoral_flutter: ^0.0.5 copied to clipboard

A Flutter plugin to integrate Cuoral SDK for customer support and engagement.

example/lib/main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:cuoral_flutter/cuoral_flutter.dart';

void main() {
  // Wrap your app with error tracking
  CuoralErrorHandler.runApp(() async {
    WidgetsFlutterBinding.ensureInitialized();

    // Initialize Cuoral SDK
    await Cuoral.instance.initialize(
      publicKey: 'c8e3081e-8dfc-49b5-bbd1-4ef513504d88',
      email: 'demo@example.com',
      firstName: 'Demo',
      lastName: 'User',
    );

    runApp(const MyApp());
  });
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cuoral Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      debugShowCheckedModeBanner: false,
      // Add Cuoral navigation observer for automatic screen tracking
      navigatorObservers: [CuoralNavigatorObserver()],
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _isRecording = false;
  String? _recordingPath;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Scaffold(
          appBar: AppBar(
            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
            title: const Text('Cuoral Flutter Demo'),
          ),
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: SingleChildScrollView(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  // SDK Status
                  Card(
                    child: Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Text(
                            'SDK Status',
                            style: TextStyle(
                              fontSize: 18,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          const SizedBox(height: 8),
                          Text('Initialized: ${Cuoral.instance.isInitialized}'),
                          Text(
                            'Session ID: ${Cuoral.instance.sessionId ?? "N/A"}',
                          ),
                        ],
                      ),
                    ),
                  ),
                  const SizedBox(height: 16),

                  // Intelligence Tracking Demos
                  const Text(
                    'Intelligence Tracking',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 8),

                  ElevatedButton(
                    onPressed: () {
                      // Manual page view tracking
                      Cuoral.instance.trackPageView('/demo_screen');
                      _showSnackBar('Page view tracked');
                    },
                    child: const Text('Track Page View'),
                  ),

                  ElevatedButton(
                    onPressed: () async {
                      // Test error tracking
                      try {
                        throw Exception('This is a test error');
                      } catch (e, stackTrace) {
                        await CuoralErrorHandler.trackError(
                          e,
                          stackTrace,
                          context: 'demo_button',
                        );
                        _showSnackBar('Error tracked');
                      }
                    },
                    child: const Text('Track Test Error'),
                  ),

                  ElevatedButton(
                    onPressed: () async {
                      // Test automatic network error tracking
                      // No need to use special HTTP client - ALL requests are tracked automatically
                      final client = HttpClient();
                      try {
                        final request = await client.getUrl(
                          Uri.parse('https://httpstat.us/404'),
                        );
                        final response = await request.close();
                        _showSnackBar(
                          'Network error automatically tracked (${response.statusCode})',
                        );
                      } catch (e) {
                        _showSnackBar('Network error tracked: $e');
                      } finally {
                        client.close();
                      }
                    },
                    child: const Text('Test Auto Network Tracking (404)'),
                  ),

                  ElevatedButton(
                    onPressed: () async {
                      // Track a custom event
                      await Cuoral.instance.trackCustomEvent(
                        name: 'demo_button_clicked',
                        category: 'user_action',
                        properties: {
                          'button_name': 'Custom Event Demo',
                          'screen': 'home',
                          'timestamp': DateTime.now().toIso8601String(),
                        },
                        elementSelector: 'demo_custom_event_button',
                      );
                      _showSnackBar('Custom event tracked');
                    },
                    child: const Text('Track Custom Event'),
                  ),

                  const SizedBox(height: 16),

                  // Screen Recording Demo
                  const Text(
                    'Screen Recording',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 8),

                  ElevatedButton(
                    onPressed: _isRecording ? null : _startRecording,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.red,
                      foregroundColor: Colors.white,
                    ),
                    child: const Text('Start Recording'),
                  ),

                  ElevatedButton(
                    onPressed: _isRecording ? _stopRecording : null,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.green,
                      foregroundColor: Colors.white,
                    ),
                    child: const Text('Stop Recording'),
                  ),

                  if (_recordingPath != null)
                    Padding(
                      padding: const EdgeInsets.only(top: 8.0),
                      child: Text(
                        'Last recording: $_recordingPath',
                        style: const TextStyle(fontSize: 12),
                      ),
                    ),

                  const SizedBox(height: 16),

                  // Navigation Demo
                  ElevatedButton(
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => const SecondScreen(),
                          settings: const RouteSettings(name: '/second_screen'),
                        ),
                      );
                    },
                    child: const Text('Navigate to Second Screen'),
                  ),

                  const SizedBox(height: 16),

                  // Cuoral Chat Widget Demo
                  const Text(
                    'Chat Widget',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 8),
                  const Text(
                    'Look for the floating chat button in the bottom-right corner!',
                    style: TextStyle(fontSize: 14, fontStyle: FontStyle.italic),
                  ),
                ],
              ),
            ),
          ),
        ),

        // Add the Cuoral chat launcher floating button
        CuoralLauncher(
          publicKey: 'c8e3081e-8dfc-49b5-bbd1-4ef513504d88',
          email: 'demo@example.com',
          firstName: 'Demo',
          lastName: 'User',
          backgroundColor: Colors.red,
          icon: const Icon(Icons.chat, color: Colors.white),
          isVisible: true,
          position: Alignment.bottomRight,
        ),
      ],
    );
  }

  Future<void> _startRecording() async {
    print('DEBUG: _startRecording called');

    final isAvailable = await CuoralPlatform.instance.isRecordingAvailable();
    print('DEBUG: isRecordingAvailable = $isAvailable');

    if (!isAvailable) {
      _showSnackBar('Screen recording not available');
      return;
    }

    print('DEBUG: Calling CuoralPlatform.startRecording...');
    final success = await CuoralPlatform.instance.startRecording(
      withAudio: true,
    );
    print('DEBUG: startRecording returned: $success');

    if (success) {
      setState(() {
        _isRecording = true;
      });
      _showSnackBar('Recording started');
    } else {
      _showSnackBar('Failed to start recording');
    }
  }

  Future<void> _stopRecording() async {
    print('DEBUG: _stopRecording called');
    final filePath = await CuoralPlatform.instance.stopRecording();
    print('DEBUG: stopRecording returned: $filePath');

    setState(() {
      _isRecording = false;
      _recordingPath = filePath;
    });

    if (filePath != null) {
      _showSnackBar('Recording saved');
    } else {
      _showSnackBar('Failed to save recording');
    }
  }

  void _showSnackBar(String message) {
    ScaffoldMessenger.of(
      context,
    ).showSnackBar(SnackBar(content: Text(message)));
  }
}

class SecondScreen extends StatelessWidget {
  const SecondScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Second Screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'This is the second screen',
              style: TextStyle(fontSize: 18),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: const Text('Go Back'),
            ),
          ],
        ),
      ),
    );
  }
}
1
likes
0
points
178
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin to integrate Cuoral SDK for customer support and engagement.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_inappwebview, http, path_provider, permission_handler, platform, plugin_platform_interface, shared_preferences

More

Packages that depend on cuoral_flutter

Packages that implement cuoral_flutter