cello_sdk 0.0.1 copy "cello_sdk: ^0.0.1" to clipboard
cello_sdk: ^0.0.1 copied to clipboard

Flutter plugin wrapper for the Cello iOS and Android SDKs.

example/lib/main.dart

import 'dart:async';

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

void main() {
  runApp(const CelloExampleApp());
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: CelloExampleHome());
  }
}

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

  @override
  State<CelloExampleHome> createState() => _CelloExampleHomeState();
}

class _CelloExampleHomeState extends State<CelloExampleHome> {
  final _productIdController = TextEditingController(text: 'dev.cello.so');
  final _tokenController = TextEditingController();
  final _environmentController = TextEditingController(text: 'sandbox');
  final _languageController = TextEditingController(text: 'en');
  final _themeModeController = TextEditingController(text: 'system');
  final _firstNameController = TextEditingController();
  final _lastNameController = TextEditingController();
  final _emailController = TextEditingController();

  final List<String> _logs = <String>[];
  StreamSubscription<CelloTokenEvent>? _tokenSubscription;
  CelloConfiguration? _configuration;
  Map<String, String> _activeUcc = <String, String>{};
  Map<String, dynamic> _campaignConfig = <String, dynamic>{};
  bool _initializing = false;

  @override
  void initState() {
    super.initState();
    _tokenSubscription = Cello.tokenEvents.listen((event) {
      setState(() {
        _logs.add('[${event.timestamp.toIso8601String()}] ${event.type.name}');
      });
    });
  }

  @override
  void dispose() {
    _tokenSubscription?.cancel();
    _productIdController.dispose();
    _tokenController.dispose();
    _environmentController.dispose();
    _languageController.dispose();
    _themeModeController.dispose();
    _firstNameController.dispose();
    _lastNameController.dispose();
    _emailController.dispose();
    super.dispose();
  }

  Future<void> _initialize() async {
    FocusScope.of(context).unfocus();
    if (_tokenController.text.isEmpty || _productIdController.text.isEmpty) {
      _log('Provide productId and token before initializing.');
      return;
    }

    setState(() {
      _initializing = true;
    });

    try {
      final options = CelloInitializeOptions(
        productId: _productIdController.text.trim(),
        token: _tokenController.text.trim(),
        environment: _environmentController.text.trim().isEmpty
            ? null
            : _environmentController.text.trim(),
        language: _languageController.text.trim().isEmpty
            ? null
            : _languageController.text.trim(),
        themeMode: _themeModeController.text.trim().isEmpty
            ? null
            : _themeModeController.text.trim(),
        userDetails: _buildUserDetails(),
      );

      final configuration = await Cello.initialize(options);
      setState(() {
        _configuration = configuration;
      });
      _log('Cello initialized.');
      await Cello.showFab();
    } catch (error) {
      _log('Initialization failed: $error');
    } finally {
      setState(() {
        _initializing = false;
      });
    }
  }

  Future<void> _updateToken() async {
    if (_tokenController.text.isEmpty) {
      _log('Enter a token to update.');
      return;
    }
    try {
      await Cello.updateToken(_tokenController.text.trim());
      _log('Token updated.');
    } catch (error) {
      _log('Failed to update token: $error');
    }
  }

  Future<void> _changeLanguage() async {
    if (_languageController.text.isEmpty) {
      _log('Enter a language code.');
      return;
    }
    try {
      await Cello.changeLanguage(_languageController.text.trim());
      _log('Language changed.');
    } catch (error) {
      _log('Failed to change language: $error');
    }
  }

  Future<void> _setThemeMode() async {
    if (_themeModeController.text.isEmpty) {
      _log('Enter a theme mode (light, dark, or system).');
      return;
    }
    try {
      await Cello.setThemeMode(_themeModeController.text.trim());
      _log('Theme mode set to ${_themeModeController.text.trim()}.');
    } catch (error) {
      _log('Failed to set theme mode: $error');
    }
  }

  Future<void> _fetchActiveUcc() async {
    try {
      final response = await Cello.getActiveUcc();
      setState(() {
        _activeUcc = response;
      });
      _log('Fetched active UCC (${response.length} keys).');
    } catch (error) {
      _log('Failed to fetch active UCC: $error');
    }
  }

  Future<void> _fetchCampaignConfig() async {
    try {
      final response = await Cello.getCampaignConfig();
      setState(() {
        _campaignConfig = response;
      });
      _log('Fetched campaign config (${response.length} keys).');
    } catch (error) {
      _log('Failed to fetch campaign config: $error');
    }
  }

  Future<void> _shutdown() async {
    try {
      await Cello.shutdown();
      _log('Cello shutdown complete.');
      setState(() {
        _configuration = null;
      });
    } catch (error) {
      _log('Failed to shutdown: $error');
    }
  }

  ProductUserDetails? _buildUserDetails() {
    if (_firstNameController.text.isEmpty &&
        _lastNameController.text.isEmpty &&
        _emailController.text.isEmpty) {
      return null;
    }

    return ProductUserDetails(
      firstName: _firstNameController.text.trim().isEmpty
          ? null
          : _firstNameController.text.trim(),
      lastName: _lastNameController.text.trim().isEmpty
          ? null
          : _lastNameController.text.trim(),
      email: _emailController.text.trim().isEmpty
          ? null
          : _emailController.text.trim(),
    );
  }

  void _log(String message) {
    setState(() {
      _logs.add(message);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Cello Flutter Example'),
        actions: [
          IconButton(
            onPressed: () {
              setState(() {
                _logs.clear();
              });
            },
            icon: const Icon(Icons.delete_outline),
            tooltip: 'Clear logs',
          ),
        ],
      ),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: ListView(
            children: [
              _sectionTitle('Credentials'),
              _textField('Product ID', _productIdController),
              _textField('Token', _tokenController),
              _textField('Environment (optional)', _environmentController),
              _textField('Language (optional)', _languageController),
              _textField('Theme Mode (optional)', _themeModeController),
              const SizedBox(height: 8),
              _sectionTitle('Product User (optional)'),
              _textField('First name', _firstNameController),
              _textField('Last name', _lastNameController),
              _textField(
                'Email',
                _emailController,
                keyboardType: TextInputType.emailAddress,
              ),
              const SizedBox(height: 16),
              Wrap(
                spacing: 12,
                runSpacing: 12,
                children: [
                  ElevatedButton(
                    onPressed: _initializing ? null : _initialize,
                    child: Text(
                      _initializing ? 'Initializing…' : 'Initialize & Show FAB',
                    ),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized
                        ? () => Cello.hideFab()
                        : null,
                    child: const Text('Hide FAB'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized
                        ? () => Cello.openWidget()
                        : null,
                    child: const Text('Open Widget'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized
                        ? () => Cello.hideWidget()
                        : null,
                    child: const Text('Hide Widget'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized ? _updateToken : null,
                    child: const Text('Update Token'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized ? _changeLanguage : null,
                    child: const Text('Change Language'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized ? _setThemeMode : null,
                    child: const Text('Set Theme Mode'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized ? _fetchActiveUcc : null,
                    child: const Text('Get Active UCC'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized
                        ? _fetchCampaignConfig
                        : null,
                    child: const Text('Get Campaign Config'),
                  ),
                  ElevatedButton(
                    onPressed: Cello.isInitialized ? _shutdown : null,
                    child: const Text('Shutdown'),
                  ),
                ],
              ),
              const SizedBox(height: 24),
              _sectionTitle('Latest Configuration'),
              Text(
                _configuration?.rawResponse?.toString() ?? 'Not initialized',
              ),
              const SizedBox(height: 16),
              _sectionTitle('Active UCC'),
              Text(
                _activeUcc.isEmpty ? 'Not available' : _activeUcc.toString(),
              ),
              const SizedBox(height: 16),
              _sectionTitle('Campaign Config'),
              Text(
                _campaignConfig.isEmpty
                    ? 'Not available'
                    : _campaignConfig.toString(),
              ),
              const SizedBox(height: 16),
              _sectionTitle('Token Events'),
              SizedBox(
                height: 160,
                child: DecoratedBox(
                  decoration: BoxDecoration(
                    border: Border.all(color: Colors.grey.shade400),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: ListView.builder(
                    itemCount: _logs.length,
                    itemBuilder: (context, index) => Padding(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 8,
                        vertical: 4,
                      ),
                      child: Text(_logs[_logs.length - index - 1]),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _sectionTitle(String title) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: Text(
        title,
        style: Theme.of(
          context,
        ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
      ),
    );
  }

  Widget _textField(
    String label,
    TextEditingController controller, {
    TextInputType keyboardType = TextInputType.text,
  }) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: TextField(
        controller: controller,
        keyboardType: keyboardType,
        decoration: InputDecoration(
          border: const OutlineInputBorder(),
          labelText: label,
        ),
      ),
    );
  }
}
0
likes
140
points
106
downloads

Publisher

verified publishercello.so

Weekly Downloads

Flutter plugin wrapper for the Cello iOS and Android SDKs.

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on cello_sdk

Packages that implement cello_sdk