openpanel 0.1.1 copy "openpanel: ^0.1.1" to clipboard
openpanel: ^0.1.1 copied to clipboard

OpenPanel analytics for Flutter with native Android and iOS clients, persistent offline event queue and batching.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:openpanel/openpanel.dart';

/// Configuration comes from --dart-define so no credentials live in the
/// repository:
///
/// ```sh
/// flutter run \
///   --dart-define=OPENPANEL_CLIENT_ID=... \
///   --dart-define=OPENPANEL_API_URL=https://your-openpanel.example.com
/// ```
const String clientId = String.fromEnvironment('OPENPANEL_CLIENT_ID');
const String apiUrl = String.fromEnvironment(
  'OPENPANEL_API_URL',
  defaultValue: OpenpanelOptions.defaultApiUrl,
);
const String clientSecret = String.fromEnvironment('OPENPANEL_CLIENT_SECRET');
const bool verbose = bool.fromEnvironment('OPENPANEL_VERBOSE');

void main() {
  // Any plugin call before runApp requires an initialized binding.
  WidgetsFlutterBinding.ensureInitialized();

  if (clientId.isNotEmpty) {
    // The SDK queues events until initialization completes, so tracking can
    // start immediately.
    Openpanel.instance.initialize(
      OpenpanelOptions(
        clientId: clientId,
        apiUrl: apiUrl,
        clientSecret: clientSecret.isEmpty ? null : clientSecret,
        verbose: verbose,
      ),
    );
  }
  runApp(const OpenpanelExampleApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'OpenPanel Example',
      theme: ThemeData(colorSchemeSeed: Colors.indigo, useMaterial3: true),
      home: const ExamplePage(),
    );
  }
}

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

  void _run(BuildContext context, String label, Future<void> Function() body) {
    final messenger = ScaffoldMessenger.of(context);
    body().then(
      (_) => _toast(messenger, '$label ✓'),
      onError: (Object error) => _toast(messenger, '$label failed: $error'),
    );
  }

  void _toast(ScaffoldMessengerState messenger, String message) {
    messenger
      ..hideCurrentSnackBar()
      ..showSnackBar(SnackBar(content: Text(message)));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('OpenPanel Example')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Text(
                clientId.isEmpty
                    ? 'Not configured. Run with '
                          '--dart-define=OPENPANEL_CLIENT_ID=... '
                          '(and OPENPANEL_API_URL for self-hosted).'
                    : 'Configured. api: $apiUrl\n'
                          'Events are queued natively and flushed in batches.',
              ),
            ),
          ),
          const SizedBox(height: 8),
          FilledButton(
            onPressed: () => _run(context, 'track', () {
              return Openpanel.instance.track(
                'button_clicked',
                properties: <String, Object?>{
                  'button': 'track_demo',
                  'timestamp': DateTime.now().millisecondsSinceEpoch,
                },
              );
            }),
            child: const Text('track: button_clicked'),
          ),
          FilledButton(
            onPressed: () => _run(context, 'identify', () {
              return Openpanel.instance.identify(
                'example-user-42',
                email: 'user@example.com',
                properties: <String, Object?>{'plan': 'free'},
              );
            }),
            child: const Text('identify: example-user-42'),
          ),
          FilledButton(
            onPressed: () => _run(context, 'increment', () {
              return Openpanel.instance.increment(
                'example-user-42',
                'demo_counter',
                value: 1,
              );
            }),
            child: const Text('increment: demo_counter'),
          ),
          FilledButton(
            onPressed: () => _run(context, 'decrement', () {
              return Openpanel.instance.decrement(
                'example-user-42',
                'demo_counter',
                value: 1,
              );
            }),
            child: const Text('decrement: demo_counter'),
          ),
          FilledButton(
            onPressed: () => _run(context, 'setGlobalProperties', () {
              return Openpanel.instance.setGlobalProperties(<String, Object?>{
                'environment': 'example',
              });
            }),
            child: const Text('setGlobalProperties: environment'),
          ),
          FilledButton(
            onPressed: () => _run(context, 'flush', Openpanel.instance.flush),
            child: const Text('flush'),
          ),
          OutlinedButton(
            onPressed: () => _run(context, 'clear', Openpanel.instance.clear),
            child: const Text('clear'),
          ),
        ],
      ),
    );
  }
}
1
likes
160
points
152
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

OpenPanel analytics for Flutter with native Android and iOS clients, persistent offline event queue and batching.

Repository (GitHub)
View/report issues

Topics

#analytics

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on openpanel

Packages that implement openpanel