vivanta_connect_flutter 0.6.0+10 copy "vivanta_connect_flutter: ^0.6.0+10" to clipboard
vivanta_connect_flutter: ^0.6.0+10 copied to clipboard

Vivanta Connect for Flutter

example/lib/main.dart

import 'dart:io';

import 'package:example/vivanta.dart';
import 'package:flutter/material.dart';
import 'package:vivanta_connect_flutter/helpers/vivanta_sync.dart';
import 'package:vivanta_connect_flutter/services/preferences.dart';
import 'package:vivanta_connect_flutter/styles/colors.dart';
import 'package:vivanta_connect_flutter/styles/fonts.dart';
import 'package:vivanta_connect_flutter/views/embedded_graph.dart';
import 'package:vivanta_connect_flutter/vivanta_connect_flutter.dart';

void main() => runApp(const Example());

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Vivanta Connect Example',
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String companyId = 'Vivanta';
  final Preferences preferences = Preferences();
  late TextEditingController _usernameController;
  late TextEditingController _brandController;
  late FocusNode _usernameFocusNode;
  late FocusNode _brandFocusNode;

  @override
  void initState() {
    _usernameController = TextEditingController();
    _usernameFocusNode = FocusNode();
    _brandController = TextEditingController();
    _brandFocusNode = FocusNode();

    _usernameFocusNode.addListener(() {
      if (!_usernameFocusNode.hasFocus) {
        preferences.setExternalUserId(_usernameController.text);
      }
    });

    _brandFocusNode.addListener(() {
      if (!_brandFocusNode.hasFocus) {
        preferences.setBrandId(_brandController.text);
      }
    });
    initAsync();
    super.initState();
  }

  @override
  void dispose() {
    _usernameController.dispose();
    _usernameFocusNode.dispose();
    _brandController.dispose();
    _brandFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Vivanta Connect Example'),
      ),
      body: Container(
        width: MediaQuery.of(context).size.width,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            _box(),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Text(
                      'External User ID:',
                      textAlign: TextAlign.start,
                    ),
                  ),
                  TextField(
                    keyboardType: TextInputType.text,
                    controller: _usernameController,
                    focusNode: _usernameFocusNode,
                    onEditingComplete: () {
                      FocusScope.of(context).unfocus();
                    },
                  ),
                ],
              ),
            ),
            _box(),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Text(
                      'Brand ID:',
                      textAlign: TextAlign.start,
                    ),
                  ),
                  TextField(
                    keyboardType: TextInputType.text,
                    controller: _brandController,
                    focusNode: _brandFocusNode,
                    onEditingComplete: () {
                      FocusScope.of(context).unfocus();
                    },
                  ),
                ],
              ),
            ),
            _box(),
            TextButton(
              onPressed: _usernameController.text.isEmpty
                  ? null
                  : () {
                      Navigator.of(context).push(
                        MaterialPageRoute(
                          builder: (context) => VivantaConnectFlutter(
                            apiKey: Vivanta.apiKey,
                            customerId: Vivanta.customerId,
                            externalUserId: _usernameController.text,
                            companyId: companyId,
                          ),
                        ),
                      );
                    },
              style: _buttonStyle(),
              child: Text(
                'Connect your device with Vivanta',
                textAlign: TextAlign.center,
                style: VivantaFonts.button,
              ),
            ),
            if (Platform.isIOS) ...[
              _box(),
              TextButton(
                onPressed: _usernameController.text.isEmpty ? null : _sync,
                style: _buttonStyle(),
                child: Text(
                  'Sync Apple Health Data',
                  textAlign: TextAlign.center,
                  style: VivantaFonts.button,
                ),
              ),
            ],
            if (Platform.isAndroid) ...[
              _box(),
              TextButton(
                onPressed: _usernameController.text.isEmpty ? null : _sync,
                style: _buttonStyle(),
                child: Text(
                  'Sync Google Health Connect Data',
                  textAlign: TextAlign.center,
                  style: VivantaFonts.button,
                ),
              ),
            ],
            _box(),
            _getButtonToGraph(
              'Open activity graph',
              GraphType.activity,
            ),
            _box(),
            _getButtonToGraph(
              'Open active time graph',
              GraphType.activeTime,
            ),
            _box(),
            _getButtonToGraph(
              'Open sleep graph',
              GraphType.sleep,
            ),
          ],
        ),
      ),
    );
  }

  Future<void> initAsync() async {
    final externalUserId = await preferences.getExternalUserId();
    final brandId = await preferences.getBrandId();
    if (externalUserId.isNotEmpty) {
      _usernameController.text = externalUserId;
      setState(() {});
      _sync(showSuccess: true);
    }
    if (brandId.isNotEmpty) {
      _brandController.text = brandId;
      setState(() {});
    }
  }

  ButtonStyle _buttonStyle() => ButtonStyle(
        backgroundColor: MaterialStateProperty.all<Color>(
          VivantaColors.primary,
        ),
        fixedSize: MaterialStateProperty.all<Size>(
          Size(MediaQuery.of(context).size.width - 32, 32),
        ),
      );

  Widget _box() => SizedBox(height: 24);

  Widget _getButtonToGraph(String text, GraphType graphType) {
    final brandId = int.tryParse(_brandController.text);
    return TextButton(
      onPressed: _usernameController.text.isEmpty
          ? null
          : () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (context) => EmbeddedGraph(
                    apiKey: Vivanta.apiKey,
                    customerId: Vivanta.customerId,
                    externalUserId: _usernameController.text,
                    graphType: graphType,
                    brandId: brandId,
                  ),
                ),
              );
            },
      style: _buttonStyle(),
      child: Text(
        text,
        textAlign: TextAlign.center,
        style: VivantaFonts.button,
      ),
    );
  }

  Future<void> _sync({
    bool showSuccess = true,
  }) async {
    final sync = VivantaSync(
      apiKey: Vivanta.apiKey,
      customerId: Vivanta.customerId,
      externalUserId: _usernameController.text,
    );
    sync.executeAll().then((value) {
      if (showSuccess) {
        showModalBottomSheet(
          context: context,
          builder: (context) {
            return Container(
              height: 100,
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    const Text('Data sync finished successfully'),
                    SizedBox(
                      height: 8,
                    ),
                    ElevatedButton(
                      child: const Text('Close'),
                      onPressed: () => Navigator.pop(context),
                    ),
                    SizedBox(
                      height: 8,
                    ),
                  ],
                ),
              ),
            );
          },
        );
      }
    }).catchError(
      (onError) {},
    );
  }
}